Category Archives: X++

The best way to pass records to a class

This is the best method to pass the selected records from a Form to a Class

static void Main(Args args)
{
    MultiSelectionHelper    multiSelectionHelper;
    AssetTable              AssetTable;
    ;

    multiSelectionHelper = MultiSelectionHelper::createFromCaller(args.caller());
    assetTable  = multiSelectionHelper.getFirst();
    while (assetTable)
    {
        info(assetTable.AssetId);
        assetTable = multiSelectionHelper.getNext();
    }
}

MultiSelectionHelper class helps to iterate into selected records.
If you are using args object on your target class consider to use the method:

multiSelectionHelper.parmCacheRecords(true);

How to get SalesLine record from ReqTrans table using X++ AX 2012

Add these two methods to the ReqTrans table

public SalesLine getSalesLine(ReqTrans _reqTrans)
{
    ReqTrans        reqTrans_Settle,reqTrans_next;
    SalesLine       salesLine;
    ;
    reqTrans_Settle = _reqTrans.getSettleTrans();
    do
    {
        select reqTrans_next
            where reqTrans_next.RefId == reqTrans_Settle.RefId
               && reqTrans_next.Direction == InventDirection::Receipt;
        if (!reqTrans_next)
        {
            break;
        }
        reqTrans_Settle = reqTrans_next.getSettleTrans();
    }
    while(reqTrans_next);
 
    if(reqTrans_Settle.RefType == ReqRefType::Sales)
    {
        salesLine = SalesLine::findInventTransId(InventTransOrigin::find(reqTrans_Settle.InventTransOrigin).InventTransId);
    }
 
    return salesLine;
}
 
private ReqTrans getSettleTrans()
{
    ReqTrans    reqTrans_Settle;
    ReqTransCov reqTransCov;
    ;
 
    switch(this.Direction)
    {
        case InventDirection::Issue:
                select reqTransCov
                    where reqTransCov.IssueRecId == this.RecId;
 
                reqTrans_Settle = reqTrans::findRecId(reqTransCov.ReceiptRecId);
            break;
 
        case InventDirection::Receipt:
                select reqTransCov
                    where reqTransCov.ReceiptRecId == this.RecId;
 
                reqTrans_Settle = reqTrans::findRecId(reqTransCov.IssueRecId);
            break;
 
    }
 
    return reqTrans_Settle;
}

[AX 2012 R3] How to get avail quantity of a product by ItemId and get details by inventory dimensions (InventDimId)

 InventDimOnHand onHand;
 InventDimOnHandIterator iter;
 InventDimOnHandMember member;
 InventOnhand inventOnhand;
 ItemId itemId;
 InventDim inventDimCrit;
 InventDimParm inventDimParmCrit, inventDimParmOnHandLevel;
 InventDim inventDim;
 InventDimOnHandLevel level;
 ;

 itemId = '123456';

 // Known dimensions
 inventDimCrit.wMSLocationId = 'location01';
 inventDimCrit = InventDim::findOrCreate(inventDimCrit);

 // Determine which of the known dimensions to use
 inventDimParmCrit.WMSLocationIdFlag = true;

 level = InventDimOnHandLevel::DimParm;

 // Determines the level of detail returned
 inventDimParmOnHandLevel.ItemIdFlag = true;
 inventDimParmOnHandLevel.InventLocationIdFlag = true;
 inventDimParmOnHandLevel.WMSLocationIdFlag = true;
 inventDimParmOnHandLevel.InventBatchIdFlag = true;

 onHand = InventDimOnHand::newPhysicalArrived(itemId, inventDimCrit, InventDimParmCrit, level, inventDimParmOnHandLevel);

 iter = onHand.onHandIterator();
 while (iter.more())
 {
 member = iter.value();
 inventDim = InventDim::find(member.parmInventDimId());
 inventDimParmOnHand.initFromInventDim(inventDim);
 inventOnHand = InventOnhand::newParameters(itemId, inventDim,inventDimParmOnHand);
 info(con2str([member.parmItemId(), inventDim.inventLocationId, inventDim.inventBatchId, inventDim.LicensePlateId, inventDim.inventSerialId, member.parmInventQty(), inventOnHand.availPhysical()]));

 iter.next();
 }

 info('Done'); 

[AX 2012 R3] How to get product color description

We want to display the description of a dimension (in this case the colour) of a product

We just need the ItemId and InventColorId

productAx

static void GetColorDescription(Args _args)
{
 ItemId ItemId = "123456789"; //Change with your ItemId
 EcoResProductMasterColor EcoResProductMasterColor;
 EcoResProductMasterDimensionValue EcoResProductMasterDimensionValue;
 EcoResColor EcoResColor;
 EcoResProductMaster EcoResProductMaster;
 EcoResProductMasterDimValueTranslation EcoResProductMasterDimValueTranslation;
 
 EcoResColorName EcoResColorName = InventDim::find("InventDimId").InventColorId; 

 select * from EcoResProductMasterDimValueTranslation
 join RecId from EcoResProductMasterDimensionValue
 where EcoResProductMasterDimValueTranslation.ProductMasterDimensionValue
 == EcoResProductMasterDimensionValue.RecId
 join RecId from EcoResProductMasterColor
 where EcoResProductMasterDimensionValue.RecId == EcoResProductMasterColor.RecId
 join RecId from EcoResColor
 where EcoResColor.RecId == EcoResProductMasterColor.Color
 && EcoResColor.Name == EcoResColorName
 join RecId from EcoResProductMaster
 where EcoResProductMasterColor.ColorProductMaster == EcoResProductMaster.RecId
 && EcoResProductMaster.DisplayProductNumber == ItemId;

 info(EcoResProductMasterDimValueTranslation.Name);
}

In case you don’t have any translaction
ax2012r3_product_with_no_translation
the object EcoResProductMasterDimValueTranslation.Name will be empty, so you can retrive the Deault value using this code:

static void GetColorDescription(Args _args)
{
 ItemId ItemId = "123456789"; //Change with your ItemId
 EcoResProductMasterColor EcoResProductMasterColor;
 EcoResProductMasterDimensionValue EcoResProductMasterDimensionValue;
 EcoResColor EcoResColor;
 EcoResProductMaster EcoResProductMaster;
 EcoResProductMasterDimValueTranslation EcoResProductMasterDimValueTranslation;
 
 EcoResColorName EcoResColorName = InventDim::find("InventDimId").InventColorId; 

 select * from EcoResProductMasterDimValueTranslation
 join RecId from EcoResProductMasterDimensionValue
 where EcoResProductMasterDimValueTranslation.ProductMasterDimensionValue
 == EcoResProductMasterDimensionValue.RecId
 join RecId from EcoResProductMasterColor
 where EcoResProductMasterDimensionValue.RecId == EcoResProductMasterColor.RecId
 join RecId from EcoResColor
 where EcoResColor.RecId == EcoResProductMasterColor.Color
 && EcoResColor.Name == EcoResColorName
 join RecId from EcoResProductMaster
 where EcoResProductMasterColor.ColorProductMaster == EcoResProductMaster.RecId
 && EcoResProductMaster.DisplayProductNumber == ItemId;

if(EcoResProductMasterDimValueTranslation.Name)
{
info(EcoResProductMasterDimValueTranslation.Name);
}
else
{
EcoResProductMasterDimValueTranslation = EcoResProductMasterDimValueTranslation::getNameOrDefaultName(EcoResProductMasterDimensionValueId, SystemParameters::getSystemLanguageId()); info(EcoResProductMasterDimValueTranslation.Name);
info(EcoResProductMasterDimValueTranslation.Name);
}

AX2012 R2: Failed to create a session

I retrive in AX2012 R2 the foolowing error when I sync the DB or when I try to load a queque of batch jobs:

Failed to create a session; confirm that the user has the proper privileges to log on to Microsoft Dynamics

A closer look into this learned that this is linked to the new partitions feature.

It seems the UserInfo table is not correctly updated and the partition administrator is not updated correctly when you restore an existing DB or the Demo database.
To fix this, you can do the following.

Stop the AOS
Restore the database again
Start the AOS
Start a client and complete the partition initialiasation checklist
Close the client and execute the script below on the SQL database
Restart the client and reimport your license (if you were restoring the Microsoft demo data, the demo license is back in there)
Then compile / generate CIL / DB sync and you should be on track again!
The script for updating the UserInfo inforation is as follows:

How to find by X++ code On Hand Stock for an Item

The example below show how to find On Hand Stock quantity for and Item

Error when generating CIL on AX 2012

When you run a Full CIL or an Incremental CIL and the system returns this error:

CIL generation: The given key was not present in the dictionary

You must navigate this path: C:Program FilesMicrosoft Dynamics AX60Server<AOS ISTANCE NAME>binXppIL

and open the file: Dynamics.Ax.Application.dll.log

here you can see error like this:

Finished pass 1 at 28/10/2013 09:12:55
Error when loading the method. Type: TaxSalesShippingBill_IN, Method: new
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary

Now you must correct all exceptions and recompile the objects

Executing SQL statements from X++

Example #1: Retrieve data:

Example #2: Edit data (delete):

How to get day month year from date in AX X++

Get field label in X++

With this little example we can get the Label assigned to Field Table