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)

ramherfer 25-01-2025 09:41:54

Cita:

Empezado por Quim Herrera (Mensaje 561437)
Hola a todos y muchas gracias a seccion_31 por el aporte

He adaptado el código para ejecutarlo como un servicio. Funciona perfectamente si ejecuto el exe directamente, pero a la que lo intento ejecutar como servicio me da el mismo error:

Código:

(ESOAPHTTPException)-Received content of invalid Content-Type setting: text/html - SOAP expects "text/xml"
Tengo el certificado guardado en Equipo Local ( LocalSystemStore ), el certificado lo encuentra y asigna el número de serie a Httprio, pero da este error hacer el envio.
¿Sabéis si hay que hacer algo más con el certificado para que funcione en un servicio?

Gracias y un saludo

Ojo el servicio no puede buscar certificados en el almacen del usuario, por lo que tendrá que estar instalado a nivel de máquina para que en caso de usar CAPICOM lo busque en CAPICOM_LOCAL_MACHINE_STORE.
en HTTPRIO1HTTPWebNode1BeforePost Estás usando CAPICOM_CURRENT_USER_STORE y debes usar CAPICOM_LOCAL_MACHINE_STORE. Pero cuando tengas el certificado instalado a nivel de máquina no a nivel de usuario.
Espero te sirva

seccion_31 26-01-2025 10:24:46

buenos dias !

Ya tengo disponible una version mas que funcional del componente y servidor de mensajes para D7.

Incluyo la version compilada y codigo fuente del servidor en B10.

Lamentablemente no he podido estar por aqui antes, por motivos personales, pero ahora procurare estar mas atento. especialmente esta semana por si alguien quiere implementarlo.

Lo he tenido que subir a mi google drive porque github no me deja.

https://drive.google.com/file/d/1fKx...usp=drive_link


Aquí no hay milagros, se usa D7 para componer el envío, pero finalmente se transmite atraves de una aplicacion en B10, lo que si es cierto es que mucho mas manejable desde D7.

Se arranca el servidor de mensajes y después de esto, podéis ejecutar la demo (que sube una hoja excel), o empezar desarrollar vuestra aplicacion.

La parte mas imporante es un record que guarda la factura(s), la factura a enviar y la anterior (si existe). El servidor de mensajes se intenta hacer cargo de componer el resto.

Actualmente soporta, facturas, y tickets, y su rectificacion. Ademas se ofrece el control del almacen de certificados, validacion del nif, y el cotejo con la AEAT de los registros enviados.

La cuestión es que hay que probarlo y pulirlo. En teoria es posible utilizarlo con versiones mas alla de D7, directamente sin servidor.

Queda ofrecido aqui como una demostracion, bajo la TOTAL responsabilidad de quien lo utilice.



Saludos cordiales y mucha suerte.

DarkDudae 27-01-2025 07:24:53

Cita:

Empezado por seccion_31 (Mensaje 561440)
buenos dias !

Ya tengo disponible una version mas que funcional del componente y servidor de mensajes para D7.

Incluyo la version compilada y codigo fuente del servidor en B10.

Muchas gracias por el código.
Lo estudiaré en profundidad, pero tiene muy buena pinta. En un principio pensé en hacerme un ejecutable o un servicio completo que fuese mirando en la BD cada X segundos si hay alguna factura nueva a enviar, pero con el tema de generar el QR para los tickets, algo de envío directo con un componente se hace más práctico.

seccion_31 27-01-2025 08:11:54

Buenos dias !

Registro que carga la factura, podeis verlo en la unidad: utiposVerifactu y necesario para añadir las facturas al envio.

Código:

  TRegistroFactura=record
        sesion          :integer;          // no tocar
        nfactura        :integer;          // no tocar


        numSerieFactura :string[60];
        fechaFactura    :string[10];
        alta_baja      :string[1];      // "A"lta, o "B"aja

        DescripcionOperacion:TMyString;

        cliente        :string[120];
        clienteNIF      :string[20];      // 9 (nif) ... 20 (otros docs.)
        clientetipoNIF  :string[2];      // si se deja en blanco se determinara segun el pais
        clienteCodPais  :string[2];      // si se deja en blanco se considerara ES

        canarias        :boolean;        // = true si de canarias

        nivas : integer;
        iva  : array[0..maxivas] of TRegistroFacturaIVAS;

        cuotatotal, total:currency;

        situacion :TMyString;

        huella    :TMyString;

        facturaRectificada      :string[60];  // nº serie factura rectificada
        fechaFacturaRectificada :string[10];  // fecha
    end;

Los campos:

clientetipoNIF :string[2]; // si se deja en blanco se determinara segun el pais
clienteCodPais :string[2]; // si se deja en blanco se considerara ES
canarias :boolean; // = true si de canarias

Son opcionales, es decir si no se envia el clienteTipoNIF se determinara segun el pais, (lista de paises comunitarios o exportacion):

Código:

  country_ue:array[0..26] of string=('DE','AT','BE','BG','CY','HR','DK','SI','ES','EE','FI',
                                'FR','GR','HU','IE','IT','LV','LT','LU','MT','NL','PL',
                                'PT','CZ','SK','RO','SE');

Si no hay pais en clienteCodPais, se considerara ES

y Canarias si es un cliente canario.

La huella en la factura actual la calculara el componente.

Situacion: No se utiliza, que recuerde.

Asi que basicamente es limitarse a cumplimentar los datos basicos de una factura en la factura actual.



En la factura anterior, es identificarla, NO hace falta cargar todos los datos:

Numeroserie
Fecha
Huella

Si la factura anterior se encuentra entre las emitidas del envio, la huella la colocara el componente, solo necesaria si esta fuera del paquete de envio. Por ello una vez transmitida la factura hay que guardar su huella y sobre todo el CSV devuelto.

Saludos !

Neftali [Germán.Estévez] 27-01-2025 08:36:29

Cita:

Empezado por seccion_31 (Mensaje 561440)
Lo he tenido que subir a mi google drive porque github no me deja.
https://drive.google.com/file/d/1fKx...usp=drive_link

He subvido una copia al FTP del club:
http://terawiki.clubdelphi.com/Otros...27_01_2025.rar

ramherfer 28-01-2025 09:15:38

Buenos días.
Como planteais el maldito control de flujo. En una instalacion monopuesto lo tengo, está claro, pero en una instalación multipuesto que funciona al libre albedrio y que cada usuario puede hacer facturas teniendo la misma serie de facturación, ya que los contadores están a nivel de ejercicio me está volviendo loco.
No se si la solución sería cada usuario un SIF distinto, envio independiente de un mismo (OT) y que cada uno envíe y encadene sus registros. Para esto creo que tambien cada usuario debería tener su serie de facturas y su propio servidor de envío.
A ver si me podeis echar un cable, un rayito de luz a esto.
Gracias.
Un saludo.

newtron 28-01-2025 09:48:08

Cita:

Empezado por ramherfer (Mensaje 561475)
Buenos días.
Como planteais el maldito control de flujo. En una instalacion monopuesto lo tengo, está claro, pero en una instalación multipuesto que funciona al libre albedrio y que cada usuario puede hacer facturas teniendo la misma serie de facturación, ya que los contadores están a nivel de ejercicio me está volviendo loco.
No se si la solución sería cada usuario un SIF distinto, envio independiente de un mismo (OT) y que cada uno envíe y encadene sus registros. Para esto creo que tambien cada usuario debería tener su serie de facturas y su propio servidor de envío.
A ver si me podeis echar un cable, un rayito de luz a esto.
Gracias.
Un saludo.


Por si te sirve de algo la solución que yo he montado puede no ser la más elegante pero creo que es bastante simple y efectiva. Al emitirse una factura desde cualquier terminal se crea en una carpeta compartida un fichero .csv con la información de la factura y mi programa "enviador" lo que hace es estar atento a los ficheros que van apareciendo en esa carpeta, los va encolando por orden de llegada y los va enviando y borrando. De esta manera, en caso de problema y que todo se atasque sigo teniendo en la carpeta los ficheros pendientes de enviar.


Saludos.

ramherfer 28-01-2025 10:11:38

Cita:

Empezado por newtron (Mensaje 561477)
Por si te sirve de algo la solución que yo he montado puede no ser la más elegante pero creo que es bastante simple y efectiva. Al emitirse una factura desde cualquier terminal se crea en una carpeta compartida un fichero .csv con la información de la factura y mi programa "enviador" lo que hace es estar atento a los ficheros que van apareciendo en esa carpeta, los va encolando por orden de llegada y los va enviando y borrando. De esta manera, en caso de problema y que todo se atasque sigo teniendo en la carpeta los ficheros pendientes de enviar.


Saludos.

Claro que me sirve, es un comienzo de algo que me trae loco. Esto no se trata de elegancia, si no que sea funcional y funcione. ¡Gracias!

seccion_31 29-01-2025 09:16:11

Buenos dias !

Crear una lista de facturas para enviar, ya sea en un csv u otro medio era tambien mi intencion, hasta la llegada del componente para D7.

Pero con el componente y servidor para D7 la cosa cambia, al menos a mi modo de ver.

Si tienes varios puestos enviando, cada uno arrancara su servidor B10.
Cada terminal cuando haga una factura o ticket puede intentar enviar directamente el documento, sin mas desde D7:

Eso si:

Bloquear el momento de envío. (un Flag comun para todos los terminales)
Enviar los documentos pendientes y el nuevo.
Si lo envia Ok, perfecto, sino pasa a la lista de pendientes. (por el motivo que sea).
Desbloquear envio


Crear un formulario con los pendientes, y lanzarlo manualmente o mediante un timer, que envie.
Cuando el formulario envia, de nuevo se bloquea mediante un flag, para que nadie mas pueda enviar.
Desbloquear cuando se termina de enviar.


Aunque parezca mas farragoso (explicado) pienso que es mas directo, porque todo queda dentro de la aplicación en D7 si se utiliza el componente del que va este hilo.

Saludos

En mi caso tras crear el documento, muestro la pantalla de pendientes, y realizo el envío. Y ya. (no hay mas). Luego le programare un timer, y lo mostrare al iniciar o cerrar la aplicacion.


Cita:

Empezado por ramherfer (Mensaje 561480)
Claro que me sirve, es un comienzo de algo que me trae loco. Esto no se trata de elegancia, si no que sea funcional y funcione. ¡Gracias!


seccion_31 29-01-2025 20:54:19

Una vez enviado es muy sencillo cargar el resultado.

Este es un extracto del ejemplo incluido que carga desde la excel:

Se envia, y se obtiene el resultado en el record resultado
Si no se puede si quiera enviar, devuelve false, si hay envio devuelve true, y en resultado carga lo devuelto por la aeat

Código:

      if VeriFactuD7.envio(resultado) then                          // enviarlo !!
        procesarEnvio(resultado)                                    // procesar el resultado (mostrar en pantalla, y guardarlo en xmlFacturas)
      else
      begin
          memoRes.lines.add('El Envio No Ha Podido Ser Realizado');
          memoRes.lines.add(resultado.EstadoEnvio);
          memoRes.lines.add(resultado.error);
      end;

///////////////////////////////////////////////////////////


procedure TForm1.procesarEnvio(resultado:TResultadoEnvio);
var
  desError,error,estado,factura, emisor:string;

  j:integer;

  _ok,_oke,_err:integer;

begin
      memoXML.Lines.LoadFromFile(xmlEnvio);
      memoXML.Text:=FormatXMLData(memoXML.Text);

      memoRes.lines.clear;
      memoRes.lines.Add('Se ha realizado el envío');
      memoRes.Lines.Add('');
      memoRes.Lines.Add('Estado Del Envio:'+resultado.EstadoEnvio );
      memoRes.lines.Add('CSV: ' + resultado.CSV);
      memoRes.lines.Add('TimeStamp: ' + resultado.Fecha+' '+resultado.Hora);
      memoRes.Lines.Add('');


      _ok  :=0;    // nº facturas OK
      _oke  :=0;    // nº facturas OK ( pero aceptadas con errores )
      _err  :=0;    // nº facturas con errores  (no aceptadas)

      for j:=0 to resultado.nFacturas-1 do
      begin
            factura  := resultado.facturas[j].NumSerieFactura;
            emisor  := resultado.facturas[j].IDEmisorFactura;
            estado  := resultado.facturas[j].estado;
            error    := inttostr(resultado.facturas[j].errorcodigo);
            desError := resultado.facturas[j].descripcionError;


            memoRes.Lines.Add( factura + ' ' + estado + ' '+error+' '+desError );    // ver en pantalla

            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
      end;

      memoRes.Lines.Add('');
      memoRes.Lines.Add('Facturas Aceptadas: '+inttostr(_ok) );
      memoRes.Lines.Add('Facturas Aceptadas Con Errores: '+inttostr(_oke) );
      memoRes.Lines.Add('Facturas Con Errores: '+inttostr(_err) );

      // tiempo de espera:
      if resultado.tiempoDeEspera<>'' then memoRes.Lines.Add('Se Ha Establecido Un Tiempo De Espera Proximo Envio De '+resultado.tiempoDeEspera);
end;

En el array resultado.facturas esta incluidas el resultado para cada factura.
Solo hay que recorerlo y colocar los datos devueltos:

Código:

      for j:=0 to resultado.nFacturas-1 do
      begin
            factura  := resultado.facturas[j].NumSerieFactura;
            emisor  := resultado.facturas[j].IDEmisorFactura;
            estado  := resultado.facturas[j].estado;
            error    := inttostr(resultado.facturas[j].errorcodigo);
            desError := resultado.facturas[j].descripcionError;


ramherfer 31-01-2025 12:38:22

Es posible que me esté marcando todos los envios como incidencia.

Cita:

<RemisionVoluntaria xmlns="https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/tike/cont/ws/SuministroInformacion.xsd">
<Incidencia>S</Incidencia>
</RemisionVoluntaria>
¿Como distingue los tickets de las facturas ordinarias?

Venga muchas gracias, lo tengo implementado y ahora simplemente a pulir algunas cosas.

seccion_31 31-01-2025 13:31:46

El componente distingue los tickets de las facturas, si se envían o no datos del cliente, con la factura. (El nif del cliente, debe estar en blanco para ser considerado un ticket).

Se marca con incidencia si la fecha de lo que estas enviando es distinta a la fecha del dia. Con solo una factura o ticket, fuera de fecha el envío es marcado con incidencia, porque no hay forma de hacerlo individualmente.

ramherfer ¿cual ha sido tu experencia con la demo? ¿te ha costado mucho la implementacion?

¿has revisado que todo lo que estas enviando vaya bien?

saludos !

ramherfer 31-01-2025 17:01:52

Cita:

Empezado por seccion_31 (Mensaje 561601)
El componente distingue los tickets de las facturas, si se envían o no datos del cliente, con la factura. (El nif del cliente, debe estar en blanco para ser considerado un ticket).

Se marca con incidencia si la fecha de lo que estas enviando es distinta a la fecha del dia. Con solo una factura o ticket, fuera de fecha el envío es marcado con incidencia, porque no hay forma de hacerlo individualmente.

ramherfer ¿cual ha sido tu experencia con la demo? ¿te ha costado mucho la implementacion?

¿has revisado que todo lo que estas enviando vaya bien?

saludos !

