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

Announcements

News and Announcements icon
Community site session details

Community site session details

Session Id :
Small and medium business | Business Central, N...
Suggested Answer

Auto-post Sales Invoices received from external application without Job Queue

(1) ShareShare
ReportReport
Posted on by 35

Hi Experts,
I have a requirement in Business Central and would appreciate your guidance on the best approach.
Scenario
An external application (Third-Party App) pushes Sales Invoices into Business Central.
The invoice is created successfully in BC as an Unposted Sales Invoice.

Requirement
As soon as the invoice arrives in BC, it should be automatically posted within a few seconds.
Conditions
✅ No Post button click by the user
✅ No Job Queue
✅ No Report/Batch Processing page
✅ No manual action from users
✅ Invoice should post automatically after it is fully created


Challenge
I tried using a subscriber on Sales Header OnAfterModifyEvent and calling:


Codeunit.Run(Codeunit::"Release Sales Document", SalesHeader);
Codeunit.Run(Codeunit::"Sales-Post", SalesHeader);

but this resulted in transaction issues and errors such as:

(The record in table Sales Shipment Header already exists.)

and sometimes:

(An error occurred and the transaction is stopped.)

The reason seems to be that OnAfterModifyEvent fires multiple times while the invoice is still being created.

Question
What is the recommended Business Central approach to automatically post a Sales Invoice immediately after it is fully created by an external application, without using Job Queue or any user action?

Thanks in advance for your suggestions and best practices.

 

I have the same question (0)
  • Suggested answer
    ALI NASIK Profile Picture
    22 on at

     OnAfterModifyEvent fires many times during document creation (every field validate = a Modify call). You're posting on every firing — hence duplicate/transaction errors.

    Best solution: Add a "ready to post" flag

    1. Add custom field ReadyToPost (Boolean) on Sales Header.
    2. External app sets it to true only on its last/final update call (after all lines are added).
    3. Subscribe to OnAfterModifyEvent, but only act when the flag transitions false → true:
    codeunit 50101 "Auto Post Sales Invoice"
    {
        SingleInstance = true;
        var
            IsPosting: Boolean;
    
        [EventSubscriber(ObjectType::Table, Database::"Sales Header", 'OnAfterModifyEvent', '', false, false)]
        local procedure OnModify(var Rec: Record "Sales Header"; var xRec: Record "Sales Header")
        begin
            if IsPosting then
                exit;
            if Rec."Document Type" <> Rec."Document Type"::Invoice then
                exit;
            if not (Rec.ReadyToPost and not xRec.ReadyToPost) then
                exit;
    
            IsPosting := true;
            Commit();
            if not TryPost(Rec) then
                LogError(Rec, GetLastErrorText());
            IsPosting := false;
        end;
    
        [TryFunction]
        local procedure TryPost(var SalesHeader: Record "Sales Header")
        var
            Release: Codeunit "Release Sales Document";
        begin
            Release.Run(SalesHeader);
            SalesHeader.Find();
            Codeunit.Run(Codeunit::"Sales-Post", SalesHeader);
        end;
    
        local procedure LogError(SalesHeader: Record "Sales Header"; Msg: Text)
        begin
            // insert into a custom error log table
        end;
    }
    

    Why this fixes your errors:

    • Only fires once (on the flag transition), not on every Modify.
    • IsPosting guard blocks re-entrancy.
    • Commit() closes the current transaction before posting starts its own — this alone fixes "record already exists."
    • TryFunction prevents a posting failure from crashing the external app's API call.

    Even better (if you can influence the external app)

    Skip table events entirely. Add a custom bound action on your API page (postInvoice), and have the external app call it explicitly as the last step. Zero ambiguity, zero duplicate-firing risk — this is Microsoft's recommended pattern for automated posting via API.

    You need an explicit "creation is complete" signal — either a custom flag field or a dedicated API action call. Without one, there's no reliable way to know the document is "done" from table events alone.

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

Season of Sharing Community Challenge Winners!

Congratulations to our community stars!

Women in Power Builds Momentum

Expanding mentorship, skilling, and AI innovation

Congratulations to the June Top 10 Community Leaders

These are the community rock stars!

Leaderboard > Small and medium business | Business Central, NAV, RMS

#1
OussamaSabbouh Profile Picture

OussamaSabbouh 580 Super User 2026 Season 1

#2
YUN ZHU Profile Picture

YUN ZHU 462 Super User 2026 Season 1

#3
Grigorios Mavrogeorgis Profile Picture

Grigorios Mavrogeorgis 272 Super User 2026 Season 1

Last 30 days Overall leaderboard

Featured topics

Microsoft Training Manuals

Product updates

Dynamics 365 release plans