Hola Elvira, si te refieres a todo el PRG, te lo adjunto, aunque lo he personalizado para que se enlace con mis bases de datos y los campos de las mismas:
Code: Select all | Expand
/* v.1.0 31/12/2013
* SEPA ISO 20022 http://http://www.iso20022.org/
* pain.008.001.02 Direct Debit Core y B2B
* pain.001.001.03 Credit Transfer
*
* Para lenguaje Harbour - http://harbour-project.org
* (c) Joaquim Ferrer Godoy <quim_ferrer@yahoo.es>
*
* Características :
* Generacion de formato XML
* Control de errores en campos requeridos
* Verifica importes y numero total de efectos
*
* Reglas de uso locales AEB:
* (1) TRUE = Un apunte en cuenta por la suma de los importes de todas las operaciones del mensaje.
* FALSE= Un apunte en cuenta por cada una de las operaciones incluidas en el mensaje.
* (2) FNAL=Último adeudo de una serie de adeudos recurrentes.
* FRST=Primer adeudo de una serie de adeudos recurrentes.
* OOFF=Adeudo correspondiente a una operación con un único pago(*).
* RCUR=Adeudo de una serie de adeudos recurrentes, cuando no se trata ni del primero ni del último.
* (*) Para este tipo de operaciones el mandato y su referencia deben ser únicos y no pueden utilizarse para operaciones
* puntuales posteriores. Si siempre se factura a los mismos clientes, aunque varie el importe de los adeudos y la periodicidad
* de los mismos, es necesario utilizar el tipo de adeudo recurrente si se utiliza la misma referencia, creando para cada
* cliente deudor un solo mandato que ampare todos los adeudos que se emitan.
* El primer adeudo deberá ser FRST y los siguientes RCUR.
* (3) Esta etiqueta sólo debe usarse cuando un mismo número de cuenta cubra diferentes divisas y el presentador
* necesite identificar en cuál de estas divisas debe realizarse el asiento sobre su cuenta.
* (4) Regla de uso: Solamente se admite el código ‘SLEV’
* (5) La etiqueta ‘Cláusula de gastos’ puede aparecer, bien en el nodo ‘Información del pago’ (2.0), bien en el
* nodo ‘Información de la operación de adeudo directo’ (2.28), pero solamente en uno de ellos.
* Se recomienda que se recoja en el bloque ‘Información del pago’ (2.0).
* (6) Regla de uso: Para el sistema de adeudos SEPA se utilizará exclusivamente la etiqueta 'Otra' estructurada
* según lo definido en el epígrafe 'Identificador del presentador' de la sección 3.3 del cuaderno.
* (7) Regla de uso: Solamente se admite el código 'SEPA'
*/#include "hbclass.ch"#include "hbmxml.ch"#define SEPA_DIRECT_DEBIT
0#define SEPA_CREDIT_TRANSFER
1#define SEPA_SCHEME_CORE
0#define SEPA_SCHEME_COR1
1#define SEPA_SCHEME_B2B
2#define ENTIDAD_JURIDICA
0#define ENTIDAD_FISICA
1#define ENTIDAD_OTRA
2//--------------------------------------------------------------------------------------//// --> ejemplo de uso :FUNCTION PRESEPAXML
(OP,MCODIGO
) PUBLIC aDATOSREM, aRECIBO, aCABREM, aLOSRECIBOS
// OP==1 -> CORE BÁSICO XML // OP==2 -> B2B XML if op==
1 cFitx:=cGetFile32
( "Rem"+MCODIGO+
"CORE.xml",
"Seleccione un nombre para el fichero ...", ,
".",.t.
) else cFitx:=cGetFile32
( "Rem"+MCODIGO+
"B2B.xml",
"Seleccione un nombre para el fichero ...", ,
".",.t.
) endif SELECT 1 aCABREM:=
{} FOR N=
1 TO FCOUNT
() AADD
(aCABREM,FIELDGET
(N
)) NEXT SELECT 2 USE RECIBOS
INDEX CODREC,NOMREC,REMREC,FECREC SHARED
SELECT 8 USE CLIENTES
INDEX CODCLIEN,NOMCLIEN,COMCLIEN, TELCLIEN, DNICLIEN, POBCLIEN SHARED
SELECT 9 USE DATOSREM SHARED
aDATOSREM:=
{} FOR N=
1 TO FCOUNT
() AADD
(aDATOSREM,
(FIELDGET
(N
))) NEXT SELECT 4 SEEK MCODIGO
aLOSRECIBOS:=
{} aTEMP:=
{} DO WHILE !EOF
() .AND. CODIGO==MCODIGO
FOR N=
1 TO FCOUNT
() AADD
(aTEMP,FIELDGET
(N
)) NEXT AADD
(aLOSRECIBOS,aTEMP
) SKIP
ENDDO SELECT 1 SEPAENXML
(OP,MCODIGO
) select 1 if file
(cFitx
) MsgInfo("El fichero se creó correctamente, "+alltrim
(str
(FSize
(cFitx
)))+
" bytes escritos",
"Información") else MsgStop
("Ocurrió un error al crear el fichero o el proceso ha sido cancelado",
"Error!!!") endifRETURN NILfunction SEPAENXML
(TIPOSEPA,MCODIGO
) local n
IF TIPOSEPA==
1 oDoc := SepaXml
():
New( SEPA_DIRECT_DEBIT, SEPA_SCHEME_CORE, cFitx
) ELSE oDoc := SepaXml
():
New( SEPA_DIRECT_DEBIT, SEPA_SCHEME_B2B, cFitx
) endif // Documento---------------------------------------------------------------- WITH OBJECT oDoc
:
MsgId := alltrim
(id_File
('Rem'+MCODIGO+
'CORE')) // Identificación del mensaje :
NbOfTxs :=
0 // Número de operaciones :
CtrlSum :=
0 // Control de suma total importes /* Idea ! NbOfTxs y CtrlSum deberan ser informadas, contrastar con variables calculadas en Activate() */ ENDWITH
// Presentador-------------------------------------------------------------- WITH OBJECT oDoc:
oInitPart :
nEntity := ENTIDAD_JURIDICA
:
Nm := aDATOSREM
[1] :
BICOrBEI := aCABREM
[12] :
id := aDATOSREM
[2] ENDWITH
// Acreedor----------------------------------------------------------------- WITH OBJECT oDoc:
oCreditor :
nEntity := ENTIDAD_JURIDICA
:
Nm := aDATOSREM
[1] :
BICOrBEI := aCABREM
[12] :
id := aDATOSREM
[2] ENDWITH
/* Si el Acreedor es tambien el presentador, especificar asi :
* oDoc:oCreditor := __objClone( oDoc:oInitPart )
*/ // Deudor/es---------------------------------------------------------------- for n :=
1 to LEN
(aLOSRECIBOS
) oDebtor := SepaDebitActor
():
New() SELECT 2 GO TOP
SEEK aLOSRECIBOS
[N,
2] aRECIBO:=
{} FOR i=
1 TO FCOUNT
() AADD
(aRECIBO,FIELDGET
(i
)) NEXT SELECT 8 GO TOP
SEEK aRECIBO
[4] cCLIDNI:=FIELDGET
(6) WITH OBJECT oDebtor
:
Nm := aRECIBO
[5] :
nEntity := ENTIDAD_OTRA
:
id := cCLIDNI
:
InstdAmt := aRECIBO
[9] // Importe :
ReqdColltnDt := aRECIBO
[8] // Fecha de cobro (Vencimiento) :
IBAN := aRECIBO
[6] :
BICOrBEI := aRECIBO
[12] :
MndtId := hb_md5
(oDoc:
oCreditor:
Id + :
id) // Identificación del mandato, idea: Utilizar NIF // Acreedor + NIF Deudor :
DtOfSgntr := ctod
("31-10-2009") // Fecha de firma ENDWITH
oDoc:
DebtorAdd( oDebtor
) next oDoc :
NbOfTxs := LEN
(aLOSRECIBOS
) // Número de operaciones oDoc :
CtrlSum := aCABREM
[6] // Control de suma total importes oDoc:
Activate()return NIL// <-- ejemplo de uso ://--------------------------------------------------------------------------------------//CLASS SepaXml
DATA hXmlDoc
DATA FinancialMsg
DATA SchmeNm
DATA DocType
DATA cFileOut
DATA lMinified AS LOGICAL
INIT .f.
// Documento compactado o con espacios y tabuladores DATA aErrors AS ARRAY
INIT {} // Control de errores DATA ErrorMessages AS ARRAY
INIT {=>
} // Hash mensajes de error multilenguaje DATA aDebtors AS ARRAY
INIT {} // Lista de deudores DATA MsgId
// Identificación del mensaje DATA CreDtTm
// Fecha y hora de creación DATA NbOfTxs
// Número de operaciones DATA CtrlSum
// Control de suma DATA ServiceLevel AS CHARACTER
INIT "SEPA" // Código Nivel de servicio (7) DATA SeqTp AS CHARACTER
INIT "RCUR" // Tipo de secuencia (2) DATA PurposeCd
// Código categoria proposito DATA PurposePrtry
// Propietario categoria proposito DATA oInitPart
DATA oCreditor
DATA oUltimateCreditor
/* */ DATA oDebtor
DATA oUltimateDebtor
METHOD New() METHOD DebtorAdd
(oDebtor
) INLINE aadd
(::
aDebtors, oDebtor
) METHOD GroupHeader
() METHOD InfoPayment
() METHOD DirectDebit
() METHOD SetActor
() METHOD TypePayment
() METHOD IdPayment
() METHOD Creditor
() METHOD IdCreditor
() METHOD SetLanguage
() METHOD Activate() METHOD End
() INLINE mxmlDelete
( ::
hXmlDoc )ENDCLASS//--------------------------------------------------------------------------------------//METHOD New( nFinanMsg, nScheme, cFileOut
) CLASS SepaXml
::
cFileOut := cFileOut
::
CreDtTm := IsoDateTime
() // Fecha y hora de creación switch nFinanMsg
case SEPA_DIRECT_DEBIT
::
FinancialMsg :=
"CstmrDrctDbtInitn" ::
DocType :=
"pain.008.001.02" EXIT
case SEPA_CREDIT_TRANSFER
::
FinancialMsg :=
"CstmrCdtTrfInitn" ::
DocType :=
"pain.001.001.03" end
switch nScheme
case SEPA_SCHEME_CORE ; ::
SchmeNm :=
"CORE" ; EXIT
case SEPA_SCHEME_COR1 ; ::
SchmeNm :=
"COR1" ; EXIT
case SEPA_SCHEME_B2B ; ::
SchmeNm :=
"B2B" ; EXIT
otherwise ; ::
SchmeNm :=
"SEPA" end
::
oInitPart := SepaDebitActor
():
New() ::
oCreditor := SepaDebitActor
():
New() ::
oUltimateCreditor := SepaDebitActor
():
New() ::
oDebtor := SepaDebitActor
():
New() ::
oUltimateDebtor := SepaDebitActor
():
New()return Self//--------------------------------------------------------------------------------------//METHOD GroupHeader
( hParent
) CLASS SepaXml
local hItem
if ::
MsgId !=
NIL .or. ::
CreDtTm !=
NIL .or. ::
NbOfTxs !=
NIL .or. ::
CtrlSum !=
NIL hItem := ItemNew
(hParent,
"GrpHdr") // Cabecera ItemNew
(hItem,
"MsgId",
35, ::
MsgId) // Identificación del mensaje ItemNew
(hItem,
"CreDtTm",
19, ::
CreDtTm) // Fecha y hora de creación ItemNew
(hItem,
"NbOfTxs",
15, str
(::
NbOfTxs,
0)) // Número de operaciones ItemNew
(hItem,
"CtrlSum",
18, ::
CtrlSum) // Control de suma if ::
oInitPart:
Nm !=
NIL // Opcional o Requerido ? ::
SetActor(hItem,
"InitgPty", ::
oInitPart ) // Parte iniciadora (6) else // Error endif endif return NIL//--------------------------------------------------------------------------------------//METHOD InfoPayment
( hParent
) CLASS SepaXml
/*
Regla de uso: Las etiquetas ‘Último acreedor’, ‘Cláusula de gastos’ e ‘Identificación del acreedor’ pueden aparecer,
bien en el nodo ‘Información del pago’ (2.0), bien en el nodo ‘Información de la operación de adeudo directo’ (2.28),
pero solamente en uno de ellos.
Se recomienda que se recojan en el bloque ‘Información del pago’ (2.0).
*/ local hItem
if ::
oDebtor:
PmtInfId !=
NIL .or. ::
oDebtor:
PmtMtd !=
NIL .or. ;
::
oDebtor:
BtchBookg !=
NIL .or. ::
oDebtor:
NbOfTxs !=
NIL .or. ;
::
oDebtor:
CtrlSum !=
NIL .or. ::
oDebtor:
ReqdColltnDt !=
NIL .or. ::
oDebtor:
ChrgBr !=
NIL hItem := ItemNew
(hParent,
"PmtInf") // Información del pago ::
IdPayment(hItem
) // Identificación de la información del pago ::
TypePayment(hItem
) // Información del tipo de pago ItemNew
(hItem,
"ReqdColltnDt",
8, ;
// Fecha de cobro (Vencimiento) ::
oDebtor:
ReqdColltnDt) ::
Creditor(hItem
) // Datos Acreedor, Cuenta, Entidad if ::
oUltimateCreditor:
Nm !=
NIL // Opcional, Último acreedor (6) ::
SetActor(hItem,
"UltmtCdtr", ::
oUltimateCreditor) endif // No produce error, es opcional ItemNew
(hItem,
"ChrgBr",
4, ::
oDebtor:
ChrgBr) // Cláusula de gastos (5) ::
IdCreditor(hItem
) // Identificación del acreedor endifreturn hItem
//--------------------------------------------------------------------------------------//METHOD DirectDebit
( hParent
) CLASS SepaXml
local hItem, hChild
if ::
oDebtor:
InstdAmt >
0 hItem := ItemNew
(hParent,
"DrctDbtTxInf") // Información de la operación de adeudo directo if ::
oDebtor:
InstrId !=
NIL .or. ::
oDebtor:
EndToEndId !=
NIL hChild := ItemNew
(hItem,
"PmtId") // Identificación del pago ItemNew
(hChild,
"InstrId",
35, ::
oDebtor:
InstrId) // Identificación de la instrucción ItemNew
(hChild,
"EndToEndId",
35, ::
oDebtor:
EndToEndId) // Identificación de extremo a extremo endif ItemNew
(hItem,
"InstdAmt",
12, ::
oDebtor:
InstdAmt, .t.
) // Importe ordenado if ::
oDebtor:
MndtId !=
NIL .or. ::
oDebtor:
DtOfSgntr !=
NIL hChild := ItemNew
(hItem,
"DrctDbtTx") // Operación de adeudo directo hChild := ItemNew
(hChild,
"MndtRltdInf") // Información del mandato ItemNew
(hChild,
"MndtId",
35, ::
oDebtor:
MndtId) // Identificación del mandato ItemNew
(hChild,
"DtOfSgntr",
8, ::
oDebtor:
DtOfSgntr) // Fecha de firma if ::
oDebtor:
AmdmntInd !=
NIL .and. ::
oDebtor:
OrgnlMndtId !=
NIL ItemNew
(hChild,
"AmdmntInd",
5, ::
oDebtor:
AmdmntInd) // Indicador de modificación hChild := ItemNew
(hChild,
"AmdmntInfDtls") // Detalles de la modificación ItemNew
(hChild,
"OrgnlMndtId",
35, ::
oDebtor:
OrgnlMndtId) // Identificación del mandato original endif endif //CreditItem(7, "OrgnlCdtrSchmeId") // Identificación del acreedor original /*
REVISAR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ItemNew(7, "OrgnlDbtrAcct") // Cuenta del deudor original
ItemNew(8, "Id") // Identificación
ItemNew(9, "IBAN", 34, aData["DebtorIban"]) // IBAN
ItemNew(7, "OrgnlDbtrAgt") // Entidad del deudor original
ItemNew(8, "FinInstnId") // Identificación de la entidad
ItemNew(9, "Othr") // Otra
ItemNew(10,"Id", 35, aData["DebtorAgent"]) // Identificación
ItemNew(6, "ElctrncSgntr", 1025, aData["ElctrncSgntr"]) // Firma electrónica
CreditItem(5, "CdtrSchmeId", aCreditor) // Identificación del acreedor
FieldNew(4, "UltmtCdtr") // Último acreedor (6)
*/ if ::
oDebtor:
BICOrBEI !=
NIL hChild := ItemNew
(hItem,
"DbtrAgt") // Entidad del deudor hChild := ItemNew
(hChild,
"FinInstnId") // Identificación de la entidad ItemNew
(hChild,
"BIC",
11, ::
oDebtor:
BICOrBEI) // BIC else aadd
( ::
aErrors, ::
ErrorMessages['SEPA_DEBTOR_AGENT'] ) endif if ::
oDebtor:
Nm !=
NIL // Requerido ::
SetActor(hItem,
"Dbtr", ::
oDebtor ) // Deudor (6) else aadd
( ::
aErrors, ::
ErrorMessages['SEPA_DEBTOR_NAME'] ) endif if ::
oDebtor:
IBAN !=
NIL hChild := ItemNew
(hItem,
"DbtrAcct") // Cuenta del deudor hChild := ItemNew
(hChild,
"Id") // Identificación ItemNew
(hChild,
"IBAN",
34, ::
oDebtor:
IBAN) // IBAN else aadd
( ::
aErrors, ::
ErrorMessages['SEPA_DEBTOR_ACCOUNT'] ) endif if ::
oUltimateDebtor:
Nm !=
NIL // Opcional o Requerido ? ::
SetActor(hItem,
"UltmtDbtr", ::
oUltimateDebtor) // Último deudor (6) endif if ::
PurposeCd !=
NIL hChild := ItemNew
(hItem,
"Purp") // Propósito ItemNew
(hChild,
"Cd",
4, ::
PurposeCd) // Código endif /* Bloque solo a efectos estadisticos, para obligados en Balanza de Pagos
REVISAR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ItemNew(4, "RgltryRptg") // Información regulatoria
ItemNew(5, "DbtCdtRptgInd", 4, aData["DbtCdtRptgInd"]) // Alcance de la información
ItemNew(5, "Dtls") // Detalles
ItemNew(6, "Cd", 3, aData["DtlsCode"]) // Código
ItemNew(6, "Amt", 21, aData["Amt"], .t.) // Importe
ItemNew(6, "Inf", 35, aData["Inf"]) // Información
*/ if ::
oDebtor:
Info !=
NIL hChild := ItemNew
(hItem,
"RmtInf") // Concepto ItemNew
(hChild,
"Ustrd",
140, ::
oDebtor:
Info) // No estructurado endif /* Bloque para informacion estructurada
REVISAR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ItemNew(5, "Strd") // Estructurado
ItemNew(6, "CdtrRefInf") // Referencia facilitada por el acreedor
ItemNew(7, "Tp") // Tipo de referencia
ItemNew(8, "CdOrPrtry") // Código o propietario
ItemNew(9, "Cd", 4, aData["RefInf"]) // Código
ItemNew(8, "Issr", 35, aData["Issr"]) // Emisor
ItemNew(7, "Ref", 35, aData["Ref"]) // Referencia
*/ else // Error endifreturn NIL//--------------------------------------------------------------------------------------//METHOD SetActor
( hParent, cLabel, oActor
) CLASS SepaXml
local hItem := ItemNew
(hParent, cLabel
) // Actor ItemNew
(hItem,
"Nm",
70, oActor:
Nm) // Nombre if oActor:
BICOrBEI !=
NIL .or. oActor:
BirthDt !=
NIL .or. oActor:
PrvcOfBirth !=
NIL .or. ;
oActor:
CityOfBirth !=
NIL .or. oActor:
CtryOfBirth .or. oActor:
Id !=
NIL .or. oActor:
Issr !=
NIL hItem := ItemNew
(hItem,
"Id") // Identificación if oActor:
nEntity == ENTIDAD_JURIDICA
hItem := ItemNew
(hItem,
"OrgId") // Persona jurídica elseif oActor:
nEntity == ENTIDAD_FISICA
hItem := ItemNew
(hItem,
"PrvtId") // Persona física else // Error, no se ha especificado un tipo de identificador valido // Solo existen 2 opciones : Fisica o Juridica endif switch oActor:
nEntity case ENTIDAD_JURIDICA
if oActor:
BICOrBEI !=
NIL ItemNew
(hItem,
"BICOrBEI",
11, oActor:
BICOrBEI) // BIC o BEI else // Error endif EXIT
case ENTIDAD_FISICA
if oActor:
BirthDt !=
NIL .or. oActor:
PrvcOfBirth !=
NIL .or. ;
oActor:
CityOfBirth !=
NIL .or. oActor:
CtryOfBirth !=
NIL hItem := ItemNew
(hItem,
"DtAndPlcOfBirth") // Fecha y lugar de nacimiento ItemNew
(hItem,
"BirthDt",
8, oActor:
BirthDt) // Fecha de nacimiento ItemNew
(hItem,
"PrvcOfBirth",
35, oActor:
PrvcOfBirth) // Provincia de nacimiento ItemNew
(hItem,
"CityOfBirth",
35, oActor:
CityOfBirth) // Ciudad de nacimiento ItemNew
(hItem,
"CtryOfBirth",
2, oActor:
CtryOfBirth) // País de nacimiento else // Error endif EXIT
otherwise if oActor:
Id !=
NIL .or. oActor:
Cd !=
NIL .or. oActor:
Prtry !=
NIL .or. oActor:
Issr !=
NIL hItem := ItemNew
(hItem,
"Othr") // Otra ItemNew
(hItem,
"Id",
35, oActor:
Id) // Identificación if oActor:
Cd !=
NIL .or. oActor:
Prtry !=
NIL hChild := ItemNew
(hItem,
"SchmeNm") // Nombre del esquema ItemNew
(hChild
+5,
"Cd",
4, oActor:
Cd) // Código ItemNew
(hChild
+5,
"Prtry",
35, oActor:
Prtry) // Propietario endif ItemNew
(hItem,
"Issr",
35, oActor:
Issr) // Emisor else // Error endif end
else // Error endifreturn NIL//--------------------------------------------------------------------------------------//METHOD IdPayment
( hItem
) CLASS SepaXml
/* Generar identificador de pago, a partir del mensaje */ ::
oDebtor:
PmtInfId := alltrim
(::
MsgId)// +"-"+ strzero(::oDebtor:NbOfTxs, 3) ItemNew
(hItem,
"PmtInfId",
35, ::
oDebtor:
PmtInfId) // Identificación de la información del pago ItemNew
(hItem,
"PmtMtd",
2, ::
oDebtor:
PmtMtd) // Método de pago ItemNew
(hItem,
"BtchBookg",
5, ::
oDebtor:
BtchBookg) // Indicador de apunte en cuenta ItemNew
(hItem,
"NbOfTxs",
15, str
(::
oDebtor:
NbOfTxs,
0)) // Número de operaciones ItemNew
(hItem,
"CtrlSum",
18, ::
oDebtor:
CtrlSum) // Control de suma return NIL//--------------------------------------------------------------------------------------//METHOD TypePayment
( hParent
) CLASS SepaXml
local hItem, hChild
hItem := ItemNew
(hParent,
"PmtTpInf") // Información del tipo de pago hChild := ItemNew
(hItem,
"SvcLvl") // Nivel de servicio ItemNew
(hChild,
"Cd",
4, ::
ServiceLevel) // Código Nivel de servicio hChild := ItemNew
(hItem,
"LclInstrm") // Instrumento local ItemNew
(hChild,
"Cd",
35, ::
SchmeNm) // Código Instrumento local ItemNew
(hItem,
"SeqTp",
4, ::
SeqTp) // Tipo de secuencia /* Lista de códigos recogidos en la norma ISO 20022
Ex: CASH=CashManagementTransfer (Transaction is a general cash management instruction) */ if ::
PurposeCd !=
NIL hChild := ItemNew
(hItem,
"CtgyPurp") // Categoría del propósito ItemNew
(hChild,
"Cd",
4, ::
PurposeCd) // Código ItemNew
(hChild,
"Prtry",
35, ::
PurposePrtry) // Propietario endifreturn NIL//--------------------------------------------------------------------------------------//METHOD Creditor
( hParent
) CLASS SepaXml
local hItem
if ::
oCreditor:
Nm !=
NIL hItem := ItemNew
(hParent,
"Cdtr") // Acreedor ItemNew
(hItem,
"Nm",
70, ::
oCreditor:
Nm) // Nombre if ::
oCreditor:
Ctry !=
NIL .or. ::
oCreditor:
AdrLine1 !=
NIL hItem := ItemNew
(hItem,
"PstlAdr") // Dirección postal ItemNew
(hItem,
"Ctry",
2, ::
oCreditor:
Ctry) // País ItemNew
(hItem,
"AdrLine",
70, ::
oCreditor:
AdrLine1) // Dirección en texto libre ItemNew
(hItem,
"AdrLine",
70, ::
oCreditor:
AdrLine2) // Dirección en texto libre else // Error //aadd( ::aErrors, ::aMessages['creditor_does_not_exist'] ) endif else // Error endif if ::
oCreditor:
IBAN !=
NIL hItem := ItemNew
(hParent,
"CdtrAcct") // Cuenta del acreedor // ItemNew(hItem, "Ccy", 3, aData["Ccy"]) // Moneda hItem := ItemNew
(hItem,
"Id") // Identificación ItemNew
(hItem,
"IBAN",
34, ::
oCreditor:
IBAN) // IBAN else // Error endif if ::
oCreditor:
BIC !=
NIL hItem := ItemNew
(hParent,
"CdtrAgt") // Entidad del acreedor hItem := ItemNew
(hItem,
"FinInstnId") // Identificación de la entidad ItemNew
(hItem,
"BIC",
11, ::
oCreditor:
BIC) // BIC else // Error endif return NIL//--------------------------------------------------------------------------------------//METHOD IdCreditor
( hParent
) CLASS SepaXml
if ::
oCreditor:
Id !=
NIL hItem := ItemNew
(hParent,
"CdtrSchmeId") // Identificación del acreedor hItem := ItemNew
(hItem,
"Id") // Identificación hItem := ItemNew
(hItem,
"PrvtId") // Identificación privada hItem := ItemNew
(hItem,
"Othr") // Otra ItemNew
(hItem,
"Id",
35, ::
oCreditor:
Id) // Identificación if ::
oCreditor:
Prtry !=
NIL hItem := ItemNew
(hItem
+4,
"SchmeNm") // Nombre del esquema ItemNew
(hItem,
"Prtry",
35, ::
oCreditor:
Prtry) // Propietario endif else // Error endifreturn NIL//--------------------------------------------------------------------------------------//METHOD SetLanguage
() CLASS SepaXml
::
ErrorMessages['SEPA_DEBTOR_AGENT'] :=
"La entidad del cliente no existe" ::
ErrorMessages['SEPA_DEBTOR_NAME'] :=
"El nombre del deudor no existe" ::
ErrorMessages['SEPA_DEBTOR_ACCOUNT'] :=
"La cuenta del deudor no existe"return NIL//--------------------------------------------------------------------------------------//METHOD Activate() CLASS SepaXml
local hItem, oDebtor
::
SetLanguage() // Comprobar numero de operaciones y suma total de importes for each oDebtor in ::
aDebtors ::
oDebtor:
NbOfTxs +=
1 ::
oDebtor:
CtrlSum += oDebtor:
InstdAmt next if ::
NbOfTxs != ::
oDebtor:
NbOfTxs outstd
( 'Existen errores, no es posible continuar' ) return(NIL) endif if ::
CtrlSum != ::
oDebtor:
CtrlSum outstd
( 'Existen errores, no es posible continuar' ) return(NIL) endif ::
hXmlDoc := mxmlNewXML
() hItem := mxmlNewElement
(::
hXmlDoc,
"Document") mxmlElementSetAttr
( hItem,
"xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance" ) mxmlElementSetAttr
( hItem,
"xmlns",
"urn:iso:std:iso:20022:tech:xsd:"+ ::
DocType ) hItem := ItemNew
(hItem, ::
FinancialMsg) // Raíz del mensaje ::
GroupHeader(hItem
) // Cabecera /* La informacion del pago puede incluir varios adeudos por fecha de cobro
* Aqui se asume fecha de cobro distinta para cada adeudo, no realizando agrupacion.
*/ for each oDebtor in ::
aDebtors ::
oDebtor:= __objClone
(oDebtor
) ::
oDebtor:
NbOfTxs :=
1 ::
oDebtor:
CtrlSum := oDebtor:
InstdAmt hChild := ::
InfoPayment(hItem
) // Informacion del pago ::
DirectDebit(hChild
) // Adeudo individual next if len
( ::
aErrors ) >
0 aeval
( ::
aErrors,
{|err| outstd
( err + hb_eol
() ) } ) else if ::
lMinified mxmlSaveFile
( ::
hXmlDoc, ::
cFileOut, MXML_NO_CALLBACK
) else mxmlSaveFile
( ::
hXmlDoc, ::
cFileOut, @WhiteSpace
() ) endif endif ::
End()return NIL//--------------------------------------------------------------------------------------//CLASS SepaDebitActor
DATA nEntity
DATA Nm
// Nombre DATA Ctry
// Pais DATA AdrLine1
// Dirección en texto libre DATA AdrLine2
// Se permiten 2 etiquetas para direccion DATA IBAN
// IBAN DATA BIC
// BIC DATA BICOrBEI
// BIC o BEI DATA BirthDt
// Fecha de nacimiento DATA PrvcOfBirth
// Provincia de nacimiento DATA CityOfBirth
// Ciudad de nacimiento DATA CtryOfBirth
// País de nacimiento DATA Id // Identificación DATA Issr
// Emisor DATA Cd
// Codigo DATA Prtry
// Propietario DATA PmtInfId
// Identificación de la información del pago DATA BtchBookg AS CHARACTER
INIT "TRUE" // Indicador de apunte en cuenta (1) DATA ReqdColltnDt
// Fecha de cobro (Vencimiento) DATA Info
// Informacion no estructurada, p.e., concepto del cobro DATA NbOfTxs AS NUMERIC
INIT 0 // Número de operaciones DATA CtrlSum AS NUMERIC
INIT 0.00 // Control de suma DATA PmtMtd AS CHARACTER
INIT "DD" READONLY
// Método de pago Regla de uso: Solamente se admite el código ‘DD’ DATA ChrgBr AS CHARACTER
INIT "SLEV" READONLY
// Cláusula de gastos (4) DATA InstrId
// Identificación de la instrucción DATA EndToEndId
// Identificación de extremo a extremo DATA InstdAmt AS NUMERIC
INIT 0.00 // Importe ordenado DATA MndtId
// Identificación del mandato DATA DtOfSgntr
// Fecha de firma DATA AmdmntInd
// Indicador de modificación DATA OrgnlMndtId
// Identificación del mandato original METHOD New() ENDCLASS//--------------------------------------------------------------------------------------//METHOD New() CLASS SepaDebitActor
return Self//--------------------------------------------------------------------------------------//static function ItemNew
(hParent, cLabel, nLen, xValue, lCurrency
) local hItem, cType
if nLen !=
NIL if xValue !=
NIL hItem := mxmlNewElement
( hParent, cLabel
) cType := valtype
(xValue
) if cType ==
"N" xValue := ltrim
( str
(xValue, nLen,
2) ) elseif cType ==
"D" xValue := sDate
(xValue
) endif mxmlNewText
( hItem,
0, xValue
) //mxmlNewText( hItem, 0, padR(xValue, nLen) ) endif else hItem := mxmlNewElement
( hParent, cLabel
) endif if hItem !=
NIL .and. lCurrency !=
NIL mxmlElementSetAttr
( hItem,
"Ccy",
"EUR" ) endifreturn hItem
//--------------------------------------------------------------------//static function WhiteSpace
( hNode, nWhere
) return If(nWhere == MXML_WS_AFTER_OPEN .or. nWhere == MXML_WS_AFTER_CLOSE, hb_eol
(),
NIL)//--------------------------------------------------------------------//