Make Partial and Fully Product Receipt of PO also make Partial and Fully Invoicing of PO in ax 2012 using X++

 In this blog we will discuss how to make partial and fully product receipt and also partial and fully invoice of PO using x++.

Importing data from .CSV Microsoft file which contain PO data and converting the purchase order status to invoiced status by a two-way matching process.  

Functional Process 

  • In AP Module > Accounts payable parameter we create an AP automation Tab. which contain file path and archieve folder path.


  • In periodic tab, there is an custom form AP automation. 

Process of  PO Data

  • Here is the .CSV file which contain PO data.

  • Upload file, and give Invoice number and product receipt number if PO status is opened order.
  • Process the file.
  • Now, Product receipt number and invoice number is created of that lines which are uploaded from the file.
  • Repeating same process to Invoice all lines of PO partially, to make the status of PO Invoiced.

Process of Non-PO Data

  • Upload Non PO data and process it.
  • It will create reference journal number and also journal in Invoice journal tab.

Technical Background

  •  For PO Data.
private boolean ProcessPO(PurchId     PONumber,    DataAreaId  Company)
{
    WBInvJournalStaging     _WBInvJournalStaging, _WBInvJournalStagingLoc = null;
    POStatus                            NENPOStatus;
    str                                                errorMsg = '';
    boolean                                       errorFound = false;
    InvoiceId                                    invoiceId;
    ProductReceiptId                        productReceiptId;

    PurchFormLetter_Invoice          purchFormLetter;
    PurchTable                                 purchTable,purchTableUpd;
    PurchLine                                  purchLine,partial_purchLine, purchLineLoc;
    PurchParmUpdate                     purchParmUpdate;
    Set                                             purchTableSet, purchLineSet;
    VendInvoiceInfoTable              vendInvoiceInfoTable,vendInvoiceInfoTableUpd;
    PurchId                                     purchId;
    PackingSlipId                           packingSlipId;
    SetIterator                                 setIteratorPurchLine, setIteratorPurchLine1;

    PurchFormLetter                     partial_purchFormLetter;
    PurchFormletterParmData      purchFormLetterParmData;
    PurchParmTable                      purchParmTable;
    PurchParmLine                       purchParmLine;
    PurchTable                              partial_purchTable,partial_purchTableLoc, localPurchTable, localPurchTableTest;                                                                   
    Num                                         partial_packingSlipId;
    ;

    while select _WBInvJournalStaging
            where _WBInvJournalStaging.Status == NENPOStatus::Ready && _WBInvJournalStaging.PoNumber == PONumber && _WBInvJournalStaging.Company == Company
            exists join localPurchTable
            where localPurchTable.PurchId == _WBInvJournalStaging.PoNumber && localPurchTable.PurchStatus == PurchStatus::Backorder
            {
                purchId                 = _WBInvJournalStaging.PoNumber;
                partial_packingSlipId   = _WBInvJournalStaging.PackingSlipReference;
                partial_purchTable      = PurchTable::find(purchId);

                if (partial_purchTable.PurchStatus == PurchStatus::Backorder)
                {
                    purchId                 = _WBInvJournalStaging.PoNumber;
                    partial_packingSlipId   = _WBInvJournalStaging.PackingSlipReference;
                    partial_purchTable      = PurchTable::find(purchId);

                    if (partial_purchTable.PurchStatus == PurchStatus::Backorder)
                    {
                        // Create PurchParamUpdate table
                        // If file contains 3 PO lines out 5. So, this condition make 1 header of 3 lines. Product number should be the same of 3 lines.
                        if (productReceiptId != partial_packingSlipId )
                        {
                            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                      = partial_packingSlipId;
                            purchParmTable.PurchId                  = partial_purchTable.PurchId;
                            purchParmTable.PurchName                = partial_purchTable.PurchName;
                            purchParmTable.DeliveryName             = partial_purchTable.DeliveryName;
                            purchParmTable.DeliveryPostalAddress    = partial_purchTable.DeliveryPostalAddress;
                            purchParmTable.OrderAccount             = partial_purchTable.OrderAccount;
                            purchParmTable.CurrencyCode             = partial_purchTable.CurrencyCode;
                            purchParmTable.InvoiceAccount           = partial_purchTable.InvoiceAccount;
                            purchParmTable.ParmId                   = purchParmUpdate.ParmId;
                            purchParmTable.insert();
                            productReceiptId = _WBInvJournalStaging.PackingSlipReference;
                        }

                        // Set PurchParmLine table
                        select partial_purchLine
                            where partial_purchLine.PurchId == partial_purchTable.purchId && partial_purchLine.LineNumber == _WBInvJournalStaging.POLineNumber;

                            purchParmLine.InitFromPurchLine(partial_purchLine);
                            purchParmLine.ReceiveNow    = _WBInvJournalStaging.Quantity;
                            purchParmLine.ParmId        = purchParmTable.ParmId;
                            purchParmLine.TableRefId    = purchParmTable.TableRefId;
                            purchParmLine.setQty(DocumentStatus::PackingSlip, false, true);
                            purchParmLine.setLineAmount();
                            purchParmLine.insert();

                    }

                }
             }

             select _WBInvJournalStaging
                where _WBInvJournalStaging.Status == NENPOStatus::Ready && _WBInvJournalStaging.PoNumber == PONumber && _WBInvJournalStaging.Company == Company
                exists join localPurchTable
                where localPurchTable.PurchId == _WBInvJournalStaging.PoNumber && localPurchTable.PurchStatus == PurchStatus::Backorder;
                if (_WBInvJournalStaging.recId)
                {
                    partial_purchTable = purchTable::find(_WBInvJournalStaging.PoNumber);
                    if (partial_purchTable.PurchStatus == PurchStatus::Backorder)
                    {
                        partial_purchFormLetter = PurchFormLetter::construct(DocumentStatus::PackingSlip);
                        partial_purchFormLetter.transDate(systemDateGet());
                        partial_purchFormLetter.proforma(false);
                        partial_purchFormLetter.specQty(PurchUpdate::ReceiveNow);
                        partial_purchFormLetter.purchTable(partial_purchTable);
                        partial_purchFormLetter.parmParmTableNum(purchParmTable.ParmId);
                        partial_purchFormLetter.parmId(purchParmTable.ParmId);
                        partial_purchFormLetter.purchParmUpdate(purchFormLetterParmData.parmParmUpdate());
                        partial_purchFormLetter.run();

                        info(strFmt('Product receipt created %1',purchParmTable.Num));

                        //Invoicing
                        purchTableSet = new Set(Types::String);
                        purchLineSet  = new Set(Types::Int64);

                        while select _WBInvJournalStagingLoc
                            order by _WBInvJournalStagingLoc.POLineNumber
                            where _WBInvJournalStagingLoc.Status == NENPOStatus::Ready && _WBInvJournalStagingLoc.PoNumber == partial_purchTable.PurchId
                            {
                                invoiceId = _WBInvJournalStagingLoc.Invoice;
                                purchTableSet.add(partial_purchTable.PurchId);

                                //update Qty to be invoiced
                                select forupdate purchLine
                                    where purchLine.PurchId == partial_purchTable.PurchId && purchLine.LineNumber == _WBInvJournalStagingLoc.POLineNumber;

                                    purchLine.PurchReceivedNow = _WBInvJournalStaging.Quantity;
                                    purchLine.update();
                                    purchLineSet.add(purchLine.RecId);
                            }

                            purchFormLetter = PurchFormLetter::construct(DocumentStatus::Invoice);
                            purchFormLetter.purchTable(partial_purchTable);
                            purchFormLetter.transDate(today());
                            purchFormLetter.specQty(PurchUpdate::PackingSlip);
                            purchFormLetter.printFormLetter(NoYes::No);
                            purchFormLetter.prePromptInit();
                            purchParmUpdate = purchFormLetter.purchParmUpdate();
                            purchFormLetter.initParameters(purchParmUpdate);
                            purchFormLetter.purchParmUpdate(purchParmUpdate);

                            vendInvoiceInfoTable = VendInvoiceInfoTable::findPurchId(partial_purchTable.PurchId, purchFormLetter.parmId(), true);
                            select forupdate vendInvoiceInfoTableUpd
                                where vendInvoiceInfoTableUpd.RecId == vendInvoiceInfoTable.RecId;
                            vendInvoiceInfoTableUpd.Num = invoiceId;
                            vendInvoiceInfoTableUpd.update();

                            setIteratorPurchLine = new SetIterator(purchLineSet);

                            purchFormLetter.purchSelectLines(purchTableSet, purchLineSet, vendInvoiceInfoTable);
                            if (purchFormLetter.validate())
                            {
                                purchFormLetter.reArrangeNow(false);
                                purchFormLetter.run();
                            }

                            info(strFmt("Invoiced %1 Posted successfully",vendInvoiceInfoTableUpd.Num));
                    }
                }

            // PO Receeived Order
            select _WBInvJournalStaging
                where _WBInvJournalStaging.Status == NENPOStatus::Ready && _WBInvJournalStaging.POnumber == PONumber && _WBInvJournalStaging.Company == Company
                exists join localPurchTable
                where localPurchTable.PurchId == _WBInvJournalStaging.PoNumber && localPurchTable.PurchStatus == PurchStatus::Received;

                if (_WBInvJournalStaging.RecId)
                {
                    partial_purchTable = purchTable::find(_WBInvJournalStaging.PoNumber);
                    if (partial_purchTable.PurchStatus == PurchStatus::Received)
                    {
                       purchTableSet = new Set(Types::String);
                       purchLineSet  = new Set(Types::Int64);

                       while select forupdate _WBInvJournalStagingLoc
                           order by _WBInvJournalStagingLoc.POLineNumber
                           where _WBInvJournalStagingLoc.Status == NENPOStatus::Ready && _WBInvJournalStagingLoc.PoNumber == partial_purchTable.PurchId
                           {
                               invoiceId = _WBInvJournalStaging.Invoice;
                               purchTableSet.add(partial_purchTable.PurchId);

                               //update Qty to be invoiced
                               select forupdate purchLine
                                   where purchLine.PurchId == partial_purchTable.PurchId && purchLine.LineNumber == _WBInvJournalStagingLoc.POLineNumber;
                               {
                                   purchLine.PurchReceivedNow = _WBInvJournalStagingLoc.Quantity;
                                   purchLine.update();
                                   purchLineSet.add(purchLine.RecId);
                               }

                           }

                       //update Qty to be invoiced
                       purchFormLetter = null;
                       purchFormLetter = PurchFormLetter::construct(DocumentStatus::Invoice);
                       purchFormLetter.purchTable(partial_purchTable);
                       purchFormLetter.transDate(today());
                       purchFormLetter.specQty(PurchUpdate::PackingSlip);
                       purchFormLetter.printFormLetter(NoYes::No);
                       purchFormLetter.prePromptInit();
                       purchParmUpdate = purchFormLetter.purchParmUpdate();
                       purchFormLetter.initParameters(purchParmUpdate);
                       purchFormLetter.purchParmUpdate(purchParmUpdate);

                       vendInvoiceInfoTable = VendInvoiceInfoTable::findPurchId(partial_purchTable.PurchId, purchFormLetter.parmId(), true);
                       select forupdate vendInvoiceInfoTableUpd
                           where vendInvoiceInfoTableUpd.RecId == vendInvoiceInfoTable.RecId;
                       vendInvoiceInfoTableUpd.Num = invoiceId;
                       vendInvoiceInfoTableUpd.update();

                       setIteratorPurchLine = new SetIterator(purchLineSet);

                       purchFormLetter.purchSelectLines(purchTableSet, purchLineSet, vendInvoiceInfoTable);
                       if (purchFormLetter.validate())
                       {
                           purchFormLetter.reArrangeNow(false);
                           purchFormLetter.run();
                       }

                       info(strFmt("Invoiced %1 Posted successfully",vendInvoiceInfoTableUpd.Num));
                    }
                }
}

  • For Non-PO Data.
private container processInvJr(WBInvJournalStagingView _WBInvJournalStaging, LedgerJournalTable _ledgerJrTable)
{
    AXLedgerJournalTrans        trans;
    VendTable                           _vendTable= null;
// Main accounts and Departments are uploaded from the file 
    container                   acctPattern = ['_WBInvJournalStaging.MainAccount -_WBInvJournalStaging.Department', _WBInvJournalStaging.MainAccount,1,'Department', _WBInvJournalStaging.Department];
    container                   offsetAccPattern  = ['_WBInvJournalStaging.MainAccount -_WBInvJournalStaging.Department', _WBInvJournalStaging.MainAccount,1,'Department', _WBInvJournalStaging.Department];
    ;

    if (_WBInvJournalStaging && _ledgerJrTable)
    {
        _vendTable = VendTable::find(_WBInvJournalStaging.Account);
        trans  = new AXLedgerJournalTrans();
        trans.parmAccountType(LedgerJournalACType::Vend);
        trans.parmOffsetLedgerDimension(AxdDimensionUtil::getLedgerAccountId(acctPattern));
        trans.parmOffsetCompany(curext());
        trans.parmLedgerDimension(DimensionStorage::getDynamicAccount(_WBInvJournalStaging.Account, LedgerJournalACType::Vend));
        trans.parmOffsetAccountType(LedgerJournalACType::Ledger);
        trans.parmOffsetLedgerDimension(AxdDimensionUtil::getLedgerAccountId(offsetAccPattern));
        trans.parmTxt(_WBInvJournalStaging.InvoiceDescription);
        trans.parmJournalNum(_ledgerJrTable.JournalNum);
        if (_WBInvJournalStaging.AmountCur > 0)
        {
            trans.parmAmountCurCredit(abs(_WBInvJournalStaging.AmountCur +(_WBInvJournalStaging.SalesTax + _WBInvJournalStaging.Freight)));
        }
        if (_WBInvJournalStaging.AmountCur < 0)
        {
            trans.parmAmountCurDebit(abs(_WBInvJournalStaging.AmountCur +(_WBInvJournalStaging.SalesTax + _WBInvJournalStaging.Freight)));
        }
        trans.parmTaxGroup(vendtable::find(_WBInvJournalStaging.Account).TaxGroup);
        trans.parmPayment(vendtable::find(_WBInvJournalStaging.Account).PaymTermId);
        trans.parmPaymMode(vendtable::find(_WBInvJournalStaging.Account).PaymMode);
        trans.parmPaymId(vendtable::find(_WBInvJournalStaging.Account).PaymId);
        trans.parmCurrencyCode(_WBInvJournalStaging.Currency);
        trans.parmExchRate(Currency::exchRate(_WBInvJournalStaging.Currency));
        trans.parmDocumentDate(_WBInvJournalStaging.DocumentDate);
        trans.parmTransDate(today());
        trans.parmApproved(NoYes::Yes);
        trans.parmDue(PaymTerm::find(_vendTable.PaymTermId).due(_WBInvJournalStaging.DueDate));
        trans.parmInvoice(_WBInvJournalStaging.invoice);
        trans.clearField(fieldNum(ledgerJournalTrans, offsetLedgerDimension), false);
        trans.parmApproved(NoYes::Yes);
        trans.parmApprover(HcmWorker::findByPersonnelNumber('citp').RecId);
        trans.save();
        trans.ledgerJournalTrans();
        return [_ledgerJrTable.JournalNum,NENPOStatus::Processed,_ledgerJrTable.createdDateTime];
    }
     return [_ledgerJrTable.JournalNum,NENPOStatus::Processed,_ledgerJrTable.createdDateTime];
}
























Comments

Popular posts from this blog

Assembly reference containing type is not referenced, Object 'CLRObject' could not be created

Open Packing slip posting form when updating Generate picking list

Extract data of PO from the System in Ax 2012