Tuesday, December 27, 2022

Posting Invoice/Product Receipt/Packing Slip - D365FO X++

Posting Vendor invoice based on Product receipt

public void postPurchaseInvoiceJournal()

    {

        VendPackingSlipJour             vendPackingSlipJour;

        VendPackingSlipTrans            vendPackingSlipTrans;

        TmpFrmVirtual                   tmpFrmVirtual;

        boolean                         isValidToProcess = false;

        container                       conTmpFrmVirtual;

        SysQueryRun                     chooseLinesQuery;

        SysQueryRun                     chooseLinesPendingInvoiceQuery;


        select firstonly vendPackingSlipJour

            order by RecId desc

            where vendPackingSlipJour.PackingSlipId == shipmentId;


        if(vendPackingSlipJour)

        {

            isValidToProcess = true;

        }


        chooseLinesQuery = new SysQueryRun(queryStr(PurchUpdate));

       

        List packingSlipList = new List(Types::Record);

        while select OrigPurchId from vendPackingSlipTrans

            group by OrigPurchId

            where vendPackingSlipTrans.PackingSlipId == vendPackingSlipJour.PackingSlipId

        {

            tmpFrmVirtual.clear();

            tmpFrmVirtual.TableNum      = tableNum(VendPackingSlipJour);

            tmpFrmVirtual.RecordNo      = vendPackingSlipJour.RecId;

            tmpFrmVirtual.NoYes         = NoYes::Yes;

            tmpFrmVirtual.Id            = vendPackingSlipTrans.OrigPurchId;

            tmpFrmVirtual.insert();


            packingSlipList.addEnd(tmpFrmVirtual);

            conTmpFrmVirtual            = packingSlipList.pack();


            chooseLinesQuery.query().dataSourceTable(tableNum(PurchTable)).addRange(fieldNum(PurchTable, PurchId)).value(queryValue(vendPackingSlipTrans.OrigPurchid));

        }


        chooseLinesQuery.query().interactive (false);

        chooseLinesQuery.saveUserSetup (false);

        chooseLinesQuery.query().addDataSource(tableNum(VendInvoiceInfoTable)).enabled(false);


        chooseLinesPendingInvoiceQuery = new SysQueryRun(queryStr(PurchUpdatePendingInvoice));

        chooseLinesPendingInvoiceQuery.query().dataSourceTable(tableNum(PurchTable)).addRange(fieldNum(PurchTable,PurchId)).value(queryValue(''));


        TransDate postingDate = getTodayDate;


        PurchFormLetter_Invoice purchFormLetter;

        purchFormLetter = PurchFormLetter::construct(DocumentStatus::Invoice);

        purchFormLetter.chooseLinesQuery (chooseLinesQuery);

        purchFormLetter.parmQueryChooseLinesPendingInvoice(chooseLinesPendingInvoiceQuery);

        purchFormLetter.transDate (postingDate);

        purchFormLetter.parmParmTableNum(shipmentId);

        purchFormLetter.printFormLetter (NoYes::No);

        purchFormLetter.sumBy (AccountOrder::Account);

        purchFormLetter.specQty (PurchUpdate::PackingSlip);

        purchFormLetter.selectFromJournal(conTmpFrmVirtual);

        purchFormLetter.reArrangeNow(true);         

        purchFormLetter.runOperation();


        if(purchFormLetter.parmJournalRecord())

        {            

            VendInvoiceJour                 invoiceJour;

            

            invoiceJour = VendInvoiceJour::findRecId(purchFormLetter.parmJournalRecord().RecId);

            if(invoiceJour)

            {

//Successful posting

            }

        }

    }


Process Customer invoice based on PackingSlip

--> Normal Sales order/ Direct delivery sales order

public void processSalesInvoiceDataToPost(str  _salesPackingSlipId)

    {

        salesFormletterParmData     salesFormLetterParmData;

        SalesParmUpdate             salesParmUpdate;

        SalesTable                  salesTable;

        SalesParmTable              salesParmTable;

        CustPackingSlipJour         custPackingSlipJour;

        CustPackingSlipTrans        custPackingSliptrans;

        SalesLine                   salesLine;


        TransDate postingDate = getToday;


        select firstonly custPackingSlipJour

            where custPackingSlipJour.PackingSlipId == _salesPackingSlipId;


        salesFormLetterParmData = salesFormletterParmData::newData(DocumentStatus::Invoice, VersioningUpdateType::Initial);

       

        salesFormLetterParmData.parmOnlyCreateParmUpdate(true);

        salesFormLetterParmData.parmProforma(this.parmIsProformaProcess());

        salesFormLetterParmData.createData(false);

        salesParmUpdate = salesFormLetterParmData.parmParmUpdate();


        InventTransOrigin       inventTransOrigin;

        InventTrans             inventTrans;


        if(_salesPackingSlipId)

        {

            salesTable  = salesTable::find(custPackingSlipJour.SalesId);

            salesParmTable.clear();

            salesParmTable.TransDate                = transportInvoiceTable.InvoiceDate;

            salesParmTable.Ordering                 = DocumentStatus::Invoice;

            salesParmTable.ParmJobStatus            = ParmJobStatus::Waiting;

            salesParmTable.salesId                  = salesTable.salesId;

            salesParmTable.salesName                = salesTable.salesName;

            salesParmTable.DeliveryName             = salesTable.DeliveryName;

            salesParmTable.DeliveryPostalAddress    = salesTable.DeliveryPostalAddress;

            salesParmTable.CustAccount              = salesTable.CustAccount;

            salesParmTable.CurrencyCode             = salesTable.CurrencyCode;

            salesParmTable.InvoiceAccount           = salesTable.InvoiceAccount;

            salesParmTable.ParmId                   = salesParmUpdate.ParmId;

            salesParmTable.insert();

       

            while select custPackingSliptrans group by OrigSalesId

                where custPackingSliptrans.PackingSlipId == custPackingSlipJour.PackingSlipId

                    && custPackingSliptrans.OrigSalesId != custPackingSlipJour.SalesId

            {

                this.processSalesParmSubTableData(salesParmTable, SalesTable::find(custPackingSliptrans.OrigSalesId));

            }

       

            custPackingSliptrans.clear();

            while select custPackingSliptrans

                where custPackingSliptrans.PackingSlipId == custPackingSlipJour.PackingSlipId

                    join salesLine

                        where salesLine.InventTransId == custPackingSliptrans.InventTransId

            {

                this.processSalesParmLinesTableData(salesParmTable, salesLine, custPackingSliptrans);

            }

        }

        else 

        {

            //Update reference on salesParmUpdate

            if(salesParmUpdate)

            {

                ttsbegin;

                salesParmUpdate.selectForUpdate(true);

                salesParmUpdate.SpecQty        = SalesUpdate::PickingList;

                salesParmUpdate.update();

                ttscommit;

            }

        SalesFormLetter_Invoice salesFormLetter = salesFormLetter::construct(DocumentStatus::Invoice);

        salesFormLetter.transDate(postingDate);

        salesFormLetter.proforma(this.parmIsProformaProcess()); 

         salesFormLetter.specQty(salesUpdate::PackingSlip); 

        salesFormLetter.salesTable(salesTable);

        salesFormLetter.parmId(salesParmTable.ParmId);

        salesFormLetter.salesParmUpdate(salesFormLetterParmData.parmParmUpdate());

        if(//Need print destination setting)

        {

            SRSPrintDestinationSettings     printSettings = new SRSPrintDestinationSettings();

            PrintSetupOriginalCopy          printSetupOriginalCopy;


            printSetupOriginalCopy = this.parmIsProformaProcess() ? PrintSetupOriginalCopy::Copy : PrintSetupOriginalCopy::Original;

            printSettings = new SRSPrintDestinationSettings(salesFormLetter.printerSettingsFormletter(printSetupOriginalCopy));

            printSettings.printMediumType(PrintMediumType::Printer);

            //printSettings.DestinationSettings(printSettings);

            salesFormLetter.updatePrinterSettingsFormLetter(printSettings.pack());

        }

//To open FORM, User will click post

        salesFormLetter.startOperation();// process operation to post invoice

//To Direct POST without UI FORM open

        salesFormLetter.runOperation();// process operation to post invoice


        if (salesFormLetter.parmJournalRecord().RecId )

        {

// Success posting

        }

    }


    /// <summary>

    /// Process sales update parm history sub table data for posting invoice

    /// </summary>

    /// <param name = "_salesParmTable">current salesParmTable</param>

    /// <param name = "_SalesTable">current sales id to process</param>

    public void processSalesParmSubTableData(SalesParmTable     _salesParmTable, SalesTable     _SalesTable)

    {

        SalesParmSubTable       parmSubTable;


        parmSubTable.clear();

        parmSubTable.initValue();

        parmSubTable.InitFromSalesParmTable(_salesParmTable);

        parmSubTable.initFromSalesTable(_SalesTable);

        parmSubTable.insert();

    }


    /// <summary>

    /// Process sales update parm history sub line table data for posting invoice

    /// </summary>

    /// <param name = "_salesParmTable">current salesParmTable</param>

    /// <param name = "_salesLine">current salesLine</param>

    /// <param name = "_custPackingSliptrans">current custPackingslipTrans</param>

    /// <param name = "_qty">current trasnprot line qty</param>

    public void processSalesParmLinesTableData(SalesParmTable       _salesParmTable, SalesLine      _salesLine, CustPackingSlipTrans    _custPackingSliptrans, Qty      _qty = 0)

    {

        SalesParmLine       salesParmLine;

        SalesParmSubLine    salesParmSubLine;


        salesParmLine.clear();

        salesParmLine.initValue();

        salesParmLine.InitFromsalesLine(_salesLine);

        salesParmLine.DeliverNow    = _qty ? _qty : _custPackingSliptrans.Qty;  

        salesParmLine.ParmId        = _salesParmTable.ParmId;

        salesParmLine.TableRefId    = _salesParmTable.TableRefId;

        salesParmLine.setQty(DocumentStatus::Invoice, false, true);

        salesParmLine.setLineAmount(_salesLine);

        salesParmLine.insert();


        salesParmSubLine.clear();

        salesParmSubLine.initValue();

        salesParmSubLine.initFromCustPackingSlipTrans(_custPackingSliptrans);

        salesParmSubLine.initFromSalesParmLine(salesParmLine);

        if(_custPackingSliptrans    == null) 

        {

            salesParmSubLine.InventNow              = _qty;

            salesParmSubLine.DeliverNow             = _qty;

        }

        salesParmSubLine.insert();

    }


    public void processMultipleSOInvoice()

    {

        SalesFormLetter_invoice salesFormLetter;

        CustPackingSlipJour custPackingSlipJour;

        TmpFrmVirtual tmpFrmVirtual;

        salesFormletterParmData     salesFormLetterParmData;

        SalesParmLine   salesParmLine;

        SalesParmUpdate             salesParmUpdate;

        List selectedList = new List(Types::Record);


        tmpFrmVirtual.setTmp();     

        while select from custPackingSlipJour

            where custPackingSlipJour.ReferenceId== 'ReferenceId' //Reference Id custom field

        {          


            tmpFrmVirtual.clear();

            tmpFrmVirtual.TableNum = custPackingSlipJour.TableId;

            tmpFrmVirtual.RecordNo = custPackingSlipJour.RecId;

            tmpFrmVirtual.NoYes = NoYes::Yes;

            tmpFrmVirtual.Id = custPackingSlipJour.SalesId;

            tmpFrmVirtual.insert();

            if (!salesParmUpdate)

            {

                salesFormLetterParmData = salesFormletterParmData::newData(DocumentStatus::Invoice, VersioningUpdateType::Initial);

       

                salesFormLetterParmData.parmOnlyCreateParmUpdate(true);

                salesFormLetterParmData.parmProforma(this.parmIsProformaProcess());//Added code bug fix 410277

                salesFormLetterParmData.createData(false);

                salesParmUpdate = salesFormLetterParmData.parmParmUpdate();

            }

            this.processMultipleSalesInvoiceParmData(custPackingSlipJour,salesParmUpdate);

        }


        while select tmpFrmVirtual

        {

            selectedList.addEnd(tmpFrmVirtual);

        }


     

        // Construct form letter

        salesFormLetter = salesFormLetter::construct(DocumentStatus::Invoice);

        // Add the packing slips to the sales form letter

        salesFormLetter.selectFromJournal(selectedList.pack());

        select firstonly salesParmLine

               where salesParmLine.ParmId == salesParmUpdate.ParmId;

       

        if(salesParmLine)

       

        {

            salesFormLetter.salesParmUpdate(salesParmUpdate);

        }

        // Reorganize as desired

        salesFormLetter.specQty(SalesUpdate::PackingSlip);

        salesFormLetter.sumBy(AccountOrder::Auto);

        salesFormLetter.transDate(transportInvoiceTable.InvoiceDate);

   


        salesFormLetter.reArrangeNow(true);

        salesFormLetter.parmId(salesParmUpdate.ParmId);

        salesFormLetter.startOperation();

     

    }


    public void processMultipleSalesInvoiceParmData(CustPackingSlipJour _custPackingSlipJour,

                                            SalesParmUpdate     _salesParmUpdate)

    {

        SalesParmUpdate             salesParmUpdate = _salesParmUpdate;

        SalesTable                  salesTable;

        SalesParmTable              salesParmTable;

        CustPackingSlipJour         custPackingSlipJour = _custPackingSlipJour;

        CustPackingSlipTrans        custPackingSliptrans;

        SalesLine                   salesLine;


        TransDate postingDate = getToday;


        if(_custPackingSlipJour.PackingSlipId)

        {

            salesTable  = salesTable::find(custPackingSlipJour.SalesId);

            salesParmTable.clear();

            salesParmTable.TransDate                = transportInvoiceTable.InvoiceDate;

            salesParmTable.Ordering                 = DocumentStatus::Invoice;

            salesParmTable.ParmJobStatus            = ParmJobStatus::Waiting;

            salesParmTable.salesId                  = salesTable.salesId;

            salesParmTable.salesName                = salesTable.salesName;

            salesParmTable.DeliveryName             = salesTable.DeliveryName;

            salesParmTable.DeliveryPostalAddress    = salesTable.DeliveryPostalAddress;

            salesParmTable.CustAccount              = salesTable.CustAccount;

            salesParmTable.CurrencyCode             = salesTable.CurrencyCode;

            salesParmTable.InvoiceAccount           = salesTable.InvoiceAccount;

            salesParmTable.ParmId                   = salesParmUpdate.ParmId;

            salesParmTable.insert();

       

            while select custPackingSliptrans group by OrigSalesId

                where custPackingSliptrans.PackingSlipId == custPackingSlipJour.PackingSlipId

                    && custPackingSliptrans.OrigSalesId != custPackingSlipJour.SalesId

            {

                this.processSalesParmSubTableData(salesParmTable, SalesTable::find(custPackingSliptrans.OrigSalesId));

            }

       

            custPackingSliptrans.clear();

            while select custPackingSliptrans

                where custPackingSliptrans.PackingSlipId == custPackingSlipJour.PackingSlipId

                    join salesLine

                        where salesLine.InventTransId == custPackingSliptrans.InventTransId

            {

                this.processSalesParmLinesTableData(salesParmTable, salesLine, custPackingSliptrans);

            }

        }

       

    }


Process Purchase product receipt - Post

public void postProductReceiptJournal()

    {

        PurchFormLetter             purchFormLetter;

        PurchFormletterParmData     purchFormLetterParmData;

        PurchParmUpdate             purchParmUpdate;

        PurchParmTable              purchParmTable;       

        SanJournalTrans   jourTrans; //Custom table

        PurchTable                  purchTable;

        PurchLine                   purchLine;

        PurchId                     purchId;

        container                   conPurchList;

        Num                         packingSlipId = purchInvoiceHeaderInbound.InvoiceId;


        purchFormLetterParmData = PurchFormletterParmData::newData(

        DocumentStatus::PackingSlip,

        VersioningUpdateType::Initial);


        select firstonly jourTrans

            where jourTrans.JournalId == this.journalId;

        purchId = jourTrans.PurchId;


        purchTable = PurchTable::find(purchId, false);

    

        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;

        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();


        if(purchTable)

        {

            conPurchList += [purchTable.PurchId];

        }


        // Set PurchParmLine table

        jourTrans.clear();

        while select jourTrans

            where jourTrans.JournalId == this.journalId

                && jourTrans.purchId && jourTrans.SourceLineNumber

            join purchLine

                where purchLine.PurchId == jourTrans.purchId

                && purchLine.POL_OriginalLotID == jourTrans.SourceLineNumber

        {

            if(!conFind(conPurchList, purchTable.PurchId))

            {

                conPurchList += [jourTrans.PurchId];

                this.processPurchParmSubTable(purchParmTable,jourTrans.PurchId );

            }

            this.processPurchParmLine(purchLine, purchParmTable, jourTrans.Quantity);

        }


        purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);

        purchFormLetter.transDate(systemDateGet());

        purchFormLetter.proforma(false);

        purchFormLetter.specQty(PurchUpdate::All);

        purchFormLetter.purchTable(purchTable);

        purchFormLetter.parmParmTableNum(purchParmTable.ParmId);

        purchFormLetter.parmId(purchParmTable.ParmId);

        purchFormLetter.purchParmUpdate(purchFormLetterParmData.parmParmUpdate());

        purchFormLetter.runOperation();

        if(purchFormLetter.parmJournalRecord())

        {

            shipmentId = '';//Can get here posted number

        }

    }


    private void processPurchParmLine(PurchLine _purchLine, PurchParmTable  _purchParmTable, Qty        _curQty)

    {

        PurchParmLine               purchParmLine;


        purchParmLine.InitFromPurchLine(_purchLine);

        purchParmLine.ReceiveNow    = _curQty;

        purchParmLine.ParmId        = _purchParmTable.ParmId;

        purchParmLine.TableRefId    = _purchParmTable.TableRefId;

        purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);

        purchParmLine.setLineAmount();

        purchParmLine.insert();

        this.processPurchParmSubLine(purchParmLine);

    }


    private void processPurchParmSubLine(PurchParmLine  _purchParmLine)

    {

        PurchParmSubLine               purchParmSubLine;


        purchParmSubLine.ParmId               = _purchParmLine.ParmId;

        purchParmSubLine.LineRefRecId         = _purchParmLine.RecId;

        purchParmSubLine.ReceiveNow           = _purchParmLine.ReceiveNow;

        purchParmSubLine.JournalRefRecId      = _purchParmLine.RecId;

        purchParmSubLine.JournalRefTableId    = _purchParmLine.TableId;

        purchParmSubLine.insert();

    }


    private void processPurchParmSubTable(PurchParmTable  _purchParmTable, PurchId  _origPurchId)

    {

        PurchParmSubTable       purchParmSubTable;

        PurchTable              purchTable = PurchTable::find(_origPurchId,false);


        purchParmSubTable.OrigPurchId   = _origPurchId;

        purchParmSubTable.ParmId        = _purchParmTable.ParmId;

        purchParmSubTable.TableRefId    = _purchParmTable.TableRefId;

        purchParmSubTable.PurchName     = purchTable.PurchName;

        AccountingEvent accountingEvent;

        select firstonly accountingEvent

            order by CreatedDateTime desc

            where accountingEvent.SourceDocumentHeader == purchTable.SourceDocumentHeader

                && accountingEvent.Type != AccountingEventType::PeriodClose;


        purchParmSubTable.SourceAccountingEvent   = accountingEvent.RecId;

        purchParmSubTable.insert();

    }


Process Sales packing slip - Post

In Progress

Tuesday, December 20, 2022

ADF expression - Sample & examples

ForEach loop,

@Item()

GetMetaData

@Item().Name

FileFormat -> yyMMdd_HHmmss

FormatDateTime:

@formatDateTime(utcnow(),'yyyy-MM-dd HH:mm:ss')

Date to integer to string

concat(Column_2,'_',toString(toDate(Column_3, 'MM/dd/yyyy','en-US'), 'yyyyMMdd')) 

Str upper ->  upper('test')

concat ->  concat('test-1','_','test-2')

Data Flow: SinkDataset ( enable -> optimize ->  Single partition)


If expression (Data flow)

iif(GROUPNAME == 'WG', 'Y', 'N')

Compare -> 

Ex

 iif((compare(TABLENAME,"VENDTABLE")>0),iif(isNull(sendVendorId), concat(ACCOUNTNUM,'_',PARTY,'_',PARTNERDATAAREAID),ACCOUNTNUM ),concat(ACCOUNTNUM,'_',PARTY,'_',PARTNERDATAAREAID))

iif((compare(TABLENAME,"VENDTABLE")>0),"SUPPLIER","CUSTOMER")

iif((compare(TABLENAME,"PurchLine")>0),"0",toString(round(toDecimal(EXTENDEDPRICE),2)))

iif((compare(TABLENAME,"PurchLine")>0),"SO","PO")

Agreegate: first('fieldname')

Filter On: TABLENAME == "VendTable"

Address street (3 fields)
Derived column1:
Address1-> split(STREET, "\n")

Derived column2:
Address1 ->
replace(iif(length(STREET) > 100, substring(STREET,1, 100), Address1[1]),'\n',' ')

Address2 ->replace(iif(length(STREET) > 100, substring(STREET,101, 100), iif(size(Address1) > 1,Address1[2], '')),'\n',' ')

Address3 ->replace(iif(length(STREET) > 200, substring(STREET,201, 100), iif(size(Address1 ) > 2,Address1 [3], '')),'\n',' ')

substring: (replace .csv to .zip)
@concat(
    substring(
        dataset().p_fileName,
        0,
        sub(
            length(dataset().p_fileName)
            ,4)
    ),'.zip'
)
Replace -> replace(toString(DATE,'YYYY-MM-DD'),'00:00:00','')

Dataset:
UTF-8 (format by D365FO DMF)

Friday, December 2, 2022

Auto Approve purchTable X++ in D365FO

 VersioningPurchaseOrder versioningPurchaseOrder;


        if (_PurchTable.ChangeRequestRequired)

        {

            versioningPurchaseOrder = VersioningPurchaseOrder::newPurchaseOrder(_PurchTable);

            versioningPurchaseOrder.submitChangeRequest();

            versioningPurchaseOrder.approveChangeRequest();

        }

Convert Call stack to readable format in D365FO X++

//Input --container _xppCallStack = xSession::xppCallStack();  Public static str POL_formatXppCallStack(container _xppCallStack, int _skipFr...