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)

seccion_31 02-04-2025 20:15:23

Cita:

Empezado por seccion_31 (Mensaje 563362)
esta filtrando con los valores por defecto de multiplesOT, indicador y modosoloverifactu. (añadidos a sistemaInformatico) si los colocas como se enviaron los registros te lo encontrara.

¿Es un tema, que habra que darle una vuelta para poder omitirlos o no en la busqueda por SIF? solucion, tenerlos como caracter para determinar S/N/blanco y asi poder incluirlos o no en el filtro. (o añadir algun indicador para buscar por cada uno de ellos opcionalmente:


filtroModoVerifactu:boolean;
filtroPosiblesMOT :boolean;
filtroIndicadorMOT :boolean;

Esto ira nuevo en la 3.0

me autocito, yo diria que no se pueden suprimir de la busqueda una vez que se activa el SIF.

En la demo se ha enviado registros con valores un poco random, en la 2 los he ajustado a modosoloverifactu=S y los otros dos a false, por tanto es posible que con filtro SIF ya no se vean esos registros.

He eliminado del XML de consulta estos apartados manualmente y el envio me da el error:

<faultstring>Codigo[4102].El XML no cumple el esquema. Falta informar campo obligatorio.: TipoUsoPosibleSoloVerifactu</faultstring>

se admiten ideas. como siempre.

Saludos !

mqm 03-04-2025 10:27:40

Lo he solucionado poniendo:
Código:

  if filtroSIF.checked then
    begin
        // Datos de sistema Informatico:
        VerifactuD7.SistemaInformatico.razonSocial      := editRazonSocial.Text;
        VerifactuD7.SistemaInformatico.nif              := editNIF.Text;
        VerifactuD7.SistemaInformatico.nombre            := editNombre.Text;
        VerifactuD7.SistemaInformatico.ID                := editID.text;
        VerifactuD7.SistemaInformatico.Version          := editVersion.text;
        VerifactuD7.SistemaInformatico.NumeroInstalacion := editInstalacion.text;

        VerifactuD7.SistemaInformatico.TipoUsoPosibleSoloVerifactu:=true;
        VerifactuD7.SistemaInformatico.TipoUsoPosibleMultiOT:=True;   
        VerifactuD7.SistemaInformatico.IndicadorMultiplesOT :=True; 
 
    end;


seccion_31 03-04-2025 11:03:46

Cita:

Empezado por mqm (Mensaje 563371)
Lo he solucionado poniendo:
Código:

  if filtroSIF.checked then
    begin
        // Datos de sistema Informatico:
        VerifactuD7.SistemaInformatico.razonSocial      := editRazonSocial.Text;
        VerifactuD7.SistemaInformatico.nif              := editNIF.Text;
        VerifactuD7.SistemaInformatico.nombre            := editNombre.Text;
        VerifactuD7.SistemaInformatico.ID                := editID.text;
        VerifactuD7.SistemaInformatico.Version          := editVersion.text;
        VerifactuD7.SistemaInformatico.NumeroInstalacion := editInstalacion.text;

        VerifactuD7.SistemaInformatico.TipoUsoPosibleSoloVerifactu:=true;
        VerifactuD7.SistemaInformatico.TipoUsoPosibleMultiOT:=True;   
        VerifactuD7.SistemaInformatico.IndicadorMultiplesOT :=True; 
 
    end;


esos son tus valores de envio, de cuando la DEMO enviaba sin preocuparse, por defecto verifactu colocaba esos valores. que no aparecen en rojo ni obligatorios en la hoja de caculo, pero que evidentemente creo que hay que enviar.

Ahora la demo pone modo verifactu a true, y los dos OT a false. (que es lo normal que hace la demo, 1 solo OT y modo soloverifactu)

Hay que ajustar BIEN esos valores en la aplicacion real. Antes de comenzar a enviar.

Saludos !

mqm 03-04-2025 11:39:16

¿Alguien se ha planteado o sabe cómo pasar la dll a unit?
Estoy enfocando todo a un proceso externo en Delphi 10.1 y me es más cómodo usar la unidad original, pero no tengo ni idea de cómo hacerlo.

seccion_31 03-04-2025 13:19:42

Cita:

Empezado por mqm (Mensaje 563375)
¿Alguien se ha planteado o sabe cómo pasar la dll a unit?
Estoy enfocando todo a un proceso externo en Delphi 10.1 y me es más cómodo usar la unidad original, pero no tengo ni idea de cómo hacerlo.

tienes una unidad de tipos (comun)
otra de funciones. (DLL)
otra con el componente (que importa de la anterior via DLL)


crea una unidad copia del componente para crearte un TVeriFactu alternativo
usa la unidad de funciones
elimina las importaciones a la DLL (de esa copia que acabas de hacer)
haz que llamen directo, quizas tengas que ajustar algo, nombres o asi.

y listo.

ese es el plan mas sencillo que se me ocurre. Seguiras teniendo un componente alternativo TVeriFactu que no necesitara la DLL.

Saludos !

Neftali [Germán.Estévez] 03-04-2025 13:29:35

2 Archivos Adjunto(s)
Cita:

Empezado por mqm (Mensaje 563315)
El problema lo tienes en la unit QuricolAPI.pas. Puedes omitir la generación del QR e intentar compilarlo con delphi 12.

Cita:

Empezado por Galahad (Mensaje 563307)
Estoy intentando compilar el proyecto verifactuformd7 en delphi 12.1 y crea un ejecutable, pero no válido,, aparece el error:

'No se encuentra el punto de entrada del procedimiento setbackgroundcolor en la biblioteca de vinculos dinamicos verifactuformd7.exe'
es compatible el proyecto con delphi 12.1 ¿?

Yo para probar, lo he compilado con Delphi 12.3 y con pocos cambios parece que funciona.
No he hecho grandes cosas, porque hasta ahora estaba desconectado del funcionamiento, pero al menos la pantalla principal carga y "hace cosas".

1) Descargar la versión actualizada de los ficheros desde aquí y sustituir los que hay (Quricol.inc, QuricolAPI.pas, QuricolCode.pas).
https://github.com/perevoznyk/qurico.../Delphi/Source
2) Generar la unit SistemaFacturacion.pas (para Delphi 12); La adjunto al mensaje.
3) Añadir condicionales a uVerifactuFuncs.pas para algunas firmas de procedimientos que han cambiado. Lo adjunto al mensaje.

Lo dicho. con esto compila.
Habrá que ver si todo funciona. No me he dedicado a realizar pruebas porque no se muy bien como va.

NOTA: La DLL también está compilada con la 12.3

seccion_31 03-04-2025 14:06:40

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 563393)
Yo para probar, lo he compilado con Delphi 12.3 y con pocos cambios parece que funciona.
No he hecho grandes cosas, porque hasta ahora estaba desconectado del funcionamiento, pero al menos la pantalla principal carga y "hace cosas".

1) Descargar la versión actualizada de los ficheros desde aquí y sustituir los que hay (Quricol.inc, QuricolAPI.pas, QuricolCode.pas).
https://github.com/perevoznyk/qurico.../Delphi/Source
2) Generar la unit SistemaFacturacion.pas (para Delphi 12); La adjunto al mensaje.
3) Añadir condicionales a uVerifactuFuncs.pas para algunas firmas de procedimientos que han cambiado. Lo adjunto al mensaje.

Lo dicho. con esto compila.
Habrá que ver si todo funciona. No me he dedicado a realizar pruebas porque no se muy bien como va.

NOTA: La DLL también está compilada con la 12.3

Neftali [Germán.Estévez] puedo añadir los cambios a la version actual y asi mantener la compatibilidad en adelante, lass dudas que tengo son:

¿SistemaFacturacion.pas es compatible con las anteriores versiones de delphi ?

entiendo que la DLL de QuricolCode sera la misma....

gracias y Saludos !

Neftali [Germán.Estévez] 03-04-2025 15:02:45

He seguido haciendo alguna prueba más y llego a obtener el error de "S240015 Incorrecto 3000 Registro de facturación duplicado.", por lo tanto creo que ha llegado a realizar el envío y ha obtenido la respuesta de error.

Neftali [Germán.Estévez] 03-04-2025 15:09:35

Cita:

Empezado por seccion_31 (Mensaje 563395)
Neftali [Germán.Estévez] puedo añadir los cambios a la version actual y asi mantener la compatibilidad en adelante, lass dudas que tengo son:
¿SistemaFacturacion.pas es compatible con las anteriores versiones de delphi ?
entiendo que la DLL de QuricolCode sera la misma....
gracias y Saludos !

La DLL de QRuiCol parece que funciona, porque me ha generado un QR que parece correcto, y almacena la URL.
El fichero <SistemaFacturacion.pas> tengo dudas de que sea compatible, porque normalmente los nuevos Delphi generan ficheros con tipos no existentes en los antiguos. Tengo un Delphi 7 por alguna máquina virtual. Déjame que lo pruebe y veo a ver cómo se comporta y cómo se puede integrar.

seccion_31 03-04-2025 15:12:24

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 563400)
La DLL de QRuiCol parece que funciona, porque me ha generado un QR que parece correcto, y almacena la URL.
El fichero <SistemaFacturacion.pas> tengo dudas de que sea compatible, porque normalmente los nuevos Delphi generan ficheros con tipos no existentes en los antiguos. Tengo un Delphi 7 por alguna máquina virtual. Déjame que lo pruebe y veo a ver cómo se comporta y cómo se puede integrar.


el sistemafacturacion.pas debe compilar en D10, lo pruebo yo. gracias !

ramherfer 03-04-2025 17:35:09

Hola buenas tardes y disculpar mi torpeza.
Estoy revisando todo el tema de encadenamiento y acabo de caer en el asunto y creo que lo estoy haciendo incorrectamente en algunos casos (subsanación). A ver si por favor alguien me echa un cablecillo.

Tengo en el sif los siguientes registros:

Código:

FA250090 29/03/2025 Aceptado                                                ENCADENAMIENTO FA250089
FA250079 28/03/2025 Aceptado                      SUBSANACION          ENCADENAMIENTO FA250078 <----- ¿?
FA250089 29/03/2025 Aceptado                                                ENCADENAMIENTO FA250088
FA250088 29/03/2025 Aceptado                                                ENCADENAMIENTO FA250087
FA250087 29/03/2025 Aceptado                                                ENCADENAMIENTO FA250086
FA250086 29/03/2025 Aceptado                                                ENCADENAMIENTO FA250085
FA250085 29/03/2025 Aceptado                                                ENCADENAMIENTO FA250084
FA250084 29/03/2025 Aceptado                                                ENCADENAMIENTO FA250083
FA250083 29/03/2025 Aceptado                                                ENCADENAMIENTO FA250082
FA250082 29/03/2025 Aceptado                                                ENCADENAMIENTO FA250081
FA250081 29/03/2025 Aceptado                                                ENCADENAMIENTO FA250080
FA250080 28/03/2025 Aceptado                                                ENCADENAMIENTO FA250079
FA250079 28/03/2025 AceptadoConErrores                                        ENCADENAMIENTO FA250078        <---
FA250078 28/03/2025 Aceptado                                                ENCADENAMIENTO FA250077

La factura FA250079 la aceptan con errores y al día siguiente habiendo revisado el problema la subsano, al estar revisando el registro hoy con las pruebas realizadas, creo que las dos últimas incluida la de subsanación lo tengo, mal no, peor. Estoy en lo cierto verdad?
Un saludo,

bmfranky 03-04-2025 17:39:58

Cita:

Empezado por ramherfer (Mensaje 563405)
Hola buenas tardes y disculpar mi torpeza.
Estoy revisando todo el tema de encadenamiento y acabo de caer en el asunto y creo que lo estoy haciendo incorrectamente en algunos casos (subsanación). A ver si por favor alguien me echa un cablecillo.

Tengo en el sif los siguientes registros:

Código:

FA250090 29/03/2025 Aceptado                                        ENCADENAMIENTO FA250079 con los datos de subsanacion
FA250079 28/03/2025 Aceptado                      SUBSANACION          ENCADENAMIENTO FA250078 <----- ¿? No ,ha de encadenar con el anterior con el n89
FA250089 29/03/2025 Aceptado                                        ENCADENAMIENTO FA250088
FA250088 29/03/2025 Aceptado                                        ENCADENAMIENTO FA250087
FA250087 29/03/2025 Aceptado                                        ENCADENAMIENTO FA250086
FA250086 29/03/2025 Aceptado                                        ENCADENAMIENTO FA250085
FA250085 29/03/2025 Aceptado                                        ENCADENAMIENTO FA250084
FA250084 29/03/2025 Aceptado                                        ENCADENAMIENTO FA250083
FA250083 29/03/2025 Aceptado                                        ENCADENAMIENTO FA250082
FA250082 29/03/2025 Aceptado                                        ENCADENAMIENTO FA250081
FA250081 29/03/2025 Aceptado                                        ENCADENAMIENTO FA250080
FA250080 28/03/2025 Aceptado                                        ENCADENAMIENTO FA250079
FA250079 28/03/2025 AceptadoConErrores                                ENCADENAMIENTO FA250078    <---
FA250078 28/03/2025 Aceptado                                        ENCADENAMIENTO FA250077

La factura FA250079 la aceptan con errores y al día siguiente habiendo revisado el problema la subsano, al estar revisando el registro hoy con las pruebas realizadas, creo que las dos últimas incluida la de subsanación lo tengo, mal no, peor. Estoy en lo cierto verdad?
Un saludo,


Tiene que diferenciar los registros enviados , de las facturas a las que pertenecen, no es lo mismo, siempre ha de encadenar con lo enviado en el registro anterior, independientemente de su contenido.

ramherfer 03-04-2025 17:49:06

Cita:

Empezado por bmfranky (Mensaje 563406)
Tiene que diferenciar los registros enviados , de las facturas a las que pertenecen, no es lo mismo, siempre ha de encadenar con lo enviado en el registro anterior, independientemente de su contenido.

Con este tema, no termino bien, ya te lo digo.

Muchas gracias!!!

seccion_31 03-04-2025 17:58:08

Cita:

Empezado por ramherfer (Mensaje 563408)
Con este tema, no termino bien, ya te lo digo.

Muchas gracias!!!

En este hilo nos lo explicaron a todos. (entre ellos a mi), por eso se colocó el registroinicial y se anulo el envio de factura anterior.

En la ayuda.txt del componente cuando se añadió el registroinicial lo explique.

A mi me costo entenderlo, pero el encadenamiento es un dato tuyo, que encadena con el registro anterior del mismo OT (y SIF, segun instalacion). y ya. Cronologicamente hablando. Para mi mucho mas simple.

Saludos !

ramherfer 05-04-2025 11:25:46

Buenos días.
Estoy con la versión 2.1 y el tema de encadenamientos y tengo el siguiente problema:
Código Delphi [-]
      FacturasEnviadas.Last;
      VeriFactuD7.addRegistroInicial(facturasEnviadas.fieldbyName('NumSerieFactura').text, facturasEnviadas.fieldbyName('FechaExpedicioFactura').text, facturasEnviadas.fieldbyName('huella').text);

Me pone como encadenamiento una factura que está a mitad de facturas.xml (no la última enviada) y al hacer el envío me lo rechazan dado que en NumeroSerieFactura está poniendo en lugar de la serie de factura la huella.

No se si solo me está pasando a mi o alguien más a tenido problemas con esto.

Un saludo,

seccion_31 05-04-2025 12:02:28

Bdias !
Funciona correctamente. De echo hoy he estado enviando. :)

Ahora bien..., estás usando la demo con algun fin?? Fuera del de servir de demostrativo?

Porque el encadenamiento inicial en la demo no es que me preocupe mucho. Voy a la última enviada y ya, pero igual los datos están regular cargados ahí. Y tendría que revisarlo.

Entiendo que para tu programa estás escribiendo código y no sirviéndote de la demo como tal, porque si es así no creo que sea buena idea.

Revisaré la demo.

Saludos !

ramherfer 05-04-2025 12:36:55

Cita:

Empezado por seccion_31 (Mensaje 563458)
Bdias !
Funciona correctamente. De echo hoy he estado enviando. :)

Ahora bien..., estás usando la demo con algun fin?? Fuera del de servir de demostrativo?

Porque el encadenamiento inicial en la demo no es que me preocupe mucho. Voy a la última enviada y ya, pero igual los datos están regular cargados ahí. Y tendría que revisarlo.

Entiendo que para tu programa estás escribiendo código y no sirviéndote de la demo como tal, porque si es así no creo que sea buena idea.

Revisaré la demo.

Saludos !

No la estoy de forma que la app envie los datos. El encadenamiento que estaba haciendo era erróneo y he querido utilizar el de la demo con esas dos instrucciones, pero me ha extrañado mucho que me asignara mal la factura anterior, ya que más simple no puede ser con el codigo de la demo. Cierto es que tengo rectificativas con distintas series, es decir, Facturas xml tiene numeros de serie FA00000, RF00000 y la última se me va a la última RF que está a mitad de tabla ya que es una rectificativa de prueba que hice hace unos días. Voy a realizar una prueba eliminando los registros RF de rectificativas.

seccion_31 05-04-2025 12:41:20

Cita:

Empezado por ramherfer (Mensaje 563461)
No la estoy de forma que la app envie los datos. El encadenamiento que estaba haciendo era erróneo y he querido utilizar el de la demo con esas dos instrucciones, pero me ha extrañado mucho que me asignara mal la factura anterior, ya que más simple no puede ser con el codigo de la demo.

Si, En principio es mucho más sencillo

Vas a la última factura o ticket generada y enviada y cargas los datos del registro inicial después añades tu factura o ticket y envías. No hay más.

Que la demo en facturas.xml tenga los datos mal puede ser.

Quizás tenga algún índice activo que habrá que quitar. No me acuerdo.

Reviso la demo.

ramherfer 05-04-2025 13:29:39

Cita:

Empezado por seccion_31 (Mensaje 563462)
Si, En principio es mucho más sencillo

Vas a la última factura o ticket generada y enviada y cargas los datos del registro inicial después añades tu factura o ticket y envías. No hay más.

Que la demo en facturas.xml tenga los datos mal puede ser.

Quizás tenga algún índice activo que habrá que quitar. No me acuerdo.

Reviso la demo.

Creo que el problema está en las series, ya que según esto:

Código Delphi [-]
      // cargar el archivo xml de facturas ya enviadas
      FacturasEnviadas.LoadFromFile( xmlFacturas );
      FacturasEnviadas.IndexFieldNames:='Emisor;NumSerieFactura';
      FacturasEnviadas.Active:=true;

lo esta haciendo bien por lógica ya que de un mismo emisor, la serie FA250092 (que es la anterior que debía seleccionar) está antes que la RF250003 que es la última y la que seleciona como factura anterior. Pero erróneo en la práctica ya que la anterior debiera ser la FA250092.

seccion_31 05-04-2025 13:36:33

Cita:

Empezado por ramherfer (Mensaje 563463)
Creo que el problema está en las series, ya que según esto:

Código Delphi [-]
      // cargar el archivo xml de facturas ya enviadas
      FacturasEnviadas.LoadFromFile( xmlFacturas );
      FacturasEnviadas.IndexFieldNames:='Emisor;NumSerieFactura';
      FacturasEnviadas.Active:=true;

lo esta haciendo bien por lógica ya que de un mismo emisor, la serie FA250092 (que es la anterior que debía seleccionar) está antes que la RF250003 que es la última y la que seleciona como factura anterior. Pero erróneo en la práctica ya que la anterior debiera ser la FA250092.

correcto, elimina la linea FacturasEnviadas.IndexFieldNames:='Emisor;NumSerieFactura'; y listo. en la practica ira a la ultima generada/enviada cronologicamente independiemente de su serie/numero. (la demo solo permite un emisor/OT.)



En la version 3, esa linea ya no estara.

Saludos !

entiendo que sin esa linea el encadenamiento esta correcto, huella y demas?

ramherfer 05-04-2025 13:48:17

Cita:

Empezado por seccion_31 (Mensaje 563464)
correcto, elimina la linea FacturasEnviadas.IndexFieldNames:='Emisor;NumSerieFactura'; y listo. en la practica ira a la ultima generada/enviada cronologicamente independiemente de su serie/numero. (la demo solo permite un emisor/OT.)



En la version 3, esa linea ya no estara.

Saludos !

entiendo que sin esa linea el encadenamiento esta correcto, huella y demas?

de momento no. la última que tengo en facturas.xml está rechazada y no tiene huella, estoy probando con esa línea de definición del indice eliminada, pero en la primera prueba no "parece" estar funcionando bien

seccion_31 05-04-2025 14:16:18

La demo no se cómo se comporta con facturas no aceptadas y huellas. En su envío, luego lo miro

Elimina facturas.xml y comienza otras pruebas

Saludos

seccion_31 05-04-2025 16:05:00

La demo solo coloca y añade la huella en las facturas enviadas OK. El resto lo ignorara en su BD xml.

He tenido que modificar un poco el programa demo para que lo ordene cronologicamente bien. y envie como huella anterior la ultima aceptada. (que en una aplicacion real, seria la ultima generada).

Como digo es una demo.

Estas modificaciones iran en la version 3.0

seccion_31 05-04-2025 16:45:20

donde si tiene un error es en la anulacion (DLL)


en la 3.0 estara corregido


pero si quereis corregirlo ya:


uverifactuFuncs.pas (D10):


reemplazar esta funcion:


Código:

function anulacionfactura_verifactu(sesion:integer; cabecera:TVeriFactuInicio; indice:integer):RegistroFacturaType;
var
    Factura            : RegistroFacturaType;
    Destinatario        : PersonaFisicaJuridicaType;
    ListaDestinatarios  : Destinatarios;
    ListaDesglose      : DesgloseType;
    DetalleDesglose    : DetalleType;
    XSDatetime          : TXSDatetime;

    j:integer;
    _huellaAnterior    : string;
    facturaRegistro    : TRegistrofactura;
