Codeunit 107 Import and Consolidate, source in 29
Source29
src/Layers/W1/BaseApp/Finance/Consolidation/ImportAndConsolidate.Codeunit.al144 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.Consolidation;
using Microsoft.Finance.GeneralLedger.Journal;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Foundation.NoSeries;
using System.Telemetry;
using System.Threading;
/// <summary>
/// Coordinates the complete import and consolidation process for multiple business units.
/// Manages job queue processing, business unit iteration, and consolidation method execution.
/// </summary>
/// <remarks>
/// Main orchestration codeunit for automated consolidation workflows. Handles business unit processing,
/// data import method selection, and consolidation method execution through extensible interface patterns.
/// </remarks>
codeunit 107 "Import and Consolidate"
{
Permissions = tabledata "General Ledger Setup" = R,
tabledata "Gen. Journal Batch" = R;
TableNo = "Job Queue Entry";
trigger OnRun()
var
ConsolidationProcess: Record "Consolidation Process";
begin
ConsolidationProcess.Get(Rec."Record ID to Process");
ImportAndConsolidate(ConsolidationProcess);
end;
var
ConsolidationSetup: Record "Consolidation Setup";
FinancialConsolidationServiceNameTxt: Label 'Financial Consolidation', Locked = true;
SecurityAuditConsolidationStartedTxt: Label 'Consolidation process %1 started for period %2 to %3 across %4 business unit(s).', Locked = true, Comment = '%1 - Consolidation Process Id, %2 - Starting Date, %3 - Ending Date, %4 - Business Unit count';
SecurityAuditConsolidationCompletedTxt: Label 'Consolidation process %1 completed.', Locked = true, Comment = '%1 - Consolidation Process Id';
internal procedure ImportAndConsolidate(var ConsolidationProcess: Record "Consolidation Process")
var
GeneralLedgerSetup: Record "General Ledger Setup";
GenJournalBatch: Record "Gen. Journal Batch";
BusUnitInConsProcess: Record "Bus. Unit In Cons. Process";
BusinessUnit: Record "Business Unit";
BusUnitConsolidationData: Record "Bus. Unit Consolidation Data";
ImportConsolidationFromAPI: Codeunit "Import Consolidation From API";
FeatureTelemetry: Codeunit "Feature Telemetry";
NoSeries: Codeunit "No. Series";
ConsolidationMethod: Interface "Consolidation Method";
ImportConsolidationData: Interface "Import Consolidation Data";
begin
if ConsolidationProcess.Status <> ConsolidationProcess.Status::NotStarted then
exit;
BusUnitInConsProcess.SetRange("Consolidation Process Id", ConsolidationProcess.Id);
BusUnitInConsProcess.SetAutoCalcFields("Default Data Import Method");
GeneralLedgerSetup.Get();
ConsolidationProcess.Status := ConsolidationProcess.Status::InProgress;
if GeneralLedgerSetup."Journal Templ. Name Mandatory" then begin
GenJournalBatch.Get(ConsolidationProcess."Journal Template Name", ConsolidationProcess."Journal Batch Name");
GenJournalBatch.TestField("No. Series");
ConsolidationProcess."Document No." := NoSeries.GetNextNo(GenJournalBatch."No. Series", WorkDate());
end;
ConsolidationProcess.Modify();
Commit();
Session.LogSecurityAudit(
FinancialConsolidationServiceNameTxt, SecurityOperationResult::Success,
StrSubstNo(SecurityAuditConsolidationStartedTxt, ConsolidationProcess.Id, ConsolidationProcess."Starting Date", ConsolidationProcess."Ending Date", BusUnitInConsProcess.Count()),
AuditCategory::CustomerFacing);
if BusUnitInConsProcess.FindSet() then begin
FeatureTelemetry.LogUptake('0000KOJ', ImportConsolidationFromAPI.GetFeatureTelemetryName(), Enum::"Feature Uptake Status"::"Set up");
FeatureTelemetry.LogUptake('0000KOG', ImportConsolidationFromAPI.GetFeatureTelemetryName(), Enum::"Feature Uptake Status"::Used);
repeat
BusinessUnit.Get(BusUnitInConsProcess."Business Unit Code");
BusUnitInConsProcess.Status := BusUnitInConsProcess.Status::ImportingData;
BusUnitInConsProcess.Modify();
Commit();
BusUnitConsolidationData."Consolidation Process Id" := ConsolidationProcess.Id;
BusUnitConsolidationData."Business Unit Code" := BusinessUnit.Code;
GetBusinessUnitConsolidationImplementations(BusinessUnit, BusUnitInConsProcess, ImportConsolidationData, ConsolidationMethod);
ImportConsolidationData.ImportConsolidationDataForBusinessUnit(ConsolidationProcess, BusinessUnit, BusUnitConsolidationData);
Session.LogMessage('0000OUM', 'Data imported succesfully', Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::All, 'Category', ConsolidationSetup.GetTelemetryCategory());
ConsolidationMethod.Consolidate(ConsolidationProcess, BusinessUnit, BusUnitConsolidationData);
Session.LogMessage('0000OUN', 'Business unit consolidated succesfully', Verbosity::Normal, DataClassification::SystemMetadata, TelemetryScope::All, 'Category', ConsolidationSetup.GetTelemetryCategory());
BusUnitInConsProcess.Status := BusUnitInConsProcess.Status::Finished;
BusUnitInConsProcess.Modify();
Commit();
until BusUnitInConsProcess.Next() = 0;
FeatureTelemetry.LogUsage('0000KOH', ImportConsolidationFromAPI.GetFeatureTelemetryName(), 'Completed consolidation imported from API');
end;
ConsolidationProcess.Status := ConsolidationProcess.Status::Completed;
ConsolidationProcess.Modify();
Session.LogSecurityAudit(
FinancialConsolidationServiceNameTxt, SecurityOperationResult::Success,
StrSubstNo(SecurityAuditConsolidationCompletedTxt, ConsolidationProcess.Id),
AuditCategory::CustomerFacing);
end;
local procedure GetBusinessUnitConsolidationImplementations(BusinessUnit: Record "Business Unit"; BusUnitInConsProcess: Record "Bus. Unit In Cons. Process"; var ImportConsolidationDataImplementation: Interface "Import Consolidation Data"; var ConsolidationMethodImplementation: Interface "Consolidation Method")
begin
case BusinessUnit."Default Data Import Method" of
BusinessUnit."Default Data Import Method"::Database:
ImportConsolidationDataImplementation := Enum::"Import Consolidation Data"::"Import Consolidation Data from DB";
BusinessUnit."Default Data Import Method"::API:
ImportConsolidationDataImplementation := Enum::"Import Consolidation Data"::"Import Consolidation Data from API";
end;
ConsolidationMethodImplementation := Enum::"Consolidation Method"::Default;
OnAfterGetBusinessUnitConsolidationImplementations(BusinessUnit, BusUnitInConsProcess, ImportConsolidationDataImplementation, ConsolidationMethodImplementation);
end;
/// <summary>
/// Integration event raised after retrieving business unit consolidation implementations.
/// Enables custom override of import data and consolidation method implementations.
/// </summary>
/// <param name="BusinessUnit">Business Unit being processed for consolidation</param>
/// <param name="BusUnitInConsProcess">Business Unit in Consolidation Process record</param>
/// <param name="ImportConsolidationDataImplementation">Interface implementation for data import method</param>
/// <param name="ConsolidationMethodImplementation">Interface implementation for consolidation method</param>
[IntegrationEvent(false, false)]
local procedure OnAfterGetBusinessUnitConsolidationImplementations(BusinessUnit: Record "Business Unit"; BusUnitInConsProcess: Record "Bus. Unit In Cons. Process"; var ImportConsolidationDataImplementation: Interface "Import Consolidation Data"; var ConsolidationMethodImplementation: Interface "Consolidation Method")
begin
end;
// No other event should be required in this codeunit.
#if not CLEAN27
/// <summary>
/// Integration event raised before setting consolidation process parameters.
/// OBSOLETE: Use OnAfterGetBusinessUnitConsolidationImplementations instead with custom interface implementations.
/// </summary>
/// <param name="ConsolidationProcess">Consolidation Process record being configured</param>
/// <param name="BusUnitInConsProcess">Business Unit in Consolidation Process record</param>
/// <param name="IsHandled">Set to true to bypass standard parameter setting</param>
[IntegrationEvent(false, false)]
[Obsolete('Please use OnAfterGetBusinessUnitConsolidationImplementations instead. You can override the behavior by providing your own implementations of the interfaces "Import Consolidation Data" and "Consolidation Method"', '27.0')]
local procedure OnImportAndConsolidateOnBeforeSetConsolidationProcessParameters(var ConsolidationProcess: Record "Consolidation Process"; var BusUnitInConsProcess: Record "Bus. Unit In Cons. Process"; var IsHandled: Boolean)
begin
end;
#endif
}