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
SALES ORDER INVOICE POSTING IN DYNAMICS 365
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.
SALES ORDER INVOICE POSTING: DYNAMICS 365 FUNCTIONAL WALKTHROUGH
Here is the functional process flow for a process of sales order invoice posting:
STEP 1
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.’
STEP 2
After selecting the sales order, select the ‘Invoice’ tab. Under the ‘GENERATE’ group click ‘Invoice’ to create the sales order invoice.
STEP 3
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.
STEP 4
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 TECHNICAL WALKTHROUGH
There are two primary tables involve in the process of posting sales order invoices, “CustInvoiceJour” and “CustInvoiceTrans.”
ENTITY RELATIONSHIP DIAGRAM (ERD)- SALES ORDER INVOICE POSTING
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.
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;
ttsBegin;
try
{
_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));
}
}
else
{
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));
}
ttscommit;
}
}
[/sourcecode]
Let’s have a look at the details of these two primary tables: CustInvoiceJour and CustInvoiceTrans
CustInvoiceJour
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 |
CustInvoiceTrans
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 |
InventTrans
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 |
Summary
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.