Dynamics 365 Business Central: How to customize post options (Dialog: Ship, Invoice, Ship and Invoice)

Dynamics 365 Business Central

Hi, Readers.
It is my first work day in 2021. Hope all the best in 2021!
I saw a new problem in Dynamics 365 Business Central/NAV User Group today. “How to remove the Receive & Invoice option in the PO Posting?”
So in this blog, we will discuss how to customize post options (Dialog: Ship, Invoice, Ship and Invoice) in the SO or PO posting.
Actually I shared this topic in Japanese in August last year. In order to let more developers find it, I world like to post it again in English this time.

Update 2023.04.04: Business Central 2023 wave 1 (BC22) new features: Posting restrictions (Sales/Purch Invoice Posting Policy in User Setup)

On the Sales Order page or Purchase Order page and so on, after you press the Post action, there will be a dialog.
For example on the Sales Order page: Ship, Invoice, Ship and Invoice

Can it be customized?
As you can find from the standard source code (codeunit 81 “Sales-Post (Yes/No)”), the StrMenu method is used. Therefore, you may think that it cannot be customized unless you change the standard source code.

However, in the same Codeunit, there is an event called OnBeforeConfirmSalesPost. And it contains a variable called HideDialog. So the answer is Yes, it can be customized.

Let’s try it.
Overview Design:
1. Customize Post action on Sales Order Card
2. Hide the default posting process Dialog
3. Add a new Dialog

Create a new project and add a new Codeunit in Visual Studio Code.

Use shortcut keys “Shift + Alt + E” to search for events.

Search for OnBeforeConfirmSalesPost and click.

OK.

Then add the following code.

HideDialog := true;
NewConfirmPost(SalesHeader);

Start coding by referring to the ConfirmPost function in codeunit 81 “Sales-Post (Yes/No)”.
Try to change Ship -> Ship New, Invoice -> Invoice New, Ship and Invoice -> Ship and Invoice New.

local procedure NewConfirmPost(var SalesHeader: Record "Sales Header"): Boolean
    var
        Selection: Integer;
        ConfirmManagement: Codeunit "Confirm Management";
        ShipInvoiceQst: Label '&Ship New,&Invoice New,Ship &and Invoice New';
        PostConfirmQst: Label 'Do you want to post the %1?', Comment = '%1 = Document Type';
        ReceiveInvoiceQst: Label '&Receive,&Invoice,Receive &and Invoice';
        NothingToPostErr: Label 'There is nothing to post.';
    begin
        case SalesHeader."Document Type" of
            SalesHeader."Document Type"::Order:
                begin
                    Selection := StrMenu(ShipInvoiceQst, 1);
                    SalesHeader.Ship := Selection in [1, 3];
                    SalesHeader.Invoice := Selection in [2, 3];
                    if Selection = 0 then
                        exit(false);
                end;
            SalesHeader."Document Type"::"Return Order":
                begin
                    Selection := StrMenu(ReceiveInvoiceQst, 1);
                    if Selection = 0 then
                        exit(false);
                    SalesHeader.Receive := Selection in [1, 3];
                    SalesHeader.Invoice := Selection in [2, 3];
                end
            else
                if not ConfirmManagement.GetResponseOrDefault(
                     StrSubstNo(PostConfirmQst, LowerCase(Format(SalesHeader."Document Type"))), true)
                then
                    exit(false);
        end;
        SalesHeader."Print Posted Documents" := false;
        exit(true);
    end;

Publish and check. It succeeded.

Test Video:

Next, remove the options related to the Invoice, leaving only the Ship.
If you understood the above source code in NewConfirmPost function, it is obvious that the options is controlled by the following three lines, so leaving only the Ship content in the Label and narrowing down the scope of SalesHeader.Ship.

ShipInvoiceQst: Label '&Ship New,&Invoice New,Ship &and Invoice New';
                    SalesHeader.Ship := Selection in [1, 3];
                    SalesHeader.Invoice := Selection in [2, 3];

Change as follows.

ShipInvoiceQst: Label '&Ship New';
                    SalesHeader.Ship := Selection in [1, 1];

Publish.

Test Video:

Finally, let’s leave Sales and Invoice only.

ShipInvoiceQst: Label 'Ship &and Invoice New';
                    SalesHeader.Ship := Selection in [1, 1];
                    SalesHeader.Invoice := Selection in [1, 1];

Test:

Source Code:

codeunit 83001 NewPostDialog
{
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Post (Yes/No)", 'OnBeforeConfirmSalesPost', '', false, false)]
    local procedure OnBeforeConfirmSalesPost(var SalesHeader: Record "Sales Header"; var HideDialog: Boolean; var IsHandled: Boolean; var DefaultOption: Integer; var PostAndSend: Boolean);
    begin
        HideDialog := true;
        NewConfirmPost(SalesHeader);
    end;


    local procedure NewConfirmPost(var SalesHeader: Record "Sales Header"): Boolean
    var
        Selection: Integer;
        ConfirmManagement: Codeunit "Confirm Management";
        ShipInvoiceQst: Label '&Ship New,&Invoice New,Ship &and Invoice New';
        PostConfirmQst: Label 'Do you want to post the %1?', Comment = '%1 = Document Type';
        ReceiveInvoiceQst: Label '&Receive,&Invoice,Receive &and Invoice';
        NothingToPostErr: Label 'There is nothing to post.';
    begin
        case SalesHeader."Document Type" of
            SalesHeader."Document Type"::Order:
                begin
                    Selection := StrMenu(ShipInvoiceQst, 1);
                    SalesHeader.Ship := Selection in [1, 3];
                    SalesHeader.Invoice := Selection in [2, 3];
                    if Selection = 0 then
                        exit(false);
                end;
            SalesHeader."Document Type"::"Return Order":
                begin
                    Selection := StrMenu(ReceiveInvoiceQst, 1);
                    if Selection = 0 then
                        exit(false);
                    SalesHeader.Receive := Selection in [1, 3];
                    SalesHeader.Invoice := Selection in [2, 3];
                end
            else
                if not ConfirmManagement.GetResponseOrDefault(
                     StrSubstNo(PostConfirmQst, LowerCase(Format(SalesHeader."Document Type"))), true)
                then
                    exit(false);
        end;
        SalesHeader."Print Posted Documents" := false;
        exit(true);
    end;
}

END

Hope this will help.

Thanks for your reading.

ZHU

コメント

Copied title and URL