Skip to content

[Event Request] Codeunit 1535 "Approvals Mgmt." - Possibility to skip check of approvals tables #29307

@krpr-navax

Description

@krpr-navax

Why do you need this change?

We would like to request new integration events in the Approvals Mgmt., which checks if approvals exist. As this check is executed for every line being posted, the overhead for bulk operations is incredibly high, even though the functionality is not in use by any of our customers. We also have our own approval system, which is checked efficiently before bulk posting operations. To improve performance during our bulk posting operations, the events will be subscribed using manual subscription to skip these costly executions for each line.

Describe the request

The code changes are marked within the #if NEWEVENTS ... #endif areas.

Object: codeunit 1535 "Approvals Mgmt."
Procedure: HasOpenOrPendingApprovalEntriesForCurrentUser

Code:

#if NEWEVENTS
    [IntegrationEvent(false, false)]
    local procedure OnBeforeHasOpenOrPendingApprovalEntriesForCurrentUser(RecordID: RecordID; var HasOpenOrPendingApproval: Boolean; var IsHandled: Boolean)
    begin
    end;

    procedure HasOpenOrPendingApprovalEntriesForCurrentUser(RecordID: RecordID) HasOpenOrPendingApproval: Boolean
    var
        ApprovalEntry: Record "Approval Entry";
        IsHandled: Boolean;
    begin
        OnBeforeHasOpenOrPendingApprovalEntriesForCurrentUser(RecordID, HasOpenOrPendingApproval, IsHandled);
        if IsHandled then
            exit;
#else
    procedure HasOpenOrPendingApprovalEntriesForCurrentUser(RecordID: RecordID): Boolean
    var
        ApprovalEntry: Record "Approval Entry";
    begin
#endif

        ApprovalEntry.SetRange("Table ID", RecordID.TableNo);
        ApprovalEntry.SetRange("Record ID to Approve", RecordID);
        ApprovalEntry.SetFilter(Status, '%1|%2', ApprovalEntry.Status::Open, ApprovalEntry.Status::Created);
        ApprovalEntry.SetRange("Approver ID", UserId);
        // Initial check before performing an expensive query due to the "Related to Change" flow field.
        if ApprovalEntry.IsEmpty() then
            exit(false);
        ApprovalEntry.SetRange("Related to Change", false);
        exit(not ApprovalEntry.IsEmpty);
    end;

Object: codeunit 1535 "Approvals Mgmt."
Procedure: PreventInsertRecIfOpenApprovalEntryExist

Code:

#if NEWEVENTS
    [IntegrationEvent(false, false)]
    local procedure OnBeforePreventInsertRecIfOpenApprovalEntryExist(var Variant: Variant; var IsHandled: Boolean)
    begin
    end;
#endif

    procedure PreventInsertRecIfOpenApprovalEntryExist(Variant: Variant)
    var
        GenJournalBatch: Record "Gen. Journal Batch";
        WorkflowWebhookMgt: Codeunit "Workflow Webhook Management";
        ConfirmManagement: Codeunit "Confirm Management";
        RecRef: RecordRef;
#if NEWEVENTS
        IsHandled: Boolean;
#endif
    begin
#if NEWEVENTS
        OnBeforePreventInsertRecIfOpenApprovalEntryExist(Variant, IsHandled);
        if IsHandled then
            exit;
#endif

        RecRef.GetTable(Variant);
        case RecRef.Number of
            Database::"Gen. Journal Batch":
                begin
                    if HasOpenOrPendingApprovalEntriesForCurrentUser(RecRef.RecordId) and CanCancelApprovalForRecord(RecRef.RecordId) then
                        Error(PreventInsertRecordWithOpenApprovalEntryForCurrUserMsg);

                    if (HasOpenApprovalEntries(RecRef.RecordId) and CanCancelApprovalForRecord(RecRef.RecordId))
                      or WorkflowWebhookMgt.HasPendingWorkflowWebhookEntryByRecordId(RecRef.RecordId) then
                        if ConfirmManagement.GetResponseOrDefault(PreventInsertRecordWithOpenApprovalEntryMsg, true) then begin
                            RecRef.SetTable(GenJournalBatch);
                            OnCancelGeneralJournalBatchApprovalRequest(GenJournalBatch);
                        end else
                            Error('');
                end;
        end;
    end;

Object: codeunit 1535 "Approvals Mgmt."
Procedure: PreventModifyRecIfOpenApprovalEntryExistForCurrentUser

