12 March 2020

How to get MainAccount using ledger dimension recId in ax 2012

In the below code have to pass ledgerDimension recId to get the main account Id.

Table.MainAccountId             =   MainAccount::findByLedgerDimension(ledgerDimension).MainAccountId;

01 March 2020

How to extend standard report (Purchase order report ) in D365 F&O using print management / Report extension in D365

Dynamics Ax 365 SSRS: How to call new Report/Design for existing Print management report

To get the report format in the setup Print management setup:
Need to create extension for the PrintMgmtReportFormatPopulator->addDocuments()
Need to add the new report to get the report in the configuration

Step1. Duplicate the PurchPurchaseOrder standard Report as PurchPurchaseOrderADD
Step2. Go to PrintMgmtDocType class and copy the eventHandler delegate method called getDefaultReportFormatDelegate
Step3. Create new class "PrintMgmtDelegatesHandler_Test" and paste the eventHandler.

below is reference code. To execute the report different designs per each legal entity.

Once we done this - Need to go to AP-Setup-Forms->Form setup -> Print Management button then in that form have to select the that related Purchase order report in the dropdown.



class PrintMgmtDelegatesHandler_Test
{
    /// <summary>
    ///
    /// </summary>
    /// <param name="_docType"></param>
    /// <param name="_result"></param>
    [SubscribesTo(classStr(PrintMgmtDocType), delegateStr(PrintMgmtDocType, getDefaultReportFormatDelegate))]
    public static void PrintMgmtDocType_getDefaultReportFormatDelegate(PrintMgmtDocumentType _docType, EventHandlerResult _result)
    {
        PrintMgmtReportFormatName formatName = PrintMgmtDelegatesHandler_Test::getDefaultReportFormat(_docType);
        if (formatName)
        {
            _result.result(formatName);
        }
    }

    private static PrintMgmtReportFormatName getDefaultReportFormat(PrintMgmtDocumentType _docType)
    {

        switch (_docType)
        {
            case PrintMgmtDocumentType::PurchaseOrderRequisition:
                {
                    if(curExt() == "USMF")
                    {
                        return ssrsReportStr(PurchPurchaseOrderADD, Report);
                    }
                    if(curExt() == "RUMF")
                    {
                        return ssrsReportStr(PurchPurchaseOrderADD, ReportRU);
                    }

                }
            case PrintMgmtDocumentType::PurchaseOrderConfirmationRequest:
                {
                    if(curExt() == "USMF")
                    {
                        return ssrsReportStr(PurchPurchaseOrderADD, Report);
                    }
                    if(curExt() == "RUMF")
                    {
                        return ssrsReportStr(PurchPurchaseOrderADD, ReportRU);
                    }
                }
        }
        return '';
    }

}

Need to execute the below job to populate new report design in the Print management setup Table(PrintMgmtReportFormat) can open see new report is inserted in this table or not after executing below populate method.

class PrintPopulateReportFormat
{
    public static void main(Args _args)
    {
        PrintMgmtReportFormatSubscriber::populate();
        
    }
}

18 December 2019

From date and toDate query ranges in Report and form X++ code in AX 2012

Below logic can be used for filtering using from date and to date.

dateRange.value(SysQuery::range(FromDate.dateValue(), ToDate.dateValue()));

Form level in the execute query can write the below logic.

QueryBuildRange dateRange = SysQuery::findOrCreateRange(this.queryBuildDataSource(), fieldNum(MyTable, MyDateField));

26 November 2019

SysOperation frame work in D365 F&O example with batch job

class TRGBatchService extends SysOperationServiceBase { /// <summary> /// /// </summary> /// //[SysEntryPoint(false)] private void processCode() { Info("Test"); } }

class TRGBatchController extends sysOperationServiceController
{
  public static void main(Args args)
    {
        TRGBatchController controller = new TRGBatchController(classStr(TRGBatchService),methodStr(TRGBatchService,processCode),SysOperationExecutionMode::Synchronous);
        controller.startOperation();
    }

    /// <summary>
    ///
    /// </summary>
    /// <returns></returns>
    public ClassDescription caption()
    {
        ClassDescription ret;
    
        ret ="Operation batch job";
    
        return ret;
    }


}

14 November 2019

Sequence of methods in the FORM level in AX / Form opening sequences in AX 2012 D365


Sequence of methods in the FORM level in AX / Form opening sequences in AX 2012 D365

Sequence of Methods calls while opening the Form
Form --- init ()
Form --- Datasource --- init ()
Form --- run ()
Form --- Datasource --- execute Query ()
Form --- Datasource --- active ()


Sequence of Method calls while saving the record in the Form
Form --- Datasource --- ValidateWrite ()
Table --- ValidateWrite ()
Form --- Datasource --- write ()
Table --- insert ()

Sequence of Methods calls while creating the record in the Form
Form --- Datasource --- create ()
Form --- Datasource --- initValue ()
Table --- initValue ()
Form --- Datasource --- active ()

Sequence of Methods calls while closing the Form
Form --- canClose ()
Form --- close ()


Sequence of Methods calls while modifying the fields in the Form
Table --- validateField ()
Table --- modifiedField ()

Sequence of Method calls while deleting the record in the Form
Form --- Datasource --- validatedelete ()
Table --- validatedelete ()
Table --- delete ()
Form --- Datasource --- active ()



17 October 2019

BOM Explode X++ logic in AX 2012 D365 FO

class BOMExplode
{
    date                        _date = mkDate(22,09,2019);
    void itemExplode(ItemId _ItemId, int _level = 0, BOMQty _bomQty = 1)
    {
        BOM                         bomTable;
        BOMVersion                  bomVersion;
        boolean                     enable;
        InventTestVariableId        cvQualityGroupId;
        Level                       level = _level;
       
        while select bomVersion
            where bomVersion.ItemId == _itemid
                && bomVersion.Active
                && bomVersion.FromDate <= _date//DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone())
                && (!bomVersion.ToDate || bomVersion.ToDate >= _date)//DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()))
        {
            if (bomVersion.RecId)
            {
                While select bomTable
                    where bomTable.BOMId == bomVersion.BOMId
                {
                    Info(strFmt("Parent Item: %1 Part Number: %2 Quantity: %3, Level: %4 ",bomVersion.ItemId,bomTable.ItemId, bomTable.bomQty,level));
                    if (this.hasChild(bomTable.ItemId))
                    {
                        this.itemExplode(bomTable.ItemId, level + 1, bomTable.BOMQty);
                    }
                }
            }
        }
    }

    boolean hasChild(ItemId _itemId)
    {
        BOMVersion  bomVersion;
        boolean     ret = false;

        select firstonly bomVersion
            where bomVersion.ItemId == _itemid
                && bomVersion.Active
                && bomVersion.FromDate <= _date//DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone())
        && (!bomVersion.ToDate || bomVersion.ToDate >= _date);//DateTimeUtil::getSystemDate(DateTimeUtil::getUserPreferredTimeZone()));

        if (bomVersion.RecId)
        {
            ret = true ;
        }

        return ret;
    }

    public static void Main(Args args)
    {
        BOMExplode bomExplode = new BOMExplode();

        bomExplode.itemExplode("A20HBA06B7");

    }

}

Service class to get the selected record and deleted matching records and refresh the form data source in D365 F&O

 [DataContractAttribute] class ABCUserProfilesBulkDeleteContract {         UserId userId;     [DataMemberAttribute('UserId')]     pu...