This time I want to write about a problem that affects every Latam implementation, the bank payments.
Unlike Europe and countries with more organized banking systems, in Latam we have a chaotic bank system in which every bank creates and use their own “schema” to accept the payment transactions.
Some bank even has multiple format definitions based in the operation type, vendor payment, payroll payment, other bank payment, and others.
I saw some “payment solutions” in the appsource, I don’t know how much cost those apps but is very difficult to understand why we don’t have similar solutions from Latam partners.
I believe that Latam partners work with banks, I mean, they have bank accounts and know someone in the bank, maybe the people which manages their accounts, so, why don’t ask that person for the bank layouts, and develop an extension for that?
Yes, I know about the Host2Host service but you can use that service or upload a txt file to the bank site.
I’m going to focus on the txt file this time.
First, you need to decide if you want only one codeunit or one per format or bank, this time I chose only one codeunit to rule them all layouts.
I created a “base payment table” to put the information there in the first place and then start witht he txt file. This allows me to grow the solution and add more fields to add more banks and avoid to add fields in the General Journal Line table keeping that table clean.
/// <summary>
/// Table ExportPayment (ID 58100).
/// </summary>
table 58100 ExportPayment
{
Caption = 'ExportPayment';
DataClassification = CustomerContent;
fields
{
field(1; "Line No"; Integer)
{
Caption = 'Line No';
DataClassification = CustomerContent;
}
field(2; "Origin Bank"; Code[20])
{
Caption = 'Origin Bank';
DataClassification = CustomerContent;
}
field(3; "Origin Account No"; Text[30])
{
Caption = 'Origin Account No';
DataClassification = CustomerContent;
}
field(4; "Origin Branch No"; Text[20])
{
Caption = 'Origin Branch No';
DataClassification = CustomerContent;
}
field(5; "Origin Bank Place"; Text[20])
{
Caption = 'Origin Bank Place';
DataClassification = CustomerContent;
}
field(7; "Origin Bank Currency"; Code[10])
{
Caption = 'Origin Bank Currency';
DataClassification = CustomerContent;
}
field(8; "Origin Bank Country"; Code[10])
{
Caption = 'Origin Bank Country';
DataClassification = CustomerContent;
}
field(9; "Origin Bank Export Code"; Enum CCExpBankCodes)
{
Caption = 'Origin Bank Export Code';
DataClassification = CustomerContent;
}
field(10; "Bank Agreement"; Code[9])
{
Caption = 'Bank Agreement';
DataClassification = CustomerContent;
}
field(11;"Payment Reference"; Text[30])
{
Caption = 'Payment Reference';
DataClassification = CustomerContent;
}
field(12; Description; Text[50])
{
Caption = 'Description';
DataClassification = CustomerContent;
}
field(20; "Vendor No"; Code[20])
{
Caption = 'Vendor No';
DataClassification = CustomerContent;
}
field(21; "Vendor ID "; Code[20])
{
Caption = 'Vendor ID ';
DataClassification = CustomerContent;
}
field(22; "Invoice to Pay"; Code[20])
{
Caption = 'Invoice to Pay';
DataClassification = CustomerContent;
}
field(23; "Vendor Bank"; Code[20])
{
Caption = 'Vendor Bank';
DataClassification = CustomerContent;
}
field(24; "Vendor Bank Account No"; Text[30])
{
Caption = 'Vendor Bank Account No';
DataClassification = CustomerContent;
}
field(25; "Destination Bank Branch"; Text[20])
{
Caption = 'Destination Bank Branch';
DataClassification = CustomerContent;
}
field(26; "Destination Bank Place"; Text[20])
{
Caption = 'Destination Bank Place';
DataClassification = CustomerContent;
}
field(27; "Payment Currency Code"; Code[10])
{
Caption = 'Payment Currency Code';
DataClassification = CustomerContent;
}
field(28; "Destination Bank Country"; Code[10])
{
Caption = 'Destination Bank Country';
DataClassification = CustomerContent;
}
field(29; "Destination Bank Export Code"; Enum CCExpBankCodes)
{
Caption = 'Destination Bank Export Code';
DataClassification = CustomerContent;
}
field(30; "Payment Amount"; Decimal)
{
Caption = 'Payment Amount';
DataClassification = CustomerContent;
}
field(36;"Vendor Name";Text[50])
{
Caption = 'Vendor Name';
DataClassification = CustomerContent;
}
field(40; BBVAOperType; Text[1])
{
Caption = 'BBVAOperType';
DataClassification = CustomerContent;
}
field(41; BBVARefNo; Text[25])
{
Caption = 'BBVARefNo';
DataClassification = CustomerContent;
}
field(42; BBVAAccType; Text[2])
{
Caption = 'BBVAAccType';
DataClassification = CustomerContent;
}
field(60; AreSameBank; Boolean)
{
Caption = 'AreSameBank';
DataClassification = CustomerContent;
}
field(61; AreSameCurrency; Boolean)
{
Caption = 'AreSameCurrency';
DataClassification = CustomerContent;
}
field(62; AreSameCountry; Boolean)
{
Caption = 'AreSameCountry';
DataClassification = CustomerContent;
}
field(100; "Exported to Payment File"; Boolean)
{
Caption ='Exported to Payment File';
DataClassification = CustomerContent;
}
}
keys
{
key(PK; "Line No")
{
Clustered = true;
}
}
}
I call everything from the payment journal so my first procedure to call in every export is the next code and then, create the txt file.
/// <summary>
/// PrepareExport.
/// </summary>
/// <param name="JTN">Code[10].</param>
/// <param name="JBN">Code[10].</param>
procedure PrepareExport(JTN: Code[10]; JBN: Code[10])
var
ExpData: Record ExportPayment;
GenJnlLine: Record "Gen. Journal Line";
begin
ExpData.Reset();
if ExpData.FindSet() then
ExpData.DeleteAll();
GenJnlLine.Reset();
GenJnlLine.SetRange("Journal Template Name", JTN);
GenJnlLine.SetRange("Journal Batch Name", JBN);
GenJnlLine.SetRange("Exported to Payment File", false);
if GenJnlLine.FindSet() then
repeat
ExpData."Line No" := GenJnlLine."Line No.";
ExpData."Origin Bank" := GenJnlLine."Bal. Account No.";
ExpData."Origin Account No" := GetBankAccNo(GenJnlLine."Bal. Account No.");
ExpData."Origin Branch No" := GetBankBranch(GenJnlLine."Bal. Account No.");
ExpData."Origin Bank Place" := GetBankPlace(GenJnlLine."Bal. Account No.");
ExpData."Origin Bank Currency" := GetBankCurr(GenJnlLine."Bal. Account No.");
ExpData."Origin Bank Country" := GetBankCountry(GenJnlLine."Bal. Account No.");
ExpData."Origin Bank Export Code" := GetBankExpCode(GenJnlLine."Bal. Account No.");
ExpData.Description := GenJnlLine.Description;
ExpData."Bank Agreement" := GetBankAgr(GenJnlLine."Bal. Account No.");
ExpData."Vendor No" := GenJnlLine."Account No.";
ExpData."Vendor Name" := GetVendorName(GenJnlLine."Account No.");
ExpData."Vendor ID " := GetVendorID(GenJnlLine."Account No.");
ExpData."Invoice to Pay" := GenJnlLine."Applies-to Doc. No.";
ExpData."Vendor Bank" := GenJnlLine."Recipient Bank Account";
ExpData."Vendor Bank Account No" := GetVendBankAcc(GenJnlLine."Account No.", GenJnlLine."Recipient Bank Account");
ExpData."Destination Bank Branch" := '';
ExpData."Destination Bank Place" := '';
ExpData."Destination Bank Country" := GetVendBankCountry(GenJnlLine."Account No.", GenJnlLine."Recipient Bank Account");
ExpData."Destination Bank Export Code" := GetVendBankExpCode(GenJnlLine."Account No.", GenJnlLine."Recipient Bank Account");
if GenJnlLine."Currency Code" <> '' then
ExpData."Payment Currency Code" := GenJnlLine."Currency Code"
else
ExpData."Payment Currency Code" := 'MXN';
ExpData."Payment Amount" := GenJnlLine.Amount;
//Here starts a new section to define some options for each bank in the codeunit
if ExpData."Origin Bank Export Code" = ExpData."Destination Bank Export Code" then
ExpData.AreSameBank := true
else
ExpData.AreSameBank := false;
if ExpData."Origin Bank Country" = ExpData."Destination Bank Country" then
ExpData.AreSameCountry := true
else
ExpData.AreSameCountry := false;
if ExpData."Origin Bank Currency" = ExpData."Payment Currency Code" then
ExpData.AreSameCurrency := true
else
ExpData.AreSameCurrency := false;
if ExpData.AreSameCountry = true then
ExpData.BBVAOperType := '2'
else
ExpData.BBVAOperType := '4';
if (ExpData.AreSameCurrency = true) and (ExpData.AreSameBank = true) then
ExpData.BBVAOperType := '2'
else
ExpData.BBVAOperType := '6';
ExpData.Insert(true);
until GenJnlLine.Next() = 0;
end;
Let’s look one of the most used banks in Mexico, BBVA.
They have a 1,366 positions layout, this layout has a 2 sections, header, and detail. The detail sections contain 106 fields that sums those 1366 positions and covers almost any BBVA supported transaction.
This code contains all fields for bbva layout
/// <summary>
/// CreateLayout1.
/// </summary>
/// <param name="JTN">Code[10].</param>
/// <param name="JBN">Code[10].</param>
procedure CreateBBVA(JTN: Code[10]; JBN: Code[10])
var
InStr: InStream;
OutStr: OutStream;
tmpblob: Codeunit "Temp Blob";
FileName: Text;
CRLF: Text[2];
SpaceStr: Text;
ZeroStr: Text;
TotalAmnt: Decimal;
ExpPaym: Record ExportPayment;
begin
CRLF[1] := 13;
CRLF[2] := 10;
FileName := 'BBVA.txt';
SpaceStr := ' ';
TotalAmnt := 0;
ExpPaym.Reset();
ExpPaym.SetRange("Exported to Payment File", false);
if ExpPaym.FindSet() then begin
tmpBlob.CreateOutStream(OutStr, TextEncoding::Windows);
OutStr.WriteText(
//>> Start Header/Inicia Header
'H' + //1 Record type/Indicador del registro
Format(ExpPaym."Bank Agreement").PadLeft(9, '0') + //2 Arrangement/Convenio
Format(WorkDate(), 0, 9) + //3 Send Date/Fecha de envio
'01' + //4 Recipient Type/Tipo de validación del tercero
PadStr('PAGO' + Format(WorkDate, 0, '<Year4><Month,2><Day,2>'), 30, ' ') + //5 file name/Clave del archivo
'00' + //6 Response Code/Código de respuesta
PadStr(SpaceStr, 20, ' ') + //7 Response Description/Descripción código de respuesta
PadStr(SpaceStr, 3, ' ') + //8 Channel/Canal
PadStr(SpaceStr, 35, ' ') + //9 CHarge Account/Cuenta de cargo
PadStr(SpaceStr, 3, ' ') +//10 Arrangement Currency/Divisa del convenio
PadStr(SpaceStr, 1251, ' ') +//11 Filler 1251 spaces/espacios
CRLF
);
//<<End Header/termina header
repeat
OutStr.WriteText(
//>>Start Detail/Inicia Detalle
'D' + //1 Record number/Indicador del registtro
'A' + //2 Instruction/Instrucción
'P' + //3 Document Type/Tipo de documento
PadStr(ExpPaym."Invoice to Pay", 20, ' ') + //4 Reference/Referencia SIT
PadStr(ExpPaym."Vendor No", 30, ' ') + //5 Vendor No, add empty spaces/Clave de proveedor o concepto o datos RSTM TODO, revisar el largo de la cuenta proveedor y sumarle a 30 padstr
'PDA' + //6 Service Type/Tipo de servicio
ExpPaym.BBVAOperType + //7 Operation Code/Código de operación
PadStr(ZeroStr, 20, ' ') + //8 Charge Account and vendor No for SPID/Cuenta de cargo y RFC del proveedor para SPID
PadStr(SpaceStr, 15, ' ') + //9 Filler
PadStr(SpaceStr, 25, ' ') + //10 Numerical reference/Referencia Numérica o Leyenda personalizada de CARGO/Concepto o Codigo de seguridad y folio identificador RSTM
PadStr('PAGO' + Format(ExpPaym."Invoice to Pay"), 37, ' ') + //11 Pay Reason/Motivo de pago o Leyenda personalizada de CARGO/ Referencia Amplia TODO, revisar el largo de la cuenta proveedor y sumarle a 30 padstr
PadStr(SpaceStr, 15, ' ') + //12 Filler
PadStr(ExpPaym."Payment Reference", 25, ' ') + //13 Payment Description/Leyenda personalizada de ABONO/CONCEPTO
PadStr(ExpPaym."Payment Reference", 37, ' ') + //14 CIE Concept/Concepto CIE O Leyenda personalizada de ABONO Referencia Amplia
'N' + //15 Fiscal Receipt/Comprobante fiscal
PadStr(SpaceStr, 8, ' ') + //16 Filler
'40' +//17 Account Type/Tipo de cuenta
PadStr(SpaceStr, 35, ' ') + //18 Credit Account/Cuenta de abono
PadStr(SpaceStr, 40, ' ') + //19 Receipt Name/Nombre del 1er Beneficiario o Nombre del titular de la cuenta de abono
PadStr(SpaceStr, 1, ' ') + //20 Receipt ID Code/Clave de identificación del 1er Beneficiario
PadStr(SpaceStr, 30, ' ') + //21 Receipt ID Number/Número identificación 1er Beneficiario
PadStr(SpaceStr, 40, ' ') + //22 Receipt Name/Nombre del 2do Beneficiario o Nombre comercial de la empresa
PadStr(SpaceStr, 1, ' ') + //23 2nd Receipt ID Code/Clave de identificación del 2do Beneficiario
PadStr(SpaceStr, 30, ' ') + //24 2nd Receipt ID Number/Número identificación 2do Beneficiario o CURP del Beneficiario para RSTM O Clave de rastreo para interbanciarios
ExpPaym."Payment Currency Code" + //25 Destination transfer currency/Divisa de la transferencia destino
PadStr(SpaceStr, 11, ' ') + //26 BIC CODE/CLAVE BIC
PadStr(SpaceStr, 9, ' ') + //27 ABA CODE/CLAVE ABA
'FA' + //28 Document Code/Clave de documento
Format(ExpPaym."Payment Amount" * 100, 0, 2).PadLeft(15, '0') + //29 Payment Amount/Importe del documento
PadStr(ZeroStr, 15, '0') + //30 Filler
'01' + //31 Confirmation Type/Tipo de confirmación
PadStr(SpaceStr, 50, ' ') + //32 Email or celullar
'N' + //33 Interest frequency/Periodicidad de interes
PadStr(ZeroStr, 8, '0') + //34 Filler Núm (2.6)
PadStr(ZeroStr, 4, '0') + //35 Filler Núm (2.2)
Format(WorkDate(), 0, 9) + //36 Payment Date/Fecha de pago
'0001-01-01' + //37 Effective date/Fecha de vigencia
'0001-01-01' + //38 Grace date/Fecha de gracia
'0001-01-01' + //39 Effective date/Fecha de vigencia
Format(WorkDate(), 0, 9) + //40 Document Date/Fecha del documento
'N' + //41 Periodic Payment Indicator/Indicador del pago recurrente
PadStr(SpaceStr, 1, ' ') + //42 Filler
'0001-01-01' + //43
'700' + //44 Payment Detail/Longitud de Datos adicionales o Detalle de pago
PadStr(SpaceStr, 700, ' ') + //45 Additional Data/Datos adicionales
PadStr(SpaceStr, 10, ' ') + //46 Filler
PadStr(SpaceStr, 10, ' ') + //47 Filler
PadStr(SpaceStr, 2, ' ') + //48 Document Status Code/Código de estatus del documento
PadStr(SpaceStr, 30, ' ') + //49 Description of the document status code/Descripción del código estatus del documento
'0001-01-01' + //50 Date of last document event/Fecha de ultimo evento del documento
CRLF
);
TotalAmnt += ExpPaym."Payment Amount";
until ExpPaym.Next() = 0;
//<<End Detail/Termina Detalle
//>>Start summary/Inicia Sumario
OutStr.WriteText(
'T' + //1 REcord Indicator/Indicador del registro
'' + //2 Number of records High MXP (Mexican peso) Number of providers to pay are newrecords validate if payments can be summarized by provider and not n payments for n invoices/Número de registros Altas MXP (peso mexicano) Numero de proveedores a pagar son altas validar si se pueden sumarizar los pagos por proveedor y no n pagos por n facturas
Format(TotalAmnt, 0, 2).PadLeft(15, '0') + //3 Total amount newrecords MXP sum of invoice payments by supplier/Importe total Altas MXP suma de pagos de facturas por proveedor
PadStr(ZeroStr, 10, '0') + //4 Number of records Deletions MXP 10 zeros because there are no withdrawals is the registration file (Payments)/Número de registros Bajas MXP 10 ceros por que no hay bajas es archivo de altas (Pagos)
PadStr(ZeroStr, 215, '0') + //5 al 21
'' + //22 Number of new records USD (American dollar) how many payments will normally be paid per provider USD or 10 zeros/Número de registros ALTAS USD (dólar americano) cuantos pagos se haran normalmente se paga por proveedor USD o 10 ceros
'' + //23 Total Amount new records USD sum of invoice payments per supplier USD or 15 zerosImportte Total Altas USD suma de pagos de facturas por proveedor USD o 15 ceros
PadStr(ZeroStr, 125, '0') + //24 al 33
'' + //34 Registration number new records EUR how many payments will normally be paid per provider EUR or 10 zerosNúmero de registro Altas EUR cuantos pagos se haran normalmente se paga por proveedor EUR o 10 ceros
'' + //35 New Records Total Amount EUR/Importe total Altas EUR
PadStr(ZeroStr, 125, '0') + //36 al 45
'' + //46 New Records Count CAD/Número de registros Altas CAD
'' + //47 New Records Total Amount CAD/Importe total Altas CAD
PadStr(ZeroStr, 125, '0') + //48 al 57
'' + //58 New Records Count CHF/Número de registros Altas CHF
'' + //59 New Records Total Amount CHF/Importe total Altas CHF
PadStr(ZeroStr, 125, '0') + //60 al 69
'' + //70 New Records Count GBP/Número de registros Altas GBP
'' + //71 New Records Total Amount GBP/Importe total Altas GBP
PadStr(ZeroStr, 125, '0') + //72 al 81
'' + //82 New Records Count SEK/Número de registros Altas SEK
'' + //83 New Records Total Amount SEK/Importe total Altas SEK
PadStr(ZeroStr, 125, '0') + //84 al 93
'' + //94 New Records Count JPY/Número de registros Altas JPY
'' + //95 New Records Total Amount JPY/Importe total Altas JPY
PadStr(ZeroStr, 190, '0') + //96 al 106
//<<Termina Sumario
CRLF
);
tmpBlob.CreateInStream(InStr, TextEncoding::Windows);
DownloadFromStream(InStr, '', '', '', FileName);
end;
end;
when you check the code, you will find references to journal and new table fields, also, you can add code to use more currencies in the summary. Text dates are as BBVA ask it.
Now, let’s check a small layout, this is Banorte and has fewer fields
/// <summary>
/// CreateBNTE.
/// </summary>
/// <param name="JTN">Code[10].</param>
/// <param name="JBN">Code[10].</param>
procedure CreateBNTE(JTN: Code[10]; JBN: Code[10])
var
InStr: InStream;
OutStr: OutStream;
tmpblob1: Codeunit "Temp Blob";
FileName: Text;
CRLF: Text[2];
SpaceStr: Text;
ZeroStr: Text;
TotalAmnt: Decimal;
ExpPaym: Record ExportPayment;
begin
CRLF[1] := 13;
CRLF[2] := 10;
FileName := 'BNTE.txt';
SpaceStr := ' ';
TotalAmnt := 0;
ExpPaym.Reset();
ExpPaym.SetRange("Exported to Payment File", false);
if ExpPaym.FindSet() then begin
tmpBlob1.CreateOutStream(OutStr, TextEncoding::Windows);
repeat
OutStr.WriteText(
'07' + //1 OPI Operation/Operación OPIs
PadStr(ExpPaym."Vendor No", 13, ' ') + //2 ID Code/Clave ID
PadStr(SpaceStr, 10, ' ') + //3 Origin Account/Cuenta Origen
PadStr(SpaceStr, 20, ' ') + //4 Destination Account CLABE/Cuenta/CLABE Destino
Format(ExpPaym."Payment Amount", 0, 2).PadLeft(16,'0') + //5 Amount/Importe
Format(ExpPaym."Payment Reference").PadLeft(7,'0') + //6 Reference/Referencia
PadStr(ExpPaym.Description, 30, ' ') + //7 Description/Descripción
PadStr(GetCompRFC, 13, ' ') + //8 Paying TAX ID/RFC Ordenante
Format((ExpPaym."Payment Amount"-(ExpPaym."Payment Amount"/1.16)),0,2).PadLeft(14,'0') + //9 TAX(VAT)/IVA
Format(WorkDate, 0, '<Day,2><Month,2><Year4>') + //10 Apply on Date/Fecha aplicación
'X' + //11 Payment Instruction/Instrucción de pago
CRLF
);
until ExpPaym.Next() = 0;
end;
tmpBlob1.CreateInStream(InStr, TextEncoding::Windows);
DownloadFromStream(InStr, '', '', '', FileName);
end;
As you can see, I´m using the same source table, so if I need to add more fields because I add a new bank layout, I just simply add the required fields without touch the existing layouts.
Finally, I added a last bank layout, this time Santander
/// <summary>
/// CreateSANT.
/// </summary>
/// <param name="JTN">Code[10].</param>
/// <param name="JBN">Code[10].</param>
procedure CreateSANT(JTN: Code[10]; JBN: Code[10])
var
InStr: InStream;
OutStr: OutStream;
tmpblob2: Codeunit "Temp Blob";
FileName: Text;
CRLF: Text[2];
SpaceStr: Text;
ZeroStr: Text;
TotalAmnt: Decimal;
ExpPaym: Record ExportPayment;
begin
CRLF[1] := 13;
CRLF[2] := 10;
FileName := 'SANT.txt';
SpaceStr := ' ';
TotalAmnt := 0;
ExpPaym.Reset();
ExpPaym.SetRange("Exported to Payment File", false);
if ExpPaym.FindSet() then begin
tmpBlob2.CreateOutStream(OutStr, TextEncoding::Windows);
repeat
OutStr.WriteText(
PadStr(ExpPaym."Origin Account No", 16, ' ') + //1 Charged account/Cuenta de Cargo
PadStr(ExpPaym."Vendor Bank Account No", 20, ' ') + //2 Crediot Account/Cuenta de abono / Número Móvil
PadStr(SpaceStr, 5, ' ') + //3 Bank/Banco
PadStr(ExpPaym."Vendor Name", 40, ' ') + //4 Receipt/Beneficiario
PadStr(SpaceStr, 4, ' ') + //5 Branch/Sucursal
Format(ExpPaym."Payment Amount", 0, 2).PadLeft(16,'0')+ //6 Amount/Importe
PadStr(SpaceStr, 7, ' ') + //7 City/Plaza
PadStr(ExpPaym.Description, 40, ' ') + //8 Concept/Concepto
PadStr(SpaceStr, 90, ' ') + //9 Blank Space/Espacio en Blanco
PadStr(SpaceStr, 1, ' ') + //10 Fiscal Accoutn Statement/Estado de cuenta fiscal
PadStr(SpaceStr, 13, ' ') + //11 TAX ID/RFC
PadStr(ZeroStr, 15, '0') + //12 TAX(VAT)/IVA
PadStr(ExpPaym."Payment Reference", 7, ' ') + //13 Originator Reference/Referencia Ordenante
PadStr(SpaceStr, 1, ' ') + //14 Application Form/Forma de aplicación
PadStr(SpaceStr, 2, ' ') + //15 Payment Type/Tipo de Pago
PadStr(SpaceStr, 1, ' ') + //16 Application Date/Fecha de aplicación
CRLF
);
until ExpPaym.Next() = 0;
end;
tmpBlob2.CreateInStream(InStr, TextEncoding::Windows);
DownloadFromStream(InStr, '', '', '', FileName);
end;
And some procedures to get general information for every layout
local procedure GetCompRFC(): Text
var
CompInfo: Record "Company Information";
begin
CompInfo.Get();
exit(CompInfo."RFC No.")
end;
local procedure GetBankAccNo(BankNo: Code[20]): Text[30]
var
Banks: Record "Bank Account";
begin
Banks.Reset();
Banks.SetRange("No.", BankNo);
if Banks.findset then
exit(Banks."Bank Account No.")
end;
local procedure GetBankBranch(BankNo: Code[20]): Text[30]
var
Banks: Record "Bank Account";
begin
Banks.Reset();
Banks.SetRange("No.", BankNo);
if Banks.findset then
exit(Banks."Bank Branch No.")
end;
local procedure GetBankPlace(BankNo: Code[20]): Text[30]
var
Banks: Record "Bank Account";
begin
Banks.Reset();
Banks.SetRange("No.", BankNo);
if Banks.findset then
exit(Banks."Bank Account No.")
end;
local procedure GetBankAgr(BankNo: Code[20]): Text[30]
var
Banks: Record "Bank Account";
begin
Banks.Reset();
Banks.SetRange("No.", BankNo);
if Banks.findset then
exit(Banks."Bank Agreement")
end;
local procedure GetBankCurr(BankNo: Code[20]): Text[10]
var
Banks: Record "Bank Account";
begin
Banks.Reset();
Banks.SetRange("No.", BankNo);
if Banks.findset then
if banks."Currency Code" <> '' then
exit(Banks."Currency Code")
else
exit('MXN');
end;
local procedure GetBankCountry(BankNo: Code[20]): Text[10]
var
Banks: Record "Bank Account";
begin
Banks.Reset();
Banks.SetRange("No.", BankNo);
if Banks.findset then
exit(Banks."Country/Region Code")
end;
local procedure GetBankExpCode(BankNo: Code[20]): Enum CCExpBankCodes
var
Banks: Record "Bank Account";
begin
Banks.Reset();
Banks.SetRange("No.", BankNo);
if Banks.findset then
exit(Banks."Bank Export Code");
end;
local procedure GetVendorID(VendNo: Code[20]): Code[20]
var
Vend: Record Vendor;
begin
Vend.Reset();
Vend.SetRange("No.", VendNo);
if Vend.FindSet() then
exit(Vend."RFC No.");
end;
local procedure GetVendorName(VendNo: Code[20]): Text[50]
var
Vend: Record Vendor;
begin
Vend.Reset();
Vend.SetRange("No.", VendNo);
if Vend.FindSet() then
exit(Vend.Name);
end;
local procedure GetVendBankAcc(VendNo: Code[20]; Vendbank: Code[20]): Code[20]
var
VeBank: Record "Vendor Bank Account";
begin
VeBank.Reset();
VeBank.SetRange("Vendor No.", VendNo);
VeBank.SetRange(Code, Vendbank);
if VeBank.FindSet() then
exit(VeBank."Bank Account No.");
end;
local procedure GetVendBankCountry(VendNo: Code[20]; Vendbank: Code[20]): Code[20]
var
VeBank: Record "Vendor Bank Account";
begin
VeBank.Reset();
VeBank.SetRange("Vendor No.", VendNo);
VeBank.SetRange(Code, Vendbank);
if VeBank.FindSet() then
exit(VeBank."Country/Region Code");
end;
local procedure GetVendBankExpCode(VendNo: Code[20]; Vendbank: Code[20]): Enum ExpBankCodes
var
VeBank: Record "Vendor Bank Account";
begin
VeBank.Reset();
VeBank.SetRange("Vendor No.", VendNo);
VeBank.SetRange(Code, Vendbank);
if VeBank.FindSet() then
exit(VeBank."Bank Export Code");
end;
So, lets talk about a new idea here:
Lets make the base table available as a base required app, available with your first “layout purchase”. For example, the customer wants to purchase BBVA so, we sell BBVA layout plus base table, later, the same customer wants Banorte, so our Banorte app, checks if the base table exists and the fields, if detects that the base table needs an udpate, then apply the updated and add the new fields, if not change is need, just add the new layout codeunit and make required mods in some pages.
With this approach, we can build a multi layout solution that we can sell by parts and those apps relies in a “single source table” and sell this solution to any customer in Mexico, and maybe you can “clone” this approach to other countries.
If you need to use Host to Host solutions or webservices , you simply add another layer to accomplish these throught powerapps or BC web services calls.
Feel free to use and modify the code according to your needs.
Leave a Reply
You must be logged in to post a comment.