Thursday 26 January 2017

Set Delivery Address on Sales order through code X++ AX 2012

In this post we will learn how to set delivery address / over rider the default customer delivery address on a Sales order.

This method will return the  LogisticsPostalAddress recId, which we will assign to parm method of AXsalesTable class..
axsalesTable.parmDeliveryPostalAddress(this.setDeliveryAddress(_tmpSalesheaders));
private RecId setDeliveryAddress(TmpSalesTable           _tmpSalesheaders)
{
    DirPartyPostalAddressView   addressView, ret;
    DirPartyRecId                        partyRecId;
    DirParty                                 dirParty;
    LogisticsPostalAddress          postalAddress;
    ;
    //Create new Name
    partyRecId = DirPartyTable::createNew(DirPartyType::None, _tmpSalesheaders.DeliveryName).RecId;
   
    addressView.CountryRegionId = _tmpSalesheaders.DeliveryCountryRegionId;//"AUS";
    addressView.State = _tmpSalesheaders.DeliveryState;//"VIC";
    addressView.ZipCode = _tmpSalesheaders.DeliveryZipCode;//"3000";
    addressView.Street  = _tmpSalesheaders.DeliveryStreet;//"238 Flinders St";
    addressView.Party = partyRecId;
   
    //Handel errors for addresses
    if (!LogisticsAddressCountryRegion::exist(addressView.CountryRegionId))
        throw error(strFmt("@SYS9347",addressView.CountryRegionId));
    if (addressView.County && !LogisticsAddressCounty::exist(addressView.CountryRegionId, addressView.State, addressView.County))
        throw error(strFmt("@SYS72719",addressView.County));
    if (addressView.State && !LogisticsAddressState::exist(addressView.CountryRegionId, addressView.State))
        throw error(strFmt("@SYS72786",addressView.State));
    if (!LogisticsAddressZipCode::exist(addressView.ZipCode))
        throw error(strFmt("@SYS24626",addressView.ZipCode));

    addressView.Party  = partyRecId;
    if( addressView.Street || addressView.ZipCode || addressView.City || addressView.State || addressView.CountryRegionId)
    {
        DirParty = DirParty::constructFromPartyRecId(addressView.Party );
        ret = DirParty.createOrUpdatePostalAddress(addressView);
        postalAddress = LogisticsPostalAddress::findByLocation(ret.Location);
    }
    return postalAddress.RecId;
}

Monday 23 January 2017

X++ code to copy Ledger from company (A) to Company (B)


public void copyLedgerSetup()
{
    Ledger   fromLedger = Ledger::findByLegalEntity(CompanyInfo::findDataArea(fromCompany).RecId);
    Ledger   toLedger   = Ledger::findByLegalEntity(CompanyInfo::findDataArea(toCompany).RecId);
    LedgerStructure fromLedgerStructure, toLedgerStructure;
    LedgerGainLossAccount fromLedgerGainLossAccount, toLedgerGainLossAccount;

    if (fromLedger && !toLedger)
    {
        toLedger.data(fromLedger);
        toLedger.PrimaryForLegalEntity = CompanyInfo::findDataArea(toCompany).RecId;
        toLedger.Name = toCompany;
        toLedger.doInsert();

        while select fromLedgerStructure
            where fromLedgerStructure.Ledger == fromLedger.RecId
        {
            toLedgerStructure.data(fromLedgerStructure);
            toLedgerStructure.Ledger = toLedger.RecId;
            toLedgerStructure.insert();
        }

        while select fromLedgerGainLossAccount
            where fromLedgerGainLossAccount.Ledger == fromLedger.RecId
        {
            toLedgerGainLossAccount.data(fromLedgerGainLossAccount);
            toLedgerGainLossAccount.Ledger = toLedger.RecId;
            toLedgerGainLossAccount.insert();
        }
    }
}

X++ code to copy Number sequence from one company(A) to other (B)

