Automate ICO purchase invoice in Dynamics 365 Finance
On the current occasion that spoiled my Saturday: one legal entity posts an intercompany sales invoice, but the receiving entity does not automatically react. As a result, stock and intercompany balances start to diverge, because the sales side is already fully posted while the corresponding vendor invoice on the purchasing side is either missing or only created after manual intervention. In day-to-day operations, this leads to inconsistencies and unnecessary reconciliation effort. In the ICO direct delivery – “a chain of three” SO -> ICO PO -> ICO SO – this can be fully automated out of the box, but in the “chain of two” ICO SO -> ICO PO it cannot.
The standard process requires a user to actively navigate to the purchase order in the receiving company, follow the intercompany tracing, switch legal entities, and manually trigger the “Generate intercompany invoice” function. Only after this step does the vendor invoice appear. The expectation is straightforward: once the sales invoice is posted, the corresponding intercompany vendor invoice should automatically be created in the receiving entity and appear there as a pending invoice, ready for review and approval. The system already contains all the necessary logic, but it simply does not execute it at the right moment.
The solution may be a surprisingly small extension at the right place. By hooking into the invoice posting process and calling the existing intercompany update logic immediately after posting, the missing step is automated:
[ExtensionOf(classStr(SalesFormLetter_Invoice))]
internal final class SalesFormLetter_Invoice_Extension
{
public void run()
{
next run();
FormletterOutputContract outputContract = this.getOutputContract();
if (outputContract)
{
CustInvoiceJour custInvoiceJour = outputContract.parmJournal() as CustInvoiceJour;
if (custInvoiceJour && custInvoiceJour.InterCompanyCompanyId)
{
setPrefix("@SCM:IntercompanyGenerateInvoiceMenuCaption");
custInvoiceJour.interCompanyUpdate();
}
}
}
}
The key method is deliberately NOT wrapped into the same transaction as the main run(): a workflow or a closed period in the company of the recipient should not disrupt the seller’s operations.