Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Envío de registros y sus respuestas (https://www.clubdelphi.com/foros/forumdisplay.php?f=66)
-   -   Demo con código Verifactu.dll para (delphi 7) (https://www.clubdelphi.com/foros/showthread.php?t=97004)

newtron 10-02-2025 20:03:06

Cita:

Empezado por ramherfer (Mensaje 561914)
Hola buenas tardes.
A ver si alguien me puede dar un empujoncito con respecto a la anulación.
Tenemos el siguiente planteamiento:

Oper. NumFra Fecha Fra
ALTA F240001 21/01/2024
ALTA F240002 22/01/2024
BAJA F240001 21/01/2024
ALTA F240003 22/01/2024
ALTA F240004 22/01/2024
ALTA F240005 22/01/2024
ALTA F240006 22/01/2024

En la hoja excel lo tengo claro y lo veo y sin ningún problema. pero me lleva loco el tema de la anulación y ostras, no soy capaz de encaminarlo. Como orientais el asunto en la base de datos si la tabla tiene como índice principal NumFra y tenemos ya el registro de alta con el número F240001. Sería sencillo y básico botón derecho en el alta correspondiente y opción anual factura, automáticamente se duplica el registro con la operación de baja y su fecha, pero no llego ni a probarlo ya que automáticamente me daría registros duplicados en la tabla de cabecera de facturas.

Si alguno me diera una pista de como orientar el tema se lo agradecería. No pensaba utilizar el tema de anulación, pero creo que se va a dar el caso en más de una vez y me gustaría tenerlo previsto.

Disculpar mi torpeza.
Un saludo,


No sé cómo piensas orientar el tema de las bajas pero yo lo veo peliagudo. Primero te crea problemas para manejar ese dato en la misma tabla de facturas (como ya estás comprobando) y segundo que no creo que sea muy recomendable anular facturas.


Si te sirve de algo yo he optado por no dejar anular facturas y en cambio generar facturas rectificativas. A partir de una factura determinada que se quiera modificar por algún motivo creo en memoria una copia para hacer los cambios que se quieran y si se aceptan muevo la factura original a otra tabla y se queda la rectificada con un nuevo número de otra serie. Si lo que se quiere es directamente eliminar la factura lo que hago es un abono. Este proceso, como tantas cosas, es discutible pero creo que es legal y no me marea mucho el programa.


Saludos.

ramherfer 10-02-2025 20:05:52

Esto es como todo, en enviar pregunta y se aparece la iluminación divina....

Tratar el indice principal con un autoincrement y un secundario mantenido con número de factura. Pasa que no soy muy amigo de los autoincrement, pero como no afecta a los datos, me daría igual que este variara en cualquier momento y por cualquier motivo.
El problema es que no se a nivel de aplicación como me afectaría, en la busqueda de facturas.

J...r estoy encasquillado con el tema.

ramherfer 10-02-2025 20:13:00

Cita:

Empezado por newtron (Mensaje 561918)
No sé cómo piensas orientar el tema de las bajas pero yo lo veo peliagudo. Primero te crea problemas para manejar ese dato en la misma tabla de facturas (como ya estás comprobando) y segundo que no creo que sea muy recomendable anular facturas.


Si te sirve de algo yo he optado por no dejar anular facturas y en cambio generar facturas rectificativas. A partir de una factura determinada que se quiera modificar por algún motivo creo en memoria una copia para hacer los cambios que se quieran y si se aceptan muevo la factura original a otra tabla y se queda la rectificada con un nuevo número de otra serie. Si lo que se quiere es directamente eliminar la factura lo que hago es un abono. Este proceso, como tantas cosas, es discutible pero creo que es legal y no me marea mucho el programa.


Saludos.

Pues mira creo que tienes razón newtron, yo opté por esa opción en un principio, pero al verlo tan sencillo para el usuario, anular y volver a enviar un nuevo alta, "el empecinamiento creo que es mi mayor enemigo" y no me deja ver con claridad. Y creo que así se va a quedar, error -> abono y vuelta a empezar, que se fijen antes de facturar y ya vendrán mejores tiempos, e un mondo difichile!!, que nuestro trabajo no está pagado.

Gracias Darkdudae y Newtron por los aportes.

Neftali [Germán.Estévez] 11-02-2025 08:58:25

Cita:

Empezado por ramherfer (Mensaje 561914)
En la hoja excel lo tengo claro y lo veo y sin ningún problema. pero me lleva loco el tema de la anulación y ostras, no soy capaz de encaminarlo. Como orientais el asunto en la base de datos si la tabla tiene como índice principal NumFra y tenemos ya el registro de alta con el número F240001. Sería sencillo y básico botón derecho en el alta correspondiente y opción anual factura, automáticamente se duplica el registro con la operación de baja y su fecha, pero no llego ni a probarlo ya que automáticamente me daría registros duplicados en la tabla de cabecera de facturas.


Nosotros tenemos en la tabla de facturas un campo de ESTADO, que en un momento dado nos marca si la factura está ANULADA (y otros estados por los que puede pasar).
Por otro lado, tenemos una tabla de RegistrosDeFacturación, donde se almacena un registro por cada operación que se le realiza a una factura, y por lo tanto podemos tener varios registros (sobre la misma factura):

ALTA
MODIFICACION
MODIFICACION
ANULACION

Además, esa segunda tabla se puede consultar, para acceder rápidamente al "historial" de una factura y debe permitir descargar el RegistroDeFacturación de cada factura.


seccion_31 11-02-2025 13:48:53

Vamos a ver si entendi lo de las bajas, como creo que lo he entendido siempre. bajo la experiencia del SII

Las bajas son una factura mas para la AEAT, tiene su huella: la que tuvo durante el alta y encadenamiento.

Cuando das de alta una nueva siguiente a la baja la encadenas con ella y listo.

El lugar de la baja no se puede ocupar porque dara error 3000.

¿esto es asi? lo unico que tienes que marcar es un flag en el archivo de facturas que te indique cual es su estado, sin mas.

Saludos

Nota: gracias a la demo de darkdudae, el componente con total seguridad abandonara el servidor de mensajes, y pasara a funcionar bajo DLL. No hay que modificar nada en el código de los programas que usan el componente. La semana que viene lo publicare.

ramherfer 11-02-2025 14:34:52

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 561925)
Por otro lado, tenemos una tabla de RegistrosDeFacturación, donde se almacena un registro por cada operación que se le realiza a una factura, y por lo tanto podemos tener varios registros (sobre la misma factura):

Además, esa segunda tabla se puede consultar, para acceder rápidamente al "historial" de una factura y debe permitir descargar el RegistroDeFacturación de cada factura.


Hola Germán. Esa segunda tabla podría tener esta estructura, partiendo los envios desde la misma

Código:

Id        N.Factura        Fec.Factura  Operacion        Notificada
1        FR250001        02/06/2025        A                  S
2        FR250002        02/07/2025        A                  S
3        FR250003        02/07/2025        A                  S
4        FR250003        02/07/2025        M                  S
5        FR250004        02/10/2025        A                  S                    Encadenada a la 3
6        FR250001        02/06/2025        B                  S                    Encadenada a la 4???
7        FR250005        02/11/2025        A                  S                    Encadenada a la 1???
8        FR250006        02/11/2025        A                  S                    Encadenada a la 6


Cita:

debe permitir descargar el RegistroDeFacturación de cada factura.
Esto me ha dejado muerto...
Gracias.

Neftali [Germán.Estévez] 11-02-2025 15:35:37

Cita:

Empezado por ramherfer (Mensaje 561933)
Hola Germán. Esa segunda tabla podría tener esta estructura, partiendo los envios desde la misma
...

Similar a la que tengo yo, aunque en la mía hay más campos.
Por ejemplo, en cada registro de facturación tengo el HASH, tengo el contenido del registro en formato XML,...

En esa tabla me lía un poco las fechas que has puesto.
En cuanto al encadenamiento, se va haciendo con el último RegistroDeFacturación generado, digamos de forma conológica (independientemente si lo último ha sido un alta, una subsanación o una anulación).


Cita:

Empezado por ramherfer (Mensaje 561933)
debe permitir descargar el RegistroDeFacturación de cada factura.

Digamos que tenemos una pantalla que muestra todos los registros de facturación dedicada a posibles inspecciones. Desde esa pantalla puedes buscar una fcatura y deberías ver su "historial" y su estado actual (todas sus operacion o registros de facturación); La mayoría aparecerán 1 vez como Alta aceptada, pero también podrás encontrar un Alta + Baja o Alta + Modificacion + Modificación + Baja,...

Y tal como pone la documentación se debe poder ver o descargar el registro de facturación (XML), por eso lo guardamos tal cual en un campo.

DarkDudae 11-02-2025 16:11:50

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 561936)
Y tal como pone la documentación se debe poder ver o descargar el registro de facturación (XML), por eso lo guardamos tal cual en un campo.

Con el “registro de facturación” en XML te refieres a la respuesta que devuelve Hacienda o a una suerte de “Factura Electrónica” con los metadatos de la factura?

