Codeunit 1660 Payroll Management, source in 29
Source29
src/Layers/W1/BaseApp/Finance/Payroll/PayrollManagement.Codeunit.al170 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.Payroll;
using Microsoft.Finance.GeneralLedger.Journal;
using Microsoft.Utilities;
using System.Environment;
using System.Environment.Configuration;
using System.Security.AccessControl;
/// <summary>
/// Manages payroll service registration, selection, and import orchestration.
/// Provides centralized payroll service management with guided setup support.
/// </summary>
/// <remarks>
/// Integrates with Service Connections for payroll service discovery and management.
/// Extensibility: OnRegisterPayrollService, OnImportPayroll events for custom payroll providers.
/// </remarks>
codeunit 1660 "Payroll Management"
{
Permissions = TableData User = rimd;
trigger OnRun()
begin
end;
var
PayrollServiceNotFoundErr: Label 'A payroll service could not be found.';
PayrollServiceDisabledErr: Label 'Payroll service %1 is disabled.', Comment = '%1 Payroll Service Name';
SelectPayrollServiceToUseTxt: Label 'Several payroll services are installed and enabled. Select a service you want to use.';
SelectPayrollServiceToEnableTxt: Label 'Select a payroll service you want to enable and use.';
EnablePayrollServicesQst: Label 'All payroll services are disabled. Do you want to enable a payroll service?';
/// <summary>
/// Determines payroll visibility based on environment type for testing purposes.
/// </summary>
/// <returns>True if payroll should be visible in current environment</returns>
procedure ShowPayrollForTestInNonSaas(): Boolean
var
EnvironmentInfo: Codeunit "Environment Information";
begin
if EnvironmentInfo.IsSaaS() then
exit(true);
exit(false);
end;
/// <summary>
/// Initiates payroll import process with service discovery and selection.
/// Handles service registration, enablement, and import orchestration.
/// </summary>
/// <param name="GenJournalLine">Target journal line for payroll data import</param>
procedure ImportPayroll(var GenJournalLine: Record "Gen. Journal Line")
var
TempServiceConnection: Record "Service Connection" temporary;
begin
TempServiceConnection.DeleteAll();
OnRegisterPayrollService(TempServiceConnection);
if TempServiceConnection.IsEmpty() then
Error(PayrollServiceNotFoundErr);
if not EnabledPayrollServiceExists(TempServiceConnection) then
if Confirm(EnablePayrollServicesQst) then
EnablePayrollService(TempServiceConnection)
else
exit;
if EnabledPayrollServiceExists(TempServiceConnection) then
if SelectPayrollService(TempServiceConnection, SelectPayrollServiceToUseTxt) then
OnImportPayroll(TempServiceConnection, GenJournalLine);
end;
local procedure EnabledPayrollServiceExists(var TempServiceConnection: Record "Service Connection" temporary): Boolean
begin
TempServiceConnection.SetFilter(
Status, StrSubstNo('%1|%2', TempServiceConnection.Status::Enabled, TempServiceConnection.Status::Connected));
exit(TempServiceConnection.FindSet());
end;
local procedure EnablePayrollService(var TempServiceConnection: Record "Service Connection" temporary)
var
SelectedServiceRecordId: RecordID;
SelectedServiceName: Text;
begin
TempServiceConnection.Reset();
if SelectPayrollService(TempServiceConnection, SelectPayrollServiceToEnableTxt) then begin
SelectedServiceRecordId := TempServiceConnection."Record ID";
SelectedServiceName := TempServiceConnection.Name;
SetupPayrollService(TempServiceConnection);
TempServiceConnection.DeleteAll();
OnRegisterPayrollService(TempServiceConnection);
if not TempServiceConnection.IsEmpty() then begin
TempServiceConnection.SetRange("Record ID", SelectedServiceRecordId);
if not EnabledPayrollServiceExists(TempServiceConnection) then
Error(PayrollServiceDisabledErr, SelectedServiceName);
end else
Error(PayrollServiceNotFoundErr);
end;
end;
local procedure SelectPayrollService(var TempServiceConnection: Record "Service Connection" temporary; Instruction: Text): Boolean
var
ServiceList: Text;
SelectedServiceIndex: Integer;
begin
if TempServiceConnection.Count < 2 then
exit(TempServiceConnection.FindFirst());
TempServiceConnection.SetCurrentKey(Name);
TempServiceConnection.SetAscending(Name, true);
TempServiceConnection.FindFirst();
repeat
if ServiceList = '' then
ServiceList := ConvertStr(TempServiceConnection.Name, ',', ' ')
else
ServiceList := ServiceList + ',' + ConvertStr(TempServiceConnection.Name, ',', ' ');
until TempServiceConnection.Next() = 0;
SelectedServiceIndex := StrMenu(ServiceList, 1, Instruction);
if SelectedServiceIndex > 0 then begin
TempServiceConnection.FindFirst();
if SelectedServiceIndex > 1 then
TempServiceConnection.Next(SelectedServiceIndex - 1);
end;
exit(SelectedServiceIndex > 0);
end;
local procedure SetupPayrollService(var TempServiceConnection: Record "Service Connection" temporary)
var
GuidedExperience: Codeunit "Guided Experience";
RecordRef: RecordRef;
RecordRefVariant: Variant;
GuidedExperienceType: Enum "Guided Experience Type";
begin
RecordRef.Get(TempServiceConnection."Record ID");
if (TempServiceConnection.Status <> TempServiceConnection.Status::Enabled) and
(TempServiceConnection.Status <> TempServiceConnection.Status::Connected) and
(TempServiceConnection."Assisted Setup Page ID" <> 0) and
(GuidedExperience.AssistedSetupExistsAndIsNotComplete(ObjectType::Page, TempServiceConnection."Assisted Setup Page ID"))
then
GuidedExperience.Run(GuidedExperienceType::"Assisted Setup", ObjectType::Page, TempServiceConnection."Assisted Setup Page ID")
else begin
RecordRefVariant := RecordRef;
PAGE.RunModal(TempServiceConnection."Page ID", RecordRefVariant);
end;
end;
/// <summary>
/// Allows payroll service providers to register their services for discovery.
/// </summary>
/// <param name="TempServiceConnection">Service connection record for registration</param>
[IntegrationEvent(false, false)]
procedure OnRegisterPayrollService(var TempServiceConnection: Record "Service Connection" temporary)
begin
end;
/// <summary>
/// Enables payroll service providers to implement custom import logic.
/// </summary>
/// <param name="TempServiceConnection">Selected service connection for import</param>
/// <param name="GenJournalLine">Target journal line for imported data</param>
[IntegrationEvent(false, false)]
procedure OnImportPayroll(var TempServiceConnection: Record "Service Connection" temporary; GenJournalLine: Record "Gen. Journal Line")
begin
end;
}