web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Suggested Answer

Unable to create invoice with multiple purchase orders and with same receipt number using x++

(0) ShareShare
ReportReport
Posted on by 5

Hi everyone,

I am trying to create invoice for multiple purchase orders with same product receipt number using custom class. But when I try to run that class it is posting invoice for only one purchase order and remaining PO is not considering under invoice journal.

Can anyone help me to achieve this using x++ code.

I have the same question (0)
  • nmaenpaa Profile Picture
    101,160 Moderator on at

    Hi Gopal k,

    would you mind sharing your code? This way we might be able to spot out what's causing the problem.

    Thanks!

  • Gopal k Profile Picture
    5 on at

    Hi Nikolaos,

    Thank you so much for reply, and below is the code is helping me to post the invoice journal for 1 purchase order and it's product receipt and multiple invoices. For example my purchase order line has 40 qty and receipt done for 40 qty but I can do the invoice 4 times with 10 qty. So below code helping me to achieve this.

    But it is failing with multiple POs with same invoice number.

    I am using AOT query and having group by column on Legalentity, Invoicenumber, Interfacestatus of my staging table (MT_PurchaseInvoiceStagingTable ) data.

    And in run method using below code :

    while (queryRun.next())

           {

               infologLine = infologLine();

               purchaseInvoiceStagingTable = queryRun.get(tableNum(MT_PurchaseInvoiceStagingTable));

               purchaseInvoiceStagingTable.selectForUpdate(true);    

               try

               {

                   ttsbegin;

                   MT_PurchaseInvoiceStagingTable purchaseInvoiceStaging;

                   select firstonly purchaseInvoiceStaging

                       where purchaseInvoiceStaging.InvoiceNumber == purchaseInvoiceStagingTable.InvoiceNumber

                        &&  purchaseInvoiceStaging.PurchaseOrderNumber

                        && (purchaseInvoiceStaging.InterfaceStatus == MT_InterfaceStatus::Pending

    || purchaseInvoiceStaging.InterfaceStatus == MT_InterfaceStatus::Error);

                   if (purchaseInvoiceStaging && this.validateInvoiceAmount(purchaseInvoiceStaging))

                   {

                       boolean ret;

                       changecompany (purchaseInvoiceStagingTable.LEGALENTITY)

                       {                        

                           if (PurchTable::find(purchaseInvoiceStaging.PurchaseOrderNumber))

                           {

                               ret = this.purchaseInvoicePartial(purchaseInvoiceStaging, true);

                           }

                           else

                           {

                               throw error("Purchase order doesn't exist");

                           }

                       }

                       if (ret)

                       {

                           update_recordset purchaseInvoiceErrorUpdate setting

                                 InterfaceStatus = MT_InterfaceStatus::ReadyToTransfer

                                 where purchaseInvoiceErrorUpdate.LEGALENTITY    == purchaseInvoiceStaging.LEGALENTITY

                                   && purchaseInvoiceErrorUpdate.InvoiceNumber   == purchaseInvoiceStaging.InvoiceNumber

    && purchaseInvoiceErrorUpdate.InterfaceStatus == purchaseInvoiceStaging.InterfaceStatus;

                       }

    }

    }

    This is my method :

     public boolean purchaseInvoicePartial(MT_PurchaseInvoiceStagingTable _purchaseInvoiceStagingTable)

       {

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

           PurchTable purchTable;

           PurchLine purchLine;

           PurchParmLine parmLine;

           PurchParmTable parmTable;

           //Purchformletter_invoice         PurchFormLetter;

           vendPackingSlipJour             vendPackingSlipJour,vendPackingSlipJourChk;

           vendPackingSlipTrans vendPackingSlipTrans,packingSlipGrpByLineNumQty;

           TmpFrmVirtual                   tmpFrmVirtual;

           ParmId                          parmId;

           VendInvoiceInfoTable            vendInvoiceInfoTable, vendInvoiceInfoTableIns;

           VendInvoiceInfoSubTable vendInvoiceInfoSubTable;

           vendInvoiceInfoLine             vendInvoiceInfoLine, vendInvoiceInfoLineIns;

           vendInvoiceInfoSubLine vendInvoiceInfoSubLine;

           int                             i;

           container                       con;

           container                       conPurchReceiptId;

           str receiptNumber = '';

           PurchId                         PurchId;

           //PurchTable purchTable;

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

           MT_PurchaseInvoiceStagingTable  InvoiceStagingTable,InvoiceStagingGrpByLineNum,InvoiceStagingTableParm;

           vendInvoiceInfoLine_Asset       vendInvoiceInfoLine_Asset;

           boolean ret = true;

           ;

    try

           {

               while select InvoiceStagingTable

                   where InvoiceStagingTable.InvoiceNumber == _purchaseInvoiceStagingTable.InvoiceNumber

                       && InvoiceStagingTable.LEGALENTITY == _purchaseInvoiceStagingTable.LEGALENTITY

                       && InvoiceStagingTable.InterfaceStatus == _purchaseInvoiceStagingTable.InterfaceStatus

               {

                   receiptNumber = InvoiceStagingTable.Receiptnumber;

                   purchTable = PurchTable::find(InvoiceStagingTable.PurchaseOrderNumber);

                   if (purchTable)

                   {

                       select firstonly vendPackingSlipJourChk

                           where vendPackingSlipJourChk.PackingSlipId == InvoiceStagingTable.Receiptnumber

                           && vendPackingSlipJourChk.DataAreaId == InvoiceStagingTable.LEGALENTITY

                           && vendPackingSlipJourChk.PurchId == purchTable.PurchId;

                       if(vendPackingSlipJourChk)

                       {

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

                           {

                               con+= [purchTable.PurchId];

                           }

                           if (!conFind(conPurchReceiptId, purchTable.PurchId + InvoiceStagingTable.Receiptnumber + int2Str(InvoiceStagingTable.LineNumber)))

                           {

                               ttsbegin;

                               tmpFrmVirtual.setTmp();

                               while select vendPackingSlipJour

                                   where vendPackingSlipJour.PurchId == purchTable.PurchId

                                      && vendPackingSlipJour.PackingSlipId == vendPackingSlipJourChk.PackingSlipId

                               {

                                   tmpFrmVirtual.clear();

                                   tmpFrmVirtual.TableNum = vendPackingSlipJour.TableId;

                                   tmpFrmVirtual.RecordNo = vendPackingSlipJour.RecId;

                                   tmpFrmVirtual.NoYes = NoYes::Yes;

                                   tmpFrmVirtual.Id = vendPackingSlipJour.PurchId;

                                   tmpFrmVirtual.insert();

                                   conPurchReceiptId+= [purchTable.PurchId + InvoiceStagingTable.Receiptnumber + int2Str(InvoiceStagingTable.LineNumber)];

                               }

                               ttsCommit;

                           }

                       }

                       else

                       {

                           throw error(strFmt("Product receipt %1 doesn't exists",  InvoiceStagingTable.Receiptnumber));

                       }

                   }

               }

               while select tmpFrmVirtual

               {

                   selectedList.addEnd(tmpFrmVirtual);

               }

               if (!selectedList)

               {

                   throw error(strFmt("Product receipt doesn't exists"));

               }

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

               PurchFormLetter.selectFromJournal(selectedList.pack());

               //PurchFormLetter.sumBy(AccountOrder::Account);

               parmId = PurchFormLetter.parmId();

    purchFormLetter.purchTable(purchTable);

    purchFormLetter.transDate (systemDateGet());

    purchFormLetter.specQty (PurchUpdate::All);

    //If you want proforma you can enable the code

    //salesFormLetter.proforma (true);

    //salesFormLetter.printFormLetter (true);

    purchFormLetter.createParmUpdateFromParmUpdateRecord(purchFormLetter.purchParmUpdate());

    //purchFormLetter.initParmPurchTable(purchTable);

               purchFormLetter.purchTable(purchTable);

    purchFormLetter.initParameters(purchFormLetter.purchParmUpdate(),Printout::After);

    purchFormLetter.initLinesQuery();

               select forupdate vendInvoiceInfoTableIns

                   where vendInvoiceInfoTableIns.ParmId == parmId;

               if(vendInvoiceInfoTableIns)

               {

    vendInvoiceInfoTableIns.Num = _purchaseInvoiceStagingTable.InvoiceNumber;

    vendInvoiceInfoTableIns.doUpdate();

               }

               while select InvoiceStagingTable

                   where InvoiceStagingTable.InvoiceNumber    == _purchaseInvoiceStagingTable.InvoiceNumber

                       && InvoiceStagingTable.LEGALENTITY   == _purchaseInvoiceStagingTable.LEGALENTITY

                       && InvoiceStagingTable.InterfaceStatus == _purchaseInvoiceStagingTable.InterfaceStatus

               {

                   select firstonly purchLine

                           where purchLine.LineNumber == InvoiceStagingTable.LineNumber

                           && purchLine.DataAreaId == _purchaseInvoiceStagingTable.LEGALENTITY

                           &&( purchLine.Purchid == InvoiceStagingTable.IvaluaPurchaseOrderNumber

                           || purchLine.Purchid == InvoiceStagingTable.PurchaseOrderNumber);

                   select forupdate vendInvoiceInfoLine

                           where vendInvoiceInfoLine.ParmId == parmId

                             &&  vendInvoiceInfoLine.OrigPurchId == purchLine.PurchId

                             &&  vendInvoiceInfoLine.PurchLineRecId == purchLine.RecId;

                   if (vendInvoiceInfoLine)

                   {

                       vendInvoiceInfoLine.TaxItemGroup = InvoiceStagingTable.TaxCode;//'D-'+ InvoiceStagingTable.TaxCode;

                       vendInvoiceInfoLine.TaxGroup = InvoiceStagingTable.TaxCode;//'D-'+ InvoiceStagingTable.TaxCode;

                       vendInvoiceInfoLine.TaxWithholdGroup = InvoiceStagingTable.WHTCode;

                       vendInvoiceInfoLine.ReceiveNow = decRound(InvoiceStagingTable.LINEAMOUNT/InvoiceStagingTable.PURCHASEPRICE,1);

                       vendInvoiceInfoLine.InventNow = decRound(InvoiceStagingTable.LINEAMOUNT/InvoiceStagingTable.PURCHASEPRICE,1);

                       vendInvoiceInfoLine.RemainBefore = decRound(InvoiceStagingTable.LINEAMOUNT/InvoiceStagingTable.PURCHASEPRICE,1);

                       vendInvoiceInfoLine.RemainBeforeInvent = decRound(InvoiceStagingTable.LINEAMOUNT/InvoiceStagingTable.PURCHASEPRICE,1);

                       if(vendInvoiceInfoLine.ReceiveNow)

                       {

                           vendInvoiceInfoLine.PurchPrice =  InvoiceStagingTable.PURCHASEPRICE;

                       }

                       vendInvoiceInfoLine.LineAmount = InvoiceStagingTable.LINEAMOUNT;

                       vendInvoiceInfoLine.doupdate();

                   }

    else

                   {

                       select firstonly vendPackingSlipJour

                           where vendPackingSlipJour.PurchId == InvoiceStagingTable.PurchaseOrderNumber

                           && vendPackingSlipJour.PackingSlipId == InvoiceStagingTable.Receiptnumber;

                       select vendPackingSlipTrans

                       where vendPackingSlipTrans.PackingSlipId   == vendPackingSlipJour.PackingSlipId

                       && vendPackingSlipTrans.VendPackingSlipJour   == vendPackingSlipJour.RecId

                       && vendPackingSlipTrans.PurchaseLineLineNumber == InvoiceStagingTable.LineNumber;

                       vendInvoiceInfoLineIns.clear();

                       vendInvoiceInfoLineIns.initValue();

                       vendInvoiceInfoLineIns.defaultRow();

                       vendInvoiceInfoLineIns.initFromPurchLine(purchLine);

                       vendInvoiceInfoLineIns.OrigPurchId  = purchLine.PurchId;

                       vendInvoiceInfoLineIns.DeliveryName = vendInvoiceInfoTableIns.DeliveryName;

                       vendInvoiceInfoLineIns.ParmId = vendInvoiceInfoTableIns.ParmId;

                       vendInvoiceInfoLineIns.TableRefId = vendInvoiceInfoTableIns.TableRefId;

                       vendInvoiceInfoLineIns.currencyCode = vendInvoiceInfoTableIns.CurrencyCode;

                       vendInvoiceInfoLineIns.LineNum = any2int(purchLine.LineNumber);

                       vendInvoiceInfoLineIns.InvoiceAccount = vendInvoiceInfoTableIns.InvoiceAccount;

                       vendInvoiceInfoLineIns.InventDimId = vendPackingSlipTrans.InventDimId;

                       vendInvoiceInfoLineIns.OrderAccount = vendInvoiceInfoTableIns.OrderAccount;

                       vendInvoiceInfoLineIns.ItemId = vendPackingSlipTrans.ItemId;

                       vendInvoiceInfoLineIns.TaxItemGroup = InvoiceStagingTable.TaxCode;//'D-'+ InvoiceStagingTable.TaxCode;

                       vendInvoiceInfoLineIns.TaxGroup = InvoiceStagingTable.TaxCode;//'D-'+ InvoiceStagingTable.TaxCode;

                       vendInvoiceInfoLineIns.TaxWithholdGroup = InvoiceStagingTable.WHTCode;

                       vendInvoiceInfoLineIns.InventTransId = vendPackingSlipTrans.InventTransId;

                       vendInvoiceInfoLineIns.DocumentOrigin = DocumentOrigin::Manual;

                       vendInvoiceInfoLineIns.ReceiveNow = decRound(InvoiceStagingTable.LINEAMOUNT/InvoiceStagingTable.PURCHASEPRICE,1);

                       vendInvoiceInfoLineIns.RemainBefore = decRound(InvoiceStagingTable.LINEAMOUNT/InvoiceStagingTable.PURCHASEPRICE,1);

                       vendInvoiceInfoLineIns.RemainBeforeInvent = decRound(InvoiceStagingTable.LINEAMOUNT/InvoiceStagingTable.PURCHASEPRICE,1);

                       vendInvoiceInfoLineIns.InventNow = decRound(InvoiceStagingTable.LINEAMOUNT/InvoiceStagingTable.PURCHASEPRICE,1);

                       if(vendInvoiceInfoLineIns.ReceiveNow)

                       {

                           vendInvoiceInfoLineIns.PurchPrice =  InvoiceStagingTable.PURCHASEPRICE;

                       }

                       vendInvoiceInfoLineIns.LineAmount = InvoiceStagingTable.LINEAMOUNT;//vendInvoiceInfoLineIns.ReceiveNow * vendInvoiceInfoLineIns.PurchPrice;

                       vendInvoiceInfoLineIns.DefaultDimension = purchLine.DefaultDimension;

                       vendInvoiceInfoLineIns.SourceDocumentLine = vendPackingSlipTrans.SourceDocumentLine;

                       select forupdate vendInvoiceInfoLine

                                    where vendInvoiceInfoLine.ParmId == parmId

                                      &&  vendInvoiceInfoLine.OrigPurchId == purchLine.PurchId

                                      &&  vendInvoiceInfoLine.PurchLineRecId == purchLine.RecId;

                       if (!vendInvoiceInfoLine)

                       {

                           vendInvoiceInfoLineIns.doInsert();

                       }

                       if (purchLine.AssetId && vendInvoiceInfoLineIns)

                       {

                           vendInvoiceInfoLine_Asset.initFromPurchLine(purchLine);

                           vendInvoiceInfoLine_Asset.VendInvoiceInfoLineRecId = vendInvoiceInfoLineIns.RecId;

                           vendInvoiceInfoLine_Asset.insert();

                       }

                       if (vendInvoiceInfoLineIns.RecId)

                       {

                           vendInvoiceInfoSubLine.clear();

                           vendInvoiceInfoSubLine.initValue();

                           vendInvoiceInfoSubLine.defaultRow();

                           vendInvoiceInfoSubLine.ParmId = vendInvoiceInfoTableIns.ParmId;

                           vendInvoiceInfoSubLine.LineRefRecId = vendInvoiceInfoLineIns.RecId;

                           vendInvoiceInfoSubLine.ReceiveNow = vendInvoiceInfoLineIns.ReceiveNow;

                           vendInvoiceInfoSubLine.InventNow = vendInvoiceInfoLineIns.InventNow ;

                           vendInvoiceInfoSubLine.JournalRefRecId = vendPackingSlipTrans.RecId;

                           vendInvoiceInfoSubLine.JournalRefTableId = vendPackingSlipTrans.TableId;

                           vendInvoiceInfoSubLine.DocumentId = vendPackingSlipTrans.PackingSlipId;

                           vendInvoiceInfoSubLine.insert();

                       }

    }

    }

               select * from parmTable

    where parmTable.Num == _purchaseInvoiceStagingTable.Receiptnumber

                   && parmTable.ParmId == parmId;

               while select forUpdate parmLine

                   where parmLine.ParmId == parmTable.ParmId

    {

       ttsBegin;

                   parmLine.InventNow = _purchaseInvoiceStagingTable.InvoicedQty;

                   parmLine.ReceiveNow = _purchaseInvoiceStagingTable.InvoicedQty;

       parmLine.setQty(parmLine.purchParmTable().ordering, purchFormLetter.purchParmUpdate().creditRemaining);

       parmLine.setInventReceiveNow();

       parmLine.setLineAmount();

       parmLine.update();

       ttsCommit;

    }

               purchFormLetter.parmNumber(_purchaseInvoiceStagingTable.InvoiceNumber);

    purchFormLetter.run();

    if (purchFormLetter.parmJournalRecord().recid)

    {

       info(strFmt("Invoice %1 created sucessfully",_purchaseInvoiceStagingTable.InvoiceNumber));

    }

    else

    {

       throw error(strFmt("Invoice %1 can't be created",_purchaseInvoiceStagingTable.InvoiceNumber));

    }

           }

           catch

           {

               infologLine = this.updateError(infologLine);

               ret= false;

           }

           return ret;

       }

  • Suggested answer
    Sheikh Sohail Profile Picture
    6,125 on at

    Hi Gopal

    Would you please share more details, including the code you are using?

    Please correct me if I am understanding wrong, are you trying to create a single invoice for multiple purchase orders or multiple invoices for multiple purchase orders?

    Just for FYI, a Single invoice for multiple purchase orders is not possible.

  • Gopal k Profile Picture
    5 on at

    Hi Sohail,

    Thanks for your reply, I posted my code and I am trying to achieve single invoice for multiple purchase orders and with same receipt number.

  • Suggested answer
    Sheikh Sohail Profile Picture
    6,125 on at

    Hi Gopal

    Consolidated invoice feature OOTB available for Japan, would recommend you to view the below reference link, but with normal classes, you couldn't make a single invoice of multiple purchase orders, Yes,

    You can create multiple invoices with the same receipt number.

    docs.microsoft.com/.../create-confirm-vendor-consolidated-invoice

  • Gopal k Profile Picture
    5 on at

    Hi Sohail,

    Thank you so much for quick response, so you mean to say we can't achieve this scenario with custom code right ?

  • Suggested answer
    Sheikh Sohail Profile Picture
    6,125 on at

    Hi Gopal

    I would suggest you explore the consolidated invoice, might be possible this feature will help you to achieve your business requirement but generating the single invoice of multiple purchase orders technically will create issues for you.

  • Suggested answer
    Gopal k Profile Picture
    5 on at

    Below method helped me to achieve this scenario:

    public boolean multiplePOInv(PurchaseInvoiceStagingTable _purchaseInvoiceStagingTable)

       {

           boolean ret = true;

           PurchFormLetter    purchFormLetter;

           Map    mapPurchTable;

           vendPackingSlipJour             vendPackingSlipJour,vendPackingSlipJourChk;

           PurchTable purchTable;

           PurchaseInvoiceStagingTable  InvoiceStagingTable,InvoiceStagingGrpByLineNum,InvoiceStagingTableParm;

    try

           {

               ttsBegin;

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

               mapPurchTable = new Map(typeName2Type(extendedTypeStr(RecId)), Types::Record);

               while select InvoiceStagingTable

                   where InvoiceStagingTable.InvoiceNumber == _purchaseInvoiceStagingTable.InvoiceNumber

                       && InvoiceStagingTable.LEGALENTITY == _purchaseInvoiceStagingTable.LEGALENTITY

                       && InvoiceStagingTable.InterfaceStatus == _purchaseInvoiceStagingTable.InterfaceStatus

               {

                    purchTable = PurchTable::find(InvoiceStagingTable.PurchaseOrderNumber);

                   if (purchTable)

                   {

                       select firstonly vendPackingSlipJourChk

                           where vendPackingSlipJourChk.PackingSlipId == InvoiceStagingTable.Receiptnumber

                           && vendPackingSlipJourChk.DataAreaId == InvoiceStagingTable.LEGALENTITY

                           && vendPackingSlipJourChk.PurchId == purchTable.PurchId;

                       if(vendPackingSlipJourChk)

                       {

                           mapPurchTable.insert(purchTable.RecId, purchTable);

                       }

                       else

                       {

                           throw error(strFmt("Product receipt %1 doesn't exists",  InvoiceStagingTable.Receiptnumber));

                       }

                   }

               }

               purchFormLetter.parmDataSourceRecordsPacked(mapPurchTable.pack());

               purchFormLetter.initNewPurchParmUpdate();

               purchFormLetter.sumBy(AccountOrder::Account);

               purchFormLetter.reArrangeNow(true);

               purchFormLetter.update(purchTable,_purchaseInvoiceStagingTable.InvoiceNumber,_purchaseInvoiceStagingTable.InvoiceDate, PurchUpdate::All);

               ttsCommit;

           }

           catch

           {

               infologLine = this.updateError(infologLine);

               ret= false;

           }

           return ret;

       }

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Martin Dráb Profile Picture

Martin Dráb 646 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 529 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 285 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans