Table 221 Gen. Jnl. Allocation
- App
- Base Application
- Namespace
- Microsoft.Finance.GeneralLedger.Journal
- Versions
- 17-28
Fields, 25Keys, 1Procedures, 14Events, 19Obsolete, 3
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJnlAllocation.Table.al1027 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.Journal;
using Microsoft.Finance.AllocationAccount;
using Microsoft.Finance.Currency;
using Microsoft.Finance.Dimension;
using Microsoft.Finance.GeneralLedger.Account;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Finance.SalesTax;
using Microsoft.Finance.VAT.Setup;
using Microsoft.Foundation.Enums;
using System.Utilities;
/// <summary>
/// Table for storing allocation lines that distribute general journal line amounts across multiple G/L accounts.
/// Enables splitting journal line amounts using percentages, amounts, or quantities for cost allocation and distribution.
/// </summary>
/// <remarks>
/// Core allocation functionality for general journal lines enabling multi-account distribution.
/// Supports percentage-based, amount-based, and quantity-based allocation methods.
/// Key fields: Account No., Allocation %, Amount, VAT handling for proper tax distribution.
/// Integration: Links to parent journal line via template, batch, and line number references.
/// </remarks>
table 221 "Gen. Jnl. Allocation"
{
Caption = 'Gen. Jnl. Allocation';
Permissions = tabledata "Gen. Jnl. Allocation" = R;
DataClassification = CustomerContent;
fields
{
/// <summary>
/// Journal template name that defines the type and behavior of the journal containing this allocation line.
/// </summary>
field(1; "Journal Template Name"; Code[10])
{
Caption = 'Journal Template Name';
TableRelation = "Gen. Journal Template";
}
/// <summary>
/// Journal batch name that groups related journal lines for this allocation.
/// </summary>
field(2; "Journal Batch Name"; Code[10])
{
Caption = 'Journal Batch Name';
TableRelation = "Gen. Journal Batch".Name where("Journal Template Name" = field("Journal Template Name"));
}
/// <summary>
/// Line number of the parent general journal line to which this allocation applies.
/// </summary>
field(3; "Journal Line No."; Integer)
{
Caption = 'Journal Line No.';
TableRelation = "Gen. Journal Line"."Line No." where("Journal Template Name" = field("Journal Template Name"),
"Journal Batch Name" = field("Journal Batch Name"));
}
/// <summary>
/// Sequential line number for this allocation entry within the parent journal line.
/// </summary>
field(4; "Line No."; Integer)
{
Caption = 'Line No.';
}
/// <summary>
/// G/L account number to which the allocated amount will be posted.
/// </summary>
field(5; "Account No."; Code[20])
{
Caption = 'Account No.';
ToolTip = 'Specifies the account number that the allocation will be posted to.';
TableRelation = "G/L Account";
trigger OnValidate()
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeValidateAccountNo(Rec, xRec, IsHandled);
if IsHandled then
exit;
if "Account No." = '' then begin
GLAcc.Init();
CreateDimFromDefaultDim();
end else begin
GLAcc.Get("Account No.");
GLAcc.CheckGLAcc();
CheckGLAccount(GLAcc);
end;
"Account Name" := GLAcc.Name;
if CopyVATSetupToJnlLines() then begin
"Gen. Posting Type" := GLAcc."Gen. Posting Type";
"Gen. Bus. Posting Group" := GLAcc."Gen. Bus. Posting Group";
"Gen. Prod. Posting Group" := GLAcc."Gen. Prod. Posting Group";
"VAT Bus. Posting Group" := GLAcc."VAT Bus. Posting Group";
"VAT Prod. Posting Group" := GLAcc."VAT Prod. Posting Group";
Validate("VAT Prod. Posting Group");
end;
CreateDimFromDefaultDim();
end;
}
/// <summary>
/// First shortcut dimension code for this allocation line, typically used for department or project classification.
/// </summary>
field(6; "Shortcut Dimension 1 Code"; Code[20])
{
CaptionClass = '1,2,1';
Caption = 'Shortcut Dimension 1 Code';
ToolTip = 'Specifies the code for Shortcut Dimension 1, which is one of two global dimension codes that you set up in the General Ledger Setup window.';
TableRelation = "Dimension Value".Code where("Global Dimension No." = const(1),
Blocked = const(false));
trigger OnValidate()
begin
Rec.ValidateShortcutDimCode(1, "Shortcut Dimension 1 Code");
Modify();
end;
}
/// <summary>
/// Second shortcut dimension code for this allocation line, typically used for cost center or area classification.
/// </summary>
field(7; "Shortcut Dimension 2 Code"; Code[20])
{
CaptionClass = '1,2,2';
Caption = 'Shortcut Dimension 2 Code';
ToolTip = 'Specifies the code for Shortcut Dimension 2, which is one of two global dimension codes that you set up in the General Ledger Setup window.';
TableRelation = "Dimension Value".Code where("Global Dimension No." = const(2),
Blocked = const(false));
trigger OnValidate()
begin
Rec.ValidateShortcutDimCode(2, "Shortcut Dimension 2 Code");
Modify();
end;
}
/// <summary>
/// Allocation quantity used for quantity-based distribution of journal line amounts.
/// When specified, amounts are distributed proportionally based on quantities rather than percentages.
/// </summary>
field(8; "Allocation Quantity"; Decimal)
{
Caption = 'Allocation Quantity';
ToolTip = 'Specifies the quantity that will be used to calculate the amount in the allocation journal line.';
DecimalPlaces = 0 : 5;
AutoFormatType = 0;
trigger OnValidate()
begin
if "Allocation Quantity" = 0 then begin
"Allocation %" := 0;
Amount := 0;
end;
UpdateAllocations(GenJnlLine);
GenJnlLine.UpdateLineBalance();
end;
}
/// <summary>
/// Percentage of the parent journal line amount to allocate to this account.
/// Used for percentage-based distribution where total percentages across allocation lines should equal 100%.
/// </summary>
field(9; "Allocation %"; Decimal)
{
Caption = 'Allocation %';
ToolTip = 'Specifies the percentage that will be used to calculate the amount in the allocation journal line.';
DecimalPlaces = 2 : 2;
AutoFormatType = 0;
trigger OnValidate()
begin
"Allocation Quantity" := 0;
if "Allocation %" = 0 then
Amount := 0;
UpdateAllocations(GenJnlLine);
GenJnlLine.UpdateLineBalance();
end;
}
/// <summary>
/// Fixed allocation amount to be posted to this account.
/// Used for amount-based distribution where specific amounts are allocated rather than percentages or quantities.
/// </summary>
field(10; Amount; Decimal)
{
AutoFormatExpression = GetCurrencyCode();
AutoFormatType = 1;
Caption = 'Amount';
ToolTip = 'Specifies the amount that will be posted from the allocation journal line.';
trigger OnValidate()
begin
if ("Allocation Quantity" <> 0) or ("Allocation %" <> 0) then begin
"Allocation Quantity" := 0;
"Allocation %" := 0;
UpdateAllocations(GenJnlLine);
end else begin
Validate("VAT Prod. Posting Group");
Modify();
GenJnlLine.UpdateLineBalance();
UpdateJnlBalance(GenJnlLine);
end;
end;
}
/// <summary>
/// General posting type that determines how this allocation line affects general ledger posting.
/// Controls whether the allocation creates purchase, sale, or other general ledger entries.
/// </summary>
field(11; "Gen. Posting Type"; Enum "General Posting Type")
{
Caption = 'Gen. Posting Type';
ToolTip = 'Specifies the type of transaction.';
trigger OnValidate()
begin
Validate("VAT Prod. Posting Group");
end;
}
/// <summary>
/// General business posting group used for determining posting accounts and VAT treatment for this allocation line.
/// Links to general posting setup for proper account determination during posting.
/// </summary>
field(12; "Gen. Bus. Posting Group"; Code[20])
{
Caption = 'Gen. Bus. Posting Group';
ToolTip = 'Specifies the vendor''s or customer''s trade type to link transactions made for this business partner with the appropriate general ledger account according to the general posting setup.';
TableRelation = "Gen. Business Posting Group";
trigger OnValidate()
begin
if xRec."Gen. Bus. Posting Group" <> "Gen. Bus. Posting Group" then
if GenBusPostingGrp.ValidateVatBusPostingGroup(GenBusPostingGrp, "Gen. Bus. Posting Group") then
Validate("VAT Bus. Posting Group", GenBusPostingGrp."Def. VAT Bus. Posting Group");
end;
}
/// <summary>
/// General product posting group used for determining posting accounts and VAT treatment for this allocation line.
/// Links to general posting setup for proper account determination during posting.
/// </summary>
field(13; "Gen. Prod. Posting Group"; Code[20])
{
Caption = 'Gen. Prod. Posting Group';
ToolTip = 'Specifies the item''s product type to link transactions made for this item with the appropriate general ledger account according to the general posting setup.';
TableRelation = "Gen. Product Posting Group";
trigger OnValidate()
begin
if xRec."Gen. Prod. Posting Group" <> "Gen. Prod. Posting Group" then
if GenProdPostingGrp.ValidateVatProdPostingGroup(GenProdPostingGrp, "Gen. Prod. Posting Group") then
Validate("VAT Prod. Posting Group", GenProdPostingGrp."Def. VAT Prod. Posting Group");
end;
}
/// <summary>
/// VAT calculation method used for this allocation line to determine VAT amount computation.
/// </summary>
field(14; "VAT Calculation Type"; Enum "Tax Calculation Type")
{
Caption = 'VAT Calculation Type';
Editable = false;
}
/// <summary>
/// VAT amount calculated for this allocation line based on the allocation amount and VAT percentage.
/// </summary>
field(15; "VAT Amount"; Decimal)
{
AutoFormatExpression = GetCurrencyCode();
AutoFormatType = 1;
Caption = 'VAT Amount';
Editable = false;
}
/// <summary>
/// VAT percentage rate applied to this allocation line for VAT amount calculation.
/// </summary>
field(16; "VAT %"; Decimal)
{
Caption = 'VAT %';
DecimalPlaces = 0 : 5;
Editable = false;
MaxValue = 100;
MinValue = 0;
AutoFormatType = 0;
}
/// <summary>
/// Name of the G/L account specified for this allocation line, automatically populated when Account No. is selected.
/// </summary>
field(17; "Account Name"; Text[100])
{
CalcFormula = lookup("G/L Account".Name where("No." = field("Account No.")));
Caption = 'Account Name';
ToolTip = 'Specifies the name of the account that the allocation will be posted to.';
Editable = false;
FieldClass = FlowField;
}
/// <summary>
/// Tax area code for sales tax calculation when tax functionality is enabled for this allocation line.
/// </summary>
field(18; "Tax Area Code"; Code[20])
{
Caption = 'Tax Area Code';
TableRelation = "Tax Area";
trigger OnValidate()
begin
Validate("VAT Prod. Posting Group");
end;
}
/// <summary>
/// Indicates whether this allocation line is subject to sales tax liability when tax functionality is enabled.
/// </summary>
field(19; "Tax Liable"; Boolean)
{
Caption = 'Tax Liable';
trigger OnValidate()
begin
Validate("VAT Prod. Posting Group");
end;
}
/// <summary>
/// Tax group code for sales tax calculation when tax functionality is enabled for this allocation line.
/// </summary>
field(20; "Tax Group Code"; Code[20])
{
Caption = 'Tax Group Code';
TableRelation = "Tax Group";
trigger OnValidate()
begin
Validate("VAT Prod. Posting Group");
end;
}
/// <summary>
/// Indicates whether this allocation line uses reverse charge VAT (use tax) when tax functionality is enabled.
/// </summary>
field(21; "Use Tax"; Boolean)
{
Caption = 'Use Tax';
trigger OnValidate()
begin
Validate("VAT Prod. Posting Group");
end;
}
/// <summary>
/// VAT business posting group code for VAT calculation setup applicable to this allocation line.
/// </summary>
field(22; "VAT Bus. Posting Group"; Code[20])
{
Caption = 'VAT Bus. Posting Group';
ToolTip = 'Specifies the VAT specification of the involved customer or vendor to link transactions made for this record with the appropriate general ledger account according to the VAT posting setup.';
TableRelation = "VAT Business Posting Group";
trigger OnValidate()
begin
Validate("VAT Prod. Posting Group");
end;
}
/// <summary>
/// VAT product posting group code for VAT calculation setup applicable to this allocation line.
/// </summary>
field(23; "VAT Prod. Posting Group"; Code[20])
{
Caption = 'VAT Prod. Posting Group';
ToolTip = 'Specifies the VAT specification of the involved item or resource to link transactions made for this record with the appropriate general ledger account according to the VAT posting setup.';
TableRelation = "VAT Product Posting Group";
trigger OnValidate()
begin
GenJnlLine.Get("Journal Template Name", "Journal Batch Name", "Journal Line No.");
CheckVAT(GenJnlLine);
UpdateVAT(GenJnlLine);
end;
}
/// <summary>
/// Allocation amount expressed in the additional reporting currency when ACY functionality is enabled.
/// </summary>
field(24; "Additional-Currency Amount"; Decimal)
{
AutoFormatType = 1;
Caption = 'Additional-Currency Amount';
Editable = false;
AutoFormatExpression = GetAdditionalReportingCurrencyCode();
}
/// <summary>
/// Unique identifier for the dimension set associated with this allocation line for financial analysis and reporting.
/// </summary>
field(480; "Dimension Set ID"; Integer)
{
Caption = 'Dimension Set ID';
Editable = false;
TableRelation = "Dimension Set Entry";
trigger OnLookup()
begin
Rec.ShowDimensions();
end;
trigger OnValidate()
begin
DimMgt.UpdateGlobalDimFromDimSetID("Dimension Set ID", "Shortcut Dimension 1 Code", "Shortcut Dimension 2 Code");
end;
}
}
keys
{
key(Key1; "Journal Template Name", "Journal Batch Name", "Journal Line No.", "Line No.")
{
Clustered = true;
}
}
fieldgroups
{
}
trigger OnDelete()
begin
Validate(Amount, 0);
end;
trigger OnInsert()
begin
LockTable();
GenJnlLine.Get("Journal Template Name", "Journal Batch Name", "Journal Line No.");
Rec.ValidateShortcutDimCode(1, "Shortcut Dimension 1 Code");
Rec.ValidateShortcutDimCode(2, "Shortcut Dimension 2 Code");
end;
var
GLAcc: Record "G/L Account";
GenJnlLine: Record "Gen. Journal Line";
GenBusPostingGrp: Record "Gen. Business Posting Group";
GenProdPostingGrp: Record "Gen. Product Posting Group";
DimMgt: Codeunit DimensionManagement;
AllocAccountImportWrongAccTypeErr: Label 'Import from Allocation Account is only allowed for G/L Account Destination account type.';
ImportDeletesExistingLinesQst: Label 'Importing from Allocation Account will delete all existing allocations. Do you want to continue?';
#pragma warning disable AA0074
#pragma warning disable AA0470
Text000: Label '%1 cannot be used in allocations when they are completed on the general journal line.';
#pragma warning restore AA0470
#pragma warning restore AA0074
protected procedure CopyVATSetupToJnlLines(): Boolean
var
GenJournalBatch: Record "Gen. Journal Batch";
begin
if ("Journal Template Name" <> '') and ("Journal Batch Name" <> '') then
if GenJournalBatch.Get(Rec."Journal Template Name", Rec."Journal Batch Name") then
exit(GenJournalBatch."Copy VAT Setup to Jnl. Lines");
exit(true);
end;
/// <summary>
/// Updates allocation amounts and distributions for all allocation lines associated with the specified journal line.
/// Recalculates allocation percentages and amounts to ensure total allocation equals journal line amount.
/// </summary>
/// <param name="GenJnlLine">General journal line record for which allocations should be updated.</param>
procedure UpdateAllocations(var GenJnlLine: Record "Gen. Journal Line")
var
GenJnlAlloc: Record "Gen. Jnl. Allocation";
GenJnlAlloc2: Record "Gen. Jnl. Allocation";
FromAllocations: Boolean;
TotalQty: Decimal;
TotalPct: Decimal;
TotalPctRnded: Decimal;
TotalAmountLCY: Decimal;
TotalAmountLCY2: Decimal;
TotalAmountLCYRnded: Decimal;
TotalAmountLCYRnded2: Decimal;
UpdateGenJnlLine: Boolean;
begin
TotalQty := 0;
TotalPct := 0;
TotalPctRnded := 0;
TotalAmountLCYRnded := 0;
TotalAmountLCYRnded2 := 0;
if "Line No." <> 0 then begin
FromAllocations := true;
GenJnlAlloc.UpdateVAT(GenJnlLine);
Modify();
GenJnlLine.Get("Journal Template Name", "Journal Batch Name", "Journal Line No.");
CheckVAT(GenJnlLine);
end;
GenJnlAlloc.SetRange("Journal Template Name", GenJnlLine."Journal Template Name");
GenJnlAlloc.SetRange("Journal Batch Name", GenJnlLine."Journal Batch Name");
GenJnlAlloc.SetRange("Journal Line No.", GenJnlLine."Line No.");
if FromAllocations then
UpdateGenJnlLine := true
else
if not GenJnlAlloc.IsEmpty() then begin
GenJnlAlloc.LockTable();
UpdateGenJnlLine := true;
end;
if GenJnlAlloc.FindSet() then
repeat
if (GenJnlAlloc."Allocation Quantity" <> 0) or (GenJnlAlloc."Allocation %" <> 0) then begin
if not FromAllocations then
GenJnlAlloc.CheckVAT(GenJnlLine);
if GenJnlAlloc."Allocation Quantity" = 0 then begin
TotalAmountLCY2 := TotalAmountLCY2 - GenJnlLine."Amount (LCY)" * GenJnlAlloc."Allocation %" / 100;
GenJnlAlloc.Amount := Round(TotalAmountLCY2) - TotalAmountLCYRnded2;
TotalAmountLCYRnded2 := TotalAmountLCYRnded2 + GenJnlAlloc.Amount;
end else begin
if TotalQty = 0 then begin
GenJnlAlloc2.Copy(GenJnlAlloc);
GenJnlAlloc2.SetFilter("Allocation Quantity", '<>0');
GenJnlAlloc2.CalcSums("Allocation Quantity");
TotalQty := GenJnlAlloc2."Allocation Quantity";
if TotalQty = 0 then
TotalQty := 1;
end;
TotalPct := TotalPct + GenJnlAlloc."Allocation Quantity" / TotalQty * 100;
GenJnlAlloc."Allocation %" := Round(TotalPct, 0.01) - TotalPctRnded;
TotalPctRnded := TotalPctRnded + GenJnlAlloc."Allocation %";
TotalAmountLCY := TotalAmountLCY - GenJnlLine."Amount (LCY)" * GenJnlAlloc."Allocation Quantity" / TotalQty;
GenJnlAlloc.Amount := Round(TotalAmountLCY) - TotalAmountLCYRnded;
TotalAmountLCYRnded := TotalAmountLCYRnded + GenJnlAlloc.Amount;
end;
GenJnlAlloc.UpdateVAT(GenJnlLine);
OnUpdateAllocationsOnBeforeGenJnlAllocModify(GenJnlLine, GenJnlAlloc);
GenJnlAlloc.Modify();
OnUpdateAllocationsOnAfterGenJnlAllocModify(GenJnlAlloc);
end;
until GenJnlAlloc.Next() = 0;
if UpdateGenJnlLine then
UpdateJnlBalance(GenJnlLine);
if FromAllocations then
Find();
end;
/// <summary>
/// Updates allocation amounts in additional reporting currency for all allocation lines associated with the specified journal line.
/// Converts allocation amounts to additional currency using current exchange rates.
/// </summary>
/// <param name="GenJnlLine">General journal line record for which additional currency allocations should be updated.</param>
/// <param name="AddCurrAmount">Total additional currency amount to distribute across allocation lines.</param>
procedure UpdateAllocationsAddCurr(var GenJnlLine: Record "Gen. Journal Line"; AddCurrAmount: Decimal)
var
GenJnlAlloc: Record "Gen. Jnl. Allocation";
GenJnlAlloc2: Record "Gen. Jnl. Allocation";
GLSetup: Record "General Ledger Setup";
Currency: Record Currency;
TotalQty: Decimal;
TotalPct: Decimal;
TotalPctRnded: Decimal;
TotalAmountAddCurr: Decimal;
TotalAmountAddCurr2: Decimal;
TotalAmountAddCurrRnded: Decimal;
TotalAmountAddCurrRnded2: Decimal;
begin
TotalQty := 0;
TotalPct := 0;
TotalPctRnded := 0;
TotalAmountAddCurr := 0;
TotalAmountAddCurr2 := 0;
TotalAmountAddCurrRnded := 0;
TotalAmountAddCurrRnded2 := 0;
GenJnlAlloc.SetRange("Journal Template Name", GenJnlLine."Journal Template Name");
GenJnlAlloc.SetRange("Journal Batch Name", GenJnlLine."Journal Batch Name");
GenJnlAlloc.SetRange("Journal Line No.", GenJnlLine."Line No.");
GenJnlAlloc.LockTable();
if GenJnlAlloc.FindSet() then begin
GLSetup.Get();
Currency.Get(GLSetup."Additional Reporting Currency");
Currency.TestField("Amount Rounding Precision");
repeat
if (GenJnlAlloc."Allocation Quantity" <> 0) or (GenJnlAlloc."Allocation %" <> 0) then begin
if GenJnlAlloc."Allocation Quantity" = 0 then begin
TotalAmountAddCurr2 :=
TotalAmountAddCurr2 - AddCurrAmount * GenJnlAlloc."Allocation %" / 100;
GenJnlAlloc."Additional-Currency Amount" :=
Round(TotalAmountAddCurr2, Currency."Amount Rounding Precision") -
TotalAmountAddCurrRnded2;
TotalAmountAddCurrRnded2 :=
TotalAmountAddCurrRnded2 + GenJnlAlloc."Additional-Currency Amount";
end else begin
if TotalQty = 0 then begin
GenJnlAlloc2.Copy(GenJnlAlloc);
GenJnlAlloc2.SetFilter("Allocation Quantity", '<>0');
repeat
TotalQty := TotalQty + GenJnlAlloc2."Allocation Quantity";
until GenJnlAlloc2.Next() = 0;
if TotalQty = 0 then
TotalQty := 1;
end;
TotalPct := TotalPct + GenJnlAlloc."Allocation Quantity" / TotalQty * 100;
GenJnlAlloc."Allocation %" := Round(TotalPct, 0.01) - TotalPctRnded;
TotalPctRnded := TotalPctRnded + GenJnlAlloc."Allocation %";
TotalAmountAddCurr :=
TotalAmountAddCurr -
AddCurrAmount * GenJnlAlloc."Allocation Quantity" / TotalQty;
GenJnlAlloc."Additional-Currency Amount" :=
Round(TotalAmountAddCurr, Currency."Amount Rounding Precision") -
TotalAmountAddCurrRnded;
TotalAmountAddCurrRnded :=
TotalAmountAddCurrRnded + GenJnlAlloc."Additional-Currency Amount";
end;
GenJnlAlloc.Modify();
OnUpdateAllocationsAddCurrOnAfterGenJnlAllocModify(GenJnlAlloc);
end;
until GenJnlAlloc.Next() = 0;
end;
end;
local procedure UpdateJnlBalance(var GenJnlLine: Record "Gen. Journal Line")
begin
GenJnlLine.CalcFields("Allocated Amt. (LCY)");
if GenJnlLine."Bal. Account No." = '' then
GenJnlLine."Balance (LCY)" := GenJnlLine."Amount (LCY)" + GenJnlLine."Allocated Amt. (LCY)"
else
GenJnlLine."Balance (LCY)" := GenJnlLine."Allocated Amt. (LCY)";
GenJnlLine.Modify();
end;
/// <summary>
/// Validates VAT setup and calculations for this allocation line based on the associated journal line context.
/// Ensures VAT posting groups and calculation types are compatible with journal line requirements.
/// </summary>
/// <param name="GenJnlLine">General journal line record providing VAT validation context for this allocation.</param>
procedure CheckVAT(var GenJnlLine: Record "Gen. Journal Line")
begin
if ("Gen. Posting Type" <> "Gen. Posting Type"::" ") and (GenJnlLine."Gen. Posting Type" <> GenJnlLine."Gen. Posting Type"::" ") then
Error(
Text000,
GenJnlLine.FieldCaption("Gen. Posting Type"));
end;
/// <summary>
/// Updates VAT amounts and percentages for this allocation line based on current VAT setup and allocation amount.
/// Calculates VAT amount using VAT posting group configuration and allocation base amount.
/// </summary>
/// <param name="GenJnlLine">General journal line record providing VAT calculation context for this allocation.</param>
procedure UpdateVAT(var GenJnlLine: Record "Gen. Journal Line")
var
GenJnlLine2: Record "Gen. Journal Line";
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeUpdateVAT(GenJnlLine, IsHandled, Rec);
if not IsHandled then begin
GenJnlLine2.CopyFromGenJnlAllocation(Rec);
GenJnlLine2."Posting Date" := GenJnlLine."Posting Date";
GenJnlLine2.Validate("VAT Prod. Posting Group");
Amount := GenJnlLine2."Amount (LCY)";
"VAT Calculation Type" := GenJnlLine2."VAT Calculation Type";
"VAT Amount" := GenJnlLine2."VAT Amount";
"VAT %" := GenJnlLine2."VAT %";
end;
OnAfterUpdateVAT(GenJnlLine, GenJnlLine2, Rec);
end;
/// <summary>
/// Retrieves the currency code applicable to this allocation line based on the associated journal line.
/// Returns the journal line's currency code or LCY if no specific currency is defined.
/// </summary>
/// <returns>Currency code for this allocation line's amounts and VAT calculations.</returns>
procedure GetCurrencyCode(): Code[10]
var
GenJnlLine3: Record "Gen. Journal Line";
begin
GenJnlLine3.SetRange("Journal Template Name", "Journal Template Name");
GenJnlLine3.SetRange("Journal Batch Name", "Journal Batch Name");
GenJnlLine3.SetRange("Line No.", "Journal Line No.");
if GenJnlLine3.FindFirst() then
exit(GenJnlLine3."Currency Code");
exit('');
end;
local procedure GetAdditionalReportingCurrencyCode(): Code[10]
var
GLSetup: Record "General Ledger Setup";
begin
if GLSetup.Get() then
exit(GLSetup."Additional Reporting Currency");
exit('');
end;
/// <summary>
/// Creates dimension set for this allocation line from the specified default dimension sources.
/// Builds dimension combinations for financial analysis and reporting requirements.
/// </summary>
/// <param name="DefaultDimSource">List of default dimension sources to use for dimension set creation.</param>
procedure CreateDim(DefaultDimSource: List of [Dictionary of [Integer, Code[20]]])
var
IsHandled: Boolean;
OldDimSetID: Integer;
begin
IsHandled := false;
OnBeforeCreateDim(Rec, IsHandled);
if IsHandled then
exit;
"Shortcut Dimension 1 Code" := '';
"Shortcut Dimension 2 Code" := '';
OldDimSetID := Rec."Dimension Set ID";
"Dimension Set ID" :=
DimMgt.GetRecDefaultDimID(Rec, CurrFieldNo, DefaultDimSource, '', "Shortcut Dimension 1 Code", "Shortcut Dimension 2 Code", 0, 0);
OnAfterCreateDimProcedure(Rec, CurrFieldNo, DefaultDimSource, xRec, OldDimSetID);
end;
/// <summary>
/// Validates shortcut dimension code for the specified dimension and updates the allocation line's dimension set.
/// Ensures dimension values are valid and updates the dimension set ID accordingly.
/// </summary>
/// <param name="FieldNumber">Field number indicating which shortcut dimension is being validated.</param>
/// <param name="ShortcutDimCode">Shortcut dimension code value to validate and assign.</param>
procedure ValidateShortcutDimCode(FieldNumber: Integer; var ShortcutDimCode: Code[20])
begin
OnBeforeValidateShortcutDimCode(Rec, xRec, FieldNumber, ShortcutDimCode);
DimMgt.ValidateShortcutDimValues(FieldNumber, ShortcutDimCode, "Dimension Set ID");
OnAfterValidateShortcutDimCode(Rec, xRec, FieldNumber, ShortcutDimCode);
end;
/// <summary>
/// Opens lookup for shortcut dimension code selection and updates the allocation line's dimension set.
/// Provides user interface for selecting valid dimension values for the specified dimension.
/// </summary>
/// <param name="FieldNumber">Field number indicating which shortcut dimension lookup should be opened.</param>
/// <param name="ShortcutDimCode">Current shortcut dimension code value, updated with user selection.</param>
procedure LookupShortcutDimCode(FieldNumber: Integer; var ShortcutDimCode: Code[20])
begin
DimMgt.LookupDimValueCode(FieldNumber, ShortcutDimCode);
DimMgt.ValidateShortcutDimValues(FieldNumber, ShortcutDimCode, "Dimension Set ID");
end;
/// <summary>
/// Retrieves and displays shortcut dimension codes for this allocation line in the provided array.
/// Populates shortcut dimension code array with current dimension values for display purposes.
/// </summary>
/// <param name="ShortcutDimCode">Array to populate with current shortcut dimension codes from this allocation.</param>
procedure ShowShortcutDimCode(var ShortcutDimCode: array[8] of Code[20])
begin
DimMgt.GetShortcutDimensions(Rec."Dimension Set ID", ShortcutDimCode);
end;
/// <summary>
/// Opens the dimensions page to display and allow editing of all dimensions for this allocation line.
/// Provides comprehensive dimension management interface for detailed financial analysis setup.
/// </summary>
procedure ShowDimensions()
begin
"Dimension Set ID" :=
DimMgt.EditDimensionSet(Rec, "Dimension Set ID",
StrSubstNo('%1 %2 %3', "Journal Template Name", "Journal Batch Name", "Journal Line No."),
"Shortcut Dimension 1 Code", "Shortcut Dimension 2 Code");
OnAfterShowDimensions(Rec, xRec);
end;
/// <summary>
/// Creates dimension set for this allocation line from default dimension setup for the G/L account.
/// Automatically applies standard dimension configuration based on account and posting group defaults.
/// </summary>
procedure CreateDimFromDefaultDim()
var
DefaultDimSource: List of [Dictionary of [Integer, Code[20]]];
begin
InitDefaultDimensionSources(DefaultDimSource);
CreateDim(DefaultDimSource);
end;
local procedure InitDefaultDimensionSources(var DefaultDimSource: List of [Dictionary of [Integer, Code[20]]])
begin
DimMgt.AddDimSource(DefaultDimSource, Database::"G/L Account", Rec."Account No.");
OnAfterInitDefaultDimensionSources(Rec, DefaultDimSource);
end;
internal procedure ChooseAndImportFromAllocationAccount()
var
AllocationAccount: Record "Allocation Account";
begin
if ChooseAllocationAccount(AllocationAccount) then
ImportFromAllocationAccount(AllocationAccount);
end;
local procedure ChooseAllocationAccount(var AllocationAccount: Record "Allocation Account") AccountChosen: Boolean
var
AllocationAccountList: Page "Allocation Account List";
begin
AllocationAccount.SetRange("Account Type", AllocationAccount."Account Type"::Fixed);
AllocationAccountList.SetTableView(AllocationAccount);
AllocationAccountList.LookupMode(true);
if AllocationAccountList.RunModal() = Action::LookupOK then begin
AccountChosen := true;
AllocationAccountList.GetRecord(AllocationAccount);
end;
end;
local procedure ImportFromAllocationAccount(AllocationAccount: Record "Allocation Account")
var
AllocAccountDistribution: Record "Alloc. Account Distribution";
ConfirmManagement: Codeunit "Confirm Management";
NextLineNo: Integer;
begin
if not Rec.IsEmpty() then
if not ConfirmManagement.GetResponse(ImportDeletesExistingLinesQst) then
exit;
Rec.DeleteAll();
AllocationAccount.TestField("Account Type", AllocationAccount."Account Type"::Fixed);
AllocAccountDistribution.SetRange("Allocation Account No.", AllocationAccount."No.");
NextLineNo := 10000;
CheckAccountType(AllocAccountDistribution);
if AllocAccountDistribution.FindSet() then
repeat
Rec.Init();
Rec."Line No." := NextLineNo;
Rec.Insert();
NextLineNo += 10000;
CopyFieldsFromAllocationAccountDistribution(AllocAccountDistribution);
until AllocAccountDistribution.Next() = 0;
end;
local procedure CheckAccountType(var AllocAccountDistribution: Record "Alloc. Account Distribution")
begin
AllocAccountDistribution.SetFilter("Destination Account Type", '<>%1', AllocAccountDistribution."Destination Account Type"::"G/L Account");
if not AllocAccountDistribution.IsEmpty() then
Error(AllocAccountImportWrongAccTypeErr);
AllocAccountDistribution.SetRange("Destination Account Type");
end;
local procedure CopyFieldsFromAllocationAccountDistribution(AllocAccountDistribution: Record "Alloc. Account Distribution")
begin
Rec.Validate("Account No.", AllocAccountDistribution."Destination Account Number");
Rec.Validate("Allocation %", AllocAccountDistribution.Percent);
Rec.Validate("Shortcut Dimension 1 Code", AllocAccountDistribution."Global Dimension 1 Code");
Rec.Validate("Shortcut Dimension 2 Code", AllocAccountDistribution."Global Dimension 2 Code");
Rec.Validate("Dimension Set ID", AllocAccountDistribution."Dimension Set ID");
Rec.Modify(true);
end;
local procedure CheckGLAccount(var GLAccount: Record "G/L Account")
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeCheckGLAccount(GLAccount, IsHandled, Rec);
if IsHandled then
exit;
GLAccount.TestField("Direct Posting", true);
OnAfterCheckGLAccount(GLAccount, Rec);
end;
/// <summary>
/// Integration event raised after initializing default dimension sources for allocation line dimension creation.
/// Enables custom modification of dimension sources before dimension set creation for allocation lines.
/// </summary>
/// <param name="GenJnlAllocation">General journal allocation record for which dimension sources are being initialized.</param>
/// <param name="DefaultDimSource">List of default dimension sources that can be modified for custom dimension logic.</param>
[IntegrationEvent(false, false)]
local procedure OnAfterInitDefaultDimensionSources(var GenJnlAllocation: Record "Gen. Jnl. Allocation"; var DefaultDimSource: List of [Dictionary of [Integer, Code[20]]])
begin
end;
/// <summary>
/// Integration event raised before creating dimension set for allocation line.
/// Enables custom logic to completely override standard dimension creation processing for allocations.
/// </summary>
/// <param name="GenJnlAllocation">General journal allocation record for which dimensions are being created.</param>
/// <param name="IsHandled">Set to true to skip standard dimension creation logic.</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeCreateDim(var GenJnlAllocation: Record "Gen. Jnl. Allocation"; var IsHandled: Boolean);
begin
end;
/// <summary>
/// Integration event raised after completing dimension creation procedure for allocation line.
/// Enables custom processing and validation after standard dimension set creation is completed.
/// </summary>
/// <param name="GenJnlAllocation">General journal allocation record for which dimensions were created.</param>
/// <param name="CurrFieldNo">Field number that triggered the dimension creation process.</param>
/// <param name="DefaultDimSource">List of default dimension sources used in dimension creation.</param>
/// <param name="xGenJnlAllocation">Previous version of allocation record before dimension changes.</param>
/// <param name="OldDimSetID">Previous dimension set ID before changes were applied.</param>
[IntegrationEvent(false, false)]
local procedure OnAfterCreateDimProcedure(var GenJnlAllocation: Record "Gen. Jnl. Allocation"; CurrFieldNo: Integer; DefaultDimSource: List of [Dictionary of [Integer, Code[20]]]; xGenJnlAllocation: Record "Gen. Jnl. Allocation"; OldDimSetID: Integer);
begin
end;
/// <summary>
/// Integration event raised after displaying dimensions page for allocation line.
/// Enables custom processing after user interaction with allocation line dimensions.
/// </summary>
/// <param name="GenJnlAllocation">General journal allocation record for which dimensions were displayed.</param>
/// <param name="xGenJnlAllocation">Previous version of allocation record before dimension display interaction.</param>
[IntegrationEvent(false, false)]
local procedure OnAfterShowDimensions(var GenJnlAllocation: Record "Gen. Jnl. Allocation"; xGenJnlAllocation: Record "Gen. Jnl. Allocation")
begin
end;
/// <summary>
/// Integration event raised after validating shortcut dimension code for allocation line.
/// Enables custom processing after shortcut dimension validation and dimension set updates.
/// </summary>
/// <param name="GenJnlAllocation">General journal allocation record for which shortcut dimension was validated.</param>
/// <param name="xGenJnlAllocation">Previous version of allocation record before shortcut dimension validation.</param>
/// <param name="FieldNumber">Field number indicating which shortcut dimension was validated.</param>
/// <param name="ShortcutDimCode">Shortcut dimension code value that was validated and applied.</param>
[IntegrationEvent(false, false)]
local procedure OnAfterValidateShortcutDimCode(var GenJnlAllocation: Record "Gen. Jnl. Allocation"; var xGenJnlAllocation: Record "Gen. Jnl. Allocation"; FieldNumber: Integer; var ShortcutDimCode: Code[20])
begin
end;
/// <summary>
/// Integration event raised before validating shortcut dimension code for allocation line.
/// Enables custom logic to override standard shortcut dimension validation processing.
/// </summary>
/// <param name="GenJnlAllocation">General journal allocation record for which shortcut dimension is being validated.</param>
/// <param name="xGenJnlAllocation">Previous version of allocation record before shortcut dimension validation.</param>
/// <param name="FieldNumber">Field number indicating which shortcut dimension is being validated.</param>
/// <param name="ShortcutDimCode">Shortcut dimension code value being validated (can be modified).</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeValidateShortcutDimCode(var GenJnlAllocation: Record "Gen. Jnl. Allocation"; var xGenJnlAllocation: Record "Gen. Jnl. Allocation"; FieldNumber: Integer; var ShortcutDimCode: Code[20])
begin
end;
/// <summary>
/// Integration event that occurs after modifying a general journal allocation line during update process.
/// Allows customization of allocation line processing after standard modification logic.
/// </summary>
/// <param name="GenJnlAlloc">The general journal allocation record that was modified.</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateAllocationsOnAfterGenJnlAllocModify(var GenJnlAlloc: Record "Gen. Jnl. Allocation")
begin
end;
/// <summary>
/// Integration event that occurs before modifying a general journal allocation line during update process.
/// Allows customization of allocation line values before standard modification logic.
/// </summary>
/// <param name="GenJournalLine">The source general journal line being processed.</param>
/// <param name="GenJnlAlloc">The general journal allocation record being modified.</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateAllocationsOnBeforeGenJnlAllocModify(GenJournalLine: Record "Gen. Journal Line"; var GenJnlAlloc: Record "Gen. Jnl. Allocation")
begin
end;
/// <summary>
/// Integration event raised after modifying allocation line during additional currency allocation updates.
/// Enables custom processing after allocation line changes during ACY amount distribution.
/// </summary>
/// <param name="GenJnlAlloc">General journal allocation record that was modified during ACY update process.</param>
[IntegrationEvent(false, false)]
local procedure OnUpdateAllocationsAddCurrOnAfterGenJnlAllocModify(var GenJnlAlloc: Record "Gen. Jnl. Allocation")
begin
end;
/// <summary>
/// Integration event raised before validating G/L account setup for allocation line.
/// Enables custom logic to override standard G/L account validation processing for allocations.
/// </summary>
/// <param name="GLAccount">G/L Account record being validated for allocation line usage.</param>
/// <param name="IsHandled">Set to true to skip standard G/L account validation logic.</param>
/// <param name="GenJnlAllocation">General journal allocation record providing context for G/L account validation.</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeCheckGLAccount(GLAccount: Record "G/L Account"; var IsHandled: Boolean; var GenJnlAllocation: Record "Gen. Jnl. Allocation");
begin
end;
/// <summary>
/// Integration event raised after validating G/L account setup for allocation line.
/// Enables custom processing and validation after standard G/L account checks are completed.
/// </summary>
/// <param name="GLAccount">G/L Account record that was validated for allocation line usage.</param>
/// <param name="GenJnlAllocation">General journal allocation record providing context for G/L account validation.</param>
[IntegrationEvent(false, false)]
local procedure OnAfterCheckGLAccount(var GLAccount: Record "G/L Account"; GenJnlAllocation: Record "Gen. Jnl. Allocation")
begin
end;
/// <summary>
/// Integration event raised before updating VAT amounts for allocation line.
/// Enables custom logic to completely override standard VAT update processing for allocations.
/// </summary>
/// <param name="GenJournalLine">General journal line record providing VAT update context.</param>
/// <param name="IsHandled">Set to true to skip standard VAT update logic.</param>
/// <param name="GenJnlAllocation">General journal allocation record for which VAT is being updated.</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeUpdateVAT(var GenJournalLine: Record "Gen. Journal Line"; var IsHandled: Boolean; var GenJnlAllocation: Record "Gen. Jnl. Allocation")
begin
end;
/// <summary>
/// Integration event raised after updating VAT amounts for allocation line.
/// Enables custom processing after standard VAT calculation and update is completed.
/// </summary>
/// <param name="GenJournalLine">General journal line record that provided VAT update context.</param>
/// <param name="GenJournalLine2">Additional journal line record used during VAT update process.</param>
/// <param name="GenJnlAllocation">General journal allocation record for which VAT was updated.</param>
[IntegrationEvent(false, false)]
local procedure OnAfterUpdateVAT(var GenJournalLine: Record "Gen. Journal Line"; GenJournalLine2: Record "Gen. Journal Line"; var GenJnlAllocation: Record "Gen. Jnl. Allocation")
begin
end;
/// <summary>
/// Integration event raised before validating account number for allocation line.
/// Enables custom logic to completely override standard account number validation processing.
/// </summary>
/// <param name="GenJnlAllocation">General journal allocation record for which account number is being validated.</param>
/// <param name="xGenJnlAllocation">Previous version of allocation record before account number validation.</param>
/// <param name="IsHandled">Set to true to skip standard account number validation logic.</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeValidateAccountNo(var GenJnlAllocation: Record "Gen. Jnl. Allocation"; xGenJnlAllocation: Record "Gen. Jnl. Allocation"; var IsHandled: Boolean)
begin
end;
}