Wednesday, December 30, 2020

Test custom page type api on postman

Today we see how to test the custom page type API on postman.

Step 1: Open postman set the request type GET, paste API url, set authorization type Basic Auth, add user name and password.













Step 2: search the users and open the form











Step 3: copy the username and web service access key and paste it is Postman Authorization.














Step 4: Now click on send button you can see result.





How to create Custom page type API Business central

Today we see how to make custom API in business central.

I ma making API for Item data.


Step 1: 

add new file in project and set the any name.al Write the below code in the file.

page 50103 Products
{
    PageType = Card;
    SourceTable = Item;

    layout
    {
        area(Content)
        {
            group(GroupName)
            {
                field("No."; Rec."No."{ }

                field(Description; Rec.Description{ }
                field(Blocked; Rec.Blocked{ }
                field(Type; Rec.Type) { }
                field("Base Unit of Measure"; Rec."Base Unit of Measure"{ }
                field("Last Date Modified"; Rec."Last Date Modified"{ }
            }
        }
    }
}


Step 2: Add new file in the project and set the name.xml. In file write twebservices and click enter you will automatically get the structure.

<?xml version="1.0" encoding="UTF-8"?>
<ExportedData>
    <TenantWebServiceCollection>
        <TenantWebService>
            <ObjectType>Page</ObjectType>
            <ServiceName>Products</ServiceName>
            <ObjectID>50103</ObjectID>
            <Published>true</Published>
        </TenantWebService>
    </TenantWebServiceCollection> 
</ExportedData>


Step 3: Now run the project it automatically publish your api.

Step 4: Search web service in business central search bar and click on it.



Step 5: You can see the webservice in the below image.



In the next post we will look at how we use our API on postman.


Monday, September 14, 2020

X++ Call rest Api from AX 2012

Now we see how to Authenticate the REST API from AX 2012

  System.Net.WebRequest webreq = System.Net.WebRequest::Create("URL");

    System.IO.Stream streamstr,responsestr;

    System.IO.StreamWriter streamWriter;

    System.Net.WebResponse webresponse;

    System.IO.StreamReader reader;

    System.Exception ex;

   


    str json = "{\"clientId\":\"Value\",\"clientSecret\":\"Value\"}";


   webreq.set_Method("POST");

   webreq.set_ContentType("application/json");

   streamstr = webreq.GetRequestStream();

   streamWriter = new System.IO.StreamWriter(streamstr);

   streamWriter.Write(json);

   streamWriter.Flush();

   streamWriter.Close();

   streamWriter.Dispose();


    try

    {

       webresponse = webreq.GetResponse();

       responsestr = webresponse.GetResponseStream();

       reader = new System.IO.StreamReader(responsestr);

       info(reader.ReadToEnd());

    }

    catch(Exception::CLRError)

    {

        ex = ClrInterop::getLastException();

        if (ex != null)

        {

            ex = ex.get_InnerException();

            if (ex != null)

            {

                error(ex.ToString());

            }

        }

    }

Thursday, August 20, 2020

Create Sales order Using X++ Ax 2012

 public void CreateSalesOrder()

{

    CustTable                   custtable;

    SalesTable                  salesTable;

    NumberSeq                   NumberSeq;

    SalesId                     sid;

    SalesLine                   sl;

   

// sales order header part

        NumberSeq = NumberSeq::newGetNum(SalesParameters::numRefSalesId() , true);

        sid = NumberSeq.num();

        salesTable.SalesId                  = sid;

        salesTable.initValue();

        salesTable.CustAccount              = custtable.AccountNum;

        salesTable.initFromCustTable();

        salesTable.ShippingDateRequested    = systemDateGet();

        salesTable.ShippingDateConfirmed    = systemDateGet();

        salesTable.ReceiptDateConfirmed     = systemDateGet();

        salesTable.ReceiptDateRequested     = systemDateGet();

        ttsBegin;

            salesTable.insert();

        ttsCommit;



// Sales order line part        

    sl.clear();

            sl.SalesId      = salesTable.SalesId;

            sl.ItemId       = //ItemID;

            sl.initFromInventTable(InventTable::find(sl.ItemId));

            sl.SalesQty     = //QTY;

            sl.SalesPrice   = InventTableModule::find(sl.ItemId,ModuleInventPurchSales::Sales).Price;

            sl.LineAmount   = sl.SalesQty*sl.SalesPrice;

            sl.createLine(NoYes::Yes, // Validate

                NoYes::Yes, // initFromSalesTable

                NoYes::No, // initFromInventTable

                NoYes::Yes, // calcInventQty

                NoYes::Yes, // searchMarkup

                NoYes::No); // searchPrice

   

        }

     

}

Monday, April 13, 2020

C# how to make PDF file password protected

how to make PDF file password protected in C# using itext sharp

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using iTextSharp.text;
using System.IO;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            String FilePath = @"C:\Users\rashid\Desktop\Customer.pdf";
            string PDFFilepassword = "12345";
            try
            {
                byte[] bytes = System.IO.File.ReadAllBytes(FilePath);
                using (MemoryStream inputData = new MemoryStream(bytes))
                {
                    using (MemoryStream outputData = new MemoryStream())
                    {
                   
                        PdfReader reader = new PdfReader(inputData);
                        PdfReader.unethicalreading = true;
                        PdfEncryptor.Encrypt(reader, outputData, true, PDFFilepassword, PDFFilepassword, PdfWriter.ALLOW_SCREENREADERS);
                        bytes = outputData.ToArray();
                        File.WriteAllBytes(FilePath , bytes);
                     
                     
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}

Tuesday, April 7, 2020

batch job ax 2012 using x++

Basic structure of Batch Job in AX 2012 using X++

class BEProjectEmailAutomationBatch extends RunBaseBatch
{
}
public void run()
{
    //write login in this method
}
public container pack()
{
    return conNull();
}
public boolean unpack(container packedclass)
{
    return true;
}
public static ClassDescription description()
{
    return "Project Report Email Automation";
}
public static void main(Args _args)
{
    BEProjectEmailAutomationBatch EmailAutomation = new BEProjectEmailAutomationBatch();

    if (EmailAutomation.prompt())
    {
        EmailAutomation.run();
    }
}

Monday, April 6, 2020

Export template in AX 2012 X++

today we will see how to export template like if you have written any uploaded but after some time you don't remember which value will come first or you forget the sequence.

For this situation we will make the template you just need to fill the template and then import the data in ax 2012.

class BEUploadTickets extends RunBaseBatch
{

    DialogRunbase               dialog;
    DialogField                 fileNameField;
    FilenameOpen                csvFileName;
}

protected Object dialog()
{
    container               conFilter;
    DialogText              dlgText;
    DialogGroup             exportGroup, importGroup;
    FormBuildControl        dialogGroupControlExp, dialogGroupControlImp;
    FormBuildButtonControl  exportTemplateButton;
    ;
    #File
    dialog          = super();
    conFilter       = ['Excel File","*.xlsx'];


    importGroup = dialog.addGroup('Import');

    dialogGroupControlImp       = dialog.formBuildDesign().control(importGroup.formBuildGroup().id());

    fileNameField   = dialog.addField(extendedTypeStr('FilenameOpen'));
    dialog.filenameLookupFilter(conFilter);

    dlgText = dialog.addText('\nPlease Select a EXCEL file to upload Ticket info data.');
    dlgText.displayHeight(3);

    exportGroup = dialog.addGroup('Export');

    dialogGroupControlExp       = dialog.formBuildDesign().control(exportGroup.formBuildGroup().id());
    exportTemplateButton        = dialogGroupControlExp.addControl(FormControlType::Button,'exportTemplateButton');

    exportTemplateButton.text("@SYS91539");
    exportTemplateButton.backgroundColor(10);
    exportTemplateButton.backStyle(5);
    exportTemplateButton.bold(15);
    exportTemplateButton.foregroundColor(7);

    return dialog;
}

public void dialogPostRun(DialogRunbase _dialog)
{
    super(dialog);

    _dialog.formRun().controlMethodOverload(true);
    _dialog.formRun().controlMethodOverloadObject(this);
}

protected void exportTemplate()
{
     #AviFiles
    SysOperationProgress progress1 = new SysOperationProgress();
    SysExcelApplication sysExcelApplication;
    SysExcelWorkbooks sysExcelWorkBooks;
   // FileName fileName = @'C:\\Desktop\\Mounting\\Mounting Journal.xlsx';
    SysExcelWorkbook sysExcelWorkBook;
    SysExcelWorkSheets sysExcelWorkSheets;
    SysExcelWorkSheet sysExcelWorkSheet;
    SysExcelWorksheet sysExcelWorkSheetToBeDeleted;
    SysExcelStyles styles;
    SysExcelStyle style;
    SysExcelFont font;
    SysExcelCells cells;

    int row = 1;
    boolean workSheetAdded = false;
    ;

    progress1.setCaption('Export To Excel in progress...');
    progress1.setAnimation(#AviTransfer);
    sysExcelApplication = SysExcelApplication::construct();
    sysExcelWorkBooks = sysExcelApplication.workbooks();
    sysExcelWorkBook = sysExcelWorkBooks.add();
    styles = sysExcelWorkBook.styles();
    style = styles.add('Header');

    font = style.font();
    font.bold(true);
    font.color(255);

    sysExcelWorkSheets = sysExcelWorkbook.worksheets();
    sysExcelApplication.visible(true);
    while(sysExcelWorkSheets.count() > 1)
    {
        sysExcelWorkSheetToBeDeleted = sysExcelWorkSheets.itemFromNum(2);
        sysExcelWorkSheetToBeDeleted.delete();
    }

    sysExcelWorkSheet = sysExcelWorkSheets.add(null,null,1);
    sysExcelWorkSheet.name('Ticket Uploader Template');

    sysExcelWorkSheet.cells().item(1,1).value('Ticket Type');
    sysExcelWorksheet.cells().item(1,2).value('Ticket sub type ID');
    //sysExcelWorksheet.cells().item(1,3).value('');
    sysExcelWorksheet.cells().item(1,4).value('Contract Id');
    sysExcelWorksheet.cells().item(1,5).value('Property Id');
    sysExcelWorksheet.cells().item(1,6).value('Move In Customer');
    sysExcelWorksheet.cells().item(1,7).value('Disconnection Date');
    sysExcelWorksheet.cells().item(1,8).value('DL Charge Date');
    sysExcelWorksheet.cells().item(1,9).value('Settlement Date');

    sysExcelWorksheet.rows().item(1).style('Header');
    {
        progress1.setText(strfmt("@BEL958"));

        sysExcelWorksheet.columns().autoFit();
        cells = sysExcelWorksheet.cells();
        cells.range('D2:D99').numberFormat('0,00');
        workSheetAdded = false;
    }
    sysExcelWorksheet.columns().autoFit();
    sysExcelApplication.displayAlerts(false);

}

public void exportTemplateButton_clicked()
{
    this.exportTemplate();
}

public static void main(Args _args)
{
    BEUploadTickets uploadsTicket = new BEUploadTickets();
    if(uploadsTicket.prompt())
    {
        BEUploadTickets::uploadandValidateData();
    }

}

private static void uploadandValidateData()
{
    For this please check the link how to import data from excel.
   https://dynamicszerotohero.blogspot.com/2020/04/x-import-data-from-excel-ax-2012.html

}















see the below image when you click on the Create Template button









Fill all the values in it and import the file.

Left Right String padding in X++

We will see how to add the character on the left side or the right side of string.
it is very simple for this we will use two functions.

For right side padding we use strLfix(str _str, int _lenght [, char _char])
For Left side padding we use strRfix(str _str, int _lenght [, char _char])


     str text = "Score";

    str leftPadding,rightpadding;
    // for right side padding we use strLFix function
    leftPadding = strLFix(text,strLen(text)+1,'s');
    info(strFmt("Right side padding result - %1",leftPadding));

     
    // for left side padding we use strRFix function
    rightpadding = strRFix(text,strLen(text)+1,'s');
     info(strFmt("Left side padding result- %1",rightpadding));


Wednesday, April 1, 2020

x++ Import data from excel ax 2012

In this post we check how to import data from excel in AX 2012 using X++.
we Import data from excel and check if the record exist in table then update the field otherwise print the excel row number which has failed.

static void UpdateOldProperty(Args _args)
{
    SysExcelApplication         application;
    SysExcelWorkbooks           workbooks;
    SysExcelWorkbook            workbook;
    SysExcelWorksheets          worksheets;
    SysExcelWorksheet           worksheet;
    SysExcelCells               cells;
    COMVariantType              type;

    FileName                    filename;
    int                         row =1; //ignore header row
    int                         i=0,failed=0;
    Dialog                      dialog;
    DialogField                 dialogField;
    BEProperties                properties,properties1;
    BEPropertyID                propertyID;
    BEOldPropertyID             OldPropertyID;
    ;

    application = SysExcelApplication::construct();
    workbooks = application.workbooks();
    dialog = new Dialog("FileOpen");
    dialogfield = dialog.addField(extendedTypeStr(Filenameopen), "File Name");
    dialog.run();

    if (dialog.run())
    {
        filename = (dialogfield.value());
    }
    try
    {
        workbooks.open(filename);
    }
    catch (Exception::Error)
    {
        throw error("File cannot be opened.");
    }
    workbook = workbooks.item(1);
    worksheets = workbook.worksheets();
    worksheet = worksheets.itemFromNum(1);
    cells = worksheet.cells();
    startLengthyOperation();
    do
    {
        row++;
        OldPropertyID = COMVariant2Str(cells.item(row,1).value());
        propertyID = BEProperties::find(COMVariant2Str(cells.item(row,2).value())).PropertyID;
        if(!propertyID)
        {
            info(strFmt("RowNo. %1, PropertyID %2, OldPropertyID %3",row,propertyID,OldPropertyID));
            failed++;
        }
        else
        {
            ttsBegin;
            select forUpdate properties1 where properties1.PropertyID == propertyID;
            properties1.OldPropertyID = OldPropertyID;
            properties1.update();
            ttsCommit;

            i++;
        }

        type = cells.item(row+1, 1).value().variantType();
    }

    while (type != COMVariantType::VT_EMPTY);
    workbook.close();
    application.quit();
    endLengthyOperation();
    info(strFmt("%1 Records Updated and %2 records failed",i,failed));
}

Monday, March 30, 2020

Hide Query Select button in ax 2012

In this blog post we will see how to Disable or  Hide the query select button using controller class.
override the  showQuerySelectButton method in controller class and just add ret = false;


public boolean showQuerySelectButton(str parameterName)
{
    boolean ret;


    ret = super(parameterName);

    ret = false; 

    return ret;
}

AX 2012 Roles Associated with current user Using X++

In this blog post we will will find the Security Role assigning to the particular user using X++ in AX 2012.

SecurityRole        role;
SecurityUserRole    userRole;
UserInfo            userinfo;

While select role
    exists join userRole
 where role.RecId == userRole.SecurityRole
  && userRole.User == curUserId()
    {
        info(role.Name );
       
    }


Wednesday, March 18, 2020

add address tab on custom form D365FO

In this post we see how to add address tab on custom form dynamics 365 finance and operation. The scenario was to add the tab on custom form same like as on customer or vendor form.

For this scenario we will look how to add the address tab.

Step 1: Create new table or add the DirPartyRecid on your table and make the relationship with DirPartyTable


















Step 2: Create new form or add MainTable and DirPartTable in form datasource




















Step 3: Set the properties on DirPartyTable datasource













Step 4: Add tab page on form and add form part control in it











Step 5: Set the properties on the form part control in the Menu Item Name set (LogisticsPostalAddressGridFormPart)



















Step 6: Add link and set the properties on it.







Step 7: See the results as shown below























Thursday, March 12, 2020

X++ Create and post Journal voucher

In this blog we will see how to write the job for Create and post Journal voucher in dynamics ax 2012.

static void legerDimCreateGLJournal(Args _args)
{
   AxLedgerJournalTable journalTable;
AxLedgerJournalTrans journalTrans;
container accCon;
container offSetCon;
LedgerJournalTable ledgerJournalTable;
ledgerJournalCheckPost ledgerJournalCheckPost;
;


journalTable = new AxLedgerJournalTable();
journalTrans = new AxLedgerJournalTrans();

//Journal Name
journalTable.parmJournalName("GenJrn");
journalTable.save();

journalTrans.parmJournalNum(journalTable.ledgerJournalTable().JournalNum);
journalTrans.parmTransDate(systemDateGet());
journalTrans.parmAccountType(LedgerJournalACType::Ledger);

accCon = ["110110","110110", 2, "BusinessUnit","001", "Department", "023"];
journalTrans.parmLedgerDimension(AxdDimensionUtil::getLedgerAccountId(accCon));

journalTrans.parmAmountCurDebit(20);

journalTrans.parmOffsetAccountType(LedgerJournalACType:: Ledger );
offSetCon = ["110110","110110", 2, "BusinessUnit","001", "Department", "024"];
journalTrans.clearField(fieldNum(LedgerJournalTrans, OffsetLedgerDimension), false);
journalTrans.parmOffsetLedgerDimension(AxdDimensionUtil::getLedgerAccountId( offSetCon));

journalTrans.save();

ledgerJournalCheckPost = ledgerJournalCheckPost::newLedgerJournalTable(journalTable.ledgerJournalTable(),NoYes::Yes);
ledgerJournalCheckPost.run();


info(strFmt("Journal No. %1.", journalTable.ledgerJournalTable().JournalNum));

}

Lookup for color Picker In Ax 2012

In this blog we will see how to make lookup for color picker in Dynamics Ax 2012. In a grid we will give the drop down for color picker.
  1. Make Int feild in Table 
  2. Add as a datasource of form 
  3. Overide Lookup Mehtrod of the Int feild 

Public void lookup()
{
    #DEFINE.COLORVALUE(64)
    Int r,g,b
    container choosencolor;
    Binary customcolors = new Binary(#COLORVALUE);
    CCColor colorvalue;

    Super();

    [r,g,b] = WinAPI::RGBint2Con(this.backgroundColor());

    chosenColor = WinAPI::chooseColor(element.hWnd(),r,g,b, customColors, true);

    If(chosencolor)
    {
        [r, g, b] = chosencolor;
        Colorvalue = WinAPI::RGB2int(r,g,b);
        This.backgroundColor(colorValue);
        employeeWorkPlannerForm.parmAbsensceColor(colorvalue);
        Employeetable.columns(employeeworkplannerform.numberofcolumns());
        Absenscecolorparm = colorvalue;
    }
}


X++ Create and post movement journal in AX 2012

static void createMovementJournalAx(Args _args)
{
InventJournalTable inventJournalTable;
InventJournalTrans inventJournalTrans;
InventJournalNameId inventJournalName;
InventDim inventDim;
JournalCheckPost journalCheckPost;

//Below code creates journal header
inventJournalTable.clear();
inventJournalName = InventJournalName::standardJournalName(InventJournalType::Movement);
inventJournalTable.initFromInventJournalName(InventJournalName::find(inventJournalName ));
inventJournalTable.insert();

//Below code creates journal lines
inventJournalTrans.clear();
inventJournalTrans.initFromInventJournalTable(inventJournalTable);
inventJournalTrans.TransDate = systemDateGet();
inventJournalTrans.ItemId = "L0001";
inventJournalTrans.initFromInventTable(InventTable::find("L0001"));
inventJournalTrans.Qty = 25;
inventDim.InventSiteId = '1';
inventDim.InventLocationId = '13';
inventDim.wMSLocationId = '13';
inventJournalTrans.InventDimId = inventDim::findOrCreate(inventDim).inventDimId;
inventJournalTrans.insert();


//The below code posts the journal
journalCheckPost = InventJournalCheckPost::newPostJournal(inventJournalTable);
journalCheckPost.run();
}

Sunday, March 8, 2020

Filter LocationID lookup by name D365FO

We will see how to filter location id by name.
Add new string in table and set any name is my case name is (InventLocation) as shown in image below




Create a new relation with InventLocation Table and set the relation properties.
























Create a new form for lookup set the design pattern Lookup - Basic. In data source add the IventLocation table.
Add grid in the form and add fields.












Override the form run method and write the code in it













Now add the field in original form to show the lookup. Override Lookup and resolveAmbiguousReference method on string control (A_Student_InventLocation)










Now write the code in lookup and resolveAmbiguousReference  method

Lookup Method














resolveAmbiguousReference  Method









After this build and sync the project and you will get appropriate result as shown below.
















For more information please see the following link
https://docs.microsoft.com/en-us/dynamics365/fin-ops-core/dev-itpro/user-interface/contextual-data-entry-lookups

Tuesday, March 3, 2020

Filter lookup By Name D365 Finance and Operation

Today, we will see how to filter record based on the name or description. By default this functionality is not enable on lookup. 
See the image below that is my default lookup.














When we write in the box student id, it automatically filter the record that the default behavior of any lookup. See the below Image.













But when we search from Name It shows nothing
To search with name we will set the Cache Lookup property on the Header table .



















Now, we are able to filter the lookup by name.













For more information please see the following link.