Codeunit 960 Posting Group Change
- App
- Base Application
- Namespace
- Microsoft.Finance.ReceivablesPayables
- Versions
- 22-28
Procedures, 11Events, 1Obsolete, 1
Versions171819202122232425262728
Source29
Source in 29
src/Layers/W1/BaseApp/Finance/ReceivablesPayables/PostingGroupChange.Codeunit.al248 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.ReceivablesPayables;
using Microsoft.Finance.GeneralLedger.Journal;
using Microsoft.HumanResources.Employee;
using Microsoft.HumanResources.Setup;
using Microsoft.Purchases.Document;
using Microsoft.Purchases.Setup;
using Microsoft.Purchases.Vendor;
using Microsoft.Sales.Customer;
using Microsoft.Sales.Document;
using Microsoft.Sales.FinanceCharge;
using Microsoft.Sales.Setup;
/// <summary>
/// Implements posting group change validation and processing for customer, vendor, and employee posting groups.
/// Handles validation logic when posting groups are modified in documents and journal lines.
/// </summary>
/// <remarks>
/// Core implementation of posting group change validation ensuring data integrity and proper setup requirements.
/// Validates posting group changes across sales headers, purchase headers, general journal lines, and finance charge memos.
/// Integrates with substitute posting group setup to support alternative posting group configurations.
/// Extensible through the posting group change method interface for custom validation scenarios.
/// </remarks>
codeunit 960 "Posting Group Change" implements "Posting Group Change Method"
{
var
CannotChangePostingGroupErr: Label 'You cannot change the value %1 to %2 because %3 has not been filled in.', Comment = '%1 = old posting group; %2 = new posting group; %3 = tablecaption of Subst. Vendor/Customer Posting Group';
/// <summary>
/// Changes posting group with validation based on document type and substitute posting group setup.
/// </summary>
/// <param name="NewPostingGroup">New posting group code to apply</param>
/// <param name="OldPostingGroup">Current posting group code</param>
/// <param name="SourceRecordVar">Source record variant containing the posting group field</param>
procedure ChangePostingGroup(NewPostingGroup: Code[20]; OldPostingGroup: Code[20]; SourceRecordVar: Variant)
var
SourceRecordRef: RecordRef;
begin
if OldPostingGroup = NewPostingGroup then
exit;
SourceRecordRef.GetTable(SourceRecordVar);
case SourceRecordRef.Number of
Database::"Sales Header":
CheckPostingGroupChangeInSalesHeader(NewPostingGroup, OldPostingGroup);
Database::"Purchase Header":
CheckPostingGroupChangeInPurchaseHeader(NewPostingGroup, OldPostingGroup);
Database::"Gen. Journal Line":
CheckPostingGroupChangeInGenJnlLine(NewPostingGroup, OldPostingGroup, SourceRecordVar);
Database::"Finance Charge Memo Header":
CheckPostingGroupChangeInFinChrgMemoHeader(NewPostingGroup, OldPostingGroup);
end;
OnAfterChangePostingGroup(SourceRecordRef, NewPostingGroup, OldPostingGroup);
end;
local procedure CheckPostingGroupChangeInSalesHeader(NewPostingGroup: Code[20]; OldPostingGroup: Code[20])
begin
CheckCustomerPostingGroupChange(NewPostingGroup, OldPostingGroup);
end;
local procedure CheckPostingGroupChangeInPurchaseHeader(NewPostingGroup: Code[20]; OldPostingGroup: Code[20])
begin
CheckVendorPostingGroupChange(NewPostingGroup, OldPostingGroup);
end;
local procedure CheckPostingGroupChangeInGenJnlLine(NewPostingGroup: Code[20]; OldPostingGroup: Code[20]; GenJournalLine: Record "Gen. Journal Line")
begin
case GenJournalLine."Account Type" of
GenJournalLine."Account Type"::Customer:
CheckCustomerPostingGroupChangeAndCustomer(NewPostingGroup, OldPostingGroup, GenJournalLine."Account No.");
GenJournalLine."Account Type"::Vendor:
CheckVendorPostingGroupChangeAndVendor(NewPostingGroup, OldPostingGroup, GenJournalLine."Account No.");
GenJournalLine."Account Type"::Employee:
CheckEmployeePostingGroupChangeAndEmployee(NewPostingGroup, OldPostingGroup, GenJournalLine."Account No.");
else
GenJournalLine.FieldError(GenJournalLine."Account Type");
end;
end;
local procedure CheckPostingGroupChangeInFinChrgMemoHeader(NewPostingGroup: Code[20]; OldPostingGroup: Code[20])
begin
CheckCustomerPostingGroupChange(NewPostingGroup, OldPostingGroup);
end;
local procedure CheckCustomerPostingGroupChange(NewPostingGroup: Code[20]; OldPostingGroup: Code[20])
begin
CheckCustomerPostingGroupChangeAndCustomer(NewPostingGroup, OldPostingGroup, '');
end;
local procedure CheckVendorPostingGroupChange(NewPostingGroup: Code[20]; OldPostingGroup: Code[20])
begin
CheckVendorPostingGroupChangeAndVendor(NewPostingGroup, OldPostingGroup, '');
end;
local procedure CheckCustomerPostingGroupChangeAndCustomer(NewPostingGroup: Code[20]; OldPostingGroup: Code[20]; CustomerNo: Code[20])
begin
CheckAllowChangeSalesSetup();
if not HasCustomerSamePostingGroup(NewPostingGroup, CustomerNo) then
CheckCustomerPostingGroupSubstSetup(NewPostingGroup, OldPostingGroup);
end;
local procedure CheckVendorPostingGroupChangeAndVendor(NewPostingGroup: Code[20]; OldPostingGroup: Code[20]; VendorNo: Code[20])
begin
CheckAllowChangePurchaseSetup();
if not HasVendorSamePostingGroup(NewPostingGroup, VendorNo) then
CheckVendorPostingGroupSubstSetup(NewPostingGroup, OldPostingGroup);
end;
local procedure CheckEmployeePostingGroupChangeAndEmployee(NewPostingGroup: Code[20]; OldPostingGroup: Code[20]; EmployeeNo: Code[20])
begin
CheckAllowChangeHRSetup();
if not HasEmployeeSamePostingGroup(NewPostingGroup, EmployeeNo) then
CheckEmployeePostingGroupSubstSetup(NewPostingGroup, OldPostingGroup);
end;
procedure CheckCustomerPostingGroupSubstSetup(NewPostingGroup: Code[20]; OldPostingGroup: Code[20])
var
AltCustomerPostingGroup: Record "Alt. Customer Posting Group";
begin
if not AltCustomerPostingGroup.Get(OldPostingGroup, NewPostingGroup) then
Error(CannotChangePostingGroupErr, OldPostingGroup, NewPostingGroup, AltCustomerPostingGroup.TableCaption());
end;
/// <summary>
/// Checks vendor posting group substitute setup before allowing posting group change.
/// </summary>
/// <param name="NewPostingGroup">New vendor posting group code</param>
/// <param name="OldPostingGroup">Current vendor posting group code</param>
procedure CheckVendorPostingGroupSubstSetup(NewPostingGroup: Code[20]; OldPostingGroup: Code[20])
var
AltVendorPostingGroup: Record "Alt. Vendor Posting Group";
begin
if not AltVendorPostingGroup.Get(OldPostingGroup, NewPostingGroup) then
Error(CannotChangePostingGroupErr, OldPostingGroup, NewPostingGroup, AltVendorPostingGroup.TableCaption());
end;
/// <summary>
/// Checks employee posting group substitute setup before allowing posting group change.
/// </summary>
/// <param name="NewPostingGroup">New employee posting group code</param>
/// <param name="OldPostingGroup">Current employee posting group code</param>
procedure CheckEmployeePostingGroupSubstSetup(NewPostingGroup: Code[20]; OldPostingGroup: Code[20])
var
AltEmployeePostingGroup: Record "Alt. Employee Posting Group";
begin
if not AltEmployeePostingGroup.Get(OldPostingGroup, NewPostingGroup) then
Error(CannotChangePostingGroupErr, OldPostingGroup, NewPostingGroup, AltEmployeePostingGroup.TableCaption());
end;
/// <summary>
/// Checks if sales and receivables setup allows multiple posting groups before changing customer posting groups.
/// </summary>
procedure CheckAllowChangeSalesSetup()
var
SalesReceivablesSetup: Record "Sales & Receivables Setup";
begin
SalesReceivablesSetup.Get();
SalesReceivablesSetup.TestField("Allow Multiple Posting Groups");
SalesReceivablesSetup.TestField("Check Multiple Posting Groups", "Posting Group Change Method"::"Alternative Groups");
end;
/// <summary>
/// Checks if purchases and payables setup allows multiple posting groups before changing vendor posting groups.
/// </summary>
procedure CheckAllowChangePurchaseSetup()
var
PurchasesPayablesSetup: Record "Purchases & Payables Setup";
begin
PurchasesPayablesSetup.Get();
PurchasesPayablesSetup.TestField("Allow Multiple Posting Groups");
PurchasesPayablesSetup.TestField("Check Multiple Posting Groups", "Posting Group Change Method"::"Alternative Groups");
end;
/// <summary>
/// Checks if human resources setup allows multiple posting groups before changing employee posting groups.
/// </summary>
procedure CheckAllowChangeHRSetup()
var
HumanResourcesSetup: Record "Human Resources Setup";
begin
HumanResourcesSetup.Get();
HumanResourcesSetup.TestField("Allow Multiple Posting Groups");
HumanResourcesSetup.TestField("Check Multiple Posting Groups", "Posting Group Change Method"::"Alternative Groups");
end;
/// <summary>
/// Checks if a customer already has the same posting group to avoid unnecessary validation.
/// </summary>
/// <param name="NewPostingGroup">New customer posting group code</param>
/// <param name="CustomerNo">Customer number to check</param>
/// <returns>True if customer already has the new posting group</returns>
procedure HasCustomerSamePostingGroup(NewPostingGroup: Code[20]; CustomerNo: Code[20]): Boolean
var
Customer: Record Customer;
begin
if Customer.Get(CustomerNo) then
exit(NewPostingGroup = Customer."Customer Posting Group");
exit(false);
end;
/// <summary>
/// Checks if a vendor already has the same posting group to avoid unnecessary validation.
/// </summary>
/// <param name="NewPostingGroup">New vendor posting group code</param>
/// <param name="VendorNo">Vendor number to check</param>
/// <returns>True if vendor already has the new posting group</returns>
procedure HasVendorSamePostingGroup(NewPostingGroup: Code[20]; VendorNo: Code[20]): Boolean
var
Vendor: Record Vendor;
begin
if Vendor.Get(VendorNo) then
exit(NewPostingGroup = Vendor."Vendor Posting Group");
exit(false);
end;
/// <summary>
/// Checks if an employee already has the same posting group to avoid unnecessary validation.
/// </summary>
/// <param name="NewPostingGroup">New employee posting group code</param>
/// <param name="EmployeeNo">Employee number to check</param>
/// <returns>True if employee already has the new posting group</returns>
procedure HasEmployeeSamePostingGroup(NewPostingGroup: Code[20]; EmployeeNo: Code[20]): Boolean
var
Employee: Record Employee;
begin
if Employee.Get(EmployeeNo) then
exit(NewPostingGroup = Employee."Employee Posting Group");
exit(false);
end;
/// <summary>
/// Integration event raised after changing posting group to allow custom processing.
/// </summary>
/// <param name="SourceRecordRef">Record reference of the source record with changed posting group</param>
/// <param name="NewPostingGroup">New posting group code that was applied</param>
/// <param name="OldPostingGroup">Previous posting group code</param>
[IntegrationEvent(false, false)]
local procedure OnAfterChangePostingGroup(SourceRecordRef: RecordRef; NewPostingGroup: Code[20]; OldPostingGroup: Code[20])
begin
end;
}