This repository has been archived on 2024-11-28. You can view files and clone it, but cannot push or open issues or pull requests.
LuisLeon_FactuGES2/Source/Modulos/Banca electronica/Utiles/CVBNorma19SEPA.pas

720 lines
18 KiB
ObjectPascal

unit CVBNorma19SEPA;
interface
uses
Messages, SysUtils, Classes, Dialogs;
type
TSEPAPresentador = record
Nombre : string;
NIFCIF : string;
Sufijo : string;
end;
TSEPAFichero = record
Fecha : TDateTime;
Identificador : string;
end;
TSEPAReceptor = record
Oficina : string;
Entidad : string;
end;
TSEPAAcreedor = record
Nombre : string;
Direccion1 : string;
Direccion2 : string;
Direccion3 : string;
Pais : string;
CuentaIBAN : string;
Sufijo : string;
NIFCIF : string;
end;
TSEPADeudor = record
Nombre : string;
Direccion1 : string;
Direccion2 : string;
Direccion3 : string;
Pais : string;
CuentaIBAN : string;
CodigoBIC : string;
end;
TSEPAAdeudo = record
Referencia : string;
Importe : Currency;
end;
TCVBNorma19SEPA = class(TComponent)
private
pReg: array[0..602] of char; // 2 digitos más por el #13 #10
_LL_: integer; // Longitud Línea. Aquí almacenamos el valor 164 para usarlo
// en el resto del componente.
_INDICA_: string;
_CERO_, _SPCE_: char;
_MSK_EU_: string;
_PAIS_DEFECTO_ : string;
HayError: boolean;
FDepura: boolean;
NFic: file;
FEnCasoError: TNotifyEvent;
sReg: string;
CRLF: string;
sPrimerosDigitos: string;
cSumaImportesTotalesAdeudos : Currency; // Suma de los importes (campo 8) en los registros 003 (adeudos)
iNumeroRegistrosAdeudos: integer; // Número de registros individuales '003', adeudos
iNumeroRegistrosAcreedor : integer; // Número de registros de un bloque de acreedor (002, 003 y 004)
iNumeroRegistros: integer; // Nº de registros individuales (tipo '003')
iTotalRegistros: integer; // Total de registros del fichero incluida el registro cabecera y el registro de totales generales
procedure ComprobarDatos(sParte: string);
protected
procedure Error(iErr: integer); dynamic;
public
NrError: integer;
FNomFic: string; // Nombre del archivo en disco
Presentador : TSEPAPresentador;
Fichero : TSEPAFichero;
Receptor : TSEPAReceptor;
Acreedor : TSEPAAcreedor;
Deudor : TSEPADeudor;
Adeudo : TSEPAAdeudo;
FecAbono: TDateTime;
FechaCobro : TDateTime;
constructor Create(AOwner: TComponent); override;
procedure Abrir;
procedure GenerarCabeceraPresentador;
procedure GenerarCabeceraAcreedor;
procedure GenerarRegistroAdeudo;
procedure GenerarTotalAcreedor;
procedure Cerrar;
published
property NomFichero: string Read FNomFic Write FNomFic;
property Depura: boolean Read FDepura Write FDepura default False;
property EnCasoError: TNotifyEvent Read FEnCasoError Write FEnCasoError;
{ Published declarations }
end;
implementation
uses
Windows, uStringsUtils, CVBUtils;
constructor TCVBNorma19SEPA.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
{Asignar la propiedades por defecto}
_LL_ := high(pReg);
_INDICA_ := '<--';
_CERO_ := '0';
_SPCE_ := ' ';
_MSK_EU_ := '00000000.00';
_PAIS_DEFECTO_ := 'ES';
end;
//*******************************************************************************
procedure TCVBNorma19SEPA.Abrir;
begin
HayError := False;
AssignFile(NFic, FNomFic);
{$I+}
rewrite(Nfic, _LL_);
{$I-}
if IOResult <> 0 then
Error(0);
iNumeroRegistros := 0;
iTotalRegistros := 0;
{fTotImpOrdEu := 0;
iTotImpOrdPts := 0;
iTotDomOrd := 0;
iTotRegOrd := 0;
fTotImpCinEu := 0;
iTotImpCinPts := 0;
iTotDomCin := 0;
IniOrdenan;
IniRegistro;}
CRLF := #13 + #10;
end;
procedure TCVBNorma19SEPA.GenerarCabeceraPresentador;
var
auxDC : integer;
auxIdentificador : string;
begin
HayError := False;
sReg := '';
ComprobarDatos('01');
// Código de registro (2)
sReg := '01';
// Versión del cuaderno (5)
sReg := sReg + '19143';
// Número del dato (3)
sReg := sReg + '001'; // Adeudo directo
// Identificador del presentador (35)
auxIdentificador := Presentador.NIFCIF + _PAIS_DEFECTO_ + '00';
auxDC := Modulo9710(auxIdentificador);
sReg := sReg + _PAIS_DEFECTO_;
sReg := sReg + Ajusta(IntToStr(auxDC), 'I', 2, _CERO_);
sReg := sReg + Ajusta(Presentador.Sufijo, 'I', 3, _CERO_);
sReg := sReg + Ajusta(Presentador.NIFCIF, 'D', 28, _SPCE_);
// Nombre del presentador (70)
sReg := sReg + Ajusta(Presentador.Nombre, 'D', 70, _SPCE_);
// Fecha de creación del fichero (8)
sReg := sReg + Ajusta(FormatDateTime('yyyymmdd', Fichero.Fecha), 'I', 8, _SPCE_);
// Identificación del fichero (35)
auxIdentificador := 'PRE' + FormatDateTime('yyyymmddhhnnsszzz', Now);
auxIdentificador := auxIdentificador + Fichero.Identificador;
auxIdentificador := UpperCase(ReplaceAccents(auxIdentificador));
auxIdentificador := StringReplace(auxIdentificador, ' ' , '', [rfReplaceAll]);
sReg := sReg + Ajusta(auxIdentificador, 'D', 35, _SPCE_);
// Entidad receptora (4)
sReg := sReg + Ajusta(Receptor.Entidad, 'I', 4, _CERO_);
// Oficina receptora (4)
sReg := sReg + Ajusta(Receptor.Oficina, 'I', 4, _CERO_);
// Libre (434)
sReg := sReg + Ajusta('', 'D', 434, _SPCE_);
// Fin
sReg := sReg + CRLF;
StrPCopy(@pReg, sReg);
BlockWrite(NFic, pReg, 1);
if not (length(sReg) = _LL_) then
Error(_LL_);
Inc(iTotalRegistros);
end;
procedure TCVBNorma19SEPA.GenerarRegistroAdeudo;
var
auxDC : integer;
auxCadena : string;
begin
HayError := False;
sReg := '';
ComprobarDatos('03');
// Código de registro (2)
sReg := '03';
// Versión del cuaderno (5)
sReg := sReg + '19143';
// Número de dato (3)
sReg := sReg + '003';
// Referencia del adeudo (AT-10) (35)
auxCadena := Adeudo.Referencia;
auxCadena := auxCadena + FormatDateTime('yyyymmddhhnnsszzz', Now);
sReg := sReg + Ajusta(auxCadena, 'D', 35, _SPCE_);
// Referencia única del mandato (AT-01) (35)
sReg := sReg + Ajusta(Adeudo.Referencia, 'D', 35, _SPCE_);
// Tipo de adeudo (AT-21) (4)
sReg := sReg + 'OOFF';
// Categoría del propósito (AT-59) (4)
sReg := sReg + Ajusta('', 'D', 4, _SPCE_);
// Importe del adeudo (AT-06) (11)
auxCadena := FormatFloat(_MSK_EU_, Adeudo.Importe);
auxCadena := StringReplace(auxCadena, DecimalSeparator, '', [rfReplaceAll]);
sReg := sReg + Ajusta(auxCadena, 'I', 11, _CERO_);
// Fecha de firma del mandato (AT-25) (8)
sReg := sReg + Ajusta(FormatDateTime('yyyymmdd', Now), 'D', 8, _CERO_);
// Entidad del deudor (AT-13) (11)
sReg := sReg + Ajusta(Deudor.CodigoBIC, 'D', 11, _SPCE_);
// Nombre del deudor (AT-14) (70)
sReg := sReg + Ajusta(Deudor.Nombre, 'D', 70, _SPCE_);
// Dirección del deudor D1 (AT-09) (50)
sReg := sReg + Ajusta(Deudor.Direccion1, 'D', 50, _SPCE_);
// Dirección del deudor D2 (AT-09) (50)
sReg := sReg + Ajusta(Deudor.Direccion2, 'D', 50, _SPCE_);
// Dirección del deudor D3 (AT-09) (40)
sReg := sReg + Ajusta(Deudor.Direccion3, 'D', 40, _SPCE_);
// País del deudor (AT-09) (2)
sReg := sReg + _PAIS_DEFECTO_;
// Tipo de identificación del deudor (1)
sReg := sReg + ' '; // optativo
// Identificación del deudor (código) (AT-27) (36)
sReg := sReg + Ajusta('', 'D', 36, _SPCE_);
// Identificación del deudor emisor código (otro) (AT-27) (35)
sReg := sReg + Ajusta('', 'D', 35, _SPCE_);
// Identificador de la cuenta del deudor (1)
sReg := sReg + 'A'; // A -> IBAN
// Cuenta del deudor (AT-07) (34)
sReg := sReg + Ajusta(Deudor.CuentaIBAN, 'D', 34, _SPCE_);
// Propósito del adeudo (AT-58) (4)
sReg := sReg + Ajusta('', 'D', 4, _SPCE_);
// Concepto (AT-22) (140)
sReg := sReg + Ajusta('', 'D', 140, _SPCE_);
// Libre (19)
sReg := sReg + Ajusta('', 'D', 19, _SPCE_);
// Fin
sReg := sReg + CRLF;
StrPCopy(@pReg, sReg);
BlockWrite(NFic, pReg, 1);
if not (length(sReg) = _LL_) then
Error(_LL_);
cSumaImportesTotalesAdeudos := cSumaImportesTotalesAdeudos + Adeudo.Importe;
Inc(iNumeroRegistrosAcreedor);
Inc(iNumeroRegistrosAdeudos);
Inc(iTotalRegistros);
Inc(iNumeroRegistros);
end;
procedure TCVBNorma19SEPA.GenerarTotalAcreedor;
var
auxDC : integer;
auxIdentificador, auxCadena : string;
begin
HayError := False;
sReg := '';
Inc(iNumeroRegistrosAcreedor);
// Código de registro (2)
sReg := '04';
// Identificador del acreedor (AT-02) (35)
auxIdentificador := Acreedor.NIFCIF + _PAIS_DEFECTO_ + '00';
auxDC := Modulo9710(auxIdentificador);
sReg := sReg + _PAIS_DEFECTO_;
sReg := sReg + Ajusta(IntToStr(auxDC), 'I', 2, _CERO_);
sReg := sReg + Ajusta(Acreedor.Sufijo, 'I', 3, _CERO_);
sReg := sReg + Ajusta(Acreedor.NIFCIF, 'D', 28, _SPCE_);
// Fecha de cobro (AT-11) (8)
sReg := sReg + Ajusta(FormatDateTime('yyyymmdd', FechaCobro), 'I', 8, _SPCE_);
// Total de importes (17)
auxCadena := FormatFloat(_MSK_EU_, cSumaImportesTotalesAdeudos);
auxCadena := StringReplace(auxCadena, DecimalSeparator, '', [rfReplaceAll]);
sReg := sReg + Ajusta(auxCadena, 'I', 17, _CERO_);
// Número de adeudos (8)
sReg := sReg + Ajusta(IntToStr(iNumeroRegistrosAdeudos), 'I', 8, _CERO_);
// Total de registros (10)
sReg := sReg + Ajusta(IntToStr(iNumeroRegistrosAcreedor), 'I', 10, _CERO_);
// Libre (520)
sReg := sReg + Ajusta('', 'D', 520, _SPCE_);
// Fin
sReg := sReg + CRLF;
StrPCopy(@pReg, sReg);
BlockWrite(NFic, pReg, 1);
if not (length(sReg) = _LL_) then
Error(_LL_);
Inc(iTotalRegistros);
Inc(iNumeroRegistrosAcreedor);
// Código de registro (2)
sReg := '05';
// Identificador del acreedor (AT-02) (35)
auxIdentificador := Acreedor.NIFCIF + _PAIS_DEFECTO_ + '00';
auxDC := Modulo9710(auxIdentificador);
sReg := sReg + _PAIS_DEFECTO_;
sReg := sReg + Ajusta(IntToStr(auxDC), 'I', 2, _CERO_);
sReg := sReg + Ajusta(Acreedor.Sufijo, 'I', 3, _CERO_);
sReg := sReg + Ajusta(Acreedor.NIFCIF, 'D', 28, _SPCE_);
// Total de importes (17)
auxCadena := FormatFloat(_MSK_EU_, cSumaImportesTotalesAdeudos);
auxCadena := StringReplace(auxCadena, DecimalSeparator, '', [rfReplaceAll]);
sReg := sReg + Ajusta(auxCadena, 'I', 17, _CERO_);
// Número de adeudos (8)
sReg := sReg + Ajusta(IntToStr(iNumeroRegistrosAdeudos), 'I', 8, _CERO_);
// Total de registros (10)
sReg := sReg + Ajusta(IntToStr(iNumeroRegistrosAcreedor), 'I', 10, _CERO_);
// Libre (528)
sReg := sReg + Ajusta('', 'D', 528, _SPCE_);
// Fin
sReg := sReg + CRLF;
StrPCopy(@pReg, sReg);
BlockWrite(NFic, pReg, 1);
if not (length(sReg) = _LL_) then
Error(_LL_);
Inc(iTotalRegistros);
end;
procedure TCVBNorma19SEPA.GenerarCabeceraAcreedor;
var
auxDC : integer;
auxIdentificador : string;
begin
HayError := False;
sReg := '';
iNumeroRegistrosAdeudos := 0;
iNumeroRegistrosAcreedor := 0;
cSumaImportesTotalesAdeudos := 0;
ComprobarDatos('02');
// Código de registro (2)
sReg := '02';
// Versión del cuaderno (5)
sReg := sReg + '19143';
// Número de dato (3)
sReg := sReg + '002';
// Identificador del acreedor (AT-02) (35)
auxIdentificador := Acreedor.NIFCIF + _PAIS_DEFECTO_ + '00';
auxDC := Modulo9710(auxIdentificador);
sReg := sReg + _PAIS_DEFECTO_;
sReg := sReg + Ajusta(IntToStr(auxDC), 'I', 2, _CERO_);
sReg := sReg + Ajusta(Acreedor.Sufijo, 'I', 3, _CERO_);
sReg := sReg + Ajusta(Acreedor.NIFCIF, 'D', 28, _SPCE_);
// Fecha de cobro (AT-11) (8)
sReg := sReg + Ajusta(FormatDateTime('yyyymmdd', FechaCobro), 'I', 8, _SPCE_);
// Nombre del acreedor (AT-03) (70)
sReg := sReg + Ajusta(Acreedor.Nombre, 'D', 70, _SPCE_);
// Dirección del acreedor D1 (AT-05) (50)
sReg := sReg + Ajusta(Acreedor.Direccion1, 'D', 50, _SPCE_);
// Dirección del acreedor D2 (AT-05) (50)
sReg := sReg + Ajusta(Acreedor.Direccion2, 'D', 50, _SPCE_);
// Dirección del acreedor D3 (AT-05) (40)
sReg := sReg + Ajusta(Acreedor.Direccion3, 'D', 40, _SPCE_);
// País del acreedor (AT-05) (2)
sReg := sReg + _PAIS_DEFECTO_;
// Cuenta del acreedor (AT-04) (34)
sReg := sReg + Ajusta(Acreedor.CuentaIBAN, 'D', 34, _SPCE_);
// Libre (301)
sReg := sReg + Ajusta('', 'D', 301, _SPCE_);
// Fin
sReg := sReg + CRLF;
StrPCopy(@pReg, sReg);
BlockWrite(NFic, pReg, 1);
if not (length(sReg) = _LL_) then
Error(_LL_);
Inc(iNumeroRegistrosAcreedor);
Inc(iTotalRegistros);
end;
procedure TCVBNorma19SEPA.ComprobarDatos(sParte: string);
var
bError: boolean;
begin
bError := False;
if sParte = '01' then // cabecera / presentador
begin
if EsCadenaVacia(Presentador.NIFCIF) then
begin
Presentador.NIFCIF := _INDICA_;
bError := True;
end
else
Presentador.NIFCIF := UpperCase(Presentador.NIFCIF);
if EsCadenaVacia(Presentador.Sufijo) then
begin
Presentador.Sufijo := _INDICA_;
bError := True;
end;
if EsCadenaVacia(Presentador.Nombre) then
begin
Presentador.Nombre := _INDICA_;
bError := True;
end
else
Presentador.Nombre := UpperCase(ReplaceAccents(Presentador.Nombre));
if EsCadenaVacia(Fichero.Identificador) then
begin
Fichero.Identificador := _INDICA_;
bError := True;
end;
if EsCadenaVacia(Receptor.Entidad) then
begin
Receptor.Entidad := _INDICA_;
bError := True;
end;
if EsCadenaVacia(Receptor.Oficina) then
begin
Receptor.Oficina := _INDICA_;
bError := True;
end;
if bError then
ShowMessage('Faltan datos al procesar el registro 01: ' + CRLF + CRLF +
'NIF/CIF del presentador: ' + Presentador.NIFCIF + CRLF +
'Sufijo del presentador: ' + Presentador.Sufijo + CRLF +
'Nombre del presentador: ' + Presentador.Nombre + CRLF +
'Identificador del fichero: ' + Fichero.Identificador + CRLF +
'Cód. entidad del receptor: ' + Receptor.Entidad + CRLF +
'Cód. oficina del receptor: ' + Receptor.Oficina + CRLF
);
end;
if sParte = '02' then // acreedor
begin
if EsCadenaVacia(Acreedor.NIFCIF) then
begin
Acreedor.NIFCIF := _INDICA_;
bError := True;
end
else
Acreedor.NIFCIF := UpperCase(Acreedor.NIFCIF);
if EsCadenaVacia(Acreedor.Nombre) then
begin
Acreedor.Nombre := _INDICA_;
bError := True;
end
else
Acreedor.Nombre := UpperCase(ReplaceAccents(Acreedor.Nombre));
if EsCadenaVacia(Acreedor.Direccion1) then
begin
Acreedor.Direccion1 := _INDICA_;
bError := True;
end
else
Acreedor.Direccion1 := UpperCase(ReplaceAccents(Acreedor.Direccion1));
Acreedor.Direccion2 := UpperCase(ReplaceAccents(Acreedor.Direccion2));
Acreedor.Direccion3 := UpperCase(ReplaceAccents(Acreedor.Direccion3));
Acreedor.Pais := UpperCase(ReplaceAccents(Acreedor.Pais));
if EsCadenaVacia(Acreedor.CuentaIBAN) then
begin
Acreedor.CuentaIBAN := _INDICA_;
bError := True;
end;
if EsCadenaVacia(Acreedor.Sufijo) then
begin
Acreedor.Sufijo := _INDICA_;
bError := True;
end;
if bError then
ShowMessage('Faltan datos al procesar el registro 02: ' + CRLF + CRLF +
'NIF/CIF del acreedor: ' + Acreedor.NIFCIF + CRLF +
'Sufijo del acreedor: ' + Acreedor.Sufijo + CRLF +
'Nombre del acreedor: ' + Acreedor.Nombre + CRLF +
'Cuenta IBAN del acreedor: ' + Acreedor.CuentaIBAN + CRLF +
'Dirección 1 del acreedor: ' + Acreedor.Direccion1 + CRLF
);
end;
if sParte = '03' then // deudor
begin
// Quitar espacios y caracteres no estándar
Adeudo.Referencia := StringReplace(UpperCase(ReplaceAccents(Adeudo.Referencia)), ' ', '', [rfReplaceAll]);
if EsCadenaVacia(Deudor.Nombre) then
begin
Deudor.Nombre := _INDICA_;
bError := True;
end
else
Deudor.Nombre := UpperCase(ReplaceAccents(Deudor.Nombre));
if EsCadenaVacia(Deudor.Direccion1) then
begin
Deudor.Direccion1 := _INDICA_;
bError := True;
end
else
Deudor.Direccion1 := UpperCase(ReplaceAccents(Deudor.Direccion1));
Deudor.Direccion2 := UpperCase(ReplaceAccents(Deudor.Direccion2));
Deudor.Direccion3 := UpperCase(ReplaceAccents(Deudor.Direccion3));
Deudor.Pais := UpperCase(ReplaceAccents(Deudor.Pais));
if EsCadenaVacia(Deudor.CuentaIBAN) then
begin
Deudor.CuentaIBAN := _INDICA_;
bError := True;
end;
// No obligar a tener código BIC/SWIFT
{if EsCadenaVacia(Deudor.CodigoBIC) then
begin
Deudor.CodigoBIC := _INDICA_;
bError := True;
end;}
if bError then
ShowMessage('Faltan datos al procesar el registro 03: ' + CRLF + CRLF +
'Nombre del deudor: ' + Deudor.Nombre + CRLF +
'Dirección 1 del deudor: ' + Deudor.Direccion1 + CRLF +
'Cuenta IBAN del deudor: ' + Deudor.CuentaIBAN + CRLF +
'Código BIC del deudor: ' + Deudor.CodigoBIC
);
end;
end;
procedure TCVBNorma19SEPA.Cerrar;
var
auxCadena : string;
begin
HayError := False;
sReg := '';
Inc(iTotalRegistros);
// Código de registro
sReg := '99';
// Total de importes general (17)
auxCadena := FormatFloat(_MSK_EU_, cSumaImportesTotalesAdeudos);
auxCadena := StringReplace(auxCadena, DecimalSeparator, '', [rfReplaceAll]);
sReg := sReg + Ajusta(auxCadena, 'I', 17, _CERO_);
// Número de registros (8)
sReg := sReg + Ajusta(IntToStr(iNumeroRegistros), 'I', 8, _CERO_);
// Total de registros (10)
sReg := sReg + Ajusta(IntToStr(iTotalRegistros), 'I', 10, _CERO_);
// Libre (563)
sReg := sReg + Ajusta('', 'D', 563, _SPCE_);
// Fin
sReg := sReg + CRLF;
StrPCopy(@pReg, sReg);
BlockWrite(NFic, pReg, 1);
if not (length(sReg) = _LL_) then
Error(_LL_);
CloseFile(NFic);
end;
procedure TCVBNorma19SEPA.Error(iErr: integer);
begin
NrError := iErr;
HayError := True;
if Assigned(FEnCasoError) then
FEnCasoError(Self)
else
CloseFile(NFic);
if NrError = _LL_ then
raise Exception.Create('Error en la longitud de la línea')
else
raise Exception.Create('Error en la generación del fichero');
end;
end.