CarlosArjonomia 12-02-2025 09:50:01

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 561936)
Similar a la que tengo yo, aunque en la mía hay más campos.
Por ejemplo, en cada registro de facturación tengo el HASH, tengo el contenido del registro en formato XML,...

En esa tabla me lía un poco las fechas que has puesto.
En cuanto al encadenamiento, se va haciendo con el último RegistroDeFacturación generado, digamos de forma conológica (independientemente si lo último ha sido un alta, una subsanación o una anulación).



Digamos que tenemos una pantalla que muestra todos los registros de facturación dedicada a posibles inspecciones. Desde esa pantalla puedes buscar una fcatura y deberías ver su "historial" y su estado actual (todas sus operacion o registros de facturación); La mayoría aparecerán 1 vez como Alta aceptada, pero también podrás encontrar un Alta + Baja o Alta + Modificacion + Modificación + Baja,...

Y tal como pone la documentación se debe poder ver o descargar el registro de facturación (XML), por eso lo guardamos tal cual en un campo.

No se si me he perdido algo, pero si le meto una huella incorrecta en el encadenamiento del registro anterior se lo traga sin error. ¿Es esto normal?.

Neftali [Germán.Estévez] 12-02-2025 15:17:32

Cita:

Empezado por DarkDudae (Mensaje 561939)
Con el “registro de facturación” en XML te refieres a la respuesta que devuelve Hacienda o a una suerte de “Factura Electrónica” con los metadatos de la factura?

El registro de facturación es el fichero XML que debemos generar para cada factura (en realidad uno para cada alta, modificación o anulación). Si estamos en Verifactu, ese fichero/XML se envía, si estamos en NO-Verifactu, ese XML se firma y se guarda.
En cualquier momento esos XML se deen poder acceder y descargar.

https://sede.agenciatributaria.gob.e...generales.html

seccion_31 12-02-2025 17:48:08

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 561986)
El registro de facturación es el fichero XML que debemos generar para cada factura (en realidad uno para cada alta, modificación o anulación). Si estamos en Verifactu, ese fichero/XML se envía, si estamos en NO-Verifactu, ese XML se firma y se guarda.
En cualquier momento esos XML se deen poder acceder y descargar.

https://sede.agenciatributaria.gob.e...generales.html

bueno en el caso de verifactu en ese xml de envio no ira solamente 1 factura, pueden ir docenas.

Pienso que lo ideal a parte de quizas guardarlo en disco en una carpeta, con un nombre serializado, seria incluirlo en una tabla con un codigo y desde la factura(s) enlazarlo, con dos campos binarios, uno para el envio y otro la respuesta.

Saludos !

DarkDudae 12-02-2025 18:53:07

Cita:

Empezado por seccion_31 (Mensaje 561992)
bueno en el caso de verifactu en ese xml de envio no ira solamente 1 factura, pueden ir docenas.

Pienso que lo ideal a parte de quizas guardarlo en disco en una carpeta, con un nombre serializado, seria incluirlo en una tabla con un codigo y desde la factura(s) enlazarlo, con dos campos binarios, uno para el envio y otro la respuesta.

Saludos !

Es justo como lo estoy planteando yo en mi sistema.

Tengo una tabla llamada: verifactu_logcomunicaciones con la siguiente estructura:

Código:

ID (Autonumérico Entero)
FechaHora (TIMESTAMP)
XMLEnvio (BLOB comprimido con COMPRESS de MySQL)
XMLRespuesta (BLOB comprimido con COMPRESS de MySQL)
CSVRespuesta (VARCHAR)

Como al hacer un envío nos devuelve un CSV, y este CSV yo lo guardo en la tabla verifactu_registrofacturas cuando hago un envío, pues simplemente relaciono esos dos campos y ya tengo el XML de envío y de recepción de cada una de las facturas a nivel individual y/o colectivo.

bmfranky 12-02-2025 20:58:21

Cita:

Empezado por seccion_31 (Mensaje 561992)
bueno en el caso de verifactu en ese xml de envio no ira solamente 1 factura, pueden ir docenas.

Pienso que lo ideal a parte de quizas guardarlo en disco en una carpeta, con un nombre serializado, seria incluirlo en una tabla con un codigo y desde la factura(s) enlazarlo, con dos campos binarios, uno para el envio y otro la respuesta.

Saludos !

Hola, pero puedes perfectamente guardar solo el XML de la factura, no hace faltya que sea del envio completo, es mas lo que se guarda en el no verifactu es exactamente eso , solo el nodo RegistroAlta, por ejemplo.
Código:

<sum1:RegistroAlta xmlns:sum1="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
    <sum1:IDVersion>1.0</sum1:IDVersion>
    <sum1:IDFactura>
        <sum1:IDEmisorFactura>89890001K</sum1:IDEmisorFactura>
        <sum1:NumSerieFactura>12345678-G66</sum1:NumSerieFactura>
        <sum1:FechaExpedicionFactura>03-02-2025</sum1:FechaExpedicionFactura>
    </sum1:IDFactura>
    <sum1:NombreRazonEmisor>certificado uno telematicas</sum1:NombreRazonEmisor>
    <sum1:Subsanacion>N</sum1:Subsanacion>
    <sum1:RechazoPrevio>N</sum1:RechazoPrevio>
    <sum1:TipoFactura>R3</sum1:TipoFactura>
    <sum1:TipoRectificativa>I</sum1:TipoRectificativa>
    <sum1:FacturasRectificadas>
        <sum1:IDFacturaRectificada>
            <sum1:IDEmisorFactura>89890001K</sum1:IDEmisorFactura>
            <sum1:NumSerieFactura>12345600-G66</sum1:NumSerieFactura>
            <sum1:FechaExpedicionFactura>01-04-2024</sum1:FechaExpedicionFactura>
        </sum1:IDFacturaRectificada>
    </sum1:FacturasRectificadas>
    <sum1:FechaOperacion>03-02-2025</sum1:FechaOperacion>
    <sum1:DescripcionOperacion>fecha entrega</sum1:DescripcionOperacion>
    <sum1:Destinatarios>
        <sum1:IDDestinatario>
            <sum1:NombreRazon>certificado dos telematicas</sum1:NombreRazon>
            <sum1:NIF>89890002E</sum1:NIF>
        </sum1:IDDestinatario>
    </sum1:Destinatarios>
    <sum1:Desglose>
        <sum1:DetalleDesglose>
            <sum1:ClaveRegimen>01</sum1:ClaveRegimen>
            <sum1:CalificacionOperacion>S1</sum1:CalificacionOperacion>
            <sum1:TipoImpositivo>4</sum1:TipoImpositivo>
            <sum1:BaseImponibleOimporteNoSujeto>10</sum1:BaseImponibleOimporteNoSujeto>
            <sum1:CuotaRepercutida>0.4</sum1:CuotaRepercutida>
        </sum1:DetalleDesglose>
        <sum1:DetalleDesglose>
            <sum1:ClaveRegimen>01</sum1:ClaveRegimen>
            <sum1:CalificacionOperacion>S1</sum1:CalificacionOperacion>
            <sum1:TipoImpositivo>21</sum1:TipoImpositivo>
            <sum1:BaseImponibleOimporteNoSujeto>100</sum1:BaseImponibleOimporteNoSujeto>
            <sum1:CuotaRepercutida>21</sum1:CuotaRepercutida>
        </sum1:DetalleDesglose>
        <sum1:DetalleDesglose>
            <sum1:ClaveRegimen>05</sum1:ClaveRegimen>
            <sum1:CalificacionOperacion>S1</sum1:CalificacionOperacion>
            <sum1:TipoImpositivo>10</sum1:TipoImpositivo>
            <sum1:BaseImponibleOimporteNoSujeto>100</sum1:BaseImponibleOimporteNoSujeto>
            <sum1:CuotaRepercutida>10</sum1:CuotaRepercutida>
        </sum1:DetalleDesglose>
    </sum1:Desglose>
    <sum1:CuotaTotal>41.4</sum1:CuotaTotal>
    <sum1:ImporteTotal>241.4</sum1:ImporteTotal>
    <sum1:Encadenamiento>
        <sum1:RegistroAnterior>
            <sum1:IDEmisorFactura>89890001K</sum1:IDEmisorFactura>
            <sum1:NumSerieFactura>12345677-G33</sum1:NumSerieFactura>
            <sum1:FechaExpedicionFactura>15-04-2024</sum1:FechaExpedicionFactura>
            <sum1:Huella>C9AF4AF1EF5EBBA700350DE3EEF12C2D355C56AC56F13DB2A25E0031BD2B7ED5</sum1:Huella>
        </sum1:RegistroAnterior>
    </sum1:Encadenamiento>
    <sum1:SistemaInformatico>
        <sum1:NombreRazon>CERTIFICADO UNO TELEMATICAS</sum1:NombreRazon>
        <sum1:NIF>89890001K</sum1:NIF>
        <sum1:NombreSistemaInformatico>NombreSistemaInformatico</sum1:NombreSistemaInformatico>
        <sum1:IdSistemaInformatico>77</sum1:IdSistemaInformatico>
        <sum1:Version>1.0.03</sum1:Version>
        <sum1:NumeroInstalacion>383</sum1:NumeroInstalacion>
        <sum1:TipoUsoPosibleSoloVerifactu>S</sum1:TipoUsoPosibleSoloVerifactu>
        <sum1:TipoUsoPosibleMultiOT>N</sum1:TipoUsoPosibleMultiOT>
        <sum1:IndicadorMultiplesOT>N</sum1:IndicadorMultiplesOT>
    </sum1:SistemaInformatico>
    <sum1:FechaHoraHusoGenRegistro>2025-02-03T14:30:00+01:00</sum1:FechaHoraHusoGenRegistro>
    <sum1:TipoHuella>01</sum1:TipoHuella>
    <sum1:Huella>FF954378B64ED331A9B2366AD317D86E9DEC1716B12DD0ACCB172A6DC4C105AA</sum1:Huella>



Este es el ejemplo de la aeat.


Y de la respuesta lo mismo , puedes deserializar los nodosde la respuesta por separado y almacenar solo el resultado de ese nodo en particular.
Seleccionas el nodo correspondiente a tu factura.
Código:

<RespuestaLinea>
<IDFactura>
<IDEmisorFactura>89890001K</IDEmisorFactura>
<NumSerieFactura>12345677-G33</NumSerieFactura>
<FechaExpedicionFactura>15-04-2024</FechaExpedicionFactura>
</IDFactura>
<EstadoRegistro>AceptadoConErrores</EstadoRegistro>
<CodigoErrorRegistro>2004</CodigoErrorRegistro>
<DescripcionErrorRegistro>El valor del campo FechaHoraHusoGenRegistro debe ser la fecha actual del sistema de la AEAT, admitiéndose un margen de error de: 120 segundos.</DescripcionErrorRegistro>
</RespuestaLinea>


seccion_31 13-02-2025 06:57:39

Cita:

Empezado por bmfranky (Mensaje 562000)
Hola, pero puedes perfectamente guardar solo el XML de la factura, no hace faltya que sea del envio completo, es mas lo que se guarda en el no verifactu es exactamente eso , solo el nodo RegistroAlta, por ejemplo.
Código:

<sum1:RegistroAlta xmlns:sum1="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
    <sum1:IDVersion>1.0</sum1:IDVersion>
    <sum1:IDFactura>
        <sum1:IDEmisorFactura>89890001K</sum1:IDEmisorFactura>
        <sum1:NumSerieFactura>12345678-G66</sum1:NumSerieFactura>
        <sum1:FechaExpedicionFactura>03-02-2025</sum1:FechaExpedicionFactura>
    </sum1:IDFactura>
    <sum1:NombreRazonEmisor>certificado uno telematicas</sum1:NombreRazonEmisor>
    <sum1:Subsanacion>N</sum1:Subsanacion>
    <sum1:RechazoPrevio>N</sum1:RechazoPrevio>
    <sum1:TipoFactura>R3</sum1:TipoFactura>
    <sum1:TipoRectificativa>I</sum1:TipoRectificativa>
    <sum1:FacturasRectificadas>
        <sum1:IDFacturaRectificada>
            <sum1:IDEmisorFactura>89890001K</sum1:IDEmisorFactura>
            <sum1:NumSerieFactura>12345600-G66</sum1:NumSerieFactura>
            <sum1:FechaExpedicionFactura>01-04-2024</sum1:FechaExpedicionFactura>
        </sum1:IDFacturaRectificada>
    </sum1:FacturasRectificadas>
    <sum1:FechaOperacion>03-02-2025</sum1:FechaOperacion>
    <sum1:DescripcionOperacion>fecha entrega</sum1:DescripcionOperacion>
    <sum1:Destinatarios>
        <sum1:IDDestinatario>
            <sum1:NombreRazon>certificado dos telematicas</sum1:NombreRazon>
            <sum1:NIF>89890002E</sum1:NIF>
        </sum1:IDDestinatario>
    </sum1:Destinatarios>
    <sum1:Desglose>
        <sum1:DetalleDesglose>
            <sum1:ClaveRegimen>01</sum1:ClaveRegimen>
            <sum1:CalificacionOperacion>S1</sum1:CalificacionOperacion>
            <sum1:TipoImpositivo>4</sum1:TipoImpositivo>
            <sum1:BaseImponibleOimporteNoSujeto>10</sum1:BaseImponibleOimporteNoSujeto>
            <sum1:CuotaRepercutida>0.4</sum1:CuotaRepercutida>
        </sum1:DetalleDesglose>
        <sum1:DetalleDesglose>
            <sum1:ClaveRegimen>01</sum1:ClaveRegimen>
            <sum1:CalificacionOperacion>S1</sum1:CalificacionOperacion>
            <sum1:TipoImpositivo>21</sum1:TipoImpositivo>
            <sum1:BaseImponibleOimporteNoSujeto>100</sum1:BaseImponibleOimporteNoSujeto>
            <sum1:CuotaRepercutida>21</sum1:CuotaRepercutida>
        </sum1:DetalleDesglose>
        <sum1:DetalleDesglose>
            <sum1:ClaveRegimen>05</sum1:ClaveRegimen>
            <sum1:CalificacionOperacion>S1</sum1:CalificacionOperacion>
            <sum1:TipoImpositivo>10</sum1:TipoImpositivo>
            <sum1:BaseImponibleOimporteNoSujeto>100</sum1:BaseImponibleOimporteNoSujeto>
            <sum1:CuotaRepercutida>10</sum1:CuotaRepercutida>
        </sum1:DetalleDesglose>
    </sum1:Desglose>
    <sum1:CuotaTotal>41.4</sum1:CuotaTotal>
    <sum1:ImporteTotal>241.4</sum1:ImporteTotal>
    <sum1:Encadenamiento>
        <sum1:RegistroAnterior>
            <sum1:IDEmisorFactura>89890001K</sum1:IDEmisorFactura>
            <sum1:NumSerieFactura>12345677-G33</sum1:NumSerieFactura>
            <sum1:FechaExpedicionFactura>15-04-2024</sum1:FechaExpedicionFactura>
            <sum1:Huella>C9AF4AF1EF5EBBA700350DE3EEF12C2D355C56AC56F13DB2A25E0031BD2B7ED5</sum1:Huella>
        </sum1:RegistroAnterior>
    </sum1:Encadenamiento>
    <sum1:SistemaInformatico>
        <sum1:NombreRazon>CERTIFICADO UNO TELEMATICAS</sum1:NombreRazon>
        <sum1:NIF>89890001K</sum1:NIF>
        <sum1:NombreSistemaInformatico>NombreSistemaInformatico</sum1:NombreSistemaInformatico>
        <sum1:IdSistemaInformatico>77</sum1:IdSistemaInformatico>
        <sum1:Version>1.0.03</sum1:Version>
        <sum1:NumeroInstalacion>383</sum1:NumeroInstalacion>
        <sum1:TipoUsoPosibleSoloVerifactu>S</sum1:TipoUsoPosibleSoloVerifactu>
        <sum1:TipoUsoPosibleMultiOT>N</sum1:TipoUsoPosibleMultiOT>
        <sum1:IndicadorMultiplesOT>N</sum1:IndicadorMultiplesOT>
    </sum1:SistemaInformatico>
    <sum1:FechaHoraHusoGenRegistro>2025-02-03T14:30:00+01:00</sum1:FechaHoraHusoGenRegistro>
    <sum1:TipoHuella>01</sum1:TipoHuella>
    <sum1:Huella>FF954378B64ED331A9B2366AD317D86E9DEC1716B12DD0ACCB172A6DC4C105AA</sum1:Huella>



Este es el ejemplo de la aeat.


Y de la respuesta lo mismo , puedes deserializar los nodosde la respuesta por separado y almacenar solo el resultado de ese nodo en particular.
Seleccionas el nodo correspondiente a tu factura.
Código:

<RespuestaLinea>
<IDFactura>
<IDEmisorFactura>89890001K</IDEmisorFactura>
<NumSerieFactura>12345677-G33</NumSerieFactura>
<FechaExpedicionFactura>15-04-2024</FechaExpedicionFactura>
</IDFactura>
<EstadoRegistro>AceptadoConErrores</EstadoRegistro>
<CodigoErrorRegistro>2004</CodigoErrorRegistro>
<DescripcionErrorRegistro>El valor del campo FechaHoraHusoGenRegistro debe ser la fecha actual del sistema de la AEAT, admitiéndose un margen de error de: 120 segundos.</DescripcionErrorRegistro>
</RespuestaLinea>


Buenos dias,

Tecnicamente me gusta la idea, si x favor, me cedes el código para hacerlo lo incluyo en el componente, y que el usuario seleccione lo que desea archivar.

El componente ya no necesita de una aplicacion servidora, funciona bajo DLL, e incorpora bastantes cambios, incluyendo una demo muy mejorada. El fin de semana lo publicare. Las aplicaciones ya desarrolladas usandolo no van a necesitar cambio alguno.

Saludos !

Neftali [Germán.Estévez] 13-02-2025 09:24:07

Cita:

Empezado por seccion_31 (Mensaje 561992)
bueno en el caso de verifactu en ese xml de envio no ira solamente 1 factura, pueden ir docenas.


Ojo que son cosas diferentes.
RegistroDeFacturación: Nos referimos a la información referente a 1 factura (en formato XML), que va firmada o no dependiendo si estamos en Verifactu o no-verifactu.
Otra cosa es el envío (sólo en la modalidad verifactu). en el envío cómo han dicho pueden ir 1..1000 registros de facturación incluídos.

El RegistrodeFacturación es el que hay que guardar de forma obligatoria y debe ser accesible y descargable.

La información del envío, no es obligatorio guardarla, y cada uno puede decidir cómo y qué guardar (para luego gestionar toda esa lógica desde el programa). Si guardar todo el paquete (con las 1000 fcaturas), si guardar la respuesta en el formato que la da la AEAT, si guardar sólo los códigos,...

seccion_31 13-02-2025 09:48:14

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 562006)
Ojo que son cosas diferentes.
RegistroDeFacturación: Nos referimos a la información referente a 1 factura (en formato XML), que va firmada o no dependiendo si estamos en Verifactu o no-verifactu.
Otra cosa es el envío (sólo en la modalidad verifactu). en el envío cómo han dicho pueden ir 1..1000 registros de facturación incluídos.

El RegistrodeFacturación es el que hay que guardar de forma obligatoria y debe ser accesible y descargable.

La información del envío, no es obligatorio guardarla, y cada uno puede decidir cómo y qué guardar (para luego gestionar toda esa lógica desde el programa). Si guardar todo el paquete (con las 1000 fcaturas), si guardar la respuesta en el formato que la da la AEAT, si guardar sólo los códigos,...

Opcion 1:
Vale, sin intencion de hacerme el pesado, en tu opinion, (porque me acabo de enterar ahora) si guardamos todo el envio, asociado a cada factura, ¿estariamos cumpliendo? porque tecnicamente la informacion del registroDeFacturacion se encuentra alli. Encontrarla es tan facil como hacer una busqueda de texto.

Opcion 2:
Me gustaria poder sacar esa informacion del XML de envio, a ver si me podeis hacer llegar ese codigo ( bmfranky ) para incorporarlo.

¿Puedes por favor neftali resumir brevemente que es necesario guardar y disponer en un sistema verifactu? porque en el foro la informacion esta muy dispersa, para ver que le falta al componente y como incorporarlo.

gracias !

Neftali [Germán.Estévez] 13-02-2025 10:09:02

Extraído directamente de la documentación de la AEAT (cuestiones generales):
Capacidad de exportar los registros

Todos los sistemas informáticos de facturación producidos y comercializados deberán tener capacidad de exportar y transmitir en línea los registros de facturación. Cuando la modalidad elegida sea NO VERI* FACTU, en caso de que se requieran por parte de la Administración Tributaria dichos registros, los mismos podrán ser directamente enviados a través de un procedimiento simplificado y automatizado.


La transmisión:
Verifactu: La transmisión es inmediata
No-verifactu: deben implementar la transmisión de registros bajo requrimiento.


Capacidad de exportar.
Yo creo que no deja dudas, desde el programa hay que poder exportar un registro de facturación.
El cómo lo hagamamos ya es cuestión de cada uno.

Digamos que en nuestro programa tenemos FACTURAS, para cada factura sabemos que hay 1..N REGISTROSDEFACTURACION (alta, subsanación, anuulación).
Nosotros hemos barajado varias opciones:

* Desde la factura exportar todos los registros asociados a esa factura (1..N)
* Desde la facttura, acceder a sus registros de facturación (1..N) -es como ver el historial de las operaciones sobre esa factura- y desde ahí poder exportarlos 1 a 1.

Neftali [Germán.Estévez] 13-02-2025 10:12:39

Cita:

Empezado por seccion_31 (Mensaje 562007)
Opcion 1:
Vale, sin intencion de hacerme el pesado, en tu opinion, (porque me acabo de enterar ahora) si guardamos todo el envio, asociado a cada factura, ¿estariamos cumpliendo? porque tecnicamente la informacion del registroDeFacturacion se encuentra alli. Encontrarla es tan facil como hacer una busqueda de texto.

Opcion 2:
Me gustaria poder sacar esa informacion del XML de envio, a ver si me podeis hacer llegar ese codigo ( bmfranky ) para incorporarlo.


Yo creo que es más sencillo enfocarlo a cada registro de facturación que enfocarlo al envío.
Al grabar la factura DEBES generar el registro, por lo tanto creo que en ese momento es el punto fácil para guardarlo.

También puedes enfocarlo al envío, pero creo que es más complejo a la hora de recuperar los registros.
Pienso en que si has hecho varias operaciones sobre una factura (ALTA, SUBSANACION, ANULACION) si queres obtener todo la información de esa factura (y sus registros de facturación) vas a tener que ir navegando por diferentes envíos e ir extrayendo de cada uno de ellos el registro de facturación correspondiente a esa operación. Se puede hacer, pero creo que es más complejo.

seccion_31 13-02-2025 11:03:59

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 562009)
Yo creo que es más sencillo enfocarlo a cada registro de facturación que enfocarlo al envío.
Al grabar la factura DEBES generar el registro, por lo tanto creo que en ese momento es el punto fácil para guardarlo.

También puedes enfocarlo al envío, pero creo que es más complejo a la hora de recuperar los registros.
Pienso en que si has hecho varias operaciones sobre una factura (ALTA, SUBSANACION, ANULACION) si queres obtener todo la información de esa factura (y sus registros de facturación) vas a tener que ir navegando por diferentes envíos e ir extrayendo de cada uno de ellos el registro de facturación correspondiente a esa operación. Se puede hacer, pero creo que es más complejo.

Al grabar la factura, la coloco en el objeto de la AEAT y no puedo o no se, recuperar ese XML parcial hasta su envio.

El plan desde mi ignorancia es enviar, guardar el XML completo y mediante alguna funcion extraer cada registrodefacturacion procesado para las facturas aceptadas. Si alguien tiene ese codigo para extraer una seccion del XML dado el numSerie de la factura, me evitaria trabajo de investigacion, o que se quedara pendiente.

Con Darkduae estamos mejorando la demo y el parseo de la respuesta de la AEAT para cubrir mas casos.

Neftali [Germán.Estévez] 13-02-2025 11:19:29

Cita:

Empezado por seccion_31 (Mensaje 562016)
Al grabar la factura, la coloco en el objeto de la AEAT y no puedo o no se, recuperar ese XML parcial hasta su envio.


Creo que hay varios mensajes donde está cómo hacerlo.
Por ejemplo este, genera el registro con SOAP y en un momento dado extrae el XML del registro de facturación.
https://www.clubdelphi.com/foros/sho...postcount=1428

Código Delphi [-]
...
 try
   newNode := Factura.RegistroFacturacion.ObjectToSOAP( ARootNode, ARootNode, MOPToSoapDomConvert, 'RegistroFacturacionType',
   Swdsl,'T',[ocoDontPrefixNode,ocoDontPutTypeAttr], RefId  ); //ocoDontPrefixNode

   XML.DocumentElement := ARootNode;
   XML.XML.SaveToFile('RegistroFacturacion.xml',TEncoding.UTF8);
   XML.Active := False;

 Except
   On E : Exception do Begin
    Showmessage(E.Message);
    XML.DocumentElement := ARootNode;
    XML.XML.SaveToFile('RegistroFacturacionError.xml',TEncoding.UTF8);
    XML.Active := False;
 End;
 ...

seccion_31 13-02-2025 12:28:21

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 562017)
Creo que hay varios mensajes donde está cómo hacerlo.
Por ejemplo este, genera el registro con SOAP y en un momento dado extrae el XML del registro de facturación.
https://www.clubdelphi.com/foros/sho...postcount=1428

Código Delphi [-]
...
 try
   newNode := Factura.RegistroFacturacion.ObjectToSOAP( ARootNode, ARootNode, MOPToSoapDomConvert, 'RegistroFacturacionType',
   Swdsl,'T',[ocoDontPrefixNode,ocoDontPutTypeAttr], RefId  ); //ocoDontPrefixNode

   XML.DocumentElement := ARootNode;
   XML.XML.SaveToFile('RegistroFacturacion.xml',TEncoding.UTF8);
   XML.Active := False;

 Except
   On E : Exception do Begin
    Showmessage(E.Message);
    XML.DocumentElement := ARootNode;
    XML.XML.SaveToFile('RegistroFacturacionError.xml',TEncoding.UTF8);
    XML.Active := False;
 End;
 ...