begin
    facturaRegistro:=sesiones[sesion].facturas[indice];

    Factura := RegistroFacturaType.Create;

    Factura.RegistroAnulacion            := RegistroAnulacion.Create;
    Factura.RegistroAnulacion.IDVersion  := VersionType._1_0;

    Factura.RegistroAnulacion.IDFactura                              := IDFacturaExpedidaBajaType.Create;
    Factura.RegistroAnulacion.IDFactura.IDEmisorFacturaAnulada        := cabecera.emisor.nifEmisor;
    Factura.RegistroAnulacion.IDFactura.NumSerieFacturaAnulada        := facturaRegistro.numSerieFactura;
    Factura.RegistroAnulacion.IDFactura.FechaExpedicionFacturaAnulada := verifactuFecha( facturaRegistro.fechafactura ) ; // (dd-mm-yyyy)


    // Encadenamiento
    Factura.RegistroAnulacion.Encadenamiento := Encadenamiento2.Create;

    // ¿ es el primer registro ?
    if sesiones[sesion].facturas[indice-1].huella='' then Factura.RegistroAnulacion.Encadenamiento.PrimerRegistro:=PrimerRegistroCadenaType(0) // S
    else
    begin
          Factura.RegistroAnulacion.Encadenamiento.RegistroAnterior:=EncadenamientoFacturaAnteriorType.Create;

          Factura.RegistroAnulacion.Encadenamiento.RegistroAnterior.IDEmisorFactura        :=cabecera.emisor.nifEmisor;
          Factura.RegistroAnulacion.Encadenamiento.RegistroAnterior.NumSerieFactura        :=sesiones[sesion].facturas[indice-1].numSerieFactura;
          Factura.RegistroAnulacion.Encadenamiento.RegistroAnterior.FechaExpedicionFactura  :=sesiones[sesion].facturas[indice-1].fechaFactura;
          Factura.RegistroAnulacion.Encadenamiento.RegistroAnterior.Huella                  :=sesiones[sesion].facturas[indice-1].huella;
    end;

    // Sin registro previo: (anulacion de facturas fuera de verifactu)
    if sesiones[sesion].facturas[indice].sinregistroPrevio then
          Factura.RegistroAnulacion.SinRegistroPrevio:=SinRegistroPrevioType.S;

    // sistemaInformatico
    sistemaInformatico( cabecera, Factura );

    //XSDatetime
    XSDatetime := TXSDatetime.Create;
    XSDatetime.UseZeroMilliseconds := False;
    XSDatetime.AsDateTime := Now;
    XSDatetime.Millisecond := 0;
    XSDatetime.UseZeroMilliseconds := False;
    XSDatetime.FractionalSeconds := 0;
    Factura.RegistroAnulacion.FechaHoraHusoGenRegistro := XSDatetime; // Formato: YYYY-MM-DDThh:mm:ssTZD (ej: 2024-01-01T19:20:30+01:00) (ISO 8601)

    // Huella
    facturaRegistro.Huella  := GenerarHuella_anulacion_RegistroVerifactu( Factura.RegistroAnulacion );
    sesiones[sesion].facturas[indice].huella:=facturaRegistro.Huella;

    Factura.RegistroAnulacion.TipoHuella := TipoHuellaType._01;
    Factura.RegistroAnulacion.Huella    := facturaRegistro.Huella;

    // fin, devolver el objeto  RegistroFacturacionAnulacionType  creado desde la informacion contenida en el record TRegistroFactura (ver utiles.pas)
    result:=factura;
end;


ramherfer 05-04-2025 17:42:19

Cita:

Empezado por seccion_31 (Mensaje 563468)
donde si tiene un error es en la anulacion (DLL)


en la 3.0 estara corregido


pero si quereis corregirlo ya:


uverifactuFuncs.pas (D10):


reemplazar esta funcion:


Código:

function anulacionfactura_verifactu(sesion:integer; cabecera:TVeriFactuInicio; indice:integer):RegistroFacturaType;
var
    Factura            : RegistroFacturaType;
    Destinatario        : PersonaFisicaJuridicaType;
    ListaDestinatarios  : Destinatarios;
    ListaDesglose      : DesgloseType;
    DetalleDesglose    : DetalleType;
    XSDatetime          : TXSDatetime;

    j:integer;
    _huellaAnterior    : string;
    facturaRegistro    : TRegistrofactura;
begin
    facturaRegistro:=sesiones[sesion].facturas[indice];

    Factura := RegistroFacturaType.Create;

    Factura.RegistroAnulacion            := RegistroAnulacion.Create;
    Factura.RegistroAnulacion.IDVersion  := VersionType._1_0;

    Factura.RegistroAnulacion.IDFactura                              := IDFacturaExpedidaBajaType.Create;
    Factura.RegistroAnulacion.IDFactura.IDEmisorFacturaAnulada        := cabecera.emisor.nifEmisor;
    Factura.RegistroAnulacion.IDFactura.NumSerieFacturaAnulada        := facturaRegistro.numSerieFactura;
    Factura.RegistroAnulacion.IDFactura.FechaExpedicionFacturaAnulada := verifactuFecha( facturaRegistro.fechafactura ) ; // (dd-mm-yyyy)


    // Encadenamiento
    Factura.RegistroAnulacion.Encadenamiento := Encadenamiento2.Create;

    // ¿ es el primer registro ?
    if sesiones[sesion].facturas[indice-1].huella='' then Factura.RegistroAnulacion.Encadenamiento.PrimerRegistro:=PrimerRegistroCadenaType(0) // S
    else
    begin
          Factura.RegistroAnulacion.Encadenamiento.RegistroAnterior:=EncadenamientoFacturaAnteriorType.Create;

          Factura.RegistroAnulacion.Encadenamiento.RegistroAnterior.IDEmisorFactura        :=cabecera.emisor.nifEmisor;
          Factura.RegistroAnulacion.Encadenamiento.RegistroAnterior.NumSerieFactura        :=sesiones[sesion].facturas[indice-1].numSerieFactura;
          Factura.RegistroAnulacion.Encadenamiento.RegistroAnterior.FechaExpedicionFactura  :=sesiones[sesion].facturas[indice-1].fechaFactura;
          Factura.RegistroAnulacion.Encadenamiento.RegistroAnterior.Huella                  :=sesiones[sesion].facturas[indice-1].huella;
    end;

    // Sin registro previo: (anulacion de facturas fuera de verifactu)
    if sesiones[sesion].facturas[indice].sinregistroPrevio then
          Factura.RegistroAnulacion.SinRegistroPrevio:=SinRegistroPrevioType.S;

    // sistemaInformatico
    sistemaInformatico( cabecera, Factura );

    //XSDatetime
    XSDatetime := TXSDatetime.Create;
    XSDatetime.UseZeroMilliseconds := False;
    XSDatetime.AsDateTime := Now;
    XSDatetime.Millisecond := 0;
    XSDatetime.UseZeroMilliseconds := False;
    XSDatetime.FractionalSeconds := 0;
    Factura.RegistroAnulacion.FechaHoraHusoGenRegistro := XSDatetime; // Formato: YYYY-MM-DDThh:mm:ssTZD (ej: 2024-01-01T19:20:30+01:00) (ISO 8601)

    // Huella
    facturaRegistro.Huella  := GenerarHuella_anulacion_RegistroVerifactu( Factura.RegistroAnulacion );
    sesiones[sesion].facturas[indice].huella:=facturaRegistro.Huella;

    Factura.RegistroAnulacion.TipoHuella := TipoHuellaType._01;
    Factura.RegistroAnulacion.Huella    := facturaRegistro.Huella;

    // fin, devolver el objeto  RegistroFacturacionAnulacionType  creado desde la informacion contenida en el record TRegistroFactura (ver utiles.pas)
    result:=factura;
end;


En la anulación me devuelve esto

Código:

<Encadenamiento>
<RegistroAnterior>
<IDEmisorFactura>25000000Z</IDEmisorFactura>
<NumSerieFactura>37734AAA13D8E2D74A4FBDDAD7B34C4EA026C3112A80334FFEDC500ADFDE0128</NumSerieFactura>
<FechaExpedicionFactura>04/04/2025</FechaExpedicionFactura>
<Huella>37734AAA13D8E2D74A4FBDDAD7B34C4EA026C3112A80334FFEDC500ADFDE0128</Huella>
</RegistroAnterior>
</Encadenamiento>

he comprobado y en VerifactuD7.addRegistroInicial(factura,fecha,huella)
Le estoy pasando los parametros correctos, pero la simulación me graba esos datos en el registro de anulación. Estoy dando de baja una factura enviada ayer.

En las altas funciona bien.

seccion_31 06-04-2025 07:41:02

Cita:

Empezado por ramherfer (Mensaje 563470)
En la anulación me devuelve esto

Código:

<Encadenamiento>
<RegistroAnterior>
<IDEmisorFactura>25000000Z</IDEmisorFactura>
<NumSerieFactura>37734AAA13D8E2D74A4FBDDAD7B34C4EA026C3112A80334FFEDC500ADFDE0128</NumSerieFactura>
<FechaExpedicionFactura>04/04/2025</FechaExpedicionFactura>
<Huella>37734AAA13D8E2D74A4FBDDAD7B34C4EA026C3112A80334FFEDC500ADFDE0128</Huella>
</RegistroAnterior>
</Encadenamiento>

he comprobado y en VerifactuD7.addRegistroInicial(factura,fecha,huella)
Le estoy pasando los parametros correctos, pero la simulación me graba esos datos en el registro de anulación. Estoy dando de baja una factura enviada ayer.

En las altas funciona bien.

con la correccion que envie sobre la DLL deberia quedar solucionado. Usando la demo hice una baja sin problema. Estaba enviado como se ve en tu registro la huella como numserie.

slds

ramherfer 07-04-2025 16:26:53

Cita:

Empezado por seccion_31 (Mensaje 563475)
con la correccion que envie sobre la DLL deberia quedar solucionado. Usando la demo hice una baja sin problema. Estaba enviado como se ve en tu registro la huella como numserie.

slds

Correcto con la corrección la anulación funciona correctamente.
¡Gracias!

seccion_31 08-04-2025 08:30:46

nueva version 3.0

En espera de su publicacion

Cita:

> Nota general:



ATENCION:
Con cada cambio, aseguraos que la unidad del componente en delphi 7 es recompilada, de lo contrario tendreis una unidad TVerifactu
desactualizada contra una DLL que usa tipos distintos, por tanto dara errores de proteccion general.


version 3.0
----------------------------------------------------------------------------------------------------------------------------
Se reducen las sesiones de 10 a 6.

Nuevo:

Tras el envio, y/o en el evento es posible consultar el resultado de la automatizacion:

TRegistroFacturaStatus=record
exenta :boolean; <- hay valores en record de exentas
canarias :boolean; <- ha sido clasificada como canarias, ceuta, o melilla
sujetopasivo:boolean; <- ha sido marcada como sujeto pasivo
cee :boolean; <- ha sido enviada como cee
exporta :boolean; <- ha sido enviada como exportacion
end;

por ejemplo:

if resultado.facturas[1].status.canarias then ....



En consultas ahora se devuelve correctamente CLIENTENIF cuando se trata de una factura con IDOtro. (exportacion y cee)

Modificada incidencia de string a boolean en el resultado de consulta por cada factura.

Añadida informacion sobre incidencia, en el resultado de facturas tras un envio:

Por cada factura, se devuelve el campo incidencia informado SOLO para esa factura (que afectara a todo el envio), en el elemento del array de cada factura
En el conjunto del envio, el campo incidenciaEnvio ya que se informo al menos 1 factura con incidencia ese "pack" de envio.


---> Evento para recibir las facturas consultadas:

TRegistroConEvent = procedure( Sender: TObject; resultadoConsulta:TConsultaCallBack ) of object;

Permite recibir mas alla de las 1000 facturas contenidas en el array, hasta las 10.000 de la primera pagina de la AEAT
Todavia se mantiene la recepcion de las 1000 primeras via array, pero se puede implementar el evento.

La Demo D7 se ha actualizado para mostrar el uso de eventos, con una pestaña nueva.

Se pueden enviar 1000 facturas, con descripcion de operacion de 500 digitos.

En la consulta, la descripcion de operacion recibida/consultada se reduce a 255 digitos, tanto por evento como por array.


---> Evento para recibir el resultado de las facturas enviadas:

Permite recibir factura a factura en un evento su estado tras el envio
Todavia se mantiene el array del resultado de facturas enviadas, pero ademas se puede implementar el evento.

TRegistroResEvent = procedure( Sender: TObject; resultadoEnvio:TResultadoCallBack ) of object;

En la demo hay un ejemplo de implementacion.

Neftali [Germán.Estévez] 08-04-2025 08:54:30

Ya está publicada la versión 3.0 en el FTP del club.

seccion_31 08-04-2025 09:39:58

TRegistroFacturaStatus:

empezamos bien:

para que funcione correctamente el tema del status segun la automatizacion ejecutada por el componente, algo que puede venir bien para documentar el registro, hay que cambiar esto en

la unidad uverifactuFuncs (D10) y recompilar la DLL

El resto de funciones estan correctas. Este cambio y otros apareceran la semana que viene en el 3.1


Código:

procedure clearStatus(sesion, indice:integer);
begin
    sesiones[sesion].status[indice].exenta      :=false;
    sesiones[sesion].status[indice].canarias    :=false;
    sesiones[sesion].status[indice].sujetoPasivo:=false;
    sesiones[sesion].status[indice].cee        :=false;
    sesiones[sesion].status[indice].exporta    :=false;
end;

y

Código:

function altafactura_F1_F2_R4_R5_verifactu( sesion:integer; cabecera:TVeriFactuInicio; indice:integer ): RegistroFacturaType;
var
    Factura            : RegistroFacturaType;
    Destinatario        : PersonaFisicaJuridicaType;
    ListaDestinatarios  : Destinatarios2;
    ListaDesglose      : DesgloseType;
    DetalleDesglose    : DetalleType;
    XSDatetime          : TXSDatetime;

    FacturaRegistro    : TRegistroFactura;

    rectificadasArray  :  FacturasRectificadas2;
    rectificada        :  IDFacturaARType;

    j:integer;
begin
    FacturaRegistro:=sesiones[sesion].facturas[indice];
    clearStatus(sesion, indice);

    Factura := RegistroFacturaType.Create;

    Factura.RegistroAlta            := RegistroAlta.Create;
    Factura.RegistroAlta.IDVersion  := SistemaFacturacion.VersionType(0);


    Factura.RegistroAlta.NombreRazonEmisor                := cabecera.emisor.NombreRazonEmisor;
    Factura.RegistroAlta.IDFactura                        := IDFacturaExpedidaType.Create;
    Factura.RegistroAlta.IDFactura.IDEmisorFactura        := cabecera.emisor.nifEmisor;

    Factura.RegistroAlta.IDFactura.NumSerieFactura        := facturaRegistro.numSerieFactura;
    Factura.RegistroAlta.IDFactura.FechaExpedicionFactura := verifactuFecha( facturaRegistro.fechafactura ) ; // (dd-mm-yyyy)
    Factura.RegistroAlta.DescripcionOperacion            := facturaRegistro.DescripcionOperacion;

    if facturaRegistro.subsanacion then
        Factura.RegistroAlta.Subsanacion:=SubsanacionType.S;

    if facturaRegistro.rechazoPrevioExiste then
        Factura.RegistroAlta.RechazoPrevio:=RechazoPrevioType.S;

    if facturaRegistro.rechazoPrevioNoExiste then
        Factura.RegistroAlta.RechazoPrevio:=RechazoPrevioType.X;

    if facturaRegistro.refExterna<>'' then  // informacion libre
        Factura.RegistroAlta.RefExterna := facturaRegistro.refExterna;

    // 1 destinatario (cliente):
    if facturaRegistro.clienteNIF<>'' then        // es una factura con destinatario TIPO F1
    begin
        if facturaRegistro.total<0 then
          Factura.RegistroAlta.TipoFactura := ClaveTipoFacturaType.R4
        else
          Factura.RegistroAlta.TipoFactura := ClaveTipoFacturaType.F1;

        Destinatario                    := PersonaFisicaJuridicaType.Create;
        Destinatario.NombreRazon        := facturaRegistro.cliente;

        // si no es españa puede ser comunitario o exportacion
        if facturaRegistro.clienteCodPais<>'ES' then
        begin
            Destinatario.IDOtro            := IDOtroType.Create;
            Destinatario.IDOtro.CodigoPais  := verifactu_codigoPais( facturaRegistro.clienteCodPais );

            if facturaRegistro.clientetipoNIF<>'' then
                Destinatario.IDOtro.IdType  := verifactu_tipoNIF  ( facturaRegistro.clientetipoNIF )
            else
            begin
                if CodpaisEuropea(facturaRegistro.clienteCodPais) then
                    Destinatario.IDOtro.IdType :=PersonaFisicaJuridicaIDTypeType._02
                else
                    Destinatario.IDOtro.IdType :=PersonaFisicaJuridicaIDTypeType._06;
            end;
            Destinatario.IDOtro.ID          := facturaRegistro.clienteNIF;
        end
        else
            Destinatario.NIF                := facturaRegistro.clienteNIF;  // España

        // El destinatario (cliente) a la lista  (solo 1 cliente x factura)
        ListaDestinatarios:= destinatarios2.Create();
        SetLength(ListaDestinatarios, 1);
        ListaDestinatarios[0]              := Destinatario;
        Factura.RegistroAlta.Destinatarios  := ListaDestinatarios;
    end
    else        // Es un ticket o factura F2 con el cliente sin identificar
    begin
        if facturaRegistro.total<0 then
            Factura.RegistroAlta.TipoFactura := ClaveTipoFacturaType.R5
        else
            Factura.RegistroAlta.TipoFactura := ClaveTipoFacturaType.F2;

        Factura.RegistroAlta.FacturaSinIdentifDestinatarioArt61d:=CompletaSinDestinatarioType.S;
    end;

    // Desglose de iva y exenciones: (Nacional, Comunitario, o Exportacion)
    ListaDesglose := DesgloseType.Create();

    // Exenciones
    for j:=0 to facturaRegistro.nexentas-1 do      // x cada exencion
    begin
        if (facturaRegistro.exenta[j].baseImp<>0)and(facturaRegistro.exenta[j].tipoExenta<>'') then
        begin
            DetalleDesglose:= DetalleType.Create;

            if facturaRegistro.exenta[j].claveRegimen<>'' then
              DetalleDesglose.ClaveRegimen        :=codigoTrascendencia_verifactu( facturaRegistro.exenta[j].claveRegimen);

            if facturaRegistro.exenta[j].calificacionOperacion<>'' then
              DetalleDesglose.CalificacionOperacion:=codigoCalificacion_verifactu( facturaRegistro.exenta[j].calificacionOperacion );

            DetalleDesglose.OperacionExenta      :=codigoExenta_verifactu(facturaRegistro.exenta[j].tipoExenta);

            DetalleDesglose.BaseImponibleOimporteNoSujeto := NumeroVeriFactu( facturaRegistro.exenta[j].baseImp );

            sesiones[sesion].status[indice].exenta:=true;

            // colocar el desglose en la lista
            SetLength( ListaDesglose, Length(ListaDesglose) +1 );
            ListaDesglose[ High(ListaDesglose ) ] := DetalleDesglose ;
        end;
    end;

    // IVA
    for j:=0 to facturaRegistro.nivas-1 do      // x cada iva:
    Begin
          DetalleDesglose              := DetalleType.Create;

          DetalleDesglose.ClaveRegimen := IdOperacionesTrascendenciaTributariaType._01;

          // Tipo de calificacion y exenta segun pais
          if facturaRegistro.clienteCodPais='ES' then          // España:
          begin
              if not facturaRegistro.canarias then            // Si no es canarias:
              begin
                        // ¿inversion del sujeto pasivo?
                        if NOT facturaRegistro.inversionSujetoPasivo then // Factura Normal
                        begin
                            DetalleDesglose.CalificacionOperacion        := CalificacionOperacionType.S1;

                            DetalleDesglose.TipoImpositivo                := NumeroVeriFactu( facturaRegistro.iva[j].iva );
                            DetalleDesglose.CuotaRepercutida              := NumeroVeriFactu( facturaRegistro.iva[j].impiva );

                            if facturaRegistro.iva[j].req<>0 then  // ¿ lleva recargo de equivalencia ?
                            begin
                                DetalleDesglose.ClaveRegimen                  :=IdOperacionesTrascendenciaTributariaType._18;
                                DetalleDesglose.TipoRecargoEquivalencia      := NumeroVeriFactu( facturaRegistro.iva[j].req );
                                DetalleDesglose.CuotaRecargoEquivalencia      := NumeroVeriFactu( facturaRegistro.iva[j].impreq );
                            end;
                        end
                        else  // Con inversion del sujeto pasivo
                        begin
                            sesiones[sesion].status[indice].sujetopasivo      :=true;
                            DetalleDesglose.CalificacionOperacion        := CalificacionOperacionType.S2;
                            DetalleDesglose.TipoImpositivo                := NumeroVeriFactu( 0 );
                            DetalleDesglose.CuotaRepercutida              := NumeroVeriFactu( 0 );
                        end;
              end
              else  // caso especifico Canarias ceuta y melilla entrega de bienes
              begin
                  DetalleDesglose.ClaveRegimen    := IdOperacionesTrascendenciaTributariaType._02;
                  DetalleDesglose.OperacionExenta  := OperacionExentaType.E2;
              end;
          end
          else  // exportacion o comunidad Europea
          begin
              DetalleDesglose.OperacionExenta:= verifactu_tipoDesglose( facturaRegistro.clienteCodPais );

              if DetalleDesglose.OperacionExenta=OperacionExentaType.E5 then // UE
              begin
                  sesiones[sesion].status[indice].cee:=true;
                  DetalleDesglose.ClaveRegimen := IdOperacionesTrascendenciaTributariaType._01;
              end;

              if DetalleDesglose.OperacionExenta=OperacionExentaType.E2 then // Exportacion fuera de la UE
              begin
                  sesiones[sesion].status[indice].exporta:=true;
                  DetalleDesglose.ClaveRegimen := IdOperacionesTrascendenciaTributariaType._02;
              end;
          end;

          // Base Imponible
          DetalleDesglose.BaseImponibleOimporteNoSujeto := NumeroVeriFactu( facturaRegistro.iva[j].baseImp );

          // colocar el desglose en la lista
          SetLength( ListaDesglose, Length(ListaDesglose) +1 );
          ListaDesglose[ High(ListaDesglose ) ] := DetalleDesglose ;
      end;
      // asignar los desgloses de iva recien creados, al objeto de factura:
      Factura.RegistroAlta.Desglose:= ListaDesglose;

      // totales de factura ¿inversion sujeto pasivo?
      if NOT facturaRegistro.inversionSujetoPasivo then // Factura Normal
      begin
          Factura.RegistroAlta.CuotaTotal  := NumeroVeriFactu(  facturaRegistro.cuotatotal ) ;
          Factura.RegistroAlta.ImporteTotal := NumeroVeriFactu(  facturaRegistro.total );
      end
      else
      begin
          Factura.RegistroAlta.CuotaTotal  := NumeroVeriFactu( 0 );  // inversion sujeto pasivo
          Factura.RegistroAlta.ImporteTotal := NumeroVeriFactu( facturaRegistro.iva[0].baseImp );
      end;


      // factura rectificada: (1 x factura)
      if facturaRegistro.total <0 then
      begin
          setLength(rectificadasArray,1);
          rectificada:=IDFacturaARType.Create;

          rectificada.IDEmisorFactura      :=cabecera.emisor.nifEmisor;
          rectificada.NumSerieFactura      :=facturaRegistro.facturaRectificada;
          rectificada.FechaExpedicionFactura:=facturaRegistro.fechaFacturaRectificada;

          rectificadasArray[0]:=rectificada;

          Factura.RegistroAlta.FacturasRectificadas :=rectificadasArray;
          Factura.RegistroAlta.TipoRectificativa    :=ClaveTipoRectificativaType(1);
      end;

      // Encadenamiento con factura anterior
      Factura.RegistroAlta.Encadenamiento := Encadenamiento3.Create;

      // ¿ es el primer registro ?
      if sesiones[sesion].facturas[indice-1].huella='' then Factura.RegistroAlta.Encadenamiento.PrimerRegistro:=PrimerRegistroCadenaType(0) // S
      else
      begin  // no es el primer registro, colocar encadenamiento anterior
          Factura.RegistroAlta.Encadenamiento.RegistroAnterior:=EncadenamientoFacturaAnteriorType.Create;

          Factura.RegistroAlta.Encadenamiento.RegistroAnterior.IDEmisorFactura        :=cabecera.emisor.nifEmisor;
          Factura.RegistroAlta.Encadenamiento.RegistroAnterior.NumSerieFactura        :=sesiones[sesion].facturas[indice-1].numSerieFactura;
          Factura.RegistroAlta.Encadenamiento.RegistroAnterior.FechaExpedicionFactura  :=sesiones[sesion].facturas[indice-1].fechaFactura;
          Factura.RegistroAlta.Encadenamiento.RegistroAnterior.Huella                  :=sesiones[sesion].facturas[indice-1].huella;
      end;

    // sistemaInformatico
    sistemaInformatico( cabecera, Factura );

    // XSDatetime
    XSDatetime := TXSDatetime.Create;
    XSDatetime.UseZeroMilliseconds := False;
    XSDatetime.AsDateTime := Now;
    XSDatetime.Millisecond := 0;
    XSDatetime.UseZeroMilliseconds := False;
    XSDatetime.FractionalSeconds := 0;


    Factura.RegistroAlta.FechaHoraHusoGenRegistro := XSDatetime; // Formato: YYYY-MM-DDThh:mm:ssTZD (ej: 2024-01-01T19:20:30+01:00) (ISO 8601)

    // Huella
    Factura.RegistroAlta.TipoHuella := TipoHuellaType._01;

    Factura.RegistroAlta.Huella            := GenerarHuella_alta_RegistroVerifactu(sesion,indice,Factura.RegistroAlta);
    sesiones[sesion].facturas[indice].huella:=Factura.RegistroAlta.Huella;

    // fin, devolver el objeto  registroFacturaType.RegistroAlta  creado desde la informacion contenida en el record TRegistroFactura (ver utiles.pas)
    result:=factura;
