Report 596 Exch. Rate Adjustment
- App
- Base Application
- Namespace
- Microsoft.Finance.Currency
- Versions
- 20-28
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Finance/Currency/ExchRateAdjustment.Report.al475 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.Currency;
using Microsoft.Bank.BankAccount;
using Microsoft.Finance.GeneralLedger.Journal;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Foundation.NoSeries;
using Microsoft.HumanResources.Employee;
using Microsoft.Purchases.Vendor;
using Microsoft.Sales.Customer;
/// <summary>
/// Report for performing comprehensive exchange rate adjustments across multiple account types.
/// Processes currency revaluation for customer, vendor, employee, bank account, and G/L account balances
/// to reflect current exchange rates and ensure accurate financial reporting.
/// </summary>
/// <remarks>
/// Integrates with Exchange Rate Adjustment Process codeunit for calculation logic.
/// Supports filtering by currency, account types, and date ranges. Creates journal entries
/// for posting adjustment amounts and maintains audit trail through register tables.
/// </remarks>
report 596 "Exch. Rate Adjustment"
{
ApplicationArea = Basic, Suite;
Caption = 'Exchange Rates Adjustment';
ProcessingOnly = true;
UsageCategory = Tasks;
dataset
{
dataitem(CurrencyFilter; Currency)
{
DataItemTableView = sorting(Code);
RequestFilterFields = "Code";
dataitem(BankAccountFilter; "Bank Account")
{
DataItemLink = "Currency Code" = field(Code);
RequestFilterFields = "No.";
}
}
dataitem(CustomerFilter; Customer)
{
DataItemTableView = sorting("No.");
RequestFilterFields = "No.";
trigger OnPreDataItem()
begin
if not AdjCust then
CurrReport.Break();
end;
}
dataitem(VendorFilter; Vendor)
{
DataItemTableView = sorting("No.");
RequestFilterFields = "No.";
trigger OnPreDataItem()
begin
if not AdjVend then
CurrReport.Break();
end;
}
dataitem(EmployeeFilter; Employee)
{
DataItemTableView = sorting("No.");
RequestFilterFields = "No.";
trigger OnPreDataItem()
begin
if not AdjEmpl then
CurrReport.Break();
end;
}
}
requestpage
{
SaveValues = true;
layout
{
area(content)
{
group(Options)
{
Caption = 'Options';
group("Adjustment Period")
{
Caption = 'Adjustment Period';
field(StartingDate; StartDate)
{
ApplicationArea = Basic, Suite;
Caption = 'Starting Date';
ToolTip = 'Specifies the beginning of the period for which entries are adjusted. This field is usually left blank, but you can enter a date.';
}
field(EndingDate; EndDateReq)
{
ApplicationArea = Basic, Suite;
Caption = 'Ending Date';
ToolTip = 'Specifies the last date for which entries are adjusted. This date is usually the same as the posting date in the Posting Date field.';
trigger OnValidate()
begin
PostingDate := EndDateReq;
end;
}
}
field(PostingDescriptionReq; PostingDescription)
{
ApplicationArea = Basic, Suite;
Caption = 'Posting Description';
ToolTip = 'Specifies text for the general ledger entries that are created by the batch job. The default text is Exchange Rate Adjmt. of %1 %2, in which %1 is replaced by the currency code and %2 is replaced by the currency amount that is adjusted. For example, Exchange Rate Adjmt. of DEM 38,000.';
}
field(PostingDateReq; PostingDate)
{
ApplicationArea = Basic, Suite;
Caption = 'Posting Date';
ToolTip = 'Specifies the date on which the general ledger entries are posted. This date is usually the same as the ending date in the Ending Date field.';
trigger OnValidate()
begin
CheckPostingDate();
end;
}
field(DocumentNo; PostingDocNo)
{
ApplicationArea = Basic, Suite;
Caption = 'Document No.';
ToolTip = 'Specifies the document number that will appear on the general ledger entries that are created by the batch job.';
Visible = not IsJournalTemplNameVisible;
}
field(JournalTemplateName; GenJournalLineReq."Journal Template Name")
{
ApplicationArea = Basic, Suite;
Caption = 'Journal Template Name';
TableRelation = "Gen. Journal Template";
ToolTip = 'Specifies the name of the journal template that is used for the posting.';
Visible = IsJournalTemplNameVisible;
trigger OnValidate()
begin
GenJournalLineReq."Journal Batch Name" := '';
end;
}
field(JournalBatchName; GenJournalLineReq."Journal Batch Name")
{
ApplicationArea = Basic, Suite;
Caption = 'Journal Batch Name';
Lookup = true;
ToolTip = 'Specifies the name of the journal batch that is used for the posting.';
Visible = IsJournalTemplNameVisible;
trigger OnLookup(var Text: Text): Boolean
var
GenJnlManagement: Codeunit GenJnlManagement;
begin
GenJnlManagement.SetJnlBatchName(GenJournalLineReq);
if GenJournalLineReq."Journal Batch Name" <> '' then
GenJournalBatch.Get(GenJournalLineReq."Journal Template Name", GenJournalLineReq."Journal Batch Name");
end;
trigger OnValidate()
begin
if GenJournalLineReq."Journal Batch Name" <> '' then begin
GenJournalLineReq.TestField("Journal Template Name");
GenJournalBatch.Get(GenJournalLineReq."Journal Template Name", GenJournalLineReq."Journal Batch Name");
end;
end;
}
field(AdjCustAcc; AdjCust)
{
ApplicationArea = Basic, Suite;
Caption = 'Adjust Customers';
ToolTip = 'Specifies if you want to adjust customers for currency fluctuations.';
}
field(AdjVendAcc; AdjVend)
{
ApplicationArea = Basic, Suite;
Caption = 'Adjust Vendors';
ToolTip = 'Specifies if you want to adjust vendors for currency fluctuations.';
}
field(AdjEmplAcc; AdjEmpl)
{
ApplicationArea = Basic, Suite;
Caption = 'Adjust Employees';
ToolTip = 'Specifies if you want to adjust employees for currency fluctuations.';
}
field(AdjBankAcc; AdjBank)
{
ApplicationArea = Basic, Suite;
Caption = 'Adjust Bank Accounts';
ToolTip = 'Specifies if you want to adjust bank accounts for currency fluctuations.';
}
field(AdjGLAccount; AdjGLAcc)
{
ApplicationArea = Suite;
Caption = 'Adjust G/L Accounts for Add.-Reporting Currency';
ToolTip = 'Specifies if you want to post in an additional reporting currency and adjust general ledger accounts for currency fluctuations between LCY and the additional reporting currency.';
}
field(AdjustPerEntry; AdjPerEntry)
{
ApplicationArea = Suite;
Caption = 'Adjust per entry';
Tooltip = 'Specifies if adjustment should be posted per each customer or vendor ledger entry with currency fluctuations.';
}
field(PreviewPost; PreviewPosting)
{
ApplicationArea = Basic, Suite;
Caption = 'Preview Posting';
ToolTip = 'Specifies if you want to preview posting for currency fluctuations.';
}
field(DimensionPost; DimensionPosting)
{
ApplicationArea = Basic, Suite;
Caption = 'Dimension Posting';
ToolTip = 'Specifies how you want to move dimensions to posted ledger entries.';
}
}
}
}
actions
{
}
trigger OnOpenPage()
begin
OnBeforeOpenPage(AdjCust, AdjVend, AdjEmpl, AdjBank, AdjGLAcc, PostingDocNo);
if PostingDescription = '' then
PostingDescription := AdjustmentDescriptionTxt;
if not (AdjCust or AdjVend or AdjEmpl or AdjBank or AdjGLAcc) then begin
AdjCust := true;
AdjVend := true;
AdjEmpl := true;
AdjBank := true;
end;
GeneralLedgerSetup.Get();
IsJournalTemplNameVisible := GeneralLedgerSetup."Journal Templ. Name Mandatory";
end;
}
labels
{
}
trigger OnInitReport()
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeOnInitReport(IsHandled);
if IsHandled then
exit;
end;
trigger OnPreReport()
var
NoSeries: Codeunit "No. Series";
begin
GeneralLedgerSetup.Get();
if EndDateReq = 0D then
EndDate := DMY2Date(31, 12, 9999)
else
EndDate := EndDateReq;
GeneralLedgerSetup.Get();
if GeneralLedgerSetup."Journal Templ. Name Mandatory" then begin
if GenJournalLineReq."Journal Template Name" = '' then
Error(MustBeEnteredErr, GenJournalLineReq.FieldCaption("Journal Template Name"));
if GenJournalLineReq."Journal Batch Name" = '' then
Error(MustBeEnteredErr, GenJournalLineReq.FieldCaption("Journal Batch Name"));
Clear(PostingDocNo);
GenJournalBatch.Get(GenJournalLineReq."Journal Template Name", GenJournalLineReq."Journal Batch Name");
GenJournalBatch.TestField("No. Series");
if not PreviewPosting then
PostingDocNo := NoSeries.GetNextNo(GenJournalBatch."No. Series", PostingDate);
end else
if (PostingDocNo = '') and (not PreviewPosting) then
Error(MustBeEnteredErr, GenJournalLineReq.FieldCaption("Document No."));
if PreviewPosting then
PostingDocNo := '***';
if (not AdjCust) and (not AdjVend) and (not AdjBank) and (not AdjEmpl) and AdjGLAcc then
if not Confirm(ConfirmationTxt + ContinueTxt, false) then
Error(AdjustmentCancelledErr);
if AdjGLAcc then
CheckAmountRoundingPrecision();
if (not AdjCust) and (not AdjVend) and (not AdjBank) and (not AdjEmpl) and (not AdjGLAcc) then
exit;
RunAdjustmentProcess();
end;
var
GenJournalBatch: Record "Gen. Journal Batch";
GenJournalLineReq: Record "Gen. Journal Line";
GeneralLedgerSetup: Record "General Ledger Setup";
PostingDate: Date;
PostingDescription: Text[100];
PostingDocNo: Code[20];
StartDate: Date;
EndDate: Date;
EndDateReq: Date;
HideUI: Boolean;
IsJournalTemplNameVisible: Boolean;
MustBeEnteredErr: Label '%1 must be entered.', Comment = '%1 = field name';
ConfirmationTxt: Label 'Do you want to adjust general ledger entries for currency fluctuations without adjusting customer, vendor and bank ledger entries? This may result in incorrect currency adjustments to payables, receivables and bank accounts.\\ ';
ContinueTxt: Label 'Do you wish to continue?';
AdjustmentCancelledErr: Label 'The adjustment of exchange rates has been canceled.';
AdjustmentDescriptionTxt: Label 'Adjmt. of %1 %2, Ex.Rate Adjust.', Comment = '%1 = Currency Code, %2= Adjust Amount';
FilterIsTooComplexErr: Label '%1 filter is too complex', Comment = '%1 - table caption';
PostingDateNotInPeriodErr: Label 'This posting date cannot be entered because it does not occur within the adjustment period. Reenter the posting date.';
RoundingPrecisionDiffersQst: Label 'The Amount Rounding Precision in General Ledger Setup (%1) differs from the Amount Rounding Precision on the additional reporting currency (%2). This may cause rounding differences during exchange rate adjustment.\\Do you want to continue?', Comment = '%1 = Amount Rounding Precision in General Ledger Setup, %2 = Amount Rounding Precision on the additional reporting currency';
protected var
ExchRateAdjmtParameters: Record "Exch. Rate Adjmt. Parameters";
DimensionPosting: Enum "Exch. Rate Adjmt. Dimensions";
AdjCust: Boolean;
AdjVend: Boolean;
AdjEmpl: Boolean;
AdjBank: Boolean;
AdjGLAcc: Boolean;
AdjPerEntry: Boolean;
PreviewPosting: Boolean;
local procedure RunAdjustmentProcess()
var
ExchRateAdjmtProcess: Codeunit "Exch. Rate Adjmt. Process";
begin
Clear(ExchRateAdjmtProcess);
CopyParameters(ExchRateAdjmtParameters);
if StrLen(CurrencyFilter.GetView()) > MaxStrLen(ExchRateAdjmtParameters."Currency Filter") then
Error(FilterIsTooComplexErr, CurrencyFilter.TableCaption());
ExchRateAdjmtParameters."Currency Filter" :=
CopyStr(CurrencyFilter.GetView(), 1, MaxStrLen(ExchRateAdjmtParameters."Currency Filter"));
if StrLen(BankAccountFilter.GetView()) > MaxStrLen(ExchRateAdjmtParameters."Bank Account Filter") then
Error(FilterIsTooComplexErr, BankAccountFilter.TableCaption());
ExchRateAdjmtParameters."Bank Account Filter" :=
CopyStr(BankAccountFilter.GetView(), 1, MaxStrLen(ExchRateAdjmtParameters."Bank Account Filter"));
if StrLen(CustomerFilter.GetView()) > MaxStrLen(ExchRateAdjmtParameters."Customer Filter") then
Error(FilterIsTooComplexErr, CustomerFilter.TableCaption());
ExchRateAdjmtParameters."Customer Filter" :=
CopyStr(CustomerFilter.GetView(), 1, MaxStrLen(ExchRateAdjmtParameters."Customer Filter"));
if StrLen(VendorFilter.GetView()) > MaxStrLen(ExchRateAdjmtParameters."Vendor Filter") then
Error(FilterIsTooComplexErr, VendorFilter.TableCaption());
ExchRateAdjmtParameters."Vendor Filter" :=
CopyStr(VendorFilter.GetView(), 1, MaxStrLen(ExchRateAdjmtParameters."Vendor Filter"));
ExchRateAdjmtParameters."Employee Filter" :=
CopyStr(EmployeeFilter.GetView(), 1, MaxStrLen(ExchRateAdjmtParameters."Employee Filter"));
if PreviewPosting then
ExchRateAdjmtProcess.Preview(ExchRateAdjmtParameters)
else
ExchRateAdjmtProcess.Run(ExchRateAdjmtParameters);
end;
procedure InitializeRequest(NewStartDate: Date; NewEndDate: Date; NewPostingDescription: Text[100]; NewPostingDate: Date)
begin
StartDate := NewStartDate;
EndDate := NewEndDate;
PostingDescription := NewPostingDescription;
PostingDate := NewPostingDate;
if EndDate = 0D then
EndDateReq := DMY2Date(31, 12, 9999)
else
EndDateReq := EndDate;
end;
procedure InitializeRequest2(NewStartDate: Date; NewEndDate: Date; NewPostingDescription: Text[100]; NewPostingDate: Date; NewPostingDocNo: Code[20]; NewAdjCustVendEmplBank: Boolean; NewAdjGLAcc: Boolean)
begin
InitializeRequest(NewStartDate, NewEndDate, NewPostingDescription, NewPostingDate);
PostingDocNo := NewPostingDocNo;
AdjBank := NewAdjCustVendEmplBank;
AdjCust := NewAdjCustVendEmplBank;
AdjVend := NewAdjCustVendEmplBank;
AdjEmpl := NewAdjCustVendEmplBank;
AdjGLAcc := NewAdjGLAcc;
PreviewPosting := false;
end;
local procedure CopyParameters(var ExchRateAdjmtParameters2: Record "Exch. Rate Adjmt. Parameters" temporary)
begin
ExchRateAdjmtParameters2."Start Date" := StartDate;
ExchRateAdjmtParameters2."End Date" := EndDate;
ExchRateAdjmtParameters2."Posting Date" := PostingDate;
ExchRateAdjmtParameters2."Posting Description" := PostingDescription;
ExchRateAdjmtParameters2."Document No." := PostingDocNo;
ExchRateAdjmtParameters2."Adjust Bank Accounts" := AdjBank;
ExchRateAdjmtParameters2."Adjust Customers" := AdjCust;
ExchRateAdjmtParameters2."Adjust Vendors" := AdjVend;
ExchRateAdjmtParameters2."Adjust Employees" := AdjEmpl;
ExchRateAdjmtParameters2."Adjust G/L Accounts" := AdjGLAcc;
ExchRateAdjmtParameters2."Adjust Per Entry" := AdjPerEntry;
ExchRateAdjmtParameters2."Hide UI" := HideUI;
ExchRateAdjmtParameters2."Preview Posting" := PreviewPosting;
ExchRateAdjmtParameters2."Dimension Posting" := DimensionPosting;
if GeneralLedgerSetup."Journal Templ. Name Mandatory" then begin
ExchRateAdjmtParameters2."Journal Template Name" := GenJournalBatch."Journal Template Name";
ExchRateAdjmtParameters2."Journal Batch Name" := GenJournalBatch.Name;
end;
OnAfterCopyParameters(ExchRateAdjmtParameters2);
end;
procedure SetGenJnlBatch(NewGenJournalBatch: Record "Gen. Journal Batch")
begin
GenJournalBatch := NewGenJournalBatch;
end;
procedure SetPreviewMode(NewPreviewPosting: Boolean)
begin
PreviewPosting := NewPreviewPosting;
end;
procedure SetHideUI(NewHideUI: Boolean)
begin
HideUI := NewHideUI;
end;
procedure CheckPostingDate()
begin
if PostingDate < StartDate then
Error(PostingDateNotInPeriodErr);
if PostingDate > EndDateReq then
Error(PostingDateNotInPeriodErr);
end;
local procedure CheckAmountRoundingPrecision()
var
AddRepCurrency: Record Currency;
begin
if GeneralLedgerSetup."Additional Reporting Currency" = '' then
exit;
if not AddRepCurrency.Get(GeneralLedgerSetup."Additional Reporting Currency") then
exit;
if GeneralLedgerSetup."Amount Rounding Precision" = AddRepCurrency."Amount Rounding Precision" then
exit;
if not HideUI then
if not Confirm(RoundingPrecisionDiffersQst, false,
GeneralLedgerSetup."Amount Rounding Precision",
AddRepCurrency."Amount Rounding Precision")
then
Error(AdjustmentCancelledErr);
end;
[IntegrationEvent(true, false)]
local procedure OnAfterCopyParameters(var ExchRateAdjmtParameters2: Record "Exch. Rate Adjmt. Parameters" temporary)
begin
end;
[IntegrationEvent(true, false)]
local procedure OnBeforeOnInitReport(var IsHandled: Boolean)
begin
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeOpenPage(var AdjCust: Boolean; var AdjVend: Boolean; var AdjEmpl: Boolean; AdjBank: Boolean; var AdjGLAcc: Boolean; var PostingDocNo: Code[20])
begin
end;
}