Report 11 G/L - VAT Reconciliation
- App
- Base Application
- Namespace
- Microsoft.Finance.VAT.Reporting
- Versions
- 17-28
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Finance/VAT/Reporting/GLVATReconciliation.Report.al587 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.VAT.Reporting;
using Microsoft.Finance.Currency;
using Microsoft.Finance.GeneralLedger.Account;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Finance.VAT.Ledger;
/// <summary>
/// Reconciles G/L account balances with VAT statement line calculations for accuracy verification.
/// Compares VAT amounts calculated from VAT entries against corresponding G/L account balances to identify discrepancies.
/// </summary>
report 11 "G/L - VAT Reconciliation"
{
ApplicationArea = Basic, Suite;
Caption = 'G/L - VAT Reconciliation';
UsageCategory = ReportsAndAnalysis;
DefaultRenderingLayout = RDLCLayout;
dataset
{
dataitem("VAT Statement Name"; "VAT Statement Name")
{
DataItemTableView = sorting("Statement Template Name", Name);
RequestFilterFields = Name;
column(VAT_Statement_Name_Statement_Template_Name; "Statement Template Name")
{
}
column(VAT_Statement_Name_Name; Name)
{
}
dataitem("VAT Statement Line"; "VAT Statement Line")
{
DataItemLink = "Statement Template Name" = field("Statement Template Name"), "Statement Name" = field(Name);
DataItemTableView = sorting("Statement Template Name", "Statement Name", "Line No.") where(Type = filter("Account Totaling" | "VAT Entry Totaling"));
PrintOnlyIfDetail = true;
column(VAT_Statement_Name__Name; "VAT Statement Name".Name)
{
}
column(VAT_Statement_Name___Statement_Template_Name_; "VAT Statement Name"."Statement Template Name")
{
}
column(COMPANYNAME; COMPANYPROPERTY.DisplayName())
{
}
column(USERID; UserId)
{
}
column(Header; Header)
{
}
column(FORMAT_TODAY_0_0______FORMAT_TIME_0_0_; Format(Today, 0, 0))
{
}
column(HeaderText; HeaderText)
{
}
column(Header2; Header2)
{
}
column(VAT_Statement_Line__TABLECAPTION__________VATStmtLineFilter; TableCaption + ': ' + VATStmtLineFilter)
{
}
column(VATStmtLineFilter; VATStmtLineFilter)
{
}
column(VAT_Statement_Line__Row_No__; "Row No.")
{
}
column(VAT_Statement_Line_Description; Description)
{
}
column(VAT_Statement_Line_Type; Type)
{
}
column(VAT_Statement_Line__Amount_Type_; "Amount Type")
{
}
column(VAT_Statement_Line__VAT_Bus__Posting_Group_; "VAT Bus. Posting Group")
{
}
column(VAT_Statement_Line__VAT_Prod__Posting_Group_; "VAT Prod. Posting Group")
{
}
column(VAT_Statement_Line__Gen__Posting_Type_; "Gen. Posting Type")
{
}
column(TypeNo; TypeNo)
{
}
column(TotalAmount; TotalAmount)
{
}
column(TotalVAT; TotalVAT)
{
}
column(VAT_Statement_Line_Statement_Template_Name; "Statement Template Name")
{
}
column(VAT_Statement_Line_Statement_Name; "Statement Name")
{
}
column(VAT_Statement_Line_Line_No_; "Line No.")
{
}
column(VAT_Statement_Name__NameCaption; VAT_Statement_Name__NameCaptionLbl)
{
}
column(VAT_Statement_Name___Statement_Template_Name_Caption; VAT_Statement_Name___Statement_Template_Name_CaptionLbl)
{
}
column(CurrReport_PAGENOCaption; CurrReport_PAGENOCaptionLbl)
{
}
column(GL_VAT_ReconciliationCaption; GL_VAT_ReconciliationCaptionLbl)
{
}
column(AmountCaption; AmountCaptionLbl)
{
}
column(VATCaption; VATCaptionLbl)
{
}
column(Account_No_Caption; Account_No_CaptionLbl)
{
}
column(G_L_Account_Name_Control1140052Caption; "G/L Account".FieldCaption(Name))
{
}
column(Account_TypeCaption; Account_TypeCaptionLbl)
{
}
column(VAT_Statement_Line__VAT_Prod__Posting_Group_Caption; FieldCaption("VAT Prod. Posting Group"))
{
}
column(VAT_Statement_Line__VAT_Bus__Posting_Group_Caption; FieldCaption("VAT Bus. Posting Group"))
{
}
column(VAT_Statement_Line__Gen__Posting_Type_Caption; FieldCaption("Gen. Posting Type"))
{
}
column(VAT_Statement_Line__Amount_Type_Caption; FieldCaption("Amount Type"))
{
}
column(VAT_Statement_Line___Account_Totaling_Caption; VAT_Statement_Line___Account_Totaling_CaptionLbl)
{
}
column(VAT_Statement_Line_TypeCaption; FieldCaption(Type))
{
}
column(VAT_Statement_Line_DescriptionCaption; FieldCaption(Description))
{
}
column(VAT_Statement_Line__Row_No__Caption; FieldCaption("Row No."))
{
}
column(Grand_TotalCaption; Grand_TotalCaptionLbl)
{
}
dataitem("G/L Account"; "G/L Account")
{
DataItemTableView = sorting("No.") where("No." = filter(<> ''));
column(VAT_Statement_Line___Amount_Type_; Format("VAT Statement Line"."Amount Type"))
{
}
column(VAT_Statement_Line__Description; "VAT Statement Line".Description)
{
}
column(VAT_Statement_Line__Type; Format("VAT Statement Line".Type))
{
}
column(VAT_Statement_Line___Row_No__; "VAT Statement Line"."Row No.")
{
}
column(VAT_Statement_Line___Account_Totaling_; "VAT Statement Line"."Account Totaling")
{
}
column(Number; Number)
{
}
column(CountTotals; CountTotals)
{
}
column(Identifier; Identifier)
{
}
column(VAT_Statement_Line___Row_No___Control1140044; "VAT Statement Line"."Row No.")
{
}
column(VAT_Statement_Line___Amount_Type__Control1140045; "VAT Statement Line"."Amount Type")
{
}
column(VAT_Statement_Line___Account_Totaling__Control1140046; "VAT Statement Line"."Account Totaling")
{
}
column(VAT_Statement_Line__Type_Control1140047; "VAT Statement Line".Type)
{
}
column(VAT; VAT)
{
}
column(Amount1; Amount1)
{
}
column(G_L_Account_Name; Name)
{
}
column(G_L_Account__No__; "No.")
{
}
column(G_L_Account_Name_Control1140052; Name)
{
}
column(G_L_Account__No___Control1140053; "No.")
{
}
column(G_L_Account__TABLECAPTION; TableCaption)
{
}
column(Amount1_Control1140055; Amount1)
{
}
column(VAT_Control1140056; VAT)
{
}
column(VAT_Control1140058; VAT)
{
}
column(Amount1_Control1140059; Amount1)
{
}
column(TotalCaption; TotalCaptionLbl)
{
}
trigger OnAfterGetRecord()
begin
if "VAT Statement Line".Type = "VAT Statement Line".Type::"Account Totaling" then begin
CalcFields("Net Change", "Additional-Currency Net Change", "VAT Amt.");
Amount1 := ConditionalAdd("Net Change", "Additional-Currency Net Change");
VAT := ConditionalAdd("VAT Amt.", ExchangeAmtLCYtoFCY("VAT Amt."));
end else begin
VATEntry.SetRange("G/L Acc. No.", "No.");
if VATEntry.IsEmpty() then
CurrReport.Skip();
case "VAT Statement Line"."Amount Type" of
"VAT Statement Line"."Amount Type"::" ", "VAT Statement Line"."Amount Type"::Amount, "VAT Statement Line"."Amount Type"::Base:
begin
VATEntry.CalcSums(Base, "Additional-Currency Base", Amount, "Additional-Currency Amount");
Amount1 := ConditionalAdd(VATEntry.Base, VATEntry."Additional-Currency Base");
VAT := ConditionalAdd(VATEntry.Amount, VATEntry."Additional-Currency Amount");
end;
"VAT Statement Line"."Amount Type"::"Unrealized Amount", "VAT Statement Line"."Amount Type"::"Unrealized Base":
begin
VATEntry.CalcSums("Unrealized Base", "Add.-Currency Unrealized Base", "Unrealized Amount", "Add.-Currency Unrealized Amt.");
Amount1 := ConditionalAdd(VATEntry."Unrealized Base", VATEntry."Add.-Currency Unrealized Base");
VAT := ConditionalAdd(VATEntry."Unrealized Amount", VATEntry."Add.-Currency Unrealized Amt.");
end;
VATStmtLine2."Amount Type"::"Non-Deductible Base", VATStmtLine2."Amount Type"::"Non-Deductible Amount":
begin
VATEntry.CalcSums("Non-Deductible VAT Base", "Non-Deductible VAT Base ACY", "Non-Deductible VAT Amount", "Non-Deductible VAT Amount ACY");
Amount1 := ConditionalAdd(VATEntry."Non-Deductible VAT Base", VATEntry."Non-Deductible VAT Base ACY");
VAT := ConditionalAdd(VATEntry."Non-Deductible VAT Amount", VATEntry."Non-Deductible VAT Amount ACY");
end;
VATStmtLine2."Amount Type"::"Full Base", VATStmtLine2."Amount Type"::"Full Amount":
begin
VATEntry.CalcSums(
Base, "Additional-Currency Base", Amount, "Additional-Currency Amount",
"Non-Deductible VAT Base", "Non-Deductible VAT Base ACY", "Non-Deductible VAT Amount", "Non-Deductible VAT Amount ACY");
Amount1 :=
ConditionalAdd(
VATEntry.Base + VATEntry."Non-Deductible VAT Base",
VATEntry."Additional-Currency Base" + VATEntry."Non-Deductible VAT Base ACY");
VAT :=
ConditionalAdd(
VATEntry.Amount + VATEntry."Non-Deductible VAT Amount",
VATEntry."Additional-Currency Amount" + VATEntry."Non-Deductible VAT Amount ACY");
end;
end;
end;
OnBeforeCalcTotalAmount("VAT Statement Line", VATEntry, Amount1, VAT);
TotalAmount := TotalAmount + Amount1;
TotalVAT := TotalVAT + VAT;
end;
trigger OnPostDataItem()
begin
if Number > 1 then
if (Amount1 <> 0) or (VAT <> 0) then
CountTotals := CountTotals + 1;
end;
trigger OnPreDataItem()
var
VATEntryCopy: Record "VAT Entry";
begin
if "VAT Statement Line".Type = "VAT Statement Line".Type::"Account Totaling" then begin
SetFilter("No.", "VAT Statement Line"."Account Totaling");
SetRange("Date Filter", StartDate, EndDate);
Number := count();
end else begin
Number := 2;
VATEntry.SetCurrentKey("Posting Date", Type, Closed, "VAT Bus. Posting Group", "VAT Prod. Posting Group", Reversed, "G/L Acc. No.");
VATEntry.SetRange(Type, "VAT Statement Line"."Gen. Posting Type");
case Selection of
Selection::Open:
VATEntry.SetRange(Closed, false);
Selection::Closed:
VATEntry.SetRange(Closed, true);
end;
VATEntry.SetRange("VAT Bus. Posting Group", "VAT Statement Line"."VAT Bus. Posting Group");
VATEntry.SetRange("VAT Prod. Posting Group", "VAT Statement Line"."VAT Prod. Posting Group");
if (EndDateReq <> 0D) or (StartDate <> 0D) then
if PeriodSelection = PeriodSelection::"Before and Within Period" then
VATEntry.SetRange("VAT Reporting Date", 0D, EndDate)
else
VATEntry.SetRange("VAT Reporting Date", StartDate, EndDate);
VATEntry.SetRange(Reversed, false);
end;
VATEntryCopy.Copy(VATEntry);
VATEntryCopy.SetCurrentKey("Entry No.");
VATEntryCopy.SetGLAccountNoWithResponse(true, AdjustVATEntryConfirm, AdjustVATEntry);
AdjustVATEntryConfirm := false;
CheckGLAccountNoFilled(VATEntryCopy);
Identifier := Identifier + 1;
end;
}
trigger OnAfterGetRecord()
begin
if (Type = Type::"Account Totaling") and ("Account Totaling" = '') then
CurrReport.Skip();
VATStmtLine2.Get("Statement Template Name", "Statement Name", "Line No.");
VATStmtLine2.SetRange("Row No.", "Row No.");
VATStmtLine2.SetRange("Gen. Posting Type", "Gen. Posting Type");
VATStmtLine2.SetRange("VAT Bus. Posting Group", "VAT Bus. Posting Group");
VATStmtLine2.SetRange("VAT Prod. Posting Group", "VAT Prod. Posting Group");
if VATStmtLine2.Find('<') then
CurrReport.Skip();
TotalAmount := 0;
TotalVAT := 0;
CountTotals := 0;
TypeNo := Type.AsInteger();
end;
trigger OnPreDataItem()
begin
VATStmtLine2.CopyFilters("VAT Statement Line");
end;
}
trigger OnPreDataItem()
begin
if UseAmtsInAddCurr then
HeaderText := StrSubstNo(AllAmountsLbl, GLSetup."Additional Reporting Currency")
else begin
GLSetup.TestField("LCY Code");
HeaderText := StrSubstNo(AllAmountsLbl, GLSetup."LCY Code");
end;
end;
}
}
requestpage
{
AboutTitle = 'About G/L - VAT Reconciliation';
AboutText = 'The **G/L - VAT Reconciliation** report compares VAT amounts posted in the general ledger with the underlying VAT entries. Use it for validating VAT accuracy during filing periods to ensure reported amounts match transaction-level data. It helps detect discrepancies early and supports audit readiness by reconciling VAT postings with actual entries.';
SaveValues = true;
layout
{
area(content)
{
group(Options)
{
Caption = 'Options';
group("Statement Period")
{
Caption = 'Statement Period';
field(StartDate; StartDate)
{
ApplicationArea = Basic, Suite;
Caption = 'Starting Date';
ToolTip = 'Specifies the date from which the report or batch job processes information.';
}
field(EndDateReq; EndDateReq)
{
ApplicationArea = Basic, Suite;
Caption = 'Ending Date';
ToolTip = 'Specifies the last date that the report includes data for.';
}
}
field(Selection; Selection)
{
ApplicationArea = Basic, Suite;
Caption = 'Include VAT Entries by State';
ToolTip = 'Specifies if you want to include VAT entries that are open and/or closed in the report.';
}
field(PeriodSelection; PeriodSelection)
{
ApplicationArea = Basic, Suite;
Caption = 'Include VAT Entries by Period';
ToolTip = 'Specifies if you want to include VAT entries from before the specified time period in the report.';
}
field(UseAmtsInAddCurr; UseAmtsInAddCurr)
{
ApplicationArea = Basic, Suite;
Caption = 'Show Amounts in Add. Reporting Currency';
MultiLine = true;
ToolTip = 'Specifies if you want report amounts to be shown in the additional reporting currency.';
}
}
}
}
actions
{
}
}
rendering
{
layout(RDLCLayout)
{
Type = RDLC;
LayoutFile = './Finance/VAT/Reporting/GLVATReconciliation.rdlc';
Summary = 'Report layout made in the legacy RDLC format. Use an RDLC editor to modify the layout.';
}
}
labels
{
}
trigger OnPreReport()
begin
AdjustVATEntry := false;
AdjustVATEntryConfirm := true;
if EndDateReq = 0D then
EndDate := 99991231D
else
EndDate := EndDateReq;
"VAT Statement Line".SetRange("Date Filter", StartDate, EndDate);
VATStmtLineFilter := "VAT Statement Line".GetFilters();
if PeriodSelection = PeriodSelection::"Before and Within Period" then
Header := BeforeAndWithinPeriodLbl
else
Header := PeriodLbl + "VAT Statement Line".GetFilter("Date Filter");
case Selection of
Selection::Closed:
Header2 := OnlyClosedVATEntriesLbl;
Selection::"Open and Closed":
Header2 := AllVATEntriesLbl;
end;
GLSetup.Get();
if UseAmtsInAddCurr then begin
GLSetup.TestField("Additional Reporting Currency");
Currency.Get(GLSetup."Additional Reporting Currency");
CurrencyFactor := CurrencyExchRate.ExchangeRate(WorkDate(), GLSetup."Additional Reporting Currency");
end;
end;
var
VATEntry: Record "VAT Entry";
GLSetup: Record "General Ledger Setup";
VATStmtLine2: Record "VAT Statement Line";
CurrencyExchRate: Record "Currency Exchange Rate";
Currency: Record Currency;
UseAmtsInAddCurr: Boolean;
EndDate: Date;
StartDate: Date;
EndDateReq: Date;
Amount1: Decimal;
VAT: Decimal;
CurrencyFactor: Decimal;
TotalAmount: Decimal;
TotalVAT: Decimal;
CountTotals: Integer;
Number: Integer;
Selection: Enum "VAT Statement Report Selection";
PeriodSelection: Enum "VAT Statement Report Period Selection";
VATStmtLineFilter: Text;
Header: Text;
Header2: Text[50];
HeaderText: Text[50];
TypeNo: Integer;
Identifier: Integer;
AdjustVATEntry: Boolean;
AdjustVATEntryConfirm: Boolean;
NoGLAccNoOnVATEntriesErr: Label 'There is one or more VAT Entries with no G/L Account defined in the selected period. Please exclude these VAT entries or ask your partner to help you fix this data issue.';
BeforeAndWithinPeriodLbl: Label 'VAT entries before and within the period';
PeriodLbl: Label 'Period: ';
OnlyClosedVATEntriesLbl: Label 'The report includes only closed VAT entries.';
AllVATEntriesLbl: Label 'The report includes all VAT entries.';
AllAmountsLbl: Label 'All amounts are in %1', Comment = '%1 = currency';
VAT_Statement_Name__NameCaptionLbl: Label 'VAT Statement Name';
VAT_Statement_Name___Statement_Template_Name_CaptionLbl: Label 'VAT Statement Template';
CurrReport_PAGENOCaptionLbl: Label 'Page';
GL_VAT_ReconciliationCaptionLbl: Label 'G/L - VAT Reconciliation';
AmountCaptionLbl: Label 'Amount';
VATCaptionLbl: Label 'VAT';
Account_No_CaptionLbl: Label 'Account No.';
Account_TypeCaptionLbl: Label 'Account Type';
VAT_Statement_Line___Account_Totaling_CaptionLbl: Label 'Account Totaling';
Grand_TotalCaptionLbl: Label 'Grand Total';
TotalCaptionLbl: Label 'Total';
/// <summary>
/// Conditionally returns amount in either local currency or additional reporting currency.
/// Selects appropriate currency amount based on report currency display preferences.
/// </summary>
/// <param name="AmountToAdd">Amount in local currency</param>
/// <param name="AddCurrAmountToAdd">Amount in additional reporting currency</param>
/// <returns>Selected amount based on UseAmtsInAddCurr setting</returns>
procedure ConditionalAdd(AmountToAdd: Decimal; AddCurrAmountToAdd: Decimal): Decimal
begin
if UseAmtsInAddCurr then
exit(AddCurrAmountToAdd);
exit(AmountToAdd);
end;
/// <summary>
/// Converts local currency amount to foreign currency equivalent using exchange rates.
/// Applies currency conversion for additional reporting currency display purposes.
/// </summary>
/// <param name="Amount">Amount in local currency to convert</param>
/// <returns>Converted amount in foreign currency based on exchange rate settings</returns>
procedure ExchangeAmtLCYtoFCY(Amount: Decimal): Decimal
begin
if not UseAmtsInAddCurr then
exit(Amount);
exit(Round(CurrencyExchRate.ExchangeAmtLCYToFCY(WorkDate(), GLSetup."Additional Reporting Currency", Amount, CurrencyFactor), Currency."Amount Rounding Precision"));
end;
local procedure CheckGLAccountNoFilled(var VATEntry2: Record "VAT Entry")
var
VATEntryLocal: Record "VAT Entry";
begin
VATEntryLocal.Copy(VATEntry2);
VATEntryLocal.ReadIsolation := IsolationLevel::ReadCommitted;
VATEntryLocal.SetCurrentKey("G/L Acc. No.");
VATEntryLocal.SetRange("G/L Acc. No.", '');
if not VATEntryLocal.IsEmpty() then
Error(NoGLAccNoOnVATEntriesErr);
end;
/// <summary>
/// Integration event raised before calculating total amounts during G/L VAT reconciliation.
/// Enables custom calculation logic and modification of amount totals before standard processing.
/// </summary>
/// <param name="VATStmtLine">VAT statement line being reconciled</param>
/// <param name="TempVATEntryTable">Temporary VAT entry table for calculation</param>
/// <param name="Amount1">Base amount calculation, can be modified</param>
/// <param name="VAT">VAT amount calculation, can be modified</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeCalcTotalAmount(VATStmtLine: Record "VAT Statement Line"; var TempVATEntryTable: Record "VAT Entry" temporary; var Amount1: Decimal; var VAT: Decimal)
begin
end;
}