end;


seccion_31 08-04-2025 11:23:19

Generacion de huella

este es un tema sobre el que tengo dudas.

el componente, genera la huella durante el envio de la factura. Si enviamos en el momento de hacer la factura, no hay problema. La huella generada coincide con la generacion de la factura.

Si la factura no pasa (por motivos tecnicos, fallo de la AEAT o de internet), no se cambia nada de la factura, y se reenvia de nuevo, se generara otra huella con la fecha y hora actualizadas. Que podria diferir del momento de la generacion de la factura.

( Eso si: si la fecha de la factura es distinta a la actual se activara el flag de incidencia, pero con una fecha de generacion de registro actual que NO coincidira con la fecha de la factura )

ramherfer 08-04-2025 18:35:16

Cita:

Empezado por seccion_31 (Mensaje 563529)
Generacion de huella

este es un tema sobre el que tengo dudas.

el componente, genera la huella durante el envio de la factura. Si enviamos en el momento de hacer la factura, no hay problema. La huella generada coincide con la generacion de la factura.

Si la factura no pasa (por motivos tecnicos, fallo de la AEAT o de internet), no se cambia nada de la factura, y se reenvia de nuevo, se generara otra huella con la fecha y hora actualizadas. Que podria diferir del momento de la generacion de la factura.

( Eso si: si la fecha de la factura es distinta a la actual se activara el flag de incidencia, pero con una fecha de generacion de registro actual que NO coincidira con la fecha de la factura )

Habiendo revisado la documentación y teniendo en cuenta que no es un reenvio, sino que en el intento anterior por algún motivo, no pudo hacerlo. La huella debería ser la misma que en el primer intento y debiendo coincidir con el envio que se complete, ya que esa coincidiría la fecha de expedición y la de generación (entrada en nuestro registro SIF - primer intento -). Yo genero el registro SIF pero por motivos ajenos al sistema de facturación, no puedo enviar el registro.

Es como lo entiendo y veo. Por favor corregirme si estoy en un error.
Un saludo,

newtron 08-04-2025 19:59:56

Cita:

Empezado por seccion_31 (Mensaje 563529)
Generacion de huella

este es un tema sobre el que tengo dudas.

el componente, genera la huella durante el envio de la factura. Si enviamos en el momento de hacer la factura, no hay problema. La huella generada coincide con la generacion de la factura.

Si la factura no pasa (por motivos tecnicos, fallo de la AEAT o de internet), no se cambia nada de la factura, y se reenvia de nuevo, se generara otra huella con la fecha y hora actualizadas. Que podria diferir del momento de la generacion de la factura.

