Codeunit 250 Gen. Jnl.-Post via Job Queue, source in 29
Source29
src/Layers/W1/BaseApp/Finance/GeneralLedger/Posting/GenJnlPostviaJobQueue.Codeunit.al232 lines, Copyright (c) Microsoft Corporation. MIT
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.Finance.GeneralLedger.Posting;
using Microsoft.Finance.GeneralLedger.Journal;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Foundation.BatchProcessing;
using System.Threading;
/// <summary>
/// Manages background posting of general journal lines through the job queue system.
/// Handles asynchronous posting operations with status tracking, error handling, and optional document printing.
/// </summary>
/// <remarks>
/// Supports both immediate job queue scheduling and UI-driven background posting.
/// Integrates with job queue status management, recurring journal processing, and print functionality.
/// </remarks>
codeunit 250 "Gen. Jnl.-Post via Job Queue"
{
TableNo = "Job Queue Entry";
trigger OnRun()
var
GenJrnlLine: record "Gen. Journal Line";
OrigGenJrnlLine: Record "Gen. Journal Line";
GenJrnlTemplate: Record "Gen. Journal Template";
BatchPostingPrintMgt: Codeunit "Batch Posting Print Mgt.";
RecRef: RecordRef;
RecRefToPrint: RecordRef;
PrintPostDocuments: Boolean;
begin
Rec.TestField("Record ID to Process");
RecRef.Get(Rec."Record ID to Process");
RecRef.SetTable(GenJrnlLine);
PrintPostDocuments := GenJrnlLine."Print Posted Documents";
GenJrnlTemplate.Get(GenJrnlLine."Journal Template Name");
if GenJrnlTemplate.Recurring then
ExecuteRecurringGeneralJournalsLogic(GenJrnlLine);
OrigGenJrnlLine.Copy(GenJrnlLine);
GenJrnlLine.SetRange("Journal Template Name", GenJrnlLine."Journal Template Name");
GenJrnlLine.SetRange("Journal Batch Name", GenJrnlLine."Journal Batch Name");
GenJrnlLine.SetRange("Document No.", GenJrnlLine."Document No.");
GenJrnlLine.FindSet();
SetJobQueueStatus(GenJrnlLine, GenJrnlLine."Job Queue Status"::Posting);
if not CODEUNIT.Run(CODEUNIT::"Gen. Jnl.-Post Batch", GenJrnlLine) then begin
SetJobQueueStatus(GenJrnlLine, GenJrnlLine."Job Queue Status"::Error);
Error(GetLastErrorText);
end;
if PrintPostDocuments then begin
RecRefToPrint.GetTable(GenJrnlLine);
BatchPostingPrintMgt.PrintJournal(RecRefToPrint);
end;
ClearBackgroundPostingInfo(OrigGenJrnlLine);
end;
var
#pragma warning disable AA0074
PostDescription: Label 'Post journal lines for journal template %1, journal batch %2, document no. %3.', Comment = '%1 = template name, %2 = batch name, %3 = document no. Example: Post journal lines for journal template GENERAL, journal batch DEFAULT, document no. G00123.';
PostAndPrintDescription: Label 'Post and print journal lines for journal template %1, journal batch %2, document no. %3.', Comment = '%1 = template name, %2 = batch name, %3 = document no. Example: Post and print journal lines for journal template GENERAL, journal batch DEFAULT, document no. G00123.';
Confirmation: Label 'Journal lines have been scheduled for posting.';
WrongJobQueueStatus: Label 'Journal lines cannot be posted because they have already been scheduled for posting. Choose the Remove from Job Queue action to reset the job queue status and then post again.';
PostingDateError: Label 'is not within your range of allowed posting dates';
#pragma warning restore AA0074
local procedure SetJobQueueStatus(var GenJrnlLine: Record "Gen. Journal Line"; NewStatus: Enum "Document Job Queue Status")
begin
GenJrnlLine.LockTable();
if GenJrnlLine.Find() then begin
GenJrnlLine.SetRange("Journal Template Name", GenJrnlLine."Journal Template Name");
GenJrnlLine.SetRange("Journal Batch Name", GenJrnlLine."Journal Batch Name");
GenJrnlLine.SetRange("Document No.", GenJrnlLine."Document No.");
GenJrnlLine.ModifyAll("Job Queue Status", NewStatus);
Commit();
end;
end;
/// <summary>
/// Schedules general journal lines for background posting via job queue with default UI confirmation.
/// Creates job queue entries for asynchronous processing with user notifications enabled.
/// </summary>
/// <param name="GenJrnlLine">Journal line record to be posted in background</param>
procedure EnqueueGenJrnlLine(var GenJrnlLine: Record "Gen. Journal Line")
begin
EnqueueGenJrnlLineWithUI(GenJrnlLine, true);
end;
/// <summary>
/// Schedules general journal lines for background posting via job queue with configurable UI behavior.
/// Creates job queue entries for asynchronous processing with optional user confirmation messages.
/// </summary>
/// <param name="GenJrnlLine">Journal line record to be posted in background</param>
/// <param name="WithUI">True to show confirmation messages, false for silent operation</param>
procedure EnqueueGenJrnlLineWithUI(var GenJrnlLine: Record "Gen. Journal Line"; WithUI: Boolean)
var
Handled: Boolean;
begin
OnBeforeEnqueueGenJrnlLine(GenJrnlLine, Handled);
if Handled then
exit;
if not (GenJrnlLine."Job Queue Status" in [GenJrnlLine."Job Queue Status"::" ", GenJrnlLine."Job Queue Status"::Error]) then
Error(WrongJobQueueStatus);
OnBeforeReleaseGenJrnlLine(GenJrnlLine);
GenJrnlLine."Job Queue Entry ID" := EnqueueJobEntry(GenJrnlLine);
GenJrnlLine.Modify();
GenJrnlLine.SetRange("Journal Template Name", GenJrnlLine."Journal Template Name");
GenJrnlLine.SetRange("Journal Batch Name", GenJrnlLine."Journal Batch Name");
GenJrnlLine.SetRange("Document No.", GenJrnlLine."Document No.");
GenJrnlLine.ModifyAll("Job Queue Status", GenJrnlLine."Job Queue Status"::"Scheduled for Posting");
GenJrnlLine.ModifyAll("Job Queue Entry ID", GenJrnlLine."Job Queue Entry ID");
if GuiAllowed then
if WithUI then
Message(Confirmation);
end;
local procedure EnqueueJobEntry(GenJrnlLine: Record "Gen. Journal Line"): Guid
var
JobQueueEntry: Record "Job Queue Entry";
begin
Clear(JobQueueEntry.ID);
JobQueueEntry."Object Type to Run" := JobQueueEntry."Object Type to Run"::Codeunit;
JobQueueEntry."Object ID to Run" := CODEUNIT::"Gen. Jnl.-Post via Job Queue";
JobQueueEntry."Record ID to Process" := GenJrnlLine.RecordId;
JobQueueEntry."Earliest Start Date/Time" := CreateDateTime(Today(), Time());
FillJobEntryFromGeneralLedgerSetup(JobQueueEntry);
FillJobEntryGeneralLedgerDescription(JobQueueEntry, GenJrnlLine);
CODEUNIT.Run(CODEUNIT::"Job Queue - Enqueue", JobQueueEntry);
exit(JobQueueEntry.ID);
end;
local procedure FillJobEntryFromGeneralLedgerSetup(var JobQueueEntry: Record "Job Queue Entry")
var
GeneralLedgerSetup: record "General Ledger Setup";
begin
GeneralLedgerSetup.Get();
JobQueueEntry."Notify On Success" := GeneralLedgerSetup."Notify On Success";
JobQueueEntry."Job Queue Category Code" := GeneralLedgerSetup."Job Queue Category Code";
end;
local procedure FillJobEntryGeneralLedgerDescription(var JobQueueEntry: Record "Job Queue Entry"; GenJrnlLine: Record "Gen. Journal Line")
begin
if GenJrnlLine."Print Posted Documents" then
JobQueueEntry.Description := PostAndPrintDescription
else
JobQueueEntry.Description := PostDescription;
JobQueueEntry.Description :=
CopyStr(StrSubstNo(JobQueueEntry.Description, GenJrnlLine."Journal Template Name", GenJrnlLine."Journal Batch Name", GenJrnlLine."Document No."), 1, MaxStrLen(JobQueueEntry.Description));
end;
/// <summary>
/// Cancels scheduled background posting job queue entries for general journal lines.
/// Removes associated job queue entries and resets job queue status to allow manual posting.
/// </summary>
/// <param name="GenJrnlLine">Journal line record with scheduled job queue entries to cancel</param>
procedure CancelQueueEntry(var GenJrnlLine: Record "Gen. Journal Line")
begin
if GenJrnlLine."Job Queue Status" <> GenJrnlLine."Job Queue Status"::" " then begin
DeleteJobs(GenJrnlLine);
SetJobQueueStatus(GenJrnlLine, GenJrnlLine."Job Queue Status"::" ");
end;
end;
local procedure DeleteJobs(GenJrnlLine: Record "Gen. Journal Line")
var
JobQueueEntry: Record "Job Queue Entry";
begin
if not IsNullGuid(GenJrnlLine."Job Queue Entry ID") then
JobQueueEntry.SetRange(ID, GenJrnlLine."Job Queue Entry ID");
JobQueueEntry.SetRange("Record ID to Process", GenJrnlLine.RecordId);
if not JobQueueEntry.IsEmpty() then
JobQueueEntry.DeleteAll(true);
end;
local procedure ClearBackgroundPostingInfo(GenJrnlLine: Record "Gen. Journal Line")
var
EmptyGuid: Guid;
begin
GenJrnlLine.SetRange("Journal Template Name", GenJrnlLine."Journal Template Name");
GenJrnlLine.SetRange("Journal Batch Name", GenJrnlLine."Journal Batch Name");
GenJrnlLine.SetRange("Document No.", GenJrnlLine."Document No.");
GenJrnlLine.ModifyAll("Job Queue Status", GenJrnlLine."Job Queue Status"::" ");
GenJrnlLine.ModifyAll("Job Queue Entry ID", EmptyGuid);
GenJrnlLine.ModifyAll("Print Posted Documents", false);
end;
local procedure ExecuteRecurringGeneralJournalsLogic(GenJrnlLine: Record "Gen. Journal Line")
var
GenJnlCheckLine: Codeunit "Gen. Jnl.-Check Line";
begin
if GenJnlCheckLine.DateNotAllowed(GenJrnlLine."Posting Date", GenJrnlLine."Journal Template Name") then begin
SetJobQueueStatus(GenJrnlLine, GenJrnlLine."Job Queue Status"::Error);
GenJrnlLine.FieldError("Posting Date", PostingDateError);
end;
// If the template is Recurring and WorkDate() < GenJrnlLine."Posting Date", update the WorkDate to allow background posting of lines that are set to post in the future.
// In the UI, users can modify the WorkDate to allow this.
if WorkDate() < GenJrnlLine."Posting Date" then
WorkDate := WorkDate(GenJrnlLine."Posting Date");
end;
/// <summary>
/// Integration event raised before enqueuing general journal lines for background posting.
/// Enables custom validation or preprocessing before job queue entry creation.
/// </summary>
/// <param name="GenJrnlLine">Journal line record being prepared for background posting</param>
/// <param name="Handled">Set to true to skip standard job queue enqueuing process</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeEnqueueGenJrnlLine(var GenJrnlLine: Record "Gen. Journal Line"; var Handled: Boolean)
begin
end;
/// <summary>
/// Integration event raised before releasing general journal lines to job queue processing.
/// Enables final validation or modification before lines are scheduled for background posting.
/// </summary>
/// <param name="GenJrnlLine">Journal line record being released for job queue processing</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeReleaseGenJrnlLine(var GenJrnlLine: Record "Gen. Journal Line")
begin
end;
}