Codeunit 2582 Dimension Correction Undo, source in 29
Source29
src/Layers/W1/BaseApp/Finance/Dimension/Correction/DimensionCorrectionUndo.Codeunit.al173 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.Dimension.Correction;
using Microsoft.Finance.Dimension;
using Microsoft.Finance.GeneralLedger.Ledger;
using System.Threading;
/// <summary>
/// Reverses dimension correction by restoring original dimension values to affected G/L entries.
/// Runs as background job queue entry with validation and comprehensive logging.
/// </summary>
codeunit 2582 "Dimension Correction Undo"
{
TableNo = "Job Queue Entry";
Permissions = tabledata "G/L Entry" = rimd;
trigger OnRun()
var
DimensionCorrection: Record "Dimension Correction";
begin
DimensionCorrection.Get(Rec."Record ID to Process");
RunUndoDimensionCorrection(DimensionCorrection);
end;
/// <summary>
/// Undoes dimension correction by restoring original dimension values to all affected G/L entries.
/// </summary>
/// <param name="DimensionCorrection">Dimension correction record to undo</param>
procedure RunUndoDimensionCorrection(var DimensionCorrection: Record "Dimension Correction")
var
DimensionCorrectionMgt: Codeunit "Dimension Correction Mgt";
begin
Session.LogMessage('0000EHM', StrSubstNo(StartingDimensionCorrectionUndoLbl, DimensionCorrection."Entry No."), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', DimensionCorrectionTok);
Session.LogMessage('0000EHN', StrSubstNo(StartingVerifyingCanUndoDimensionCorrectionLbl, DimensionCorrection."Entry No."), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', DimensionCorrectionTok);
DimensionCorrectionMgt.VerifyCanUndoDimensionCorrection(DimensionCorrection);
Session.LogMessage('0000EHO', StrSubstNo(CompletedVerifyingCanUndoDimensionCorrectionLbl, DimensionCorrection."Entry No."), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', DimensionCorrectionTok);
DimensionCorrectionMgt.SetUndoStatusInProgress(DimensionCorrection);
UndoDimensionCorrection(DimensionCorrection);
DimensionCorrection.Status := DimensionCorrection.Status::"Undo Completed";
DimensionCorrection.Modify();
Commit();
if DimensionCorrection."Update Analysis Views" then
DimensionCorrectionMgt.ScheduleUpdateAnalysisViews(DimensionCorrection);
Session.LogMessage('0000EHP', StrSubstNo(CompletedDimensionCorrectionUndoLbl, DimensionCorrection."Entry No."), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', DimensionCorrectionTok);
end;
local procedure UndoDimensionCorrection(var DimensionCorrection: Record "Dimension Correction")
var
DimCorrectionEntryLog: Record "Dim Correction Entry Log";
TempDimCorrectionSetBuffer: Record "Dim Correction Set Buffer" temporary;
InvalidatedDimCorrection: Record "Invalidated Dim Correction";
GLEntry: Record "G/L Entry";
TempInvalidatedDimCorrection: Record "Invalidated Dim Correction" temporary;
DimensionCorrectionMgt: Codeunit "Dimension Correction Mgt";
StartDateTime: DateTime;
begin
Session.LogMessage('0000EHQ', StrSubstNo(StartingUndoDimensionCorrectionEntriesLbl, DimensionCorrection."Entry No."), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', DimensionCorrectionTok);
StartDateTime := CurrentDateTime();
if not DimensionCorrectionManagement.LoadTempDimCorrectionSetBuffer(DimensionCorrection."Entry No.", TempDimCorrectionSetBuffer) then
Error(CannotFindChangesToUndoErr);
DimCorrectionEntryLog.SetCurrentKey("Start Entry No.");
DimCorrectionEntryLog.Ascending(true);
DimCorrectionEntryLog.SetRange("Dimension Correction Entry No.", DimensionCorrection."Entry No.");
DimCorrectionEntryLog.SetFilter("End Entry No.", '>=%1', DimensionCorrection."Undo Last Ledger Entry No.");
if not DimCorrectionEntryLog.FindSet() then
Error(CannotFindEntriesToUndoErr);
if DimCorrectionEntryLog."Start Entry No." < DimensionCorrection."Undo Last Ledger Entry No." then
DimCorrectionEntryLog."Start Entry No." := DimensionCorrection."Undo Last Ledger Entry No.";
repeat
GLEntry.SetRange("Entry No.", DimCorrectionEntryLog."Start Entry No.", DimCorrectionEntryLog."End Entry No.");
if GLEntry.FindSet() then
repeat
if DimensionCorrectionMgt.GetTargetDimCorrectionSetBuffer(TempDimCorrectionSetBuffer, DimensionCorrection, GLEntry) then begin
UndoGLEntry(GLEntry, TempDimCorrectionSetBuffer, TempInvalidatedDimCorrection);
CommitCounter += 1;
if CommitCounter >= DimensionCorrectionMgt.GetCommitCount() then begin
DimensionCorrection."Undo Last Ledger Entry No." := GLEntry."Entry No.";
Commit();
Session.LogMessage('0000EHR', StrSubstNo(CommitedUndoLedgerEntriesUpdateTelemetryLbl, Format(CurrentDateTime() - StartDateTime), DimensionCorrectionMgt.GetCommitCount()), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', DimensionCorrectionTok);
StartDateTime := CurrentDateTime();
CommitCounter := 0;
end;
end;
until GLEntry.Next() = 0;
until DimCorrectionEntryLog.Next() = 0;
if CommitCounter > 0 then
Commit();
InvalidatedDimCorrection.SetRange("Invalidated By Entry No.", DimensionCorrection."Entry No.");
InvalidatedDimCorrection.DeleteAll();
Commit();
Session.LogMessage('0000EHS', StrSubstNo(CompletedUndoDimensionCorrectionEntriesLbl, DimensionCorrection."Entry No."), Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::ExtensionPublisher, 'Category', DimensionCorrectionTok);
end;
local procedure UndoGLEntry(var GLEntry: Record "G/L Entry"; var TempDimCorrectionSetBuffer: Record "Dim Correction Set Buffer" temporary; var TempInvalidatedDimCorrection: Record "Invalidated Dim Correction" temporary): Boolean
var
InvalidatedDimCorrection: Record "Invalidated Dim Correction";
DimensionManagement: Codeunit "DimensionManagement";
Result: Boolean;
begin
if GLEntry."Dimension Set ID" = TempDimCorrectionSetBuffer."Dimension Set ID" then
exit(false);
GLEntry."Dimension Set ID" := TempDimCorrectionSetBuffer."Dimension Set ID";
DimensionManagement.UpdateGlobalDimFromDimSetID(
GLEntry."Dimension Set ID", GLEntry."Global Dimension 1 Code", GLEntry."Global Dimension 2 Code");
OnUndoGLEntryOnAfterUpdateGlobalDimFromDimSetID(GLEntry);
GLEntry."Dimension Changes Count" += 1;
if not TempInvalidatedDimCorrection.Get(GLEntry."Last Dim. Correction Node") then begin
InvalidatedDimCorrection.Get(GLEntry."Last Dim. Correction Node");
TempInvalidatedDimCorrection.TransferFields(InvalidatedDimCorrection, true);
TempInvalidatedDimCorrection.Insert();
end;
GLEntry."Last Dim. Correction Node" := TempInvalidatedDimCorrection."Parent Node Id";
GLEntry."Last Dim. Correction Entry No." := TempInvalidatedDimCorrection."Invalidated Entry No.";
GLEntry.Modify(true);
Result := true;
OnAfterUndoGLEntry(GLEntry, TempDimCorrectionSetBuffer, Result, TempInvalidatedDimCorrection);
exit(Result);
end;
var
DimensionCorrectionManagement: Codeunit "Dimension Correction Mgt";
CommitCounter: Integer;
CannotFindChangesToUndoErr: Label 'Cannot find the changed dimension set IDs to undo.';
CannotFindEntriesToUndoErr: Label 'Cannot find changed entries to undo.';
DimensionCorrectionTok: Label 'DimensionCorrection', Locked = true;
StartingDimensionCorrectionUndoLbl: Label 'Starting Undo of Dimension Correction - %1', Locked = true, Comment = '%1 Dimension Correction Entry No.';
CompletedDimensionCorrectionUndoLbl: Label 'Completed Undo of Dimension Correction - %1', Locked = true, Comment = '%1 Dimension Correction Entry No.';
StartingVerifyingCanUndoDimensionCorrectionLbl: Label 'Starting Verify if Undo is possible of Dimension Correction - %1', Locked = true, Comment = '%1 Dimension Correction Entry No.';
CompletedVerifyingCanUndoDimensionCorrectionLbl: Label 'Completed Verify if Undo is possible of Dimension Correction - %1', Locked = true, Comment = '%1 Dimension Correction Entry No.';
StartingUndoDimensionCorrectionEntriesLbl: Label 'Starting undo of Ledger entries of Dimension Correction %1.', Locked = true, Comment = '%1 Dimension Correction Entry No.';
CompletedUndoDimensionCorrectionEntriesLbl: Label 'Starting undo of Ledger entries of Dimension Correction %1.', Locked = true, Comment = '%1 Dimension Correction Entry No.';
CommitedUndoLedgerEntriesUpdateTelemetryLbl: Label 'Commited Undo G/L Entries Dimensions. Time from last commit: %1. Number of entries iterated: %2', Locked = true, Comment = '%1 - Time passed between commits, %2 Number';
/// <summary>
/// Integration event raised after updating global dimensions from dimension set ID during undo operation.
/// </summary>
/// <param name="GLEntry">G/L entry with restored global dimensions</param>
[IntegrationEvent(false, false)]
local procedure OnUndoGLEntryOnAfterUpdateGlobalDimFromDimSetID(var GLEntry: Record "G/L Entry")
begin
end;
/// <summary>
/// Integration event raised after undoing dimension changes for a G/L entry.
/// </summary>
/// <param name="GLEntry">G/L entry that was restored</param>
/// <param name="TempDimCorrectionSetBuffer">Temporary dimension correction set buffer</param>
/// <param name="Result">Undo operation result status</param>
/// <param name="TempInvalidatedDimCorrection">Temporary invalidated dimension correction record</param>
[IntegrationEvent(false, false)]
local procedure OnAfterUndoGLEntry(var GLEntry: Record "G/L Entry"; var TempDimCorrectionSetBuffer: Record "Dim Correction Set Buffer"; var Result: Boolean; var TempInvalidatedDimCorrection: Record "Invalidated Dim Correction" temporary)
begin
end;
}