Techno-Functional Dynamics 365 F&S Data Model Explanations for Reporting, Part 10 Of 25 – Sales Order Invoice Posting

Techno-Functional Dynamics 365 F&S Data Model Explanations for Reporting, Part 10 Of 25 – Sales Order Invoice Posting

Things have changed a lot since I started blogging over a decade ago.  There are so many wonderful topics to blog and learn today; it seems like one doesn’t even know where to start.  To make the process more friendly, I’ve introduced a new sort of post — the hybrid video/blog tutorial. Some very talented developers from my team have contributed their expertise to assist with this content/video approach to ensure that we keep our quality and quantity high.  I hope you all sincerely enjoy the new approaches that we’ve innovated.  And as always, don’t hesitate to reach out to me.. I’m always here to help. — Brandon Ahmad


In this blog post, we take you to the last step in the sales order process of Dynamics 365: posting the sales order invoice. Previously in this series of techno-functional walkthroughs, we talked about sales order creation process, picking list creation for sales order, and picking list creation for sales order in Dynamics 365. As you’re already familiar with our style of techno-functional walkthrough series, this post will also explain the functional and technical process behind the sales order invoice posting process.

Before we begin, let’s first discuss what happens as we post a sales order invoice.

When we post the sales invoice, all financial values are automatically implemented on the sales order because the general ledger module is integrated with customers, products, and charges. As the sales invoice is posted along with sales order lines transaction, the status of sales order changes to invoiced and after that you cannot make any changes to the sales order.

The invoice increases the open customer balance and reduces the financial value in inventory. After all the lines of a sales order have been invoiced, the sales order is now complete. The payment of the invoice is processed separately in the finance module.

Now we can finally get started with the functional process of the final step of a sales order process in Dynamics 365.


Here is the functional process flow for a process of sales order invoice posting:


The first step is to click on the icon  at the top left of the D365 client. Then navigate to ‘All sales orders’ by clicking on ‘Accounts receivable’ > ‘Orders’ > ‘All sales orders.’

Sales order invoice posting Dynamics 365 - Step 1


After selecting the sales order, select the ‘Invoice’ tab. Under the ‘GENERATE’ group click ‘Invoice’ to create the sales order invoice.


Now you’re directed to ‘Sales order invoice form’ where you can see all the details of sales orders lines and packing slip. Click on ‘OK’ to post the invoice receipt.


You can see the message below stating, “Operation completed,” which ensures your invoice has been posted successfully. Now go to the ‘Invoice’ tab and click on ‘Invoice’ under the ‘JOURNALS’ group to check the posted invoice receipt.

Sales order invoice posting Dynamics 365 - Step 4


There are two primary tables involve in the process of posting sales order invoices, “CustInvoiceJour” and “CustInvoiceTrans.”


To have a deeper understanding of the functionality of the sales order invoice posting process, let’s have a look at the Entity Relationship Diagram (ERD) which shows all the cardinality constraints relationship among the tables.

Sales order invoice posting Dynamics 365 - Entity Relationship Diagram ERP

Here is the Runnable class(job), which will post the invoice of a sales order.

[sourcecode language=”c-sharp”] class ibSalesInvoicePostingJob
/// <summary>
/// Runs the class with the specified arguments.
/// </summary>
/// <param name = "_args">The specified arguments.</param>
public static void main(Args _args)
SalesFormLetter _salesFormLetter;
SalesTable _salesTable;
SalesId _salesId = ‘001286’;
CustInvoiceJour _custInvoiceJour;
_salesTable = SalesTable::find(_salesId);
if (_salesTable && _salesTable.SalesStatus == SalesStatus::Delivered)
_salesFormLetter = SalesFormLetter::construct(DocumentStatus::Invoice);
_salesFormLetter.update(_salesTable, systemDateGet(), SalesUpdate::All, AccountOrder::None, NoYes::No, NoYes::No, NoYes::No, NoYes::Yes);
if (_salesFormLetter.parmJournalRecord().TableId == tableNum(CustInvoiceJour))
_custInvoiceJour = _salesFormLetter.parmJournalRecord();
info(strFmt(‘Invoice for Sales Order: %1 has been posted, Invoice: %2’, _custInvoiceJour.SalesId, _custInvoiceJour.InvoiceId));
info(strFmt(‘%1 does not exsists or not in delivered state.’, _salesId));
catch (Exception::Error)
info(strFmt(‘Failed to post Sales order invoice for %1.’, _salesId));

Let’s have a look at the details of these two primary tables: CustInvoiceJour and CustInvoiceTrans


The CustInvoiceJour table contains the header information of the sales order invoice. This table:

  • has the customer account details of posted sales orders, which includes customer balances and transactions.
  • helps in finding posted sales order details, which are very useful for reporting purposes or for finding already invoiced sales orders.
  • contains charge details and financial transactions can also be tracked from this table.

Now we will go through some important fields of the CustInvoiceJour with a few of the technical details.

Field Data Type Description
InvoiceId string invoice id information
InvoiceAccount string customer account number of sales order invoice
InvoiceDate date information of invoice date
SalesId String information on the sales order number
DeliveryPostalAddress string reference for delivery postal address
LedgerVoucher string Ledger voucher number for sales order invoice
DlvTerm string Contain information about delivery term of sales order


The CustInvoiceTrans table contains the lines information on the sales order invoice. You can also view the detailed transaction information for the line items from this table. This table contains:

  • information about posted sales order line-items.
  • financial transactions of sales order line-item details.
  • invoice transaction details searchable by using the sales order number or invoice id.

Now we will go through some important fields of the CustInvoiceTrans with a few of the technical details.

Field Data Type Description
SalesId string sales order number
ItemId string information of Item id
inventDimId string inventory dimension details Id of sales order lines
Name string description of item/product
Qty real total quantity
Remain real remaining quantity
SalesPrice real unit price for items
LineAmount real line amount of the items for the sales order line
PdsCWQty real catchweight product quantity


The InventTrans table stores all inventory transactions that occur in Dynamics 365. The system stores all the transactions with a source document, for instance, if the transaction occurs as a result of the sales order posting, the relevant sales order number will be saved with lines. From this table, we can generate the reports to:

  • get invoiced sales order or purchase order with invoice id.
  • check invoicing trends against the specific items or all the items.
  • get relevant voucher number and details of all financial transactions attached to the voucher.
Field Data Type Description
InventTransOrigin Int64 RecId of relevant record in InventTransOrigin table
InvoiceId string invoice id information
Qty Real item quantity
InventDimId string relevant inventory dimension id
StatusIssue Enum current inventory status e.g Sold, Picked
DateFinancial Date date of financial transaction occurrence
Voucher String voucher number attached to the invoice id


In this post, we:

  • looked at the functional process behind the sales order invoice posting process.
  • walked through the process for invoicing, posting, and reviewing the sales orders in Dynamics 365 F&S.
  • saw the runnable code that posts the invoice and closes it out.
  • analyzed the technical data model along with the table fields behind the sales order invoice posting process.
  • explored the main tables (CustInvoiceJour & CustInvoiceTrans) involved in invoicing a sales order in Dynamics 365 Finance and Operations.
We sincerely hope that you enjoyed part 10 of our exciting series on the Dynamics 365 data model. We aim to provide quality service at all times.  And as always, if you need to reach me, you know how to get in touch by reaching out to me here.  — Brandon Ahmad, founder of InstructorBrandon and Dynatuners