Hola,
Gracias a la clase de Manuel Calero Solís he conseguido generar el .xml.
Adjunto una clase envoltorio.
Me faltaría firmar con el estandar XAdEs.
Code: Select all
///////////////
// CLASS TEnvoltorioFacturaElectronica
//
//
// Clase envoltorio para la clase TFacturaElectronica de
// Manuel Calero Sol¡s. (Gracias Manuel)
///////////////////////////////////////////////////////////////////////////
#Include "FiveWin.Ch"
*
//-------------------------------------------------------------------------//
// Ejemplo de la clase
// Hay que asignar los datos en el metodo ::AsignaDatos()
FUNCTION TestFacturaElectronica()
Local oEnv
oEnv:= TEnvoltorioFacturaElectronica():New()
oEnv:cNif := "43787173S"
oEnv:cNumFac:= "A-00001/13"
oEnv:cCli := "43000001"
oEnv:lFirmar:= .f.
oEnv:lEnviar:= .t.
oEnv:Activate()
IF oEnv:lError
oEnv:ShowErr()
oenv:showmsg()
ENDIF
RETURN NIL
*
*
*
*
//-------------------------------------------------------------------------//
CLASS TEnvoltorioFacturaElectronica
METHOD New()
METHOD Activate()
DATA cNif // Obligatorio. Al menos para firmar
DATA cNumFac // Obligatorio. Nº de factura.
DATA cCli // Obligatorio. Codigo de cliente de la fra.
DATA lFirmar // Opcional. Si se quiere o no firmar
DATA lEnviar // Opcional. Si se quiere enviar por email
DATA cPathGuardar HIDDEN // Opcional. Por si se quiere tener almacen de fras. enviadas
DATA cFileXml HIDDEN // Fichero xml resultante
DATA cFileXmlFir HIDDEN // Fichero xml resultante firmado, si se llega a firmar
DATA oFactuE HIDDEN
DATA oTree HIDDEN
METHOD InstanciaClase() HIDDEN
METHOD AsignaDatos() HIDDEN
METHOD GeneraXml() HIDDEN
DATA lError READONLY
METHOD ShowMsg() INLINE ::oTree:ShowMsg() // Muestra todos los mensajes de error y no error
METHOD ShowErr() INLINE ::oTree:ShowErr() // Muestra solo los mensajes que son de error
ENDCLASS
*
//-------------------------------------------------------------------------//
METHOD New() CLASS TEnvoltorioFacturaElectronica
::lFirmar:= .t.
::lEnviar:= .t.
::lError := .f.
RETURN Self
*
//-------------------------------------------------------------------------//
METHOD Activate() CLASS TEnvoltorioFacturaElectronica
::InstanciaClase()
::AsignaDatos()
::GeneraXml()
::lError:= ::oTree:lError()
RETURN NIL
*
//-------------------------------------------------------------------------//
METHOD InstanciaClase() CLASS TEnvoltorioFacturaElectronica
Local cIniFile:= FileCarValidos(::cCli+ Space(1)+ ::cNumFac) // Quitar (o sustituir) caracteres no validos para nombre de archivo
*
::cFileXml:= cIniFile+ ".Xml"
IF ::lFirmar
::cFileXmlFir:= cIniFile+ "Fir"+ ".Xml"
ENDIF
*
::oTree:= TSimulateTreeForFacturaElectronica():New()
*
::oFactuE:= TFacturaElectronica():New(::oTree)
*
IF ::lFirmar
::cFileXml := cIniFile+ " - Origen.Xml"
::cFileXmlFir:= cIniFile+ ".Xml"
*
ELSE
::cFileXml := cIniFile+ ".Xml"
::cFileXmlFir:= NIL
ENDIF
::oFactuE:cFicheroOrigen := ::cFileXml
::oFactuE:cFicheroDestino:= ::cFileXmlFir
*
//-------------------------------------------------------------------------//
METHOD AsignaDatos() CLASS TEnvoltorioFacturaElectronica
// AQUI asignar estos datos
::oFactuE:nTotalGrossAmount := 0
::oFactuE:nTotalGeneralDiscounts := 0
::oFactuE:nTotalGeneralSurcharges := 0
::oFactuE:nTotalGrossAmountBeforeTaxes := 0
::oFactuE:nTotalTaxOutputs := 0
::oFactuE:nTotalTaxesWithheld := 0
::oFactuE:nInvoiceTotal := 0
::oFactuE:nTotalOutstandingAmount := 0
::oFactuE:nTotalExecutableAmount := 0
::oFactuE:nTotalReimbursableExpenses := 0
::oFactuE:nInvoiceTotalAmount := 0
// AQUI asignar oSellerParty y oBuyerParty
::oFactuE:oSellerParty := ::oFactuE:oSellerParty
::oFactuE:oBuyerParty := ::oFactuE:oBuyerParty
// AQUI rellenar estos arrays
::oFactuE:aTax := {}
::oFactuE:aDiscount := {}
::oFactuE:aItemLine := {}
::oFactuE:aInstallment := {}
RETURN NIL
*
*
//-------------------------------------------------------------------------//
METHOD GeneraXml() CLASS TEnvoltorioFacturaElectronica
::oFactuE:GeneraXml()
IF ::lFirmar
::oFactuE:Firma()
::oFactuE:VerificaFirma()
ENDIF
IF ::lEnviar
::oFactuE:Enviar()
ENDIF
RETURN NIL
*
//-------------------------------------------------------------------------//
// Esta clase simula un objeto oTree que utiliza Manuel en su clase parece
// ser para obtener informacion de la generacion xml de la factura.
// Nosotros simulamos esa clase para, primero aprovechar su uso y segundo,
// dejar intacto el codigo de Manuel.
CLASS TSimulateTreeForFacturaElectronica
METHOD New()
METHOD Add()
METHOD Expand() INLINE NIL
DATA nNivel INIT 1 HIDDEN
DATA aMsg INIT {} HIDDEN
DATA aMsgErr INIT {} HIDDEN
METHOD ShowMsg()
METHOD ShowErr()
METHOD lError() INLINE !Empty(::aMsgErr)
ENDCLASS
*
//-------------------------------------------------------------------------//
METHOD New() CLASS TSimulateTreeForFacturaElectronica
RETURN Self
*
//-------------------------------------------------------------------------//
// nTipoMsg: 1 Ok, vacio error.
METHOD Add(cTexto, nTipoMsg) CLASS TSimulateTreeForFacturaElectronica
Local oTree
oTree:= TSimulateTreeForFacturaElectronica():New()
oTree:nNivel:= Self:nNivel+ 1
*
Aadd(::aMsg, {cTexto, nTipoMsg})
IF Empty(nTipoMsg)
Aadd(::aMsgErr, {cTexto, nTipoMsg})
ENDIF
RETURN oTree
*
//-------------------------------------------------------------------------//
METHOD ShowMsg() CLASS TSimulateTreeForFacturaElectronica
Local cMsg
#Define MSG_ a[1]+ Space(1)+ "["+ hb_ValToStr(a[2])+ "]"
cMsg:= Arr2String(::aMsg, {|a| MSG_ }, CRLF )
*
MsgInfo(cMsg, "Mensajes")
RETURN NIL
*
//-------------------------------------------------------------------------//
METHOD ShowErr() CLASS TSimulateTreeForFacturaElectronica
Local cMsg
*
cMsg:= Arr2String(::aMsgErr, {|a| MSG_ }, CRLF )
*
MsgInfo(cMsg, "Errores")
RETURN NIL
*
*
//---------------------------------------------------------------------------//
// Funciones que faltan para compilar la clase de Manuel Calero
FUNCTION nRouDiv() ; RETURN 2
FUNCTION FullCurDir(); RETURN CurDriveDir()
FUNCTION DToIso(d)
Local c
c:= Str(Year(d), 4)+ "-"+;
Str(Month(d), 2)+ "-"+;
Str(Day(d), 2)
RETURN c
*
//-------------------------------------------------------------------------//
STATIC FUNCTION FileCarValidos(c); RETURN c
*
//-------------------------------------------------------------------------//
STATIC FUNCTION Arr2String( aList, bMTransform, cSep)
local i, cList := ''
DEFAULT cSep:= ","
IF bMTransform == NIL
bMTransform:= {|x, nPos| x }
ENDIF
for i = 1 to Len( aList )
cList += Eval(bMTransform, aList[ i ], i) + cSep
next
return Left( cList, Len( cList ) - Len( cSep ) )
Saludos