public void copyNumberSequence()
{
    NumberSequenceScope         fromNumberSequenceScope, toNumberSequenceScope;
    NumberSequenceTable         fromNumberSequenceTable, toNumberSequenceTable;
    NumberSequenceReference     fromNumberSequenceReference, toNumberSequenceReference;
    //mk
    Map                         mapKeyValue;
    MapEnumerator               enumer;
    MapIterator                 mapIter;
    int64                       iCurrentKey;
    int64                       sCurrentValue;

    while select fromNumberSequenceScope
        where (fromNumberSequenceScope.LegalEntity == CompanyInfo::findDataArea(fromCompany).RecId ||
              fromNumberSequenceScope.DataArea == fromCompany)
    {
        try
        {
            ttsBegin;
            toNumberSequenceScope = NumberSequenceScope::findByNaturalKey(
                                        toCompany,
                                        CompanyInfo::findDataArea(toCompany).RecId,
                                        fromNumberSequenceScope.OperatingUnit,
                                        fromNumberSequenceScope.FiscalCalendarPeriod,
                                        fromNumberSequenceScope.OperatingUnitType);

            if ((fromNumberSequenceScope.LegalEntity || fromNumberSequenceScope.DataArea) && !toNumberSequenceScope)
            {
                toNumberSequenceScope.clear();
                toNumberSequenceScope.data(fromNumberSequenceScope);
                if (toNumberSequenceScope.LegalEntity)
                {
                    toNumberSequenceScope.LegalEntity = CompanyInfo::findDataArea(toCompany).RecId;
                }
                if (toNumberSequenceScope.DataArea)
                {
                    toNumberSequenceScope.DataArea = toCompany;
                }
                toNumberSequenceScope.insert();
                mapKeyValue = null;
                mapKeyValue = new Map(Types::Int64,Types::Int64); //mk

                while select fromNumberSequenceTable
                    where fromNumberSequenceTable.NumberSequenceScope == fromNumberSequenceScope.RecId
                {
                    if (!NumberSequenceTable::findByNaturalKey(fromNumberSequenceTable.NumberSequence, toNumberSequenceScope.RecId))
                    {
                        toNumberSequenceTable.clear();
                        toNumberSequenceTable.data(fromNumberSequenceTable);
                        toNumberSequenceTable.NumberSequenceScope = toNumberSequenceScope.RecId;
                        toNumberSequenceTable.NextRec = toNumberSequenceTable.Lowest;
                        toNumberSequenceTable.insert();
                        if (!mapKeyValue.exists(fromNumberSequenceTable.RecId))
                        {
                            mapKeyValue.insert(fromNumberSequenceTable.RecId,toNumberSequenceTable.RecId); //mk
                        }
                    }
                }
                enumer = null;
                while select fromNumberSequenceReference
                    where fromNumberSequenceReference.NumberSequenceScope == fromNumberSequenceScope.RecId
                {
                    if (!NumberSequenceReference::findNaturalKey(toNumberSequenceScope.RecId, fromNumberSequenceReference.NumberSequenceDatatype))
                    {
                        toNumberSequenceReference.clear();
                        toNumberSequenceReference.data(fromNumberSequenceReference);
                        toNumberSequenceReference.NumberSequenceScope = toNumberSequenceScope.RecId;
                        enumer = mapKeyValue.getEnumerator();
                        iCurrentKey = 0;
                        sCurrentValue = 0;
                        while (enumer.moveNext())
                        {
                            iCurrentKey = enumer.currentKey();
                            if (fromNumberSequenceReference.NumberSequenceId == iCurrentKey)
                            {
                                sCurrentValue = enumer.currentValue();
                                //info(strFmt("Key: %1 and Value %2",iCurrentKey,sCurrentValue));
                                break;
                            }

                        }
                        if (sCurrentValue != 0)
                        {
                            toNumberSequenceReference.NumberSequenceId  = sCurrentValue; //mk
                        }
                        toNumberSequenceReference.insert();
                    }
                }
            }
            ttsCommit;
        }
        catch
        {
            warning("Error copying number sequence");
        }

    }

}

Sunday 22 January 2017

X++ code to set Default Order Settings for an Item

static void ASM_UpdateDefaultOrderSettings(Args _args)
{
    InventTable inventTable;
    InventItemInventSetup inventItemInventSetup;
    InventItemPurchSetup inventItemPurchSetup;
    InventItemSalesSetup inventItemSalesSetup;
    InventDim inventDim;
    DataArea                dataArea;
    InventDimid             inventDimid;
    InventSite              lInventSite;

   ;
 
   inventTable = InventTable::find("S403010", true);
     While select dataArea where !dataArea.isVirtual && ( dataArea.id == "xsd")
     {
        changeCompany(dataArea.Id)
        {
            inventDimid = "";
            inventTable = null;
            lInventSite = null;
            inventDim = null;
            select firstonly lInventSite where lInventSite.dataAreaId == dataArea.id;
            if (lInventSite.RecId)
            {
               while select * from inventTable
               {
                   ttsBegin;
                   //select firstonly lInventSite
                   inventDim.initValue();
                   inventDim.InventSiteId = lInventSite.SiteId;//"AUS";
                   inventDim.inventLocationId = "standard";
                   inventDim = InventDim::findOrCreate(inventDim);

                   //Site specific setup
                   /*
                   inventItemInventSetup.initValue();
                   inventItemInventSetup.InventDimId = inventDim.inventDimId;
                   inventItemInventSetup.ItemId = inventTable.ItemId;
                   inventItemInventSetup.insert();

                   inventItemPurchSetup.initValue();
                   inventItemPurchSetup.InventDimId = inventDim.inventDimId;
                   inventItemPurchSetup.ItemId = inventTable.ItemId;
                   inventItemPurchSetup.insert();

                   inventItemSalesSetup.initValue();
                   inventItemSalesSetup.InventDimId = inventDim.inventDimId;
                   inventItemSalesSetup.ItemId = inventTable.ItemId;
                   inventItemSalesSetup.insert(); */

                   //Default order settings
                   inventItemInventSetup= inventItemInventSetup::findDefault(inventTable.itemId, true);
                   if(inventItemInventSetup.RecId)
                   {
                        inventItemInventSetup.InventDimIdDefault = inventDim.inventDimId;
                        inventItemInventSetup.update();
                   }
                   else
                   {
                       inventItemInventSetup.initValue();
                       inventItemInventSetup.InventDimId = inventDim.inventDimId;
                       inventItemInventSetup.ItemId = inventTable.ItemId;
                       inventItemInventSetup.insert();
                     
                      /*  inventItemInventSetup= inventItemInventSetup::findDefault(inventTable.itemId, true);
                        inventItemInventSetup.InventDimIdDefault = inventDim.inventDimId;
                        inventItemInventSetup.update(); */
                     
                   }
                   inventItemPurchSetup = inventItemPurchSetup::findDefault(inventTable.itemId, true);
                   if (inventItemPurchSetup.RecId)
                   {
                       inventItemPurchSetup.InventDimIdDefault = inventDim.inventDimId;
                       inventItemPurchSetup.update();
                   }
                   else
                   {
                       inventItemPurchSetup.initValue();
                       inventItemPurchSetup.InventDimId = inventDim.inventDimId;
                       inventItemPurchSetup.ItemId = inventTable.ItemId;
                       inventItemPurchSetup.insert();
                     
                       /* inventItemPurchSetup = inventItemPurchSetup::findDefault(inventTable.itemId, true);
                        inventItemPurchSetup.InventDimIdDefault = inventDim.inventDimId;
                        inventItemPurchSetup.update(); */
                     
                 
                   }
                   inventItemSalesSetup= inventItemSalesSetup::findDefault(inventTable.itemId, true);
                   if(inventItemSalesSetup.RecId)
                   {
                        inventItemSalesSetup.InventDimIdDefault = inventDim.inventDimId;
                        inventItemSalesSetup.update();
                   }
                   else
                   {
                       inventItemSalesSetup.initValue();
                       inventItemSalesSetup.InventDimId = inventDim.inventDimId;
                       inventItemSalesSetup.ItemId = inventTable.ItemId;
                       inventItemSalesSetup.insert();
                     
                      /*  inventItemSalesSetup= inventItemSalesSetup::findDefault(inventTable.itemId, true);
                        inventItemSalesSetup.InventDimIdDefault = inventDim.inventDimId;
                        inventItemSalesSetup.update(); */
                 
                   }
                   ttsCommit;
               }
            }
        }
     }

}

Tuesday 17 January 2017

Stock on Hand of a Item using X++ code

Here we will see how to find the Stock on hand of a Item using the X++ code.

Key things to know:

1. The stock on hand will vary depending on Inventory dimensions.
2. The standard Class "InventOnhand" will have all the methods to find out the different formats of stock.
3. Job:

static void MK_stockOnHand(Args _args)
{
    InventOnhand        inventOnHand;
    InventDim           inventDim;
    InventDimParm       inventDimParm;
    InventQty           stockOnHand;
    ItemId              itemid = "00001aTestInter";
   
    inventDim.InventSiteId = "VIC"; // site
    inventDim.InventLocationId = "SOM"; // warehouse
   // inventDim.InventLocationId = "RES";
   
    inventDimParm.initFromInventDim(inventDim);
   
    inventOnHand = InventOnhand::newParameters(itemid,inventDim,inventDimParm);
   
    stockOnHand = inventOnHand.availPhysical();
   
    info (strFmt(" Stock on Hand for Item %1 is %2",itemid,stockOnHand));
   
}

Happy learning...Mallik

Sunday 15 January 2017

Unpick / unreserve a sales order line X++

Unreserve / Unpick a sales order line X++ 


In this article we will see how to unreserved or unpick the piked sales order line. In standard AX 2012 we can do it manually by using the 'Update line" and pick functionality.

For doing it automatically, I am going to add a button(Action Menu Item) on Sales order Header, using this button we will call the class to do the job. 

below is the code which dose the job.. 

One good thing about this job is, it also show the relation on InventTrans and SalesLine in AX 2012. As you all know that, there is no more InventTransID in InventTrans Table, we have to pick it from InventTransOrigin.

///
/// Contains the code that does the actual job of the class ---Mallik.
///
void  run()
{
    InventTrans                 inventTransLocal;
    InventTransOriginSalesLine  inventTransOriginSalesLine;
    InventTransOrigin           inventTransOrigin;
    SalesLine                   salesLine;
    InventTransWMS_Pick         inventTransWMS_Pick;
    TmpInventTransWMS           tmpInventTransWMS;
    Query                       baseQueryInventTrans;
    QueryBuildDataSource        qbdsInventTrans;

    baseQueryInventTrans =  new Query();
    qbdsInventTrans = baseQueryInventTrans.addDataSource(tableNum(InventTrans));
    baseQueryInventTrans.dataSourceTable(tableNum(InventTrans));
    qbdsInventTrans.clearDynalinks();
    qbdsInventTrans.clearRanges();
    qbdsInventTrans.addRange(fieldNum(InventTrans,StatusReceipt)).value(SysQuery::value(StatusReceipt::None));
    qbdsInventTrans.addRange(fieldNum(InventTrans,StatusIssue)).value(SysQuery::range(StatusIssue::Picked,StatusIssue::OnOrder));

    inventTransWMS_Pick = InventTransWMS_Pick::newStandard(tmpInventTransWMS,baseQueryInventTrans);
    while select forUpdate salesLine where salesLine.SalesId == salesTable.SalesId
        && salesLine.ILSLocked == true
    {
       select inventTransLocal
        where  inventTransLocal.ItemId                   == salesline.ItemId
            && inventTransLocal.StatusIssue              == StatusIssue::Picked
        exists join inventTransOrigin
        where   inventTransOrigin.RecId                  == inventTransLocal.InventTransOrigin
        exists join inventTransOriginSalesLine
            where inventTransOriginSalesLine.SalesLineInventTransId      == salesline.InventTransId;
        if (inventTransLocal.RecId)
        {
           
            inventTransWMS_Pick.createFromInventTrans(inventTransLocal);
        }
    }
    inventTransWMS_Pick.updateInvent();

}

Happy learning.. Mallik

Wednesday 11 January 2017

Manual invoice inter-company purchase orders

Adding to the previous posts regarding the setup you require, ensure you have the below setup on the customer master card (which you probably have already since orders are being created in legal entities)
if your process dictates processing the respective documents (PO receipt and invoice) from the sales order you need to perform the folloing:
1. Once you post the packing slip from the sales order--> open the packing slip journal--> post the intercompany packing slip 
Result: PO receipt posted automatically
2. Post the invoice from the sales order and then go to invoice journal-->Intercompany invoice posting 
Result: PO invoice posted
Hope this helps. 

Auto Inter company Purchase order Invoice posting.

Inter-company Invoice posting.

In this post we can find the code to Automatical post the intercompany purchase order, when you click the sales order invoice.
This is a manual process in the standard AX and would require around 4 steps to the above process. Refere the below link for the Manual process.

Link: Manual Inter-company PO invoice

So for the auto process... we will start with creating the class as below.
class Mk_IntercompanyPOInvoice
{
    CustInvoiceJour     custInvoiceJour;
}

add new method

protected void new(CustInvoiceJour     _custInvoiceJour)
{
    custInvoiceJour = _custInvoiceJour;
}

and a construct method

///

/// Initializes a new instance of the Mk_IntercompanyPOInvoice class
///
///
/// parameter for CustInvoiceJour
///
///
///  A new instance of the Mk_IntercompanyPOInvoice class.
///
///
///
///

public static server Mk_IntercompanyPOInvoice construct(CustInvoiceJour     _custInvoiceJour)
{
    return new Mk_IntercompanyPOInvoice(_custInvoiceJour);
}

Add below methods

public void invoiceIntercompanyPO(SalesTable  _salesTable)
{
    SalesTable      lsalesTable;
    PurchTable      lPurchTable;
    lsalesTable = _salesTable;
    lPurchTable = lsalesTable.interCompanyPurchTable();
    changecompany(lsalesTable.InterCompanyCompanyId)
    {
        //Method to confirm the PO
this.confirmationPO(lPurchTable);
// Method to do product receipt of PO
        this.postProductReceipt(lPurchTable);

    }
    // Invoice the PO
    this.interCompanyUpdate();

}

private void confirmationPO(PurchTable  _purchTable)
{
    PurchFormLetter purchFormLetter;
    PurchTable      lPurchTable;
    lPurchTable = _purchTable;
    //PO confirmation
    purchFormLetter = PurchFormLetter::construct(DocumentStatus::PurchaseOrder);
    purchFormLetter.update(lPurchTable, strFmt("Inv_%1", lPurchTable.PurchId));
}

public void postProductReceipt(PurchTable  _purchTable)
{
    PurchFormLetter             purchFormLetter;
    PurchFormletterParmData     purchFormLetterParmData;
    PurchParmUpdate             purchParmUpdate;
    PurchParmTable              purchParmTable;
    PurchParmLine               purchParmLine;
    PurchTable                  purchTable;
    PurchLine                   purchLine;
    PurchId                     purchId;
    Num                         packingSlipId;

    purchId       = "0000-000187";
    packingSlipId = "MAK3101";
    purchTable    = _purchTable;

    ttsBegin;
    // Create PurchParamUpdate table
    purchFormLetterParmData = PurchFormletterParmData::newData(
        DocumentStatus::PackingSlip,
        VersioningUpdateType::Initial);

    purchFormLetterParmData.parmOnlyCreateParmUpdate(true);
    purchFormLetterParmData.createData(false);
    purchParmUpdate = purchFormLetterParmData.parmParmUpdate();

    // Set PurchParmTable table
    purchParmTable.clear();
    purchParmTable.TransDate                = SystemDateGet();
    purchParmTable.Ordering                 = DocumentStatus::PackingSlip;
    purchParmTable.ParmJobStatus            = ParmJobStatus::Waiting;
    purchParmTable.Num                      = packingSlipId;//To-Do check for number sequence
    purchParmTable.PurchId                  = purchTable.PurchId;
    purchParmTable.PurchName                = purchTable.PurchName;
    purchParmTable.DeliveryName             = purchTable.DeliveryName;
    purchParmTable.DeliveryPostalAddress    = purchTable.DeliveryPostalAddress;
    purchParmTable.OrderAccount             = purchTable.OrderAccount;
    purchParmTable.CurrencyCode             = purchTable.CurrencyCode;
    purchParmTable.InvoiceAccount           = purchTable.InvoiceAccount;
    purchParmTable.ParmId                   = purchParmUpdate.ParmId;
    purchParmTable.insert();

    // Set PurchParmLine table
    while select purchLine
        where purchLine.PurchId == purchTable.purchId
    {
        purchParmLine.InitFromPurchLine(purchLine);

        purchParmLine.ReceiveNow    = PurchLine.PurchQty;
        purchParmLine.ParmId        = purchParmTable.ParmId;
        purchParmLine.TableRefId    = purchParmTable.TableRefId;
        purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);
        purchParmLine.setLineAmount();
        purchParmLine.insert();
    }

    purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);
    purchFormLetter.transDate(systemDateGet());
    purchFormLetter.proforma(false);
    purchFormLetter.specQty(PurchUpdate::All);
    purchFormLetter.purchTable(purchTable);

    // This is the ID we hard code as the product receipt ID, if we do the posting via UI
    // user would have the option to manually enter this value
    purchFormLetter.parmParmTableNum(purchParmTable.ParmId);
    purchFormLetter.parmId(purchParmTable.ParmId);
    purchFormLetter.purchParmUpdate(purchFormLetterParmData.parmParmUpdate());
    purchFormLetter.run();
    ttsCommit;
}

private void  interCompanyUpdate()
{
    CustInvoiceTrans        custInvoiceTrans;
    Map                     inventTransIdMap    = new Map(new DictField(tableNum(CustInvoiceTrans),fieldNum(CustInvoiceTrans, InventTransId)).baseType(), Types::Container);
    MapIterator             miInventTransId;
    Map                     purchIdMap          = new Map(new DictField(tableNum(PurchTable),fieldNum(PurchTable, PurchId)).baseType(), Types::Integer);
    MapIterator             miPurchId;
    Map                     receiveNowMap       = new Map(new DictField(tableNum(PurchLine),fieldNum(PurchLine, InventTransId)).baseType(), Types::Container);
    container               receiveNow;
    PurchFormLetter_Invoice purchFormLetter;
    SysQueryRun             chooseLinesQuery;
    SysQueryRun             chooseLinesPendingInvoiceQuery;

    SalesParmUpdate         salesParmUpdate;

    PurchId                 interCompanyPurchId;
    InventTransId           interCompanyInventTransId;
    PurchLine               purchLine;

    InventTrans             inventTrans;
    InventTransOrigin       inventTransOrigin;

    VendPackingSlipJour     vendPackingSlipJour;
    CustPackingSlipTrans    custPackingSlipTrans;
    CustInvoicePackingSlipQuantityMatch custInvoicePackingSlipQuantityMatch;
    TmpFrmVirtual           tmpFrmVirtualCust;
    TmpFrmVirtual           tmpFrmVirtualVend;
    List                    selectedList = new List(Types::Record);
    container               conTmpFrmVirtual;

    salesParmUpdate = SalesParmUpdate::find(custInvoiceJour.ParmId);
    while select InventTransId, InterCompanyInventTransId, Qty, PdsCWQty, StockedProduct, SourceDocumentLine from custInvoiceTrans
        where custInvoiceTrans.SalesId              == custInvoiceJour.SalesId
               && custInvoiceTrans.InvoiceId            == custInvoiceJour.InvoiceId
               && custInvoiceTrans.InvoiceDate          == custInvoiceJour.InvoiceDate
               && custInvoiceTrans.NumberSequenceGroup  == custInvoiceJour.NumberSequenceGroup
    {
        if (custInvoiceTrans.isStocked())
        {
            inventTransIdMap.insert(custInvoiceTrans.InterCompanyInventTransId, [custInvoiceTrans.Qty, custInvoiceTrans.PdsCWQty]);

            while select PackingSlipId, DatePhysical from inventTrans
                  where inventTrans.InvoiceId     == custInvoiceJour.InvoiceId
                  &&    inventTrans.DateFinancial == custInvoiceJour.InvoiceDate
                  exists join inventTransOrigin
                    where inventTransOrigin.RecId         == inventTrans.InventTransOrigin
                       && inventTransOrigin.InventTransId == custInvoiceTrans.InventTransId
            {
                select firstonly tmpFrmVirtualCust
                       where tmpFrmVirtualCust.Id        == custInvoiceJour.InterCompanyPurchId
                       &&    tmpFrmVirtualCust.ItemId    == inventTrans.PackingSlipId
                       &&    tmpFrmVirtualCust.TransDate == inventTrans.DatePhysical;
                if (!tmpFrmVirtualCust)
                {
                    tmpFrmVirtualCust.clear();
                    tmpFrmVirtualCust.Id        = custInvoiceJour.InterCompanyPurchId;
                    tmpFrmVirtualCust.ItemId    = inventTrans.PackingSlipId;
                    tmpFrmVirtualCust.TransDate = inventTrans.DatePhysical;
                    tmpFrmVirtualCust.insert();

                }
            }
        }
        else
        {
            while select PackingSlipId from custPackingSlipTrans
                exists join custInvoicePackingSlipQuantityMatch
                    where custInvoicePackingSlipQuantityMatch.InvoiceSourceDocumentLine == custInvoiceTrans.SourceDocumentLine
                        && custInvoicePackingSlipQuantityMatch.PackingSlipSourceDocumentLine == custPackingSlipTrans.SourceDocumentLine
            {
                select firstonly tmpFrmVirtualCust
                       where tmpFrmVirtualCust.Id        == custInvoiceJour.InterCompanyPurchId
                       &&    tmpFrmVirtualCust.ItemId    == custPackingSlipTrans.PackingSlipId;

                if (!tmpFrmVirtualCust)
                {
                    tmpFrmVirtualCust.clear();
                    tmpFrmVirtualCust.Id        = custInvoiceJour.InterCompanyPurchId;
                    tmpFrmVirtualCust.ItemId    = custPackingSlipTrans.PackingSlipId;
                    tmpFrmVirtualCust.insert();

                }
            }
        }
    }

    changecompany(custInvoiceJour.InterCompanyCompanyId)
    {
        this.intercompanyAllocateMarkupAndConfirm(inventTransIdMap);
        tmpFrmVirtualVend = null;
        while select tmpFrmVirtualCust
        {
            select firstonly vendPackingSlipJour
                where vendPackingSlipJour.PurchId       == tmpFrmVirtualCust.Id
                &&    vendPackingSlipJour.PackingSlipId == tmpFrmVirtualCust.ItemId;
/*
// This is omitted, due to problems when the intercompany sales order items are delivered one day,
// and the items are received on the intercompany purchase order on the following day
//
                &&    vendPackingSlipJour.DeliveryDate  == tmpFrmVirtualCust.TransDate;
*/
            if (vendPackingSlipJour)
            {
                select firstonly tmpFrmVirtualVend
                       where tmpFrmVirtualVend.TableNum   == vendPackingSlipJour.TableId
                       &&    tmpFrmVirtualVend.RecordNo   == vendPackingSlipJour.RecId
                       &&    tmpFrmVirtualVend.Id         == vendPackingSlipJour.PurchId;
                if (!tmpFrmVirtualVend)
                {
                    tmpFrmVirtualVend.clear();
                    tmpFrmVirtualVend.TableNum      = vendPackingSlipJour.TableId;
                    tmpFrmVirtualVend.RecordNo      = vendPackingSlipJour.RecId;
                    tmpFrmVirtualVend.NoYes         = NoYes::Yes;
                    tmpFrmVirtualVend.Id            = vendPackingSlipJour.PurchId;
                    tmpFrmVirtualVend.insert();
                }
            }
            else
            {
                tmpFrmVirtualVend   = null;
                warning(strFmt("@SYS106122",custInvoiceJour.InterCompanyPurchId));
                break;
            }
        }

        ttsbegin;

        chooseLinesQuery = new SysQueryRun(queryStr(PurchUpdate));

        miInventTransId = new MapIterator(inventTransIdMap);
        miInventTransId.begin();
        while (miInventTransId.more())
        {
            interCompanyInventTransId = miInventTransId.key();
            interCompanyPurchId       = PurchLine::findInventTransId(interCompanyInventTransId).PurchId;

            if (!purchIdMap.exists(interCompanyPurchId))
            {
                while select forupdate purchLine
                      where purchLine.PurchId == interCompanyPurchId
                         && !purchLine.IsDeleted
                {
                    if (inventTransIdMap.exists(purchLine.InventTransId))
                    {
                        [purchLine.PurchReceivedNow, purchLine.PdsCWInventReceivedNow] = inventTransIdMap.lookup(purchLine.InventTransId);
                    }
                    else
                    {
                        receiveNow = [purchLine.PurchReceivedNow, purchLine.InventReceivedNow];
                        receiveNowMap.insert(purchLine.InventTransId, receiveNow);
                        purchLine.PurchReceivedNow = 0;
                    }
                    purchLine.setInventReceivedNow();
                    purchLine.update();
                }
                purchIdMap.insert(interCompanyPurchId, 1);
                chooseLinesQuery.query().dataSourceTable(tableNum(PurchTable)).addRange(fieldNum(PurchTable, PurchId)).value(queryValue(interCompanyPurchId));
            }
            miInventTransId.next();
        }
        ttscommit;
        chooseLinesQuery.query().interactive    (false);
        chooseLinesQuery.saveUserSetup          (false);

        // VendInvoiceInfoTable is the required datasource of the query
        chooseLinesQuery.query().addDataSource(tableNum(VendInvoiceInfoTable)).enabled(false);
        // chooseLinesPendingInvoiceQuery needs to be initialized, although it will not be used
        chooseLinesPendingInvoiceQuery  = new SysQueryRun(queryStr(PurchUpdatePendingInvoice));
        chooseLinesPendingInvoiceQuery.query().dataSourceTable(tableNum(PurchTable)).addRange(fieldNum(PurchTable,PurchId)).value(queryValue(''));

        purchFormLetter = PurchFormLetter::construct(DocumentStatus::Invoice);
        purchFormLetter.chooseLinesQuery        (chooseLinesQuery);
        purchFormLetter.parmQueryChooseLinesPendingInvoice(chooseLinesPendingInvoiceQuery);
        purchFormLetter.purchTable              (PurchTable::find(custInvoiceJour.InterCompanyPurchId));
        purchFormLetter.transDate               (custInvoiceJour.InvoiceDate);
        purchFormLetter.parmParmTableNum        (custInvoiceJour.InvoiceId);
        purchFormLetter.creditRemaining         (salesParmUpdate.CreditRemaining);
        purchFormLetter.printFormLetter         (NoYes::No);
        purchFormLetter.interCompanyVoucher     (custInvoiceJour.LedgerVoucher);
        purchFormLetter.sumBy                   (AccountOrder::Auto);

        if (tmpFrmVirtualVend)
        {
            purchFormLetter.specQty                 (PurchUpdate::PackingSlip);

            while select tmpFrmVirtualVend
            {
                selectedList.addEnd(tmpFrmVirtualVend);
                conTmpFrmVirtual = selectedList.pack();
            }
            purchFormLetter.selectFromJournal(conTmpFrmVirtual);
        }
        else
        {
            purchFormLetter.specQty                 (PurchUpdate::All);
            purchFormLetter.chooseLines(false);
        }

        purchFormLetter.reArrangeNow(true);
        purchFormLetter.run();

        if (receiveNowMap.elements())
        {
            ttsbegin;
            miPurchId = new MapIterator(purchIdMap);
            miPurchId.begin();
            while (miPurchId.more())
            {
                interCompanyPurchId = miPurchId.key();

                while select forupdate purchLine
                      where purchLine.PurchId == interCompanyPurchId
                         && !purchLine.IsDeleted
                {
                    if (receiveNowMap.exists(purchLine.InventTransId))
                    {
                        receiveNow = receiveNowMap.lookup(purchLine.InventTransId);
                        purchLine.PurchReceivedNow = conPeek(receiveNow, 1);
                        purchLine.InventReceivedNow = conPeek(receiveNow, 2);
                        purchLine.doUpdate();
                    }
                }

                miPurchId.next();
            }
            ttscommit;
        }
    }
}


Now call the above class from SalesTable from clicked method.

void clicked()
{
    Mk_IntercompanyPOInvoice   intercompanyPOInvoice;
    CustInvoiceJour             custInvoiceJour;
    SalesTable                  lSalesTable;
    ;


    //
    if (isRU)
    {
        salesTable.checkMarkupTrans_RU();
    }
    //
    super();
    custInvoiceJour = CustInvoiceJour::findFromSalesId_IN(SalesTable.SalesId);
    if (custInvoiceJour.RecId)
    {
        intercompanyPOInvoice = MK_IntercompanyPOInvoice::construct(custInvoiceJour);
        intercompanyPOInvoice.invoiceIntercompanyPO(SalesTable);
    }
}


Hope this will help you. by....Mallik!!!

X++ job to create site specific order settings

static void MK_SiteSpecificSetupCreate(Args _args)
{
    InventTable inventTable;
    InventItemInventSetup inventItemInventSetup;
    InventItemPurchSetup inventItemPurchSetup;
    InventItemSalesSetup inventItemSalesSetup;
    InventDim               _inventdimPurch;
    InventDim               inventDim;
    DataArea                dataArea;
    InventDimid             inventDimid;
    InventDim               lInventDim;
    Inventsite              inventSite;

    ;
   
     While select dataArea where !dataArea.isVirtual
    {
        //ttsbegin;
        cl ++;
        changeCompany(dataArea.Id)
        {
            inventDimid = "";
            inventTable = null;

            while select inventTable where inventTable.dataAreaId == dataArea.Id
            {
                InventItemPurchSetup = null;
                _inventdimPurch = null;
                inventItemPurchSetup = null;
                inventItemSalesSetup = null;
                inventItemInventSetup = null;
                inventSite = null;
                select firstonly inventSite where inventSite.dataAreaId ==  dataArea.Id;
                if (inventsite.RecId)
                {
                    inventDim.InventSiteId = inventsite.SiteId;
                }
                else
                {
                   
                        inventDim.InventSiteId     = "AUS";
                   
                }
                inventDimid = InventDim::findOrCreate(inventDim).inventDimId;
                //inventTable = InventTable::find("S403040", true);
                if(inventDimid && inventTable.ItemId)//if _inventdimid -- BEGIN
                {
                    if(InventItemPurchSetup::exist(inventTable.ItemId,inventDimid) == false)
                    {
                        ttsbegin;
                        inventItemPurchSetup.InventDimId           = inventDimid;
                        inventItemPurchSetup.ItemId                = inventTable.ItemId;
                            _inventdimPurch.InventLocationId            = "standard";
                            inventItemPurchSetup.InventDimIdDefault    = InventDim::findOrCreate(_inventdimPurch).inventDimId;
                        inventItemPurchSetup.insert();
                        inventItemPurchSetup.validateWrite();
                        inventItemInventSetup.ItemId               = inventTable.ItemId;
                            inventItemInventSetup.InventDimId          = inventItemPurchSetup.InventDimId;
                            inventItemInventSetup.InventDimIdDefault   = InventDim::findOrCreate(_inventdimPurch).inventDimId;
                        inventItemInventSetup.insert();
                        inventItemInventSetup.validateWrite();
                        inventItemSalesSetup.ItemId               = inventTable.ItemId;
                            inventItemSalesSetup.InventDimId          = inventItemPurchSetup.InventDimId;
                            inventItemSalesSetup.InventDimIdDefault   = InventDim::findOrCreate(_inventdimPurch).inventDimId;
                        inventItemSalesSetup.insert();
                        inventItemSalesSetup.validateWrite();
                        ttscommit;
                   }

                 }
            }//while
        }// change company
    }//while
}

