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

Notifications

Announcements

No record found.

Community site session details

Community site session details

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

To create or convert sales order to a sales quote

(3) ShareShare
ReportReport
Posted on by 117

Hello everyone,

 

I am working on a task to create a job queue that processes all released sales quotes and creates corresponding sales orders. I am using an event subscriber on the Sales Quote table, specifically the OnAfterRun trigger, to release the sales order upon processing.

The requirement is that the job should not be interrupted if an error occurs. For this, I am using the TRY function to handle exceptions.

However, I need some clarification regarding error handling: If an error occurs during the release of a sales order, I want to ensure that the associated sales quote is retained and the partially created sales order is deleted.

How can I achieve this in AL (or Dynamics 365 Business Central)? Specifically, I need guidance on how to manage the sales quote and sales order in such a way that if an error happens, the sales quote remains intact while the sales order is rolled back or deleted.

Any suggestions or best practices for handling this scenario would be greatly appreciated!

I have the same question (0)
  • Martin Dráb Profile Picture
    237,965 Most Valuable Professional on at
    Moved from Integration, Dataverse, and general topics forum.
  • Suggested answer
    Mansi Soni Profile Picture
    8,909 Super User 2025 Season 2 on at
  • Suggested answer
    Jainam M. Kothari Profile Picture
    15,639 Super User 2025 Season 2 on at
  • TB-28100618-0 Profile Picture
    117 on at
    Thanks for the answers!
    I tried both but it ends up like creating sales order but not released and sales quote is deleted.

     
    codeunit 90916 SO_job
    {
        trigger OnRun()
        begin
            createso();
        end;
     
        local procedure createso()
        var
            mydatetime: DateTime;
            mydate: date;
            createsroCodeunit: Codeunit SalesReturnOrderProcessor;
            salesheader: Record "Sales Header";
            sro: record "Sales Header";
            salesorederheader: Record "Sales Header";
        begin
            mydate := CalcDate('<-1D>', Today);
            mydatetime := CreateDateTime(mydate, 0T);
            SalesHeader.Reset();
            SalesHeader.SetRange(SystemCreatedAt, mydatetime, CurrentDateTime);
            SalesHeader.SetFilter("Document Type", '=%1', SalesHeader."Document Type"::Quote);
            SalesHeader.SetFilter(Status, '=%1', SalesHeader.Status::Released);
            salesheader.SetFilter("Order Type", '=%1', SalesHeader."Order Type"::"SALES");
            salesheader.SetFilter("Responsibility Center", '=%1', 'SALESM');
            if salesheader.Find('-') then begin
                Message(Format(salesheader.Count));
                repeat
                    message(format(salesheader."No."));
                    if not CreateSalesOrder(salesheader) then begin
                        salesorederheader.Reset();
                        salesorederheader.SetRange("Quote No.", salesheader."No.");
                        Message(getlasterrortext());
     
                        if salesorederheader.FindSet() then begin
                            Message(Format(salesorederheader."No."));
                            salesorederheader."SO Error" := GetLastErrorText();
                            salesorederheader.Modify();
                            Message(Format(salesorederheader."SO Error"));
     
                        end;
                        // salesheader."SO Error" := GetLastErrorText();
     
                        // salesheader.Modify();
                    end;
                until salesheader.Next() = 0;
            end;
        end;
     
        [TryFunction]
        procedure CreateSalesOrder(SalesHeader: Record "Sales Header")
        var
            SalesQuoteLine: Record "Sales Line";
            SalesOrderTemp: Record "Sales Header";
            SalesOrderLine: Record "Sales Line";
            NewReturnOrderNo: Code[20];
            ReleaseSalesDoc: Codeunit "Release Sales Document";
            ReturnCode: Record "Return Reason";
            ApprovalsMgmt: Codeunit "Approvals Mgmt.";
            SalesQuoteToOrder: Codeunit "Sales-Quote to Order";
        begin
            if ApprovalsMgmt.PrePostApprovalCheckSales(SalesHeader) then
                SalesQuoteToOrder.run(SalesHeader)
     
        end;


     
        var
            myInt: Integer;
    }
  • Gerardo Rentería García Profile Picture
    25,236 Most Valuable Professional on at

    Hi, good day
    I hope this can help you, and give you some hints.

    How to Convert Sales Quotes to Sales Order Using Power Automate? - MADHDA Business Solutions - a Microsoft Partner

    Best Regards
    Gerardo

  • Suggested answer
    Ramiz Profile Picture
    597 on at
    Hi,
    Try this.
     
    codeunit 50103 "SO Job"
    {
        trigger OnRun()
        begin
            CreateSO();
        end;
    
        local procedure CreateSO()
        var
            SalesHeader: Record "Sales Header";
            SRO: Record "Sales Header";
            SalesOrderHeader: Record "Sales Header";
            MyDateTime: DateTime;
            MyDate: Date;
        begin
            MyDate := CalcDate('<-1D>', Today);
            MyDateTime := CreateDateTime(MyDate, 0T);
            SalesHeader.Reset();
            SalesHeader.SetRange(SystemCreatedAt, MyDateTime, CurrentDateTime);
            SalesHeader.SetFilter("Document Type", '=%1', SalesHeader."Document Type"::Quote);
            SalesHeader.SetFilter(Status, '=%1', SalesHeader.Status::Released);
            if GuiAllowed then
                Message(Format(SalesHeader.Count));
            if SalesHeader.FindSet() then
                repeat
                    Message(Format(SalesHeader."No."));
                    if not CreateSalesOrder(SalesHeader) then begin
                        SalesOrderHeader.Reset();
                        SalesOrderHeader.SetRange("Quote No.", SalesHeader."No.");
                        if GuiAllowed then
                            Message(getlasterrortext());
    
                        if SalesOrderHeader.FindSet() then begin
                            if GuiAllowed then
                                Message(Format(SalesOrderHeader."No."));
                            SalesOrderHeader."SO Error" := GetLastErrorText();
                            SalesOrderHeader.Modify();
                            if GuiAllowed then
                                Message(Format(SalesOrderHeader."SO Error"));
    
                        end;
                    end;
                until SalesHeader.Next() = 0;
        end;
    
        local procedure CreateSalesOrder(var SalesHeader: Record "Sales Header"): Boolean
        var
            SalesQuoteLine: Record "Sales Line";
            SalesOrderTemp: Record "Sales Header";
            SalesOrderLine: Record "Sales Line";
            NewReturnOrderNo: Code[20];
            ReleaseSalesDoc: Codeunit "Release Sales Document";
            ApprovalsMgmt: Codeunit "Approvals Mgmt.";
            SalesQuoteToOrder: Codeunit "Sales-Quote to Order";
        begin
            if ApprovalsMgmt.PrePostApprovalCheckSales(SalesHeader) then
                if SalesQuoteToOrder.Run(SalesHeader) then
                    exit(true);
            exit(false);
        end;
     
     
    codeunit 50104 "Release Sales Doc"
    {
        TableNo = "Sales Header";
    
        trigger OnRun()
        var
            ReleaseSalesDoc: Codeunit "Release Sales Document";
        begin
            ReleaseSalesDoc.PerformManualRelease(Rec);
        end;
    
    }
     
    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Sales-Quote to Order", OnBeforeDeleteSalesQuote, '', false, false)]
        local procedure OnAfterOnRun(var QuoteSalesHeader: Record "Sales Header"; var OrderSalesHeader: Record "Sales Header"; var IsHandled: Boolean; var SalesQuoteLine: Record "Sales Line")
        var
            ReleaseSalesDoc: Codeunit "Release Sales Doc";
        begin
            if not ReleaseSalesDoc.Run(OrderSalesHeader) then
                IsHandled := true;
        end;
  • Vahid Ghafarpour Profile Picture
    12,166 Super User 2025 Season 2 on at
    If any of the responses helped resolve your issue, please take a moment to mark the best answer. This helps others in the community quickly find solutions to similar problems.

    To do this, simply click the "Does this answer your question?" button on the most helpful response and like the helpful posts. If your issue is still unresolved, feel free to provide more details so the community can assist further!

    Thanks for being an active part of the Dynamics 365 Community! 😊

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

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

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

#1
OussamaSabbouh Profile Picture

OussamaSabbouh 2,238

#2
YUN ZHU Profile Picture

YUN ZHU 773 Super User 2025 Season 2

#3
Sumit Singh Profile Picture

Sumit Singh 630

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans