Why do you need this change?
In 4PS Construct we need to suppress the insertion of the CustomerBankAccount."Bank Account No." and VendorBankAccount."Bank Account No." into the reconciliation temp buffer when IBAN is empty because reconciliation matching should be IBAN-based. A customer/vendor bank account without IBAN has only a legacy domestic account number, which would risk false-positive matches during statement reconciliation.
Existing events don't allow conditional, per-record suppression of CustomerBankAccount."Bank Account No."/VendorBankAccount."Bank Account No." insertion within the loop, without affecting IBAN insertion for the same record.
The standard code inserts "Bank Account No." and IBAN as two separate, unconditional calls. Only the first ("Bank Account No.") needs to be conditionally suppressed; the second (IBAN) must always be executed. IsHandled allows subscriber to override only when the NL Telebank rule applies — without touching the IBAN path or the loop structure.
The event fires inside procedure MakeTempFile, once per CustomerBankAccount/VendorBankAccount record, per reconciliation run. The number of invocations scales with the total number of customer/vendor bank accounts across all customers/vendors. For large environments this could be in the thousands per run. The subscriber itself is trivially fast (one field read + boolean assignment), so performance impact is negligible.
The event exposes the full CustomerBankAccount/VendorBankAccount record (by value, so read-only). This record contains IBAN and "Bank Account No.", both of which are financial identifiers subject to GDPR/PSD2 data minimization requirements. The exposure is necessary: the subscriber's sole purpose is to inspect IBAN to decide whether to suppress the domestic number. Passing the record by value prevents modification.
The risk of several subscriptions is a future subscriber that sets IsHandled := false to force the insert regardless of IBAN — that would override this NL-specific rule with no error. Future subscribers should therefore treat IsHandled = true as a definitive "suppress" decision and never reset it to false; they should add logic only for cases not yet covered (e.g., checking a different condition when IsHandled is still false).
Describe the request
Dear ALAppExtensions team,
On behalf of 4PS I would like to request integration events 'OnBeforeInsertCustomerBankAccountNo' and 'OnBeforeInsertVendorBankAccountNo' to be added to procedure MakeTempfile of codeunit 11000006 "CBG Statement Reconciliation".
local procedure MakeTempfile()
var
NumberRec: Integer;
RecNumerator: Integer;
IsHandled: Boolean; //new
begin
BankAccountCharsToKeep := 'ABCDEFGHIJKLMNOPQRSTUVWYXZ0123456789';
TempReconciliationBuffer.Reset();
if not TempReconciliationBuffer.Find('-') then begin
NumberRec := Customer.Count + Vendor.Count + CustomerBankAccount.Count + VendorBankAccount.Count + Employee.Count();
if Customer.Find('-') then
repeat
RecNumerator := RecNumerator + 1;
StatusWindowUpdate(1, Round(RecNumerator / NumberRec * 10000, 1));
InsertTempfileRecord(
Customer.Name, TempReconciliationBuffer."Source Type"::Customer, Customer."No.",
TempReconciliationBuffer."Data Type"::Name);
InsertTempfileRecord(
Customer.Address, TempReconciliationBuffer."Source Type"::Customer, Customer."No.",
TempReconciliationBuffer."Data Type"::Street);
InsertTempfileRecord(
Customer.City, TempReconciliationBuffer."Source Type"::Customer, Customer."No.",
TempReconciliationBuffer."Data Type"::City);
until Customer.Next() = 0;
if Vendor.Find('-') then
repeat
RecNumerator := RecNumerator + 1;
StatusWindowUpdate(1, Round(RecNumerator / NumberRec * 10000, 1));
InsertTempfileRecord(
Vendor.Name, TempReconciliationBuffer."Source Type"::Vendor, Vendor."No.",
TempReconciliationBuffer."Data Type"::Name);
InsertTempfileRecord(
Vendor.Address, TempReconciliationBuffer."Source Type"::Vendor, Vendor."No.",
TempReconciliationBuffer."Data Type"::Street);
InsertTempfileRecord(
Vendor.City, TempReconciliationBuffer."Source Type"::Vendor, Vendor."No.",
TempReconciliationBuffer."Data Type"::City);
until Vendor.Next() = 0;
if Employee.Find('-') then
repeat
RecNumerator := RecNumerator + 1;
StatusWindowUpdate(1, Round(RecNumerator / NumberRec * 10000, 1));
InsertTempfileRecord(
CopyStr(Employee.FullName(), 1, MaxStrLen(TempReconciliationBuffer.Word)),
TempReconciliationBuffer."Source Type"::Employee, Employee."No.",
TempReconciliationBuffer."Data Type"::Name);
InsertTempfileRecord(
Employee.Address, TempReconciliationBuffer."Source Type"::Employee, Employee."No.",
TempReconciliationBuffer."Data Type"::Street);
InsertTempfileRecord(
Employee.City, TempReconciliationBuffer."Source Type"::Employee, Employee."No.",
TempReconciliationBuffer."Data Type"::City);
until Employee.Next() = 0;
if CustomerBankAccount.Find('-') then
repeat
RecNumerator := RecNumerator + 1;
StatusWindowUpdate(1, Round(RecNumerator / NumberRec * 10000, 1));
IsHandled := false; //new
OnBeforeInsertCustomerBankAccountNo(CustomerBankAccount, IsHandled); //new
if not IsHandled then //new
InsertTempfileRecord(
LocalFunctionalityMgt.CharacterFilter(CustomerBankAccount."Bank Account No.", BankAccountCharsToKeep),
TempReconciliationBuffer."Source Type"::Customer, CustomerBankAccount."Customer No.",
TempReconciliationBuffer."Data Type"::Bankaccount);
InsertTempfileRecord(
LocalFunctionalityMgt.CharacterFilter(CustomerBankAccount.IBAN, BankAccountCharsToKeep),
TempReconciliationBuffer."Source Type"::Customer, CustomerBankAccount."Customer No.",
TempReconciliationBuffer."Data Type"::Bankaccount);
until CustomerBankAccount.Next() = 0;
if VendorBankAccount.Find('-') then
repeat
RecNumerator := RecNumerator + 1;
StatusWindowUpdate(1, Round(RecNumerator / NumberRec * 10000, 1));
IsHandled := false; //new
OnBeforeInsertVendorBankAccountNo(VendorBankAccount, IsHandled); //new
if not IsHandled then //new
InsertTempfileRecord(
LocalFunctionalityMgt.CharacterFilter(VendorBankAccount."Bank Account No.", BankAccountCharsToKeep),
TempReconciliationBuffer."Source Type"::Vendor, VendorBankAccount."Vendor No.",
TempReconciliationBuffer."Data Type"::Bankaccount);
InsertTempfileRecord(
LocalFunctionalityMgt.CharacterFilter(VendorBankAccount.IBAN, BankAccountCharsToKeep),
TempReconciliationBuffer."Source Type"::Vendor, VendorBankAccount."Vendor No.",
TempReconciliationBuffer."Data Type"::Bankaccount);
until VendorBankAccount.Next() = 0;
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInsertCustomerBankAccountNo(CustomerBankAccount: Record "Customer Bank Account"; var IsHandled: Boolean)
begin
//new
end;
[IntegrationEvent(false, false)]
local procedure OnBeforeInsertVendorBankAccountNo(VendorBankAccount: Record "Vendor Bank Account"; var IsHandled: Boolean)
begin
//new
end;
Why do you need this change?
In 4PS Construct we need to suppress the insertion of the CustomerBankAccount."Bank Account No." and VendorBankAccount."Bank Account No." into the reconciliation temp buffer when IBAN is empty because reconciliation matching should be IBAN-based. A customer/vendor bank account without IBAN has only a legacy domestic account number, which would risk false-positive matches during statement reconciliation.
Existing events don't allow conditional, per-record suppression of CustomerBankAccount."Bank Account No."/VendorBankAccount."Bank Account No." insertion within the loop, without affecting IBAN insertion for the same record.
The standard code inserts "Bank Account No." and IBAN as two separate, unconditional calls. Only the first ("Bank Account No.") needs to be conditionally suppressed; the second (IBAN) must always be executed. IsHandled allows subscriber to override only when the NL Telebank rule applies — without touching the IBAN path or the loop structure.
The event fires inside procedure MakeTempFile, once per CustomerBankAccount/VendorBankAccount record, per reconciliation run. The number of invocations scales with the total number of customer/vendor bank accounts across all customers/vendors. For large environments this could be in the thousands per run. The subscriber itself is trivially fast (one field read + boolean assignment), so performance impact is negligible.
The event exposes the full CustomerBankAccount/VendorBankAccount record (by value, so read-only). This record contains IBAN and "Bank Account No.", both of which are financial identifiers subject to GDPR/PSD2 data minimization requirements. The exposure is necessary: the subscriber's sole purpose is to inspect IBAN to decide whether to suppress the domestic number. Passing the record by value prevents modification.
The risk of several subscriptions is a future subscriber that sets IsHandled := false to force the insert regardless of IBAN — that would override this NL-specific rule with no error. Future subscribers should therefore treat IsHandled = true as a definitive "suppress" decision and never reset it to false; they should add logic only for cases not yet covered (e.g., checking a different condition when IsHandled is still false).
Describe the request
Dear ALAppExtensions team,
On behalf of 4PS I would like to request integration events 'OnBeforeInsertCustomerBankAccountNo' and 'OnBeforeInsertVendorBankAccountNo' to be added to procedure MakeTempfile of codeunit 11000006 "CBG Statement Reconciliation".