Codeunit 410 Update Analysis View
- App
- Base Application
- Namespace
- Microsoft.Finance.Analysis
- Versions
- 17-28
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Finance/Analysis/UpdateAnalysisView.Codeunit.al1033 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.Analysis;
using Microsoft.CashFlow.Forecast;
using Microsoft.Finance.Dimension;
using Microsoft.Finance.GeneralLedger.Budget;
using Microsoft.Finance.GeneralLedger.Ledger;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Foundation.Period;
using System.Reflection;
/// <summary>
/// Updates analysis view entries from G/L entries, cash flow entries, and budget entries.
/// Provides the core engine for maintaining analysis view data with optimized batch processing.
/// </summary>
/// <remarks>
/// Central processing codeunit for analysis view maintenance. Handles incremental updates from transaction data,
/// manages dimension aggregation, and maintains analysis view entry records. Supports both manual and automatic
/// updates triggered by posting routines. Includes progress tracking and error handling for large data volumes.
/// Extensibility: Multiple integration events for custom processing logic and data validation.
/// </remarks>
codeunit 410 "Update Analysis View"
{
Permissions = TableData "G/L Entry" = r,
TableData "G/L Budget Entry" = r,
TableData "Analysis View" = rm,
TableData "Analysis View Filter" = r,
TableData "Analysis View Entry" = rimd,
TableData "Analysis View Budget Entry" = rimd;
TableNo = "Analysis View";
trigger OnRun()
begin
if Rec.Code <> '' then begin
InitLastEntryNo();
Rec.LockTable();
Rec.Find();
UpdateOne(Rec, 2, Rec."Last Entry No." < LastGLEntryNo - 1000);
end;
end;
var
AnalysisView: Record "Analysis View";
GLSetup: Record "General Ledger Setup";
GLEntry: Record "G/L Entry";
CFForecastEntry: Record "Cash Flow Forecast Entry";
GLBudgetEntry: Record "G/L Budget Entry";
AnalysisViewEntry: Record "Analysis View Entry";
AnalysisViewFilter: Record "Analysis View Filter";
AnalysisViewBudgetEntry: Record "Analysis View Budget Entry";
TempAnalysisViewEntry: Record "Analysis View Entry" temporary;
TempAnalysisViewBudgetEntry: Record "Analysis View Budget Entry" temporary;
TempDimBuf: Record "Dimension Buffer" temporary;
DimSetEntry: Record "Dimension Set Entry";
TempDimSetEntry: Record "Dimension Set Entry" temporary;
TempDimEntryBuffer: Record "Dimension Entry Buffer" temporary;
Window: Dialog;
FilterIsInitialized: Boolean;
FiltersExist: Boolean;
PrevPostingDate: Date;
PrevCalculatedPostingDate: Date;
NoOfEntries: Integer;
ShowProgressWindow: Boolean;
WinLastEntryNo: Integer;
WinUpdateCounter: Integer;
WinTotalCounter: Integer;
WinTime0: Time;
WinTime1: Time;
WinTime2: Time;
LastGLEntryNo: Integer;
LastBudgetEntryNo: Integer;
LastEntryNoIsInitialized: Boolean;
#pragma warning disable AA0074
#pragma warning disable AA0470
Text005: Label 'Analysis View #1############################\\';
Text006: Label 'Updating table #2############################\';
Text007: Label 'Speed: (Entries/s)#4########\';
Text008: Label 'Average Speed #5########';
Text009: Label '#6############### @3@@@@@@@@@@@@@@@@@@@@@@@@@@@@\\';
#pragma warning restore AA0470
Text010: Label 'Summarizing';
Text011: Label 'Updating Database';
#pragma warning restore AA0074
AccountSourceNotSupportedErr: Label 'The selected account source is not supported.';
local procedure InitLastEntryNo()
begin
GLEntry.Reset();
GLBudgetEntry.Reset();
if LastEntryNoIsInitialized then
exit;
LastGLEntryNo := GLEntry.GetLastEntryNo();
LastBudgetEntryNo := GLBudgetEntry.GetLastEntryNo();
LastEntryNoIsInitialized := true;
OnAfterInitLastEntryNo(LastGLEntryNo);
end;
/// <summary>
/// Updates all analysis views that require updating based on specified entry types.
/// </summary>
/// <param name="Which">Type of entries to update (Ledger Entries, Budget Entries, or Both)</param>
/// <param name="DirectlyFromPosting">Whether the update is triggered directly from posting routines</param>
procedure UpdateAll(Which: Option "Ledger Entries","Budget Entries",Both; DirectlyFromPosting: Boolean)
var
AnalysisView2: Record "Analysis View";
InBatchPosting: Boolean;
SessionNo: Integer;
begin
OnBeforeUpdateAll(Which, DirectlyFromPosting, AnalysisView2, InBatchPosting);
if DirectlyFromPosting and InBatchPosting then
exit;
AnalysisView2.ReadIsolation(IsolationLevel::ReadUncommitted);
AnalysisView2.SetRange(Blocked, false);
if DirectlyFromPosting then
AnalysisView2.SetRange("Update on Posting", true);
if AnalysisView2.IsEmpty() then
exit;
if GuiAllowed() and DirectlyFromPosting and TaskScheduler.CanCreateTask() then
StartSession(SessionNo, Codeunit::"Update Analysis View Backgr.")
else
UpdateAll(AnalysisView2, Which, DirectlyFromPosting);
end;
internal procedure UpdateAll(var AnalysisView2: Record "Analysis View"; Which: Option "Ledger Entries","Budget Entries",Both; DirectlyFromPosting: Boolean)
begin
if not AnalysisView2.WritePermission() then
exit;
InitLastEntryNo();
if DirectlyFromPosting then
AnalysisView2.SetFilter("Last Entry No.", '<%1', LastGLEntryNo);
OnUpdateAllOnAfterFilterAnalysisView2(AnalysisView2, DirectlyFromPosting, LastBudgetEntryNo);
AnalysisView2.LockTable();
if AnalysisView2.FindSet() then
repeat
UpdateOne(AnalysisView2, Which, not DirectlyFromPosting and (AnalysisView2."Last Entry No." < LastGLEntryNo - 1000));
until AnalysisView2.Next() = 0;
OnAfterUpdateAll(Which, DirectlyFromPosting);
end;
/// <summary>
/// Updates a single analysis view with data from the specified entry types.
/// </summary>
/// <param name="NewAnalysisView">Analysis view record to update</param>
/// <param name="Which">Type of entries to update (Ledger Entries, Budget Entries, or Both)</param>
/// <param name="ShowWindow">Whether to display progress window during update</param>
procedure Update(var NewAnalysisView: Record "Analysis View"; Which: Option "Ledger Entries","Budget Entries",Both; ShowWindow: Boolean)
begin
InitLastEntryNo();
NewAnalysisView.LockTable();
NewAnalysisView.Find();
UpdateOne(NewAnalysisView, Which, ShowWindow);
end;
local procedure UpdateOne(var NewAnalysisView: Record "Analysis View"; Which: Option "Ledger Entries","Budget Entries",Both; ShowWindow: Boolean)
var
Updated: Boolean;
IsHandled: Boolean;
TableID: Integer;
LastReportedEntryNo: Integer;
Supported: Boolean;
begin
IsHandled := false;
OnBeforeUpdateOne(NewAnalysisView, Which, ShowWindow, IsHandled);
if IsHandled then
exit;
AnalysisView := NewAnalysisView;
AnalysisView.TestField(Blocked, false);
ShowProgressWindow := ShowWindow and GuiAllowed;
if ShowProgressWindow then
InitWindow();
OnUpdateOneOnBeforeUpdateEntries(AnalysisView, Which, LastBudgetEntryNo);
case AnalysisView."Account Source" of
AnalysisView."Account Source"::"G/L Account":
if Which in [Which::"Ledger Entries", Which::Both] then
if LastGLEntryNo > AnalysisView."Last Entry No." then begin
if ShowProgressWindow then
UpdateWindowHeader(DATABASE::"Analysis View Entry", GLEntry."Entry No.");
UpdateEntries();
AnalysisView."Last Entry No." := LastGLEntryNo;
Updated := true;
end;
AnalysisView."Account Source"::"Cash Flow Account":
begin
CFForecastEntry.Reset();
CFForecastEntry.LockTable();
if ShowProgressWindow then
UpdateWindowHeader(DATABASE::"Analysis View Entry", CFForecastEntry."Entry No.");
UpdateEntries();
Updated := true;
end;
else begin
OnBeforeUpdateOneUpdateEntries(AnalysisView, Which, LastReportedEntryNo, TableID, Supported);
if not Supported then
Error(AccountSourceNotSupportedErr);
if ShowProgressWindow then
UpdateWindowHeader(TableID, LastReportedEntryNo);
UpdateEntries();
Updated := true;
end;
end;
OnUpdateOneOnBeforeNewAnalysisViewIncludeBudgetsCheck(NewAnalysisView, AnalysisView, Which);
if (Which in [Which::"Budget Entries", Which::Both]) and
NewAnalysisView."Include Budgets"
then
if LastBudgetEntryNo > AnalysisView."Last Budget Entry No." then begin
if ShowProgressWindow then
UpdateWindowHeader(DATABASE::"Analysis View Budget Entry", GLBudgetEntry."Entry No.");
GLBudgetEntry.Reset();
GLBudgetEntry.SetRange("Entry No.", AnalysisView."Last Budget Entry No." + 1, LastBudgetEntryNo);
UpdateBudgetEntries(AnalysisView."Last Budget Entry No." + 1);
AnalysisView."Last Budget Entry No." := LastBudgetEntryNo;
Updated := true;
end;
OnUpdateOneOnBeforeUpdateAnalysisView(AnalysisView, TempAnalysisViewEntry, Updated, ShowProgressWindow);
if Updated then begin
AnalysisView."Last Date Updated" := Today;
AnalysisView."Reset Needed" := false;
AnalysisView.Modify();
end;
if ShowProgressWindow then
Window.Close();
end;
local procedure UpdateEntries()
var
UpdAnalysisViewEntryBuffer: Record "Upd Analysis View Entry Buffer";
begin
GLSetup.Get();
FilterIsInitialized := false;
case AnalysisView."Account Source" of
AnalysisView."Account Source"::"G/L Account":
UpdateEntriesForGLAccount();
AnalysisView."Account Source"::"Cash Flow Account":
UpdateEntriesForCFAccount();
end;
OnGetEntriesForUpdate(AnalysisView, UpdAnalysisViewEntryBuffer);
UpdAnalysisViewEntryBuffer.Reset();
if UpdAnalysisViewEntryBuffer.FindSet() then
repeat
UpdateAnalysisViewEntry(UpdAnalysisViewEntryBuffer);
until UpdAnalysisViewEntryBuffer.Next() = 0;
FlushAnalysisViewEntry();
end;
local procedure UpdateEntriesForGLAccount()
var
AnalysisViewGLQry: Query "Analysis View Source";
EntryNo: Integer;
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeUpdateEntriesForGLAccount(TempAnalysisViewEntry, AnalysisView, LastGLEntryNo, NoOfEntries, IsHandled, ShowProgressWindow);
if IsHandled then
exit;
if AnalysisView."Date Compression" = AnalysisView."Date Compression"::None then begin
UpdateEntriesForGLAccountDetailed();
exit;
end;
AnalysisViewGLQry.SetRange(AnalysisViewCode, AnalysisView.Code);
AnalysisViewGLQry.SetRange(EntryNo, AnalysisView."Last Entry No." + 1, LastGLEntryNo);
if AnalysisView."Account Filter" = '' then
AnalysisViewGLQry.SetFilter(GLAccNo, '>%1', '')
else
AnalysisViewGLQry.SetFilter(GLAccNo, AnalysisView."Account Filter");
if AnalysisView."Business Unit Filter" <> '' then
AnalysisViewGLQry.SetFilter(BusinessUnitCode, AnalysisView."Business Unit Filter");
OnUpdateEntriesForGLAccountOnAfterAnalysisViewGLQrySetFilters(AnalysisViewGLQry, AnalysisView);
AnalysisViewGLQry.Open();
while AnalysisViewGLQry.Read() do begin
if DimSetIDInFilter(AnalysisViewGLQry.DimensionSetID, AnalysisView) then
UpdateAnalysisViewEntry(
AnalysisViewGLQry.GLAccNo,
AnalysisViewGLQry.BusinessUnitCode,
'',
AnalysisViewGLQry.DimVal1,
AnalysisViewGLQry.DimVal2,
AnalysisViewGLQry.DimVal3,
AnalysisViewGLQry.DimVal4,
AnalysisViewGLQry.PostingDate,
AnalysisViewGLQry.Amount,
AnalysisViewGLQry.DebitAmount,
AnalysisViewGLQry.CreditAmount,
AnalysisViewGLQry.AmountACY,
AnalysisViewGLQry.DebitAmountACY,
AnalysisViewGLQry.CreditAmountACY,
0);
EntryNo := EntryNo + 1;
if ShowProgressWindow then
UpdateWindowCounter(EntryNo);
end;
AnalysisViewGLQry.Close();
end;
local procedure UpdateEntriesForGLAccountDetailed()
var
GLEntry: Record "G/L Entry";
EntryNo: Integer;
begin
GLEntry.SetRange("Entry No.", AnalysisView."Last Entry No." + 1, LastGLEntryNo);
if AnalysisView."Account Filter" <> '' then
GLEntry.SetFilter("G/L Account No.", AnalysisView."Account Filter");
if AnalysisView."Business Unit Filter" <> '' then
GLEntry.SetFilter("Business Unit Code", AnalysisView."Business Unit Filter");
OnUpdateEntriesForGLAccountDetailedOnAfterGLEntrySetFilters(GLEntry, AnalysisView);
if GLEntry.FindSet() then
repeat
if DimSetIDInFilter(GLEntry."Dimension Set ID", AnalysisView) then
UpdateAnalysisViewEntry(
GLEntry."G/L Account No.", GLEntry."Business Unit Code", '',
GetDimVal(AnalysisView."Dimension 1 Code", GLEntry."Dimension Set ID"),
GetDimVal(AnalysisView."Dimension 2 Code", GLEntry."Dimension Set ID"),
GetDimVal(AnalysisView."Dimension 3 Code", GLEntry."Dimension Set ID"),
GetDimVal(AnalysisView."Dimension 4 Code", GLEntry."Dimension Set ID"),
GLEntry."Posting Date", GLEntry.Amount, GLEntry."Debit Amount", GLEntry."Credit Amount",
GLEntry."Additional-Currency Amount", GLEntry."Add.-Currency Debit Amount", GLEntry."Add.-Currency Credit Amount", GLEntry."Entry No.");
EntryNo := EntryNo + 1;
if ShowProgressWindow then
UpdateWindowCounter(EntryNo);
until GLEntry.Next() = 0;
end;
local procedure UpdateEntriesForCFAccount()
begin
AnalysisViewEntry.SetRange("Analysis View Code", AnalysisView.Code);
AnalysisViewEntry.DeleteAll();
AnalysisViewEntry.Reset();
CFForecastEntry.FilterGroup(2);
CFForecastEntry.SetFilter("Cash Flow Account No.", '<>%1', '');
CFForecastEntry.FilterGroup(0);
if AnalysisView."Account Filter" <> '' then
CFForecastEntry.SetFilter("Cash Flow Account No.", AnalysisView."Account Filter");
if GLSetup."Global Dimension 1 Code" <> '' then
if AnalysisViewFilter.Get(AnalysisView.Code, GLSetup."Global Dimension 1 Code") then
if AnalysisViewFilter."Dimension Value Filter" <> '' then
CFForecastEntry.SetFilter("Global Dimension 1 Code", AnalysisViewFilter."Dimension Value Filter");
if GLSetup."Global Dimension 2 Code" <> '' then
if AnalysisViewFilter.Get(AnalysisView.Code, GLSetup."Global Dimension 2 Code") then
if AnalysisViewFilter."Dimension Value Filter" <> '' then
CFForecastEntry.SetFilter("Global Dimension 2 Code", AnalysisViewFilter."Dimension Value Filter");
if not CFForecastEntry.Find('-') then
exit;
repeat
if DimSetIDInFilter(CFForecastEntry."Dimension Set ID", AnalysisView) then
UpdateAnalysisViewEntry(
CFForecastEntry."Cash Flow Account No.",
'',
CFForecastEntry."Cash Flow Forecast No.",
GetDimVal(AnalysisView."Dimension 1 Code", CFForecastEntry."Dimension Set ID"),
GetDimVal(AnalysisView."Dimension 2 Code", CFForecastEntry."Dimension Set ID"),
GetDimVal(AnalysisView."Dimension 3 Code", CFForecastEntry."Dimension Set ID"),
GetDimVal(AnalysisView."Dimension 4 Code", CFForecastEntry."Dimension Set ID"),
CFForecastEntry."Cash Flow Date",
CFForecastEntry."Amount (LCY)",
0, 0, 0, 0, 0,
CFForecastEntry."Entry No.");
if ShowProgressWindow then
UpdateWindowCounter(CFForecastEntry."Entry No.");
until CFForecastEntry.Next() = 0;
if ShowProgressWindow then
UpdateWindowCounter(CFForecastEntry."Entry No.");
end;
local procedure UpdateBudgetEntries(DeleteFromEntry: Integer)
begin
AnalysisViewBudgetEntry.SetRange("Analysis View Code", AnalysisView.Code);
AnalysisViewBudgetEntry.SetFilter("Entry No.", '>=%1', DeleteFromEntry);
AnalysisViewBudgetEntry.DeleteAll();
AnalysisViewBudgetEntry.Reset();
if AnalysisView."Account Filter" <> '' then
GLBudgetEntry.SetFilter("G/L Account No.", AnalysisView."Account Filter");
if AnalysisView."Business Unit Filter" <> '' then
GLBudgetEntry.SetFilter("Business Unit Code", AnalysisView."Business Unit Filter");
OnUpdateBudgetEntriesOnAfterGLBudgetEntrySetFilters(GLBudgetEntry, AnalysisView);
if not GLBudgetEntry.FindSet(true) then
exit;
repeat
if DimSetIDInFilter(GLBudgetEntry."Dimension Set ID", AnalysisView) then
UpdateAnalysisViewBudgetEntry(
GetDimVal(AnalysisView."Dimension 1 Code", GLBudgetEntry."Dimension Set ID"),
GetDimVal(AnalysisView."Dimension 2 Code", GLBudgetEntry."Dimension Set ID"),
GetDimVal(AnalysisView."Dimension 3 Code", GLBudgetEntry."Dimension Set ID"),
GetDimVal(AnalysisView."Dimension 4 Code", GLBudgetEntry."Dimension Set ID"));
if ShowProgressWindow then
UpdateWindowCounter(GLBudgetEntry."Entry No.");
until GLBudgetEntry.Next() = 0;
if ShowProgressWindow then
UpdateWindowCounter(GLBudgetEntry."Entry No.");
FlushAnalysisViewBudgetEntry();
end;
/// <summary>
/// Updates analysis view entry with individual transaction data from G/L or Cash Flow entries.
/// Stages transaction data in buffer for aggregation into final analysis view entries.
/// </summary>
/// <param name="AccNo">Account number (G/L Account or Cash Flow Account)</param>
/// <param name="BusUnitCode">Business unit code for consolidation scenarios</param>
/// <param name="CashFlowForecastNo">Cash flow forecast number for cash flow entries</param>
/// <param name="DimValue1">Dimension 1 value code from source transaction</param>
/// <param name="DimValue2">Dimension 2 value code from source transaction</param>
/// <param name="DimValue3">Dimension 3 value code from source transaction</param>
/// <param name="DimValue4">Dimension 4 value code from source transaction</param>
/// <param name="PostingDate">Posting date from source transaction</param>
/// <param name="Amount">Net amount in local currency</param>
/// <param name="DebitAmount">Debit amount in local currency</param>
/// <param name="CreditAmount">Credit amount in local currency</param>
/// <param name="AmountACY">Net amount in additional currency</param>
/// <param name="DebitAmountACY">Debit amount in additional currency</param>
/// <param name="CreditAmountACY">Credit amount in additional currency</param>
/// <param name="EntryNo">Entry number from source transaction for traceability</param>
procedure UpdateAnalysisViewEntry(AccNo: Code[20]; BusUnitCode: Code[20]; CashFlowForecastNo: Code[20]; DimValue1: Code[20]; DimValue2: Code[20]; DimValue3: Code[20]; DimValue4: Code[20]; PostingDate: Date; Amount: Decimal; DebitAmount: Decimal; CreditAmount: Decimal; AmountACY: Decimal; DebitAmountACY: Decimal; CreditAmountACY: Decimal; EntryNo: Integer)
var
UpdAnalysisViewEntryBuffer: Record "Upd Analysis View Entry Buffer";
begin
UpdAnalysisViewEntryBuffer.AccNo := AccNo;
UpdAnalysisViewEntryBuffer.BusUnitCode := BusUnitCode;
UpdAnalysisViewEntryBuffer.CashFlowForecastNo := CashFlowForecastNo;
UpdAnalysisViewEntryBuffer.DimValue1 := DimValue1;
UpdAnalysisViewEntryBuffer.DimValue2 := DimValue2;
UpdAnalysisViewEntryBuffer.DimValue3 := DimValue3;
UpdAnalysisViewEntryBuffer.DimValue4 := DimValue4;
UpdAnalysisViewEntryBuffer.PostingDate := PostingDate;
UpdAnalysisViewEntryBuffer.Amount := Amount;
UpdAnalysisViewEntryBuffer.DebitAmount := DebitAmount;
UpdAnalysisViewEntryBuffer.CreditAmount := CreditAmount;
UpdAnalysisViewEntryBuffer.AmountACY := AmountACY;
UpdAnalysisViewEntryBuffer.DebitAmountACY := DebitAmountACY;
UpdAnalysisViewEntryBuffer.CreditAmountACY := CreditAmountACY;
UpdAnalysisViewEntryBuffer.EntryNo := EntryNo;
UpdAnalysisViewEntryBuffer.Insert();
UpdateAnalysisViewEntry(UpdAnalysisViewEntryBuffer);
end;
/// <summary>
/// Updates analysis view entry using buffer record with date compression and aggregation logic.
/// Processes buffer data with period start calculation and dimension aggregation rules.
/// </summary>
/// <param name="UpdAnalysisViewEntryBuffer">Buffer record containing staged transaction data for processing</param>
procedure UpdateAnalysisViewEntry(UpdAnalysisViewEntryBuffer: Record "Upd Analysis View Entry Buffer")
var
DummyUpdAnalysisViewEntryBuffer: Record "Upd Analysis View Entry Buffer";
begin
if UpdAnalysisViewEntryBuffer.PostingDate < AnalysisView."Starting Date" then begin
UpdAnalysisViewEntryBuffer.PostingDate := AnalysisView."Starting Date" - 1;
if AnalysisView."Date Compression" <> AnalysisView."Date Compression"::None then
UpdAnalysisViewEntryBuffer.EntryNo := 0;
end else begin
UpdAnalysisViewEntryBuffer.PostingDate := CalculatePeriodStart(UpdAnalysisViewEntryBuffer.PostingDate, AnalysisView."Date Compression");
if UpdAnalysisViewEntryBuffer.PostingDate < AnalysisView."Starting Date" then
UpdAnalysisViewEntryBuffer.PostingDate := AnalysisView."Starting Date";
if AnalysisView."Date Compression" <> AnalysisView."Date Compression"::None then
UpdAnalysisViewEntryBuffer.EntryNo := 0;
end;
TempAnalysisViewEntry."Analysis View Code" := AnalysisView.Code;
if UpdAnalysisViewEntryBuffer."Account Source" = DummyUpdAnalysisViewEntryBuffer."Account Source" then
UpdAnalysisViewEntryBuffer."Account Source" := AnalysisView."Account Source";
TempAnalysisViewEntry."Account Source" := UpdAnalysisViewEntryBuffer."Account Source";
TempAnalysisViewEntry."Business Unit Code" := UpdAnalysisViewEntryBuffer.BusUnitCode;
TempAnalysisViewEntry."Account No." := UpdAnalysisViewEntryBuffer.AccNo;
TempAnalysisViewEntry."Cash Flow Forecast No." := UpdAnalysisViewEntryBuffer.CashFlowForecastNo;
TempAnalysisViewEntry."Posting Date" := UpdAnalysisViewEntryBuffer.PostingDate;
TempAnalysisViewEntry."Dimension 1 Value Code" := UpdAnalysisViewEntryBuffer.DimValue1;
TempAnalysisViewEntry."Dimension 2 Value Code" := UpdAnalysisViewEntryBuffer.DimValue2;
TempAnalysisViewEntry."Dimension 3 Value Code" := UpdAnalysisViewEntryBuffer.DimValue3;
TempAnalysisViewEntry."Dimension 4 Value Code" := UpdAnalysisViewEntryBuffer.DimValue4;
TempAnalysisViewEntry."Entry No." := UpdAnalysisViewEntryBuffer.EntryNo;
OnUpdateAnalysisViewEntryOnAfterTempAnalysisViewEntryAssignment(TempAnalysisViewEntry, AnalysisView, GLEntry, UpdAnalysisViewEntryBuffer);
if TempAnalysisViewEntry.Find() then begin
TempAnalysisViewEntry.Amount += UpdAnalysisViewEntryBuffer.Amount;
TempAnalysisViewEntry."Debit Amount" += UpdAnalysisViewEntryBuffer.DebitAmount;
TempAnalysisViewEntry."Credit Amount" += UpdAnalysisViewEntryBuffer.CreditAmount;
TempAnalysisViewEntry."Add.-Curr. Amount" += UpdAnalysisViewEntryBuffer.AmountACY;
TempAnalysisViewEntry."Add.-Curr. Debit Amount" += UpdAnalysisViewEntryBuffer.DebitAmountACY;
TempAnalysisViewEntry."Add.-Curr. Credit Amount" += UpdAnalysisViewEntryBuffer.CreditAmountACY;
TempAnalysisViewEntry.Modify();
end else begin
TempAnalysisViewEntry.Amount := UpdAnalysisViewEntryBuffer.Amount;
TempAnalysisViewEntry."Debit Amount" := UpdAnalysisViewEntryBuffer.DebitAmount;
TempAnalysisViewEntry."Credit Amount" := UpdAnalysisViewEntryBuffer.CreditAmount;
TempAnalysisViewEntry."Add.-Curr. Amount" := UpdAnalysisViewEntryBuffer.AmountACY;
TempAnalysisViewEntry."Add.-Curr. Debit Amount" := UpdAnalysisViewEntryBuffer.DebitAmountACY;
TempAnalysisViewEntry."Add.-Curr. Credit Amount" := UpdAnalysisViewEntryBuffer.CreditAmountACY;
TempAnalysisViewEntry.Insert();
NoOfEntries := NoOfEntries + 1;
end;
if NoOfEntries >= 10000 then
FlushAnalysisViewEntry();
end;
local procedure UpdateAnalysisViewBudgetEntry(DimValue1: Code[20]; DimValue2: Code[20]; DimValue3: Code[20]; DimValue4: Code[20])
begin
TempAnalysisViewBudgetEntry."Analysis View Code" := AnalysisView.Code;
TempAnalysisViewBudgetEntry."Budget Name" := GLBudgetEntry."Budget Name";
TempAnalysisViewBudgetEntry."Business Unit Code" := GLBudgetEntry."Business Unit Code";
TempAnalysisViewBudgetEntry."G/L Account No." := GLBudgetEntry."G/L Account No.";
if GLBudgetEntry.Date < AnalysisView."Starting Date" then
TempAnalysisViewBudgetEntry."Posting Date" := AnalysisView."Starting Date" - 1
else begin
TempAnalysisViewBudgetEntry."Posting Date" :=
CalculatePeriodStart(GLBudgetEntry.Date, AnalysisView."Date Compression");
if TempAnalysisViewBudgetEntry."Posting Date" < AnalysisView."Starting Date" then
TempAnalysisViewBudgetEntry."Posting Date" := AnalysisView."Starting Date";
end;
TempAnalysisViewBudgetEntry."Dimension 1 Value Code" := DimValue1;
TempAnalysisViewBudgetEntry."Dimension 2 Value Code" := DimValue2;
TempAnalysisViewBudgetEntry."Dimension 3 Value Code" := DimValue3;
TempAnalysisViewBudgetEntry."Dimension 4 Value Code" := DimValue4;
TempAnalysisViewBudgetEntry."Entry No." := GLBudgetEntry."Entry No.";
OnUpdateAnalysisViewBudgetEntryOnAfterTempAnalysisViewBudgetEntryAssignment(TempAnalysisViewBudgetEntry, AnalysisView, GLBudgetEntry, DimValue1, DimValue2, DimValue3, DimValue4);
if TempAnalysisViewBudgetEntry.Find() then begin
TempAnalysisViewBudgetEntry.Amount := TempAnalysisViewBudgetEntry.Amount + GLBudgetEntry.Amount;
TempAnalysisViewBudgetEntry.Modify();
end else begin
TempAnalysisViewBudgetEntry.Amount := GLBudgetEntry.Amount;
TempAnalysisViewBudgetEntry.Insert();
NoOfEntries := NoOfEntries + 1;
end;
if NoOfEntries >= 10000 then
FlushAnalysisViewBudgetEntry();
end;
/// <summary>
/// Calculates the period start date based on the posting date and date compression setting.
/// Adjusts the date to align with analysis view period boundaries.
/// </summary>
/// <param name="PostingDate">Original posting date to calculate period start for</param>
/// <param name="DateCompression">Date compression option determining period granularity</param>
/// <returns>Calculated period start date aligned with compression settings</returns>
procedure CalculatePeriodStart(PostingDate: Date; DateCompression: Integer): Date
var
AccountingPeriod: Record "Accounting Period";
begin
if PostingDate = ClosingDate(PostingDate) then
exit(PostingDate);
case DateCompression of
AnalysisView."Date Compression"::Week:
PostingDate := CalcDate('<CW+1D-1W>', PostingDate);
AnalysisView."Date Compression"::Month:
PostingDate := CalcDate('<CM+1D-1M>', PostingDate);
AnalysisView."Date Compression"::Quarter:
PostingDate := CalcDate('<CQ+1D-1Q>', PostingDate);
AnalysisView."Date Compression"::Year:
PostingDate := CalcDate('<CY+1D-1Y>', PostingDate);
AnalysisView."Date Compression"::Period:
begin
if PostingDate <> PrevPostingDate then begin
PrevPostingDate := PostingDate;
AccountingPeriod.SetRange("Starting Date", 0D, PostingDate);
if AccountingPeriod.FindLast() then
PrevCalculatedPostingDate := AccountingPeriod."Starting Date"
else
PrevCalculatedPostingDate := PostingDate;
end;
PostingDate := PrevCalculatedPostingDate;
end;
end;
OnAfterCalculatePeriodStart(AnalysisView, DateCompression, AccountingPeriod, PostingDate, PrevCalculatedPostingDate, PrevPostingDate);
exit(PostingDate);
end;
/// <summary>
/// Flushes accumulated analysis view entries from temporary storage to the database.
/// Processes temporary analysis view entries and inserts them as permanent records.
/// </summary>
procedure FlushAnalysisViewEntry()
begin
if ShowProgressWindow then
Window.Update(6, Text011);
if TempAnalysisViewEntry.FindSet() then
repeat
AnalysisViewEntry.Init();
AnalysisViewEntry := TempAnalysisViewEntry;
OnFlushAnalysisViewEntryOnBeforeAnalysisViewEntryInsert(AnalysisViewEntry, TempAnalysisViewEntry);
if not AnalysisViewEntry.Insert() then begin
AnalysisViewEntry.Find();
AnalysisViewEntry.Amount += TempAnalysisViewEntry.Amount;
AnalysisViewEntry."Debit Amount" += TempAnalysisViewEntry."Debit Amount";
AnalysisViewEntry."Credit Amount" += TempAnalysisViewEntry."Credit Amount";
AnalysisViewEntry."Add.-Curr. Amount" += TempAnalysisViewEntry."Add.-Curr. Amount";
AnalysisViewEntry."Add.-Curr. Debit Amount" += TempAnalysisViewEntry."Add.-Curr. Debit Amount";
AnalysisViewEntry."Add.-Curr. Credit Amount" += TempAnalysisViewEntry."Add.-Curr. Credit Amount";
AnalysisViewEntry.Modify();
end;
until TempAnalysisViewEntry.Next() = 0;
TempAnalysisViewEntry.DeleteAll();
NoOfEntries := 0;
if ShowProgressWindow then
Window.Update(6, Text010);
end;
/// <summary>
/// Flushes accumulated analysis view budget entries from temporary storage to the database.
/// Processes temporary budget entries and inserts them as permanent records.
/// </summary>
procedure FlushAnalysisViewBudgetEntry()
begin
if ShowProgressWindow then
Window.Update(6, Text011);
if TempAnalysisViewBudgetEntry.FindSet() then
repeat
AnalysisViewBudgetEntry.Init();
AnalysisViewBudgetEntry := TempAnalysisViewBudgetEntry;
if not AnalysisViewBudgetEntry.Insert() then begin
AnalysisViewBudgetEntry.Find();
AnalysisViewBudgetEntry.Amount += TempAnalysisViewBudgetEntry.Amount;
AnalysisViewBudgetEntry.Modify();
end;
until TempAnalysisViewBudgetEntry.Next() = 0;
TempAnalysisViewBudgetEntry.DeleteAll();
NoOfEntries := 0;
if ShowProgressWindow then
Window.Update(6, Text010);
end;
/// <summary>
/// Retrieves dimension value code for a specific dimension from a dimension set.
/// Uses temporary caching to optimize repeated dimension value lookups during analysis view updates.
/// </summary>
/// <param name="DimCode">Dimension code to retrieve value for</param>
/// <param name="DimSetID">Dimension set ID containing the dimension values</param>
/// <returns>Dimension value code for the specified dimension, empty if not found</returns>
procedure GetDimVal(DimCode: Code[20]; DimSetID: Integer): Code[20]
begin
if TempDimSetEntry.Get(DimSetID, DimCode) then
exit(TempDimSetEntry."Dimension Value Code");
if DimSetEntry.Get(DimSetID, DimCode) then
TempDimSetEntry := DimSetEntry
else begin
TempDimSetEntry."Dimension Set ID" := DimSetID;
TempDimSetEntry."Dimension Code" := DimCode;
TempDimSetEntry."Dimension Value Code" := '';
end;
TempDimSetEntry.Insert();
exit(TempDimSetEntry."Dimension Value Code");
end;
local procedure InitWindow()
begin
Window.Open(
Text005 +
Text006 +
Text009 +
Text007 +
Text008);
Window.Update(6, Text010);
end;
/// <summary>
/// Updates progress window counter during analysis view update operations.
/// Tracks processing progress and updates user interface with percentage completion.
/// </summary>
/// <param name="EntryNo">Current entry number being processed for progress tracking</param>
procedure UpdateWindowCounter(EntryNo: Integer)
begin
WinUpdateCounter := WinUpdateCounter + 1;
WinTime2 := Time;
if (WinTime2 > WinTime1 + 1000) or (EntryNo = WinLastEntryNo) then begin
if WinLastEntryNo <> 0 then
Window.Update(3, Round(EntryNo / WinLastEntryNo * 10000, 1));
WinTotalCounter := WinTotalCounter + WinUpdateCounter;
if WinTime2 <> WinTime1 then
Window.Update(4, Round(WinUpdateCounter * (1000 / (WinTime2 - WinTime1)), 1));
if WinTime2 <> WinTime0 then
Window.Update(5, Round(WinTotalCounter * (1000 / (WinTime2 - WinTime0)), 1));
WinTime1 := WinTime2;
WinUpdateCounter := 0;
end;
end;
/// <summary>
/// Updates progress window header information during analysis view update operations.
/// Displays current table being processed and entry numbers for user feedback.
/// </summary>
/// <param name="TableID">Table ID being processed for display in progress window</param>
/// <param name="EntryNo">Entry number being processed for progress tracking</param>
procedure UpdateWindowHeader(TableID: Integer; EntryNo: Integer)
var
AllObj: Record AllObj;
begin
WinLastEntryNo := EntryNo;
WinTotalCounter := 0;
AllObj.Get(AllObj."Object Type"::Table, TableID);
Window.Update(1, AnalysisView.Code);
Window.Update(2, AllObj."Object Name");
Window.Update(3, 0);
Window.Update(4, 0);
Window.Update(5, 0);
WinTime0 := Time;
WinTime1 := WinTime0;
WinTime2 := WinTime0;
end;
/// <summary>
/// Sets the last budget entry number processed for analysis view updates.
/// Updates the analysis view record with the latest processed budget entry number to track update progress.
/// </summary>
/// <param name="NewLastBudgetEntryNo">New last budget entry number to set for tracking processed entries</param>
procedure SetLastBudgetEntryNo(NewLastBudgetEntryNo: Integer)
var
AnalysisView2: Record "Analysis View";
begin
AnalysisView.SetRange("Last Budget Entry No.", NewLastBudgetEntryNo + 1, 2147483647);
AnalysisView.SetRange("Include Budgets", true);
if AnalysisView.FindSet(true) then
repeat
AnalysisView2 := AnalysisView;
AnalysisView2."Last Budget Entry No." := NewLastBudgetEntryNo;
AnalysisView2.Modify();
until AnalysisView.Next() = 0;
end;
local procedure IsValueIncludedInFilter(DimValue: Code[20]; DimFilter: Code[250]): Boolean
begin
TempDimBuf.Reset();
TempDimBuf.DeleteAll();
TempDimBuf.Init();
TempDimBuf."Dimension Value Code" := DimValue;
TempDimBuf.Insert();
TempDimBuf.SetFilter(TempDimBuf."Dimension Value Code", DimFilter);
exit(TempDimBuf.FindFirst());
end;
/// <summary>
/// Determines whether a dimension set ID matches the analysis view's dimension filters.
/// Validates that all dimension values in the set comply with analysis view filtering criteria.
/// </summary>
/// <param name="DimSetID">Dimension set ID to validate against analysis view filters</param>
/// <param name="AnalysisView">Analysis view record containing dimension filter criteria</param>
/// <returns>True if dimension set matches all analysis view filters, false otherwise</returns>
procedure DimSetIDInFilter(DimSetID: Integer; var AnalysisView: Record "Analysis View"): Boolean
var
InFilters: Boolean;
begin
if not FilterIsInitialized then begin
TempDimEntryBuffer.DeleteAll();
FilterIsInitialized := true;
AnalysisViewFilter.SetRange("Analysis View Code", AnalysisView.Code);
FiltersExist := not AnalysisViewFilter.IsEmpty();
end;
if not FiltersExist then
exit(true);
if TempDimEntryBuffer.Get(DimSetID) then // cashed value?
exit(TempDimEntryBuffer."Dimension Entry No." <> 0);
InFilters := true;
if AnalysisViewFilter.FindSet() then
repeat
if DimSetEntry.Get(DimSetID, AnalysisViewFilter."Dimension Code") then
InFilters :=
InFilters and IsValueIncludedInFilter(DimSetEntry."Dimension Value Code", AnalysisViewFilter."Dimension Value Filter")
else
InFilters :=
InFilters and IsValueIncludedInFilter('', AnalysisViewFilter."Dimension Value Filter");
until (AnalysisViewFilter.Next() = 0) or not InFilters;
TempDimEntryBuffer."No." := DimSetID;
if InFilters then
TempDimEntryBuffer."Dimension Entry No." := 1
else
TempDimEntryBuffer."Dimension Entry No." := 0;
TempDimEntryBuffer.Insert();
exit(InFilters);
end;
/// <summary>
/// Integration event raised after initializing last entry number for analysis view updates.
/// Allows modification of the starting entry number for update processing.
/// </summary>
/// <param name="LastGLEntryNo">Last G/L entry number that can be modified by subscribers</param>
[IntegrationEvent(false, false)]
local procedure OnAfterInitLastEntryNo(var LastGLEntryNo: Integer)
begin
end;
/// <summary>
/// Integration event raised after completing analysis view update operations.
/// Enables post-update processing and cleanup activities.
/// </summary>
/// <param name="Which">Update option indicating which entries were processed</param>
/// <param name="DirectlyFromPosting">Indicates whether update was triggered directly from posting</param>
[IntegrationEvent(false, false)]
local procedure OnAfterUpdateAll(Which: Option "Ledger Entries","Budget Entries",Both; DirectlyFromPosting: Boolean)
begin
end;
/// <summary>
/// Integration event raised before starting analysis view update operations.
/// Allows preprocessing and modification of update parameters.
/// </summary>
/// <param name="Which">Update option indicating which entries to process</param>
/// <param name="DirectlyFromPosting">Indicates whether update is triggered directly from posting</param>
/// <param name="AnalysisView">Analysis view record being updated</param>
/// <param name="InBatchPosting">Set to true to indicate batch posting mode</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateAll(Which: Option "Ledger Entries","Budget Entries",Both; DirectlyFromPosting: Boolean; var AnalysisView: Record "Analysis View"; var InBatchPosting: Boolean)
begin
end;
/// <summary>
/// Integration event raised before updating a single analysis view.
/// Allows custom handling and preprocessing for individual analysis view updates.
/// </summary>
/// <param name="NewAnalysisView">Analysis view record to be updated</param>
/// <param name="Which">Update option indicating which entries to process</param>
/// <param name="ShowWindow">Indicates whether to show progress window during update</param>
/// <param name="IsHandled">Set to true to skip standard update processing</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateOne(var NewAnalysisView: Record "Analysis View"; Which: Option "Ledger Entries","Budget Entries",Both; ShowWindow: Boolean; var IsHandled: Boolean)
begin
end;
/// <summary>
/// Integration event raised before updating entries for G/L account analysis views.
/// Allows custom entry processing and modification of update parameters.
/// </summary>
/// <param name="TempAnalysisViewEntry">Temporary analysis view entry records being processed</param>
/// <param name="AnalysisView">Analysis view record controlling the update</param>
/// <param name="LastGLEntryNo">Last G/L entry number to process</param>
/// <param name="NoOfEntries">Number of entries being processed</param>
/// <param name="IsHandled">Set to true to skip standard entry processing</param>
/// <param name="ShowProgressWindow">Indicates whether to show progress window</param>
[IntegrationEvent(true, false)]
local procedure OnBeforeUpdateEntriesForGLAccount(var TempAnalysisViewEntry: Record "Analysis View Entry" temporary; AnalysisView: Record "Analysis View"; LastGLEntryNo: Integer; var NoOfEntries: Integer; var IsHandled: Boolean; ShowProgressWindow: Boolean)
begin
end;
/// <summary>
/// Integration event raised before inserting analysis view entries during flush operations.
/// Allows modification of analysis view entries before they are permanently stored.
/// </summary>
/// <param name="AnalysisViewEntry">Analysis view entry record to be inserted</param>
/// <param name="TempAnalysisViewEntry">Temporary analysis view entry source data</param>
[IntegrationEvent(false, false)]
local procedure OnFlushAnalysisViewEntryOnBeforeAnalysisViewEntryInsert(var AnalysisViewEntry: Record "Analysis View Entry"; TempAnalysisViewEntry: Record "Analysis View Entry" temporary)
begin
end;
/// <summary>
/// Integration event raised before updating analysis view during single view update operations.
/// Allows custom processing and modification of analysis view update parameters.
/// </summary>
/// <param name="AnalysisView">Analysis view record being updated</param>
/// <param name="TempAnalysisViewEntry">Temporary analysis view entry records being processed</param>
/// <param name="Updated">Indicates whether analysis view was updated</param>
/// <param name="ShowProgressWindow">Indicates whether to show progress window</param>
[IntegrationEvent(true, false)]
local procedure OnUpdateOneOnBeforeUpdateAnalysisView(var AnalysisView: Record "Analysis View"; var TempAnalysisViewEntry: Record "Analysis View Entry" temporary; var Updated: Boolean; ShowProgressWindow: Boolean)
begin
end;
/// <summary>
/// Integration event raised before checking if new analysis view includes budgets during update process.
/// Enables custom validation logic for budget inclusion in analysis view updates.
/// </summary>
/// <param name="NewAnalysisView">New analysis view configuration</param>
/// <param name="AnalysisView">Current analysis view being updated</param>
/// <param name="Which">Update type indicating whether to update ledger entries, budget entries, or both</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateOneOnBeforeNewAnalysisViewIncludeBudgetsCheck(var NewAnalysisView: Record "Analysis View"; var AnalysisView: Record "Analysis View"; Which: Option "Ledger Entries","Budget Entries",Both)
begin
end;
/// <summary>
/// Integration event raised before starting analysis view entry updates.
/// Enables custom logic before analysis view entries are processed and updated.
/// </summary>
/// <param name="AnalysisView">Analysis view being updated</param>
/// <param name="Which">Update type indicating whether to update ledger entries, budget entries, or both</param>
/// <param name="LastGLEntryNo">Last G/L entry number processed in the update</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateOneOnBeforeUpdateEntries(var AnalysisView: Record "Analysis View"; Which: Option "Ledger Entries","Budget Entries",Both; LastGLEntryNo: Integer)
begin
end;
/// <summary>
/// Integration event raised after setting filters on G/L Budget Entry during budget update process.
/// Enables additional filtering logic for budget entries being processed.
/// </summary>
/// <param name="GLBudgetEntry">G/L Budget Entry record with applied filters</param>
/// <param name="AnalysisView">Analysis view configuration being updated</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateBudgetEntriesOnAfterGLBudgetEntrySetFilters(var GLBudgetEntry: Record "G/L Budget Entry"; var AnalysisView: Record "Analysis View")
begin
end;
/// <summary>
/// Integration event raised after setting filters on G/L Entry during detailed G/L account update.
/// Enables additional filtering logic for detailed G/L entry processing.
/// </summary>
/// <param name="GLEntry">G/L Entry record with applied filters</param>
/// <param name="AnalysisView">Analysis view configuration being updated</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateEntriesForGLAccountDetailedOnAfterGLEntrySetFilters(var GLEntry: Record "G/L Entry"; var AnalysisView: Record "Analysis View")
begin
end;
/// <summary>
/// Integration event raised after setting filters on Analysis View Source query during G/L account update.
/// Enables custom query filtering for analysis view source data processing.
/// </summary>
/// <param name="AnalysisViewSourceQry">Analysis View Source query with applied filters</param>
/// <param name="AnalysisView">Analysis view configuration being updated</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateEntriesForGLAccountOnAfterAnalysisViewGLQrySetFilters(var AnalysisViewSourceQry: Query "Analysis View Source";
var
AnalysisView: Record "Analysis View")
begin
end;
/// <summary>
/// Integration event raised after assigning values to temporary Analysis View Budget Entry during update.
/// Enables modification of budget entry data before final processing.
/// </summary>
/// <param name="TempAnalysisViewBudgetEntry">Temporary Analysis View Budget Entry being updated</param>
/// <param name="AnalysisView">Analysis view configuration</param>
/// <param name="GLBudgetEntry">Source G/L Budget Entry</param>
/// <param name="DimValue1">Dimension 1 value code</param>
/// <param name="DimValue2">Dimension 2 value code</param>
/// <param name="DimValue3">Dimension 3 value code</param>
/// <param name="DimValue4">Dimension 4 value code</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateAnalysisViewBudgetEntryOnAfterTempAnalysisViewBudgetEntryAssignment(var TempAnalysisViewBudgetEntry: Record "Analysis View Budget Entry"; var AnalysisView: Record "Analysis View"; var GLBudgetEntry: Record "G/L Budget Entry"; DimValue1: Code[20]; DimValue2: code[20]; DimValue3: Code[20]; DimValue4: Code[20])
begin
end;
/// <summary>
/// Integration event raised after calculating period start date for analysis view updates.
/// Enables custom period calculation logic for different date compression methods.
/// </summary>
/// <param name="AnalysisView">Analysis view configuration</param>
/// <param name="DateCompression">Date compression method being used</param>
/// <param name="AccountingPeriod">Accounting period record for calculations</param>
/// <param name="PostingDate">Posting date being processed</param>
/// <param name="PrevCalculatedPostingDate">Previously calculated posting date</param>
/// <param name="PrevPostingDate">Previous posting date</param>
[IntegrationEvent(false, false)]
local procedure OnAfterCalculatePeriodStart(var AnalysisView: Record "Analysis View"; DateCompression: Integer; var AccountingPeriod: Record "Accounting Period"; var PostingDate: Date; var PrevCalculatedPostingDate: Date; PrevPostingDate: Date)
begin
end;
/// <summary>
/// Integration event raised before updating entries during single analysis view update process.
/// Enables pre-update validation and custom entry processing logic.
/// </summary>
/// <param name="NewAnalysisView">New analysis view configuration</param>
/// <param name="Which">Update type indicating whether to update ledger entries, budget entries, or both</param>
/// <param name="LastReportedEntryNo">Last reported entry number in the update process</param>
/// <param name="TableID">Table ID being processed</param>
/// <param name="Supproted">Whether the operation is supported</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateOneUpdateEntries(var NewAnalysisView: Record "Analysis View"; Which: Option "Ledger Entries","Budget Entries",Both; var LastReportedEntryNo: Integer; var TableID: Integer; var Supproted: Boolean)
begin
end;
/// <summary>
/// Integration event for retrieving entries to update in analysis view processing.
/// Enables custom entry retrieval logic and filtering for analysis view updates.
/// </summary>
/// <param name="AnalysisView">Analysis view configuration</param>
/// <param name="UpdAnalysisViewEntryBuffer">Update Analysis View Entry Buffer for entry staging</param>
[IntegrationEvent(false, false)]
local procedure OnGetEntriesForUpdate(var AnalysisView: Record "Analysis View"; var UpdAnalysisViewEntryBuffer: Record "Upd Analysis View Entry Buffer")
begin
end;
/// <summary>
/// Integration event raised after filtering Analysis View records during update all process.
/// Enables additional processing logic after analysis view filtering is complete.
/// </summary>
/// <param name="AnalysisView">Analysis view record with applied filters</param>
/// <param name="DirectlyFromPosting">Whether update is triggered directly from posting</param>
/// <param name="LastBudgetEntryNo">Last budget entry number processed</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateAllOnAfterFilterAnalysisView2(var AnalysisView: Record "Analysis View"; DirectlyFromPosting: Boolean; LastBudgetEntryNo: Integer)
begin
end;
/// <summary>
/// Integration event raised after assigning values to temporary Analysis View Entry during update.
/// Enables modification of analysis view entry data before final processing.
/// </summary>
/// <param name="TempAnalysisViewEntry">Temporary Analysis View Entry being updated</param>
/// <param name="AnalysisView">Analysis view configuration</param>
/// <param name="GLEntry">Source G/L Entry</param>
/// <param name="UpdAnalysisViewEntryBuffer">Update Analysis View Entry Buffer for staging</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateAnalysisViewEntryOnAfterTempAnalysisViewEntryAssignment(var TempAnalysisViewEntry: Record "Analysis View Entry" temporary; var AnalysisView: Record "Analysis View"; var GLEntry: Record "G/L Entry"; var UpdAnalysisViewEntryBuffer: Record "Upd Analysis View Entry Buffer")
begin
end;
}