Vale, entonces si llega el nif y el nombre del cliente sin datos entiendo que lo tomará como ticket. Sabiendo esto voy a preparar el código ya que los tickets me llegan con el nif 00000000T.

Con respecto a la incidencia, el primer envío de hoy, faltaban datos (Descripción de la operacion -por error en el código de la aplicación-) y me ha dado error de envio, con lo cual el servidor indicaba un mensaje como "incidencia iniciada". Solucionada la incidencia y habiendo hecho el envío correcto, entiendo que habría que reiniciar el servidor, para que la incidencia se desactive. Las pruebas las estoy realizando con fecha de hoy todas y envio obedeciendo el tiempo marcado en la respuesta de la AEAT.

Mi experiencia, "GENIAL".... MÁS QUE GENIAL. Funcionamiento sencillo y entendible cien por cien. Me faltaría estudiar un poco el codigo del servidor.

¿Que si me ha costado implementar? Menos de 5 días, ya que el equipo de desarrollo he tenido un problema con el disco duro y ante la duda la más peluda, lo he cambiado y he perdido 1 día de trabajo. El lunes creo que pusiste a disposición de todos esa MARAVILLA que has creado.

Primero adapté la demo para trabajar con mis tablas y poder hacer envíos manuales de forma controlada.

En segunda fase cuando todo estaba funcionando correctamente implementarlo ha sido muy, muy sencillo y lo tengo funcionando en la aplicación ya realizando pruebas iniciales y han funcionando correctamente.

Me falta probar tickets y rectificativas, se que va a funcionar bien -seguro-. Las anulaciones de momento las descarto ya que trabajo directamente con las tablas y una factura numero 12345 de alta y 12345 baja pues como que no lo tengo muy claro. A nivel de control de Flujo hay una tabla (a nivel de empresa) con tres datos máximas_facturas_envio, tiempo_proximo_envio y envío_activo. Envio se activa al inicio de una transmisión, si cualquier terminal inicia otra transmisión queda encolada hasta que el envio_activo quede desactivado al finalizar el procedimiento ProcesarEnvio. Por otro lado la aplicación internamente comprueba que el número de facturas no sea igual a 1000 en cuyo caso inicia una transmisión de forma inmediata (1000 facturas mis clientes les cuesta un año hacerlas :)) Pero por si algún caso se vuelven locos, está controlado.
Imagino que te sonará la idea. Te tengo un monumento en mi puerta.

Procesado el envío, envía un mensaje al registro SIF para que si está visible refresque la cola de envio y muestra una ventana con los resultados del último envio durante 20 segundos por si los quiere imprimir. A los 20 segundos se cierra la ventana de resultados de forma automática. Esto por configuración de empresa ya lo pondré de forma automática si se imprimen o no los resultados.

Me falta implantar algunas utilidades (cotejamiento, Obtener QR, impresión de documentos, etc) desde el registro del SIF. Obtener el QR lo pongo por si algún caso ya que al finalizar el procedimiento ProcesarEnvio lo genero de forma automática y todo queda disponible para imprimir la(s) factura(s) cada una con su código QR.

He variado los nombre de envío y resultados, anticipándole al nombre un timestamp (fecha,hora,minutos,segundos y milisegundos + nombre) quiero que lo guarde todo en la carpeta de cada ejercicio de la empresa. Aunque lo tenga la AEAT, mejor tener cada movimiento que realizo, por si algún tipo de duda.

He estado comprobando las huellas que estén bien encadenadas y lo están. Me faltaría implantar algún proceso que vaya desde la última factura hacia atrás comprobando los datos de encadenamiento, pero esto es relativamente sencillo de hacer y lo implantaré en las próximas semanas.

No tengo palabras y me faltaría vida, para poder agradecer tu aporte. Si encuentro alguna cosa que crea o vea que no funciona bien, rápidamente lo pongo.

Por mi parte y con afán de ayuda, como a mi se me ayudó, cualquiera que tenga una duda sobre la demo u otras cuestiones comentadas, y mi conocimiento llega para poder ayudar, estaré encantado ya que considero que es lo mínimo que puedo hacer, dentro de mis posibilidades.

Disculpar por la brasa y gracias Sección_31

ontisoft 31-01-2025 18:28:37

Yo tengo una duda, he bajado las 2 demos.

¿La del componente D7 que tiene de diferente de la otra?
Yo quiero implementar verifactu, pero tengo el ERP en Delphi 12. ¿es necesario el componente D7 o directamente lo implemento con el código de la demo?

Por cierto, me ofrezco a ayudar en lo que se necesite, ya que en breve voy a tener que dedicar tiempo a adaptar mi software

DarkDudae 31-01-2025 18:56:57

Cita:

Empezado por ontisoft (Mensaje 561620)
Yo tengo una duda, he bajado las 2 demos.

¿La del componente D7 que tiene de diferente de la otra?
Yo quiero implementar verifactu, pero tengo el ERP en Delphi 12. ¿es necesario el componente D7 o directamente lo implemento con el código de la demo?

Por cierto, me ofrezco a ayudar en lo que se necesite, ya que en breve voy a tener que dedicar tiempo a adaptar mi software

El componente lo puedes usar igualmente en versiones más recientes de Delphi, con la ventaja de que no necesitas un programa "servidor" que recepcione las facturas, sino que podrías simplemente integrar el código de ese "programa servidor" en tu programa directamente.

Por otro lado, aprovecho para preguntar una duda:

-Veo que se habla de "envíos pendientes", de colas, e incluso de envíos manuales. Tenía entendido que en sistemas VERIFACTU el envío tenía que ser instantáneo. Entiendo que en sistemas de facturación estándar en el que se hacen pocas facturas al día no es tan crítica su transmisión instantánea, pero en TPVs donde se generan cientos de facturas simples al día que además, para ser verificables deben contar con el QR impreso en los tickets, no tiene mucho sentido tener una cola de envíos a no ser que existan problemas de conexión a internet. ¿Estoy en lo correcto?

Por otro lado, ¿sabéis cómo proceder en caso de que un ticket no pueda enviarse a la AEAT por problemas de conectividad? ¿Generarse igualmente sin código QR? ¿Incluir algún indicativo en el mismo? ¿Enviarse cuando se recupere la conexión a internet? ¿Qué ocurriría si no se recupera la conexión hasta pasados unos días? Tengo entendido que el sistema verifactu no acepta facturas de días anteriores.

Siento si alguna de estas dudas está repetida. Hay tanta cantidad de información, y tanta mezcla de conceptos con la FacturaE y con el SII que al final uno se vuelve loco.

newtron 31-01-2025 19:18:46

Cita:

Empezado por DarkDudae (Mensaje 561623)
El componente lo puedes usar igualmente en versiones más recientes de Delphi, con la ventaja de que no necesitas un programa "servidor" que recepcione las facturas, sino que podrías simplemente integrar el código de ese "programa servidor" en tu programa directamente.

Por otro lado, aprovecho para preguntar una duda:

-Veo que se habla de "envíos pendientes", de colas, e incluso de envíos manuales. Tenía entendido que en sistemas VERIFACTU el envío tenía que ser instantáneo. Entiendo que en sistemas de facturación estándar en el que se hacen pocas facturas al día no es tan crítica su transmisión instantánea, pero en TPVs donde se generan cientos de facturas simples al día que además, para ser verificables deben contar con el QR impreso en los tickets, no tiene mucho sentido tener una cola de envíos a no ser que existan problemas de conexión a internet. ¿Estoy en lo correcto?

Por otro lado, ¿sabéis cómo proceder en caso de que un ticket no pueda enviarse a la AEAT por problemas de conectividad? ¿Generarse igualmente sin código QR? ¿Incluir algún indicativo en el mismo? ¿Enviarse cuando se recupere la conexión a internet? ¿Qué ocurriría si no se recupera la conexión hasta pasados unos días? Tengo entendido que el sistema verifactu no acepta facturas de días anteriores.

Siento si alguna de estas dudas está repetida. Hay tanta cantidad de información, y tanta mezcla de conceptos con la FacturaE y con el SII que al final uno se vuelve loco.


Buenas.


Imagínate un supermercado que va generando tickets de forma masiva. Teniendo en cuenta de que el plazo máximo desde que se genera el ticket hasta que se envía es de 2 minutos (si no me equivoco), no te daría tiempo a ir enviando uno por uno porque en cada envío/respuesta se necesita un tiempo y al final empezarías a enviar tickets fuera de plazo. Por eso lo más razonable es ir haciendo paquetes de X tickets (<1000), enviarlos y los que van llegando se van encolando hasta el próximo envío, que será seguramente a los 2 minutos. De esta manera harías un envío cada 2 minutos de los tickets que se hayan generado en ese tiempo.


Por otro lado los tickets se tienen que generar con su qr independientemente de que tardes o no en enviarlos, la única diferencia es que si el cliente lee el qr y se ha enviado ya el ticket le dará un resultado Ok y si no se ha enviado le dirá que no consta en la aeat.


Si tienes problemas en el envío por el motivo que sea, el primer paquete de envío tienes que marcarlo como Incidencia=S, nada más.


Espero haber resuelto tus dudas.
Saludos.

Quim Herrera 01-02-2025 07:59:47

Cita:

Empezado por ramherfer (Mensaje 561438)
Ojo el servicio no puede buscar certificados en el almacen del usuario, por lo que tendrá que estar instalado a nivel de máquina para que en caso de usar CAPICOM lo busque en CAPICOM_LOCAL_MACHINE_STORE.
en HTTPRIO1HTTPWebNode1BeforePost Estás usando CAPICOM_CURRENT_USER_STORE y debes usar CAPICOM_LOCAL_MACHINE_STORE. Pero cuando tengas el certificado instalado a nivel de máquina no a nivel de usuario.
Espero te sirva

Iba por ahí, en HTTPRIO1HTTPWebNode1BeforePost seguia usando el certificado de Usuario.
Muchas gracias ramherfer!!!!

seccion_31 01-02-2025 08:41:58

buenos dias !

encantado ramherfer que el componente haya cumplido las expectativas, gracias por tu reconocimiento.

Todavía espero que habrá que corregir alguna cosa, me extrañaria mucho que estuviera muy bien. (de hecho acabo de ver un error, porque ahora siempre envia a pre-produccion, asi que en unos dias subire otra version)
(abajo pongo lo que hay que corregir, hoy asi rapido pero habrá alguna mejora mas).

ontisoft, la primera demo la puedes descartar, era una prueba temprana.

la segunda demo es la buena. En el programa que envia desde Excel, no olvidéis seleccionar un certificado del almacén valido e indicar vuestros datos en la pestaña Datos Sistema Informático.

Para los que quieran usar el componente sin D7, desde versiones B10 en adelante, pueden hacerlo directamente usando las funciones del servidor. No lo he probado, pero debería funcionar sin mas

Para ello, hay que hacer un uses tal que así:

uses uTiposVerifactu, uVerifactuFuncs;

Aumentar el stack size maximo a: 9048576 Project -> options->linker

Tendremos las siguientes funciones disponibles: Os recomiendo que mireis la llamada a esas funciones desde la unidad de componente para D7 a modo de consulta. en la unidad: uTVerifactu.pas

Código:

function  inicio_sesion( var crearSesion:TVeriFactuInicio ):integer; stdcall;
// con sesion:
function  anadeFactura(sesion:integer; var factura:TRegistroFacturas):integer; stdcall;
procedure envio(sesion:integer; var resultadoEnvio:TResultadoEnvio);  stdcall;
function  cierreSesion(sesion:integer; cierre:TCierreSesion):boolean;
function  resetSesion(sesion:integer; cierre:TCierreSesion):boolean;
function  consultar(sesion:integer; var resultado:TConsultaResultado):boolean;

// sin sesion:
procedure validarNIF(var nifvalidador:TValidadorNif);

// auxiliares
procedure clear_factura(afactura:TRegistroFactura);
procedure clear_sesion(sesion:integer);

// Certificados
procedure GetCertificados(var certificados:TCertificados);
procedure GetAliasCertificado(var certificados:TAliasCert);
function BUSCAR_CERTIFICADO_SERIAL(Nombre_Certificado: String): string;


Correccion para permitir el envio a otra url

Unidad uTVeriFactu

Reemplazar esta funcion, por este codigo:

Código:

//
// crear una sesion
//
function  TVerifactu.inicio:boolean;
var
    inicioVeriFactu    : TVeriFactuInicio;
    filemap,filehandle : longint;
begin
      checkAutoRun;

      serverHandle := FindWindow(nil, pchar(serverName) );
      if IsWindow( serverHandle ) then
      begin
          inicioVeriFactu.simular:=simular;
          inicioVeriFactu.emisor:=emisor;
          inicioVeriFactu.sistemaInformatico:=sistemaInformatico;
          inicioVeriFactu.nombreCertificado:=Certificado;
          inicioVeriFactu.passwordCertificado:=passwordCertificado;
          inicioVeriFactu.SaveXmlEnvio:=fSave;
          inicioVeriFactu.SaveXMLResultado:=fResp;
          inicioVeriFactu.incidencia:=false;

          inicioVeriFactu.resultadoSesion:=-1;
          if fEndPoint<>'' then
            inicioVeriFactu.direccion_envio:=fEndPoint
          else
            inicioVeriFactu.direccion_envio:='https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP';

          filemap:=saveNewFileMappingData(@inicioVeriFactu, sizeof(inicioVeriFactu), filehandle);

          SENDMESSAGE( serverHandle, WM_VERIFACTU_INICIO, 0, filemap );

          loadFileMappingData(@inicioVeriFactu, sizeof(inicioVeriFactu), filemap);
          closeFileMappingData(filehandle);

          if inicioVeriFactu.resultadoSesion<>0 then
          begin
              sesion:=inicioVeriFactu.resultadoSesion;
              result:=true;
          end
          else
          begin
              result:=false;
          end;
      end
      else
          result:=false;
end;


ramherfer 01-02-2025 21:35:51

Bueno pues parece ser que me esta marcando todos los envíos como incidencia.
Las facturas las genero con la fecha del día actual y por defecto el tiempo máximo es de 60 segundos, controlado por timer que se resetea y actualizaal final del envio según el tiempo de espera que informe la AEAT en la respuesta del envio.
Desconozco si me pasa solo a mi.
Voy a ver si le doy un repaso a todo.

seccion_31 02-02-2025 08:53:36

Lo acabo de probar con la demostración de excel y funciona correcto (he lanzado 3 facturas). No veo el campo incidencia en el XML ni en la web de la AEAT.

Asegurate que usas la compilacion que deje en el rar. MSG_BERLIN\Win32\Debug\msgverifactu.exe del 2 de enero (no creo que haya otra ahi dentro)

Despues del envio, puedes abrir el servidor verifactu de la barra de tareas, ir a la pestaña de la sesion y ver a partir de que factura se activa la incidencia. (de ahi en adelante todo va con incidencia)

Saludos

Cita:

Empezado por ramherfer (Mensaje 561640)
Bueno pues parece ser que me esta marcando todos los envíos como incidencia.
Las facturas las genero con la fecha del día actual y por defecto el tiempo máximo es de 60 segundos, controlado por timer que se resetea y actualizaal final del envio según el tiempo de espera que informe la AEAT en la respuesta del envio.
Desconozco si me pasa solo a mi.
Voy a ver si le doy un repaso a todo.



La franja horaria es GMT +2. Ahora son las 16:42:54.

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