Report 8 Budget
- App
- Base Application
- Namespace
- Microsoft.Finance.GeneralLedger.Reports
- Versions
- 17-28
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Finance/GeneralLedger/Reports/Budget.Report.al403 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.Reports;
using Microsoft.Finance.Analysis;
using Microsoft.Finance.GeneralLedger.Account;
using Microsoft.Foundation.Enums;
using System.Utilities;
/// <summary>
/// Generates budget analysis report with period-by-period budget breakdowns and variance analysis.
/// Displays budgeted amounts across multiple periods with configurable rounding and period length options.
/// </summary>
/// <remarks>
/// Data sources: G/L Account table with Budget Filter integration for budget vs. actual comparison.
/// Supports period length configuration, thousands display option, and comprehensive dimension filtering.
/// Output format: RDLC layout with columnar period display and variance calculation capabilities.
/// </remarks>
report 8 Budget
{
ApplicationArea = Suite;
Caption = 'Budget';
PreviewMode = PrintLayout;
UsageCategory = ReportsAndAnalysis;
DefaultRenderingLayout = RDLCLayout;
dataset
{
dataitem("G/L Account"; "G/L Account")
{
DataItemTableView = sorting("No.");
RequestFilterFields = "No.", "Account Type", "Budget Filter", "Global Dimension 1 Filter", "Global Dimension 2 Filter";
column(CompanyName; COMPANYPROPERTY.DisplayName())
{
}
column(GLBudgetFilter; GLBudgetFilter)
{
}
column(NoOfBlankLines_GLAcc; "No. of Blank Lines")
{
}
column(AmtsInThousands; InThousands)
{
}
column(GLFilterTableCaption_GLAcc; TableCaption + ': ' + GLFilter)
{
}
column(GLFilter; GLFilter)
{
}
column(Type_GLAcc; "Account Type")
{
}
column(AccountTypePosting; GLAccountTypePosting)
{
}
column(PeriodStartDate1; Format(PeriodStartDate[1], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate2; Format(PeriodStartDate[2], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate3; Format(PeriodStartDate[3], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate4; Format(PeriodStartDate[4], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate5; Format(PeriodStartDate[5], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate6; Format(PeriodStartDate[6], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate7; Format(PeriodStartDate[7], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate8; Format(PeriodStartDate[8], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate9; Format(PeriodStartDate[9], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate10; Format(PeriodStartDate[10], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate11; Format(PeriodStartDate[11], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate12; Format(PeriodStartDate[12], 0, '<Month Text,3>'))
{
}
column(PeriodStartDate21; Format(PeriodStartDate[2] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate31; Format(PeriodStartDate[3] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate41; Format(PeriodStartDate[4] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate51; Format(PeriodStartDate[5] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate61; Format(PeriodStartDate[6] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate71; Format(PeriodStartDate[7] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate81; Format(PeriodStartDate[8] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate91; Format(PeriodStartDate[9] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate101; Format(PeriodStartDate[10] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate111; Format(PeriodStartDate[11] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate121; Format(PeriodStartDate[12] - 1, 0, '<Month Text,3>'))
{
}
column(PeriodStartDate131; Format(PeriodStartDate[13] - 1, 0, '<Month Text,3>'))
{
}
column(No_GLAcc; "No.")
{
IncludeCaption = true;
}
column(BudgetCaption; BudgetCaptionTxt)
{
}
column(PageCaption; PageCaptionLbl)
{
}
column(BudgetFilterCaption; BudgetFilterCaptionLbl)
{
}
column(AmtsAreInwhole1000sCaptn; AmtsAreInwhole1000sCaptnLbl)
{
}
column(GLAccNameCaption; GLAccNameCaptionLbl)
{
}
column(TotalCaption; TotalLbl)
{
}
column(RowNumber; RowNumber)
{
}
column(StartingDateAsText; StartingDateAsText)
{
}
dataitem(BlankLineCounter; "Integer")
{
DataItemTableView = sorting(Number);
trigger OnPreDataItem()
begin
SetRange(Number, 1, "G/L Account"."No. of Blank Lines");
end;
}
dataitem("Integer"; "Integer")
{
DataItemTableView = sorting(Number) where(Number = const(1));
column(GLAccNo_BlankLineCounter; "G/L Account"."No.")
{
IncludeCaption = true;
}
column(PADSTRIndentName_GLAcc; PadStr('', "G/L Account".Indentation * 2) + "G/L Account".Name)
{
}
column(GLBudgetedAmount1; GLBudgetedAmount[1])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount2; GLBudgetedAmount[2])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount3; GLBudgetedAmount[3])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount4; GLBudgetedAmount[4])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount5; GLBudgetedAmount[5])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount6; GLBudgetedAmount[6])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount7; GLBudgetedAmount[7])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount8; GLBudgetedAmount[8])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount9; GLBudgetedAmount[9])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount10; GLBudgetedAmount[10])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount11; GLBudgetedAmount[11])
{
DecimalPlaces = 0 : 5;
}
column(GLBudgetedAmount12; GLBudgetedAmount[12])
{
DecimalPlaces = 0 : 5;
}
column(TotalBudgetAmount; TotalBudgetAmount)
{
DecimalPlaces = 0 : 5;
}
}
trigger OnAfterGetRecord()
begin
TotalBudgetAmount := 0;
for i := 1 to ArrayLen(GLBudgetedAmount) do begin
SetRange("Date Filter", PeriodStartDate[i], PeriodStartDate[i + 1] - 1);
CalcFields("Budgeted Amount");
if InThousands then
"Budgeted Amount" := "Budgeted Amount" / 1000;
GLBudgetedAmount[i] := MatrixMgt.RoundAmount("Budgeted Amount", RndFactor);
TotalBudgetAmount += GLBudgetedAmount[i];
end;
SetRange("Date Filter", PeriodStartDate[1], PeriodStartDate[ArrayLen(PeriodStartDate)] - 1);
GLAccountTypePosting := "Account Type" = "Account Type"::Posting;
RowNumber += 1;
end;
}
}
requestpage
{
SaveValues = true;
layout
{
area(content)
{
group(Options)
{
Caption = 'Options';
field(StartingDate; PeriodStartDate[1])
{
ApplicationArea = Suite;
Caption = 'Starting Date';
ToolTip = 'Specifies the date from which the report or batch job processes information.';
}
field(PeriodLength; PeriodLength)
{
ApplicationArea = Suite;
Caption = 'Period Length';
Editable = false;
Enabled = false;
ToolTip = 'Specifies the period for which data is shown in the report. For example, enter "1M" for one month, "30D" for thirty days, "3Q" for three quarters, or "5Y" for five years.';
}
field(InThousands; InThousands)
{
ApplicationArea = Suite;
Caption = 'Amounts in whole 1000s';
ToolTip = 'Specifies if the amounts in the report are shown in whole 1000s.';
}
field(RoundingFactor; RndFactor)
{
ApplicationArea = Suite;
Caption = 'Rounding Factor';
ToolTip = 'Specifies the factor that is used to round the amounts.';
}
}
}
}
actions
{
}
trigger OnOpenPage()
begin
if PeriodStartDate[1] = 0D then
PeriodStartDate[1] := CalcDate('<-CY+1D>', WorkDate());
if Format(PeriodLength) = '' then
Evaluate(PeriodLength, '<1M>');
end;
}
rendering
{
layout(RDLCLayout)
{
Type = RDLC;
LayoutFile = './Finance/GeneralLedger/Reports/Budget.rdlc';
Summary = 'Report layout made in the legacy RDLC format. Use an RDLC editor to modify the layout.';
}
}
labels
{
}
trigger OnPreReport()
begin
GLFilter := "G/L Account".GetFilters();
GLBudgetFilter := "G/L Account".GetFilter("Budget Filter");
if PeriodStartDate[1] = 0D then
PeriodStartDate[1] := WorkDate();
for i := 2 to ArrayLen(PeriodStartDate) do
PeriodStartDate[i] := CalcDate(PeriodLength, PeriodStartDate[i - 1]);
BudgetCaptionTxt := StrSubstNo(BudgetCaptionTok, Format(PeriodStartDate[1], 0, '<Year4>'));
StartingDateAsText := StrSubstNo(StartingDateTok, PeriodStartDate[1]);
end;
var
MatrixMgt: Codeunit "Matrix Management";
PeriodLength: DateFormula;
InThousands: Boolean;
GLBudgetFilter: Text[250];
BudgetCaptionTxt: Text;
GLBudgetedAmount: array[12] of Decimal;
TotalBudgetAmount: Decimal;
PeriodStartDate: array[13] of Date;
i: Integer;
RowNumber: Integer;
GLAccountTypePosting: Boolean;
RndFactor: Enum "Analysis Rounding Factor";
StartingDateAsText: Text;
BudgetCaptionTok: Label 'Budget for %1', Comment = '%1 - year';
PageCaptionLbl: Label 'Page';
BudgetFilterCaptionLbl: Label 'Budget Filter';
AmtsAreInwhole1000sCaptnLbl: Label 'Amounts are in whole 1000s.';
GLAccNameCaptionLbl: Label 'Name';
TotalLbl: Label 'Total';
StartingDateTok: Label 'Starting Date: %1', Comment = '%1 - date';
protected var
GLFilter: Text;
/// <summary>
/// Initializes report parameters for programmatic execution with period configuration and display options.
/// Sets starting date, period length formula, and thousands display option for automated budget report generation.
/// </summary>
/// <param name="NewPeriodStartDate">Starting date for budget period analysis</param>
/// <param name="NewPeriodLength">Period length formula as text (e.g., '1M', '1Q', '1Y')</param>
/// <param name="NewInThousands">Whether to display amounts in thousands</param>
procedure InitializeRequest(NewPeriodStartDate: Date; NewPeriodLength: Text[30]; NewInThousands: Boolean)
begin
PeriodStartDate[1] := NewPeriodStartDate;
Evaluate(PeriodLength, NewPeriodLength);
InThousands := NewInThousands;
end;
/// <summary>
/// Sets the rounding factor for amount display formatting in the budget report.
/// Controls precision level for budget amounts (ones, thousands, millions).
/// </summary>
/// <param name="NewRoundingFactor">Analysis rounding factor enum value for amount formatting</param>
procedure SetRoundingFactor(NewRoundingFactor: Enum "Analysis Rounding Factor")
begin
RndFactor := NewRoundingFactor;
end;
/// <summary>
/// Retrieves the configured period length formula for the budget report.
/// Returns the DateFormula used to calculate period intervals for budget analysis.
/// </summary>
/// <returns>DateFormula representing the period length (e.g., 1M for monthly, 1Q for quarterly)</returns>
procedure GetPeriodLength(): DateFormula
begin
exit(PeriodLength);
end;
/// <summary>
/// Retrieves the starting date configured for the budget report period analysis.
/// Returns the first period's starting date used in budget calculations.
/// </summary>
/// <returns>Starting date for the first budget period</returns>
procedure GetPeriodStartDate(): Date
begin
exit(PeriodStartDate[1]);
end;
}