Perfecto, he visto el ejemplo de Delphier publicado al que agradezco su colaboracion, y ya funciona, a ver ahora como lo implemento en el componente. Pero esto ya esta. gracias !

nincillo 13-02-2025 12:46:03

Cita:

Empezado por seccion_31 (Mensaje 561795)
¿podemos estar seguro?

¿ entonces bajo el regimen general 01, la E4 ? esta tarde lo probare.

Automatizacion:

podemos automatizar, UE, fuera de UE, y canarias. Eso ya esta automatizado , (hay que modificar los tipos de exenciones que hay en el codigo, pero ya esta)

podemos automatizar facilmente, el E4, colocandole el regimen general 01. (si funciona).


Mas allá de esto, ¿ya no se puede automatizar?:

¿Quizás habría que crear un array particular para exenciones y cubrir el resto de casos?

Yo por lo que he podido ver en algún otro programa, he querido entender que las exenciones pueden incluso ir a nivel de apunte.

Eso sería bueno que nos lo aclarara alguien que estuviera más "ducho" en temas contables/fiscales.

No es lo mismo productos al 0% de IVA que productos "exentos" de IVA, como en su momento creo que eran las mascarillas y cosas de "esas".

seccion_31 13-02-2025 12:50:12

en la nueva version DLL hay un array para procesar exenciones, sin la automatizacion del array de ivas, con lo que quedaria solucionado. Eso si, hay que saber de fiscalidad para que el programa lo coloque corectamente. La nueva implementacion supera con creces la anterior.

Pero ese es el problema, yo al menos no se tanto de fiscalidad como asegurar que se estan generando bien los xml.

seria necesario y esto es una llamada de auxilio XD

un juego de XMLs para los casos principales, automatizados por el componente para verificar.


y otro despues para los menos comunes.

Pero sin eso aunque tecnicamente el componente funcione, estamos vendidos.

ramherfer 17-02-2025 21:48:29

Hola buenas tardes.
Al procesar la respuesta resultado.facturas[j].tipoOperacion me está devolviendo "SistemaFac" cuando la factura contiene algún error y es rechazada.
Si la factura es correcta y es admitida resultado.facturas[j].tipoOperacion devuelve "Alta".
Solo proceso una factura y utilizo este dato para identificar en el registroFacturación la operación de la factura a la que se refiere y actualizar su estado, movimiento.

En operaciones Baja declaradas en el registroFacturación obtengo un Access Violation en el módulo msgVerifactu.exe. He probado como fecha de factura la fecha actual y la propia fecha de la factura que se da de baja, pero no se, obtengo el mismo resultado. Voy a darle un vistazo a ver si soy capaz de encontrar el problema.

Al final creo que entiendo el sistema y tengo todo el tema de comunicaciones en una tabla independiente llamada RegistroSIF con las operaciones de cada una de las facturas (Alta, baja, modificacion, etc) que se relaciona con la tabla de cabeceras de facturas. Si genero una baja entra en RegistroSIF como baja y la cabecera de factura tambien la pone como baja. De esta forma puede tener una factura distintos movimientos o estados FR250056 ALTA y FR250056 BAJA. Gracias a los que me aclarasteis mi monumental lio mental.

Un saludo,

seccion_31 18-02-2025 06:54:40

Cita:

Empezado por ramherfer (Mensaje 562060)
Hola buenas tardes.
Al procesar la respuesta resultado.facturas[j].tipoOperacion me está devolviendo "SistemaFac" cuando la factura contiene algún error y es rechazada.
Si la factura es correcta y es admitida resultado.facturas[j].tipoOperacion devuelve "Alta".
Solo proceso una factura y utilizo este dato para identificar en el registroFacturación la operación de la factura a la que se refiere y actualizar su estado, movimiento.

En operaciones Baja declaradas en el registroFacturación obtengo un Access Violation en el módulo msgVerifactu.exe. He probado como fecha de factura la fecha actual y la propia fecha de la factura que se da de baja, pero no se, obtengo el mismo resultado. Voy a darle un vistazo a ver si soy capaz de encontrar el problema.

Al final creo que entiendo el sistema y tengo todo el tema de comunicaciones en una tabla independiente llamada RegistroSIF con las operaciones de cada una de las facturas (Alta, baja, modificacion, etc) que se relaciona con la tabla de cabeceras de facturas. Si genero una baja entra en RegistroSIF como baja y la cabecera de factura tambien la pone como baja. De esta forma puede tener una factura distintos movimientos o estados FR250056 ALTA y FR250056 BAJA. Gracias a los que me aclarasteis mi monumental lio mental.

Un saludo,

Esta pendiente el cambio a la version DLL, asi a bote pronto recuerdo que la baja daba error.

En cuanto lo publiquen en el FTP, que ya tienen el enlace, lo readaptas y vuelves a probar

Estos son los cambios de la nueva version , donde tambien ha colaborado el usuario darkdudae, a quien agradezco su trabajo.
(Algunos de ellos estan sin comprobar).

Cita:

> Nota general:
Ahora el servidor B10 ya no se suministra como aplicacion. Tenemos una DLL llamada veriFactu.dll


cuando se cambia un type (record). etc... en uTiposVeriFactu se deben recompilar verifactu.dll y aplicacion D7.
La compilacion de la DLL se guarda en la carpeta DEMO_D7 para facilitar las pruebas


Si ha utilizado la version anterior del componente, eliminarlo
Antes de registrar el componente copiar la DLL a syswow64
----------------------------------------------------------------------------------------------------------------------------


--------------------------------
---------------- version 1
--------------------------------
Se añade la funcion getCertificadosFecha para obtener no solo el nombre de los certificados si no su fecha de validez. En las funciones de certificados solo se devuelven certificados validos.

Aumentada longitud DescripcionError en el resultado de cada factura (array)

Se añade propiedad ultimo_error_verifactu con el texo de error al añadir una factura, de momento solo recoge algunos errores. Puede leerse si la funcion VeriFactuD7.addFactura retorna -1. (ver demo de ejemplo).


Se añaden en el componente las propiedades nsesion y nfacturas (numero de facturas altas y baja preparadas para enviar) como propiedades de solo lectura

Se eliminan del record TRegistroFactura nsesion y nfactura

En la DEMO se elimina del formulario el componente TVeriFactu pasando a ser creado al inicio del formulario, se incluye un ejemplo del nuevo evento OnRegFac, de esta forma ya no es necesario instalar el componente en Delphi y la DLL puede ser mantenida en el directorio de la Demo.

---> Se cambian las exenciones de operaciones EU a E5 y Export a E2, se automatiza el tipoNIF si NO esta indicado. Para EU 02 y para Export 06 (otro doc.probatorio).

Se incluye un array en la unidad uTiposVeriFactu llamado _AyudaExentas[1..6] que contiene un resumen textual de las exenciones a modo informativo.

Se añaden las funciones Paises PaisesEU PaisesExport Para obtener una lista de paises validos en un TStringList. ( ES: España se considera fuera de la lista en PaisesEU retornada )

Se añade la funcion validPais para validar el codigo de pais (ya con max. 3 digitos)

Automatizacion de facturas a España (canarias):
En codigoPais podemos enviar ahora el codigo postal de la provincia del cliente. Si se detecta valor numerico se procesara como españa, y ADEMAS si el codigo postal es 35 ó 38 se activara automaticamente el flag de canarias.

Se añade el evento OnRegFac que sera lanzado cuando se procese cada registro de facturacion, es decir, podemos dejar en blanco el pathXML_RegistroFacturacion y todavia guardar el archivo que nos ira enviando como un Stream al evento definido por el usuario: (o utilizar ambos, archivo y evento)

TRegistroFacEvent = procedure(Sender: TObject; numserieFactura:string; xml:TMemoryStream) of object;

Añadida busqueda por SIF en la funcion consulta(..... ) filtroSIF=true filtrara ademas por los datos del sistema informatico. Ver ejemplo en la Demo en consulta de periodo

Se añade refexterna en el dato de la factura, para indicar informacion libre, 60 digitos. tanto en alta/anulacion como en la consulta

Se añade el path para indicar donde guardar los registros de facturacion y una variable booleana para indicar si se guardan todos los registros o solo los aceptados, ATENCION: con una limitacion, podrian guardarse registros innecesarios de facturas con operaciones aceptadas y no aceptadas en la misma sesion de envio (si se da el caso).

pathXML_RegistroFacturacion (ruta a la carpeta, sin terminar en \)
Registro_soloAceptadas (true o false) (false= guardara todas los registros de facturacion)

Hay dos cambios de nombres en el archivo de XML:
Se cambian las variables de los xml de envio y de respuesta a: (para hacerlos mas consistentes)

filenameXML_Envio
filenameXML_Respuesta

Se corrije la consulta por fechas

La demo ha sido muy mejorada, con mas funciones y capacidad

Se añade el campo estadoderegistro en el array de la consulta para cotejar facturas (en cada factura) con los valores: Aceptada, Aceptada con errores, Anulada

Se corrigen las fechas devueltas por consulta a formato / /

Corregido fallo al dar de baja una factura, de momento solo se admiten bajas de facturas registradas en verifactu

-----------------------
Inversion del sujeto pasivo: Hay un nuevo flag que afecta todos los ivas llamado inversionSUjetoPasivo en el record de factura para facturas a ESPAÑA (no canarias):

"
- El proveedor o prestador del servicio registrará los datos de la factura en el Libro
registro de Facturas Expedidas consignando en el campo de tipo de operación la clave
“S2: Sujeta – No Exenta – Inv. Suj. Pasivo”. En los campos de tipo impositivo y cuota"
repercutida consignará “0”. -

"

> Toda la factura debe estar bajo ese regimen y utilizar el primer IVA para indicar unicamente la base imponible.
-----------------------

Corregido error al cotejar (consultar) una factura sin cliente, ni nif.

Eliminada variable situacion, por no usar

Si se suministra una fecha de factura en formato - - se convierte a / / que es el formato esperado

Se añade la extension .P12 para reconocer un certificado en disco al nombre del certificado: PFX y P12

Se añade el indicador primerRegistro para comprobar antes de enviar si no hay registro anterior en algun punto de las facturas a enviar.

Ahora hay dos indicadores: incidencia (lectura/escritura) y primerRegistro(lectura).

En la consulta a la AEAT, en desglose de iva ahora se carga la base imponible e incluye informacion sobre exencion,
revisar: TRegistroFacturaIVASConsulta

Cliente codpais pasa de 2 a 3 digitos

Se ha mejorado la limpieza de algunos records funciones clear_ internas del servidor B10 (ahora DLL)

Al validar el NIF ya se puede obtener el nombre validado (devuelto por la consulta)

EXENCIONES AUTOMATICAS : (en array iva)
------------------------
Las facturas con pais destino a la EU automaticamente se consideran tipoExenta E6 clave regimen 01 (ahora E5)

Las facturas con pais destino al resto del mundo (en clave regimen 02) y canarias (en clave regimen 01) automaticamente se consideran tipoExentas E3 (ahora E2)

Las facturas de inversion sujeto pasivo (para españa)


OTRAS EXENCIONES: (en array exenta)
-----------------
En el record de facturas hay un nuevo array para crear OTRAS exenciones:
Este array se procesa tal cual sin otro proceso generando el desglose equivalente.

Record Factura:

exenta: array[0..maxivas] of TRegistroFacturaExentas;


Array de:

TRegistroFacturaExentas=record
tipoExenta :string[2];
calificacionOperacion:string[2]; // ¿opcional?
claveRegimen :string[2];

baseImp :currency;
end;

Para indicar si la factura lleva alguna base imponible exenta, se hara de forma similar a la del iva, pero cambiando el array. (ver ejemplo en el importador de excel)

Asi mismo un record similar se encuentra en la consulta a la AEAT, para retornar informacion sobre las facturas exentas: (exenciones creadas automaticas, o manuales con el array).

Nota de uso: Cada sesion deberia limitarse a una serie de facturacion y por supuesto 1 solo objeto TVeriFactu

Saludos !

seccion_31 18-02-2025 07:09:18

Cita:

Empezado por ramherfer (Mensaje 562060)
Hola buenas tardes.
Al procesar la respuesta resultado.facturas[j].tipoOperacion me está devolviendo "SistemaFac" cuando la factura contiene algún error y es rechazada.
Si la factura es correcta y es admitida resultado.facturas[j].tipoOperacion devuelve "Alta".
Solo proceso una factura y utilizo este dato para identificar en el registroFacturación la operación de la factura a la que se refiere y actualizar su estado, movimiento.

En operaciones Baja declaradas en el registroFacturación obtengo un Access Violation en el módulo msgVerifactu.exe. He probado como fecha de factura la fecha actual y la propia fecha de la factura que se da de baja, pero no se, obtengo el mismo resultado. Voy a darle un vistazo a ver si soy capaz de encontrar el problema.

Al final creo que entiendo el sistema y tengo todo el tema de comunicaciones en una tabla independiente llamada RegistroSIF con las operaciones de cada una de las facturas (Alta, baja, modificacion, etc) que se relaciona con la tabla de cabeceras de facturas. Si genero una baja entra en RegistroSIF como baja y la cabecera de factura tambien la pone como baja. De esta forma puede tener una factura distintos movimientos o estados FR250056 ALTA y FR250056 BAJA. Gracias a los que me aclarasteis mi monumental lio mental.

Un saludo,

Aun asi puedes (y deberias) procesar la factura con

resultado.facturas[j].OK
y una vez OK entonces mirar tambien: resultado.facturas[j].aceptadoConErrores

tipoOperacion: Probablemente cuando es procesada la factura delphi interpretara ese valor dentro de los enum de tipo de operacion, muy probablemente en el campo XML no venga indicado si quiera. Si quieres postea el XML de resultado cuando ocurre eso. Ya adeverti que hace cosas raras cuando no hay valor un campo enum. quizas sea el caso.

Ver ejemplo en la demo:


Código:

            if resultado.facturas[j].OK then  // Es correcto ó aceptado con errores
            begin
                // colocar el csv y huella en la factura
                if facturasEnviadas.locate('emisor;NumSerieFactura',vararrayof([emisor, factura ]),[]) then
                begin
                    FacturasEnviadas.edit;
                    FacturasEnviadas.fieldbyName('csv').text      :=resultado.CSV;
                    FacturasEnviadas.FieldByName('huella').text  :=resultado.facturas[j].huellaFactura;
                    FacturasEnviadas.fieldbyName('situacion').text:=estado;
                    FacturasEnviadas.post;
                end;
                if resultado.facturas[j].aceptadoConErrores then inc(_oke) else inc(_ok);
            end
            else
                inc(_err);                            // Es erronea


Neftali [Germán.Estévez] 18-02-2025 09:07:55

En el FTP del clubdelphi ya está la última versión del proyecto con códo el código fuente incluído y todo lo que necesita.
De nuevo, desde aquí agradecer a [seccion_31] la aportación y la colaboración y aportes de [darkdudae].

ramherfer 18-02-2025 10:11:59

Cita:

Empezado por seccion_31 (Mensaje 562064)
Aun asi puedes (y deberias) procesar la factura con

resultado.facturas[j].OK
y una vez OK entonces mirar tambien: resultado.facturas[j].aceptadoConErrores

tipoOperacion: Probablemente cuando es procesada la factura delphi interpretara ese valor dentro de los enum de tipo de operacion, muy probablemente en el campo XML no venga indicado si quiera.
Si quieres postea el XML de resultado cuando ocurre eso. Ya adeverti que hace cosas raras cuando no hay valor un campo enum. quizas sea el caso.

Ver ejemplo en la demo:


Código:

            if resultado.facturas[j].OK then  // Es correcto ó aceptado con errores
            begin
                // colocar el csv y huella en la factura
                if facturasEnviadas.locate('emisor;NumSerieFactura',vararrayof([emisor, factura ]),[]) then
                begin
                    FacturasEnviadas.edit;
                    FacturasEnviadas.fieldbyName('csv').text      :=resultado.CSV;
                    FacturasEnviadas.FieldByName('huella').text  :=resultado.facturas[j].huellaFactura;
                    FacturasEnviadas.fieldbyName('situacion').text:=estado;
                    FacturasEnviadas.post;
                end;
                if resultado.facturas[j].aceptadoConErrores then inc(_oke) else inc(_ok);
            end
            else
                inc(_err);                            // Es erronea


Este es el XML del que intento localizar el tipoOperación de la factura para con ese dato y el numero de serie actualizar el RegistroSif para que indique que hay algo con error actualizando el codigo y la descripción del mismo para información del usuario (devuelve SistemaFac). Ojo los datos fiscales los he alterado en el nodo ObligadoEmision
Código:

<env:Header/>
<env:Body Id="Body">
<tikR:RespuestaRegFactuSistemaFacturacion xmlns:tikR="https://www2.agenciatributaria.gob.es/......" xmlns:tik="https://www2.agenciatributaria.gob.es/.....xsd">
<tikR:Cabecera>
<tik:ObligadoEmision>
<tik:NombreRazon>Nombre razon social del emisor</tik:NombreRazon>
<tik:NIF>00000000W</tik:NIF>
</tik:ObligadoEmision>
</tikR:Cabecera>
<tikR:TiempoEsperaEnvio>60</tikR:TiempoEsperaEnvio>
<tikR:EstadoEnvio>Incorrecto</tikR:EstadoEnvio>
<tikR:RespuestaLinea>
<tikR:IDFactura>
<tik:IDEmisorFactura>00000000W</tik:IDEmisorFactura>
<tik:NumSerieFactura>FR250056</tik:NumSerieFactura>
<tik:FechaExpedicionFactura>17-02-2025</tik:FechaExpedicionFactura>
</tikR:IDFactura>
<tikR:Operacion>
<tik:TipoOperacion>Alta</tik:TipoOperacion>
</tikR:Operacion>
<tikR:EstadoRegistro>Incorrecto</tikR:EstadoRegistro>
<tikR:CodigoErrorRegistro>1123</tikR:CodigoErrorRegistro>
<tikR:DescripcionErrorRegistro>El formato del NIF es incorrecto.. NIF:24369243S.</tikR:DescripcionErrorRegistro>
</tikR:RespuestaLinea>
</tikR:RespuestaRegFactuSistemaFacturacion>
</env:Body>
</env:Envelope>


seccion_31 18-02-2025 10:23:36

en uVeriFactuFuncs

asi rapido

linea 1829 -31 aproximadamente, pone:

Código Delphi [-]
sesiones[sesion].resultado.facturas[n].tipoOperacion   :=getEnumName( TypeInfo(TipoOperacionType), ord(res.RespuestaLinea[ j ].EstadoRegistro ) );

y deberia poner:

Código Delphi [-]
            sesiones[sesion].resultado.facturas[n].tipoOperacion   :=getEnumName( TypeInfo(TipoOperacionType), ord(res.RespuestaLinea[ j ].Operacion.TipoOperacion ) );

Recompila la DLL y ya

Nota: no lo he probado. Cuando este confirmado que funciona, y haya pasado algo mas de tiempo volvere a publicar otra version.

Saludos !

DarkDudae 18-02-2025 17:07:19

He encontrado un bug en el componente si el evento OnRegFac no está asignado antes de hacer un envío (lo cual causa una excepción).
En la demo este error no se muestra debido a que creamos el componente VeriFactuD7 en runtime, así como le asignamos dicha propiedad.

Para solucionarlo, debemos cambiar el código del componente (uVerifacu):

Debemos cambiar este código:

Código Delphi [-]
procedure _callbackRF(filehandleMap:longint);   stdcall;
var
  callback_RF_info:TFileHandledRecordCall;
begin
    try
      loadFileMappingData(@callback_RF_info, sizeof(callback_RF_info), filehandleMap);
      callBacksVeriFactus[callback_RF_info.sesion].FOnRegFac(callBacksVeriFactus[callback_RF_info.sesion]  ,callback_RF_info.numSerieFactura, callback_RF_info.streamXML );
   except
    ON E:Exception do
    begin
      ShowMessage('Error excepcion: '+E.Message);
    end;
   end;
end;

Por este otro en el que nos aseguramos que el evento esté asignado:
Código Delphi [-]
procedure _callbackRF(filehandleMap: longint); stdcall;
var
  callback_RF_info: TFileHandledRecordCall;
  callbackObj: TVeriFactu;
begin
  try
    loadFileMappingData(@callback_RF_info, sizeof(callback_RF_info), filehandleMap);
    
    callbackObj := callBacksVeriFactus[callback_RF_info.sesion];

    if Assigned(callbackObj) then
    begin
      // Verificar si el evento FOnRegFac está asignado antes de llamarlo
      if Assigned(callbackObj.FOnRegFac) then
        callbackObj.FOnRegFac(callbackObj, callback_RF_info.numSerieFactura, callback_RF_info.streamXML)
      else
        OutputDebugString(PAnsiChar('Advertencia: El evento FOnRegFac no está asignado.'));
    end
    else
      OutputDebugString(PAnsiChar('Error: callBacksVeriFactus[' + IntToStr(callback_RF_info.sesion) + '] es nil.'));
    
  except
    on E: Exception do
      ShowMessage('Error excepción en _callbackRF: ' + E.Message);
  end;
end;

Es posible que tengáis que desinstalar y volver a instalar el componente tras el cambio.

Un saludo

ramherfer 18-02-2025 19:40:12

Cita:

Empezado por seccion_31 (Mensaje 562071)
en uVeriFactuFuncs

asi rapido

linea 1829 -31 aproximadamente, pone:

Código Delphi [-]
sesiones[sesion].resultado.facturas[n].tipoOperacion   :=getEnumName( TypeInfo(TipoOperacionType), ord(res.RespuestaLinea[ j ].EstadoRegistro ) );

y deberia poner:

Código Delphi [-]
            sesiones[sesion].resultado.facturas[n].tipoOperacion   :=getEnumName( TypeInfo(TipoOperacionType), ord(res.RespuestaLinea[ j ].Operacion.TipoOperacion ) );

Recompila la DLL y ya

Nota: no lo he probado. Cuando este confirmado que funciona, y haya pasado algo mas de tiempo volvere a publicar otra version.

Saludos !

La modificación funciona perfectamente. Las Bajas o Anulaciones que tambien tenía problemas funcionan tambien. Gracias seccion_31.

Neftali [Germán.Estévez] 19-02-2025 08:38:21

Actualizada la última versión en el FTP del club.
Gracias a todos.

seccion_31 19-02-2025 09:49:04

Cita:

Empezado por ramherfer (Mensaje 562096)
La modificación funciona perfectamente. Las Bajas o Anulaciones que tambien tenía problemas funcionan tambien. Gracias seccion_31.

lo que falta por probar y creo que NO funciona, son las anulaciones de facturas que no tiene verifactu.

Saludos !

Y es una lastima que falten colaboraciones para depurar, ofrecer ideas, validar los XML y mejorar el codigo, este componente podria solucionar implantaciones "habituales" de verifactu sin mucho problema, en uno o tres dias de trabajo, puedes tener una instalacion verifactu funcional.

agradecer a darkdudae por su colaboracion.

CarlosMz 19-02-2025 09:55:21

Muchas gracias por los aportes,

Si me indicas en qué parte focalizar y puedo ayudar lo hago.

Yo trabajo con Delphi 12 y tengo problemas con los WDSL que vienen y necesito regenerarlos de nuevo con SOAP 1.2

Personalmente lo que estoy haciendo es modificar el código para quitar el componente y la DLL, dejando el sistema en solo código "plano" para poder usarlo en modo web y no en Windows

newtron 19-02-2025 10:03:53

Cita:

Empezado por seccion_31 (Mensaje 562110)
lo que falta por probar y creo que NO funciona, son las anulaciones de facturas que no tiene verifactu.

Saludos !

Y es una lastima que falten colaboraciones para depurar, ofrecer ideas, validar los XML y mejorar el codigo, este componente podria solucionar implantaciones "habituales" de verifactu sin mucho problema, en uno o tres dias de trabajo, puedes tener una instalacion verifactu funcional.

agradecer a darkdudae por su colaboracion.


Buenas compañero. Es posible que una factura rechazada no puedas anularla porque no exista en sus registros.


Saludos.

seccion_31 19-02-2025 10:10:21

hola carlos_mz

habria que tratar de subir una baja de factura, que no se encuentre en verifactu, y ver que pasa. en teoria puedes anular facturas que verifactu no ha almacenado. A mi no me funciono y lo deje aparcado.

verificar que en consulta, los datos que devuelve si son correctos para cada tipo de factura. en especial desgloses de iva, y exenciones.

por otro lado

generar un XML de cada tipo de factura, incluida canarias, quitas tus datos y vemos aqui en el foro si estan OK.

Eso se me ocurre como lo mas inmediato, si tienes tiempo miras lo que puedas.

Saludos !

seccion_31 19-02-2025 11:08:06

Cita:

Empezado por newtron (Mensaje 562113)
Buenas compañero. Es posible que una factura rechazada no puedas anularla porque no exista en sus registros.


Saludos.

hola !

no es una factura rechazada, es una factura anterior a la implantacion de verifactu, digamos de unos dias antes de su entrada en vigor. que yo recuerde en la documentacion dice que se puede.

: )

Neftali [Germán.Estévez] 19-02-2025 11:46:03

Cita:

Empezado por seccion_31 (Mensaje 562110)
lo que falta por probar y creo que NO funciona, son las anulaciones de facturas que no tiene verifactu.

Os adjunto cómo sería el registro enviado. Y que posteriormente me lo han aceptado.


Cita:

Empezado por newtron (Mensaje 562113)
Buenas compañero. Es posible que una factura rechazada no puedas anularla porque no exista en sus registros.

Pueden ser facturas antiguas, que modificas o borras (anteriorres a la activación). También una factura que se ha rechazado por algún motivo y que luego borras.

Cita:

Empezado por seccion_31 (Mensaje 562114)
habria que tratar de subir una baja de factura, que no se encuentre en verifactu, y ver que pasa. en teoria puedes anular facturas que verifactu no ha almacenado. A mi no me funciono y lo deje aparcado.

Cita:

Empezado por seccion_31 (Mensaje 562115)
no es una factura rechazada, es una factura anterior a la implantacion de verifactu, digamos de unos dias antes de su entrada en vigor. que yo recuerde en la documentacion dice que se puede.


Creo que pueden ser ambos casos; Se marca el registro de anulación como SinRegistroPrevio.

Código:

<sum:RegFactuSistemaFacturacion xmlns:xd="http://www.w3.org/2000/09/xmldsig#"
xmlns:sum1="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd"
xmlns:sum="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd">
  <sum:RegistroFactura>
    <sum1:RegistroAnulacion>
      <sum1:IDVersion>1.0</sum1:IDVersion>
      <sum1:IDFactura>
        <sum1:IDEmisorFacturaAnulada>ZZZZZZZZZ</sum1:IDEmisorFacturaAnulada>
        <sum1:NumSerieFacturaAnulada>RECT-3</sum1:NumSerieFacturaAnulada>
        <sum1:FechaExpedicionFacturaAnulada>23-10-2024</sum1:FechaExpedicionFacturaAnulada>
      </sum1:IDFactura>
      <sum1:SinRegistroPrevio>S</sum1:SinRegistroPrevio>
      <sum1:Encadenamiento>
        <sum1:RegistroAnterior>
          <sum1:IDEmisorFactura>ZZZZZZZ</sum1:IDEmisorFactura>
          <sum1:NumSerieFactura>-1</sum1:NumSerieFactura>
          <sum1:FechaExpedicionFactura>24-10-2024</sum1:FechaExpedicionFactura>
          <sum1:Huella>25E03B23C71B88D8337D5EB4DD7E1F3C031962C6550452D59D1841D7A9FE4444</sum1:Huella>
        </sum1:RegistroAnterior>
      </sum1:Encadenamiento>
      <sum1:SistemaInformatico>
        <sum1:NombreRazon>Empresa Conservas S.L.</sum1:NombreRazon>
        <sum1:NIF>ZZZZZZZZ</sum1:NIF>
        <sum1:NombreSistemaInformatico>MiERP</sum1:NombreSistemaInformatico>
        <sum1:IdSistemaInformatico>04</sum1:IdSistemaInformatico>
        <sum1:Version>1.0.0.0</sum1:Version>
        <sum1:NumeroInstalacion>12345678</sum1:NumeroInstalacion>
        <sum1:TipoUsoPosibleSoloVerifactu>N</sum1:TipoUsoPosibleSoloVerifactu>
        <sum1:TipoUsoPosibleMultiOT>S</sum1:TipoUsoPosibleMultiOT>
        <sum1:IndicadorMultiplesOT>N</sum1:IndicadorMultiplesOT>
      </sum1:SistemaInformatico>
      <sum1:FechaHoraHusoGenRegistro>2025-02-19T10:36:16Z</sum1:FechaHoraHusoGenRegistro>
      <sum1:TipoHuella>01</sum1:TipoHuella>
      <sum1:Huella>E0D84796EE72EB59B8ABC9A81C9715F1967839A1B3D2ACA043006ECCC9144444</sum1:Huella>
    </sum1:RegistroAnulacion>
  </sum:RegistroFactura>
</sum:RegFactuSistemaFacturacion>


seccion_31 20-02-2025 07:58:38

gracias Neftali

viendo el codigo me doy cuenta de que "creo" que lo tenia mal planteado el sinRegistroPrevio

hay un "if" por medio que creo no estaba bien situado lo he movido. No lo he probado todavia.

Quedara para la 1.2

Saludos !

CarlosMz 20-02-2025 12:46:44

Buenas, no sé si era esto lo que me pediste:

Respuesta envío factura normal con 21%
Código:

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <SOAP-ENV:Body>
    <RegFactuSistemaFacturacion xmlns="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd">
      <Cabecera>
        <ObligadoEmision xmlns="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
          <NombreRazon>INFORMATICA, S.L.</NombreRazon>
          <NIF>B1222222</NIF>
        </ObligadoEmision>
        <RemisionVoluntaria xmlns="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
          <Incidencia>S</Incidencia>
        </RemisionVoluntaria>
      </Cabecera>
      <RegistroFactura>
        <RegistroAlta xmlns="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
          <IDVersion>1.0</IDVersion>
          <IDFactura>
            <IDEmisorFactura>B1222222</IDEmisorFactura>
            <NumSerieFactura>25F00001</NumSerieFactura>
            <FechaExpedicionFactura>01-01-2025</FechaExpedicionFactura>
          </IDFactura>
          <NombreRazonEmisor>INFORMATICA, S.L.</NombreRazonEmisor>
          <TipoFactura>F1</TipoFactura>
          <DescripcionOperacion>VENTAS MERCADERIAS</DescripcionOperacion>
          <Destinatarios>
            <IDDestinatario>
              <NombreRazon>CLIM S.L.</NombreRazon>
              <NIF>B22222</NIF>
            </IDDestinatario>
          </Destinatarios>
          <Desglose>
            <DetalleDesglose>
              <ClaveRegimen>01</ClaveRegimen>
              <CalificacionOperacion>S1</CalificacionOperacion>
              <TipoImpositivo>21.00</TipoImpositivo>
              <BaseImponibleOimporteNoSujeto>46.00</BaseImponibleOimporteNoSujeto>
              <CuotaRepercutida>9.66</CuotaRepercutida>
            </DetalleDesglose>
          </Desglose>
          <CuotaTotal>9.66</CuotaTotal>
          <ImporteTotal>55.66</ImporteTotal>
          <Encadenamiento>
            <PrimerRegistro>S</PrimerRegistro>
          </Encadenamiento>
          <SistemaInformatico>
            <NombreRazon>INFORMATICA SL</NombreRazon>
            <NIF>B1222222</NIF>
            <NombreSistemaInformatico>S</NombreSistemaInformatico>
            <IdSistemaInformatico>1</IdSistemaInformatico>
            <Version>2025.1</Version>
            <NumeroInstalacion>undetermined</NumeroInstalacion>
            <TipoUsoPosibleSoloVerifactu>S</TipoUsoPosibleSoloVerifactu>
            <TipoUsoPosibleMultiOT>N</TipoUsoPosibleMultiOT>
            <IndicadorMultiplesOT>S</IndicadorMultiplesOT>
          </SistemaInformatico>
          <FechaHoraHusoGenRegistro>2025-02-20T12:43:58+01:00</FechaHoraHusoGenRegistro>
          <TipoHuella>01</TipoHuella>
          <Huella>EDC14FF1DD7F3136FCBA1FB821D516DA7C0A38BCD7965146A04A73CC1388EC32</Huella>
        </RegistroAlta>
      </RegistroFactura>
    </RegFactuSistemaFacturacion>
  </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Respuesta envío Canarias
Código:


<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SOAP-ENV:Body>
<RegFactuSistemaFacturacion xmlns="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd">
<Cabecera>
<ObligadoEmision xmlns="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
<NombreRazon>INFORMATICA, S.L.</NombreRazon>
<NIF>B1222222</NIF>
</ObligadoEmision>
<RemisionVoluntaria xmlns="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
<Incidencia>S</Incidencia>
</RemisionVoluntaria>
</Cabecera>
<RegistroFactura>
<RegistroAlta xmlns="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
<IDVersion>1.0</IDVersion>
<IDFactura>
<IDEmisorFactura>B1222222</IDEmisorFactura>
<NumSerieFactura>25F00002</NumSerieFactura>
<FechaExpedicionFactura>01-01-2025</FechaExpedicionFactura>
</IDFactura>
<NombreRazonEmisor>INFORMATICA, S.L.</NombreRazonEmisor>
<TipoFactura>F1</TipoFactura>
<DescripcionOperacion>VENTAS MERCADERIAS</DescripcionOperacion>
<Destinatarios>
<IDDestinatario>
<NombreRazon>GUSTAVO </NombreRazon>
<NIF>1111111Z</NIF>
</IDDestinatario>
</Destinatarios>
<Desglose>
<DetalleDesglose>
<ClaveRegimen>01</ClaveRegimen>
<OperacionExenta>E4</OperacionExenta>
<BaseImponibleOimporteNoSujeto>19.95</BaseImponibleOimporteNoSujeto>
</DetalleDesglose>
</Desglose>
<CuotaTotal>0.00</CuotaTotal>
<ImporteTotal>19.95</ImporteTotal>
<Encadenamiento>
<PrimerRegistro>S</PrimerRegistro>
</Encadenamiento>
<SistemaInformatico>
<NombreRazon>INFORMATICA SL</NombreRazon>
<NIF>B1222222</NIF>
<NombreSistemaInformatico>S</NombreSistemaInformatico>
<IdSistemaInformatico>1</IdSistemaInformatico>
<Version>2025.1</Version>
<NumeroInstalacion>undetermined</NumeroInstalacion>
<TipoUsoPosibleSoloVerifactu>S</TipoUsoPosibleSoloVerifactu>
<TipoUsoPosibleMultiOT>N</TipoUsoPosibleMultiOT>
<IndicadorMultiplesOT>S</IndicadorMultiplesOT>
</SistemaInformatico>
<FechaHoraHusoGenRegistro>2025-02-20T12:32:22+01:00</FechaHoraHusoGenRegistro>
<TipoHuella>01</TipoHuella>
<Huella>67C220CD32CF94DADAE0273B9A53E947E8E44086B335E669E72D66666ACABA</Huella>
</RegistroAlta>
</RegistroFactura>
</RegFactuSistemaFacturacion>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>



La franja horaria es GMT +2. Ahora son las 20:40:07.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi