Monday, August 19, 2019

How to create Vendor Invoice Journal using x++ in D365 FO

Hi folks ,


Very common requirement these days is to create Vendor Invoice Journal through code.

Here is an example mentioned below in which I am picking the values for Vendor invoice creation from a staging table :-

Class Name :- VendInvoiceJournalCreateBatch

        #define.initFromJournal('VINV')
        #define.AEDCurrency('USD')
        #define.EmptyCurrency('')
       
        int                                                                      i;
        str                                                                      invdate , invfinaldate;
        date                                                                   dateheader , dateheaderval , dateline;
        System.DateTime                                             netDttm;
        real                                                                    amountcr;
        utcdatetime                                                       xppDttm , invdatetime;
        SupplierInvoiceHeaderDetails                         vendInvoiceJourStageHeader,                                                                                                                      vendInvoiceJourStageHeaderUpdate;
        SupplierInvoiceLineDetails                                vendInvoiceJourStageLine
                                                                                    , vendInvoiceJourStageLineds;
        LedgerJournalTable                                            journalTable;
        JournalTableData                                                journalTableData;
        LedgerJournalTrans                                            journalTrans;
        container                                                             offsetCon, offsetConLoc , mainAccountCon;
        NumberSeq                                                         numberSeq;
        Voucher                                                               voucher;
        LedgerJournalName                                            ledgerJournalName;
        AccountNum                                                       vendAccount;
        HcmWorker                                                         hcmWorker;
        DirPerson                                                            dirPerson;
        DirPersonUser                                                    dirPersonUser;
        VendInvoiceJournalCreateBatch                        classVend   =   new                                                                                                                                    VendInvoiceJournalCreateBatch();
        MainAccount                                                      mainAccount;
        Voucher                                                               vch;
        DimensionAttributeValueCombination              dimCombination1;
        String255                                                            tmpOffsetAccount, tmpVoucherNo;
        DimensionAttributeValueCombination              dimCombination, dimCombinationLoc;
        NoYes                                                                 newOffsetLine = NoYes::Yes;
        LedgerJournalId                                                 journalId;
        String10                                                              purchId;
       
        i=0;

        while select vendInvoiceJourStageHeader where vendInvoiceJourStageHeader.UpdateFlag == 0
        {
            try
            {
                ledgerJournalName            =   LedgerJournalName::find(#initFromJournal);
                journalTable.initFromLedgerJournalName(#initFromJournal);
                journalTableData            =   JournalTableData::newTable(journalTable);
                journalTable.JournalNum     =   journalTableData.nextJournalId();
                journalTable.CurrencyCode   =   #AEDCurrency;
                if (journalTable.validateWrite())
                {
                    journalTable.insert();
                }

                journalId = journalTable.JournalNum;

                select count(RecId) from vendInvoiceJourStageLineds where vendInvoiceJourStageLineds.DocumentRef  ==  vendInvoiceJourStageHeader.Docref;

                while select vendInvoiceJourStageLine order by OffsetAccount desc
                    where vendInvoiceJourStageLine.DocumentRef  ==  vendInvoiceJourStageHeader.Docref
                {
                    amountcr= 0.00;
                    tmpOffsetAccount    = vendInvoiceJourStageLine.OffsetAccount;
                    tmpVoucherNo        = vendInvoiceJourStageLine.VoucherNo;

                    select dirPersonUser where dirpersonuser.User==curUserId();

                    select dirPerson where dirPerson.RecId == dirPersonUser.PersonParty;

                    select hcmWorker where hcmWorker.Person == dirPerson.RecId;

                    select  dimCombination where dimCombination.DisplayValue    ==  vendInvoiceJourStageHeader.Vendor;

                    select  dimCombinationLoc where dimCombinationLoc.DisplayValue    ==  vendInvoiceJourStageLine.OffsetAccount;
                   
                    offsetCon                           =   [vendInvoiceJourStageLine.Ledger,vendInvoiceJourStageLine.Region,vendInvoiceJourStageLine.LOB,vendInvoiceJourStageLine.Department,vendInvoiceJourStageLine.BIN,vendInvoiceJourStageLine.Contract];
                    offsetConLoc                        =   [vendInvoiceJourStageLine.OffsetAccount,vendInvoiceJourStageLine.Region,vendInvoiceJourStageLine.LOB,vendInvoiceJourStageLine.Department,vendInvoiceJourStageLine.BIN,vendInvoiceJourStageLine.Contract];

                    numberSeq                           =   NumberSeq::newGetVoucherFromId(journalTable.NumberSequenceTable, true);

                    if(vendInvoiceJourStageLine.OffsetAccount != '')
                    {
                        select  dimCombination where dimCombination.DisplayValue    ==  vendInvoiceJourStageLine.Ledger;
                        offsetConLoc                           =   [vendInvoiceJourStageLine.OffsetAccount,vendInvoiceJourStageLine.Region,vendInvoiceJourStageLine.LOB,vendInvoiceJourStageLine.Department,vendInvoiceJourStageLine.BIN,vendInvoiceJourStageLine.Contract];

                        journalTrans.JournalNum             =   journalTable.JournalNum;
                        journalTrans.Voucher                =   numberSeq.voucher();
                        journalTrans.Invoice                =   vendInvoiceJourStageHeader.InvoiceNumber;
                        journalTrans.Txt                    =   vendInvoiceJourStageHeader.InvoiceDescription;
                        invdatetime = DateTimeUtil::anyToDateTime(vendInvoiceJourStageHeader.InvoiceDate);

                        dateheader = DateTimeUtil::date(invdatetime);

                        invdate = date2Str(dateheader,321,DateDay::Digits2,DateSeparator::Slash,DateMonth::Digits2,DateSeparator::Hyphen,DateYear::Digits4);
       
                        dateheaderval = str2Date(invdate,321);

                        journalTrans.INTC_InvDate = dateheaderval;
                        journalTrans.DocumentDate = str2Date(vendInvoiceJourStageHeader.InvoiceReceivedDate,321);
                        journalTrans.TransDate              =   today();//str2Date(journalDeatils.TransactionDate, 123);
                        journalTrans.AccountType            =   LedgerJournalACType::Ledger;
                        //journalTrans.LedgerDimension        =   dimCombination.RecId;
                        journalTrans.LedgerDimension        =   classVend.generateLedgerDimension(offsetCon, vendInvoiceJourStageLine.Ledger);
                        //journalTrans.AmountCurCredit        =   vendInvoiceJourStageLine.InvoiceAmount;
                        journalTrans.AmountCurDebit         =   vendInvoiceJourStageLine.InvoiceAmount;
                        journalTrans.AmountCurCredit         = 0.00;
                        journalTrans.OffsetAccountType      =   LedgerJournalACType::Ledger;
                        //journalTrans.OffsetLedgerDimension  =   classVend.generateLedgerDimension(offsetCon, vendInvoiceJourStageLine.Ledger);
                        //journalTrans.OffsetLedgerDimension  =   dimCombinationLoc.RecId;
                        journalTrans.OffsetLedgerDimension  =   classVend.generateLedgerDimension(offsetConLoc, vendInvoiceJourStageLine.OffsetAccount);
                        journalTrans.INTC_DocumentRef       =   vendInvoiceJourStageLine.DocumentRef;

                        if(vendInvoiceJourStageLine.Currency  ==  #EmptyCurrency)
                        {
                            journalTrans.CurrencyCode   =   #AEDCurrency;
                        }
                        else
                        {
                            journalTrans.CurrencyCode   =   vendInvoiceJourStageLine.Currency;
                        }

                        journalTrans.ExchRate = Currency::exchRate1(journalTrans.CurrencyCode, journalTrans.TransDate);
                        journalTrans.Approver = hcmWorker.RecId;
                        journalTrans.Approved =NoYes::Yes;
                        journalTrans.PostingProfile = "General";
                        journalTrans.INTC_PurchId       =   vendInvoiceJourStageLine.PONo;
                        journalTrans.TransactionType = LedgerTransType::Vend;
                        journalTrans.INTC_WorkOrderId   =   vendInvoiceJourStageLine.WorkOrderNo;
                        journalTrans.INTC_Qty           =   vendInvoiceJourStageLine.Qty;
                        journalTrans.Payment = vendInvoiceJourStageLine.PaymentTerms;
                        journalTrans.insert();

                        //======================
                        numberSeq.used();
                        //======================
                    }
                    else
                    {
                        select  dimCombination where dimCombination.DisplayValue    ==  vendInvoiceJourStageLine.Ledger;
                        select  dimCombinationLoc where dimCombinationLoc.DisplayValue    ==  vendInvoiceJourStageLine.OffsetAccount;

                        offsetCon                           =   [vendInvoiceJourStageLine.Ledger,vendInvoiceJourStageLine.Region,vendInvoiceJourStageLine.LOB,vendInvoiceJourStageLine.Department,vendInvoiceJourStageLine.BIN,vendInvoiceJourStageLine.Contract];
                        if(vendInvoiceJourStageLine.OffsetAccount != '')
                        {
                            offsetConLoc                           =   [vendInvoiceJourStageLine.OffsetAccount,vendInvoiceJourStageLine.Region,vendInvoiceJourStageLine.LOB,vendInvoiceJourStageLine.Department,vendInvoiceJourStageLine.BIN,vendInvoiceJourStageLine.Contract];
                        }
                        journalTrans.JournalNum             =   journalTable.JournalNum;

                        if(newOffsetLine == NoYes::Yes)
                        {
                            numberSeq                   = NumberSeq::newGetVoucherFromId(journalTable.NumberSequenceTable, true);
                            journalTrans.Voucher        = numberSeq.voucher();
                            vch                         = journalTrans.Voucher;
                            newOffsetLine               = NoYes::No;
                        }
                        else
                        {
                            journalTrans.Voucher        = vch;
                        }

                        purchId = vendInvoiceJourStageLine.POLineNum;

                        amountcr+=vendInvoiceJourStageLine.InvoiceAmount;
                        journalTrans.Invoice            =   vendInvoiceJourStageHeader.InvoiceNumber;
                        journalTrans.Txt                 =   vendInvoiceJourStageHeader.InvoiceDescription;
                        invdatetime                     = DateTimeUtil::anyToDateTime(vendInvoiceJourStageHeader.InvoiceDate);

                        dateheader = DateTimeUtil::date(invdatetime);

                        invdate = date2Str(dateheader,321,DateDay::Digits2,DateSeparator::Slash,DateMonth::Digits2,DateSeparator::Hyphen,DateYear::Digits4);
       
                        dateheaderval = str2Date(invdate,321);

                        journalTrans.INTC_InvDate = dateheaderval;
                        journalTrans.DocumentDate = str2Date(vendInvoiceJourStageHeader.InvoiceReceivedDate,321);
                        journalTrans.TransDate              =   today();//str2Date(journalDeatils.TransactionDate, 123);
                        journalTrans.AccountType            =   LedgerJournalACType::Ledger;
                        //journalTrans.LedgerDimension        =   dimCombination.RecId;
                        journalTrans.LedgerDimension        =   classVend.generateLedgerDimension(offsetCon, vendInvoiceJourStageLine.Ledger);
                        //journalTrans.AmountCurCredit        =   vendInvoiceJourStageLine.InvoiceAmount;
                        journalTrans.AmountCurDebit         =   vendInvoiceJourStageLine.InvoiceAmount;
                        journalTrans.AmountCurCredit         = 0.00;
                        journalTrans.OffsetAccountType      =   LedgerJournalACType::Ledger;
                        //journalTrans.OffsetLedgerDimension  =   classVend.generateLedgerDimension(offsetCon, vendInvoiceJourStageLine.Ledger);

                        if(vendInvoiceJourStageLine.OffsetAccount == '')
                        {
                            journalTrans.OffsetLedgerDimension  =   dimCombinationLoc.RecId;
                        }
                        else
                        {
                            journalTrans.OffsetLedgerDimension  =   classVend.generateLedgerDimension(offsetConLoc, vendInvoiceJourStageLine.OffsetAccount);
                        }

                        journalTrans.INTC_DocumentRef       =   vendInvoiceJourStageLine.DocumentRef;
                        if(vendInvoiceJourStageLine.Currency  ==  #EmptyCurrency)
                        {
                            journalTrans.CurrencyCode   =   #AEDCurrency;
                        }
                        else
                        {
                            journalTrans.CurrencyCode   =   vendInvoiceJourStageLine.Currency;
                        }
                        journalTrans.ExchRate = Currency::exchRate1(journalTrans.CurrencyCode, journalTrans.TransDate);
                        journalTrans.Approver = hcmWorker.RecId;
                        journalTrans.Approved =NoYes::Yes;
                        journalTrans.PostingProfile = "General";
                        journalTrans.INTC_PurchId       =   vendInvoiceJourStageLine.PONo;
                        journalTrans.TransactionType = LedgerTransType::Vend;
                        journalTrans.INTC_WorkOrderId   =   vendInvoiceJourStageLine.WorkOrderNo;
                        journalTrans.INTC_Qty           =   vendInvoiceJourStageLine.Qty;
                        journalTrans.Payment = vendInvoiceJourStageLine.PaymentTerms;
                        journalTrans.insert();

                        //======================
                        numberSeq.used();
                        //======================
                    }
                }

                select dirPersonUser where dirpersonuser.User==curUserId();

                select dirPerson where dirPerson.RecId == dirPersonUser.PersonParty;

                select hcmWorker where hcmWorker.Person == dirPerson.RecId;

                select  dimCombination1 where dimCombination1.DisplayValue    ==  vendInvoiceJourStageHeader.Vendor;
                offsetCon                           =   [vendInvoiceJourStageHeader.Vendor,vendInvoiceJourStageLine.Region,vendInvoiceJourStageLine.LOB,vendInvoiceJourStageLine.Department,vendInvoiceJourStageLine.BIN,vendInvoiceJourStageLine.Contract];
                numberSeq                           =   NumberSeq::newGetVoucherFromId(journalTable.NumberSequenceTable, true);

                //journalTrans.JournalNum             =   journalTable.JournalNum;
                journalTrans.JournalNum             =   journalId;

                journalTrans.Voucher                =   vch;

                vch = journalTrans.Voucher;

                journalTrans.Invoice                =   vendInvoiceJourStageHeader.InvoiceNumber;
                journalTrans.Txt                    =   vendInvoiceJourStageHeader.InvoiceDescription;
                invdatetime = DateTimeUtil::anyToDateTime(vendInvoiceJourStageHeader.InvoiceDate);

                dateheader = DateTimeUtil::date(invdatetime);

                invdate = date2Str(dateheader,321,DateDay::Digits2,DateSeparator::Slash,DateMonth::Digits2,DateSeparator::Hyphen,DateYear::Digits4);
       
                dateheaderval = str2Date(invdate,321);

                journalTrans.INTC_InvDate = dateheaderval;
                journalTrans.DocumentDate = str2Date(vendInvoiceJourStageHeader.InvoiceReceivedDate,321);
                journalTrans.TransDate              =   today();//str2Date(journalDeatils.TransactionDate, 123);
                journalTrans.AccountType            =   LedgerJournalACType::Vend;
                journalTrans.LedgerDimension        =   dimCombination1.RecId;
                //journalTrans.LedgerDimension        =   classVend.generateLedgerDimension(offsetCon, vendInvoiceJourStageHeader.Vendor);
                journalTrans.AmountCurDebit         =   0.00;
                journalTrans.AmountCurCredit        =   amountcr;
                journalTrans.OffsetAccountType      =   LedgerJournalACType::Ledger;
                //journalTrans.OffsetLedgerDimension  =   classVend.generateLedgerDimension(offsetCon, vendInvoiceJourStageLine.Ledger);
                //journalTrans.OffsetLedgerDimension  =   dimCombinationLoc.RecId;

                if(vendInvoiceJourStageLine.OffsetAccount == '')
                {
                    journalTrans.OffsetLedgerDimension  =   dimCombinationLoc.RecId;
                }
                else
                {
                    journalTrans.OffsetLedgerDimension  =   classVend.generateLedgerDimension(offsetConLoc, vendInvoiceJourStageLine.OffsetAccount);
                }
               
                journalTrans.INTC_DocumentRef       =   vendInvoiceJourStageHeader.Docref;
               
                if(vendInvoiceJourStageLine.Currency  ==  #EmptyCurrency)
                {
                    journalTrans.CurrencyCode   =   #AEDCurrency;
                }
                else
                {
                    journalTrans.CurrencyCode   =   vendInvoiceJourStageLine.Currency;
                }
                journalTrans.ExchRate = Currency::exchRate1(journalTrans.CurrencyCode, journalTrans.TransDate);
                journalTrans.Approver = hcmWorker.RecId;
                journalTrans.Approved =NoYes::Yes;
                journalTrans.PostingProfile = "General";
                journalTrans.INTC_PurchId       =   vendInvoiceJourStageLine.PONo;
                journalTrans.TransactionType = LedgerTransType::Vend;
                journalTrans.INTC_WorkOrderId   =   vendInvoiceJourStageLine.WorkOrderNo;
                journalTrans.INTC_Qty           =   vendInvoiceJourStageLine.Qty;
                journalTrans.Payment = vendInvoiceJourStageLine.PaymentTerms;
                if(amountcr>0)
                {
                    journalTrans.insert();
                }
                ttsbegin;
                select forupdate vendInvoiceJourStageHeaderUpdate where vendInvoiceJourStageHeaderUpdate.RecId    ==    vendInvoiceJourStageHeader.RecId;
                vendInvoiceJourStageHeaderUpdate.UpdateFlag = 1;
                vendInvoiceJourStageHeaderUpdate.update();
                ttscommit;

                //======================
                numberSeq.used();
                //======================
            }
            catch(Exception::Error)
            {
                throw Exception::Error;
            }
        }



public DimensionDynamicAccount   generateLedgerDimension(container    _conData,                                                                                                                          MainAccountNum  _mainAccountNum)
    {
        int                                                               hierarchyCount;
        int                                                               hierarchyIdx;
        RecId                                                          dimAttId_MainAccount;
        LedgerRecId                                              ledgerRecId;
        MainAccount                                             mainAccount;
        RefRecId                                                    recordvalue;
        DimensionAttribute                                   dimensionAttribute;
        DimensionAttributeValue                          dimensionAttributeValue;
        DimensionSetSegmentName                     DimensionSet;
        DimensionStorage                                     dimStorage;
        LedgerAccountContract                            LedgerAccountContract = new                                                                                                                                                          LedgerAccountContract();
        DimensionAttributeValueContract            ValueContract;

        List                                                             valueContracts = new List(Types::Class);
       
         dimensionAttributeValueCombination  dimensionAttributeValueCombination;
     

        mainAccount     =   MainAccount::findByMainAccountId(_mainAccountNum);
        recordvalue     =                                                                                                                                                         DimensionHierarchy::getAccountStructure(mainAccount.RecId,Ledger::current());
        hierarchyCount  =   DimensionHierarchy::getLevelCount(recordvalue);
        DimensionSet    =                                                                                                                                                          DimensionHierarchyLevel::getDimensionHierarchyLevelNames(recordvalue);

        for(hierarchyIdx = 1;hierarchyIdx<=hierarchyCount;hierarchyIdx++)
        {
            if(hierarchyIdx == 1)
            {
                continue;
            }
            dimensionAttribute =                                                                                                                                         DimensionAttribute::findByLocalizedName(DimensionSet[hierarchyIdx],false,"en-us");

            if(dimensionAttribute)
            {
                dimensionAttributeValue =                                                                                                                     DimensionAttributeValue::findByDimensionAttributeAndValue(
                                                         dimensionAttribute,conPeek(_conData,hierarchyIdx));

                if(dimensionAttributeValue)
                {
                    ValueContract = new DimensionAttributeValueContract();
                    ValueContract.parmName(dimensionAttribute.Name) ;
                    ValueContract.parmValue(dimensionAttributeValue.CachedDisplayValue);
                    valueContracts.addEnd(ValueContract);
                }
            }
        }
        LedgerAccountContract.parmMainAccount(_mainAccountNum);
        LedgerAccountContract.parmValues(valueContracts);
        dimStorage                          =    DimensionServiceProvider::buildDimensionStorageForLedgerAccount(LedgerAccountContract);
        dimensionAttributeValueCombination  =    DimensionAttributeValueCombination::find(dimStorage.save());
        ledgerRecId                         =    dimensionAttributeValueCombination.RecId;

        return ledgerRecId;
    }


Happy Coding !!!!

Tuesday, August 13, 2019

How to create or update customers using x++ in D365 FO

Hey folks ,

This code will be helpful where the requirement is either to create or update customers using x++.

In my example I have used this code to pickup the values for customer creation from a staging table.

The code is shown below :-

        #define.CountryRegionId("US")
        CustomerDetails                                 customerDetailsStaging, custMasterupdate;
        LogisticsElectronicAddress                logisticselectronicaddress;
        LogisticsContactInfoView                  logisticsContactInfoView;
        LogisticsPostalAddress                       logisticspostaladdress;
        LogisticsLocation                                logisticslocation;
        CustTable                                             custTable, custTableUpdate, custTableFind;
        DirParty                                                dirParty;
        DirPartyLocation                                  dirPartyLocation;
        DirPartyContactInfoView                    dirPartyContactInfo;
        DirPartyTable                                       dirPartyTable;
        ContactPerson                                       contactperson;
        DirPartyPostalAddressView                 dirPartyPostalAddressView;
        LanguageId                                           languageId      =   CompanyInfo::find().LanguageId;
        LogisticsPostalAddress                         address;
        DirPartyPostalAddressView                 addressView;
        LogisticsLocationRole                          roles;
        TaxVATNumTable                                taxvatnumtableget , taxvatnumtableins;
        DimensionAttributeValue                     dimAttrBINValue,dimAtrContractValue;
        DimensionAttribute                              dimAttrBIN,dimAtrContract;
        DimensionAttributeValueSetStorage   davss;
        RecId                                                    defaultDimension;
                     

     
        while select customerDetailsStaging where customerDetailsStaging.RecId!=0
        {
            custTable = CustTable::find(customerDetailsStaging.CustomerId);
            try
            {
                if(!custTable)
                {
                    davss = DimensionAttributeValueSetStorage::find(
                                 CustTable::find(custTable.AccountNum).DefaultDimension);
                    ttsBegin;
                    custTable.clear();
                    custTable.initValue();
                    custTable.AccountNum                =   customerDetailsStaging.CustomerId;
                    custTable.CustGroup                 =   customerDetailsStaging.CustGroup;
                    custTable.CustClassificationId      =   customerDetailsStaging.CustClassGroup;
                    custTable.VATNum                    =   customerDetailsStaging.TRNNo;
                    custTable.INTC_Emirates             =   customerDetailsStaging.Emirates;
                    custTable.TaxGroup                  =   customerDetailsStaging.VAT;
                    custTable.PaymTermId                =   customerDetailsStaging.PaymentTerms;

                    dimAttrBIN                          =   DimensionAttribute::findByName("BIN");
                    dimAtrContract                      =   DimensionAttribute::findByName("Contract");
                    dimAttrBINValue       =                                   DimensionAttributeValue::findByDimensionAttributeAndValue(
                         dimAttrBIN,                  customerDetailsStaging.BIN, false, true);
                    dimAtrContractValue                 =   DimensionAttributeValue::findByDimensionAttributeAndValue(dimAtrContract, customerDetailsStaging.Contract, false, true);

                    if(dimAttrBINValue || dimAtrContractValue)
                    {
                        davss.addItem(dimAttrBINValue);
                        davss.addItem(dimAtrContractValue);
                        custTable.DefaultDimension = davss.save();
                    }

                    custTable.insert(DirPartyType::Organization, customerDetailsStaging.CustomerName);
                    dirParty = DirParty::constructFromCommon(custTable);
             
                    dirPartyPostalAddressView.Street            =   customerDetailsStaging.Address;
                    dirPartyPostalAddressView.CountryRegionId   =   #CountryRegionId;
                    dirPartyPostalAddressView.IsPrimary         =   NoYes::Yes;

                    dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);
                    ttsCommit;

               
                    if(customerDetailsStaging.TRNNo!='0')
                    {
                        select taxvatnumtableget where taxvatnumtableget.CountryRegionId=='ARE'
                            && taxvatnumtableget.VATNum==customerDetailsStaging.TRNNo &&
                            taxvatnumtableget.Name==custTable.name();
                     
                        if(!taxvatnumtableget)
                        {
                            ttsbegin;
                            taxvatnumtableins.CountryRegionId = "ARE";
                            taxvatnumtableins.VATNum = customerDetailsStaging.TRNNo;
                            taxvatnumtableins.Name = custTable.name();
                            taxvatnumtableins.insert();
                            ttscommit;
                        }
                    }

                }

                else if(custTable)
                {
                    dirParty = DirParty::constructFromCommon(custTable);

                    select taxVatNumTablefetch where taxVatNumTablefetch.Name==custTable.name() && taxVatNumTablefetch.VATNum!='0';

                    select forupdate custTableUpdate where custTableUpdate.AccountNum   ==  custTable.AccountNum;
                    {
                        davss = DimensionAttributeValueSetStorage::find(CustTable::find(custTable.AccountNum).DefaultDimension);
                        ttsbegin;
                        custTableUpdate.CustGroup               =   customerDetailsStaging.CustGroup;
                        custTableUpdate.CustClassificationId    =   customerDetailsStaging.CustClassGroup;
                        custTableUpdate.VATNum                  =   customerDetailsStaging.TRNNo;
                        custTableUpdate.INTC_Emirates           =   customerDetailsStaging.Emirates;
                        custTableUpdate.TaxGroup                =   customerDetailsStaging.VAT;
                        custTableUpdate.PaymTermId              =   customerDetailsStaging.PaymentTerms;

                        dimAttrBIN          =   DimensionAttribute::findByName("BIN");
                        dimAtrContract      =   DimensionAttribute::findByName("Contract");
                        dimAttrBINValue     =   DimensionAttributeValue::findByDimensionAttributeAndValue(dimAttrBIN, customerDetailsStaging.BIN, false, true);
                        dimAtrContractValue =   DimensionAttributeValue::findByDimensionAttributeAndValue(dimAtrContract, customerDetailsStaging.Contract, false, true);

                        if(dimAttrBINValue || dimAtrContractValue)
                        {
                            davss.addItem(dimAttrBINValue);
                            davss.addItem(dimAtrContractValue);
                            custTableUpdate.DefaultDimension = davss.save();
                        }
                        custTableUpdate.update();
                        ttscommit;
                    }

                    ttsbegin;
                    while select dirPartyLocation
                        where dirPartyLocation.Party == custTable.Party
                        join dirPartyPostalAddressView
                        where dirPartyPostalAddressView.Location == dirPartyLocation.Location
                        && dirPartyPostalAddressView.Party == dirPartyLocation.Party
                    {
                        dirPartyPostalAddressView.Street            =   customerDetailsStaging.Address;
                        dirPartyPostalAddressView.CountryRegionId   =   #CountryRegionId;
                        dirPartyPostalAddressView.IsPrimary         =   NoYes::Yes;
                        dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);
                    }

                    if(!dirPartyLocation)
                    {
                        address.Street          =   customerDetailsStaging.Address;
                        address.CountryRegionId =   #CountryRegionId;

                        addressView.Party       =   custtable.Party;
                        addressView.IsPrimary   =   NoYes::Yes;
                        addressview.initFromPostalAddress(address);

                        DirParty = DirParty::constructFromPartyRecId(CustTable.Party);
                        roles = LogisticsLocationRole::findBytype(LogisticsLocationRoleType::Delivery);
                        DirParty.createOrUpdatePostalAddress(addressView);
                    }
                    ttscommit;

                    if(customerDetailsStaging.TRNNo!='0')
                    {
                        select taxvatnumtableget where taxvatnumtableget.CountryRegionId=='ARE'
                            && taxvatnumtableget.VATNum==customerDetailsStaging.TRNNo &&
                            taxvatnumtableget.Name==custTable.name();
                     
                        if(!taxvatnumtableget)
                        {
                            ttsbegin;
                            taxvatnumtableins.CountryRegionId = "ARE";
                            taxvatnumtableins.VATNum = customerDetailsStaging.TRNNo;
                            taxvatnumtableins.Name = custTable.name();
                            taxvatnumtableins.insert();
                            ttscommit;
                        }
                    }
                 
               
                }
             
            }
            catch(Exception::Error)
            {
                throw Exception::Error;
            }
        }


Happy Coding!!!

Sunday, August 11, 2019

How to create or update vendor using x++ in D365 FO



Hey folks ,


Using the below code we can easily create or update vendors in D365 FO.

The example I am using is picking the values for vendor creation from a staging table :-


 VendTable                                       vendTable, vendTableFind, vendTableUpdate;
 DirParty                                          dirParty;
 DirPartyPostalAddressView           dirPartyPostalAddressView;
 DirPartyContactInfoView              dirPartyContactInfo, dirPartyContactEmail, dirPartyContactFax;
 DirPartyTable                                 dirPartyTable;
 PurchData                                       vendorStaging , vendorStagingUpdate;

 DirPartyLocation                           dirPartyLocation;
 ContactPerson                                contactperson;
 LogisticsPostalAddress                  address;
 DirPartyPostalAddressView          addressView;
 LogisticsLocationRole                   roles;

        while select vendorStaging
        {
            vendTableFind   =   VendTable::find(vendorStaging.SupplierCode);
            try
            {
                if(!vendTableFind)
                {
                    ttsBegin;
                    vendTable.initValue();
                    vendTable.AccountNum        =       vendorStaging.SupplierCode;
                    vendTable.VendGroup         =       vendorStaging.VendGroup;
                    vendTable.Currency          =       vendorStaging.Currency;
                    vendTable.PaymTermId        =       vendorStaging.PaymentTerms;
                    vendTable.TaxGroup          =       vendorStaging.TaxCode;
                    vendTable.INTC_Emirates     =       vendorStaging.Emirates;
                    vendTable.VATNum            =       vendorStaging.TRNNo;
                    vendTable.insert();

                    dirPartyTable               =       DirPartyTable::findRec(vendTable.Party, true);
                    dirPartyTable.Name          =       vendorStaging.SupplierName;
                    dirPartyTable.update();

                    dirParty = DirParty::constructFromCommon(vendTable);

                    dirPartyPostalAddressView.Street            = vendorStaging.Address;
                    dirPartyPostalAddressView.CountryRegionId   = 'ARE';
                    dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);

                    //phone
                    dirPartyContactInfo.LocationName    =   'Phone';
                    dirPartyContactInfo.Locator         =   vendorStaging.ContactInfoPhoneNo;
                    dirPartyContactInfo.Type            =   LogisticsElectronicAddressMethodType::Phone;
                    dirPartyContactInfo.IsPrimary       =   NoYes::Yes;
                    dirParty.createOrUpdateContactInfo(dirPartyContactInfo);

                    //Email
                    dirPartyContactEmail.LocationName   =   'Email';
                    dirPartyContactEmail.Locator        =   vendorStaging.ContactInfoEmailAddress;
                    dirPartyContactEmail.Type           =   LogisticsElectronicAddressMethodType::Email;
                    dirPartyContactEmail.IsPrimary      =   NoYes::Yes;
                    dirParty.createOrUpdateContactInfo(dirPartyContactEmail);

                    //Fax
                    dirPartyContactFax.LocationName     =   'Fax';
                    dirPartyContactFax.Locator          =   vendorStaging.ContactInfoFax;
                    dirPartyContactFax.Type             =   LogisticsElectronicAddressMethodType::Fax;
                    dirPartyContactFax.IsPrimary        =   NoYes::Yes;

                    dirParty.createOrUpdateContactInfo(dirPartyContactFax);
                    ttsCommit;

                    select forupdate vendorStagingUpdate
                              where vendorStagingUpdate.RecId==  vendorStaging.RecId;

                    ttsbegin;
                    vendorStagingUpdate.UpdateFlag  =   1;
                    vendorStagingUpdate.update();
                    ttscommit;
                 
                }
                else if(vendTableFind)
                {
                    dirParty = DirParty::constructFromCommon(vendTableFind);

                    select forupdate vendTableUpdate
                              where vendTableUpdate.AccountNum   ==  vendTableFind.AccountNum;
                    {
                        ttsbegin;
                        vendTableUpdate.VendGroup           =       vendorStaging.VendGroup;
                        vendTableUpdate.Currency            =       vendorStaging.Currency;
                        vendTableUpdate.PaymTermId          =       vendorStaging.PaymentTerms;
                        vendTableUpdate.TaxGroup            =       vendorStaging.TaxCode;
                        vendTableUpdate.INTC_Emirates       =       vendorStaging.Emirates;
                        vendTableUpdate.VATNum              =       vendorStaging.TRNNo;
                        vendTableUpdate.INTC_BankAccountId  =       vendorStaging.BankCode;
                        vendTableUpdate.INTC_BankAccountName =      vendorStaging.BankName;
                        vendTableUpdate.update();
                        ttscommit;
                    }

                    ttsbegin;
                    dirPartyPostalAddressView.Street            =   vendorStaging.Address;
                    dirPartyPostalAddressView.CountryRegionId   =   "ARE";
                    dirPartyPostalAddressView.IsPrimary         =   NoYes::Yes;
                    dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);

                    if(!(dirParty.getContactInfo(vendTableFind.RecId)))
                    {
                        //phone
                        dirPartyContactInfo.LocationName    =   'Phone';
                        dirPartyContactInfo.Locator         =   vendorStaging.ContactInfoPhoneNo;
                        dirPartyContactInfo.Type            =   LogisticsElectronicAddressMethodType::Phone;
                        dirPartyContactInfo.IsPrimary       =   NoYes::Yes;
                        dirParty.createOrUpdateContactInfo(dirPartyContactInfo);

                        //Email
                        dirPartyContactEmail.LocationName   =   'Email';
                        dirPartyContactEmail.Locator        =   vendorStaging.ContactInfoEmailAddress;
                        dirPartyContactEmail.Type           =   LogisticsElectronicAddressMethodType::Email;
                        dirPartyContactEmail.IsPrimary      =   NoYes::Yes;
                        dirParty.createOrUpdateContactInfo(dirPartyContactEmail);

                        //Fax
                        dirPartyContactFax.LocationName     =   'Fax';
                        dirPartyContactFax.Locator          =   vendorStaging.ContactInfoFax;
                        dirPartyContactFax.Type             =   LogisticsElectronicAddressMethodType::Fax;
                        dirPartyContactFax.IsPrimary        =   NoYes::Yes;

                        dirParty.createOrUpdateContactInfo(dirPartyContactFax);
                    }
                    ttscommit;

               
                }
            }
            catch(Exception::Error)
            {
                throw Exception::Error;
            }
        }


Please let me know in comments in case of any further queries.

Happy Coding!!!

Sunday, June 23, 2019

How to send multiple Free Text Invoices for direct printing to printer using x++ D365 FO

One of the typical requirements from most of the customers is to directly send multiple Posted Customer Invoices to the Network Printer so that we can save ourselves from the pain of Exporting to PDF files manually and printing them later.


Before we write the code to achieve this functionality. We need to follow few steps which are mentioned below :-


1) Go to Organization Administration --> Setup --> Network Printers --> download Microsoft

Dynamics Routing Agent (You can find this in action pane)

2) Once downloaded and installed open DRA

3) Go to settings and enter the D365 URL and Azure AD tenant :-
 
          D365 URL :- https://abc-aos.ax.dynamics.com

          Azure AD Tenant :- abcxyz.onmicrosoft.com

4) Do not select the option Run as Windows Service

5) Close the application and reopen it

6) Enter the credentials for the Azure AD Tenant

7)Click Printers and it will show all the printers available on your specific network

8) Mark your required printers and click Register


Once done write the below code in an event handler :-


 [FormControlEventHandler(formControlStr(CustFreeInvoice, BulkInvoicePrint), FormControlEventType::Clicked)]
    public static void BulkInvoicePrint_OnClicked(FormControl sender, FormControlEventArgs e)
    {
        int                                             loop;
        FormDataSource                      fds;
        MultiSelectionHelper               selectionHelper = MultiSelectionHelper::construct();
        Set                                             selectedRecords = new Set(Types::Record);
        CustPrintOutInvoice                 custPrintOutInvoice;
        NoYes                                       usePrintManagement;
        RecordSortedList                      recordSortedList;
        CustInvoiceTable                      currentCustInvoiceTable;
        SalesInvoiceJournalPrint          salesInvoiceJournalPrint;
        CustInvoiceJour                        custInvoiceJour;
        CustInvoiceTable                      currCustInvoiceTable;
        SRSPrintDestinationSettings    srsPrintDestinationSettings;
        RecordSortedList                      custInvoiceJourList;
        RecordSortedList                      rsl;
        SrsReportRunController              controller = new SrsReportRunController();
        FreeTextInvoiceContract  rdpContract = new FreeTextInvoiceContract();
        SysCorpNetPrinters                      netPrinters;
     

        fds = sender.formRun().dataSource('CustInvoiceTable');

        rsl = FreeTextInvoiceEventHandler::getSelectedRecords(fds);

        Args args = new Args();

        select firstonly netPrinters where
        netPrinters.Active == NoYesCombo::Yes &&
            netPrinters.EnableSalesInvoiceDocumentPrint==NoYes::Yes;

        custInvoiceJourList = new RecordSortedList(tableNum(CustInvoiceJour));
        custInvoiceJourList.sortOrder(fieldNum(CustInvoiceJour, RecId));

        for (loop = rsl.len(); loop > 0; loop--)
        {
            rsl.next(currentCustInvoiceTable);
            custInvoiceJour = currentCustInvoiceTable.custInvoiceJour();
            if (custInvoiceJour.RecId)
            {
                selectedRecords.add(custInvoiceJour);
           
                controller.parmReportName(ssrsReportStr(FreeTextInvoiceNew, Report));
             
                controller.parmExecutionMode(SysOperationExecutionMode::Synchronous);

                controller.parmShowDialog(false);

                rdpContract.parmRefRecid(currentCustInvoiceTable.RecId);
                rdpContract.parmInvoiceId(currentCustInvoiceTable.InvoiceId);

                controller.parmReportContract().parmRdpContract(rdpContract);

                srsPrintDestinationSettings = controller.parmReportContract().parmPrintSettings();
             
                srsPrintDestinationSettings.fromPage(1);
                srsPrintDestinationSettings.toPage(1);
                srsPrintDestinationSettings.landscape(false);
                srsPrintDestinationSettings.printerName(netPrinters.PrinterName);
                srsPrintDestinationSettings.printMediumType(SRSPrintMediumType::Printer);
                srsPrintDestinationSettings.numberOfCopies(1);
                srsPrintDestinationSettings.collate(false);
                controller.startOperation();
             
                stInvoiceJourList.ins(custInvoiceJour);
            }
         
        }

     



    }

 

     public static  RecordSortedList getSelectedRecords(FormDataSource fds1)
    {
        RecordSortedList recordSortedList;
        CustInvoiceTable currentCustInvoiceTable;

        recordSortedList = new RecordSortedList(tableNum(CustInvoiceTable));
        recordSortedList.sortOrder(fieldNum(CustInvoiceTable,RecId));

        currentCustInvoiceTable = Global::getFirstSelection(fds1);

        while (currentCustInvoiceTable)
        {
            recordSortedList.ins(currentCustInvoiceTable);
            currentCustInvoiceTable = fds1.getNext() as CustInvoiceTable;
        }

        return recordSortedList;
    }

How to post multiple Free Text Invoices using x++ D365 FO

These days one of the most common requirements is to post multiple Customer Invoices in a single click.


Here is an example :-

[FormControlEventHandler(formControlStr(CustFreeInvoice, BulkPost), FormControlEventType::Clicked)]
public static void BulkPost_OnClicked(FormControl sender, FormControlEventArgs e)
{

    FormDataSource                fds;
    MultiSelectionHelper         selectionHelper = MultiSelectionHelper::construct();
    Set                                       selectedRecords = new Set(Types::Record);
    CustInvoiceTable                custInvoiceTable;
    CustPostInvoice                  custPostInvoice;
     
        fds = sender.formRun().dataSource('CustInvoiceTable');

        custInvoiceTable = fds.cursor();

        selectionHelper.parmDataSource(fds);
        custInvoiceTable  = selectionHelper.getFirst();

        if (custInvoiceTable.RecId)
        {
            while (custInvoiceTable)
            {
                selectedRecords.add(custInvoiceTable);
                custPostInvoice = new CustPostInvoice(custInvoiceTable);
                custPostInvoice.run();
                custInvoiceTable = selectionHelper.getNext();
            }
        }

        fds.research();
        fds.reread();
        fds.refresh();

        Box::info('Invoice Posting Completed Successfully');
}

How to create a Dimension Value using x++ D365 FO

There are lot of tables holding values for Financial Dimensions such as DimensionAttributeValue and DimensionAttributeValueCombination but in case if we can't find the values in these above tables then we have another table known as DimensionFinancialTag through which we can get values as well as we can create new dimensions as well.


Here is an example mentioned below :-

        
 DimDetails                                          dimensiondetails;
 DimensionAttribute                             dimAttr;
 DimensionAttributeValue                    dimAttrValue;
 DimensionDefault                                result;
 DimensionFinancialTag                       dimFinTag , dimFinTagval;
 RecId                                                    dimFinancialCategoryRecid;
        
DimensionAttributeValueSetStorage   valueSetStorage = new 

DimensionAttributeValueSetStorage();

        try
        {
        dimAttr = DimensionAttribute::findByName('ABC');
        dimFinancialCategoryRecid = dimAttr.financialTagCategory();
        while select dimensiondetails where dimensiondetails.UpdateFlag==0
        {
            select dimFinTag where
                   dimFinTag.FinancialTagCategory == dimFinancialCategoryRecid &&
                   dimFinTag.Value == dimensiondetails.AssetCode;

            if(!dimFinTag.RecId)
            {
                dimFinTagval.Value = dimensiondetails.AssetCode;
                dimFinTagval.Description = dimensiondetails.AssetDescription;
                dimFinTagval.FinancialTagCategory = dimFinancialCategoryRecid;
                dimFinTagval.insert();
                
            }

            
        }

        }

        catch(Exception::Error)
        {
            ttsAbort;
            throw Exception::Error;
        }

Sunday, March 17, 2019

How to open a Web Page using x++ D365 FO

Hi Folks ,

All we need to do to achieve this is follow these simple steps :-


1) Create a Runnable Class

2) Write the following logic in the class :-

               class ABC
              {
                      public static void main(Args _args)
                      {
                            Browser browser = new Browser();
                            browser.navigate('www.google.com', true, false);
                       }

                }

         Same logic we can use in event handlers or on clicked event of a button.


         Happy Coding !!!!

Demystifying the SysOperation Framework in D365 F&O: Building Scalable and Maintainable Batch Jobs

 If you've been developing in Dynamics 365 Finance and Operations for a while, chances are you've either worked with or heard about ...