Thursday 1 October 2015

How to get/ fetch Sales Price (SalesPrice) from sales Trade agreement in AX 2012

Hi Guys,
Now a days I am working on Interfaces like Import order from xml into AX 2012 Sales order so here, I will share with you the logic for picking Sales price from trade agreement in ax 2012.

Firstly, I tested the values through a job, like:
static void priceFromAgreement(Args _args)
{
    PriceDiscTable      priceDiscTable;
    //PriceDiscAdmTrans   _trans;
    ItemId              itemRelation = "021-08221";
    CustAccount         accountRelation = "1652-000007";
    real                salesPrice1, salesPrice2, salesPrice3;
    PriceType           relation = PriceType::PriceSales;
    NoYes               _RelationExist = NoYes::No;

    /// First if  trade agreement exist for Item for customer
    select firstonly priceDiscTable
        where priceDiscTable.Relation           == relation
           && priceDiscTable.ItemCode           == TableGroupAll::Table
           && priceDiscTable.ItemRelation       == itemRelation
           && priceDiscTable.AccountCode        == TableGroupAll::Table
           && priceDiscTable.AccountRelation    == accountRelation;

    salesPrice1 = priceDiscTable.Amount;
    info(strFmt("salesPrice1: %1", salesPrice1));

    if (priceDiscTable !=null)
    {
        info(strFmt("found Price1: %1", priceDiscTable.Amount));
    }

    // trade agreement exist for particular item for particular customer
    select firstonly priceDiscTable
        where priceDiscTable.Relation           == relation
           && priceDiscTable.ItemCode           == TableGroupAll::Table
           && priceDiscTable.ItemRelation       == itemRelation
           && priceDiscTable.AccountCode        == TableGroupAll::GroupId
           && priceDiscTable.AccountRelation    == "ROC";

    salesPrice2 = priceDiscTable.Amount;
    info(strFmt("salesPrice2: %1", salesPrice2));

    if (priceDiscTable !=null)
    {
        info(strFmt("found Price2: %1", priceDiscTable.Amount));
    }

    // third possibility is that when Customer have to all product with same price of amount.
    select firstonly priceDiscTable
        where priceDiscTable.Relation           == relation
           && priceDiscTable.ItemCode           == TableGroupAll::Table
           && priceDiscTable.ItemRelation       == itemRelation
           && priceDiscTable.AccountCode        == TableGroupAll::All
           && priceDiscTable.AccountRelation    == " ";

    salesPrice3 = priceDiscTable.Amount;
    info(strFmt("salesPrice3: %1", salesPrice3));

    if (priceDiscTable !=null)
    {
        info(strFmt("found Price3: %1", priceDiscTable.Amount));
    }
}


Now testing is done, we can start our development, Steps are as:

Step-1: Create one method to find PriceDiscTable object

public static PriceDiscTable findPriceDiscTable(PriceDiscAccountCode        _accountCode,
                                                PriceDiscAccountRelation    _accountRelation,
                                                PriceDiscItemCode           _itemCode,
                                                PriceDiscItemRelation       _itemRelation)
{
    PriceDiscTable      priceDiscTable;
    InventSiteId        inventSiteId;
    PriceType           relation = PriceType::PriceSales;

    inventSiteId = InventDim::find(priceDiscTable.InventDimId).InventSiteId;

    select firstonly priceDiscTable
        where priceDiscTable.Relation           == relation
           && priceDiscTable.AccountCode        == _accountCode
           && priceDiscTable.AccountRelation    == _accountRelation
           && priceDiscTable.ItemCode           == _itemCode
           && priceDiscTable.ItemRelation       == _itemRelation
           && priceDiscTable.ToDate             == dateNull();

    return priceDiscTable;
}

Step-2: Create another method to specify scenarios (cases) which may be described and will run on the basis of that trade agreement. Create cases as required as:

