España: Normativa sancionadora sistemas informáticos

Re: España: Normativa sancionadora sistemas informáticos

Postby VictorCasajuana » Mon Nov 18, 2024 8:28 am

Garbi wrote:
VictorCasajuana wrote:Respuesta de hacienda:

La certificación del cumplimiento de un Sistema Informático de Facturación se realizará a través de declaraciones responsables incluidas en los SIF

por lo que no hay que preocuparse por esto.


Victor podria explicar a que se refiere eso y como se hace.


Página 12:
https://www.boe.es/boe/dias/2024/10/28/pdfs/BOE-A-2024-22138.pdf
--------
¿ Y porque no ?
¿ And why not ?
User avatar
VictorCasajuana
 
Posts: 265
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs

Re: España: Normativa sancionadora sistemas informáticos

Postby Julio Cepeda » Mon Nov 18, 2024 9:15 am

Muchas gracias FiveWiDi.
No entiendo, a pesar de que puede ser que esté utilizando caracteres no permitidos, la cuestión es que le paso a la función los mismos caracteres, primero en una cadena seguida y continua entre dobles comillas y después en la misma cadena de caracteres pero compuesta por la suma de cadenas de caracteres y variables. No se qué puede pasar.
Saludos

julio@cepedaserinf.es
FiveWin 22.12 + Harbour 3.2.0dev (r2008190002), BCC 7 Windows 11
User avatar
Julio Cepeda
 
Posts: 65
Joined: Wed Oct 12, 2005 6:58 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby quim » Mon Nov 18, 2024 9:19 am

VictorCasajuana wrote:
Garbi wrote:
VictorCasajuana wrote:Respuesta de hacienda:

La certificación del cumplimiento de un Sistema Informático de Facturación se realizará a través de declaraciones responsables incluidas en los SIF

por lo que no hay que preocuparse por esto.


Victor podria explicar a que se refiere eso y como se hace.


Página 12:
https://www.boe.es/boe/dias/2024/10/28/pdfs/BOE-A-2024-22138.pdf


Como complemento a la info facilitada por VictorCasajuana puedes ver lo que contestan de este tema en las FAQ

https://sede.agenciatributaria.gob.es/Sede/iva/sistemas-informaticos-facturacion-verifactu/preguntas-frecuentes/certificacion-sistemas-informaticos-declaracion-responsable.html
quim
 
Posts: 42
Joined: Mon Apr 11, 2011 6:22 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby FiveWiDi » Mon Nov 18, 2024 1:13 pm

Julio Cepeda wrote:Muchas gracias FiveWiDi.
No entiendo, a pesar de que puede ser que esté utilizando caracteres no permitidos, la cuestión es que le paso a la función los mismos caracteres, primero en una cadena seguida y continua entre dobles comillas y después en la misma cadena de caracteres pero compuesta por la suma de cadenas de caracteres y variables. No se qué puede pasar.

Julio,

Yo creo que el problema lo tienes en 'FechaHoraHusoGenRegistro'.

Yo utilizo esta función que creo que la encontré en este foro:

Code: Select all  Expand view  RUN
FUNCTION hb_VerifactuHuella( cNIF, ;
                             cNumSerieFacturaEmisor, ;
                             dFechaExpedicionFactura, ;
                             cTipoFactura, ;
                             nCuotaTotal, ;
                             nImporteTotal, ;
                             cHuellaRegistroAnterior, ;
                             cFechaHoraHusoGenRegistro ;
                             )

// Torna una array de 2 posicions:
// 1- cadena a on es calcula la 'Huella'.
// 2- la 'Huella'

   local c := ""
   local h := {=>}
   Local cHuella := ""

   /*
   h['Nif']                      := "B1234567"
   h['NumSerieFacturaEmisor']    := "AB-123456"
   h['FechaExpedicionFactura']   := hb_dtoc( date(), "dd-mm-yyyy" )
   h['TipoFactura']              := "F1"
   h['CuotaTotal']               := ltrim( str(261.61, 12, 2) )
   h['ImporteTotal']             := ltrim( str(1507.36, 12, 2) )
   h['HuellaRegistroAnterior']   := "ZmY2MDgxMzc2ZWIyMTI4ZDFiMDMyMDlkMTAyNmQ4ZDVmZGExMWJkYWRiMThjZTNkYjE4ODExZDg3MDUwZTNjMQ=="
   h['FechaHoraHusoGenRegistro'] := hb_TtoS( hb_datetime() )
   */


   
   /*
   h['Nif']                      := "IDEmisorFactura=" + "89890001K"
   h['NumSerieFacturaEmisor']    := "&NumSerieFactura=" + "12345679/G34"
   h['FechaExpedicionFactura']   := "&FechaExpedicionFactura=" + "01-01-2024"
   h['TipoFactura']              := "&TipoFactura=" + "F1"
   h['CuotaTotal']               := "&CuotaTotal=" + "12.35"
   h['ImporteTotal']             := "&ImporteTotal=" + "123.45"
   h['HuellaRegistroAnterior']   := "&Huella=" + "3C464DAF61ACB827C65FDA19F352A4E3BDC2C640E9E9FC4CC058073F38F12F60"
   h['FechaHoraHusoGenRegistro'] := "&FechaHoraHusoGenRegistro=" + "2024-01-01T19:20:35+01:00"
   */


   
   h['Nif']                      := "IDEmisorFactura=" +  ( cNIF )
   h['NumSerieFacturaEmisor']    := "&NumSerieFactura=" + ( cNumSerieFacturaEmisor )
   h['FechaExpedicionFactura']   := "&FechaExpedicionFactura=" + hb_dtoc( dFechaExpedicionFactura, "dd-mm-yyyy" )
   h['TipoFactura']              := "&TipoFactura=" + ( cTipoFactura )
   h['CuotaTotal']               := "&CuotaTotal=" + Alltrim( TransForm( nCuotaTotal, "999999999999.99" ) )      //  ltrim( str(nCuotaTotal, 12, 2) )
   h['ImporteTotal']             := "&ImporteTotal=" + Alltrim( TransForm( nImporteTotal, "999999999999.99" ) )    //  ltrim( str(nImporteTotal, 12, 2) )
   h['HuellaRegistroAnterior']   := "&Huella=" + cHuellaRegistroAnterior
   h['FechaHoraHusoGenRegistro'] := "&FechaHoraHusoGenRegistro=" + cFechaHoraHusoGenRegistro          //  hb_TtoS( tFechaHoraHusoGenRegistro )
   

   hb_heval( h, {|k,v,i| c += v} )    //    | key, value, index |

c := hb_StrToUTF8( c )

cHuella := ( hb_sha256( c ) )

cHuella := Upper( cHuella )

Return { c, cHuella }
/* ************************************************************************************** */


Y para 'montar' la cadena de 'FechaHoraHusoGenRegistro' utilizo esta otra función:

(Yo trabajo con fechas y horas en formato Date() y Time(), no utilizo TimeStamp)

Code: Select all  Expand view  RUN
/* *********************************************************************************** */
FUNCTION FechaHoraHuso( dDate, cTime )

Local cDataHoraHuso := ""

cDataHoraHuso := hb_dtoc( dDate, "yyyy-mm-dd" )
cDataHoraHuso := cDataHoraHuso + "T" + cTime
cDataHoraHuso := cDataHoraHuso + If( lHorariestiu( dDate ), "+02:00", "+01:00" )

Return cDataHoraHuso
/* *********************************************************************************** */


A mi me funciona y Verifactu da por buena la 'Huella' que le envío.

A ver si te sirve.
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1190
Joined: Mon Oct 10, 2005 2:38 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby Julio Cepeda » Mon Nov 18, 2024 3:43 pm

Muchas gracias Carlos. He estado probando anteriormente con una función muy parecida a la que me has pasado que creo recordar que la escribió Quim Ferrer, y no lo hacía como lo haces tu. Voy a probar y te digo. Gracias de nuevo y un saludo.
Saludos

julio@cepedaserinf.es
FiveWin 22.12 + Harbour 3.2.0dev (r2008190002), BCC 7 Windows 11
User avatar
Julio Cepeda
 
Posts: 65
Joined: Wed Oct 12, 2005 6:58 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby Garbi » Mon Nov 18, 2024 4:07 pm

Hola a todos.

Ya estoy volviendo un poco a la normalidad, (aún me queda mucho barro por sacar del garaje) pero poco a poco se va haciendo todo. Eso si, es muy cansado, parece el día de la marmota, espero no les ocurra a nadie de vosotros nunca. Tienes un sensación de desatención que te derrota. Hay tal cantidad de afectados que la ayuda no puede llegar a todos, pero la vida continua, no te deja hacer un parón.

Quisiera me pudieran explicar, yo diría que como empezar:
Yo las pruebas que he hecho es haciendo a mano el fichero xml.
Agradecería me explicarais como saber cual la estructura correcta del fichero antes de enviar, porque creo que aún están haciendo cambios.
Como crean el fichero .xml para dar una factura de alta mediante código. Ya me habéis dicho que es lo más sencillo, pero es que no tengo ni idea ni la cabeza para ir investigando, agradecería cual ayuda.

Se que estoy pidiendo tiempo vuestro del que no disponéis mucho, pero es que nunca he utilizado fichero xml en mis desarrollos y no quiero estar haciendo programación que después no sirva.

Espero haberme explicado bien.
Saludos,
Regards,

Jose Luis Alepuz
joseluis@mancomputer.com
www.mancomputer.com
Garbi
 
Posts: 341
Joined: Wed Nov 02, 2005 3:28 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby VictorCasajuana » Mon Nov 18, 2024 5:42 pm

Garbi wrote:Hola a todos.

Ya estoy volviendo un poco a la normalidad, (aún me queda mucho barro por sacar del garaje) pero poco a poco se va haciendo todo. Eso si, es muy cansado, parece el día de la marmota, espero no les ocurra a nadie de vosotros nunca. Tienes un sensación de desatención que te derrota. Hay tal cantidad de afectados que la ayuda no puede llegar a todos, pero la vida continua, no te deja hacer un parón.

Quisiera me pudieran explicar, yo diría que como empezar:
Yo las pruebas que he hecho es haciendo a mano el fichero xml.
Agradecería me explicarais como saber cual la estructura correcta del fichero antes de enviar, porque creo que aún están haciendo cambios.
Como crean el fichero .xml para dar una factura de alta mediante código. Ya me habéis dicho que es lo más sencillo, pero es que no tengo ni idea ni la cabeza para ir investigando, agradecería cual ayuda.

Se que estoy pidiendo tiempo vuestro del que no disponéis mucho, pero es que nunca he utilizado fichero xml en mis desarrollos y no quiero estar haciendo programación que después no sirva.

Espero haberme explicado bien.

Hola Garbi.
Ánimo con lo que te ha tocado pasar. Conozco a gente que está limpiando y lo que me cuentan es muy duro.

El esquema del fichero xml ya está en la versión 1.0, por lo que si sufre cambios no serán muy grandes ( supongo )
En este enlace puedes ver todos los campos y a que corresponden cada uno de ellos: https://www.agenciatributaria.es/AEAT.desarrolladores/Desarrolladores/_menu_/Documentacion/Sistemas_Informaticos_de_Facturacion_y_Sistemas_VERI_FACTU/Documento_Diseno_de_registro_de_facturacion/Documento_Diseno_de_registro_de_facturacion.html

Referente a montar el xml, en este hilo se han explicado varias formas, la mía no la puedo aportar ya que utilizo una librería externa ( xilkat ) por lo que mi código no os funcionará.

Salud!
--------
¿ Y porque no ?
¿ And why not ?
User avatar
VictorCasajuana
 
Posts: 265
Joined: Wed Mar 28, 2018 4:38 pm
Location: Vinaròs

Re: España: Normativa sancionadora sistemas informáticos

Postby Garbi » Mon Nov 18, 2024 5:50 pm

Gracias Víctor, ese fichero lo tengo.

Si alguien me pudiera indicar como podría ser el código puro y duro de fivewin para hacer el fichero xml lo agradecería muchísimo.

Paquito, creo que usa un fichero general y modifica y borra lo que no necesita, si Paquito o alguien pudiera ponerlo o enviármelo por email (mi email esta en la firma) estaría muy agradecido.

Muchas gracias por vuestra colaboración.
Saludos,
Regards,

Jose Luis Alepuz
joseluis@mancomputer.com
www.mancomputer.com
Garbi
 
Posts: 341
Joined: Wed Nov 02, 2005 3:28 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby FiveWiDi » Mon Nov 18, 2024 7:56 pm

Garbi wrote:Si alguien me pudiera indicar como podría ser el código puro y duro de fivewin para hacer el fichero xml lo agradecería muchísimo.

Paquito, creo que usa un fichero general y modifica y borra lo que no necesita, si Paquito o alguien pudiera ponerlo o enviármelo por email (mi email esta en la firma) estaría muy agradecido.


Hola Garbi,

Yo creo que lo mejor es meterse ya con funciones y clases para manejar XML, es un estándar.

El código que adjunto en mis post acostumbra a ser una copia modificada de código que veo en este foro (muchas gracias a todos).

Como estoy probando aún tengo que eliminar mucho comentario del código.

Adjunto las clases (las tengo en un solo fichero) que utilizo para generar el XML:
Code: Select all  Expand view  RUN

/* 16/07/2024

   CLASSE PER GENERAR EL XML DE VERIFACTU.
   =======================================

   Classes per a crear el fitxer XML que serà enviat a VERI*FACTU.
   
   En fase de desenvolupament 30/07/2024.
   
   ********************************************************
   Model NÓMES per presentar registres d'ALTES de factures.
   ********************************************************
   
   04/11/2024 adaptat a l'indicat per Hisenda.
   Sembla que ja és operativa en aspectes bàsics. 13/08/2024

*/


#include "Hbxml.ch"
#include "Hbclass.ch"
#include "Fileio.ch"

CLASS TVeriFactu00

    // Declaració de les DATA a on s'assignaran els valors a capturar.
    // Totes les DATA es gestionaran en modus caràcter o objectes XML.
    DATA oXmlTop
    DATA oXmlSoapEnvelope
        DATA oXmlRegFactuSistemaFacturacion
            DATA oXmlCabecera
                // Dades pel TAG Cabecera
                //DATA cIDVersion
                DATA oXmlObligadoEmision
                    // Dades pel TAG ObligadoEmision
                    DATA cObligadoEmision_NombreRazon
                    DATA cObligadoEmision_NIF
                DATA oXmlRepresentante
                    // Dades pel TAG Representante
                    DATA cRepresentante_NombreRazon
                    DATA cRepresentante_NIF
                DATA oXmlRemisionVoluntaria
                    // Dades pel TAG RemisionVoluntaria
                    DATA cFechaFinVeriFactu
                    DATA cIncidencia
                DATA oXmlRemisionRequerimiento
                    // Dades pel TAG RemisionRequerimiento
                    DATA cRefRequerimiento
                    DATA cFinRequerimiento

            DATA aRegistroFactura  INIT {}  //  -- >> Fins a 1000


    // DATA d'ús intern o que no contenen la informació a tractar.
    DATA     lError


    // ACCESS a les DATA per tal de ser usades.
    // De momento se aplica la conversión a UTF8, excepto a las huellas.
    //ACCESS IDVersion                   INLINE ( hb_StrToUTF8( alltrim( ::cIDVersion ) ) )
    ACCESS ObligadoEmision_NombreRazon INLINE ( hb_StrToUTF8( alltrim( ::cObligadoEmision_NombreRazon ) ) )
    ACCESS ObligadoEmision_NIF         INLINE ( hb_StrToUTF8( alltrim( ::cObligadoEmision_NIF ) ) )
    ACCESS Representante_NombreRazon INLINE ( hb_StrToUTF8( alltrim( ::cRepresentante_NombreRazon ) ) )
    ACCESS Representante_NIF         INLINE ( hb_StrToUTF8( alltrim( ::cRepresentante_NIF ) ) )
    //ACCESS FechaFinVeriFactu           INLINE ( hb_StrToUTF8( alltrim( ::cFechaFinVeriFactu ) ) )
    //ACCESS Incidencia                  INLINE ( hb_StrToUTF8( alltrim( ::cIncidencia ) ) )
    ACCESS RefRequerimiento            INLINE ( hb_StrToUTF8( alltrim( ::cRefRequerimiento ) ) )
    ACCESS FinRequerimiento            INLINE ( hb_StrToUTF8( alltrim( ::cFinRequerimiento ) ) )


    // Métodes per gestionar la classe.

    METHOD New() CONSTRUCTOR
    METHOD ToXML()          //  Genera estructura XML con los datos.
    METHOD GeneraXml( cFichero )      //  Vuelca el XML a fichero.

    // Añade datos de una factura para ser usados en el momento de generar XML.
    METHOD AddFactura( oFactura )   INLINE ( AADD( ::aRegistroFactura, oFactura ) )

ENDCLASS

//---------------------------------------------------------------------------//

METHOD New() CLASS TVeriFactu00

   ::lError                         := .f.

Return ( self )

//---------------------------------------------------------------------------//

METHOD ToXML() CLASS TVeriFactu00

    Local oXmlBody         := Nil
    Local nContador        := 0


    /*
       Comienza el Nodo principal--------------------------------------------------
    */

    //::oXmlTop         := TXmlDocument():new( '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sum="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd" xmlns:sum1="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd" xmlns:xd="http://www.w3.org/2000/09/xmldsig#">' )

    ::oXmlTop         := TXmlDocument():new( )

    ::oXmlTop:oRoot:AddBelow( TxmlNode():New( HBXML_TYPE_COMMENT, , , "Primeres proves..." ) )
    ::oXmlTop:oRoot:AddBelow( TxmlNode():New( HBXML_TYPE_COMMENT, , , "Date: " + DToC( Date() ) + " Time: " + Time() ) )
    ::oXmlTop:oRoot:AddBelow( TxmlNode():New( HBXML_TYPE_COMMENT, , , "Last access: " + GetEnv( "USERNAME" ) ) )

    ::oXmlSoapEnvelope := TxmlNode():New( HBXML_TYPE_TAG, "soapenv:Envelope" )
    ::oXmlTop:oRoot:AddBelow( ::oXmlSoapEnvelope )
    ::oXmlSoapEnvelope:SetAttribute( "xmlns:soapenv", "http://schemas.xmlsoap.org/soap/envelope/" )
    ::oXmlSoapEnvelope:SetAttribute( "xmlns:sum", "https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd" )
    ::oXmlSoapEnvelope:SetAttribute( "xmlns:sum1", "https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd" )
    ::oXmlSoapEnvelope:SetAttribute( "xmlns:xd", "http://www.w3.org/2000/09/xmldsig#" )
    //::oXmlTop:oRoot:AddBelow( ::oXmlSoapEnvelope )


    ::oXmlSoapEnvelope:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, "soapenv:Header" ) )
    oXmlBody := TxmlNode():New( HBXML_TYPE_TAG, "soapenv:Body" )
    ::oXmlSoapEnvelope:AddBelow( oXmlBody )


    /*
       Comienza el Nodo RegFactuSistemaFacturacion--------------------------------------------------
    */
 
    ::oXmlRegFactuSistemaFacturacion := TxmlNode():New( HBXML_TYPE_TAG, "sum:RegFactuSistemaFacturacion" )
    oXmlBody:AddBelow( ::oXmlRegFactuSistemaFacturacion )


    /*
       Comienza el Nodo Cabecera--------------------------------------------------
    */

    ::oXmlCabecera := TxmlNode():New( HBXML_TYPE_TAG, "sum:Cabecera" )
    ::oXmlRegFactuSistemaFacturacion:AddBelow( ::oXmlCabecera )

    //::oXmlCabecera:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'IDVersion', , ::cIDVersion ) )
    ::oXmlObligadoEmision := TxmlNode():New( HBXML_TYPE_TAG, "sum1:ObligadoEmision" )
    ::oXmlCabecera:AddBelow( ::oXmlObligadoEmision )
    ::oXmlObligadoEmision:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NombreRazon', , ::ObligadoEmision_NombreRazon() ) )
    ::oXmlObligadoEmision:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NIF', , ::ObligadoEmision_NIF() ) )

    If .Not. Empty( ::cRepresentante_NombreRazon )
        ::oXmlRepresentante := TxmlNode():New( HBXML_TYPE_TAG, "sum1:Representante" )
        ::oXmlCabecera:AddBelow( ::oXmlRepresentante )
        ::oXmlRepresentante:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NombreRazon', , ::Representante_NombreRazon() ) )
        ::oXmlRepresentante:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NIF', , ::Representante_NIF() ) )
    EndIf

    //::oXmlCabecera:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'TipoRegistroAEAT', , ::cTipoRegistroAEAT ) )
    If .Not. Empty( ::cFechaFinVeriFactu ) .or. .Not. Empty( ::cIncidencia )
        ::oXmlRemisionVoluntaria := TxmlNode():New( HBXML_TYPE_TAG, 'RemisionVoluntaria' )
        ::oXmlCabecera:AddBelow( ::oXmlRemisionVoluntaria )
        If .Not. Empty( ::cFechaFinVeriFactu )
            ::oXmlRemisionVoluntaria:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'FechaFinVeriFactu', , ::cFechaFinVeriFactu ) )
        EndIf
        If .Not. Empty( ::cIncidencia )
            ::oXmlRemisionVoluntaria:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'Incidencia', , ::cIncidencia ) )
        EndIf
    EndIf
    If .Not. Empty( ::cRefRequerimiento )
        ::oXmlRemisionRequerimiento := TxmlNode():New( HBXML_TYPE_TAG, 'RemisionRequerimiento' )
        ::oXmlCabecera:AddBelow( ::oXmlRemisionRequerimiento )
        ::oXmlRemisionRequerimiento:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'RefRequerimiento', , ::RefRequerimiento() ) )
        If .Not. Empty( ::cFinRequerimiento )
            ::oXmlRemisionRequerimiento:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'FinRequerimiento', , ::FinRequerimiento() ) )
        EndIf
    EndIf

    /*
       Comienza el Nodo RegistroFactura--------------------------------------------------
    */

    For nContador := 1 To Len( ::aRegistroFactura )
        ::oXmlRegFactuSistemaFacturacion:AddBelow( ::aRegistroFactura[nContador]:ToXML() )
    End

Return ( Self )
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
METHOD GeneraXML( cFichero )  CLASS TVeriFactu00

Local hDC := 0
   
   /*
   Generar fisicamente el fichero----------------------------------------------
   */


   //oBlock         := ErrorBlock( {| oError | ApoloBreak( oError ) } )
   BEGIN SEQUENCE

      ferase( cFichero )

      hDC       := fCreate( cFichero )

      if hDC < 0
          hDC := 0
      endif

      ::oXmlTop:Write( hDC, HBXML_STYLE_INDENT + HBXML_STYLE_THREESPACES )

      fClose( hDC )

      hDC := 0

   RECOVER   //   USING oError

      ::lError    := .t.

   END SEQUENCE

   //ErrorBlock( oBlock )

   // GoWeb( AllTrim( cFichero ) )

Return ( Self )

/* ***************************************************************************** */
/* ***************************************************************************** */
/* ***************************************************************************** */

CLASS RegistroFactura

    // Declaració de les DATA a on s'assignaran els valors a capturar.
    // Totes les DATA es gestionaran en modus caràcter o objectes XML.

    //DATA oXmlRegistroFactura
        // Dades pel TAG oXmlRegistroFactura
        //DATA oXmlRegistroAlta
            // Dades pel TAG RegistroAlta
            DATA cIDVersion
            //DATA oXmlIDFactura
                // Dades pel TAG IDFactura
                DATA cIDEmisorFactura
                DATA cNumSerieFactura
                DATA cFechaExpedicionFactura
            DATA cRefExterna
            DATA cNombreRazonEmisor
            DATA cSubsanacion
            DATA cRechazoPrevio
            //DATA cTipoRegistroSIF
            DATA cTipoFactura
            DATA cTipoRectificativa
            //DATA oXmlFacturasRectificadas
                // Dades pel TAG FacturasRectificadas
                DATA aIDFacturaRectificada  INIT {}     //  -- >> Fins a 1000
            //DATA oXmlFacturasSustituidas
                // Dades pel TAG FacturasSustituidas
                DATA aIDFacturaSustituida  INIT    {} //  -- >> Fins a 1000
            //DATA oXmlImporteRectificacion
                // Dades pel TAG ImporteRectificacion
                DATA cBaseRectificada
                DATA cCuotaRectificada
                DATA cCuotaRecargoRectificado
            DATA cFechaOperacion
            DATA cDescripcionOperacion
            DATA cFacturaSimplificadaArt7273
            DATA cFacturaSinIdentifDestinatarioArt61d
            DATA cMacrodato
            DATA cEmitidaPorTercerosODestinatario
            //DATA oXmlTercero
                // Dades pel TAG Tercero
                DATA cTercero_NombreRazon
                DATA cTercero_NIF
                //DATA oXmlTercero_IDOtro
                    // Dades pel TAG IDOtro
                    DATA cTercero_IDOtro_CodigoPais
                    DATA cTercero_IDOtro_IDType
                    DATA cTercero_IDOtro_ID
            //DATA oXmlDestinatarios
                // Dades pel TAG Destinatarios
                DATA aIDDestinatario  INIT  {}  //    -- >> Fins a 1000
            DATA cCupon
            //DATA oXmlDesglose
                // Dades pel TAG Desglose
                DATA aDetalleDesglose  INIT {}  //    -- >> Fins a 12
            DATA cCuotaTotal
            DATA cImporteTotal
            //DATA oXmlEncadenamiento
                // Dades pel TAG Encadenamiento
                DATA cPrimerRegistro
                //DATA oXmlIRegistroAnterior
                    // Dades pel TAG IDRegistroAnterior
                    DATA cIDEmisorFacturaRegistroAnterior
                    DATA cNumSerieFacturaRegistroAnterior
                    DATA cFechaExpedicionFacturaRegistroAnterior
                    DATA cHuellaRegistroAnterior
            //DATA oXmlSistemaInformatico
                // Dades pel TAG SistemaInformatico
                DATA cSistemaInformatico_NombreRazon
                DATA cSistemaInformatico_NIF
                //DATA oXmlSistemaInformatico_IDOtro
                    // Dades pel TAG IDOtro
                    DATA cSistemaInformatico_IDOtro_CodigoPais
                    DATA cSistemaInformatico_IDOtro_IDType
                    DATA cSistemaInformatico_IDOtro_ID
                DATA cNombreSistemaInformatico
                DATA cIdSistemaInformatico
                DATA cVersion
                DATA cNumeroInstalacion
                DATA cTipoUsoPosibleSoloVerifactu
                DATA cTipoUsoPosibleMultiOT
                DATA cIndicadorMultiplesOT
                //DATA cNumeroOTAlta
            DATA cFechaHoraHusoGenRegistro

            //DATA cFechaGenRegistro
            //DATA cHoraGenRegistro
            //DATA cHusoHorarioGenRegistro

            DATA cNumRegistroAcuerdoFacturacion
            DATA cIdAcuerdoSistemaInformatico
        //DATA oXmlDatosControl
            // Dades pel TAG DatosControl
            DATA cTipoHuella
            DATA cHuella
            DATA cSignature
           

    // ACCESS a les DATA per tal de ser usades.
    // De momento se aplica la conversión a UTF8, excepto a las huellas.   
    ACCESS IDVersion                                  INLINE ( hb_StrToUTF8( alltrim( ::cIDVersion ) ) )
    ACCESS IDEmisorFactura                            INLINE ( hb_StrToUTF8( alltrim( ::cIDEmisorFactura ) ) )
    ACCESS NumSerieFactura                            INLINE ( hb_StrToUTF8( alltrim( ::cNumSerieFactura ) ) )
    ACCESS FechaExpedicionFactura                     INLINE ( hb_StrToUTF8( alltrim( ::cFechaExpedicionFactura ) ) )
    ACCESS RefExterna                                 INLINE ( hb_StrToUTF8( alltrim( ::cRefExterna ) ) )
    ACCESS NombreRazonEmisor                          INLINE ( hb_StrToUTF8( alltrim( ::cNombreRazonEmisor ) ) )
    ACCESS Subsanacion                                INLINE ( hb_StrToUTF8( alltrim( ::cSubsanacion ) ) )
    ACCESS RechazoPrevio                              INLINE ( hb_StrToUTF8( alltrim( ::cRechazoPrevio ) ) )
    //ACCESS TipoRegistroSIF                            INLINE ( hb_StrToUTF8( alltrim( ::cTipoRegistroSIF ) ) )
    ACCESS TipoFactura                                INLINE ( hb_StrToUTF8( alltrim( ::cTipoFactura ) ) )
    ACCESS TipoRectificativa                          INLINE ( hb_StrToUTF8( alltrim( ::cTipoRectificativa ) ) )
    ACCESS BaseRectificada                            INLINE ( hb_StrToUTF8( alltrim( ::cBaseRectificada ) ) )
    ACCESS CuotaRectificada                           INLINE ( hb_StrToUTF8( alltrim( ::cCuotaRectificada ) ) )
    ACCESS CuotaRecargoRectificado                    INLINE ( hb_StrToUTF8( alltrim( ::cCuotaRecargoRectificado ) ) )
    ACCESS FechaOperacion                             INLINE ( hb_StrToUTF8( alltrim( ::cFechaOperacion ) ) )
    ACCESS DescripcionOperacion                       INLINE ( hb_StrToUTF8( alltrim( ::cDescripcionOperacion ) ) )
    ACCESS FacturaSimplificadaArt7273                 INLINE ( hb_StrToUTF8( alltrim( ::cFacturaSimplificadaArt7273 ) ) )
    ACCESS FacturaSinIdentifDestinatarioArt61d        INLINE ( hb_StrToUTF8( alltrim( ::cFacturaSinIdentifDestinatarioArt61d ) ) )
    ACCESS Macrodato                                  INLINE ( hb_StrToUTF8( alltrim( ::cMacrodato ) ) )
    ACCESS EmitidaPorTercerosODestinatario            INLINE ( hb_StrToUTF8( alltrim( ::cEmitidaPorTercerosODestinatario ) ) )
    ACCESS Tercero_NombreRazon                        INLINE ( hb_StrToUTF8( alltrim( ::cTercero_NombreRazon ) ) )
    ACCESS Tercero_NIF                                INLINE ( hb_StrToUTF8( alltrim( ::cTercero_NIF ) ) )
    ACCESS Tercero_IDOtro_CodigoPais                  INLINE ( hb_StrToUTF8( alltrim( ::cTercero_IDOtro_CodigoPais ) ) )
    ACCESS Tercero_IDOtro_IDType                      INLINE ( hb_StrToUTF8( alltrim( ::cTercero_IDOtro_IDType ) ) )
    ACCESS Tercero_IDOtro_ID                          INLINE ( hb_StrToUTF8( alltrim( ::cTercero_IDOtro_ID ) ) )
    ACCESS Cupon                                      INLINE ( hb_StrToUTF8( alltrim( ::cCupon ) ) )
    ACCESS CuotaTotal                                 INLINE ( hb_StrToUTF8( alltrim( ::cCuotaTotal ) ) )
    ACCESS ImporteTotal                               INLINE ( hb_StrToUTF8( alltrim( ::cImporteTotal ) ) )
    ACCESS PrimerRegistro                             INLINE ( hb_StrToUTF8( alltrim( ::cPrimerRegistro ) ) )
    ACCESS IDEmisorFacturaRegistroAnterior            INLINE ( hb_StrToUTF8( alltrim( ::cIDEmisorFacturaRegistroAnterior ) ) )
    ACCESS NumSerieFacturaRegistroAnterior            INLINE ( hb_StrToUTF8( alltrim( ::cNumSerieFacturaRegistroAnterior ) ) )
    ACCESS FechaExpedicionFacturaRegistroAnterior     INLINE ( hb_StrToUTF8( alltrim( ::cFechaExpedicionFacturaRegistroAnterior ) ) )
    ACCESS HuellaRegistroAnterior                     INLINE ( alltrim( ::cHuellaRegistroAnterior ) )
    ACCESS SistemaInformatico_NombreRazon             INLINE ( hb_StrToUTF8( alltrim( ::cSistemaInformatico_NombreRazon ) ) )
    ACCESS SistemaInformatico_NIF                     INLINE ( hb_StrToUTF8( alltrim( ::cSistemaInformatico_NIF ) ) )
    ACCESS SistemaInformatico_IDOtro_CodigoPais       INLINE ( hb_StrToUTF8( alltrim( ::cSistemaInformatico_IDOtro_CodigoPais ) ) )
    ACCESS SistemaInformatico_IDOtro_IDType           INLINE ( hb_StrToUTF8( alltrim( ::cSistemaInformatico_IDOtro_IDType ) ) )
    ACCESS SistemaInformatico_IDOtro_ID               INLINE ( hb_StrToUTF8( alltrim( ::cSistemaInformatico_IDOtro_ID ) ) )
    ACCESS NombreSistemaInformatico                   INLINE ( hb_StrToUTF8( alltrim( ::cNombreSistemaInformatico ) ) )
    ACCESS IdSistemaInformatico                       INLINE ( hb_StrToUTF8( alltrim( ::cIdSistemaInformatico ) ) )
    ACCESS Version                                    INLINE ( hb_StrToUTF8( alltrim( ::cVersion ) ) )
    ACCESS NumeroInstalacion                          INLINE ( hb_StrToUTF8( alltrim( ::cNumeroInstalacion ) ) )
    ACCESS TipoUsoPosibleSoloVerifactu                INLINE ( hb_StrToUTF8( alltrim( ::cTipoUsoPosibleSoloVerifactu ) ) )
    ACCESS TipoUsoPosibleMultiOT                      INLINE ( hb_StrToUTF8( alltrim( ::cTipoUsoPosibleMultiOT ) ) )
    ACCESS IndicadorMultiplesOT                       INLINE ( hb_StrToUTF8( alltrim( ::cIndicadorMultiplesOT ) ) )
    //ACCESS NumeroOTAlta                               INLINE ( hb_StrToUTF8( alltrim( ::cNumeroOTAlta ) ) )
    ACCESS FechaHoraHusoGenRegistro                   INLINE ( hb_StrToUTF8( alltrim( ::cFechaHoraHusoGenRegistro ) ) )

    //ACCESS HoraGenRegistro                            INLINE ( hb_StrToUTF8( alltrim( ::cHoraGenRegistro ) ) )
    //ACCESS HusoHorarioGenRegistro                     INLINE ( hb_StrToUTF8( alltrim( ::cHusoHorarioGenRegistro ) ) )
   
    ACCESS NumRegistroAcuerdoFacturacion              INLINE ( hb_StrToUTF8( alltrim( ::cNumRegistroAcuerdoFacturacion ) ) )
    ACCESS IdAcuerdoSistemaInformatico                INLINE ( hb_StrToUTF8( alltrim( ::cIdAcuerdoSistemaInformatico ) ) )
    ACCESS TipoHuella                                 INLINE ( hb_StrToUTF8( alltrim( ::cTipoHuella ) ) )
    ACCESS Huella                                     INLINE ( alltrim( ::cHuella ) )
    ACCESS Signature                                  INLINE ( hb_StrToUTF8( alltrim( ::cSignature ) ) )
   

    // Métodes per gestionar la classe.

    METHOD New() CONSTRUCTOR
    METHOD ToXML()      //  Genera estructura XML con los datos.


    // Guardan grupos de DATA repetitivos.
    METHOD AddFacturaRectificada( oFacturaRectificada ) INLINE ( AADD( ::aIDFacturaRectificada, oFacturaRectificada ) )
    METHOD AddFacturaSustituida( oFacturaSustituida )   INLINE ( AADD( ::aIDFacturaSustituida, oFacturaSustituida ) )
    METHOD AddIDDestinatario( oIDDestinatario )         INLINE ( AADD( ::aIDDestinatario, oIDDestinatario ) )
    METHOD AddaDetalleDesglose( oDetalleDesglose )      INLINE ( AADD( ::aDetalleDesglose, oDetalleDesglose ) )

ENDCLASS

//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//

METHOD New( ) CLASS RegistroFactura

Return ( self )

//---------------------------------------------------------------------------//

METHOD ToXML() CLASS RegistroFactura

Local oXmlRegistroFactura
Local oXmlRegistroAlta
Local oXmlIDFactura
Local oXmlFacturasRectificadas
Local oXmlFacturasSustituidas
Local oXmlImporteRectificacion
Local oXmlTercero
Local oXmlIDOtro
Local oXmlDestinatarios
Local oXmlDesglose
Local oXmlEncadenamiento
Local oXmlRegistroAnterior
//Local oXmlIDEmisorFacturaRegistroAnterior
Local oXmlSistemaInformatico
Local oXmlSistemaInformatico_IDOtro
//Local oXmlDatosControl
Local nContador           := 0

    oXmlRegistroFactura := TxmlNode():New( HBXML_TYPE_TAG, "sum:RegistroFactura" )

    oXmlRegistroAlta := TxmlNode():New( HBXML_TYPE_TAG, "sum1:RegistroAlta" )
    oXmlRegistroFactura:AddBelow( oXmlRegistroAlta )

    oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IDVersion', , ::IDVersion() ) )

    // IDFactura
    oXmlIDFactura := TxmlNode():New( HBXML_TYPE_TAG, "sum1:IDFactura" )
    oXmlRegistroAlta:AddBelow( oXmlIDFactura )
    oXmlIDFactura:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IDEmisorFactura', , ::IDEmisorFactura() ) )
    oXmlIDFactura:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NumSerieFactura', , ::NumSerieFactura() ) )
    oXmlIDFactura:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:FechaExpedicionFactura', , ::FechaExpedicionFactura() ) )

    If .Not. Empty( ::cRefExterna )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:RefExterna', , ::RefExterna() ) )
    EndIf
   
    oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NombreRazonEmisor', , ::NombreRazonEmisor() ) )
   
    If .Not. Empty( ::cSubsanacion )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:Subsanacion', , ::Subsanacion() ) )
    EndIf
    If .Not. Empty( ::cRechazoPrevio )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:RechazoPrevio', , ::RechazoPrevio() ) )
    EndIf
   
    oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:TipoFactura', , ::TipoFactura() ) )
    If .Not. Empty( ::cTipoRectificativa )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:TipoRectificativa', , ::TipoRectificativa() ) )
    EndIf

    // IDFacturaRectificada
    If .Not. Empty( ::aIDFacturaRectificada )
        oXmlFacturasRectificadas := TxmlNode():New( HBXML_TYPE_TAG, "sum1:FacturasRectificadas" )
        oXmlRegistroAlta:AddBelow( oXmlFacturasRectificadas )
        For nContador := 1 To Len( ::aIDFacturaRectificada )
            oXmlFacturasRectificadas:AddBelow( ::aIDFacturaRectificada[nContador]:ToXML() )
        End
    EndIf

    // IDFacturaSustituida
    If .Not. Empty( ::aIDFacturaSustituida )
        oXmlFacturasSustituidas := TxmlNode():New( HBXML_TYPE_TAG, "sum1:FacturasSustituidas" )
        oXmlRegistroAlta:AddBelow( oXmlFacturasSustituidas )
        For nContador := 1 To Len( ::aIDFacturaSustituida )
            oXmlFacturasSustituidas:AddBelow( ::aIDFacturaSustituida[nContador]:ToXML() )
        End
    EndIf

    // ImporteRectificacion
    If .Not. Empty( ::cBaseRectificada )
        oXmlImporteRectificacion := TxmlNode():New( HBXML_TYPE_TAG, "sum1:ImporteRectificacion" )
        oXmlRegistroAlta:AddBelow( oXmlImporteRectificacion )
        oXmlImporteRectificacion:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:BaseRectificada', , ::BaseRectificada() ) )
        oXmlImporteRectificacion:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:CuotaRectificada', , ::CuotaRectificada() ) )
        If .not. Empty( ::cCuotaRecargoRectificado )
            oXmlImporteRectificacion:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:CuotaRecargoRectificado', , ::CuotaRecargoRectificado() ) )
        EndIf
    EndIf
   
    If .not. Empty( ::cFechaOperacion )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:FechaOperacion', , ::FechaOperacion() ) )
    EndIf

    oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:DescripcionOperacion', , ::DescripcionOperacion() ) )

    If .not. Empty( ::cFacturaSimplificadaArt7273 )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:FacturaSimplificadaArt7273', , ::FacturaSimplificadaArt7273() ) )
    EndIf

    If .not. Empty( ::cFacturaSinIdentifDestinatarioArt61d )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:FacturaSinIdentifDestinatarioArt61d', , ::FacturaSinIdentifDestinatarioArt61d() ) )
    EndIf

    If .not. Empty( ::cMacrodato )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:Macrodato', , ::Macrodato() ) )
    EndIf

    // EmitidaPorTercerosODestinatario
    If .not. Empty( ::cEmitidaPorTercerosODestinatario )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:EmitidaPorTercerosODestinatario', , ::EmitidaPorTercerosODestinatario() ) )
        oXmlTercero := TxmlNode():New( HBXML_TYPE_TAG, "sum1:Tercero" )
        oXmlRegistroAlta:AddBelow( oXmlTercero )
        oXmlTercero:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NombreRazon', , ::Tercero_NombreRazon() ) )
        If .Not. Empty( ::cTercero_NIF )
            oXmlTercero:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NIF', , ::Tercero_NIF() ) )
        EndIf

        If .Not. Empty( ::cTercero_IDOtro_IDType )
            oXmlIDOtro := TxmlNode():New( HBXML_TYPE_TAG, "sum1:IDOtro" )
            oXmlTercero:AddBelow( oXmlIDOtro )
            If .Not. Empty( ::cTercero_IDOtro_CodigoPais )
                oXmlIDOtro:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:CodigoPais', , ::Tercero_IDOtro_CodigoPais() ) )
            EndIf
            oXmlIDOtro:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IDType', , ::Tercero_IDOtro_IDType() ) )
            oXmlIDOtro:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:ID', , ::Tercero_IDOtro_ID() ) )
        EndIf
    EndIf
   
    // IDDestinatario
    If .Not. Empty( ::aIDDestinatario )
        oXmlDestinatarios := TxmlNode():New( HBXML_TYPE_TAG, "sum1:Destinatarios" )
        oXmlRegistroAlta:AddBelow( oXmlDestinatarios )
        For nContador := 1 To Len( ::aIDDestinatario )
            oXmlDestinatarios:AddBelow( ::aIDDestinatario[nContador]:ToXML() )
        End
    EndIf

    If .not. Empty( ::cCupon )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:Cupon', , ::Cupon() ) )
    EndIf
   
    // Desglose
    oXmlDesglose := TxmlNode():New( HBXML_TYPE_TAG, "sum1:Desglose" )
    oXmlRegistroAlta:AddBelow( oXmlDesglose )
    For nContador := 1 To Len( ::aDetalleDesglose )
        oXmlDesglose:AddBelow( ::aDetalleDesglose[nContador]:ToXML() )
    End

    oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:CuotaTotal', , ::CuotaTotal() ) )
    oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:ImporteTotal', , ::ImporteTotal() ) )
   
    // Encadenamiento
    oXmlEncadenamiento := TxmlNode():New( HBXML_TYPE_TAG, "sum1:Encadenamiento" )
    oXmlRegistroAlta:AddBelow( oXmlEncadenamiento )
    If .Not. Empty( ::cPrimerRegistro )
        oXmlEncadenamiento:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:PrimerRegistro', , ::PrimerRegistro() ) )
    EndIf

    If .Not. Empty( ::cIDEmisorFacturaRegistroAnterior )
        oXmlRegistroAnterior := TxmlNode():New( HBXML_TYPE_TAG, "sum1:RegistroAnterior" )
        oXmlEncadenamiento:AddBelow( oXmlRegistroAnterior )
        oXmlRegistroAnterior:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IDEmisorFactura', , ::IDEmisorFacturaRegistroAnterior() ) )
        oXmlRegistroAnterior:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NumSerieFactura', , ::NumSerieFacturaRegistroAnterior() ) )
        oXmlRegistroAnterior:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:FechaExpedicionFactura', , ::FechaExpedicionFacturaRegistroAnterior() ) )
        oXmlRegistroAnterior:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:Huella', , ::HuellaRegistroAnterior() ) )
    EndIf

    // SistemaInformatico
    oXmlSistemaInformatico := TxmlNode():New( HBXML_TYPE_TAG, "sum1:SistemaInformatico" )
    oXmlRegistroAlta:AddBelow( oXmlSistemaInformatico )
    oXmlSistemaInformatico:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NombreRazon', , ::SistemaInformatico_NombreRazon() ) )
    If .not. Empty( ::cSistemaInformatico_NIF )
        oXmlSistemaInformatico:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NIF', , ::SistemaInformatico_NIF() ) )
    EndIf
    If .not. Empty( ::cSistemaInformatico_IDOtro_IDType )
        oXmlSistemaInformatico_IDOtro := TxmlNode():New( HBXML_TYPE_TAG, "sum1:IDOtro" )
        oXmlSistemaInformatico:AddBelow( oXmlSistemaInformatico_IDOtro )
        If .not. Empty( ::cSistemaInformatico_IDOtro_CodigoPais )
            oXmlSistemaInformatico_IDOtro:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:CodigoPais', , ::SistemaInformatico_IDOtro_CodigoPais() ) )
        EndIf
        oXmlSistemaInformatico_IDOtro:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IDType', , ::SistemaInformatico_IDOtro_IDType() ) )
        oXmlSistemaInformatico_IDOtro:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:ID', , ::SistemaInformatico_IDOtro_ID() ) )
    EndIf
    oXmlSistemaInformatico:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NombreSistemaInformatico', , ::NombreSistemaInformatico() ) )
    oXmlSistemaInformatico:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IdSistemaInformatico', , ::IdSistemaInformatico() ) )
    oXmlSistemaInformatico:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:Version', , ::Version() ) )
    oXmlSistemaInformatico:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NumeroInstalacion', , ::NumeroInstalacion() ) )
    oXmlSistemaInformatico:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:TipoUsoPosibleSoloVerifactu', , ::TipoUsoPosibleSoloVerifactu() ) )
    oXmlSistemaInformatico:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:TipoUsoPosibleMultiOT', , ::TipoUsoPosibleMultiOT() ) )
    oXmlSistemaInformatico:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IndicadorMultiplesOT', , ::IndicadorMultiplesOT() ) )
   
    oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:FechaHoraHusoGenRegistro', , ::FechaHoraHusoGenRegistro() ) )

    If .Not. Empty( ::cNumRegistroAcuerdoFacturacion )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NumRegistroAcuerdoFacturacion', , ::NumRegistroAcuerdoFacturacion() ) )
    EndIf
    If .Not. Empty( ::cIdAcuerdoSistemaInformatico )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IdAcuerdoSistemaInformatico', , ::IdAcuerdoSistemaInformatico() ) )
    EndIf
   
    oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:TipoHuella', , ::TipoHuella() ) )
    oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:Huella', , ::Huella() ) )
    If .Not. Empty( ::cSignature )
        oXmlRegistroAlta:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:Signature', , ::Signature() ) )
    EndIf

Return oXmlRegistroFactura

/* ***************************************************************************** */
/* ***************************************************************************** */
/* ***************************************************************************** */

CLASS IDFacturaRectificada

    // Declaració de les DATA a on s'assignaran els valors a capturar.
    // Totes les DATA es gestionaran en modus caràcter o objectes XML.

    // Dades pel TAG IDFacturaRectificada
    DATA cIDEmisorFactura
    DATA cNumSerieFactura
    DATA cFechaExpedicionFactura


    // ACCESS a les DATA per tal de ser usades.
    // De momento se aplica la conversión a UTF8, excepto a las huellas.   
    ACCESS IDEmisorFactura                 INLINE ( hb_StrToUTF8( alltrim( ::cIDEmisorFactura ) ) )
    ACCESS NumSerieFactura                 INLINE ( hb_StrToUTF8( alltrim( ::cNumSerieFactura ) ) )
    ACCESS FechaExpedicionFactura          INLINE ( hb_StrToUTF8( alltrim( ::cFechaExpedicionFactura ) ) )


    // Métodes per gestionar la classe.

    METHOD New() CONSTRUCTOR
    METHOD ToXML()      //  Genera estructura XML con los datos.

ENDCLASS
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//

METHOD New( ) CLASS IDFacturaRectificada

Return ( self )

//---------------------------------------------------------------------------//

METHOD ToXML() CLASS IDFacturaRectificada

Local oXmlIDFacturaRectificada

    oXmlIDFacturaRectificada := TxmlNode():New( HBXML_TYPE_TAG, "sum1:IDFacturaRectificada" )

    oXmlIDFacturaRectificada:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IDEmisorFactura', , ::IDEmisorFactura() ) )
    oXmlIDFacturaRectificada:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NumSerieFactura', , ::NumSerieFactura() ) )
    oXmlIDFacturaRectificada:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:FechaExpedicionFactura', , ::FechaExpedicionFactura() ) )

Return oXmlIDFacturaRectificada

/* ***************************************************************************** */
/* ***************************************************************************** */
/* ***************************************************************************** */

CLASS IDFacturaSustituida

    // Declaració de les DATA a on s'assignaran els valors a capturar.
    // Totes les DATA es gestionaran en modus caràcter o objectes XML.

    // Dades pel TAG IDFacturaSustituida
    DATA cIDEmisorFactura
    DATA cNumSerieFactura
    DATA cFechaExpedicionFactura


    // ACCESS a les DATA per tal de ser usades.
    // De momento se aplica la conversión a UTF8, excepto a las huellas.
    ACCESS IDEmisorFactura                 INLINE ( hb_StrToUTF8( alltrim( ::cIDEmisorFactura ) ) )
    ACCESS NumSerieFactura                 INLINE ( hb_StrToUTF8( alltrim( ::cNumSerieFactura ) ) )
    ACCESS FechaExpedicionFactura          INLINE ( hb_StrToUTF8( alltrim( ::cFechaExpedicionFactura ) ) )


    // Métodes per gestionar la classe.

    METHOD New() CONSTRUCTOR
    METHOD ToXML()      //  Genera estructura XML con los datos.

ENDCLASS
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//

METHOD New( ) CLASS IDFacturaSustituida

Return ( self )

//---------------------------------------------------------------------------//

METHOD ToXML() CLASS IDFacturaSustituida

Local oXmlIDFacturaSustituida

    oXmlIDFacturaSustituida := TxmlNode():New( HBXML_TYPE_TAG, "sum1:IDFacturaSustituida" )

    oXmlIDFacturaSustituida:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IDEmisorFactura', , ::IDEmisorFactura() ) )
    oXmlIDFacturaSustituida:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NumSerieFactura', , ::NumSerieFactura() ) )
    oXmlIDFacturaSustituida:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:FechaExpedicionFactura', , ::FechaExpedicionFactura() ) )


Return oXmlIDFacturaSustituida

/* ***************************************************************************** */
/* ***************************************************************************** */
/* ***************************************************************************** */

CLASS IDDestinatario

    // Declaració de les DATA a on s'assignaran els valors a capturar.
    // Totes les DATA es gestionaran en modus caràcter o objectes XML.

    // Dades pel TAG IDDestinatario  -- >> Fins a 1000
    DATA cNombreRazon
    DATA cNIF
    DATA oXmlIDOtro
        // Dades pel TAG IDOtro
        DATA cCodigoPais
        DATA cIDType
        DATA cID

    // ACCESS a les DATA per tal de ser usades.
    // De momento se aplica la conversión a UTF8, excepto a las huellas.   
    ACCESS NombreRazon                      INLINE ( hb_StrToUTF8( alltrim( ::cNombreRazon ) ) )
    ACCESS NIF                              INLINE ( hb_StrToUTF8( alltrim( ::cNIF ) ) )
    ACCESS CodigoPais                       INLINE ( hb_StrToUTF8( alltrim( ::cCodigoPais ) ) )
    ACCESS IDType                           INLINE ( hb_StrToUTF8( alltrim( ::cIDType ) ) )
    ACCESS ID                               INLINE ( hb_StrToUTF8( alltrim( ::cID ) ) )


    // Métodes per gestionar la classe.

    METHOD New() CONSTRUCTOR
    METHOD ToXML()      //  Genera estructura XML con los datos.

ENDCLASS
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//

METHOD New( ) CLASS IDDestinatario

Return ( self )

//---------------------------------------------------------------------------//

METHOD ToXML() CLASS IDDestinatario

Local oXmlIDDestinatario
Local oXmlIDOtro

    oXmlIDDestinatario := TxmlNode():New( HBXML_TYPE_TAG, "sum1:IDDestinatario" )

    oXmlIDDestinatario:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NombreRazon', , ::NombreRazon() ) )
    If .Not. Empty( ::cNIF )
        oXmlIDDestinatario:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:NIF', , ::NIF() ) )
    EndIf

    If .Not. Empty( ::cIDType )
        oXmlIDOtro := TxmlNode():New( HBXML_TYPE_TAG, "sum1:IDOtro" )
        oXmlIDDestinatario:AddBelow( oXmlIDOtro )
        If .Not. Empty( ::cCodigoPais )
            oXmlIDOtro:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:CodigoPais', , ::CodigoPais() ) )
        EndIf
        oXmlIDOtro:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:IDType', , ::IDType() ) )
        oXmlIDOtro:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:ID', , ::ID() ) )
    EndIf

Return oXmlIDDestinatario

/* ***************************************************************************** */
/* ***************************************************************************** */
/* ***************************************************************************** */

CLASS DetalleDesglose

    // Declaració de les DATA a on s'assignaran els valors a capturar.
    // Totes les DATA es gestionaran en modus caràcter o objectes XML.

    // Dades pel TAG DetalleDesglose  -- >> Fins a 12
    DATA cImpuesto
    DATA cClaveRegimen
    DATA cCalificacionOperacion
    DATA cOperacionExenta
    DATA cTipoImpositivo
    DATA cBaseImponibleOimporteNoSujeto
    DATA cBaseImponibleACoste
    DATA cCuotaRepercutida
    DATA cTipoRecargoEquivalencia
    DATA cCuotaRecargoEquivalencia
   
   
    // ACCESS a les DATA per tal de ser usades.
    // De momento se aplica la conversión a UTF8, excepto a las huellas.   
    ACCESS Impuesto                              INLINE ( hb_StrToUTF8( alltrim( ::cImpuesto ) ) )
    ACCESS ClaveRegimen                          INLINE ( hb_StrToUTF8( alltrim( ::cClaveRegimen ) ) )
    ACCESS CalificacionOperacion                 INLINE ( hb_StrToUTF8( alltrim( ::cCalificacionOperacion ) ) )
    ACCESS OperacionExenta                       INLINE ( hb_StrToUTF8( alltrim( ::cOperacionExenta ) ) )
    ACCESS TipoImpositivo                        INLINE ( hb_StrToUTF8( alltrim( ::cTipoImpositivo ) ) )
    ACCESS BaseImponibleOimporteNoSujeto         INLINE ( hb_StrToUTF8( alltrim( ::cBaseImponibleOimporteNoSujeto ) ) )
    ACCESS BaseImponibleACoste                   INLINE ( hb_StrToUTF8( alltrim( ::cBaseImponibleACoste ) ) )
    ACCESS CuotaRepercutida                      INLINE ( hb_StrToUTF8( alltrim( ::cCuotaRepercutida ) ) )
    ACCESS TipoRecargoEquivalencia               INLINE ( hb_StrToUTF8( alltrim( ::cTipoRecargoEquivalencia ) ) )
    ACCESS CuotaRecargoEquivalencia              INLINE ( hb_StrToUTF8( alltrim( ::cCuotaRecargoEquivalencia ) ) )
   

    // Métodes per gestionar la classe.

    METHOD New() CONSTRUCTOR
    METHOD ToXML()      //  Genera estructura XML con los datos.

ENDCLASS
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//

METHOD New( ) CLASS DetalleDesglose

Return ( self )

//---------------------------------------------------------------------------//

METHOD ToXML() CLASS DetalleDesglose

Local oXmlDetalleDesglose

    oXmlDetalleDesglose := TxmlNode():New( HBXML_TYPE_TAG, "sum1:DetalleDesglose" )

    If .Not. Empty( ::cImpuesto )
        oXmlDetalleDesglose:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:Impuesto', , ::Impuesto() ) )
    EndIf

    If .Not. Empty( ::cClaveRegimen )
        oXmlDetalleDesglose:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:ClaveRegimen', , ::ClaveRegimen() ) )
    EndIf

    //If .Not. Empty( ::cCalificacionOperacion )
        oXmlDetalleDesglose:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:CalificacionOperacion', , ::CalificacionOperacion() ) )
    //EndIf
    If .Not. Empty( ::cOperacionExenta )
        oXmlDetalleDesglose:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:OperacionExenta', , ::OperacionExenta() ) )
    EndIf
    If .Not. Empty( ::cTipoImpositivo )
        oXmlDetalleDesglose:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:TipoImpositivo', , ::TipoImpositivo() ) )
    EndIf
    oXmlDetalleDesglose:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:BaseImponibleOimporteNoSujeto', , ::BaseImponibleOimporteNoSujeto() ) )
    If .Not. Empty( ::cBaseImponibleACoste )
        oXmlDetalleDesglose:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:BaseImponibleACoste', , ::BaseImponibleACoste() ) )
    EndIf
    If .Not. Empty( ::cCuotaRepercutida )
        oXmlDetalleDesglose:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:CuotaRepercutida', , ::CuotaRepercutida() ) )
    EndIf
    If .Not. Empty( ::cTipoRecargoEquivalencia )
        oXmlDetalleDesglose:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:TipoRecargoEquivalencia', , ::TipoRecargoEquivalencia() ) )
    EndIf
    If .Not. Empty( ::cCuotaRecargoEquivalencia )
        oXmlDetalleDesglose:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, 'sum1:CuotaRecargoEquivalencia', , ::CuotaRecargoEquivalencia() ) )
    EndIf

Return oXmlDetalleDesglose
//---------------------------------------------------------------------------//
//---------------------------------------------------------------------------//
 


Aquí PARTE del código de la función que yo utilizo para usar estas clases:

Básicamente se trata de iniciar la clase ( oXmlVerifactu := TVeriFactu00():New() ) para poder capturar los datos, y de un While - End para tratar los registros de las facturas.
Hay muchas funciones auxiliares que no adjunto, pero la idea se ve.
Code: Select all  Expand view  RUN

If lContinua

    oXmlVerifactu := TVeriFactu00():New()

    oXmlVerifactu:cObligadoEmision_NombreRazon := cGetNomampa( AMPAARRA )
    oXmlVerifactu:cObligadoEmision_NIF         := cGetNifBD( AMPAARRA )
    // oXmlVerifactu:cFechaFinVeriFactu           :=  No l'utilitzo  01/08/2024
    // oXmlVerifactu:cIncidencia                  := "T0"


    // oXmlVerifactu:cRefRequerimiento            := Aquí no.


    // Busco las facturas que deben incluirse en el XML
    While oTdbfVFRegi:Locate( , , lRestVfRegi) .and. .Not. oTdbfVFRegi:CheckEofBof( ):Eof

        lRestVfRegi := .T.

        // En teoria no es pot donar, doncs la condició de cerca demana que no estigui esborrat.
        If oTdbfVFRegi:Deleted(); Loop; EndIf
       
        oTdbfVFRegi:Load()

        // Cerco el registre anterior al que es gestiona, doncs calen dades de l'encadenament entre factures per a fer el XML.
        // -------------------------------------------------------------------------------------------------------------------
        oTdbfVFRegiDummy:Goto( oTdbfVFRegi:Recno() )
        oTdbfVFRegiDummy:Skip( -1 )
        While ( oTdbfVFRegiDummy:Deleted() ) .And. ;
              .Not. oTdbfVFRegiDummy:CheckEofBof( ):Bof
            oTdbfVFRegiDummy:Skip( -1 )
        End
       
        While ( oTdbfVFRegiDummy:Deleted() ) .And. ;
              .Not. oTdbfVFRegiDummy:CheckEofBof( ):Eof
            oTdbfVFRegiDummy:Skip( 1 )
        End

        nRecnoAnterior := oTdbfVFRegiDummy:Recno()

        Traza( 1, "oTdbfVFRegi:Recno()/nRecnoAnterior=", oTdbfVFRegi:Recno(), "/", nRecnoAnterior )

        If oTdbfVFRegiDummy:Recno() = oTdbfVFRegi:Recno()
            oTdbfVFRegiDummy:Blank()
            oTdbfFacAlbDummy:Blank()
            nRecnoAnterior := 0

          Else
            oTdbfVFRegiDummy:Load()
            nGotoFaAlVFCodFac( AMPAarra, oTDbfFacAlbDummy, oTdbfVFRegiDummy:VFCodFac, .T., .T., 1, Nil, Nil )
            nRecnoAnterior := oTdbfVFRegiDummy:Recno()

        EndIf
        // Fi localització del registre anterior.
        // --------------------------------------

        cNumSerieFacturaRegistroAnteriorDummy        := AllTrim( oTdbfVFRegiDummy:VFCodFac )
        cFechaExpedicionFacturaRegistroAnteriorDummy := hb_dtoc( oTdbfFacAlbDummy:DataFact, "dd-mm-yyyy" )
        cHuellaRegistroAnteriorDummy                 := AllTrim( oTdbfVFRegiDummy:VFHUELLA )

       
        If nGotoFaAlVFCodFac( AMPAarra, oTDbfFacAlb, oTdbfVFRegi:VFCodFac, .T., .T., 1, Nil, Nil ) = 0
            MsgAlert( GetTrad( "No s'ha trovat la FACTURA corresponent al registre VERIFACTU que es gestiona." ) + CRLF + CRLF + ;
                      GetTrad( "Es continua amb el següent registre." ), GetTrad( "Atenció!!!" ) + " -->> " + oTdbfVFRegi:VFCodFac )
          Else

            msgnowait( AMPAarra, GetTrad( "Factura: " ) + oTdbfVFRegi:VFCODFAC + "-" + AllTrim(oTdbfFacAlb:RAOSOC), GetTrad( "Generant XML per a Verifactu de les Factures emeses...") )

            Traza( 1, GetTrad( "Factura:" ) + Str( oTdbfFacAlb:NumeFact, 10, 0) + "-" + + DToc( oTdbfFacAlb:DataFact) + "-" + AllTrim(oTdbfFacAlb:RAOSOC) )

            oXMLRegistroFactura := RegistroFactura():New()

            lVFSetXMLRegistroFactura( AMPAARRA, ;
                                      oXMLRegistroFactura, ;
                                      oTdbfVFRegi, ;
                                      oTdbfVFRegiDummy, ;
                                      oTdbfFacAlb, ;
                                      oTdbfFacAlbDummy, ;
                                      oTDbfFactur, ;
                                      ;  // lPrimerTractament, ;
                                      nRecnoAnterior, ;
                                      ;   //   @cIdFacturAnterior, ;
                                      cNumSerieFacturaRegistroAnteriorDummy, ;
                                      cFechaExpedicionFacturaRegistroAnteriorDummy, ;
                                      cHuellaRegistroAnteriorDummy ;
                                    )


            oXmlVerifactu:AddFactura( oXMLRegistroFactura )

            nRegiVerFac++

            If nRegiVerFac = 1
                cNewVerFac( AMPAARRA, oTDbfVerFac, 10, 0 )
                cCodiVefa := oTDbfVerFac:CODIVEFA
            EndIf

            oTdbfVFRegi:CODIVEFA := oTDbfVerFac:CODIVEFA
            //oTdbfVFRegi:VFHuella := AllTrim( oXMLRegistroFactura:cHuella )
            oTdbfVFRegi:VF_ESTAT := nVF_ESTAT_XmlFet()

            oTdbfVFRegi:Save()

        EndIf

    End


    //Traza( 1, "c-nRecnoAnterior=", nRecnoAnterior )

    If nRegiVerFac > 0

        oXmlVerifactu:ToXML()

        oXmlVerifactu:GeneraXML( cVFFitxerPath( AMPAARRA, oTDbfVerFac:IDVERFAC ) )

        oTDbfVerFac:NUMEREGI := nRegiVerFac
        oTDbfVerFac:VF_ESTAT := nVF_ESTAT_XmlFet()
        oTDbfVerFac:Save()

        If lPregunta
            MsgInfo( GetTrad( "Generat el fitxer per a Verifactu:" ) + CRLF + CRLF + ;
                     cVFFitxerPath( AMPAARRA, oTDbfVerFac:IDVERFAC ) + CRLF + CRLF + ;
                     GetTrad( "Amb registres:" ) + Str( nRegiVerFac, 10, 0), ;
                     GetTrad( "Atenció!!!" ) )

            If MsgNoYes( GetTrad( "Vol VEURE el fitxer per a Verifactu:" ) + CRLF + CRLF + ;
                     cVFFitxerPath( AMPAARRA, oTDbfVerFac:IDVERFAC ) + CRLF + CRLF + ;
                     GetTrad( "Amb registres:" ) + Str( nRegiVerFac, 10, 0), ;
                     GetTrad( "Atenció!!!" ) )

                XBROWSER cVFFitxerPath( AMPAARRA, oTDbfVerFac:IDVERFAC )

            EndIf
   
        EndIf

      Else

        MsgStop( GetTrad( "No s'ha generat el fitxer; '0' registres." ), ;
                 GetTrad( "Atenció!!!" ) )

    EndIf
 
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1190
Joined: Mon Oct 10, 2005 2:38 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby FiveWiDi » Mon Nov 18, 2024 7:58 pm

Garbi,

Función que captura los datos de la factura que se gestiona en ese momento.
Esta función se usa dentro del While - End del post anterior.
Code: Select all  Expand view  RUN
// ***********************************************************************************
FUNCTION lVFSetXMLRegistroFactura( AMPAARRA, ;
                                   oXMLRegistroFactura, ;
                                   oTdbfVFRegi, ;
                                   oTdbfVFRegiDummy, ;
                                   oTdbfFacAlb, ;
                                   oTdbfFacAlbDummy, ;
                                   oTDbfFactur, ;
                                   ;  // lPrimerTractament, ;
                                   nRecnoAnterior, ;
                                   ;   // cIdFacturAnterior, ;
                                   cNumSerieFacturaRegistroAnteriorDummy, ;
                                   cFechaExpedicionFacturaRegistroAnteriorDummy, ;
                                   cHuellaRegistroAnteriorDummy ;
                                 )

// Seteja els valors de un objecte oXMLRegistroFactura.

Local lRespuesta          := .T.
Local oXmlIDDestinatario  := Nil
Local oXmlDetalleDesglose := Nil
Local aHuella             := {}

        oXMLRegistroFactura:cIDVersion                   := "1.0"

        oXMLRegistroFactura:cIDEmisorFactura                            := cGetNifBD( AMPAARRA )
        oXMLRegistroFactura:cNumSerieFactura                            := AllTrim( oTdbfVFRegi:VFCodFac ) // cGetSeriNumeFact( oTdbfFacAlb, Nil, Nil, Nil ) //  Str( Year( oTdbfFacAlb:DataFact), 4, 0) + "-000-" + Right( Str( 1000000 + oTdbfFacAlb:NumeFact, 10, 0), 6)
        oXMLRegistroFactura:cFechaExpedicionFactura                     := hb_dtoc( oTdbfFacAlb:DataFact, "dd-mm-yyyy" )     //  DToc( oTdbfFacAlb:DataFact )

        //oXMLRegistroFactura:cRefExterna                                 := ""

        oXMLRegistroFactura:cNombreRazonEmisor                          := cGetNomampa( AMPAARRA )
        //oXMLRegistroFactura:cTipoRegistroSIF                            := "S0"
        oXMLRegistroFactura:cTipoFactura                                := "F1"
        //oXMLRegistroFactura:cTipoRectificativa                          :=
        //oXMLRegistroFactura:cBaseRectificada                            :=
        //oXMLRegistroFactura:cCuotaRectificada                           :=
        //oXMLRegistroFactura:cCuotaRecargoRectificado                    :=
        //oXMLRegistroFactura:cFechaOperacion                             := hb_dtoc( oTdbfFacAlb:DataFact, "dd-mm-yyyy" )  //  DToc( oTdbfFacAlb:DataFact )   No cal al ser igual que la data d'expedició
        oXMLRegistroFactura:cDescripcionOperacion                       := "Prestación de servicios."
        oXMLRegistroFactura:cFacturaSimplificadaArt7273                 := "N"
        oXMLRegistroFactura:cFacturaSinIdentifDestinatarioArt61d        := "N"
        oXMLRegistroFactura:cMacrodato                                  := "N"
        //oXMLRegistroFactura:cEmitidaPorTercerosODestinatario            :=   No cal
        //oXMLRegistroFactura:cTercero_NombreRazon                        :=
        //oXMLRegistroFactura:cTercero_NIF                                :=
        //oXMLRegistroFactura:cTercero_IDOtro_CodigoPais                  :=
        //oXMLRegistroFactura:cTercero_IDOtro_IDType                      :=
        //oXMLRegistroFactura:cTercero_IDOtro_ID                          :=
       
        oXmlIDDestinatario := IDDestinatario():New()
        oXMLRegistroFactura:AddIDDestinatario( oXmlIDDestinatario )
        oXmlIDDestinatario:cNombreRazon                                      := oTdbfFacAlb:RAOSOC
        oXmlIDDestinatario:cNIF                                              := oTdbfFacAlb:NIF
        //oXmlIDDestinatario:cCodigoPais                                       :=
        //oXmlIDDestinatario:cIDType                                           :=
        //oXmlIDDestinatario:cID                                               :=

        oXMLRegistroFactura:cCupon                                      := "N"

        //Traza( 1, "oTdbfFacAlb:IdFactur=", oTdbfFacAlb:IdFactur )

        nGotoFacturIdFactur( AMPAarra, oTDbfFactur, AllTrim( oTdbfFacAlb:IdFactur ) + "-4", .T., .T., 1 )
        // IVA deduible
            oXmlDetalleDesglose := DetalleDesglose():New()
            oXMLRegistroFactura:AddaDetalleDesglose( oXmlDetalleDesglose )
            oXmlDetalleDesglose:cImpuesto                                       := "01"
            oXmlDetalleDesglose:cClaveRegimen                                   := "01"
            oXmlDetalleDesglose:cCalificacionOperacion                          := "S1"
            // oXmlDetalleDesglose:cOperacionExenta                                :=
            oXmlDetalleDesglose:cTipoImpositivo                                 := Alltrim( TransForm( oTDbfFactur:PERCENTA, "999.99" ) )
            oXmlDetalleDesglose:cBaseImponibleOimporteNoSujeto                  := Alltrim( TransForm( oTDbfFactur:BASECALC, "999999999999.99" ) )
            //oXmlDetalleDesglose:cBaseImponibleACoste                             :=
            oXmlDetalleDesglose:cCuotaRepercutida                                := Alltrim( TransForm( oTDbfFactur:IMPORT__, "999999999999.99" ) )
            //oXmlDetalleDesglose:cTipoRecargoEquivalencia                         :=
            //oXmlDetalleDesglose:cCuotaRecargoEquivalencia                        :=

        oXMLRegistroFactura:cCuotaTotal                                 := Alltrim( TransForm( oTDbfFactur:IMPORT__, "999999999999.99" ) )

        oXMLRegistroFactura:cImporteTotal                               := Alltrim( TransForm( oTDbfFacAlb:IMPOTOTA, "999999999999.99" ) )

        //nGotoFaAl( AMPAarra, oTDbfFacAlbDummy, oTDbfFacAlb:NumeFact, .T., .T., 1, Nil, Nil )

        /* Com que es poden tractar vàries factures per generar el XML, fins que no s'envia amb certesa
           els registres de oTDbfFacAlb no s'enregistren les Huella; per tant ha de ser en aquest bucle
           que es vagi 'traspassant' el valor de HuellaAnterior d'un registre al següent.
        */

        If nRecnoAnterior = 0
            // Es cerca a oTdbfFacAlb el registre que serà l'Anterior al tractat ara.
            //If cGetLastIdFactur( AMPAARRA, oTdbfFacAlbDummy ) = ""
                oXMLRegistroFactura:cPrimerRegistro                         := "S"
                oXMLRegistroFactura:cHuellaRegistroAnterior                 := ""
                //Traza( 1 , "cIdFacturAnterior= cGetLastIdFactur() no trovat",)
            /*  Else
                nRecnoAnterior    := oTdbfFacAlbDummy:Recno()
                cIdFacturAnterior := oTdbfFacAlbDummy:IdFactur
                //Traza( 1 , "cIdFacturAnterior=", cIdFacturAnterior)
                oXMLRegistroFactura:cIDEmisorFacturaRegistroAnterior        := cGetNifBD( AMPAARRA )
                oXMLRegistroFactura:cNumSerieFacturaRegistroAnterior        := Str( Year( oTdbfFacAlbDummy:DataFact), 4, 0) + "-000-" + Right( Str( 1000000 + oTdbfFacAlbDummy:NumeFact, 10, 0), 6)
                oXMLRegistroFactura:cFechaExpedicionFacturaRegistroAnterior := hb_dtoc( oTdbfFacAlbDummy:DataFact, "dd-mm-yyyy" )
                oXMLRegistroFactura:cHuellaRegistroAnterior                 := oTdbfFacAlbDummy:HuellaVF
            EndIf
            */


          Else
            // oXMLRegistroFactura:cPrimerRegistro  està buit.
            oXMLRegistroFactura:cIDEmisorFacturaRegistroAnterior        := cGetNifBD( AMPAARRA )
            oXMLRegistroFactura:cNumSerieFacturaRegistroAnterior        := oTdbfVFRegiDummy:VFCodFac     //  cNumSerieFacturaRegistroAnteriorDummy
            oXMLRegistroFactura:cFechaExpedicionFacturaRegistroAnterior := hb_dtoc( oTdbfFacAlbDummy:DataFact, "dd-mm-yyyy" )            //   cFechaExpedicionFacturaRegistroAnteriorDummy
            oXMLRegistroFactura:cHuellaRegistroAnterior                 := AllTrim( oTdbfVFRegiDummy:VFHUELLA )   //  cHuellaRegistroAnteriorDummy
        EndIf

        //Traza( 1, "a-nRecnoAnterior=", nRecnoAnterior )

        oXMLRegistroFactura:cSistemaInformatico_NombreRazon             := cVerifactuSINombreRazon( AMPAARRA )
        oXMLRegistroFactura:cSistemaInformatico_NIF                     := cVeriFactuSINif( AMPAARRA )
        //oXMLRegistroFactura:cSistemaInformatico_IDOtro_CodigoPais       :=
        //oXMLRegistroFactura:cSistemaInformatico_IDOtro_IDType           :=
        //oXMLRegistroFactura:cSistemaInformatico_IDOtro_ID               :=
        oXMLRegistroFactura:cNombreSistemaInformatico                   := cVeriFactuSINombreSistemaInformatico( AMPAARRA )
        oXMLRegistroFactura:cIdSistemaInformatico                       := cVeriFactuSIIdSistemaInformatico( AMPAARRA )
        oXMLRegistroFactura:cVersion                                    := cVeriFactuSIVersion( AMPAARRA )
        oXMLRegistroFactura:cNumeroInstalacion                          := cVeriFactuSINumeroInstalacion( AMPAARRA )
        oXMLRegistroFactura:cTipoUsoPosibleSoloVerifactu                := cVeriFactuSIPosibleSoloVerifactu( AMPAARRA )
        oXMLRegistroFactura:cTipoUsoPosibleMultiOT                      := cVeriFactuSITipoUsoPosibleMultiOT( AMPAARRA )
        oXMLRegistroFactura:cIndicadorMultiplesOT                       := cVeriFactuSIIndicadorMultiplesOT( AMPAARRA )

        //oXMLRegistroFactura:cNumeroOTAlta                               := "1"

        oXMLRegistroFactura:cFechaHoraHusoGenRegistro                   := FechaHoraHuso( oTdbfVFRegi:DataAlta, oTdbfVFRegi:HoraAlta )
       
        //oXMLRegistroFactura:cHoraGenRegistro                            := oTdbfFacAlb:HoraAlta
        //oXMLRegistroFactura:cHusoHorarioGenRegistro                     := "02"
       
       
       
        //oXMLRegistroFactura:cNumRegistroAcuerdoFacturacion              := De moment no.
        //oXMLRegistroFactura:cIdAcuerdoSistemaInformatico                := De moment no.

        oXMLRegistroFactura:cTipoHuella                                := "01"

        aHuella                                                        := hb_VerifactuHuella( cGetNifBD( AMPAARRA ), ;
                                                                                              AllTrim( oTdbfVFRegi:VFCodFac), ;
                                                                                              oTdbfFacAlb:DataFact, ;
                                                                                              "F1", ;
                                                                                              oTDbfFactur:IMPORT__, ;
                                                                                              oTDbfFacAlb:IMPOTOTA, ;
                                                                                              AllTrim( oXMLRegistroFactura:cHuellaRegistroAnterior ), ;
                                                                                              FechaHoraHuso( oTdbfVFRegi:DataAlta, oTdbfVFRegi:HoraAlta ) ;
                                                                                            )
        oTdbfVFRegi:VFCADHUE        := aHuella[1]
        oXMLRegistroFactura:cHuella := aHuella[2]
        oTdbfVFRegi:VFHuella := AllTrim( oXMLRegistroFactura:cHuella )
        oTdbfVFRegi:VFHueAnt := AllTrim( oXMLRegistroFactura:cHuellaRegistroAnterior )

        //oXMLRegistroFactura:cSignature                                 := No cal aquí

Return lRespuesta
// ***********************************************************************************
 


De momento sólo estoy/contemplo las facturas 'normales'.
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1190
Joined: Mon Oct 10, 2005 2:38 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby FiveWiDi » Mon Nov 18, 2024 8:01 pm

Esta otra es para cuando tengo un XML que no se ha podido enviar por motivos técnicos (falta de conexión internet por ejemplo), y debo enviarlo indicando que tuvo incidencia.

Es decir, tengo un XML ya creado al que sólo le falta enviarlo a Verifactu.

Code: Select all  Expand view  RUN
FUNCTION lVFInserIncidencXML( AMPAARRA, oTdbfVERFAC, cPathXML, lPregunta )

Local lContinua    := .T.
Local oTagCabecera := Nil
Local oTagRemisionVoluntaria := Nil
Local oTagRemisionVoluntariaIncidencia := Nil

Local oXmlDoc    := Nil
Local oXmlIter   := Nil
Local oTagActual := Nil
Local hDC := 0

If ( lContinua := File( cPathXML ) )

    oXmlDoc    := TXmlDocument():New( cPathXML )
    oXmlIter   := TXmlIterator():New( oXmlDoc:oRoot )

    While .T.
        oTagActual = oXmlIter:Next()
        If oTagActual != nil
            If oTagActual:cName = "sum:Cabecera"
                oTagCabecera := oTagActual
                //MsgInfo( oTagActual:cName, oTagActual:cData )
            ElseIf oTagActual:cName = "sum1:RemisionVoluntaria"
                oTagRemisionVoluntaria := oTagActual
                //MsgInfo( oTagActual:cName, oTagActual:cData )
                oTagActual = oXmlIter:Next()

                // Lo hago 2 veces por que sum1:RemisionVoluntaria puede tener 2 Tags 'colgando' de él.
                If oTagActual:cName = "sum1:Incidencia"
                    oTagRemisionVoluntariaIncidencia := oTagActual
                    //MsgInfo( oTagActual:cName, oTagActual:cData )
                    Exit
                EndIf
                oTagActual = oXmlIter:Next()
                If oTagActual:cName = "sum1:Incidencia"
                    oTagRemisionVoluntariaIncidencia := oTagActual
                    //MsgInfo( oTagActual:cName, oTagActual:cData )
                    Exit
                EndIf
            EndIf
          Else
            Exit
        Endif
    End

  Else

    If lPregunta
        MsgStop( GetTrad( "No existeix el fitxer XML a indicar 'Incidència'." ), GetTrad( "Atenció!!!" ) )
    EndIf

EndIf

If lContinua
    If oTagRemisionVoluntaria == Nil
        oTagRemisionVoluntaria := TxmlNode():New( HBXML_TYPE_TAG, "sum1:RemisionVoluntaria" )
        oTagRemisionVoluntaria:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, "sum1:Incidencia", , "S" ) )
        oTagCabecera:AddBelow( oTagRemisionVoluntaria )
      Else
        If oTagRemisionVoluntariaIncidencia == Nil
            oTagRemisionVoluntaria:AddBelow( TxmlNode():New( HBXML_TYPE_TAG, "sum1:Incidencia", , "S" ) )
          Else

            oTagRemisionVoluntariaIncidencia:cData := "S"

        EndIf
    EndIf

    hDC := fCreate( cPathXML )
   
    If Ferror() = 0

        oXmlDoc:Write( hDC, HBXML_STYLE_INDENT + HBXML_STYLE_THREESPACES )
        fClose( hDC )

      Else

        lContinua := .F.
        If lPregunta
            MsgStop( GetTrad( "Problemes a l'obrir el fitxer XML a indicar 'Incidència'." ), GetTrad( "Atenció!!!" ) )
        EndIf
   
    EndIf

EndIf

If lContinua
    oTdbfVERFAC:INCIDENC := "S"
    oTdbfVERFAC:Save()
EndIf

Return lContinua
// ***********************************************************************************
 
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1190
Joined: Mon Oct 10, 2005 2:38 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby paquitohm » Mon Nov 18, 2024 8:55 pm

Fivewidi,

Gracias por compartir tu codigo que seguro que lleva muchas horas detrás.
Ojalá cunda el ejemplo.
Cuatro empresas de desarrollo quedan, un puñado de desarrolladores independientes.
Tenemos que unirnos en la medida que podamos, si no queremos que nos coman los BIG

Salu2
paquitohm
 
Posts: 266
Joined: Fri Jan 14, 2022 8:37 am

Re: España: Normativa sancionadora sistemas informáticos

Postby Garbi » Tue Nov 19, 2024 9:14 am

Hola FiveWidi,

Como dice Paquito, muchas gracias por compartir el código.
Esta tarde-noche lo revisare porque ahora mismo estamos dando prioridad a ayudar a los afectados de la DANA para que puedan seguir trabajando y como dice Paquito tenemos que unirnos y ayudarnos para todo lo que se pueda.

La verdad es que esto va a ser una locura para todos los usuarios que tengan que implantarlo, es que hasta lo desconocen.
Last edited by Garbi on Tue Nov 19, 2024 9:17 am, edited 1 time in total.
Saludos,
Regards,

Jose Luis Alepuz
joseluis@mancomputer.com
www.mancomputer.com
Garbi
 
Posts: 341
Joined: Wed Nov 02, 2005 3:28 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby Verhoven » Tue Nov 19, 2024 9:16 am

Sanciones:
La siguiente es solo una de ellas, otra de entre muchas, es que por cada registro considerado por la AEAT que está mal también añaden entre 150€ y 300€ -repito, por cada registro-.

Tened también en cuenta que lo de verifactu es solo una parte de los requisitos que deben de cumplir los sistemas informáticos. La adaptación necesaria es mucho más extensa y engloba tanto al hardware como al software y al resto programas que sirven para conectar unos sistemas con otros; algunos de ellos son programas de terceros (por ejemplo CURL, openssl, etc...).
¿Quien se atreve a certificar todo ese software de terceros, necesario para que su sistema funcione?

Lean en detalle las nada más y nada menos que 41 páginas que componen las preguntas y respuestas frecuentes.

Code: Select all  Expand view  RUN
El artículo 201 bis de la Ley 58/2003, de 17 de diciembre, General Tributaria (LGT), prevé dos tipos de sanciones, ambas graves:
— A la fabricación, producción y comercialización de sistemas informáticos que no cumplan con lo dispuesto en el artículo 29.2.j) de la
LGT y su normativa de desarrollo (reglamento, orden ministerial y documentación relacionada de la sede electrónica de la Agencia
Tributaria).
La cuantía estipulada es de 150.000 euros fijos por cada ejercicio económico en el que se hayan producido ventas de este tipo de
sistemas informáticos y por cada tipo distinto de estos que sea objeto de la infracción.
— Por otro lado, cuando no se certifiquen dichos sistemas informáticos estando obligados a ello, se sancionará con 1.000 euros por
sistema informático comercializado sin dicha certificación.
— A la tenencia de sistemas informáticos que no se ajusten a lo establecido en el artículo 29.2.j) de la LGT, cuando los mismos no estén
debidamente certificados teniendo que estarlo por disposición reglamentaria o cuando se hayan alterado o modificado los dispositivos
certificados. El importe es de 50.000 euros por cada ejercicio.


Las cuestiones técnicas, no sin una titánica carga de trabajo, se podrán resolver. Pero hay que valorar la de las responsabilidades, porque además la norma no es clara, es muy interpretable y esto abre la puerta a sanciones enormes que son imposibles de asumir.

Si al cliente le imponen una multa por el software que usa y que os ha adquirido, él a su vez tiene la posibilidad de repercutírselo al productor del programa.

Sigo pensando que todo esto es para poner en manos de cuatro empresas grandes todo el sistema de facturación.
Verhoven
 
Posts: 522
Joined: Sun Oct 09, 2005 7:23 pm

Re: España: Normativa sancionadora sistemas informáticos

Postby Julio Cepeda » Tue Nov 19, 2024 5:19 pm

Ya me funciona y me devuelve lo mismo que el ejemplo de la AEAT.
He hecho alguna modificación y ya devuelve bien. De nuevo gracias Carlos.
Code: Select all  Expand view  RUN
Function Main()
 
 LOCAL cCadena

 local cNIF, ;
       cNumSerieFacturaEmisor, ;
       dFechaExpedicionFactura, ;
       cTipoFactura, ;
       nCuotaTotal, ;
       nImporteTotal, ;
       cHuellaRegistroAnterior, ;
       cFechaHoraHusoGenRegistro
 
   cNIF             := "IDEmisorFactura=" + "89890001K"
   cNumSerieFacturaEmisor   := "&NumSerieFactura=" + "12345678/G33"
   dFechaExpedicionFactura      := "&FechaExpedicionFactura=" + "01-01-2024"
   cTipoFactura         := "&TipoFactura=" + "F1"
   nCuotaTotal          := "&CuotaTotal=" + "12.35"
   nImporteTotal        := "&ImporteTotal=" + "123.45"
   cHuellaRegistroAnterior      := "&Huella=" + ""
   cFechaHoraHusoGenRegistro    := "&FechaHoraHusoGenRegistro=" + "2024-01-01T19:20:30+01:00"
 
 cCadena := hb_VerifactuHuella( cNIF, ;
                                cNumSerieFacturaEmisor, ;
                            dFechaExpedicionFactura, ;
                            cTipoFactura, ;
                            nCuotaTotal, ;
                            nImporteTotal, ;
                            cHuellaRegistroAnterior, ;
                            cFechaHoraHusoGenRegistro )
                           
 MsgInfo( cCadena, "cCadena devuelta" )

 Return NIL

 Function hb_VerifactuHuella( cNIF, ;
                              cNumSerieFacturaEmisor, ;
                              dFechaExpedicionFactura, ;
                              cTipoFactura, ;
                              nCuotaTotal, ;
                              nImporteTotal, ;
                              cHuellaRegistroAnterior, ;
                              cFechaHoraHusoGenRegistro )

 local c := ""
 local h := {=>}
 Local cHuella := ""

 h['Nif']                      := cNIF
 h['NumSerieFacturaEmisor']    := cNumSerieFacturaEmisor
 h['FechaExpedicionFactura']   := dFechaExpedicionFactura
 h['TipoFactura']              := cTipoFactura
 h['CuotaTotal']               := nCuotaTotal
 h['ImporteTotal']             := nImporteTotal
 h['HuellaRegistroAnterior']   := cHuellaRegistroAnterior
 h['FechaHoraHusoGenRegistro'] := cFechaHoraHusoGenRegistro

 hb_heval( h, {|k,v,i| c += v} )        //    | key, value, index |

 c := hb_StrToUTF8( c )     // Si se quita no varía resultado.

 cHuella := ( hb_sha256( c ) )

 cHuella := Upper( cHuella )

 Return ( cHuella )
 
Ahora veré cómo pasar los campos de la factura.
Saludos

julio@cepedaserinf.es
FiveWin 22.12 + Harbour 3.2.0dev (r2008190002), BCC 7 Windows 11
User avatar
Julio Cepeda
 
Posts: 65
Joined: Wed Oct 12, 2005 6:58 pm

PreviousNext

Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 35 guests