Dynamics 365 Business Central: How to keep Orders after completely invoiced

Dynamics 365 Business Central

Hi, Readers.
Today, I would like to talk about how to keep orders after completely invoiced in Business Central.
The following descriptions are based on Sales orders, and the same goes for Purchase Orders.

As you might know, in Business Central, after posting a sales invoice from the sales order page, the system will delete the completely invoiced sales order.

In case a sales invoice is created from the sales invoice page and use Get Shipment Lines functionality to do invoicing, the system will not delete the completely invoiced sales order.

So if you want to keep orders, the easiest way is to go to post invoice from the sales invoice page.

But there may be some specific customer requirement that needs to keep the orders posted from the sales order page, is there a way to do it in Business Central?
Yes, this is actually not complicated. You just need a bit of customizations.

Navigate to codeunit 80 “Sales-Post”.

You can find an event called OnBeforeDeleteAfterPosting in local procedure DeleteAfterPosting.

There is a parameter SkipDelete.

You may think you can change this parameter as true to keep sales order as shown below.

Yes, using the above method, sales orders can be kept. But please note if everything in the sales order is invoiced, Business Central will not finish the remaining quantity calculation, such as Qty. to Ship, Quantity Shipped, Qty. to Invoice, and Quantity Invoiced (In fact, the system only needs to delete the sales line at this time, no need to recalculate). And For some other reasons, you will not be able to delete the sales order.

To avoid this situation, please do not use the above method. Actually, the sales order will be deleted if EverythingInvoicedvariable in Codeunit 80 is true.
So, you can use the OnBeforeFinalizePosting event in the local procedure FinalizePosting and just change EverythingInvoiced parameter to false.

[IntegrationEvent(false, false)]
local procedure OnBeforeFinalizePosting(var SalesHeader: Record "Sales Header"; var TempSalesLineGlobal: Record "Sales Line" temporary; var EverythingInvoiced: Boolean; SuppressCommit: Boolean; var GenJnlPostLine: Codeunit "Gen. Jnl.-Post Line")
begin
end;

For example:

Source Code:

codeunit 50123 KeepSalesOrders
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Post", 'OnBeforeFinalizePosting', '', false, false)]
    local procedure KeepSalesOrdersAfterInvoiced(var EverythingInvoiced: Boolean)
    begin
        EverythingInvoiced := false;
    end;
}

Test Video: You can delete the order manually.

For purchase order:

Source Code:

codeunit 50123 KeepSalesOrders
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Purch.-Post", 'OnBeforeFinalizePosting', '', false, false)]
    local procedure KeepPurchOrdersAfterInvoiced(var EverythingInvoiced: Boolean)
    begin
        EverythingInvoiced := false;
    end;
}

Test Video: You can delete the order manually.

PS:
1. You can also filter on a specific document type, such as “Document Type”::Order.

2. You need to handle this feature carefully and should do some more control around enabling and disabling the feature via setup.

3. Please note that the best solution to keep sales orders is to use the standard archive function and not to change the standard process of deleting the sales order.
Find more about Archive Documents in Microsoft Docs.

4. You can delete invoiced documents with a batch job, such as Delete Invoiced Sales Orders.

END

Hope this will help.

Thanks for reading.

ZHU

コメント

タイトルとURLをコピーしました