Code:

#if NEWEVENTS
    [IntegrationEvent(false, false)]
    local procedure OnBeforePreventModifyRecIfOpenApprovalEntryExistForCurrentUser(var Variant: Variant; var IsHandled: Boolean)
    begin
    end;
#endif

    procedure PreventModifyRecIfOpenApprovalEntryExistForCurrentUser(Variant: Variant)
    var
        WorkflowWebhookMgt: Codeunit "Workflow Webhook Management";
        RecRef: RecordRef;
#if NEWEVENTS
        IsHandled: Boolean;
#endif
        ErrInfo: ErrorInfo;
        RejectApprovalRequestLbl: Label 'Reject approval';
        ShowCommentsLbl: Label 'Show comments';
        RejectApprovalRequestToolTipLbl: Label 'Reject approval request';
        ShowCommentsToolTipLbl: Label 'Show approval comments';
    begin
#if NEWEVENTS
        OnBeforePreventModifyRecIfOpenApprovalEntryExistForCurrentUser(Variant, IsHandled);
        if IsHandled then
            exit;
#endif

        RecRef.GetTable(Variant);
        if HasOpenOrPendingApprovalEntriesForCurrentUser(RecRef.RecordId) or WorkflowWebhookMgt.HasPendingWorkflowWebhookEntryByRecordId(RecRef.RecordId) then begin
            ErrInfo.ErrorType(ErrorType::Client);
            ErrInfo.Verbosity(Verbosity::Error);
            ErrInfo.Message(PreventModifyRecordWithOpenApprovalEntryMsg);
            ErrInfo.TableId(RecRef.Number);
            ErrInfo.RecordId(RecRef.RecordId);
            ErrInfo.AddAction(RejectApprovalRequestLbl, Codeunit::"Approvals Mgmt.", 'RejectApprovalRequest', RejectApprovalRequestToolTipLbl);
            ErrInfo.AddAction(ShowCommentsLbl, Codeunit::"Approvals Mgmt.", 'ShowApprovalCommentLinesForJournal', ShowCommentsToolTipLbl);
            Error(ErrInfo);
        end;
    end;

Object: codeunit 1535 "Approvals Mgmt."
Procedure: PreventDeletingRecordWithOpenApprovalEntry

Code:

#if NEWEVENTS
    [IntegrationEvent(false, false)]
    local procedure OnBeforePreventDeletingRecordWithOpenApprovalEntry(var Variant: Variant; var IsHandled: Boolean)
    begin
    end;
#endif

    procedure PreventDeletingRecordWithOpenApprovalEntry(Variant: Variant)
    var
        GenJournalBatch: Record "Gen. Journal Batch";
        ConfirmManagement: Codeunit "Confirm Management";
        WorkflowWebhookMgt: Codeunit "Workflow Webhook Management";
        RecRef: RecordRef;
#if NEWEVENTS
        IsHandled: Boolean;
#endif
    begin
#if NEWEVENTS
        OnBeforePreventDeletingRecordWithOpenApprovalEntry(Variant, IsHandled);
        if IsHandled then
            exit;
#endif

        RecRef.GetTable(Variant);
        if HasOpenOrPendingApprovalEntriesForCurrentUser(RecRef.RecordId) and CanCancelApprovalForRecord(RecRef.RecordId) then
            Error(PreventDeleteRecordWithOpenApprovalEntryForCurrUserMsg);

        if (HasOpenApprovalEntries(RecRef.RecordId) and CanCancelApprovalForRecord(RecRef.RecordId))
         or WorkflowWebhookMgt.HasPendingWorkflowWebhookEntryByRecordId(RecRef.RecordId) then
            case RecRef.Number of
                Database::"Gen. Journal Batch":
                    if ConfirmManagement.GetResponseOrDefault(PreventDeleteRecordWithOpenApprovalEntryMsg, true) then begin
                        RecRef.SetTable(GenJournalBatch);
                        OnCancelGeneralJournalBatchApprovalRequest(GenJournalBatch);
                    end else
                        Error('');
                Database::"Gen. Journal Line":
                    Error(PreventDeleteRecordWithOpenApprovalEntryForSenderMsg);
            end;
    end;

Internal work item: AB#610442

Metadata

Metadata

Assignees

No one assigned

    Labels

    IntegrationGitHub request for Integration areaevent-requestRequest for adding an event

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions