Table 80 Gen. Journal Template, source in 29
Source29
src/Layers/W1/BaseApp/Finance/GeneralLedger/Journal/GenJournalTemplate.Table.al615 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.Bank.BankAccount;
using Microsoft.Finance.GeneralLedger.Account;
using Microsoft.Finance.GeneralLedger.Reports;
using Microsoft.FixedAssets.FixedAsset;
using Microsoft.FixedAssets.Journal;
using Microsoft.Foundation.AuditCodes;
using Microsoft.Foundation.NoSeries;
using Microsoft.Intercompany.Journal;
using Microsoft.Intercompany.Partner;
using Microsoft.Projects.Project.Journal;
using Microsoft.Purchases.Vendor;
using Microsoft.Sales.Customer;
using System.Reflection;
using System.Security.User;
/// <summary>
/// Stores journal template definitions that control journal behavior, validation rules, and user interface features.
/// Templates provide the framework for different types of journals with specialized functionality for specific business processes.
/// </summary>
/// <remarks>
/// Templates define default settings for journal batches including source codes, number series, posting reports, and page assignments.
/// Key relationships: Used by Gen. Journal Batch for template-based configuration inheritance.
/// Extensibility: Template types can be extended to support custom journal workflows and validation requirements.
/// </remarks>
table 80 "Gen. Journal Template"
{
Caption = 'Gen. Journal Template';
LookupPageID = "General Journal Template List";
ReplicateData = true;
DataClassification = CustomerContent;
fields
{
/// <summary>
/// Unique identifier for the journal template used to reference and configure journal batches.
/// </summary>
field(1; Name; Code[10])
{
Caption = 'Name';
ToolTip = 'Specifies the name of the journal template you are creating.';
NotBlank = true;
}
/// <summary>
/// Descriptive name for the journal template providing user-friendly identification.
/// </summary>
field(2; Description; Text[80])
{
Caption = 'Description';
ToolTip = 'Specifies a brief description of the journal template you are creating.';
}
/// <summary>
/// Report ID used for testing journal lines before posting to validate transactions.
/// </summary>
field(5; "Test Report ID"; Integer)
{
Caption = 'Test Report ID';
ToolTip = 'Specifies the test report that is printed when you click Test Report.';
TableRelation = AllObjWithCaption."Object ID" where("Object Type" = const(Report));
}
/// <summary>
/// Page ID that defines the user interface for entering journal lines with this template.
/// </summary>
field(6; "Page ID"; Integer)
{
Caption = 'Page ID';
ToolTip = 'Specifies the number of the page that is used to show the journal or worksheet that uses the template.';
TableRelation = AllObjWithCaption."Object ID" where("Object Type" = const(Page));
trigger OnValidate()
begin
if "Page ID" = 0 then
Validate(Type);
end;
}
/// <summary>
/// Report ID for the posting report that prints after successful journal posting.
/// </summary>
field(7; "Posting Report ID"; Integer)
{
Caption = 'Posting Report ID';
ToolTip = 'Specifies the posting report that is printed when you choose Post and Print.';
TableRelation = AllObjWithCaption."Object ID" where("Object Type" = const(Report));
}
/// <summary>
/// Indicates whether the posting report must be printed after journal posting.
/// </summary>
field(8; "Force Posting Report"; Boolean)
{
Caption = 'Force Posting Report';
ToolTip = 'Specifies whether a report is printed automatically when you post.';
}
/// <summary>
/// Template type that determines journal behavior and specialized functionality for different business scenarios.
/// </summary>
field(9; Type; Enum "Gen. Journal Template Type")
{
Caption = 'Type';
ToolTip = 'Specifies the journal type.';
trigger OnValidate()
begin
"Test Report ID" := REPORT::"General Journal - Test";
"Posting Report ID" := REPORT::"G/L Register";
SourceCodeSetup.Get();
case Type of
Type::General:
begin
"Source Code" := SourceCodeSetup."General Journal";
"Page ID" := PAGE::"General Journal";
end;
Type::Sales:
begin
"Source Code" := SourceCodeSetup."Sales Journal";
"Page ID" := PAGE::"Sales Journal";
end;
Type::Purchases:
begin
"Source Code" := SourceCodeSetup."Purchase Journal";
"Page ID" := PAGE::"Purchase Journal";
end;
Type::"Cash Receipts":
begin
"Source Code" := SourceCodeSetup."Cash Receipt Journal";
"Page ID" := PAGE::"Cash Receipt Journal";
end;
Type::Payments:
begin
"Source Code" := SourceCodeSetup."Payment Journal";
"Page ID" := PAGE::"Payment Journal";
end;
Type::Assets:
begin
"Source Code" := SourceCodeSetup."Fixed Asset G/L Journal";
"Page ID" := PAGE::"Fixed Asset G/L Journal";
end;
Type::Intercompany:
begin
"Source Code" := SourceCodeSetup."IC General Journal";
"Page ID" := PAGE::"IC General Journal";
end;
Type::Jobs:
begin
"Source Code" := SourceCodeSetup."Job G/L Journal";
"Page ID" := PAGE::"Job G/L Journal";
end;
end;
if Recurring then
"Page ID" := PAGE::"Recurring General Journal";
OnAfterValidateType(Rec, SourceCodeSetup);
end;
}
/// <summary>
/// Source code automatically applied to all journal lines created with this template for audit tracking.
/// </summary>
field(10; "Source Code"; Code[10])
{
Caption = 'Source Code';
ToolTip = 'Specifies the source code that specifies where the entry was created.';
TableRelation = "Source Code";
trigger OnValidate()
begin
GenJnlLine.SetRange("Journal Template Name", Name);
GenJnlLine.ModifyAll("Source Code", "Source Code");
Modify();
end;
}
/// <summary>
/// Default reason code applied to journal lines created with this template for transaction classification.
/// </summary>
field(11; "Reason Code"; Code[10])
{
Caption = 'Reason Code';
ToolTip = 'Specifies the reason code, a supplementary source code that enables you to trace the entry.';
TableRelation = "Reason Code";
}
/// <summary>
/// Indicates whether this template is used for recurring journal entries with automated posting schedules.
/// </summary>
field(12; Recurring; Boolean)
{
Caption = 'Recurring';
ToolTip = 'Specifies whether the journal template will be a recurring journal.';
trigger OnValidate()
begin
Validate(Type);
if Recurring then
TestField("No. Series", '');
end;
}
/// <summary>
/// Display caption for the test report used with this journal template.
/// </summary>
field(15; "Test Report Caption"; Text[250])
{
CalcFormula = lookup(AllObjWithCaption."Object Caption" where("Object Type" = const(Report),
"Object ID" = field("Test Report ID")));
Caption = 'Test Report Caption';
ToolTip = 'Specifies the name of the test report that is printed when you print a journal under this journal template.';
Editable = false;
FieldClass = FlowField;
}
/// <summary>
/// Display caption for the page used for journal line entry with this template.
/// </summary>
field(16; "Page Caption"; Text[250])
{
CalcFormula = lookup(AllObjWithCaption."Object Caption" where("Object Type" = const(Page),
"Object ID" = field("Page ID")));
Caption = 'Page Caption';
ToolTip = 'Specifies the displayed name of the journal or worksheet that uses the template.';
Editable = false;
FieldClass = FlowField;
}
/// <summary>
/// Display caption for the posting report used with this journal template.
/// </summary>
field(17; "Posting Report Caption"; Text[250])
{
CalcFormula = lookup(AllObjWithCaption."Object Caption" where("Object Type" = const(Report),
"Object ID" = field("Posting Report ID")));
Caption = 'Posting Report Caption';
ToolTip = 'Specifies the name of the report that is printed when you print the journal.';
Editable = false;
FieldClass = FlowField;
}
/// <summary>
/// Requires journal documents to have balanced debit and credit amounts before posting.
/// </summary>
field(18; "Force Doc. Balance"; Boolean)
{
Caption = 'Force Doc. Balance';
ToolTip = 'Specifies whether transactions that are posted in the general journal must balance by document number and document type, in addition to balancing by date.';
InitValue = true;
}
/// <summary>
/// Account type for the default balancing account used in journal lines created with this template.
/// </summary>
field(19; "Bal. Account Type"; Enum "Gen. Journal Account Type")
{
Caption = 'Bal. Account Type';
ToolTip = 'Specifies the type of account that a balancing entry is posted to, such as BANK for a cash account.';
trigger OnValidate()
begin
"Bal. Account No." := '';
end;
}
/// <summary>
/// Account number for the default balancing account used in journal lines created with this template.
/// </summary>
field(20; "Bal. Account No."; Code[20])
{
Caption = 'Bal. Account No.';
ToolTip = 'Specifies the number of the general ledger, customer, vendor, or bank account that the balancing entry is posted to, such as a cash account for cash purchases.';
TableRelation = if ("Bal. Account Type" = const("G/L Account")) "G/L Account"
else
if ("Bal. Account Type" = const(Customer)) Customer
else
if ("Bal. Account Type" = const(Vendor)) Vendor
else
if ("Bal. Account Type" = const("Bank Account")) "Bank Account"
else
if ("Bal. Account Type" = const("Fixed Asset")) "Fixed Asset"
else
if ("Bal. Account Type" = const("IC Partner")) "IC Partner";
trigger OnValidate()
begin
if "Bal. Account Type" = "Bal. Account Type"::"G/L Account" then
CheckGLAcc("Bal. Account No.");
end;
}
/// <summary>
/// Number series used for automatic document number assignment in journal lines.
/// </summary>
field(21; "No. Series"; Code[20])
{
Caption = 'No. Series';
ToolTip = 'Specifies the number series from which entry or record numbers are assigned to new entries or records.';
TableRelation = "No. Series";
trigger OnValidate()
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeNoSeriesValidate(Rec, IsHandled);
if IsHandled then
exit;
if "No. Series" <> '' then begin
if Recurring then
Error(
RecurringJnlFieldErr,
FieldCaption("Posting No. Series"));
if "No. Series" = "Posting No. Series" then
"Posting No. Series" := '';
end;
end;
}
/// <summary>
/// Number series used for posted document numbers after journal posting completion.
/// </summary>
field(22; "Posting No. Series"; Code[20])
{
Caption = 'Posting No. Series';
ToolTip = 'Specifies the code for the number series that will be used to assign document numbers to ledger entries that are posted from journals using this template.';
TableRelation = "No. Series";
trigger OnValidate()
begin
if ("Posting No. Series" = "No. Series") and ("Posting No. Series" <> '') then
FieldError("Posting No. Series", StrSubstNo(ValueNotAllowedFieldErr, "Posting No. Series"));
end;
}
/// <summary>
/// Automatically copies VAT posting setup from accounts to journal lines for VAT calculation.
/// </summary>
field(23; "Copy VAT Setup to Jnl. Lines"; Boolean)
{
Caption = 'Copy VAT Setup to Jnl. Lines';
ToolTip = 'Specifies whether the program to calculate VAT for accounts and balancing accounts on the journal line of the selected journal template.';
InitValue = true;
trigger OnValidate()
begin
if "Copy VAT Setup to Jnl. Lines" <> xRec."Copy VAT Setup to Jnl. Lines" then begin
GenJnlBatch.SetRange("Journal Template Name", Name);
GenJnlBatch.ModifyAll("Copy VAT Setup to Jnl. Lines", "Copy VAT Setup to Jnl. Lines");
end;
end;
}
/// <summary>
/// Allows manual adjustment of VAT amounts in journal lines when posting with this template.
/// </summary>
field(24; "Allow VAT Difference"; Boolean)
{
Caption = 'Allow VAT Difference';
ToolTip = 'Specifies whether to allow the manual adjustment of VAT amounts in journals.';
trigger OnValidate()
begin
if "Allow VAT Difference" <> xRec."Allow VAT Difference" then begin
GenJnlBatch.SetRange("Journal Template Name", Name);
GenJnlBatch.ModifyAll("Allow VAT Difference", "Allow VAT Difference");
end;
end;
}
/// <summary>
/// Report ID for customer receipt reports generated from journal postings with this template.
/// </summary>
field(25; "Cust. Receipt Report ID"; Integer)
{
AccessByPermission = TableData Customer = R;
Caption = 'Cust. Receipt Report ID';
ToolTip = 'Specifies how to print customer receipts when you post.';
TableRelation = AllObjWithCaption."Object ID" where("Object Type" = const(Report));
}
/// <summary>
/// Display caption for the customer receipt report used with this journal template.
/// </summary>
field(26; "Cust. Receipt Report Caption"; Text[250])
{
AccessByPermission = TableData Customer = R;
CalcFormula = lookup(AllObjWithCaption."Object Caption" where("Object Type" = const(Report),
"Object ID" = field("Cust. Receipt Report ID")));
Caption = 'Cust. Receipt Report Caption';
ToolTip = 'Specifies how to print customer receipts when you post.';
Editable = false;
FieldClass = FlowField;
}
/// <summary>
/// Report ID for vendor receipt reports generated from journal postings with this template.
/// </summary>
field(27; "Vendor Receipt Report ID"; Integer)
{
AccessByPermission = TableData Vendor = R;
Caption = 'Vendor Receipt Report ID';
ToolTip = 'Specifies how to print vendor receipts when you post.';
TableRelation = AllObjWithCaption."Object ID" where("Object Type" = const(Report));
}
/// <summary>
/// Display caption for the vendor receipt report used with this journal template.
/// </summary>
field(28; "Vendor Receipt Report Caption"; Text[250])
{
AccessByPermission = TableData Vendor = R;
CalcFormula = lookup(AllObjWithCaption."Object Caption" where("Object Type" = const(Report),
"Object ID" = field("Vendor Receipt Report ID")));
Caption = 'Vendor Receipt Report Caption';
ToolTip = 'Specifies how to print vendor receipts when you post.';
Editable = false;
FieldClass = FlowField;
}
/// <summary>
/// Automatically increments batch names when creating new batches with this template.
/// </summary>
field(30; "Increment Batch Name"; Boolean)
{
Caption = 'Increment Batch Name';
ToolTip = 'Specifies if batch names using this template are automatically incremented. Example: The posting following BATCH001 is automatically named BATCH002.';
}
/// <summary>
/// Creates copies of posted journal lines in the Posted General Journal Line table for audit history.
/// </summary>
field(31; "Copy to Posted Jnl. Lines"; Boolean)
{
Caption = 'Copy to Posted Jnl. Lines';
ToolTip = 'Specifies whether the journal lines to be copied to posted journal lines of the selected journal template.';
trigger OnValidate()
begin
if "Copy to Posted Jnl. Lines" <> xRec."Copy to Posted Jnl. Lines" then begin
TestField(Recurring, false);
GenJnlBatch.SetRange("Journal Template Name", Name);
GenJnlBatch.ModifyAll("Copy to Posted Jnl. Lines", "Copy to Posted Jnl. Lines");
end;
end;
}
/// <summary>
/// Start date for allowable posting dates when using this journal template.
/// </summary>
field(32; "Allow Posting Date From"; Date)
{
Caption = 'Allow Posting Date From';
ToolTip = 'Specifies the earliest date when posting to the journal template is allowed.';
trigger OnValidate()
begin
if xRec."Allow Posting Date From" <> Rec."Allow Posting Date From" then begin
if Rec."Allow Posting Date From" <> 0D then
Evaluate(Rec."Allow Posting From DateFormula", '');
CheckDateRange();
end;
end;
}
/// <summary>
/// End date for allowable posting dates when using this journal template.
/// </summary>
field(33; "Allow Posting Date To"; Date)
{
Caption = 'Allow Posting Date To';
ToolTip = 'Specifies the last date when posting to the journal template is allowed.';
trigger OnValidate()
begin
if xRec."Allow Posting Date To" <> Rec."Allow Posting Date To" then begin
if Rec."Allow Posting Date To" <> 0D then
Evaluate(Rec."Allow Posting To DateFormula", '');
CheckDateRange();
end;
end;
}
/// <summary>
/// Automatically unlinks incoming documents from journal lines when posting for document workflow management.
/// </summary>
field(34; "Unlink Inc. Doc On Posting"; Boolean)
{
Caption = 'Unlink Incoming Documents On Posting';
ToolTip = 'Specifies whether the the incoming document will be unlinked from the journal when it is posted.';
trigger OnValidate()
begin
if "Unlink Inc. Doc On Posting" then
TestField(Recurring);
end;
}
field(35; "Allow Posting From DateFormula"; DateFormula)
{
Caption = 'Allow Posting From Date Formula';
trigger OnValidate()
begin
if xRec."Allow Posting From DateFormula" <> Rec."Allow Posting From DateFormula" then begin
if Format(Rec."Allow Posting From DateFormula") <> '' then
Rec.Validate("Allow Posting Date From", 0D);
CheckDateRange();
end;
end;
}
field(36; "Allow Posting To DateFormula"; DateFormula)
{
Caption = 'Allow Posting To Date Formula';
trigger OnValidate()
begin
if xRec."Allow Posting To DateFormula" <> Rec."Allow Posting To DateFormula" then begin
if Format(Rec."Allow Posting To DateFormula") <> '' then
Rec.Validate("Allow Posting Date To", 0D);
CheckDateRange();
end;
end;
}
}
keys
{
key(Key1; Name)
{
Clustered = true;
}
key(Key2; Type, "Bal. Account Type", "Bal. Account No.")
{
}
key(Key3; Type, Recurring, "No. Series")
{
}
}
fieldgroups
{
fieldgroup(DropDown; Name, Description, Type)
{
}
}
trigger OnDelete()
begin
GenJnlAlloc.SetRange("Journal Template Name", Name);
GenJnlAlloc.DeleteAll();
GenJnlLine.SetRange("Journal Template Name", Name);
GenJnlLine.DeleteAll(true);
GenJnlBatch.SetRange("Journal Template Name", Name);
GenJnlBatch.DeleteAll();
end;
trigger OnInsert()
begin
Validate("Page ID");
end;
var
GenJnlBatch: Record "Gen. Journal Batch";
GenJnlLine: Record "Gen. Journal Line";
GenJnlAlloc: Record "Gen. Jnl. Allocation";
SourceCodeSetup: Record "Source Code Setup";
RecurringJnlFieldErr: Label 'Only the %1 field can be filled in on recurring journals.', comment = '%1 = a field name';
ValueNotAllowedFieldErr: Label 'must not be %1', comment = '%1 = a field value';
local procedure CheckGLAcc(AccNo: Code[20])
var
GLAcc: Record "G/L Account";
begin
if AccNo <> '' then begin
GLAcc.Get(AccNo);
GLAcc.CheckGLAcc();
GLAcc.TestField("Direct Posting", true);
end;
OnAfterCheckGLAcc(Rec, GLAcc);
end;
local procedure CheckDateRange()
var
UserSetupManagement: Codeunit "User Setup Management";
AllowedFrom: Date;
AllowedTo: Date;
begin
AllowedFrom := Rec."Allow Posting Date From";
AllowedTo := Rec."Allow Posting Date To";
UserSetupManagement.GetDateRange(
AllowedFrom, AllowedTo,
Rec."Allow Posting From DateFormula", Rec."Allow Posting To DateFormula",
Rec.RecordId());
end;
/// <summary>
/// Integration event that occurs after validating the journal template type.
/// Allows customization of template behavior based on type changes and source code setup configuration.
/// </summary>
/// <param name="GenJournalTemplate">The journal template record being validated.</param>
/// <param name="SourceCodeSetup">Source code setup record containing configuration for source codes.</param>
[IntegrationEvent(false, false)]
local procedure OnAfterValidateType(var GenJournalTemplate: Record "Gen. Journal Template"; SourceCodeSetup: Record "Source Code Setup")
begin
end;
/// <summary>
/// Integration event that occurs before validating number series configuration for the journal template.
/// Allows custom handling of number series validation logic and error prevention.
/// </summary>
/// <param name="GenJournalTemplate">The journal template record with number series being validated.</param>
/// <param name="IsHandled">Set to true to skip standard validation processing.</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeNoSeriesValidate(var GenJournalTemplate: Record "Gen. Journal Template"; var IsHandled: Boolean)
begin
end;
/// <summary>
/// Integration event that occurs after checking G/L Account configuration for the journal template.
/// Allows additional validation or processing based on the associated G/L Account settings.
/// </summary>
/// <param name="GenJournalTemplate">The journal template record being checked.</param>
/// <param name="GLAccount">The G/L Account record associated with the template for validation.</param>
[IntegrationEvent(false, false)]
local procedure OnAfterCheckGLAcc(var GenJournalTemplate: Record "Gen. Journal Template"; GLAccount: Record "G/L Account")
begin
end;
}