( Eso si: si la fecha de la factura es distinta a la actual se activara el flag de incidencia, pero con una fecha de generacion de registro actual que NO coincidira con la fecha de la factura )


Yo creo que, aunque no se pueda enviar la factura por lo que sea, la huella no habría que cambiarla. La factura se ha emitido en un momento determinado y eso no se debería de cambiar. Yo en particular no cambio absolutamente nada de la factura aunque la envíe más tarde, lo único es el parámetro de incidencia si veo que se retrasa más de lo estipulado.


Saludos.

seccion_31 08-04-2025 21:00:07

Cita:

Empezado por newtron (Mensaje 563556)
Yo creo que, aunque no se pueda enviar la factura por lo que sea, la huella no habría que cambiarla. La factura se ha emitido en un momento determinado y eso no se debería de cambiar. Yo en particular no cambio absolutamente nada de la factura aunque la envíe más tarde, lo único es el parámetro de incidencia si veo que se retrasa más de lo estipulado.


Saludos.

si, yo pienso lo mismo. De ahi mis dudas. (gracias)

hare pruebas, en principio se me ha ocurrido:

1) un evento que se enviara al calcular la huella de una factura, asi pase lo que pase, siempre se podra guardar, y/o bien al añadir la factura. (ya hay una funcion sin uso, que podria hacer eso)

(es mas seguro guardar la huella antes del envio, que recogerla tras el envio como se hace ahora)

2) al añadir la factura, se adjunta la huella archivada (lo cual indicaria de facto una incidencia), o no se adjunta, lo cual indicaria que es la primera vez que se intenta enviar, por tanto se enviara el evento.

3) enviar con incidencia o no segun ocurra.

Saludos !

jguso 09-04-2025 04:27:33

capicom
 
como hacemos si no usamos capicom para los certificados, de que forma puedo indicar el certificado y el password para poder transmitir la factura a la aeat.


No hay posibilidad de decirle nombre de certificado y password ?????

seccion_31 09-04-2025 13:35:08

Cita:

Empezado por jguso (Mensaje 563563)
como hacemos si no usamos capicom para los certificados, de que forma puedo indicar el certificado y el password para poder transmitir la factura a la aeat.


No hay posibilidad de decirle nombre de certificado y password ?????

en el nombre del certificado el nombre de archivo .pfx o .p12
en passwordcertificado pues eso.

seccion_31 09-04-2025 13:41:56

Ya esta todo prácticamente modificado. Para que funcione en esos "envios fallidos".

Pero.. una pregunta mas

El encadenamiento de esa factura reenviada, contra que se hace?

¿El encadenamiento original de cuando se genero el registro?

¿o el nuevo encadenamiento del registro anterior?

Saludos !

Neftali [Germán.Estévez] 09-04-2025 13:49:38

Cita:

Empezado por seccion_31 (Mensaje 563529)
Generacion de huella

este es un tema sobre el que tengo dudas.
el componente, genera la huella durante el envio de la factura. Si enviamos en el momento de hacer la factura, no hay problema. La huella generada coincide con la generacion de la factura.

Ya lo hemos hablado.
Yo creo que ese comportamiento es erróneo según la documentación.

Creo que la huella dela factura, los encadenamientos, los QR,... se deben generar en el momento de crear la factura, independientemente de cuando se envíe.
Si por lo que sea el envío no puede hacerse, el sistema debe seguir funcionando de forma "normal".

Perdonad, si no estáis refiriéndoos a esto y estoy "meando fuera de tiesto".

bmfranky 09-04-2025 14:00:28

Fecha a Guardar Encadenamieno
 
Cita:

Empezado por seccion_31 (Mensaje 563588)
Ya esta todo prácticamente modificado. Para que funcione en esos "envios fallidos".

Pero.. una pregunta mas

El encadenamiento de esa factura reenviada, contra que se hace?

¿El encadenamiento original de cuando se genero el registro?

¿o el nuevo encadenamiento del registro anterior?

Saludos !

Cita:

Empezado por Neftali [Germán.Estévez] (Mensaje 563590)
Ya lo hemos hablado.
Yo creo que ese comportamiento es erróneo según la documentación.

Creo que la huella dela factura, los encadenamientos, los QR,... se deben generar en el momento de crear la factura, independientemente de cuando se envíe.
Si por lo que sea el envío no puede hacerse, el sistema debe seguir funcionando de forma "normal".

Perdonad, si no estáis refiriéndoos a esto y estoy "meando fuera de tiesto".


Hola, lo que teneis que tener en cuenta es que el dato

Código:

<FechaHoraHusoGenRegistro>


Se validará que la FechaHoraHusoGenRegistro sea menor o igual que la fecha del sistema
de la AEAT, admitiéndose un margen de error. En caso de superar el umbral, se devolverá un
aviso de error (no generará rechazo).

Significa, Fecha y Hora + Huso Horario "Generacion Registro"
No pide la fechaca hora del envio, el envio puede ser despues, por varios motivos, incluso no haber envio, si estamos en no Verifactu.
Por logica se tiene que guardar en el momento de emitir/crear la factura/registro, no en el momento del envio, tampoco se puede modificar y "Siempre", consultar los datos del ultimo HASH, del encadenamiento para continuar con la cadena, sea de lo que sea, porque si encadenamos las acciones, hemos de encadenar con su cadena independiente a los de registros de facturacion.

Si a lo que te refieres es si se ha de cambiar el encadenamiento , no de ningun modo, el encadenamiento se refiere a cada registro.
Código:

  <RegistroAlta xmlns="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroLR.xsd">
    xxxxx
    xxxxx
</RegistroAlta>

Que puede ser de alta , baja ,etc, esto es lo que hay que encolar, guardar, etc para enviar/ reenviar, con sus datos originales, tanto si se envia al momento , como en diferido.
Asignando en la cabecera , si ha habido algun error, etc...

Espero que entre todos lo dejemos mas claro.

seccion_31 09-04-2025 14:46:19

gracias por las aclaraciones

En la proxima actualizacion sera posible enviar una factura con su huella original y anterior original. si han pasado mas de 2 minutos desde la huella proporcionada, marcara como incidencia ese envio. ¿ ese tiempo de 2 minutos esta bien ?

En principio la forma de trabajar con el componente sería, de forma simplificada.

INICIO

1) hago una factura
2) inmedatamente la envio, (con exito, o no, me da lo mismo, igual que imprimo la envio)
3) obtendre su huella, la archivo en la factura
4) proceso el envio (si es posible, podria ser que no, debido a causas externas, si es posible guardo el csv )

FIN

ADICIONALMENTE:

1) Crear una lista de facturas pendientes de envio
2) Enviarlas en cuanto sea posible, reutilizando esa huella y huella anterior almacenada


Creo que el proceso cumple. Para procesos de facturacion individuales.

Con este tema, creo que queda cerrado ya todos los flecos a falta de probarlo.

Su implementacion en los que lo esten usando sera muy simple.

gracias !

Nota: en mi caso particular, ni pregunto, ni hago pausas, se pulsa el boton de facturar y se envia la factura, despues se imprime. por tanto generacion del registro y envio van de la mano. Si el envio NO se completa, queda archivada la huella que sera reutilizada en su reenvio.


La franja horaria es GMT +2. Ahora son las 12:53:36.

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