Tuesday 29 November 2016

AX 2012: Create a Batch Job through SysOperation Framework

How to extract Item master through batch job


In this post we’ll learn how to create a very basic custom Batch job using SysOperation framework. We’ll use the base controller class SysOperationServiceController and develop a custom service operation class to achieve the goal.
Requirement:
To create a Batch job to extract inventory on-hand and insert records into a custom table IDT_MaterialExtractionTMP, IDT_MaterialDefaultOrderSettingTMP & IDT_MaterialUnitConversionTMP.
Project overview:

The project shows how simple yet powerful the SysOperation framework is for developing custom batch jobs as opposed to RunBase framework since the minimum development needed to create a fully functional batch job is to create a custom service operation class defining a single method giving the implementation for the batch operation to be performed.
Development steps:
1. Create a service operation class IDT_MaterialExtractionBJobService having the following class declaration:

2. Create sub-methods in the class giving a suitable name like initFrom.... having the following definition:














3. Create a new method in the class giving a suitable name like processData having the following definition:

[ SysEntryPointAttribute(false) ]
public void processData()
{
    InventTable                 inventTable;
    int                         counter = 0;
    InventDimId                 inventDimId = "AllBlank";
    //SysTableBrowser             sysTableBrowser = new SysTableBrowser();
    //IDT_MaterialExtractionBJobService   IDT_MaterialExtractionBJobService.processData

    //Determines the runtime
    if (xSession::isCLRSession())
    {
        info('Running in a CLR session.');
    }
    else
    {
        info('Running in an interpreter session.');

        //Determines the tier
        if (isRunningOnServer())
        {
            info('Running on the AOS.');
        }
        else
        {
            info('Running on the Client.');
        }
    }

    delete_from materialExtractionTMPExt
        where materialExtractionTMPExt.ItemDataAreaId == curext();
    delete_from materialUnitConversionTMPExt
        where materialUnitConversionTMPExt.ItemDataAreaId == curext();
    delete_from materialDefaultOrderSettingTMPExt
        where materialDefaultOrderSettingTMPExt.ItemDataAreaId == curext();

    //materialExtractionTMP.clear();
    while select ItemId,NameAlias,dataAreaId,IDT_Quality_required,ItemBuyerGroupId,FSProductApprovalStatus,
                 PdsShelfLife,PrimaryVendorId,PmfProductType,PdsBestBefore,Product from inventTable
        where inventTable.NameAlias != "Obsolete"
        &&    inventTable.NameAlias != "Use to Depletion"
        &&    inventTable.FSProductApprovalStatus == FSProductApprovalStatus::Approved
    {
        ttsBegin;
        materialExtractionTMP.ItemId                    = inventTable.ItemId;
        materialExtractionTMP.NameAlias                 = inventTable.NameAlias;
        materialExtractionTMP.ItemName                  = inventTable.itemName();
        materialExtractionTMP.ItemDataAreaId            = inventTable.dataAreaId;
        materialExtractionTMP.IDT_Quality_Required      = inventTable.IDT_Quality_required;
        materialExtractionTMP.ItemBuyerGroupId          = inventTable.ItemBuyerGroupId;
        materialExtractionTMP.FSProductApprovalStatus   = inventTable.FSProductApprovalStatus;
        materialExtractionTMP.PdsShelfLife              = inventTable.PdsShelfLife;
        materialExtractionTMP.PrimaryVendorId           = inventTable.PrimaryVendorId;
        materialExtractionTMP.PmfProductType            = inventTable.PmfProductType;
        materialExtractionTMP.PdsBestBefore             = inventTable.PdsBestBefore;
        materialExtractionTMP.CostGroupId               = inventTable.CostGroupId;
        materialExtractionTMP.IDT_DrawingNumber         = inventTable.IDT_DrawingNumber;
        materialExtractionTMP.IDT_StorageTemperature    = inventTable.IDT_StorageTemperature;
        materialExtractionTMP.ProdPoolId                = inventTable.ProdPoolId;

        this.initFromInventItemLocation(inventTable, inventDimId);
        this.initFromInventItemGroupItem(inventTable);
        this.initFromInventModelGroupItem(inventTable);

        this.initFromEcoResTrackingDim(inventTable);
        this.initFromEcoResStorageDim(inventTable);

        this.initFromInventTableModule(inventTable);

        this.initFromInventItemSetupSupplyType(inventTable);
        this.initFromInventItemSetup(inventTable, inventDimId);
        this.initFromSiteSpecificOrderSettings(inventTable, inventDimId);

        this.initFromReqItemTable(inventTable);
        this.initFromUnitOfMeasureConversion(inventTable);
        this.initFromEcoResCategory(inventTable);
        this.initFromCustVendExternalItem(inventTable);

        materialExtractionTMP.insert();
        ttsCommit;
        //counter++;
    }
    //sysTableBrowser.run(tableNum(IDT_MaterialExtractionTMP));

}

4. Create a new Action type menu item IDT_MaterialExtractionBJobService  pointing to SysOperationServiceController.
5. Set the parameters of the action menu item to the service operation just created, IDT_MaterialExtractionBJobService .processData.

6. Compile the service operation class and generate incremental CIL.
7.Click on the action menu item to run the batch job. Check the Batch processing checkbox to run the job in CLR runtime which is the batch server execution environment.


8. Click System administration > Inquiries > Batch jobs to view the status of the job. You may also click on the Log button to view the messages written to infolog during the job execution.

AX 2012: Create a Batch Job through SysOperation Framework

How to extract Inventory on-hand through batch job

In this post we’ll learn how to create a very basic custom Batch job using SysOperation framework. We’ll use the base controller class SysOperationServiceController and develop a custom service operation class to achieve the goal.
Requirement:
To create a Batch job to extract inventory on-hand and insert records into a custom table IDT_InventOnhandExtractionTMP.
Project overview:

The project shows how simple yet powerful the SysOperation framework is for developing custom batch jobs as opposed to RunBase framework since the minimum development needed to create a fully functional batch job is to create a custom service operation class defining a single method giving the implementation for the batch operation to be performed.
Development steps:
1. Create a service operation class IDT_InventOnhandExtractionService having the following class declaration:

2. Create sub-methods in the class giving a suitable name like initFrom.... having the following definition:



3. Create a new method in the class giving a suitable name like processData having the following definition:

[ SysEntryPointAttribute(false) ]
public void processData()
{
    InventTable             inventTable;
    InventSum               inventSum;
    InventDim               inventDim;
    InventDimId             inventDimId = "AllBlank";
    //SysTableBrowser         sysTableBrowser = new SysTableBrowser();

    //Determines the runtime
    if (xSession::isCLRSession())
    {
        info('Running in a CLR session.');
    }
    else
    {
        info('Running in an interpreter session.');

        //Determines the tier
        if (isRunningOnServer())
        {
            info('Running on the AOS.');
        }
        else
        {
            info('Running on the Client.');
        }
    }

    delete_from inventOnhandExtractionTMPExt
        where inventOnhandExtractionTMPExt.ItemDataAreaId == curext();

    //inventOnhandExtractionTMP.clear();
    while select ItemId,Closed,ClosedQty,InventDimId,PhysicalInvent from inventSum
        join ItemId,NameAlias,dataAreaId,Product from inventTable
            where inventSum.ItemId      == inventTable.ItemId
            &&    inventSum.Closed      == NoYes::No
            &&    inventSum.ClosedQty   == NoYes::No
            &&    inventSum.PhysicalInvent > 0
            &&    inventTable.NameAlias != "Obsolete"
            &&    inventTable.NameAlias != "Use to Depletion"
    {
        ttsBegin;
        inventOnhandExtractionTMP.ItemId                = inventSum.ItemId;
        inventOnhandExtractionTMP.NameAlias             = inventTable.NameAlias;
        inventOnhandExtractionTMP.ItemName              = inventTable.itemName();
        inventOnhandExtractionTMP.ItemDataAreaId        = inventTable.dataAreaId;
        inventOnhandExtractionTMP.PhysicalInvent        = inventSum.PhysicalInvent;

        inventDim = InventDim::find(inventSum.InventDimId);
        inventOnhandExtractionTMP.InventSiteId          = inventDim.InventSiteId;
        inventOnhandExtractionTMP.InventLocationId      = inventDim.InventLocationId;
        inventOnhandExtractionTMP.wmsLocationId         = inventDim.wMSLocationId;
        inventOnhandExtractionTMP.InventBatchId         = inventDim.inventBatchId;

        this.initFromInventItemGroupItem(inventSum);
        this.initFromInventTableModule(inventSum);
        this.initFromInventBatch(inventSum, inventOnhandExtractionTMP.InventBatchId);

        inventOnhandExtractionTMP.insert();
        ttsCommit;
        //counter++;
    }
    //sysTableBrowser.run(tableNum(IDT_MaterialExtractionTMP));
}

4. Create a new Action type menu item IDT_InventOnhandExtractionService pointing to SysOperationServiceController.
5. Set the parameters of the action menu item to the service operation just created, IDT_InventOnhandExtractionService.processData.

6. Compile the service operation class and generate incremental CIL.
7.Click on the action menu item to run the batch job. Check the Batch processing checkbox to run the job in CLR runtime which is the batch server execution environment.


8. Click System administration > Inquiries > Batch jobs to view the status of the job. You may also click on the Log button to view the messages written to infolog during the job execution.

Happy DAXing...

SSRS Report header (Company name, Page number and current date & time)

How to display company name, Page number and current (print) date & time in SSRS header.

expression for Company name:

=Microsoft.Dynamics.Framework.Reports.DataMethodUtility.GetFullCompanyNameForUser(Parameters!AX_CompanyName.Value, Parameters!AX_UserContext.Value)

Expression for page number

=System.String.Format(Labels!@SYS182565, Globals!PageNumber & space(2) & Labels!@sys26401 & space(2) & Globals!TotalPages)

Expression for Print date & time.

=Microsoft.Dynamics.Framework.Reports.DataMethodUtility.ConvertUtcToAxUserTimeZoneForUser(Parameters!AX_CompanyName.Value, Paraemeters!AX_UserContext.Value, System.DateTime.UtcNow, "d", Parameters!AX_RenderingCulture.Value) & vbCrLf & Microsoft.Dynamics.Framework.Reports.DataMethodUtility.ConvertUtcToAxUserTimeZoneForUser(Parameters!AX_CompanyName.Value, Parameters!AX_UserContext.Value, System.DateTime.UtcNow, "t", Parameters!AX_RenderingCulture.Value)


Happy DAXing....