diff --git a/Source/Modulos/Banca electronica/BancaElectronica_Group.bdsgroup b/Source/Modulos/Banca electronica/BancaElectronica_Group.bdsgroup new file mode 100644 index 00000000..75ac0723 --- /dev/null +++ b/Source/Modulos/Banca electronica/BancaElectronica_Group.bdsgroup @@ -0,0 +1,25 @@ + + + + + + + + + + + ..\..\DataAbstract_D10\DataAbstract_D10.bdsproj + ..\..\Base\Base.bdsproj + ..\..\Base\ControllerBase\ControllerBase.bdsproj + ..\..\Base\GUIBase\GUIBase.bdsproj + ..\..\Base\Usuarios\Usuarios.bdsproj + Controller\BancaElectronica_controller.bdsproj + Views\BancaElectronica_view.bdsproj + Plugin\BancaElectronica_plugin.bdsproj + ..\..\Cliente\FactuGES.bdsproj + DataAbstract_D10.bpl Base.bpl ControllerBase.bpl GUIBase.bpl Usuarios.bpl BancaElectronica_controller.bpl BancaElectronica_view.bpl BancaElectronica_plugin.bpl FactuGES.exe + + + + diff --git a/Source/Modulos/Banca electronica/Controller/View/uIEditorExportacionNorma32.pas b/Source/Modulos/Banca electronica/Controller/View/uIEditorExportacionNorma32.pas new file mode 100644 index 00000000..c56c01dd --- /dev/null +++ b/Source/Modulos/Banca electronica/Controller/View/uIEditorExportacionNorma32.pas @@ -0,0 +1,40 @@ +unit uIEditorExportacionNorma32; + +interface + +type + IEditorExportacionNorma32 = interface + ['{84B46A6B-5791-4E30-9ED0-2DDBCC84F353}'] + + procedure SetCodigoEntidad(const AValue: String); + function GetCodigoEntidad : String; + property CodigoEntidad : String read GetCodigoEntidad write SetCodigoEntidad; + + procedure SetCodigoAgencia(const AValue: String); + function GetCodigoAgencia : String; + property CodigoAgencia : String read GetCodigoAgencia write SetCodigoAgencia; + + procedure SetFechaCargo(const AValue: TDateTime); + function GetFechaCargo : TDateTime; + property FechaCargo : TDateTime read GetFechaCargo write SetFechaCargo; + + procedure SetFichero(const AValue: String); + function GetFichero : String; + property Fichero : String read GetFichero write SetFichero; + + function GetCodigoINE: String; + procedure SetCodigoINE(const Value: String); + property CodigoINE : String read GetCodigoINE write SetCodigoINE; + + procedure SetCodigoIdentif(const Value: String); + function GetCodigoIdentif: String; + property CodigoIdentif : String read GetCodigoIdentif write SetCodigoIdentif; + + function ShowModal : Integer; + procedure Release; + end; + + +implementation + +end. diff --git a/Source/Modulos/Banca electronica/Model/BancaElectronica_model.res b/Source/Modulos/Banca electronica/Model/BancaElectronica_model.res new file mode 100644 index 00000000..86c94e6a Binary files /dev/null and b/Source/Modulos/Banca electronica/Model/BancaElectronica_model.res differ diff --git a/Source/Modulos/Banca electronica/Utiles/CVBNorma32CSB.pas b/Source/Modulos/Banca electronica/Utiles/CVBNorma32CSB.pas new file mode 100644 index 00000000..60aa210e --- /dev/null +++ b/Source/Modulos/Banca electronica/Utiles/CVBNorma32CSB.pas @@ -0,0 +1,716 @@ +unit CVBNorma32CSB; + +interface + +uses + Messages, SysUtils, Classes, Dialogs, CVBUtils; + +type + + TProcedimiento = (prPrimero, prSegundo); + TCVBParte = (CABECERA_GENERAL, CABECERA_REMESA, + REGISTRO1, REGISTRO2, REGISTRO3, FIN_REMESA, FIN_GENERAL); + + TCVBNorma32CSB = class(TComponent) + private + pReg: array[0..152] of char; // Un digito más por el /0 + _LL_: integer; // Longitud Línea. Aquí almacenamos el valor 164 para usarlo + // en el resto del componente. + _INDICA_: string; + _CERO_, _SPCE_: char; + _MSK_PT_, _MSK_EU_: string; + + prProced: TProcedimiento; + HayError: boolean; + + FEuro: boolean; + FDepura: boolean; + + NFic: file; + + fSumaImpRecibos: double; // Suma de los recibos dentro de una remesa + fSumaImpRemesas: double; // Suma de las remesas dentro del fichero + + iNumRecibos: integer; // Nº de recibos dentro de una remesa + iNumRemesas: integer; // Nº de remesas dentro del fichero + + iTotalLineas: integer; // Nº de líneas en el fichero + iTotalRecibos : integer; // Nº de recibos dentro de un fichero + + FEnCasoError: TNotifyEvent; + sReg: string; + + _19_, _58_, _32_: integer; + protected + procedure ChequearDatos(Parte: TCVBParte); overload; + procedure Error(iErr: integer); dynamic; + procedure CompRegistro1; + procedure CompRegistro2; + procedure CompRegistro3; + public + _NORMA_: integer; + NrError: integer; + CRLF: string; + FNomFic: string; // Nombre del archivo en disco + + // CABECERA FICHERO + FechaFichero: TDateTime; + EntReceptora: string; //4 + SucReceptora: string; //4 + + // CABECERA REMESA + NumRemesa: string; //4 + IdCedente: string; //15 + + AboEnt: string; //4 + AboOfi: string; //4 + AboDC: string; //2 + AboCC: string; //10 + + AdeEnt: string; //4 + AdeOfi: string; //4 + AdeDC: string; //2 + AdeCC: string; //10 + + ImpEnt: string; //4 + ImpSuc: string; //4 + ImpDC: string; //2 + ImpCC: string; //10 + + // REGISTRO REMESA + // (I) + RegNumRecibo: string; // 7 + RegCodigoINE: string; // 9 + RegPlazaLibr: string; // 20 + RegImpEfecto: double; // 9 + RegVtoEfecto: TDateTime; // 6 + // (II) + RegCodEnt: string; // 4 + RegCodOfi: string; // 4 + RegDC: string; // 2 + RegCC: string; // 10 + RegLibrador: string; // 34 + RegLibrado: string; // 34 + RegInfoAdic: string; // 30 + // (III) + RegDomicilio: string; // 34 + RegCodPostal: string; // 5 + RegPoblacion: string; // 20 + RegNIF: string; // 9 + + + + constructor Create(AOwner: TComponent); override; + procedure Abrir; + procedure Cerrar; + procedure IniCabeceraFichero; + procedure IniCabeceraRemesa; + procedure IniRegistro; + procedure CompCabeceraFichero; + procedure CompCabeceraRemesa; + procedure CompRegistro; + procedure CompFinRemesa; + published + property NomFichero: string read FNomFic write FNomFic; + property Procedimiento: TProcedimiento read prProced write prProced default prPrimero; + property Euros: boolean read FEuro write FEuro default False; + property Depura: boolean read FDepura write FDepura default False; + property EnCasoError: TNotifyEvent read FEnCasoError write FEnCasoError; + end; + +implementation + +constructor TCVBNorma32CSB.Create(AOwner: TComponent); +begin + inherited Create(AOwner); + {Asignar la propiedades por defecto} + + _32_ := 32; + _19_ := 19; + _58_ := 58; + + _LL_ := high(pReg); + + _INDICA_ := '<--'; + _CERO_ := '0'; + _SPCE_ := ' '; + + _MSK_PT_ := '0000000000'; + _MSK_EU_ := '00000000.00'; + +end; + +//******************************************************************************* + +procedure TCVBNorma32CSB.Abrir; +begin + HayError := False; + + AssignFile(NFic, FNomFic); +{$I+} + rewrite(Nfic, _LL_); +{$I-} + if IOResult <> 0 then + error(0); + + fSumaImpRecibos := 0.0; + fSumaImpRemesas := 0.0; + + iNumRecibos := 0; + iNumRemesas := 0; + + iTotalLineas := 0; + iTotalRecibos := 0; + + IniCabeceraFichero; + IniCabeceraRemesa; + IniRegistro; + + if CRLF = '' then + CRLF := #13 + #10; +end; + +procedure TCVBNorma32CSB.IniCabeceraFichero; +begin + FechaFichero := 0; + EntReceptora := ''; + SucReceptora := ''; +end; + +procedure TCVBNorma32CSB.IniCabeceraRemesa; +begin + NumRemesa := '0001'; // <-------------------------------------------- + + AboEnt := ''; + AboOfi := ''; + AboDC := ''; + AboCC := ''; + + AdeEnt := ''; + AdeOfi := ''; + AdeDC := ''; + AdeCC := ''; + + ImpEnt := ''; + ImpSuc := ''; + ImpDC := ''; + ImpCC := ''; +end; + +procedure TCVBNorma32CSB.IniRegistro; +begin + // (I) + RegNumRecibo := ''; + RegCodigoINE := ''; + RegPlazaLibr := ''; + RegImpEfecto := 0.0; + RegVtoEfecto := 0; + // (II) + RegCodEnt := ''; + RegCodOfi := ''; + RegDC := ''; + RegCC := ''; + RegLibrador := ''; + RegLibrado := ''; + RegInfoAdic := ''; + // (III) + RegDomicilio := ''; + RegCodPostal := ''; + RegPoblacion := ''; + RegNIF := ''; +end; + +procedure TCVBNorma32CSB.CompCabeceraFichero; +begin + HayError := False; + sReg := ''; + ChequearDatos(CABECERA_GENERAL); + + // A + sReg := '02' + '65'; + sReg := sReg + Ajusta('', 'I', 2, _SPCE_); //2 + + // B + sReg := sReg + Ajusta(FormatDateTime('ddmmyy', FechaFichero), 'I', 6, _SPCE_); //6 + sReg := sReg + Ajusta('1', 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + + // C + sReg := sReg + Ajusta('', 'I', 15, _SPCE_); //15 + sReg := sReg + Ajusta('', 'I', 4, _SPCE_); //4 + sReg := sReg + Ajusta('', 'I', 4, _SPCE_); //4 + sReg := sReg + Ajusta(EntReceptora, 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta(SucReceptora, 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + + // D + sReg := sReg + Ajusta('', 'I', 61, _SPCE_); //61 + + // E + sReg := sReg + Ajusta('', 'I', 24, _SPCE_); //24 + + sReg := sReg + CRLF; //2 + + if not (length(sReg) = _LL_) then + Error(_LL_); + + StrPCopy(@pReg, sReg); + Blockwrite(NFic, pReg, 1); + + Inc(iTotalLineas); +end; + +procedure TCVBNorma32CSB.CompCabeceraRemesa; +begin + HayError := False; + + sReg := ''; + + ChequearDatos(CABECERA_REMESA); + Inc(iNumRemesas); + + // A + sReg := '11' + '65'; + sReg := sReg + Ajusta('', 'I', 2, _SPCE_); //2 + + // B + sReg := sReg + Ajusta(FormatDateTime('ddmmyy', FechaFichero), 'I', 6, _SPCE_); //6 + sReg := sReg + Ajusta(IntToStr(iNumRemesas), 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + + // C + sReg := sReg + Ajusta(IdCedente, 'D', 15, _SPCE_); //15 + sReg := sReg + '1'; + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + sReg := sReg + Ajusta('', 'I', 5, _SPCE_); //5 + sReg := sReg + Ajusta('', 'I', 4, _SPCE_); //4 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + + // D + sReg := sReg + Ajusta(AboEnt, 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta(AboOfi, 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta(AboDC, 'I', 2, _CERO_); //2 + sReg := sReg + Ajusta(AboCC, 'I', 10, _CERO_); //10 + + sReg := sReg + Ajusta(AdeEnt, 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta(AdeOfi, 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta(AdeDC, 'I', 2, _CERO_); //2 + sReg := sReg + Ajusta(AdeCC, 'I', 10, _CERO_); //10 + + sReg := sReg + Ajusta(ImpEnt, 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta(ImpSuc, 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta(ImpDC, 'I', 2, _CERO_); //2 + sReg := sReg + Ajusta(ImpCC, 'I', 10, _CERO_); //10 + + sReg := sReg + Ajusta('', 'I', 1, _SPCE_); //1 + + // E + sReg := sReg + Ajusta('', 'I', 24, _SPCE_); //24 + + sReg := sReg + CRLF; //2 + + if not (length(sReg) = _LL_) then + Error(_LL_); + + StrPCopy(@pReg, sReg); + Blockwrite(NFic, pReg, 1); + + Inc(iTotalLineas); +end; + +procedure TCVBNorma32CSB.CompFinRemesa; +var + sTotImp, cIT : string; + iP : integer; +begin + HayError := False; + sReg := ''; + ChequearDatos(FIN_REMESA); + + // A + sReg := '71' + '65'; + sReg := sReg + Ajusta('', 'I', 2, _SPCE_); //2 + + // B + sReg := sReg + Ajusta(FormatDateTime('ddmmyy', FechaFichero), 'I', 6, _SPCE_); //6 + sReg := sReg + Ajusta(NumRemesa, 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + + // C + sReg := sReg + Ajusta('', 'I', 37, _SPCE_); //37 + + // D + sReg := sReg + Ajusta('', 'I', 10, _SPCE_); //10 + + sTotImp := FormatFloat(_MSK_EU_, fSumaImpRecibos); + iP := pos(',', sTotImp); + if iP < 1 then + iP := pos('.', sTotImp); + cIT := copy(sTotImp, 1, iP - 1); + sTotImp := cIT + copy(sTotImp, iP + 1, 2); + sReg := sReg + Ajusta(sTotImp, 'I', 10, _CERO_); // 10 + + sReg := sReg + Ajusta('', 'I', 10, _SPCE_); //10 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + sReg := sReg + Ajusta('', 'I', 7, _SPCE_); //7 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + + // E + sReg := sReg + Ajusta('', 'I', 5, _SPCE_); //5 + { Nº de registros de la remesa incluidos la cabecera y éste mismo: + Num.registros = 1 (cabecera) + (3 registros * Num.recibos) + 1 (este pie) + } + sReg := sReg + Ajusta(IntToStr(1 + (3*iNumRecibos) + 1), 'I', 7, _CERO_); //7 + sReg := sReg + Ajusta(IntToStr(iNumRecibos), 'I', 6, _CERO_); //6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); //6 + + sReg := sReg + CRLF; //2 + + if not (length(sReg) = _LL_) then + Error(_LL_); + + StrPCopy(@pReg, sReg); + Blockwrite(NFic, pReg, 1); + + Inc(iTotalLineas); + + // Acumular la suma de los importes de las remesas en el fichero + fSumaImpRemesas := fSumaImpRemesas + fSumaImpRecibos; + + // Poner a cero la suma de los recibos y el número de recibos + fSumaImpRecibos := 0.0; + iNumRecibos := 0; +end; + +procedure TCVBNorma32CSB.CompRegistro; +begin + CompRegistro1; + CompRegistro2; + CompRegistro3; + + // Acumular la suma de los recibos en la remesa + fSumaImpRecibos := fSumaImpRecibos + RegImpEfecto; + + // Acumular el nº de recibos en la remesa + Inc(iNumRecibos); + Inc(iTotalRecibos); +end; + +procedure TCVBNorma32CSB.CompRegistro1; +var + sTotImp, cIT : string; + iP: integer; +begin + HayError := False; + + sReg := ''; + + ChequearDatos(REGISTRO1); + + // A + sReg := '25' + '65'; + sReg := sReg + Ajusta('', 'I', 2, _SPCE_); // 2 + + // B + // Convertir referencia EL/0001 - 1 => EL00001-1 + RegNumRecibo := StringReplace(RegNumRecibo, '/', '0', []); + RegNumRecibo := StringReplace(RegNumRecibo, ' - ', '-', []); + sReg := sReg + Ajusta(RegNumRecibo, 'D', 15, _SPCE_); // 15 + sReg := sReg + Ajusta(FormatDateTime('ddmmyy', FechaFichero), 'I', 6, _SPCE_); // 6 + sReg := sReg + Ajusta(NumRemesa, 'I', 4, _CERO_); // 4 + + // C + sReg := sReg + Ajusta(RegCodigoINE, 'I', 9, _SPCE_); // 9 + sReg := sReg + Ajusta('', 'I', 2, _SPCE_); // 2 + + // D + sReg := sReg + Ajusta(RegPlazaLibr, 'D', 20, _SPCE_); // 20 + sReg := sReg + Ajusta('', 'I', 1, _SPCE_); // 1 + + // E + sReg := sReg + Ajusta('', 'I', 15, _SPCE_); // 15 + sReg := sReg + Ajusta('', 'I', 9, _SPCE_); // 9 + + sTotImp := FormatFloat(_MSK_EU_, RegImpEfecto); + iP := pos(',', sTotImp); + if iP < 1 then + iP := pos('.', sTotImp); + cIT := copy(sTotImp, 1, iP - 1); + sTotImp := cIT + copy(sTotImp, iP + 1, 2); + sReg := sReg + Ajusta(sTotImp, 'I', 9, _CERO_); // 9 + + sReg := sReg + Ajusta('', 'I', 15, _SPCE_); // 15 + sReg := sReg + Ajusta(FormatDateTime('ddmmyy', RegVtoEfecto), 'I', 6, _SPCE_); // 6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); // 6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); // 6 + sReg := sReg + Ajusta('', 'I', 1, _SPCE_); // 1 + sReg := sReg + Ajusta('', 'I', 4, _SPCE_); // 4 + + // F + sReg := sReg + Ajusta('', 'I', 16, _SPCE_); // 16 + + sReg := sReg + CRLF; //2 + + if not (length(sReg) = _LL_) then + Error(_LL_); + + StrPCopy(@pReg, sReg); + Blockwrite(NFic, pReg, 1); + + Inc(iTotalLineas); +end; + +procedure TCVBNorma32CSB.CompRegistro2; +begin + HayError := False; + + sReg := ''; + + ChequearDatos(REGISTRO2); + + // A + sReg := '26' + '65'; + sReg := sReg + Ajusta('', 'I', 2, _SPCE_); // 2 + + // B + sReg := sReg + Ajusta(RegNumRecibo, 'D', 15, _SPCE_); // 15 + sReg := sReg + Ajusta('', 'I', 2, _SPCE_); // 2 + sReg := sReg + Ajusta('2', 'I', 1, _SPCE_); // 1 + sReg := sReg + Ajusta('000000', 'I', 6, _CERO_); // 6 + sReg := sReg + Ajusta('2', 'I', 1, _SPCE_); // 1 + sReg := sReg + Ajusta('0', 'I', 1, _SPCE_); // 1 + + // C + sReg := sReg + Ajusta(RegCodEnt, 'I', 4, _CERO_); //4 + sReg := sReg + Ajusta(RegCodOfi, 'I', 4, _CERO_); //4 + if Length(RegDC) = 0 then + RegDC := '**'; + sReg := sReg + Ajusta(RegDC, 'I', 2, _CERO_); //2 + sReg := sReg + Ajusta(RegCC, 'I', 10, _CERO_); //10 + + // D + sReg := sReg + Ajusta(RegLibrador, 'D', 34, _SPCE_); // 34 + sReg := sReg + Ajusta(RegLibrado, 'D', 34, _SPCE_); // 34 + sReg := sReg + Ajusta(RegInfoAdic, 'D', 30, _SPCE_); // 30 + + sReg := sReg + CRLF; //2 + + if not (length(sReg) = _LL_) then + Error(_LL_); + + StrPCopy(@pReg, sReg); + Blockwrite(NFic, pReg, 1); + + Inc(iTotalLineas); +end; + +procedure TCVBNorma32CSB.CompRegistro3; +begin + HayError := False; + + sReg := ''; + + ChequearDatos(REGISTRO3); + + // A + sReg := '27' + '65'; + sReg := sReg + Ajusta('', 'I', 2, _SPCE_); // 2 + + // B + sReg := sReg + Ajusta(RegNumRecibo, 'D', 15, _SPCE_); // 15 + sReg := sReg + Ajusta('', 'I', 2, _SPCE_); // 2 + sReg := sReg + Ajusta(RegDomicilio, 'D', 34, _SPCE_); // 34 + sReg := sReg + Ajusta(RegCodPostal, 'I', 5, _SPCE_); // 5 + sReg := sReg + Ajusta(RegPoblacion, 'D', 20, _SPCE_); // 20 + sReg := sReg + Ajusta(RegCodigoINE, 'I', 2, _SPCE_); // 2 + sReg := sReg + Ajusta('', 'I', 7, _SPCE_); // 7 + sReg := sReg + Ajusta(RegNIF, 'I', 9, _SPCE_); // 9 + sReg := sReg + Ajusta('', 'I', 50, _SPCE_); // 50 + + sReg := sReg + CRLF; //2 + + if not (length(sReg) = _LL_) then + Error(_LL_); + + StrPCopy(@pReg, sReg); + Blockwrite(NFic, pReg, 1); + + Inc(iTotalLineas); +end; + +procedure TCVBNorma32CSB.Cerrar; +var + sTotImp, cIT : string; + iP: integer; +begin + HayError := False; + sReg := ''; + + Inc(iTotalLineas); + + // A + sReg := '98' + '65'; + sReg := sReg + Ajusta('', 'I', 2, _SPCE_); // 2 + + // B + sReg := sReg + Ajusta('', 'I', 22, _SPCE_); // 22 + + // C + sReg := sReg + Ajusta('', 'I', 37, _SPCE_); // 37 + + // D + sReg := sReg + Ajusta('', 'I', 10, _SPCE_); // 10 + + sTotImp := FormatFloat(_MSK_EU_, fSumaImpRemesas); + iP := pos(',', sTotImp); + if iP < 1 then + iP := pos('.', sTotImp); + cIT := copy(sTotImp, 1, iP - 1); + sTotImp := cIT + copy(sTotImp, iP + 1, 2); + sReg := sReg + Ajusta(sTotImp, 'I', 10, _CERO_); // 10 + + sReg := sReg + Ajusta('', 'I', 10, _SPCE_); // 10 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); // 6 + sReg := sReg + Ajusta('', 'I', 7, _SPCE_); // 7 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); // 6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); // 6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); // 6 + + // E + sReg := sReg + Ajusta(IntToStr(iNumRemesas), 'I', 5, _CERO_); //5 + sReg := sReg + Ajusta(IntToStr(iTotalLineas), 'I', 7, _CERO_); //7 + sReg := sReg + Ajusta(IntToStr(iTotalRecibos), 'I', 6, _CERO_); //6 + sReg := sReg + Ajusta('', 'I', 6, _SPCE_); // 6 + + sReg := sReg + CRLF; //2 + + if not (length(sReg) = _LL_) then + Error(_LL_); + + StrPCopy(@pReg, sReg); + Blockwrite(NFic, pReg, 1); + + CloseFile(NFic); +end; + + +procedure TCVBNorma32CSB.ChequearDatos(Parte: TCVBParte); +var + bError: boolean; +begin +{ bError := False; + + if Parte = CABECERA_GENERAL then + begin + if ((Presentador = '') or (NomCliPres = '') or + (EntRecepPres = '') or (OfiRecepPres = '')) then + begin + if Presentador = '' then + Presentador := _INDICA_; + if NomCliPres = '' then + NomCliPres := _INDICA_; + if EntRecepPres = '' then + EntRecepPres := _INDICA_; + if OfiRecepPres = '' then + OfiRecepPres := _INDICA_; + bError := True; + end; + end + else + if iParte = 2 then + begin + if ((Ordenante = '') or (NomCliOrd = '') or + (EntOrde = '') or (OfiOrde = '') or + (CcOrde = '')) then + begin + if Ordenante = '' then + Ordenante := _INDICA_; + if NomCliOrd = '' then + NomCliOrd := _INDICA_; + if EntOrde = '' then + EntOrde := _INDICA_; + if OfiOrde = '' then + OfiOrde := _INDICA_; + if CcOrde = '' then + CcOrde := _INDICA_; + bError := True; + end; + end + else + if (iParte = 3) or (iParte = 4) then + begin + if ((Referencia = '') or (NomTitDom = '') or + (EntTitDom = '') or (OfiTitDom = '') or + (ccTitDom = '')) then + begin + if Referencia = '' then + Referencia := _INDICA_; + if NomTitDom = '' then + NomTitDom := _INDICA_; + if EntTitDom = '' then + EntTitDom := _INDICA_; + if OfiTitDom = '' then + OfiTitDom := _INDICA_; + if ccTitDom = '' then + ccTitDom := _INDICA_; + bError := True; + end; + end; + + if bError then + ShowMessage('' + CRLF + + 'Faltan datos al procesar el siguiente registro: ' + CRLF + CRLF + + 'Código Cli/Pro: ' + Referencia + CRLF + + 'Nombre Titular: ' + NomTitDom + CRLF + + 'Entidad Domiciliar: ' + EntTitDom + CRLF + + 'Oficina Domiciliar: ' + OfiTitDom + CRLF + + 'Cuenta Domiciliar: ' + ccTitDom + CRLF + + 'Presentador: ' + Presentador + CRLF + + 'Nombre Cliente Pres:' + NomCliPres + CRLF + + 'Entidad Receptora P:' + EntRecepPres + CRLF + + 'Oficina Receptora P:' + OfiRecepPres + CRLF + + 'Ordenante: ' + Ordenante + CRLF + + 'Nombre Cliente Ord.:' + NomCliOrd + CRLF + + 'Entidad Ordenante: ' + EntOrde + CRLF + + 'Oficina Ordenante: ' + OfiOrde + CRLF + + 'Cuenta Ordenante: ' + CcOrde + ); + + if iParte = 3 then + begin + if bError then + begin + if ((fImportePts = 0) and (FEuro = False)) or + ((fImporteEu = 0) and (FEuro = True)) then + begin + ShowMessage('¡¡¡ El importe no puede ser cero !!!'); + Error(27); + end; + end; + end;} +end; + +procedure TCVBNorma32CSB.Error(iErr: integer); +begin + NrError := iErr; + HayError := True; + if Assigned(FEnCasoError) then + FEnCasoError(Self) + else + if FDepura = False then + begin + 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; + + +end. diff --git a/Source/Modulos/Banca electronica/Views/uEditorExportacionNorma32.dfm b/Source/Modulos/Banca electronica/Views/uEditorExportacionNorma32.dfm new file mode 100644 index 00000000..c7585d1a --- /dev/null +++ b/Source/Modulos/Banca electronica/Views/uEditorExportacionNorma32.dfm @@ -0,0 +1,335 @@ +object fEditorExportacionNorma32: TfEditorExportacionNorma32 + Left = 0 + Top = 0 + ActiveControl = edtCodEntidad + BorderStyle = bsDialog + Caption = 'Volcado de remesas a disco (Norma 32)' + ClientHeight = 366 + ClientWidth = 389 + Color = clBtnFace + Font.Charset = DEFAULT_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + OldCreateOrder = False + Position = poMainFormCenter + OnCreate = FormCreate + DesignSize = ( + 389 + 366) + PixelsPerInch = 96 + TextHeight = 13 + object Label2: TLabel + Left = 24 + Top = 144 + Width = 90 + Height = 13 + Margins.Bottom = 0 + Caption = 'Entidad receptora:' + end + object Label3: TLabel + Left = 24 + Top = 171 + Width = 42 + Height = 13 + Margins.Bottom = 0 + Caption = 'Agencia:' + end + object JvgWizardHeader1: TJvgWizardHeader + Left = 0 + Top = 0 + Width = 389 + Height = 60 + CaptionFont.Charset = DEFAULT_CHARSET + CaptionFont.Color = clWindowText + CaptionFont.Height = -11 + CaptionFont.Name = 'Tahoma' + CaptionFont.Style = [fsBold] + CommentFont.Charset = DEFAULT_CHARSET + CommentFont.Color = clWindowText + CommentFont.Height = -11 + CommentFont.Name = 'Tahoma' + CommentFont.Style = [] + SymbolFont.Charset = DEFAULT_CHARSET + SymbolFont.Color = clHighlightText + SymbolFont.Height = -35 + SymbolFont.Name = 'Wingdings' + SymbolFont.Style = [fsBold] + Captions.Strings = ( + 'Volcado de remesas a disco') + Comments.Strings = ( + 'Introduzca los siguientes datos para realizar el volcado') + Gradient.FromColor = clHighlight + Gradient.ToColor = clWindow + Gradient.Active = False + Gradient.Orientation = fgdVertical + BufferedDraw = False + ExplicitLeft = -8 + ExplicitTop = 76 + end + object Image1: TImage + Left = 345 + Top = 15 + Width = 28 + Height = 28 + AutoSize = True + Picture.Data = { + 0A54504E474F626A65637489504E470D0A1A0A0000000D494844520000001C00 + 00001C0806000000720DDF940000000970485973000017120000171201679FD2 + 520000000467414D410000B18E7CFB5193000002CA4944415478DAADD55F4853 + 511C07F0DF25C49012DA8B1085A14581E46EAD19A3D05885CA8CA251D04325BD + D89342BEF5B087E8CD0C7AA90916E5F0A558C8989935872C866C63EE4F5BB9A8 + 508CB27AB01552F3EE4F3BBFED1E76B7BBED8E7B7F2078CFBDDCCF39BF73EE77 + 8CF575280312CA785ACD4879AE5A31043C7FAABDE243CF1D61B87DC70C81D907 + B2D1AA603A9D86296704548D0D70C3745780AAAFD833A189BE9A265111241897 + 4CC3B4EB1DE8D816887D5EA32862E12F00C1EBCA80630C03FD090E382E05AF16 + 62D8523A91260318BB59308DD89501138718A81FBE07639787E0E2AF8DEC2A53 + F0F4851BEF8D3B5288C5FFFC8551F35CAEB5EDBB406A6B4B401E4B8C0EE1F5E3 + 2040DFDA3AB6F6DCCD058A91499031D201DFDB1590DA5E01588CF14550FDF20F + B860F2E27557C75E8AE5E014FEFFCCB65815A520D9B3014B295688721333D852 + 52DA83CD303EE9A6F7CFF6AA21B199849773D18A2882674EB4E10C2D0DF5D0CF + 8A631DD15570FB23F068D286878694A08DAC39A3EFDC8FE8269704DFC35EA62C + D873EC00DD13AB6A9B00E53172DF1B7A8F60D9CF228B6A35CDE0F3AF945D2582 + 278FEECBED497E3F6676AA102DC4C85F20FA8182783A8B3EFC9EE137996F3FE3 + 150F10829D9A56FAD2647EA5F32D4D028C8C45621F05A0580EDFB2AC22681DD1 + D1B1C21C4650A7DE23C004A72F3F464A0C2CFE86D9ABD308660203785D9CC308 + 1E69DB0D368707A4542DA0580E2358185B52AA1A187C62289BC3B27E6E447338 + BE08E9ED2CDD9AE21C5616CC62B034082EA71B0E0FFEA36780CF61B21DCA829E + E3008DB997C7B2B9BEE3D26F7AE8EC4EAFC2607E753CE89A0268BDB64EBFEF59 + 975F3990BCB0CEDF4531BEC82AC1F01DF772DE13520624395CB71112AC8E2FB2 + 4A95F12B4E88CF61D920C9E186B0BE042B44B71A96690ECB6FA93609AEFB9A8A + CF6DE9FE447358362896C362D1C8C7A26CB0D61C960DD69AC3B2C15A73F83F42 + 0A9D9B19DC72610000000049454E44AE426082} + end + object Bevel1: TBevel + Left = 8 + Top = 321 + Width = 373 + Height = 3 + Anchors = [akLeft, akRight, akBottom] + Shape = bsBottomLine + ExplicitTop = 328 + end + object Label1: TLabel + Left = 24 + Top = 264 + Width = 71 + Height = 13 + Margins.Bottom = 0 + Caption = 'Guardar como:' + end + object Bevel2: TBevel + Left = 24 + Top = 245 + Width = 349 + Height = 3 + Anchors = [akLeft, akTop, akRight] + Shape = bsBottomLine + end + object Label5: TLabel + Left = 202 + Top = 144 + Width = 48 + Height = 13 + Margins.Bottom = 0 + Caption = '(4 d'#237'gitos)' + end + object Label6: TLabel + Left = 202 + Top = 171 + Width = 48 + Height = 13 + Margins.Bottom = 0 + Caption = '(4 d'#237'gitos)' + end + object Label7: TLabel + Left = 24 + Top = 90 + Width = 65 + Height = 13 + Margins.Bottom = 0 + Caption = 'Identificador:' + end + object Label8: TLabel + Left = 301 + Top = 90 + Width = 54 + Height = 13 + Margins.Bottom = 0 + Caption = '(15 d'#237'gitos)' + end + object Label9: TLabel + Left = 24 + Top = 117 + Width = 69 + Height = 13 + Margins.Bottom = 0 + Caption = 'C'#243'digo I.N.E.:' + end + object Label10: TLabel + Left = 301 + Top = 117 + Width = 48 + Height = 13 + Margins.Bottom = 0 + Caption = '(9 d'#237'gitos)' + end + object Label4: TLabel + Left = 24 + Top = 201 + Width = 78 + Height = 13 + Margins.Bottom = 0 + Caption = 'Fecha de cargo:' + end + object edtCodEntidad: TcxMaskEdit + Left = 120 + Top = 141 + Properties.BeepOnError = True + Properties.MaxLength = 4 + Style.LookAndFeel.Kind = lfStandard + Style.LookAndFeel.NativeStyle = True + StyleDisabled.LookAndFeel.Kind = lfStandard + StyleDisabled.LookAndFeel.NativeStyle = True + StyleFocused.LookAndFeel.Kind = lfStandard + StyleFocused.LookAndFeel.NativeStyle = True + StyleHot.LookAndFeel.Kind = lfStandard + StyleHot.LookAndFeel.NativeStyle = True + TabOrder = 2 + Text = ' ' + Width = 73 + end + object edtCodAgencia: TcxMaskEdit + Left = 120 + Top = 168 + Properties.BeepOnError = True + Properties.MaxLength = 4 + Style.LookAndFeel.Kind = lfStandard + Style.LookAndFeel.NativeStyle = True + StyleDisabled.LookAndFeel.Kind = lfStandard + StyleDisabled.LookAndFeel.NativeStyle = True + StyleFocused.LookAndFeel.Kind = lfStandard + StyleFocused.LookAndFeel.NativeStyle = True + StyleHot.LookAndFeel.Kind = lfStandard + StyleHot.LookAndFeel.NativeStyle = True + TabOrder = 3 + Text = ' ' + Width = 73 + end + object CancelBtn: TButton + Left = 301 + Top = 330 + Width = 75 + Height = 25 + Anchors = [akLeft, akRight, akBottom] + Cancel = True + Caption = '&Cancelar' + ModalResult = 2 + TabOrder = 7 + OnClick = CancelBtnClick + end + object OKBtn: TButton + Left = 202 + Top = 330 + Width = 85 + Height = 25 + Action = actVolcar + Anchors = [akLeft, akRight, akBottom] + TabOrder = 6 + end + object JvFilenameEdit1: TJvFilenameEdit + Left = 24 + Top = 283 + Width = 349 + Height = 21 + Flat = False + ParentFlat = False + Filter = 'Ficheros de norma 32 (*.C32)|*.C32' + DialogOptions = [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist] + DialogTitle = 'Volcar a disco la remesa' + TabOrder = 5 + end + object edtCodigoIdentif: TcxMaskEdit + Left = 120 + Top = 87 + Properties.BeepOnError = True + Properties.MaxLength = 15 + Style.LookAndFeel.Kind = lfStandard + Style.LookAndFeel.NativeStyle = True + StyleDisabled.LookAndFeel.Kind = lfStandard + StyleDisabled.LookAndFeel.NativeStyle = True + StyleFocused.LookAndFeel.Kind = lfStandard + StyleFocused.LookAndFeel.NativeStyle = True + StyleHot.LookAndFeel.Kind = lfStandard + StyleHot.LookAndFeel.NativeStyle = True + TabOrder = 0 + Text = ' ' + Width = 167 + end + object edtINE: TcxMaskEdit + Left = 120 + Top = 114 + Properties.BeepOnError = True + Properties.MaxLength = 9 + Style.LookAndFeel.Kind = lfStandard + Style.LookAndFeel.NativeStyle = True + StyleDisabled.LookAndFeel.Kind = lfStandard + StyleDisabled.LookAndFeel.NativeStyle = True + StyleFocused.LookAndFeel.Kind = lfStandard + StyleFocused.LookAndFeel.NativeStyle = True + StyleHot.LookAndFeel.Kind = lfStandard + StyleHot.LookAndFeel.NativeStyle = True + TabOrder = 1 + Text = ' ' + Width = 167 + end + object edtFechaCargo: TcxDateEdit + Left = 120 + Top = 198 + Properties.DateButtons = [btnToday] + Properties.ImmediatePost = True + Properties.SaveTime = False + Properties.ShowTime = False + Style.LookAndFeel.Kind = lfStandard + Style.LookAndFeel.NativeStyle = True + StyleDisabled.LookAndFeel.Kind = lfStandard + StyleDisabled.LookAndFeel.NativeStyle = True + StyleFocused.LookAndFeel.Kind = lfStandard + StyleFocused.LookAndFeel.NativeStyle = True + StyleHot.LookAndFeel.Kind = lfStandard + StyleHot.LookAndFeel.NativeStyle = True + TabOrder = 4 + Width = 167 + end + object JvFormStorage: TJvFormStorage + AppStorage = JvAppRegistryStorage + AppStoragePath = 'fEditorBase\' + VersionCheck = fpvcNocheck + StoredProps.Strings = ( + 'edtCodAgencia.Text' + 'edtCodEntidad.Text' + 'edtCodigoIdentif.Text' + 'edtINE.Text') + StoredValues = <> + Left = 80 + Top = 32 + end + object JvAppRegistryStorage: TJvAppRegistryStorage + StorageOptions.BooleanStringTrueValues = 'TRUE, YES, Y' + StorageOptions.BooleanStringFalseValues = 'FALSE, NO, N' + Root = 'Software\%APPL_NAME%' + SubStorages = <> + Left = 112 + Top = 32 + end + object ActionList1: TActionList + Left = 144 + Top = 32 + object actVolcar: TAction + Caption = 'Volcar a disco' + OnExecute = actVolcarExecute + OnUpdate = actVolcarUpdate + end + end +end diff --git a/Source/Modulos/Banca electronica/Views/uEditorExportacionNorma32.pas b/Source/Modulos/Banca electronica/Views/uEditorExportacionNorma32.pas new file mode 100644 index 00000000..d5d89f28 --- /dev/null +++ b/Source/Modulos/Banca electronica/Views/uEditorExportacionNorma32.pas @@ -0,0 +1,229 @@ +unit uEditorExportacionNorma32; + +interface + +uses + Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, + Dialogs, ExtCtrls, StdCtrls, pngimage, cxControls, cxContainer, cxEdit, + cxTextEdit, cxMaskEdit, cxDropDownEdit, cxCalendar, + uIEditorExportacionNorma32, JvExControls, JvComponent, JvgWizardHeader, + JvAppStorage, JvAppRegistryStorage, JvComponentBase, JvFormPlacement, + JvDialogs, Mask, JvExMask, JvToolEdit, ActnList; + +type + TfEditorExportacionNorma32 = class(TForm, IEditorExportacionNorma32) + OKBtn: TButton; + CancelBtn: TButton; + Image1: TImage; + Label2: TLabel; + Label3: TLabel; + edtCodEntidad: TcxMaskEdit; + edtCodAgencia: TcxMaskEdit; + JvgWizardHeader1: TJvgWizardHeader; + Bevel1: TBevel; + JvFormStorage: TJvFormStorage; + JvAppRegistryStorage: TJvAppRegistryStorage; + Label1: TLabel; + Bevel2: TBevel; + JvFilenameEdit1: TJvFilenameEdit; + ActionList1: TActionList; + actVolcar: TAction; + Label5: TLabel; + Label6: TLabel; + Label7: TLabel; + edtCodigoIdentif: TcxMaskEdit; + Label8: TLabel; + Label9: TLabel; + edtINE: TcxMaskEdit; + Label10: TLabel; + Label4: TLabel; + edtFechaCargo: TcxDateEdit; + procedure OKBtnClick(Sender: TObject); + procedure FormCreate(Sender: TObject); + procedure CancelBtnClick(Sender: TObject); + procedure actVolcarUpdate(Sender: TObject); + procedure actVolcarExecute(Sender: TObject); + private + FFichero : String; + protected + procedure SetCodigoEntidad(const AValue: String); + function GetCodigoEntidad : String; + + procedure SetCodigoAgencia(const AValue: String); + function GetCodigoAgencia : String; + + function GetCodigoINE: String; + procedure SetCodigoINE(const Value: String); + + procedure SetCodigoIdentif(const Value: String); + function GetCodigoIdentif: String; + + procedure SetFechaCargo(const AValue: TDateTime); + function GetFechaCargo : TDateTime; + + procedure SetFichero(const AValue: String); + function GetFichero : String; + public + property CodigoEntidad : String read GetCodigoEntidad write SetCodigoEntidad; + property CodigoAgencia : String read GetCodigoAgencia write SetCodigoAgencia; + property CodigoIdentif : String read GetCodigoIdentif write SetCodigoIdentif; + property CodigoINE : String read GetCodigoINE write SetCodigoINE; + property FechaCargo : TDateTime read GetFechaCargo write SetFechaCargo; + property Fichero : String read GetFichero write SetFichero; + end; + + +implementation + +{$R *.dfm} + +uses + uDialogUtils; + +{ TfEditorExportacionNorma32 } + +procedure TfEditorExportacionNorma32.actVolcarExecute(Sender: TObject); +begin + FFichero := JvFilenameEdit1.FileName; + ModalResult := mrOk; +end; + +procedure TfEditorExportacionNorma32.actVolcarUpdate(Sender: TObject); +begin + (Sender as TAction).Enabled := + (Length(edtCodEntidad.Text) = 4) and + (Length(edtCodAgencia.Text) = 4) and + (Length(JvFilenameEdit1.Text) > 0) +end; + +procedure TfEditorExportacionNorma32.CancelBtnClick(Sender: TObject); +begin + Close; +end; + +procedure TfEditorExportacionNorma32.FormCreate(Sender: TObject); +var + APath : String; +begin + inherited; + with JvFormStorage do + begin + if Pos('_', Self.Name) = 0 then + APath := Self.Name + else + APath := Copy(Self.Name, 0, (Pos('_', Self.Name)-1)); + AppStoragePath := APath; + end; + edtFechaCargo.Date := Now; +end; + +function TfEditorExportacionNorma32.GetCodigoAgencia: String; +begin + Result := edtCodAgencia.Text; +end; + +function TfEditorExportacionNorma32.GetCodigoEntidad: String; +begin + Result := edtCodEntidad.Text; +end; + +function TfEditorExportacionNorma32.GetCodigoINE: String; +begin + Result := edtINE.Text; +end; + +function TfEditorExportacionNorma32.GetFechaCargo: TDateTime; +begin + Result := edtFechaCargo.Date; +end; + +function TfEditorExportacionNorma32.GetFichero: String; +begin + Result := FFichero; +end; + +function TfEditorExportacionNorma32.GetCodigoIdentif: String; +begin + Result := edtCodigoIdentif.Text; +end; + +procedure TfEditorExportacionNorma32.OKBtnClick(Sender: TObject); +var + ASaveDialog : TSaveDialog; // Save dialog variable + AArchivo : string; + ARuta : String; +begin + AArchivo := FFichero; + ARuta := ExtractFilePath(Application.ExeName); + +// ASaveDialog := TSaveDialog.Create(nil); +// try +// ASaveDialog.Title := 'Volcar a disco la remesa'; +// ASaveDialog.FileName := FFichero; +// +// ASaveDialog.InitialDir := GetCurrentDir; +// +// ASaveDialog.Filter := 'Ficheros de norma 19 (*.C19)|*.C19'; +// ASaveDialog.DefaultExt := 'C19'; +// ASaveDialog.FilterIndex := 1; +// +// try +// if ASaveDialog.Execute then +// begin +// FFichero := ASaveDialog.FileName; +// ModalResult := mrOk +// end +// else begin +// ModalResult := mrCancel; +// end; +// except +// on e: exception do +// ShowErrorMessage('error', 'error', e); +// end; +// finally +// FreeAndNIL(ASaveDialog); +// end; + +{ if SaveFileDialog(Application.Handle, 'C19', 'Ficheros de norma 19 (*.C19)|*.C19', + 'c:\', 'Volcar a disco la remesa', FFichero) then} + if SaveFileDialog(Application.Handle, 'C19', 'Ficheros de norma 19 (*.C19)|*.C19', + ARuta, 'Volcar a disco la remesa', AArchivo) then + ModalResult := mrOk + else + ModalResult := mrCancel; + +end; + +procedure TfEditorExportacionNorma32.SetCodigoAgencia(const AValue: String); +begin + edtCodAgencia.Text := AValue; +end; + +procedure TfEditorExportacionNorma32.SetCodigoEntidad(const AValue: String); +begin + edtCodEntidad.Text := AValue; +end; + +procedure TfEditorExportacionNorma32.SetCodigoINE(const Value: String); +begin + edtINE.Text := Value; +end; + +procedure TfEditorExportacionNorma32.SetFechaCargo(const AValue: TDateTime); +begin + edtFechaCargo.Date := AValue; +end; + +procedure TfEditorExportacionNorma32.SetFichero(const AValue: String); +begin + FFichero := AValue; + JvFilenameEdit1.InitialDir := ExtractFilePath(Application.ExeName); + JvFilenameEdit1.FileName := JvFilenameEdit1.InitialDir + PathDelim + FFichero; +end; + +procedure TfEditorExportacionNorma32.SetCodigoIdentif(const Value: String); +begin + edtCodigoIdentif.Text := Value; +end; + +end. diff --git a/Source/Modulos/Remesas de cliente/RemesasCliente_Group.bdsgroup b/Source/Modulos/Remesas de cliente/RemesasCliente_Group.bdsgroup new file mode 100644 index 00000000..e1b69085 --- /dev/null +++ b/Source/Modulos/Remesas de cliente/RemesasCliente_Group.bdsgroup @@ -0,0 +1,26 @@ + + + + + + + + + + + ..\..\DataAbstract_D10\DataAbstract_D10.bdsproj + ..\..\Base\Base.bdsproj + ..\..\Base\ControllerBase\ControllerBase.bdsproj + ..\..\Base\GUIBase\GUIBase.bdsproj + ..\..\Base\Usuarios\Usuarios.bdsproj + Model\RemesasCliente_model.bdsproj + Data\RemesasCliente_data.bdsproj + Controller\RemesasCliente_controller.bdsproj + Views\RemesasCliente_view.bdsproj + Plugin\RemesasCliente_plugin.bdsproj + DataAbstract_D10.bpl Base.bpl ControllerBase.bpl GUIBase.bpl Usuarios.bpl RemesasCliente_model.bpl RemesasCliente_data.bpl RemesasCliente_controller.bpl RemesasCliente_view.bpl RemesasCliente_plugin.bpl + + + +