text:
[Event Request] Codeunit 5988 Serv-Documents Mgt.

The following events are required for this object:
    [IntegrationEvent(false, false)]
    local procedure OnUpdateWindow2BeforePostDocumentLines(var ServiceLine: Record "Service Line"; var Window: Dialog; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnPostDocumentLinesAfterCheckServItemRepairStatus(var ServiceLine: Record "Service Line")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnPostDocumentLinesBeforeGetServLineItem(var ServiceLine: Record "Service Line"; var Item: Record Item; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnPostDocumentLinesBeforeInvoiceRounding(var ServiceHeader: Record "Service Header"; var ServiceLine: Record "Service Line"; var TotalServiceLine: Record "Service Line"; var ServAmountsMgt: Codeunit "Serv-Amounts Mgt."; var LastLineRetrieved: Boolean; BiggestLineNo: Integer; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnUpdateWindow3BeforePostDocumentLines(var ServiceHeader: Record "Service Header"; var Window: Dialog; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnUpdateWindow4BeforePostDocumentLines(var ServiceHeader: Record "Service Header"; var Window: Dialog; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnPostDocumentLinesAfterPostLedgerEntry(ServiceHeader: Record "Service Header"; var TotalServiceLine: Record "Service Line"; ServiceLine: Record "Service Line"; var ServPostingJnlsMgt: Codeunit "Serv-Posting Journals Mgt."; GenJnlLineDocType: Enum "Gen. Journal Document Type"; GenJnlLineDocNo: Code[20]; GenJnlLineExtDocNo: Code[35]; var InvoicePostingInterface: Interface "Invoice Posting"; var Window: Dialog; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnAfterMakeInvtAdjustment(ServiceHeader: Record "Service Header")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnPrepareDocumentOnBeforePassedServLineFind(var PassedServLine: Record "Service Line"; ServiceHeader: Record "Service Header"; var ServiceLine: Record "Service Line"; var PServLine: Record "Service Line"; var ServLinesPassed: Boolean; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnPrepareDocumentBeforeInsertServItemLine(ServiceHeader: Record "Service Header")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnPrepareShipmentHeaderBeforeCalcContractDates(var ServiceHeader: Record "Service Header"; var ServItemLine: Record "Service Item Line"; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnOrderUpdateWindowBeforePrepareInvoiceHeader(var ServiceHeader: Record "Service Header"; ServInvHeader: Record "Service Invoice Header"; var Window: Dialog; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnUpdateWindowBeforePrepareInvoiceHeader(var ServiceHeader: Record "Service Header"; ServInvHeader: Record "Service Invoice Header"; var Window: Dialog; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnUpdateWindowBeforePrepareCrMemoHeader(var ServiceHeader: Record "Service Header"; ServCrMemoHeader: Record "Service Cr.Memo Header"; var Window: Dialog; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnBeforeCheckAdjustedLines(var ServiceLine: Record "Service Line"; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnUpdateServLinesOnPostOrderAfterModifyServLine(var ServiceLine: Record "Service Line"; Ship: Boolean; Consume: Boolean; Invoice: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnRemoveLinesNotSatisfyPostingAfterFilter(var ServiceLine: Record "Service Line"; var ServiceLine2: Record "Service Line"; var IsHandled: Boolean)
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnFinalizeDeleteServOrdAllocatBeforeDeleteAll(var ServiceOrderAllocationRec: Record "Service Order Allocation"; ServiceHeader: Record "Service Header")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnBeforeServInvHeaderInsert(var ServiceInvoiceHeader: Record "Service Invoice Header"; ServiceHeader: Record "Service Header"; var ServItemLine: Record "Service Item Line")
    begin
    end;

    [IntegrationEvent(false, false)]
    local procedure OnAfterServCrMemoHeaderInsert(var ServiceCrMemoHeader: Record "Service Cr.Memo Header"; ServiceHeader: Record "Service Header"; var ServItemLine: Record "Service Item Line")
    begin
    end;

    procedure PostDocumentLines(var Window: Dialog)
    var
        ServiceLineACY: Record "Service Line";
        TotalServiceLine: Record "Service Line";
        TotalServiceLineLCY: Record "Service Line";
        ServLineOld: Record "Service Line";
        TempServLine: Record "Service Line" temporary;
        TempVATAmountLine: Record "VAT Amount Line" temporary;
        TempVATAmountLineForSLE: Record "VAT Amount Line" temporary;
        TempVATAmountLineRemainder: Record "VAT Amount Line" temporary;
#if not CLEAN20
        TempInvoicePostBuffer: Record "Invoice Post. Buffer" temporary;
#endif
        DummyTrackingSpecification: Record "Tracking Specification";
        Item: Record Item;
        ServItemMgt: Codeunit ServItemManagement;
        RemQtyToBeInvoiced: Decimal;
        RemQtyToBeInvoicedBase: Decimal;
        RemQtyToBeConsumed: Decimal;
        RemQtyToBeConsumedBase: Decimal;
        TotalAmount: Decimal;
        LineCount: Integer;
        ApplToServEntryNo: Integer;
        WarrantyNo: Integer;
        BiggestLineNo: Integer;
        LastLineRetrieved: Boolean;
        ShouldPostShipmentServiceEntry: Boolean;
        IsHandled: Boolean;
    begin
        LineCount := 0;

        // init cu for posting SLE type Usage
        ServPostingJnlsMgt.InitServiceRegister(NextServLedgerEntryNo, NextWarrantyLedgerEntryNo);
        if not ApplicationAreaMgmt.IsSalesTaxEnabled then begin
            ServLine.CalcVATAmountLines(1, ServHeader, ServLine, TempVATAmountLine, Ship);
            ServLine.CalcVATAmountLines(2, ServHeader, ServLine, TempVATAmountLineForSLE, Ship);
        end;

        ServLine.Reset();
        SortLines(ServLine);
        OnPostDocumentLinesOnAfterSortLines(ServHeader, ServLine);
        ServLedgEntryNo := FindFirstServLedgEntry(ServLine);
        if ServLine.Find('-') then
            repeat
                ServPostingJnlsMgt.SetItemJnlRollRndg(false);
                if ServLine.Type = ServLine.Type::Item then
                    DummyTrackingSpecification.CheckItemTrackingQuantity(
                      DATABASE::"Service Line", ServLine."Document Type".AsInteger(), ServLine."Document No.", ServLine."Line No.",
                      ServLine."Qty. to Ship (Base)", ServLine."Qty. to Invoice (Base)", Ship, Invoice);
                LineCount += 1;
                //EVENT REQUEST
                IsHandled := false;
                OnUpdateWindow2BeforePostDocumentLines(ServLine, Window, IsHandled);
                if not IsHandled then
                    //EVENT REQUEST
                    Window.Update(2, LineCount);

                with ServLine do begin
                    OnPostDocumentLinesOnBeforeCheckServLine(ServHeader, ServLine, Ship, Invoice);

                    if Ship and ("Qty. to Ship" <> 0) or Invoice and ("Qty. to Invoice" <> 0) then
                        ServOrderMgt.CheckServItemRepairStatus(ServHeader, ServItemLine, ServLine);

                    OnPostDocumentLinesAfterCheckServItemRepairStatus(ServLine); //EVENT REQUEST
                    ServLineOld := ServLine;
                    if "Spare Part Action" in
                       ["Spare Part Action"::"Component Replaced",
                        "Spare Part Action"::Permanent,
                        "Spare Part Action"::"Temporary"]
                    then begin
                        "Spare Part Action" := "Spare Part Action"::"Component Installed";
                        Modify
                    end;

                    // post Service Ledger Entry of type Usage, on shipment
                    ShouldPostShipmentServiceEntry :=
                        (Ship and ("Document Type" = "Document Type"::Order) or
                        ("Document Type" = "Document Type"::Invoice)) and
                       ("Qty. to Ship" <> 0) and not ServAmountsMgt.RoundingLineInserted();
                    OnPostDocumentLinesOnAfterCalcShouldPostShipmentServiceEntry(ServHeader, ServLine, Ship, ApplToServEntryNo, NextServLedgerEntryNo, ShouldPostShipmentServiceEntry);
                    if ShouldPostShipmentServiceEntry then begin
                        TempServLine := ServLine;
                        ServPostingJnlsMgt.CalcSLEDivideAmount("Qty. to Ship", ServHeader, TempServLine, TempVATAmountLineForSLE);

                        ApplToServEntryNo :=
                          ServPostingJnlsMgt.InsertServLedgerEntry(NextServLedgerEntryNo,
                            ServHeader, TempServLine, ServItemLine, "Qty. to Ship", ServHeader."Shipping No.");

                        if "Appl.-to Service Entry" = 0 then
                            "Appl.-to Service Entry" := ApplToServEntryNo;
                    end;

                    //EVENT REQUEST
                    IsHandled := false;
                    OnPostDocumentLinesBeforeGetServLineItem(ServLine, Item, IsHandled);
                    if not IsHandled then
                        //EVENT REQUEST
                        if (Type = Type::Item) and ("No." <> '') then begin
                            GetServLineItem(ServLine, Item);
                            if (Item."Costing Method" = Item."Costing Method"::Standard) and not IsShipment then
                                GetUnitCost;
                        end;

                    if CheckCloseCondition(
                         Quantity, "Qty. to Invoice", "Qty. to Consume", "Quantity Invoiced", "Quantity Consumed") = false
                    then
                        CloseCondition := false;

                    if Quantity = 0 then
                        TestField("Line Amount", 0)
                    else begin
                        TestBinCode;
                        TestField("No.");
                        TestField(Type);
                        if not ApplicationAreaMgmt.IsSalesTaxEnabled then begin
                            TestField("Gen. Bus. Posting Group");
                            TestField("Gen. Prod. Posting Group");
                        end;
                        ServAmountsMgt.DivideAmount(1, "Qty. to Invoice", ServHeader, ServLine,
                          TempVATAmountLine, TempVATAmountLineRemainder);
                    end;

                    OnPostDocumentLinesOnBeforeRoundAmount(ServLine);

                    ServAmountsMgt.RoundAmount("Qty. to Invoice", ServHeader, ServLine,
                      TempServiceLine, TotalServiceLine, TotalServiceLineLCY, ServiceLineACY);

                    if "Document Type" <> "Document Type"::"Credit Memo" then begin
                        ServAmountsMgt.ReverseAmount(ServLine);
                        ServAmountsMgt.ReverseAmount(ServiceLineACY);
                    end;

                    // post Service Ledger Entry of type Sale, on invoice
                    if "Document Type" = "Document Type"::"Credit Memo" then begin
                        CheckIfServDuplicateLine(ServLine);
                        ServPostingJnlsMgt.CreateCreditEntry(NextServLedgerEntryNo,
                          ServHeader, ServLine, GenJnlLineDocNo);
                        OnPostDocumentLinesOnAfterServPostingJnlsMgtCreateCreditEntry(NextServLedgerEntryNo);
                    end else
                        if (Invoice or ("Document Type" = "Document Type"::Invoice)) and
                           ("Qty. to Invoice" <> 0) and not ServAmountsMgt.RoundingLineInserted
                        then begin
                            CheckIfServDuplicateLine(ServLine);
                            ServPostingJnlsMgt.InsertServLedgerEntrySale(NextServLedgerEntryNo,
                              ServHeader, ServLine, ServItemLine, "Qty. to Invoice", "Qty. to Invoice", GenJnlLineDocNo, "Line No.");
                            OnPostDocumentLinesOnAfterServPostingJnlsMgtInsertServLedgerEntrySaleInvoice(NextServLedgerEntryNo);
                        end;

                    InsertServLedgerEntrySaleConsume();

                    RemQtyToBeInvoiced := "Qty. to Invoice";
                    RemQtyToBeConsumed := "Qty. to Consume";
                    RemQtyToBeInvoicedBase := "Qty. to Invoice (Base)";
                    RemQtyToBeConsumedBase := "Qty. to Consume (Base)";

                    if Invoice then
                        if "Qty. to Invoice" = 0 then
                            TrackingSpecificationExists := false
                        else
                            TrackingSpecificationExists :=
                              ServITRMgt.RetrieveInvoiceSpecification(ServLine, TempInvoicingSpecification, false);

                    if Consume then
                        if "Qty. to Consume" = 0 then
                            TrackingSpecificationExists := false
                        else
                            TrackingSpecificationExists :=
                              ServITRMgt.RetrieveInvoiceSpecification(ServLine, TempInvoicingSpecification, true);

                    // update previously shipped lines with invoicing information.
                    if "Document Type" = "Document Type"::"Credit Memo" then
                        UpdateRcptLinesOnInv
                    else // Order or Invoice
                        UpdateShptLinesOnInv(ServLine,
                          RemQtyToBeInvoiced, RemQtyToBeInvoicedBase,
                          RemQtyToBeConsumed, RemQtyToBeConsumedBase);

                    if TrackingSpecificationExists then
                        ServITRMgt.SaveInvoiceSpecification(TempInvoicingSpecification, TempTrackingSpecification);

                    // post service line via journals
                    case Type of
                        Type::Item:
                            PostServiceItemLine(
                              ServHeader, ServLine, RemQtyToBeInvoicedBase, RemQtyToBeInvoiced, RemQtyToBeConsumedBase, RemQtyToBeConsumed,
                              WarrantyNo);
                        Type::Resource:
                            PostServiceResourceLine(ServLine, WarrantyNo);
                    end;

                    if Consume and ("Document Type" = "Document Type"::Order) then begin
                        OnPostDocumentLinesOnBeforePostRemQtyToBeConsumed(ServHeader, ServLine);
                        if ServPostingJnlsMgt.PostJobJnlLine(ServHeader, ServLine, RemQtyToBeConsumed) then
                            UpdateServiceLedgerEntry(NextServLedgerEntryNo - 1)
                        else
                            if (Type = Type::Resource) and (RemQtyToBeConsumed <> 0) then
                                ServPostingJnlsMgt.PostResJnlLineConsume(ServLine, ServShptHeader);
                    end;

                    if Ship and ("Document Type" = "Document Type"::Order) then begin
                        // component spare part action
                        ServItemMgt.AddOrReplaceSIComponent(ServLineOld, ServHeader,
                          ServHeader."Shipping No.", ServLineOld."Line No.", TempTrackingSpecification);
                        // allocations
                        ServAllocMgt.SetServLineAllocStatus(TempServiceLine);
                    end;

                    if (Type <> Type::" ") and ("Qty. to Invoice" <> 0) then
#if not CLEAN20
                        if ServMgtSetup."Invoice Posting Setup" = "Service Invoice Posting"::"Invoice Posting (Default)" then
                            ServAmountsMgt.FillInvoicePostBuffer(TempInvoicePostBuffer, ServLine, ServiceLineACY, ServHeader)
                        else
#endif
                            InvoicePostingInterface.PrepareLine(ServHeader, ServLine, ServiceLineACY);

                    OnPostDocumentLinesOnAfterFillInvPostingBuffer(ServHeader, ServLine, ServiceLineACY);

                    // prepare posted document lines
                    if Ship then
                        PrepareShipmentLine(TempServiceLine, WarrantyNo);
                    if Invoice then
                        if "Document Type" in ["Document Type"::Order, "Document Type"::Invoice] then
                            PrepareInvoiceLine(TempServiceLine)
                        else
                            PrepareCrMemoLine(TempServiceLine);

                    if Invoice or Consume then
                        CollectValueEntryRelation;

                    if ServAmountsMgt.RoundingLineInserted then
                        LastLineRetrieved := true
                    else begin
                        BiggestLineNo := ServAmountsMgt.MAX(ServAmountsMgt.GetLastLineNo(ServLine), "Line No.");
                        LastLineRetrieved := Next() = 0; // ServLine
                        //EVENT REQUEST
                        IsHandled := false;
                        OnPostDocumentLinesBeforeInvoiceRounding(ServHeader, ServLine, TotalServiceLine, ServAmountsMgt, LastLineRetrieved, BiggestLineNo, IsHandled);
                        if not IsHandled then
                            //EVENT REQUEST
                            if LastLineRetrieved and SalesSetup."Invoice Rounding" then
                                ServAmountsMgt.InvoiceRounding(ServHeader, ServLine, TotalServiceLine,
                                  LastLineRetrieved, false, BiggestLineNo);
                    end;
                end; // With ServLine
            until LastLineRetrieved;

        with ServHeader do begin
            // again reverse amount
            if "Document Type" <> "Document Type"::"Credit Memo" then begin
                ServAmountsMgt.ReverseAmount(TotalServiceLine);
                ServAmountsMgt.ReverseAmount(TotalServiceLineLCY);
                TotalServiceLineLCY."Unit Cost (LCY)" := -TotalServiceLineLCY."Unit Cost (LCY)";
            end;

            ServPostingJnlsMgt.FinishServiceRegister(NextServLedgerEntryNo, NextWarrantyLedgerEntryNo);

            if Invoice or ("Document Type" = "Document Type"::Invoice) then begin
                Clear(ServDocReg);
                // fake service register entry to be used in the following PostServSalesDocument()
                if Invoice and ("Document Type" = "Document Type"::Order) and (ServLine."Contract No." <> '') then
                    ServDocReg.InsertServiceSalesDocument(
                      ServDocReg."Source Document Type"::Contract, ServLine."Contract No.",
                      ServDocReg."Destination Document Type"::Invoice, ServLine."Document No.");
                ServDocReg.PostServiceSalesDocument(
                  ServDocReg."Destination Document Type"::Invoice,
                  ServLine."Document No.", ServInvHeader."No.");
            end;
            if Invoice or ("Document Type" = "Document Type"::"Credit Memo") then begin
                Clear(ServDocReg);
                ServDocReg.PostServiceSalesDocument(
                  ServDocReg."Destination Document Type"::"Credit Memo",
                  ServLine."Document No.", ServCrMemoHeader."No.");
            end;

            // Post sales and VAT to G/L entries from posting buffer
            if Invoice then begin
#if not CLEAN20
                if ServMgtSetup."Invoice Posting Setup" = "Service Invoice Posting"::"Invoice Posting (Default)" then begin
                    OnPostDocumentLinesOnBeforePostInvoicePostBuffer(
                        ServHeader, TempInvoicePostBuffer, TotalServiceLine, TotalServiceLineLCY);
                    LineCount := 0;
                    if TempInvoicePostBuffer.Find('+') then
                        repeat
                            LineCount += 1;
                            //EVENT REQUEST
                            IsHandled := false;
                            OnUpdateWindow3BeforePostDocumentLines(ServHeader, Window, IsHandled);
                            if not IsHandled then
                                //EVENT REQUEST
                                Window.Update(3, LineCount);
                            ServPostingJnlsMgt.SetPostingDate("Posting Date");
                            ServPostingJnlsMgt.PostInvoicePostBufferLine(
                                TempInvoicePostBuffer, GenJnlLineDocType.AsInteger(), GenJnlLineDocNo, GenJnlLineExtDocNo);
                        until TempInvoicePostBuffer.Next(-1) = 0;
                end else begin
#endif
                    GetInvoicePostingParameters();
                    InvoicePostingInterface.SetParameters(InvoicePostingParameters);
                    InvoicePostingInterface.SetTotalLines(TotalServiceLine, TotalServiceLineLCY);
                    ServPostingJnlsMgt.PostLines(ServHeader, InvoicePostingInterface, Window, TotalAmount);
#if not CLEAN20
                end;
#endif

                // Post customer entry
                //EVENT REQUEST
                IsHandled := false;
                OnUpdateWindow4BeforePostDocumentLines(ServHeader, Window, IsHandled);
                if not IsHandled then
                    //EVENT REQUEST
                    Window.Update(4, 1);
#if not CLEAN20
                if ServMgtSetup."Invoice Posting Setup" = "Service Invoice Posting"::"Invoice Posting (Default)" then begin
                    ServPostingJnlsMgt.SetPostingDate("Posting Date");
                    ServPostingJnlsMgt.PostCustomerEntry(
                        TotalServiceLine, TotalServiceLineLCY, GenJnlLineDocType.AsInteger(), GenJnlLineDocNo, GenJnlLineExtDocNo);
                end else
#endif
                ServPostingJnlsMgt.PostLedgerEntry(ServHeader, InvoicePostingInterface);

                // post Balancing account
                //EVENT REQUEST
                IsHandled := false;
                OnPostDocumentLinesAfterPostLedgerEntry(ServHeader, TotalServiceLine, ServLine, ServPostingJnlsMgt, GenJnlLineDocType, GenJnlLineDocNo, GenJnlLineExtDocNo, InvoicePostingInterface, Window, IsHandled);
                if not IsHandled then
                    //EVENT REQUEST
                    if "Bal. Account No." <> '' then begin
                        Window.Update(5, 1);
#if not CLEAN20
                        if ServMgtSetup."Invoice Posting Setup" = "Service Invoice Posting"::"Invoice Posting (Default)" then begin
                            ServPostingJnlsMgt.SetPostingDate("Posting Date");
                            ServPostingJnlsMgt.PostBalancingEntry(
                                TotalServiceLine, TotalServiceLineLCY, GenJnlLineDocType.AsInteger(), GenJnlLineDocNo, GenJnlLineExtDocNo);
                        end else
#endif
                    ServPostingJnlsMgt.PostBalancingEntry(ServHeader, InvoicePostingInterface);
                    end;
            end;

            MakeInvtAdjustment;
            if Ship then begin
                "Last Shipping No." := "Shipping No.";
                "Shipping No." := '';
            end;

            if Invoice then begin
                "Last Posting No." := "Posting No.";
                "Posting No." := '';
            end;

            Modify;
        end;// with header

        OnAfterPostDocumentLines(ServHeader, ServInvHeader, ServInvLine, ServCrMemoHeader, ServCrMemoLine, GenJnlLineDocType, GenJnlLineDocNo);
    end;

    local procedure MakeInvtAdjustment()
    var
        InvtSetup: Record "Inventory Setup";
        InvtAdjmtHandler: Codeunit "Inventory Adjustment Handler";
    begin
        InvtSetup.Get();
        if InvtSetup.AutomaticCostAdjmtRequired() then
            InvtAdjmtHandler.MakeInventoryAdjustment(true, InvtSetup."Automatic Cost Posting");
        OnAfterMakeInvtAdjustment(ServHeader); //EVENT REQUEST
    end;

    local procedure PrepareDocument(var PassedServHeader: Record "Service Header"; var PassedServLine: Record "Service Line")
    var
        IsHandled: Boolean;
    begin
        // fill ServiceHeader we will work with (tempTable)
        ServHeader.DeleteAll();
        ServHeader.Copy(PassedServHeader);
        ServHeader.Insert(); // temporary table

        // Fetch persistent Service Lines and Service Item Lines bound to Service Header.
        // Copy persistent records to temporary.
        with ServHeader do begin
            ServLine.DeleteAll();
            PassedServLine.Reset();
            // collect passed lines
            //EVENT CHANGE REQUEST
            IsHandled := false;
            OnPrepareDocumentOnBeforePassedServLineFind(PassedServLine, ServHeader, ServLine, PServLine, ServLinesPassed, IsHandled);
            if not IsHandled then
                //EVENT CHANGE REQUEST
                if PassedServLine.Find('-') then begin
                    repeat
                        ServLine.Copy(PassedServLine);
                        ServLine.Insert(); // temptable
                    until PassedServLine.Next() = 0;
                    ServLinesPassed := true; // indicate either we collect passed or all SLs.
                end else begin
                    // collect persistent lines related to ServHeader
                    PServLine.Reset();
                    PServLine.SetRange("Document Type", "Document Type");
                    PServLine.SetRange("Document No.", "No.");
                    OnPrepareDocumentOnAfterSetPServLineFilters(PServLine);
                    if PServLine.Find('-') then
                        repeat
                            ServLine.Copy(PServLine);
                            ServLine."Posting Date" := "Posting Date";
                            OnPrepareDocumentOnPServLineLoopOnBeforeServLineInsert(ServLine);
                            ServLine.Insert(); // temptable
                        until PServLine.Next() = 0;
                    ServLinesPassed := false;
                end;

            RemoveLinesNotSatisfyPosting();

            OnPrepareDocumentBeforeInsertServItemLine(ServHeader); //EVENT REQUEST
            ServItemLine.DeleteAll();
            PServItemLine.Reset();
            PServItemLine.SetRange("Document Type", "Document Type");
            PServItemLine.SetRange("Document No.", "No.");
            OnPrepareDocumentOnAfterSetPServItemLineFilters(PServItemLine);
            if PServItemLine.Find('-') then
                repeat
                    ServItemLine.Copy(PServItemLine);
                    ServItemLine.Insert(); // temptable
                until PServItemLine.Next() = 0;
        end;

        OnAfterPrepareDocument(PassedServHeader, PassedServLine);
    end;

    procedure PrepareShipmentHeader(): Code[20]
    var
        ServLine: Record "Service Line";
        PServShptHeader: Record "Service Shipment Header";
        PServShptLine: Record "Service Shipment Line";
        ServItemMgt: Codeunit ServItemManagement;
        RecordLinkManagement: Codeunit "Record Link Management";
        IsHandled: Boolean;
    begin
        with ServHeader do begin
            if ("Document Type" = "Document Type"::Order) or
               (("Document Type" = "Document Type"::Invoice) and ServMgtSetup."Shipment on Invoice")
            then begin
                PServShptHeader.LockTable();
                PServShptLine.LockTable();
                ServShptHeader.Init();
                ServShptHeader.TransferFields(ServHeader);
                ServShptHeader."No." := "Shipping No.";
                if "Document Type" = "Document Type"::Order then begin
                    ServShptHeader."Order No. Series" := "No. Series";
                    ServShptHeader."Order No." := "No.";
                end;
                if ServMgtSetup."Copy Comments Order to Shpt." then
                    RecordLinkManagement.CopyLinks(ServHeader, ServShptHeader);
                ServShptHeader."Source Code" := SrcCode;
                ServShptHeader."User ID" := UserId;
                ServShptHeader."No. Printed" := 0;
                OnBeforeServShptHeaderInsert(ServShptHeader, ServHeader);
                ServShptHeader.Insert();
                OnAfterServShptHeaderInsert(ServShptHeader, ServHeader);

                Clear(ServLogMgt);
                ServLogMgt.ServOrderShipmentPost("No.", ServShptHeader."No.");

                if ("Document Type" = "Document Type"::Order) and ServMgtSetup."Copy Comments Order to Shpt." then
                    ServOrderMgt.CopyCommentLines(
                      "Service Comment Table Name"::"Service Header".AsInteger(),
                      "Service Comment Table Name"::"Service Shipment Header".AsInteger(),
                      "No.", ServShptHeader."No.");

                // create Service Shipment Item Lines
                ServItemLine.Reset();
                if ServItemLine.Find('-') then
                    repeat
                        // create SSIL
                        ServShptItemLine.TransferFields(ServItemLine);
                        ServShptItemLine."No." := ServShptHeader."No.";
                        OnBeforeServShptItemLineInsert(ServShptItemLine, ServItemLine);
                        ServShptItemLine.Insert();
                        OnAfterServShptItemLineInsert(ServShptItemLine, ServItemLine);

                        // set mgt. date and service dates
                        //EVENT REQUEST
                        IsHandled := false;
                        OnPrepareShipmentHeaderBeforeCalcContractDates(ServHeader, ServItemLine, IsHandled);
                        if not IsHandled then
                            //EVENT REQUEST
                            if (ServItemLine."Contract No." <> '') and (ServItemLine."Contract Line No." <> 0) and
                               ("Contract No." <> '')
                            then begin
                                ServLine.SetRange("Document Type", "Document Type");
                                ServLine.SetRange("Document No.", "No.");
                                ServLine.SetFilter("Quantity Shipped", '>%1', 0);
                                if not ServLine.FindFirst() then
                                    ServOrderMgt.CalcContractDates(ServHeader, ServItemLine);
                            end;
                        IsHandled := false;
                        OnPrepareShipmentHeaderOnBeforeCalcServItemDates(ServHeader, ServItemLine, IsHandled);
                        if not IsHandled then
                            ServOrderMgt.CalcServItemDates(ServHeader, ServItemLine."Service Item No.");
                    until ServItemLine.Next() = 0
                else begin
                    ServShptItemLine.Init();
                    ServShptItemLine."No." := ServShptHeader."No.";
                    ServShptItemLine."Line No." := 10000;
                    ServShptItemLine.Description := Format("Document Type") + ' ' + "No.";
                    ServShptItemLine.Insert();
                end;
            end;

    procedure PrepareInvoiceHeader(var Window: Dialog): Code[20]
    var
        RecordLinkManagement: Codeunit "Record Link Management";
        IsHandled: Boolean;
    begin
        with ServHeader do begin
            ServInvHeader.Init();
            ServInvHeader.TransferFields(ServHeader);
            if "Document Type" = "Document Type"::Order then begin
                ServInvHeader."No." := "Posting No.";
                ServInvHeader."Pre-Assigned No. Series" := '';
                ServInvHeader."Order No. Series" := "No. Series";
                ServInvHeader."Order No." := "No.";
                //EVENT REQUEST
                IsHandled := false;
                OnOrderUpdateWindowBeforePrepareInvoiceHeader(ServHeader, ServInvHeader, Window, IsHandled);
                if not IsHandled then
                    //EVENT REQUEST
                    Window.Update(1, StrSubstNo(Text007, "Document Type", "No.", ServInvHeader."No."));
            end else begin
                ServInvHeader."Pre-Assigned No. Series" := "No. Series";
                ServInvHeader."Pre-Assigned No." := "No.";
                if "Posting No." <> '' then begin
                    ServInvHeader."No." := "Posting No.";
                    //EVENT REQUEST
                    IsHandled := false;
                    OnUpdateWindowBeforePrepareInvoiceHeader(ServHeader, ServInvHeader, Window, IsHandled);
                    if not IsHandled then
                        //EVENT REQUEST
                        Window.Update(1, StrSubstNo(Text007, "Document Type", "No.", ServInvHeader."No."));
                end;
            end;
            if ServMgtSetup."Copy Comments Order to Invoice" then
                RecordLinkManagement.CopyLinks(ServHeader, ServInvHeader);
            ServInvHeader."Source Code" := SrcCode;
            ServInvHeader."User ID" := UserId;
            ServInvHeader."No. Printed" := 0;
            OnBeforeServInvHeaderInsert(ServInvHeader, ServHeader, ServItemLine); //EVENT CHANGE REQUEST
            ServInvHeader.Insert();
            OnAfterServInvHeaderInsert(ServInvHeader, ServHeader);

            Clear(ServLogMgt);
            case "Document Type" of
                "Document Type"::Invoice:
                    ServLogMgt.ServInvoicePost("No.", ServInvHeader."No.");
                "Document Type"::Order:
                    ServLogMgt.ServOrderInvoicePost("No.", ServInvHeader."No.");
            end;

            SetGenJnlLineDocNos("Gen. Journal Document Type"::Invoice, ServInvHeader."No.", "No.");

            if ("Document Type" = "Document Type"::Invoice) or
               ("Document Type" = "Document Type"::Order) and ServMgtSetup."Copy Comments Order to Invoice"
            then
                ServOrderMgt.CopyCommentLinesWithSubType(
                  "Service Comment Table Name"::"Service Header".AsInteger(),
                  "Service Comment Table Name"::"Service Invoice Header".AsInteger(),
                  "No.", ServInvHeader."No.", "Document Type".AsInteger());

            OnAfterPrepareInvoiceHeader(ServInvHeader, ServHeader, ServItemLine);
            exit(ServInvHeader."No.");
        end;
    end;

    procedure PrepareCrMemoHeader(var Window: Dialog): Code[20]
    var
        RecordLinkManagement: Codeunit "Record Link Management";
        IsHandled: Boolean;
    begin
        with ServHeader do begin
            ServCrMemoHeader.Init();
            ServCrMemoHeader.TransferFields(ServHeader);
            ServCrMemoHeader."Pre-Assigned No. Series" := "No. Series";
            ServCrMemoHeader."Pre-Assigned No." := "No.";
            if "Posting No." <> '' then begin
                ServCrMemoHeader."No." := "Posting No.";
                //EVENT REQUEST
                IsHandled := false;
                OnUpdateWindowBeforePrepareCrMemoHeader(ServHeader, ServCrMemoHeader, Window, IsHandled);
                if not IsHandled then
                    //EVENT REQUEST
                    Window.Update(1, StrSubstNo(Text008, "Document Type", "No.", ServCrMemoHeader."No."));
            end;
            RecordLinkManagement.CopyLinks(ServHeader, ServCrMemoHeader);
            ServCrMemoHeader."Source Code" := SrcCode;
            ServCrMemoHeader."User ID" := UserId;
            ServCrMemoHeader."No. Printed" := 0;
            OnBeforeServCrMemoHeaderInsert(ServCrMemoHeader, ServHeader);
            ServCrMemoHeader.Insert();
            OnAfterServCrMemoHeaderInsert(ServCrMemoHeader, ServHeader, ServItemLine); //EVENT CHANGE REQUEST

            Clear(ServLogMgt);
            ServLogMgt.ServCrMemoPost("No.", ServCrMemoHeader."No.");

            SetGenJnlLineDocNos("Gen. Journal Document Type"::"Credit Memo", ServCrMemoHeader."No.", "No.");

            ServOrderMgt.CopyCommentLines(
              "Service Comment Table Name"::"Service Header".AsInteger(),
              "Service Comment Table Name"::"Service Cr.Memo Header".AsInteger(),
              "No.", ServCrMemoHeader."No.");

            OnAfterPrepareCrMemoHeader(ServCrMemoHeader, ServHeader);
            exit(ServCrMemoHeader."No.");
        end;
    end;

    procedure CheckAdjustedLines()
    var
        ServPriceMgt: Codeunit "Service Price Management";
        ConfirmManagement: Codeunit "Confirm Management";
        IsHandled: Boolean;
    begin
        //EVENT REQUEST
        IsHandled := false;
        OnBeforeCheckAdjustedLines(ServLine, IsHandled);
        if not IsHandled then
            //EVENT REQUEST
            with ServLine do begin
                if ServItemLine.Get("Document Type", "Document No.", "Service Item Line No.") then
                    if ServItemLine."Service Price Group Code" <> '' then
                        if ServPriceMgt.IsLineToAdjustFirstInvoiced(ServLine) then
                            if not ConfirmManagement.GetResponseOrDefault(
                                 StrSubstNo(Text015, TableCaption, FieldCaption("Service Price Group Code")), true)
                            then
                                Error('');
                Reset;
            end;
    end;

                        OnUpdateServLinesOnPostOrderOnBeforeInitOutstanding(ServLine);
                        InitOutstanding;
                        InitQtyToShip;

                        if "Inv. Discount Amount" <> OldInvDiscountAmount then
                            CalcInvDiscAmt := true;

                        Modify;
                        OnUpdateServLinesOnPostOrderAfterModifyServLine(ServLine, Ship, Consume, Invoice); //EVENT REQUEST
                    end;
                until Next() = 0;

            if Find('-') then
                if SalesSetup."Calc. Inv. Discount" or CalcInvDiscAmt then begin
                    ServHeader.Get("Document Type", "Document No.");
                    Clear(ServCalcDisc);
                    ServCalcDisc.CalculateWithServHeader(ServHeader, PServLine, ServLine);
                end;
        end;

    local procedure RemoveLinesNotSatisfyPosting()
    var
        ServLine2: Record "Service Line";
        IsHandled: Boolean;
    begin
        // Find ServLines not selected to post, and check if they were completely posted
        if ServLine.FindFirst() then begin
            ServLine2.SetRange("Document Type", ServHeader."Document Type");
            ServLine2.SetRange("Document No.", ServHeader."No.");
            ServLine2.FindSet();
            if ServLine.Count <> ServLine2.Count then
                repeat
                    if not ServLine.Get(ServLine2."Document Type", ServLine2."Document No.", ServLine2."Line No.") then
                        if ServLine2.Quantity <> ServLine2."Quantity Invoiced" + ServLine2."Quantity Consumed" then
                            CloseCondition := false;
                until (ServLine2.Next() = 0) or (not CloseCondition);
        end;
        // Remove ServLines that do not meet the posting conditions from the selected to post lines
        with ServLine do
            if FindSet() then
                repeat
                    //EVENT REQUEST
                    IsHandled := false;
                    OnRemoveLinesNotSatisfyPostingAfterFilter(ServLine, ServLine2, IsHandled);
                    if not IsHandled then
                        //EVENT REQUEST
                        if ((Ship and not Consume and not Invoice and (("Qty. to Consume" <> 0) or ("Qty. to Ship" = 0))) or
                            ((Ship and Consume) and ("Qty. to Consume" = 0)) or
                            ((Ship and Invoice) and (("Qty. to Consume" <> 0) or (("Qty. to Ship" = 0) and ("Qty. to Invoice" = 0)))) or
                            ((not Ship and Invoice) and (("Qty. to Invoice" = 0) or
                                                         ("Quantity Shipped" - "Quantity Invoiced" - "Quantity Consumed" = 0)))) and
                           ("Attached to Line No." = 0)
                        then begin
                            if Quantity <> "Quantity Invoiced" + "Quantity Consumed" then
                                CloseCondition := false;
                            if ((Type <> Type::" ") and (Description = '') and ("No." = '')) or
                               ((Type <> Type::" ") and (Description <> '') and ("No." <> ''))
                            then begin
                                ServLine2 := ServLine;
                                if ServLine2.Find() then begin
                                    IsHandled := false;
                                    OnRemoveLinesNotSatisfyPostingOnBeforeInitRemainingServLine(ServLine2, IsHandled);
                                    if not IsHandled then begin
                                        ServLine2.InitOutstanding();
                                        ServLine2.InitQtyToShip();
                                        ServLine2.Modify();
                                    end;
                                end;
                                DeleteWithAttachedLines;
                            end;
                        end;
                until Next() = 0;
    end;

    local procedure FinalizeDeleteServOrdAllocat()
    var
        ServiceOrderAllocationRec: Record "Service Order Allocation";
    begin
        if not (ServHeader."Document Type" in [ServHeader."Document Type"::Quote, ServHeader."Document Type"::Order]) then
            exit;
        ServiceOrderAllocationRec.Reset();
        ServiceOrderAllocationRec.SetCurrentKey("Document Type", "Document No.");
        ServiceOrderAllocationRec.SetRange("Document Type", ServHeader."Document Type");
        ServiceOrderAllocationRec.SetRange("Document No.", ServHeader."No.");
        OnFinalizeDeleteServOrdAllocatBeforeDeleteAll(ServiceOrderAllocationRec, ServHeader); //EVENT REQUEST
        ServiceOrderAllocationRec.DeleteAll();
    end;

This event request was never created as an internal work item ☹ When the description gets too long, our automations fail. Please recreate as smaller issues.

authors: JesperSchulz SimonasDargis


text:
Codeunit 367 - CheckManagement - new OnFinancialVoidCheckOnBeforePostAccount event

Please add new event OnFinancialVoidCheckOnBeforePostAccount to codeunit 367 (CheckManagement):
LOCAL [IntegrationEvent] OnFinancialVoidCheckOnBeforePostAccount(VAR GenJournalLine : Record "Gen. Journal Line";VAR GLEntry : Record "G/L Entry")
Usage:
[External] FinancialVoidCheck(VAR CheckLedgEntry : Record "Check Ledger Entry")
OnBeforeFinancialVoidCheck(CheckLedgEntry);

...

CASE CheckLedgEntry."Bal. Account Type" OF
  CheckLedgEntry."Bal. Account Type"::"G/L Account":
    WITH GLEntry DO BEGIN
      SETCURRENTKEY("Transaction No.");

      ...

      IF FINDSET THEN
        REPEAT
          GenJnlLine2.VALIDATE("Account No.","G/L Account No.");

          ...

          ///New Code
          OnFinancialVoidCheckOnBeforePostAccount(GenJnlLine2,GLEntry);

          GenJnlPostLine.RunWithCheck(GenJnlLine2);
        UNTIL NEXT = 0;
    END;

Please use latest version of code, I cannot accept you suggestion for older versions.

Thank you. Will check when I back from holiday ;-)

source: gharchive/issue

authors: AlexanderYakunin rgrygoryshchak

repo: microsoft/ALAppExtensions

license: MIT

license_type: permissive

license_source: github-api


text:
[Event Request] codeunit 86 "Sales-Quote to Order"

Describe the request
We could use a new publisher in procedure TransferQuoteToOrderLines
Existing code is:
    local procedure TransferQuoteToOrderLines(var SalesQuoteLine: Record "Sales Line"; var SalesQuoteHeader: Record "Sales Header"; var SalesOrderLine: Record "Sales Line"; var SalesOrderHeader: Record "Sales Header"; Customer: Record Customer)
    var
        ATOLink: Record "Assemble-to-Order Link";
        PrepmtMgt: Codeunit "Prepayment Mgt.";
        SalesLineReserve: Codeunit "Sales Line-Reserve";
        IsHandled: Boolean;
    begin
        SalesQuoteLine.Reset();
        SalesQuoteLine.SetRange("Document Type", SalesQuoteHeader."Document Type");
        SalesQuoteLine.SetRange("Document No.", SalesQuoteHeader."No.");
        OnTransferQuoteToOrderLinesOnAfterSetFilters(SalesQuoteLine, SalesQuoteHeader);
        if SalesQuoteLine.FindSet() then
            repeat
                IsHandled := false;
                OnBeforeTransferQuoteLineToOrderLineLoop(SalesQuoteLine, SalesQuoteHeader, SalesOrderHeader, IsHandled);
                if not IsHandled then begin
                    SalesOrderLine := SalesQuoteLine;
                    SalesOrderLine."Document Type" := SalesOrderHeader."Document Type";
                    SalesOrderLine."Document No." := SalesOrderHeader."No.";
                    SalesOrderLine."Shortcut Dimension 1 Code" := SalesQuoteLine."Shortcut Dimension 1 Code";
                    SalesOrderLine."Shortcut Dimension 2 Code" := SalesQuoteLine."Shortcut Dimension 2 Code";
                    SalesOrderLine."Dimension Set ID" := SalesQuoteLine."Dimension Set ID";
                    SalesOrderLine."Transaction Type" := SalesOrderHeader."Transaction Type";
                    OnTransferQuoteToOrderLinesOnBeforeUpdatePrepaymentPct(SalesQuoteLine, SalesQuoteHeader, SalesOrderLine, SalesOrderHeader, Customer);
                    if Customer."Prepayment %" <> 0 then
                        SalesOrderLine."Prepayment %" := Customer."Prepayment %";
                    PrepmtMgt.SetSalesPrepaymentPct(SalesOrderLine, SalesOrderHeader."Posting Date");
                    SalesOrderLine.Validate("Prepayment %");
                    IsHandled := false;
                    OnTransferQuoteToOrderLinesOnBeforeDefaultDeferralCode(SalesOrderLine, SalesOrderHeader, SalesQuoteLine, IsHandled);
                    if not IsHandled then
                        if SalesOrderLine."No." <> '' then
                            SalesOrderLine.DefaultDeferralCode();
                    OnBeforeInsertSalesOrderLine(SalesOrderLine, SalesOrderHeader, SalesQuoteLine, SalesQuoteHeader);
                    SalesOrderLine.Insert();
                    OnAfterInsertSalesOrderLine(SalesOrderLine, SalesOrderHeader, SalesQuoteLine, SalesQuoteHeader);
                    ATOLink.MakeAsmOrderLinkedToSalesOrderLine(SalesQuoteLine, SalesOrderLine);
                    OnTransferQuoteToOrderLinesOnAfterATOLinkMakeAsmOrderLinkedToSalesOrderLine(SalesQuoteLine, SalesOrderLine);
                    SalesLineReserve.TransferSaleLineToSalesLine(
                      SalesQuoteLine, SalesOrderLine, SalesQuoteLine."Outstanding Qty. (Base)");
                    SalesLineReserve.VerifyQuantity(SalesOrderLine, SalesQuoteLine);
                    if SalesOrderLine.Reserve = SalesOrderLine.Reserve::Always then
                        SalesOrderLine.AutoReserve();
                end;
            until SalesQuoteLine.Next() = 0;
        OnAfterTransferQuoteToOrderLines(SalesQuoteLine, SalesQuoteHeader);
    end;

our suggestion:
    local procedure TransferQuoteToOrderLines(var SalesQuoteLine: Record "Sales Line"; var SalesQuoteHeader: Record "Sales Header"; var SalesOrderLine: Record "Sales Line"; var SalesOrderHeader: Record "Sales Header"; Customer: Record Customer)
    var
        ATOLink: Record "Assemble-to-Order Link";
        PrepmtMgt: Codeunit "Prepayment Mgt.";
        SalesLineReserve: Codeunit "Sales Line-Reserve";
        IsHandled: Boolean;
    begin
        SalesQuoteLine.Reset();
        SalesQuoteLine.SetRange("Document Type", SalesQuoteHeader."Document Type");
        SalesQuoteLine.SetRange("Document No.", SalesQuoteHeader."No.");
        OnTransferQuoteToOrderLinesOnAfterSetFilters(SalesQuoteLine, SalesQuoteHeader);
        if SalesQuoteLine.FindSet() then
            repeat
                IsHandled := false;
                OnBeforeTransferQuoteLineToOrderLineLoop(SalesQuoteLine, SalesQuoteHeader, SalesOrderHeader, IsHandled);
                if not IsHandled then begin
                    SalesOrderLine := SalesQuoteLine;
                    SalesOrderLine."Document Type" := SalesOrderHeader."Document Type";
                    SalesOrderLine."Document No." := SalesOrderHeader."No.";
                    SalesOrderLine."Shortcut Dimension 1 Code" := SalesQuoteLine."Shortcut Dimension 1 Code";
                    SalesOrderLine."Shortcut Dimension 2 Code" := SalesQuoteLine."Shortcut Dimension 2 Code";
                    SalesOrderLine."Dimension Set ID" := SalesQuoteLine."Dimension Set ID";
                    SalesOrderLine."Transaction Type" := SalesOrderHeader."Transaction Type";
                    OnTransferQuoteToOrderLinesOnBeforeUpdatePrepaymentPct(SalesQuoteLine, SalesQuoteHeader, SalesOrderLine, SalesOrderHeader, Customer);
                    if Customer."Prepayment %" <> 0 then
                        SalesOrderLine."Prepayment %" := Customer."Prepayment %";
                    PrepmtMgt.SetSalesPrepaymentPct(SalesOrderLine, SalesOrderHeader."Posting Date");
                    SalesOrderLine.Validate("Prepayment %");
                    IsHandled := false;
                    OnTransferQuoteToOrderLinesOnBeforeDefaultDeferralCode(SalesOrderLine, SalesOrderHeader, SalesQuoteLine, IsHandled);
                    if not IsHandled then
                        if SalesOrderLine."No." <> '' then
                            SalesOrderLine.DefaultDeferralCode();
                    OnBeforeInsertSalesOrderLine(SalesOrderLine, SalesOrderHeader, SalesQuoteLine, SalesQuoteHeader);
                    SalesOrderLine.Insert();
                    OnAfterInsertSalesOrderLine(SalesOrderLine, SalesOrderHeader, SalesQuoteLine, SalesQuoteHeader);
                    ATOLink.MakeAsmOrderLinkedToSalesOrderLine(SalesQuoteLine, SalesOrderLine);
                    OnTransferQuoteToOrderLinesOnAfterATOLinkMakeAsmOrderLinkedToSalesOrderLine(SalesQuoteLine, SalesOrderLine);
                    SalesLineReserve.TransferSaleLineToSalesLine(
                      SalesQuoteLine, SalesOrderLine, SalesQuoteLine."Outstanding Qty. (Base)");
                    SalesLineReserve.VerifyQuantity(SalesOrderLine, SalesQuoteLine);
                    if SalesOrderLine.Reserve = SalesOrderLine.Reserve::Always then
                        SalesOrderLine.AutoReserve();
                    OnAfterSalesOrderLineInsert(SalesOrderLine, SalesQuoteLine);
                end;
            until SalesQuoteLine.Next() = 0;
        OnAfterTransferQuoteToOrderLines(SalesQuoteLine, SalesQuoteHeader);
    end;

    [IntegrationEvent(false, false)]
    local procedure OnAfterSalesOrderLineInsert(var SalesOrderLine: Record "Sales Line"; SalesQuoteLine: Record "Sales Line")
    begin
    end;

Additional context
We need to be able to have direct relation of SalesOrderLine and SalesQuoteLine after insert via publisher to trigger other procedures in our extension.
Internal work item: AB#534608

Thanks for reporting this. We agree, and we’ll publish a fix asap, either in an update for the current version or in the next major release. Please do not reply to this, as we do not monitor closed issues. If you have follow-up questions or requests, please create a new issue where you reference this one.
Build ID: .

authors: JesperSchulz innonav-dev


text:
[Change Request] report 6697 "Create Ret.-Related Documents"

Describe the request
Could you please move the TempRetRelDoc variable to be set as protected?
var
    Vend: Record Vendor;
    CopyDocMgt: Codeunit "Copy Document Mgt.";

protected var
    TempRetRelDoc: Record "Returns-Related Document" temporary;
    POPurchHeader: Record "Purchase Header";
    PROPurchHeader: Record "Purchase Header";
    SOSalesHeader: Record "Sales Header";
    SROSalesHeader: Record "Sales Header";
    CreatePRO: Boolean;
    CreatePO: Boolean;
    CreateSO: Boolean;
    VendorNo: Code[20];

Additional context
We need this variable to be protected, because we want to create other types of documents and we need to insert other documents into that table.
Internal work item: AB#534677

Thanks for reporting this. We agree, and we’ll publish a fix asap, either in an update for the current version or in the next major release. Please do not reply to this, as we do not monitor closed issues. If you have follow-up questions or requests, please create a new issue where you reference this one.
Build ID: 19985.

authors: JesperSchulz gordanarakovac


text:
[Issue] COD221 Resource-Find Price, unable to set return value

Can this publisher please be update to allow the return type to be returned?
Current:
    LOCAL PROCEDURE FindResPrice@1() : Boolean;
    VAR
      IsHandled@1000 : Boolean;
    BEGIN
      IsHandled := FALSE;
      OnBeforeFindResPrice(ResPrice,IsHandled);
      IF IsHandled THEN
        EXIT;

Suggested:
    LOCAL PROCEDURE FindResPrice@1() ReturnBool : Boolean;
    VAR
      IsHandled@1000 : Boolean;
    BEGIN
      IsHandled := FALSE;
      OnBeforeFindResPrice(ResPrice,IsHandled,ReturnBool);
      IF IsHandled THEN
        EXIT(ReturnBool);

Thanks for reporting this. We agree, and we’ll publish a fix asap, either in an update for the current version or in the next major release. We will update this issue with information about availability.

Thanks for reporting this. We agree, and we’ll publish a fix asap, either in an update for the current version or in the next major release. We will update this issue with information about availability.

authors: Nameyka-DC bc-ghost


text:
[Event Request] codeunit 5988 "Serv-Documents Mgt." function: FinalizeDeleteLines

Could you please add a publisher in codeunit 5988 "Serv-Documents Mgt." function: FinalizeDeleteLines
    local procedure FinalizeDeleteLines()
    begin
        // delete Service Lines persistent and temporary
        PServLine.Reset;
        PServLine.SetRange("Document Type", ServHeader."Document Type");
        PServLine.SetRange("Document No.", ServHeader."No.");
        // New Event
        SetFilterOnFinalizeDeleteLinesBeforeDeletePServLine(PServLine);

        PServLine.DeleteAll;

        ServLine.Reset;
        ServLine.DeleteAll;
    end;

 [IntegrationEvent(false, false)]
 local procedure SetFilterOnFinalizeDeleteLinesBeforeDeletePServLine(var ServiceLine: record "Service Line");
 begin
 end;

Thanks for reporting this. We agree, and we’ll publish a fix asap, either in an update for the current version or in the next major release. We will update this issue with information about availability.

Hello,
I didn't get this event with the update to BC16/CU01, the other events in the same business call (set filter) were added... is it possible to get them with BC16 CU02?

authors: Schnieringer bc-ghost


text:
[Event Request] Codeunit 5923 Service-Quote to Order - InsertServHeader - OnBeforeInsertServHeader

Hi.
We would like to extend Codeunit Service-Quote to Order InsertServHeader procedure like this:

[IntegrationEvent(false, false)]
    local procedure OnBeforeInsertServHeader(var ServiceHeaderOrder: Record "Service Header"; ServiceHeaderQuote: Record "Service Header")
    begin
    end;

Thanks for reporting this. We agree, and we’ll publish a fix asap, either in an update for the current version or in the next major release. We will update this issue with information about availability.


text:
[Event Request] Report 491 "Delete Invd Blnkt Purch Orders" – New Event “OnAfterDeletePurchaseHeader”

Could we please have a new publisher “OnAfterDeletePurchaseHeader” in Function “OnAfterGetRecord”, Report 491 "Delete Invd Blnkt Purch Orders"?

            trigger OnAfterGetRecord()
            var
                ApprovalsMgmt: Codeunit "Approvals Mgmt.";
            begin
                Window.Update(1, "No.");

                PurchLine.Reset();
                PurchLine.SetRange("Document Type", "Document Type");
                PurchLine.SetRange("Document No.", "No.");
…
                                    ApprovalsMgmt.DeleteApprovalEntries(RecordId);

                                    OnBeforeDeletePurchaseHeader("Purchase Header");
                                    Delete;
*** start new code ***
                                    OnAfterDeletePurchaseHeader("Purchase Header");
*** stop new code ***

                                    Commit();
…
*** start new code ***
    [IntegrationEvent(false, false)]
    local procedure OnAfterDeletePurchaseHeader(var PurchaseHeader: Record "Purchase Header")
    begin
    end;
*** stop new code ***

Thanks for reporting this. We agree, and we’ll publish a fix asap, either in an update for the current version or in the next major release. We will update this issue with information about availability.

authors: bc-ghost ttaeufer


text:
[Event Request] Codeunit 31000 "Sales-Post Advances ".Letter

Please add these events.
    procedure Letter(var SalesHeader: Record "Sales Header"; var AdvanceLetterNo: Code[20]; AdvanceTemplCode: Code[10])
    var
        SalesAdvanceLetterHeader: Record "Sales Advance Letter Header";
        SalesAdvanceLetterLine: Record "Sales Advance Letter Line";
        SalesHeader2: Record "Sales Header";
        TempAdvanceLetterLineRelation: Record "Advance Letter Line Relation" temporary;
        SalesAdvPmtTemplate: Record "Sales Adv. Payment Template";
        CustPostGr: Record "Customer Posting Group";
        //---------------------------------------OnBeforeCheckOpenPrepaymentLines:BEGIN
        Handled: Boolean;
        //---------------------------------------OnBeforeCheckOpenPrepaymentLines:END
    begin
        SalesHeader.TestField("Prepayment Type", SalesHeader."Prepayment Type"::Advance);

        if AdvanceTemplCode <> '' then
            SalesAdvPmtTemplate.Get(AdvanceTemplCode);

        SalesHeader2 := SalesHeader;
        with SalesHeader2 do begin
            if not ("Document Type" in ["Document Type"::Order, "Document Type"::Invoice]) then
                FieldError("Document Type");
            TestField("Sell-to Customer No.");
            TestField("Bill-to Customer No.");
            //---------------------------------------OnBeforeCheckOpenPrepaymentLines:BEGIN
            OnBeforeCheckOpenPrepaymentLines(Handled);
            if not Handled then
            //---------------------------------------OnBeforeCheckOpenPrepaymentLines:END
                if not CheckOpenPrepaymentLines(SalesHeader) then
                    Error(Text001Err);

            Validate("Prepayment Type", "Prepayment Type"::Advance);
            // Get Doc. No. and save
            if "Advance Letter No." = '' then begin
                if AdvanceTemplCode = '' then begin
                    TestField("Advance Letter No. Series");
                    "Advance Letter No." :=
                      NoSeriesMgt.GetNextNo("Advance Letter No. Series", "Posting Date", true);
                end else begin
                    SalesAdvPmtTemplate.TestField("Advance Letter Nos.");
                    "Advance Letter No." :=
                      NoSeriesMgt.GetNextNo(SalesAdvPmtTemplate."Advance Letter Nos.", "Posting Date", true);
                end;
                Modify;
                if not SystemRun and not PreviewMode then
                    Commit();
            end;
            AdvanceLetterNo := "Advance Letter No.";

            SalesSetup.Get();

            // Create header
            //---------------------------------------OnBeforeCreateSalesAdvanceLetterHeader:BEGIN
            Handled := false;
            OnBeforeCreateSalesAdvanceLetterHeader(SalesHeader2, SalesAdvanceLetterHeader, Handled);
            if not Handled then begin
            //---------------------------------------OnBeforeCreateSalesAdvanceLetterHeader:END
                SalesAdvanceLetterHeader.Init();
                SalesAdvanceLetterHeader.TransferFields(SalesHeader2);
                SalesAdvanceLetterHeader."No." := "Advance Letter No.";
                SalesAdvanceLetterHeader."Order No." := "No.";
                SalesAdvanceLetterHeader."No. Printed" := 0;
                SalesAdvanceLetterHeader."Your Reference" := "Your Reference";
                SalesAdvanceLetterHeader."Language Code" := "Language Code";
                SalesAdvanceLetterHeader."Payment Terms Code" := "Prepmt. Payment Terms Code";
                SalesAdvanceLetterHeader."Payment Method Code" := "Payment Method Code";
                SalesAdvanceLetterHeader."Registration No." := "Registration No.";
                SalesAdvanceLetterHeader."Tax Registration No." := "Tax Registration No.";
                SalesAdvanceLetterHeader."VAT Country/Region Code" := "VAT Country/Region Code";

                SalesAdvanceLetterHeader."Template Code" := AdvanceTemplCode;
                if AdvanceTemplCode <> '' then begin
                    if SalesAdvPmtTemplate."Customer Posting Group" <> '' then
                        SalesAdvanceLetterHeader."Customer Posting Group" := SalesAdvPmtTemplate."Customer Posting Group";
                    SalesAdvanceLetterHeader."Post Advance VAT Option" := SalesAdvPmtTemplate."Post Advance VAT Option";
                end;

                SalesAdvanceLetterHeader."Amounts Including VAT" := "Prices Including VAT";
                SalesAdvanceLetterHeader.Insert();
            //---------------------------------------OnBeforeCreateSalesAdvanceLetterHeader:BEGIN
            end;
            //---------------------------------------OnBeforeCreateSalesAdvanceLetterHeader:END
            // Create Lines
            TempPrepmtInvLineBuf.DeleteAll();
            CreateAdvanceInvLineBuf(SalesHeader, TempPrepmtInvLineBuf, TempAdvanceLetterLineRelation);
            //------------------------------------------------------------OnBeforeCreateSalesAdvanceLetterLines:BEGIN
            OnBeforeCreateSalesAdvanceLetterLines(TempAdvanceLetterLineRelation);
            //------------------------------------------------------------OnBeforeCreateSalesAdvanceLetterLines:END
            TempPrepmtInvLineBuf.FindSet;
            repeat
                if TempPrepmtInvLineBuf."Line No." <> 0 then
                    LineNo := TempPrepmtInvLineBuf."Line No."
                else
                    LineNo := PrevLineNo + 10000;

                SalesAdvanceLetterLine.Init();
                SalesAdvanceLetterLine."Letter No." := "Advance Letter No.";
                SalesAdvanceLetterLine."Line No." := LineNo;
                SalesAdvanceLetterLine."Bill-to Customer No." := "Bill-to Customer No.";
                SalesAdvanceLetterLine."No." := TempPrepmtInvLineBuf."G/L Account No.";
                SalesAdvanceLetterLine."Shortcut Dimension 1 Code" := TempPrepmtInvLineBuf."Global Dimension 1 Code";
                SalesAdvanceLetterLine."Shortcut Dimension 2 Code" := TempPrepmtInvLineBuf."Global Dimension 2 Code";
                SalesAdvanceLetterLine."Dimension Set ID" := TempPrepmtInvLineBuf."Dimension Set ID";
                SalesAdvanceLetterLine.Description := TempPrepmtInvLineBuf.Description;
                SalesAdvanceLetterLine."Gen. Bus. Posting Group" := TempPrepmtInvLineBuf."Gen. Bus. Posting Group";
                SalesAdvanceLetterLine."Gen. Prod. Posting Group" := TempPrepmtInvLineBuf."Gen. Prod. Posting Group";
                SalesAdvanceLetterLine."VAT Bus. Posting Group" := TempPrepmtInvLineBuf."VAT Bus. Posting Group";
                SalesAdvanceLetterLine."VAT Prod. Posting Group" := TempPrepmtInvLineBuf."VAT Prod. Posting Group";
                SalesAdvanceLetterLine."VAT %" := TempPrepmtInvLineBuf."VAT %";
                SalesAdvanceLetterLine."Advance Due Date" := SalesAdvanceLetterHeader."Advance Due Date";
                SalesAdvanceLetterLine.Amount := TempPrepmtInvLineBuf.Amount;
                SalesAdvanceLetterLine."Amount Including VAT" := TempPrepmtInvLineBuf."Amount Incl. VAT";
                SalesAdvanceLetterLine."Amount To Link" := 0;
                SalesAdvanceLetterLine."VAT Calculation Type" := TempPrepmtInvLineBuf."VAT Calculation Type";
                SalesAdvanceLetterLine."VAT Amount" := TempPrepmtInvLineBuf."VAT Amount";
                SalesAdvanceLetterLine."VAT Identifier" := TempPrepmtInvLineBuf."VAT Identifier";
                SalesAdvanceLetterLine."Currency Code" := "Currency Code";
                CustPostGr.Get(SalesAdvanceLetterHeader."Customer Posting Group");
                CustPostGr.TestField("Advance Account");
                SalesAdvanceLetterLine."Advance G/L Account No." := CustPostGr."Advance Account";
                SalesAdvanceLetterLine."Job No." := TempPrepmtInvLineBuf."Job No.";
                //---------------------------------------OnBeforeInsertSalesAdvanceLetterLine:BEGIN
                OnBeforeInsertSalesAdvanceLetterLine(TempPrepmtInvLineBuf, SalesAdvanceLetterLine);
                //---------------------------------------OnBeforeInsertSalesAdvanceLetterLine:END
                SalesAdvanceLetterLine.Insert(true);

                InsertLineRelations(TempPrepmtInvLineBuf."Entry No.", SalesAdvanceLetterLine, TempAdvanceLetterLineRelation);

                PrevLineNo := LineNo;
            until TempPrepmtInvLineBuf.Next = 0;

            // Update header
            "Advance Letter No." := '';
            Modify;
        end;
        SalesHeader := SalesHeader2;
    end;

[IntegrationEvent(false, false)]
local procedure OnBeforeCheckOpenPrepaymentLines(var Handled: Boolean);
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCreateSalesAdvanceLetterHeader(var SalesHeader: Record "Sales Header", var SalesAdvanceLetterHeader: Record "Sales Advance Letter Header", var Handled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeCreateSalesAdvanceLetterLines(var TempAdvanceLetterLineRelation: Record "Advance Letter Line Relation" temporary)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInsertSalesAdvanceLetterLine(var TempPrepmtInvLineBuf: Record "Prepayment Inv. Line Buffer" temporary, var SalesAdvanceLetterLine: Record "Sales Advance Letter Line")
begin
end;

If I understand correctly then the meaning of the OnBeforeCreateSalesAdvanceLetterHeader event is creation of your own SalesAdvanceLetterHeader. So that couldn't the event be before SalesAdvanceLetterHeader.Insert(); (OnBeforeSalesAdvanceLetterHeaderInsert for example. Then you could modify record of SalesAdvanceLetterHeader as you want. Or is there any other purpose of the handle pattern event?

Yes we create own header. I see that you do not use validate so it can be done by your suggestion, but I am afraid that you will add some testfields or validate in future and it will not work.

Availability update: We will publish a fix for this issue in the next update for releasee 17.

Thanks for reporting this. We agree, and we’ll publish a fix asap, either in an update for the current version or in the next major release. We will update this issue with information about availability. Please do not reply to this, as we do not monitor closed issues. If you have follow-up questions or requests, please create a new issue where you reference this one.

authors: DavidHolusa JesperSchulz fridrichovsky


text:
ALM Toolkit not applying changes

Hi, I've been using ALM toolkit for a while now and never had this issue before, it just started yesterday. I made changes to the SQL definition of one of my tables, then I commit the changes. The new fields do show up in the table when connected using Tabular Editor but when I refresh it, it fails because the query was not updated. I upgraded ALM to the latest version but this keeps happening. I'm manually modifying the definition with Tabular Editor and then it works fine. ALM toolkit keeps finding a difference when comparing.

Hi @oscarmqz , can you check the options in the options dialog like retain partitions? SQL queries will be covered by partition definitions.

I do use that option all the time, see attached image. That's how I keep it. I have incremental refresh set up.

I see. Can you also select "Consider partitions when comparing tables"? That should show source SQL query differences and flag those tables for updates.

It does flag it for update but is not updating, I've tried checking that option with same result.

I see. Can you share a screenshot of the differences?

Here you go, I'm trying to add a dummy test column as an example

I would expect that to get updated on when doing an Update on the table. Any chance you can send me files (such as bim files, or PBIP project files, etc.) so that I can repro on my end and run it in debug mode to see what's going on?

Resolved by e-mail

authors: christianwade oscarmqz

repo: microsoft/Analysis-Services


text:
Webpack HTML dependency files

Suggestion provided by @gfs
Description: how to consolidate various js and cs files needed for HTML format report to package them into a reduced set of references and avoid real-time internet reference and download time
My recommendation is as follows. This eliminates all dependency on external files being present on the disc, everything will be in the binary.

Use webpack either pre-build or as part of the pre-build build tasks to compile all your js and css assets. It sounds like your html is also one file too, which is great.
Embed those into your binary. Set the build task to EmbeddedResource in visual studio.
Have a simple test to ensure that the embeds are there.
At runtime access the embedded files like you do for your rules.
Do whatever processing you need to.
Write the embedded files to disc where the user has selected.

Looks good guy. Let me know if you need any help.

Thanks for digging into this one. I hope this resolves the issue I'm running into. I'm running v1.2.58 and the HTML output is non-functional and the output looks like #264. I tried from macOS and from Ubuntu and couldn't get either to produce usable output from the CLI.
I noticed a few resources are no longer referenced in my output.html when compared to an old report sample I saw online. I'm not sure this information is helpful or related but the first item looks highly important. The other JavaScript resources (query, ace, d3, c3, popper) are now sourced from cdnjs.cloudflare.com but I no longer see these:

appinspector.js
ext-settings_menu.js
ext-modelist.js
ext-beautify.js

I will verify this and get back to you tonight.  Shouldn't see it in the 1.2.58 version. There are fewer resources reference because they are embedded in the HTML

I can't reproduce this using the dotnet tool version.
You can install that version (if you have the .NET SDK installed) with dotnet tool install -g Microsoft.CST.ApplicationInspector.CLI
PS D:\GitHub> appinspector analyze -s .\LogicalAnalyzer\
The output file does not have an html or htm extension and may not open properly in your browser
Analyze command running
100% source files processed
The output.html file size is large and may render slowly.  Consider running using alternate output format options as needed.
Opening default browser to output.html report
Analyze command completed
Additional details may be found in log file at C:\Users\Gstoc\.dotnet\tools\.store\microsoft.cst.applicationinspector.cli\1.2.58\microsoft.cst.applicationinspector.cli\1.2.58\tools\netcoreapp3.1\any\appinspector.log.txt

Thanks for looking into this. I still have the error and will provide more details in a separate issue (See #279) to not detract from this issue.

Closing in favor of rewriting UI in Blazor.

authors: gfs ggjacosta guyacosta rback123

repo: microsoft/ApplicationInspector


text:
Unable to install the Teraform template

Unable to install the Teraform template with AzureDevOpsDemoGenerator

@marcelin-ndjila, please follow the note provided before provisioning the project. You can also install the extension manually and create a new project.
Thanks

authors: aksh-h marcelin-ndjila

repo: microsoft/AzureDevOpsDemoGenerator


text:
There is an error message on the 'Break Lease' dialog for blobs/folders

Storage Explorer Version: 1.29.0-dev
Build Number: 20230217.4
Branch: main
Platform/OS: Windows 10/Linux Ubuntu 22.04/MacOS Ventura 13.2.1 (Apple M1 Pro)
Architecture: ia32/x64
How Found: From running test cases
Regression From: Previous release (1.27.2)
Steps to Reproduce

Expand one storage account -> Blob Containers.
Create a blob container -> Upload one blob.
Acquire lease for the blob.
Right click the leased blob -> Click 'Break Lease...'.
Check there is no error message on the 'Break Lease' dialog.

Expected Experience
There is no error message on the 'Break Lease' dialog.

Actual Experience
There is an error message on the 'Break Lease' dialog.

Additional Context
Refer to the bug: 6209

Hi @v-xianya, I believe we have recently been trying to avoid showing a user an error message when they haven't entered any input in situations like this. @craxal please confirm if this was the case for this dialog.

@MRayermannMSFT Hiding the initial error is opt-in behavior. You have to add the hideInitialValidationError property to the config.

Hi @craxal Verified this issue on the build main 20230324.1.

This issue has been fixed for regular blobs.
This issue reproduces for ADLS Gen2 blobs.

@v-xianya A fix has been merged, but we are still verifying, because we have to update packages. We will close the bug once work is finished, and then you can verify as well.

I am not able to reproduce with ADLS Gen2 using the current state of the main branch, so you probably got a build that didn't get the necessary changes. Try verifying with a newer build.

Verified this issue on the main 20230327.1. Fixed for ADLS Gen2 blobs.

authors: MRayermannMSFT craxal v-xianya

repo: microsoft/AzureStorageExplorer


text:
Fix number-bug in the workflows

What is being addressed
In https://github.com/microsoft/AzureTRE/pull/3114 I introduced a number to the workflows which should have been a string, hence created a bug.
This fixes it.

/test-force-approve

source: gharchive/pull-request

repo: microsoft/AzureTRE


text:
formatDateTime not allowed with extra locale settings

In the adaptive expressions documentation it shows that formatDateTime can accept an additional locale parameter:

The validation in Composer however does not allow that:

@cosmicshuai @lei9444 can either of you comment?

authors: cwhitten cxbuilders

repo: microsoft/BotFramework-Composer


text:
Question About Dialogs.Debugging.SourceMap: SourceMap is taking too much memory when chatbot loading

I'm using Composer Runtime in one of the bots I working on, the bot have multiple service and we have multiple dialogs (50 dialogs) to handle these services. when bot it loading it consuming too much memory, after investigation I found that SourceMap is consuming most of the memory and below simple explanation to what I did:
I tried to load the Bot without doing any change on SourceMap and here is the memory usage screenshot (3 GB):

then I tried to Load the Bot without using SourceMap by commenting the Add method as shown below (using latest Packages 4.12.2):

and the memory after loading the bot (660 MB)

Can you please advise,

Can you please explain the purpose of SourceMap ?
Can I keep this line commented and how could this affect my Bot ? are there any better way to not use SourceMap if it does not affect the Bot ?

Please note that we face the same memory consumption issue when we deploy it to azure.


text:
Notifications get hidden when rocket panel is open

Electron App: v1.4.0-nightly.234518.839bb23
Mac OS
Steps to reproduce

create new bot
create new publishing profile > create new resources > complete

The notifications are getting hidden under the rocket panel ( see attached)
Expected behavior is that once user is done with the modal, the rocket panel should close and user should be able to see notifications of their publishing profile being created.

this has been fixed

authors: JaskeeratBedi-cmk benbrown


text:
Button Text / User Input Choices in Prompt Translation/Localization not possible

Hello there,
Currently the responses/texts are being stored in the bots lg files, which is fine and works great with translation.
Unfortunately, the texts which the buttons contain are stored in the dialog files.
For translation, the LG Files are being duplicated and named accordingly (e.g. de-de, en-us).
BUT for the dialog files that is not possible.
There is only one dialog file.
My question: is there a way to either have the button/input choices text in the lg files and then referring to the dialog file with e.g. a template, or is there another scalable and practical way to translate the button texts?
Greetings and thanks in advance.

@saskialorraine - Taking a look at this to see if there are any workable solutions. I'll reach out to you when I know more.

You can create template functions in each locale lg file like this :
In en-us.lg file :
# SendActivity_ChooseNoIntent()
- Sure, no worries.

In ko-kr.lg file :
# SendActivity_ChooseNoIntent()
- 네, 알겠습니다.

Then create a response with text that refers to the template you created :

[Activity
    Text = ${SendActivity_ChooseNoIntent()}
]

The same goes for attachments. Instead of text in the template function you would instead write json for an adaptive card like this (in your case your card would have a button rather than what I have below) :

# SendActivity_ChooseIntentPrompt_attachment_card(candidates)
-```
{
      "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
      "version": "1.0",
      "type": "AdaptiveCard",
      "speak": "",
      "body": [
          {
              "type": "TextBlock",
              "text": "${SendActivity_ChooseIntentPrompt_attachment_whichOneDidYouMean()}",
              "weight": "Bolder"
          },
          {
              "type": "TextBlock",
              "text": "${SendActivity_ChooseIntentPrompt_attachment_pickOne()}",
              "separator": "true"
          },
          {
              "type": "Input.ChoiceSet",
              "placeholder": "Placeholder text",
              "id": "userChosenIntent",
              "choices": [
                           ${SendActivity_ChooseIntentPrompt_attachment_generateChoices()},
                           {
                               "title": "None of the above",
                               "value": "none"
                           }
             ],
             "style": "expanded",
             "value": "luis"
         },
         {
             "type": "ActionSet",
             "actions": [
                {
                     "type": "Action.Submit",
                     "title": "Submit",
                     "data": {
                   "intent": "chooseIntentCardResponse"
                }
         }
       ]
     }
    ]
}
```<-- Note the json is surrounded by ```

@stevkan Thanks, that would be great!
@johnkm516 Thanks for your answer!
Did I understand that correctly though, that your solution would be to not use the prompts from BFC itself but exchange all of my questions with Adaptive Cards and read out those inputs?
That might be a solution indeed... but absolutely not a handy nor scalable one.

@saskialorraine
I am not sure what you mean by not scalable.
Templating using LG files allows you to customize the card (and therefore whatever prompts you want) in any way you'd like, and comes with pre-built functions that allows you to add loops and conditional statements. This means you can create your own version of a prompt that dynamically populates buttons with your own custom text. You could pass in an array of objects that look something like :
{
	"text" : "Click Me",
	"value" : "Value that will pass when clicked",
	"intent" : "Intent to pass when clicked"
},
...

then in your LG template, use a foreach loop and join the templates together with a comma delimiter.
For example :
# CalendarScheduleCard(data)
- ```
{
    "type": "AdaptiveCard",
    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
    "version": "1.3",
    "body": [
        {
            "type": "Container",
            "spacing": "None",
            "separator": true,
            "items": [
                ${join(foreach(data.dayRows, DateRow, DayRow(DateRow, data.currentMonth)), ',')}
            ]
        }
    ]
}
```

# DayRow(DateRow, currentMonth)
- ```
{
    "type": "ColumnSet",
    "columns": [
        ${join(foreach(DateRow.entries, day, DayCell(day, currentMonth)), ',')}
    ],
    "style": "default",
    "spacing": "None"
}
```

In your case you would create a template that has JSON for a button, and use the foreach loop and join to dynamically populate the buttons depending on how many buttons you want.
Templating is far more flexible and scalable than the base prompts on BFC. You would create a template such as the example above once, and then pass in data that dynamically populates your card. This includes all the capabilities of adaptive cards, such as video media, images, etc. You can see all the pre-built functions that you can call in LG templates here :
https://docs.microsoft.com/en-us/azure/bot-service/adaptive-expressions/adaptive-expressions-prebuilt-functions?view=azure-bot-service-4.0

hello @johnkm516 thanks a lot for your detailed answers! It is very much appreciated!
I do see the advantages of the templating and adaptive cards, but the main issue is that we've already built a huge Bot Project with the BFC prompts and it would just mean a lot of work to replace those..
And in my opinion it is just a huge flaw if not a sort of bug that the buttons can just not easily be placed in the lg files for an easy translation or a different solution for Button translation

@saskialorraine
I looked over the source code for botbuilder-dotnet. You can look over Microsoft.Bot.Builder.Dialogs.Adaptive.Input.ChoiceInput.cs and other relevant files for reference.
I think the BFC prompts are the way they are currently because it was created before multi-locale support was even a thing.
This has put the developers in a precarious position because the design for locale support was meant to be done via the addition of LG files for each different locale, yet legacy actions such as prompts hardcode text in dialog files. For a better understanding of how the locale support works, I suggest you look over Microsoft.Bot.Builder.Dialogs.Adaptive.Actions.SendActivity.cs, which now serves as the base for basically every bot generated response for multi-lingual bots as multi-lingual bots reference LG files for templating different responses per locale.
Here's the thing : even if BFC prompts are modified for multi-lingual support, it's going to reference LG files. That's the design direction of multi-lingual support. That means all the BFC prompts that's currently hardcoded in dialog files that you have currently has to be migrated over to LG files anyways. It's also difficult for MS to update BFC prompts because like you, many older chatbots use it and updating BFC prompts might break older chatbots. It's kind of a rock and a hard place type of situation IMO. MS might update BFC prompts and simultaneously change Composer or release a script to parse the dialog files and automatically update BFC prompts into the new updated prompt and migrate the prompts to LG files, but I'm not sure if this kind would be a priority or be released in due time. It would be faster if you coded your own parser to do the migration for you. Since dialog files are in JSON form it shouldn't be too difficult to code a program that finds and replaces ChoiceInput activities with SendActivity and append the appropriate LG files with the input in the dialog file.

Hello together.
@johnkm516 Again: Thanks for your answer, very interesting and insightful.
We kinda figured it out/found a solution that we will probably use.
So we are now indeed using the templates placing them in the LG Files and implementing the template tags in the button field. Like so:
DE:

EN:

Code/LG Files:

BUT still it would just be very much appreciated and frankly easier and less time consuming if the Button texts would automatically appear as templates in the LG files instead of appearing in the dialog file.

@johnkm516 - Thank you for your insight and help on this issue. Your thoughts are on point and much appreciated!
@saskialorraine - I'm glad you were able to find a workable solution. I marked this as a feature request for future consideration. Of course, there is no ETA at this point on when this might be addressed.

@saskialorraine How did you get it to work? No matter how I write template variables into the choices array, they get printed as strings...

@alitilitex Could you provide a few screenshots? :) I worked with Composer quite a long time ago, so I would need some more information.
My first guess would be that you maybe didn't use a "=" before writing the variables in the choices. But if you create the template names according to my screenshot it should work.

authors: alitilitex johnkm516 saskialorraine stevkan


text:
fix: add useMemo to improve performance

Description
updating name will render the component as well as the child component LocationSelectContent. It is expensive to rerender the component if we have many bot folders.
Task Item
Closes #4633
Screenshots

Coverage increased (+0.004%) to 55.76% when pulling e4cd98649e138493f5ffd6e165ddc891add0824d on liweitian:nameInputPerf into de5adb1f79eae671df194803355a92e6879a98de on microsoft:main.

authors: coveralls liweitian


text:
fix: Restrict template feed to those published by Microsoft

This adds the scope: microsoft parameter to the feed that is used as the source of templates in the new creation flow.

Coverage remained the same at 53.892% when pulling f06f50fba15f1d0663f7e79819745574553987a2 on benbrown/firstpartyfeed into 666828c80172bc7b2ae205ffbaff2fc1310dea37 on main.

authors: benbrown coveralls


text:
[MAS3.3.2] [Screen Reader-Open bot dialog] Narrator is not reading the place holder values for “Microsoft app id and Microsoft App Password “

Actual Result:
Narrator is not reading the place holder values for “Microsoft app id and Microsoft App Password “present in the open bot dialog.
Expected Result:
Narrator should read the place holder values for “Microsoft app id and Microsoft App Password “
Narrator should read as Microsoft app\Microsoft password protected edit optional text field.
Note: Same issue exits throughout application  for all Microsoft app ID and Microsoft password text fields.
Same issue repro for below path
Welcome Bot Framework Emulator ->Create new bot configuration
1.Microsoft App ID 2.Microsoft Password
Note1: Issue is not repro’ing with NVDA
Repro Steps:
Turn on the narrator

Open the Bot Framework V4 Emulator.
Welcome tab screen gets opened
3.Navigate to the open bot control and select it
4.Open bot dialog gest opened
5.Navigate to the “Microsoft app id and Microsoft App Password “text fields
Observe the issue.

User Impact:
Users who rely on screen reader will be affected if the place holder values are not narrating the screen reader.
Test Environment:
OS Build: Version 1903(OS Build 18362.239)
Browser: Edge
Application: Bot Framework V4 Emulator
Screen reader: Narrator
MAS Reference Link:
https://microsoft.sharepoint.com/:w:/r/teams/msenable/_layouts/15/WopiFrame.aspx?sourcedoc={4b95a70d-258c-474a-820e-5c8b79d5c0bf}

MAS3.3.2_Open bot dialog.zip

As per dev comments we are closing this bug .

repo: microsoft/BotFramework-Emulator


text:
HeroCard render in IE 11 have a lot of space at bottom

There is a bug in IE11 that an oversized image will be taking up unnecessary space.
Can you make sure the image is properly scaled?

this is the sample from https://microsoft.github.io/BotFramework-WebChat/01.getting-started/c.es5-bundle/
when only show image, no space at bottom

only show image

but when show the hero card with image, the space is showing up

show hero card and image

i think the image is scaled properly, the problem may be something else?
thanks for reply 👍

@compulim do we need to investigate further?

@den19980107, are you still running into this problem? This is a duplicate of the issue https://github.com/microsoft/BotFramework-WebChat/issues/1944
This is not a Web Chat issue, but an Adaptive Cards one. The temporary fix on the bot's side is to adjust the height of your image to one that fits inside the adaptive card.
The Adaptive Cards bug I filed is here:
https://github.com/microsoft/AdaptiveCards/issues/3056
I recommend leaving a comment saying that you are also running into this on your bot. :)

The fix for Web Chat samples is to fix the size of the image of the herocard on Mock Bot, but priority would be P2 or P3.

@corinagum yes, i’m stiil  running in this issue,i knew that fix the size of the image will fix this issue ,
but in my case ,my web chat width is dynamic, so fix the image size is not the best way to fix this issue.
thank for reply 👍

authors: a-b-r-o-w-n compulim corinagum den19980107

repo: microsoft/BotFramework-WebChat


text:
Create util linux libs package

Extract libs from util-linux-devel into the util-linux-libs package.
Merge Checklist

All boxes should be checked before merging the PR (just tick any boxes which don't apply to this PR)

[x] The toolchain has been rebuilt successfully (or no changes were made to it)
[x] The toolchain/worker package manifests are up-to-date
[x] Any updated packages successfully build (or no packages were changed)
[x] Package tests (%check section) have been verified with RUN_CHECK=y for existing SPEC files, or added to new SPEC files
[x] All package sources are available
[x] cgmanifest files are up-to-date and sorted (./cgmanifest.json, ./toolkit/tools/cgmanifest.json, ./toolkit/scripts/toolchain/cgmanifest.json, .github/workflows/cgmanifest.json)
[x] Ready to merge

Summary

What does the PR accomplish, why was it needed?
Other packages that need to access libs packaged by util-linux should not have to take a dependency on util-linux-devel at runtime. Instead, they can take a dependency on util-linux-libs.
Change Log

Split the libraries from the util-linux-devel package into util-linux-libs package
Change dependent package that have a Requires clause on util-linux-devel to util-linux-libs.

util-linux-devel
systemd
Links to CVEs

https://nvd.nist.gov/vuln/detail/CVE-YYYY-XXXX

Test Methodology

Built and checked packages.

Need this pull request to go against 2.0

repo: microsoft/CBL-Mariner


text:
Updating for current TensorFlow version

Using current instructions the version of TensorFlow generates a couple errors. This changes the lines to work with the current version installed via pip (Tensorflow 2.7.0)

Thanks for this contribution, and sorry for the confusion around TensorFlow versions right now.  The following things are true at the moment:

Most of the environments in which we run MegaDetector still use TF 1.1x (especially the Docker environment we use for large-scale batch processing)
TF 1.1x is increasingly hard to actually install
A new version of MegaDetector is coming soon that will make this issue somewhat obsolete

Consequently, rather than updating all of our tooling/environments (and users' tooling/environments) and making the main branch of the repo TF 2.x-compatible, we're keeping the main branch TF 1.1x-compatible, but we've made basically the same changes you propose here on a branch:
https://github.com/microsoft/CameraTraps/tree/tf1-compat
...and our "getting started" instructions currently recommend checking out that branch.
So I'm going to close this PR without merging, not because these changes don't work or because they're not a good idea (they are!), rather because we're going to stay the course with TF 1.1x on the main branch for just a bit longer.
Sorry for the confusion!  Hopefully this will be moot soon.  If for whatever reason the next version of the model gets delayed, we'll probably "flip this switch" in a few weeks and update everything to TF 2.x as you suggest.
Thanks!
-Dan

Totally makes sense, I missed that! The getting started does still reference the master branch though through the wget:
wget https://raw.githubusercontent.com/microsoft/CameraTraps/master/detection/run_tf_detector.py
Just updating that might help with the confusion. No worries if you'd like to close that other PR as well and handle clarifying in a different way :) Cheers!

Good catch on that, thanks!  I approved the newer PR.

authors: agentmorris brianhogg

repo: microsoft/CameraTraps


text:
fix: rename history to activities

Related to https://github.com/microsoft/ConversationLearner-UI/pull/1297

:tada: This PR is included in version 0.209.1 :tada:
The release is available on:

npm package (@next dist-tag)
GitHub release

Your semantic-release bot :package::rocket:

repo: microsoft/ConversationLearner-Models


text:
fix: remove no actions return

I had messaged this on ADO but just creating PR for visibility.
What did you mean by

TODO: Handle reload when actions not yet loaded

It seemed to work fine without this, and it prevents the bug. Does  this protect against another issue?
Also, need to consider same code in LogDialogs page

Gotcha.  I’d say just test the browser reload and see if it causes issues.  (It’s an edge case)

:tada: This PR is included in version 0.382.8 :tada:
The release is available on:

npm package (@next dist-tag)
GitHub release

Your semantic-release bot :package::rocket:

authors: LarsLiden mattmazzola

repo: microsoft/ConversationLearner-UI


text:
Compared to mindspore (the complete automatic parallel/distributed training from the low level operators graph)?

Has anyone used mindspore (https://github.com/mindspore-ai/mindspore), it seems like mindspore has parallel/distributed training implemented deep in its own deeplearning framework C++ core:

So Mindspore should have very high performance and much less train code to change,  and it has most distributed training methods(Maybe no ZeRO CPU/NVMe offload) like DeepSpeed.
By the way, mindspore has successful used to train a 200B model: https://www.reddit.com/r/MachineLearning/comments/myr072/d_huawei_just_announced_that_they_trained_a_200/?sort=new
Can DeepSpeed learn something from Mindspore?

Thanks @ghosthamlet for the pointer, we are aware of the work and have been looking into it further. As with many systems in this space I am sure there are interesting things to be learned from it! :) Will close for now but if you or others have interesting learnings feel free to re-open.

authors: ghosthamlet jeffra

repo: microsoft/DeepSpeed


text:
More tutorials topics

Add textures to simple rendering

Multistream and instancing simple rendering

Using the geometry shader (per-face normals, normal visualization)

Using hardware tessellation (simple terrain rendering)

SpriteBatch with 3D lighting, reflection, refraction using normal maps

SpriteBatch with color-keying shader (emulate old-school colorkey textures)

Simple shadows (drop, projected)

Multi-pass rendering

Basics of deferred rendering

Fullscreen exclusive swapchains

Multimonitor rendering

Split-screen rendering

Direct2D/DirectWrite interop for DX11 / DX12

Yes please, I would be very interested in seeing these.

@isral. I've added the requested tutorial

Here's a good link for any deferred rendering article
https://www.3dgep.com/forward-plus/

Notes for multi-stream & instancing:

Multi-stream vertex buffer
SV_Instance ID + ConstantBuffer/Texture

https://software.intel.com/content/www/us/en/develop/articles/rendering-grass-with-instancing-in-directx-10.html
Skinned Instancing, https://developer.download.nvidia.com/SDK/10/direct3d/samples.html
DX11 FX: https://github.com/walbourn/directx-sdk-samples/tree/master/InstancingFX11
DX12:  https://github.com/Microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12DynamicIndexing

FSE is covered in this blog series: https://walbourn.github.io/care-and-feeding-of-modern-swapchains/

I'm very interested in a deferred rendering/lighting implementation with DirectXTK 12.
A basic tutorial would be fantastic... especially if the fundamentals of setting up and rendering to a G-buffer (depth, normals, etc) can be extended to a solution containing HDR/MSAA (FP16 render targets resolving to a 10:10:10:2 backbuffer)  plus postprocessing effects.
I would be happy to write and apply my own deferred lighting shaders adopted from previous work (e.g. Practical Rendering & Computation with D3D11, by Zink et al).

authors: MaicoDeBlasio davel101 walbourn

repo: microsoft/DirectXTK


text:
Inconsistent shared string after pausing connection

Describe the bug
With two users, conflicting edits while one user paused results in users having different shared string contents
To Reproduce
Steps to reproduce the behavior:

Start with empty shared string
User A: insert "abcd" @0
User B: deltaManager.inbound.pause()
User B: deltaManager.outbound.pause()
User B: deltaManager.inboundSignal.pause()
User B: insert "X" @2 (state: "abXcd")
User A: remove @1-2 (state: "ad")
User A: insert "yz" @1 (state: "axyd")
User B: deltaManager.inbound.resume()
User B: deltaManager.outbound.resume()
User B: deltaManager.inboundSignal.resume()

User A state: "ayzXd"
User B state: "aXyzd"
Expected behavior
User A and User B have the same state.

de locos tío confundiste el mail brother
[image: Mailtrack]
https://mailtrack.io?utm_source=gmail&utm_medium=signature&utm_campaign=signaturevirality11&
Remitente
notificado con
Mailtrack
https://mailtrack.io?utm_source=gmail&utm_medium=signature&utm_campaign=signaturevirality11&
01/04/22,
01:06:22
El jue, 31 mar 2022 a las 23:39, Ransom Richardson (<
@.***>) escribió:

Describe the bug
With two users, conflicting edits while one user paused results in users
having different shared string contents
To Reproduce
Steps to reproduce the behavior:

Start with empty shared string
User A: insert "abcd" @0 https://github.com/0
User B: deltaManager.inbound.pause()
User B: deltaManager.outbound.pause()
User B: deltaManager.inboundSignal.pause()
User B: insert "X" @2 https://github.com/2 (state: "abXcd")
User A: remove @1-2 https://github.com/1-2 (state: "ad")
User A: insert "yz" @1 https://github.com/1 (state: "axyd")
User B: deltaManager.inbound.resume()
User B: deltaManager.outbound.resume()
User B: deltaManager.inboundSignal.resume()

User A state: "ayzXd"
User B state: "aXyzd"
Expected behavior
User A and User B have the same state.
—
Reply to this email directly, view it on GitHub
https://github.com/microsoft/FluidFramework/issues/9703, or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABO4LUP3A6NFH4SD5AU7IEDVCYLRZANCNFSM5SGYTOGQ
.
You are receiving this because you were mentioned.Message ID:
@.***>

repo: microsoft/FluidFramework