Codeunit 1231 SEPA DD-Fill Export Buffer, source in 29
Source29
src/Layers/W1/BaseApp/Bank/DirectDebit/SEPADDFillExportBuffer.Codeunit.al182 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.Bank.DirectDebit;
using Microsoft.Bank.BankAccount;
using Microsoft.Bank.Payment;
using Microsoft.Bank.Setup;
using Microsoft.Finance.GeneralLedger.Setup;
using Microsoft.Sales.Customer;
/// <summary>
/// Populates the payment export data buffer with information from direct debit collection entries
/// for SEPA direct debit processing. Formats and validates data for XML export compliance.
/// </summary>
codeunit 1231 "SEPA DD-Fill Export Buffer"
{
Permissions = TableData "Payment Export Data" = rimd;
TableNo = "Payment Export Data";
trigger OnRun()
begin
end;
var
HasErrorsErr: Label 'The file export has one or more errors.\\For each line to be exported, resolve the errors displayed to the right and then try to export again.';
/// <summary>
/// Fills the payment export data buffer with information from direct debit collection entries.
/// Validates entries through the configured check codeunit, retrieves mandate and customer information,
/// and formats data according to SEPA direct debit standards for XML export processing.
/// </summary>
/// <param name="DirectDebitCollectionEntry">The source direct debit collection entries to process for export.</param>
/// <param name="PaymentExportData">The target payment export data buffer to populate with formatted export data.</param>
procedure FillExportBuffer(var DirectDebitCollectionEntry: Record "Direct Debit Collection Entry"; var PaymentExportData: Record "Payment Export Data")
var
BankAccount: Record "Bank Account";
BankExportImportSetup: Record "Bank Export/Import Setup";
Customer: Record Customer;
CustomerBankAccount: Record "Customer Bank Account";
DirectDebitCollection: Record "Direct Debit Collection";
GLSetup: Record "General Ledger Setup";
SEPADirectDebitMandate: Record "SEPA Direct Debit Mandate";
TempDirectDebitCollectionEntry: Record "Direct Debit Collection Entry" temporary;
begin
TempDirectDebitCollectionEntry.CopyFilters(DirectDebitCollectionEntry);
CODEUNIT.Run(CODEUNIT::"SEPA DD-Prepare Source", TempDirectDebitCollectionEntry);
TempDirectDebitCollectionEntry.SetAutoCalcFields("Applies-to Entry Document No.", "Applies-to Entry Description");
if not TempDirectDebitCollectionEntry.FindSet() then
exit;
DirectDebitCollection.Get(TempDirectDebitCollectionEntry."Direct Debit Collection No.");
BankAccount.Get(DirectDebitCollection."To Bank Account No.");
GetDDExportImportSetup(BankAccount, BankExportImportSetup);
BankExportImportSetup.TestField("Check Export Codeunit");
repeat
CODEUNIT.Run(BankExportImportSetup."Check Export Codeunit", TempDirectDebitCollectionEntry);
until TempDirectDebitCollectionEntry.Next() = 0;
if DirectDebitCollection.HasPaymentFileErrors() then begin
Commit();
Error(HasErrorsErr);
end;
GLSetup.Get();
GLSetup.TestField("LCY Code");
TempDirectDebitCollectionEntry.FindSet();
PaymentExportData.Reset();
if PaymentExportData.FindLast() then;
repeat
PaymentExportData.Init();
PaymentExportData."Entry No." += 1;
PaymentExportData.SetPreserveNonLatinCharacters(BankExportImportSetup."Preserve Non-Latin Characters");
PaymentExportData.SetBankAsSenderBank(BankAccount);
PaymentExportData.SetCreditorIdentifier(BankAccount);
PaymentExportData."SEPA Direct Debit Mandate ID" := TempDirectDebitCollectionEntry."Mandate ID";
SEPADirectDebitMandate.Get(TempDirectDebitCollectionEntry."Mandate ID");
PaymentExportData."SEPA DD Mandate Signed Date" := SEPADirectDebitMandate."Date of Signature";
TempDirectDebitCollectionEntry."Sequence Type" :=
UpdateSourceEntrySequenceType(TempDirectDebitCollectionEntry);
PaymentExportData.Validate(PaymentExportData."SEPA Direct Debit Seq. Type", TempDirectDebitCollectionEntry."Sequence Type");
PaymentExportData."Transfer Date" := TempDirectDebitCollectionEntry."Transfer Date";
PaymentExportData."Document No." := TempDirectDebitCollectionEntry."Applies-to Entry Document No.";
PaymentExportData.Amount := TempDirectDebitCollectionEntry."Transfer Amount";
PaymentExportData."Currency Code" := GLSetup.GetCurrencyCode(TempDirectDebitCollectionEntry."Currency Code");
Customer.Get(TempDirectDebitCollectionEntry."Customer No.");
CustomerBankAccount.Get(Customer."No.", SEPADirectDebitMandate."Customer Bank Account Code");
PaymentExportData.SetCustomerAsRecipient(Customer, CustomerBankAccount);
PaymentExportData.Validate(PaymentExportData."SEPA Partner Type", Customer."Partner Type");
PaymentExportData.Validate(PaymentExportData."SEPA Instruction Priority", PaymentExportData."SEPA Instruction Priority"::NORMAL);
PaymentExportData.Validate(PaymentExportData."SEPA Payment Method", PaymentExportData."SEPA Payment Method"::TRF);
PaymentExportData.Validate(PaymentExportData."SEPA Charge Bearer", PaymentExportData."SEPA Charge Bearer"::SLEV);
PaymentExportData."SEPA Batch Booking" := false;
PaymentExportData."Message ID" := DirectDebitCollection."Message ID";
PaymentExportData."Payment Information ID" := TempDirectDebitCollectionEntry."Transaction ID";
PaymentExportData."End-to-End ID" := TempDirectDebitCollectionEntry."Transaction ID";
PaymentExportData."Message to Recipient 1" := TempDirectDebitCollectionEntry."Applies-to Entry Description";
PaymentExportData."Message to Recipient 2" := TempDirectDebitCollectionEntry."Message to Recipient";
OnBeforeInsertPaymentExportData(PaymentExportData, TempDirectDebitCollectionEntry);
PaymentExportData.Insert(true);
until TempDirectDebitCollectionEntry.Next() = 0;
end;
/// <summary>
/// Retrieves the direct debit export/import setup for the specified bank account.
/// Allows customization through integration events before falling back to the standard setup method.
/// </summary>
/// <param name="BankAccount">The bank account to get the export/import setup for.</param>
/// <param name="BankExportImportSetup">Returns the configured export/import setup for direct debit processing.</param>
local procedure GetDDExportImportSetup(BankAccount: Record "Bank Account"; var BankExportImportSetup: Record "Bank Export/Import Setup")
var
IsHandled: Boolean;
begin
IsHandled := false;
OnBeforeGetDDExportImportSetup(BankAccount, BankExportImportSetup, IsHandled);
if IsHandled then
exit;
BankAccount.GetDDExportImportSetup(BankExportImportSetup);
end;
/// <summary>
/// Updates the sequence type for a direct debit collection entry based on mandate status.
/// For new entries, determines the appropriate sequence type and updates the mandate counter.
/// Existing entries retain their current sequence type.
/// </summary>
/// <param name="TempDirectDebitCollectionEntry">The temporary direct debit collection entry to process.</param>
/// <returns>The appropriate sequence type for the collection entry based on mandate history.</returns>
local procedure UpdateSourceEntrySequenceType(TempDirectDebitCollectionEntry: Record "Direct Debit Collection Entry" temporary) SequenceType: Integer
var
DirectDebitCollectionEntry: Record "Direct Debit Collection Entry";
SEPADirectDebitMandate: Record "SEPA Direct Debit Mandate";
begin
if TempDirectDebitCollectionEntry.Status <> TempDirectDebitCollectionEntry.Status::New then
exit(TempDirectDebitCollectionEntry."Sequence Type");
SEPADirectDebitMandate.Get(TempDirectDebitCollectionEntry."Mandate ID");
SequenceType := SEPADirectDebitMandate.GetSequenceType();
SEPADirectDebitMandate.UpdateCounter();
DirectDebitCollectionEntry := TempDirectDebitCollectionEntry;
if DirectDebitCollectionEntry.Find() then begin
DirectDebitCollectionEntry."Sequence Type" := SequenceType;
DirectDebitCollectionEntry.Modify();
end;
end;
/// <summary>
/// Integration event that allows customization of the direct debit export/import setup retrieval process.
/// Subscribers can provide alternative logic for determining the appropriate setup configuration.
/// </summary>
/// <param name="BankAccount">The bank account for which to retrieve the export/import setup.</param>
/// <param name="BankExportImportSetup">The export/import setup to be populated or customized.</param>
/// <param name="IsHandled">Set to true if the subscriber handles the setup retrieval completely.</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeGetDDExportImportSetup(BankAccount: Record "Bank Account"; var BankExportImportSetup: Record "Bank Export/Import Setup"; var IsHandled: Boolean)
begin
end;
/// <summary>
/// Integration event that allows customization of payment export data before insertion.
/// Subscribers can modify export data fields or add additional validation logic.
/// </summary>
/// <param name="PaymentExportData">The payment export data record being prepared for insertion.</param>
/// <param name="TempDirectDebitCollectionEntry">The source direct debit collection entry providing the data.</param>
[IntegrationEvent(false, false)]
local procedure OnBeforeInsertPaymentExportData(var PaymentExportData: Record "Payment Export Data"; var TempDirectDebitCollectionEntry: Record "Direct Debit Collection Entry" temporary)
begin
end;
}