public static PriceDiscTable checkPriceDiscTable(PriceDiscAccountRelation    _accountRelation,
                                                 PriceDiscItemRelation       _itemRelation)
{
    PriceDiscTable              priceDiscTableRec;
    TableGroupAll               accountCode, ItemCode;
    PriceDiscAccountRelation    accountRelation;
    PriceDiscItemRelation       itemRelation;

    int     totalcases = 3;
    int     prioritycase = 0;

    while(prioritycase < totalcases)
    {
        switch (priorityCase)
        {
            case 0:
                accountCode         = TableGroupAll::Table;
                accountRelation     = _accountRelation;
                itemCode            = TableGroupAll::Table;
                itemRelation        = _itemRelation;

                priceDiscTableRec = MSSalesInterfaceLaffvlo::findPriceDiscTable(accountCode, accountRelation,
                                                                                itemCode, itemRelation);
                if(priceDiscTableRec.recId)
                {
                    return priceDiscTableRec;
                }
                break;

            case 1:
                accountCode         = TableGroupAll::GroupId;
                accountRelation     = _accountRelation;
                itemCode            = TableGroupAll::Table;
                itemRelation        = _itemRelation;

                priceDiscTableRec = MSSalesInterfaceLaffvlo::findPriceDiscTable(accountCode, accountRelation,
                                                                                itemCode, itemRelation);
                if(priceDiscTableRec.recId)
                {
                    return priceDiscTableRec;
                }
                break;

            case 2:
                accountCode         = TableGroupAll::All;
                accountRelation     = " ";
                itemCode            = TableGroupAll::Table;
                itemRelation        = _itemRelation;

                priceDiscTableRec = MSSalesInterfaceLaffvlo::findPriceDiscTable(accountCode, accountRelation,
                                                                                itemCode, itemRelation);
                if(priceDiscTableRec.recId)
                {
                    return priceDiscTableRec;
                }
                break;
        }
        prioritycase++;
    }

    return priceDiscTableRec;
}


Step-3: Add logic in Insert method from where values are getting inserted....

public static void insertLaffvloLineData(Container _value, MSSalesTable _mSSalesTable)
{
    MSSalesLine         salesline;
    InventTable         inventTable;
    InventDim           inventDim, inventDimLoc;
    PriceDiscTable      priceDiscTable;

    salesline.ItemId        = conPeek(_value, 22);
    salesline.ProductId     = conPeek(_value, 22);
    salesline.ProductName   = conPeek(_value, 7);
    salesline.Qty           = conPeek(_value, 9);
    salesline.CurrencyCode  = _mSSalesTable.CurrencyCode;
    salesline.MSSalesTable  = _mSSalesTable.RecId;  
 
    inventTable             = InventTable::find(salesline.ItemId);
    inventDim.InventSiteId  = inventTable.inventItemSalesSetup().inventDim().InventSiteId;
    inventDimLoc            = InventDim::findOrCreate(inventTable.inventItemSalesSetup().inventDim());

    priceDiscTable = MSSalesInterfaceLaffvlo::checkPriceDiscTable(_mSSalesTable.CustAccount, salesline.ItemId);
    salesline.SalesPrice = priceDiscTable.Amount;
 
    /*salesline.SalesPrice   = conPeek(PriceDisc::findItemPriceAgreement(ModuleInventPurchSales::Sales,
                                        salesline.ItemId,
                                        inventdim,
                                        "EA",
                                        today(),
                                        salesline.Qty,
                                       _mSSalesTable.CustAccount,
                                        'USD',
                                        CustTable::find(_mSSalesTable.CustAccount).PriceGroup), 1);*/

    if (!salesline.SalesPrice)
    {
        salesline.SalesPrice = InventItemPrice::findCurrent(salesline.ItemId,
                                                            CostingVersionPriceType::Sales,
                                                            inventdim.InventDimId,
                                                            today(),
                                                            inventdim.InventSiteId).Price;

        if (!salesline.SalesPrice)
            salesline.SalesPrice = InventTable::find(salesline.ItemId).salesPcsPrice();
    }

    salesline.LineAmount = salesline.Qty * salesline.SalesPrice;

    salesline.insert();
}


Note: Yeah, let me clear you on the SalesPrice scenarios

  1. If Trade agreement is created what we need then it should be 1st priority to fetch price from there
  2. If not then SalesPrice should be picked from Costing Version
  3. If not then lastly, SalesPrice should be picked up from Item base price (Item master- released products)
I tried to clarify from my best.

Thanx.
Happy DAXing.....

2 comments: