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

Send email using .Net framework

Import bacpac file