Thursday 5 January 2017

Quick Start to AX 7 Development

Quick Start to AX 7 Development 

It gives an Quick start of AX7, where in you can create a Model, X++ job using VS2015 and run it.
So Lets start by create your own Model
  • The first step is to log into Visual Studio as an Administrator
Dev1
Once within Visual Studio, go to the Dynamics AX7 menu and select Model Management and ‘Create model’. 
Dev2
Create the model in the form that appears and fill out the fields as appropriate

Dev3
Click ‘Next’ and select ‘Existing package’ and choose ‘Application Suite’

Dev4
Press ‘Next’ – accept the default values suggested and press ‘Finish’


Dev5
In the ‘Save’ screen that appears, select the project DynamicsAX7 and give it a name of your choice and press ‘OK’
Dev6
Notice in the Solution Explorer to the right in the screen a new Project has been created in your newly created Model

Dev7
On the Solution Explorer go to the project and right-click and select ‘Properties’
Dev8
In here note that the project is in the new Model just created and that the customisation will be saved in the ‘USR’ layer
Dev9
Also, it’s a good idea to specify which company you wish to execute the code in, here ‘DEMF’
Press OK
 Now to add ‘Runnable Class(Job) to the Project do the following. On the project right-click and select ‘Add’ and then select ‘New Item’
Dev10

In the screen-shot appears select ‘Code’ and then ‘Runable Class(Job)’
Dev11
And press ‘Add’
Note that now in the Solution explorer that the Runable Class has been added
Dev12
Doubleclick on the ‘Runable class’ and enter the code editor window and give your job a meaningful name and write your code like you would do any X++ job as known in previous versions
dev12B
Save the project(Ctrl + S) and to compile the job, select ‘Build’ and ‘Build Solution’ from the toolbar
Dev13b

Wait until the output window reports that the build has completed
Dev14


Now in order to run the job, you need to set it as a ‘Startup Object’
Go to the Solution Explorer and on the Job, right-click and select ‘set as Startup Object’
Dev15
Now to execute the job, select ‘Debug’ in the toolbar and then ‘Start without Debugging’
Dev16
And note the output in the browser
DevFinalOutput


Update NuGet package to new MS D365FO version

1. Import the NuGet package files from LCS for that particular version please take the PU version files only. a. Goto LCS-->Asset Libra...