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-02-2025 09:06:58

Hay algunas cosas que me gustaria comentar

1) Alguien ha conseguido hacer funcionar el httprio desde una DLL ? si fuera asi, y tuviera el codigo, lo cambiaria a funcionamiento por DLL que me parece mas elegante.

2) ¿Alguien ha probado el componente, indicando en vez del nombre del certificado el nombre de un archivo.pfx y en passwordCertificado su contraseña?

Saludos !

ramherfer 02-02-2025 11:10:34

Cita:

Empezado por seccion_31 (Mensaje 561642)

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)

Saludos

Si correcto estoy usando esa del 2 de enero de 2025 de las 12:46

Cita:

Empezado por seccion_31 (Mensaje 561642)

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

ok en la primera que he confeccionado hoy y enviado ya me sale incidencia activa.

https://drive.google.com/file/d/17qT...ew?usp=sharing

Voy a revisar mi código a ver si veo algo raro comparandolo con la demo y si no veo nada haré lo propio con el del servidor.

ramherfer 02-02-2025 12:29:50

Cita:

Empezado por ramherfer (Mensaje 561644)
Si correcto estoy usando esa del 2 de enero de 2025 de las 12:46



ok en la primera que he confeccionado hoy y enviado ya me sale incidencia activa.

https://drive.google.com/file/d/17qT...ew?usp=sharing

Voy a revisar mi código a ver si veo algo raro comparandolo con la demo y si no veo nada haré lo propio con el del servidor.

encontrado el problema. Está en la unidad uVerifactuFuncs.pas en la comparación de fechas

Cita:

if factura.actual.fechaFactura<>datetostr(date) then
sesiones[sesion].inicio.incidencia:=true;
Lo he sacado a disco y está comparando esto
Cita:

FechaFactura: 02-02-2025
FechaSistema: 02/02/2025
Siempre son distintas.

la reemplazo por:

Cita:

if factura.actual.fechaFactura<>StringReplace(DateToStr(Date), '/', '-', [rfReplaceAll]) then
sesiones[sesion].inicio.incidencia:=true;

seccion_31 03-02-2025 08:10:06

ramherfer

Creo que estas suministrando la fecha en el record factura.actual.fechaFactura con el formato 01-01-2025 cuando deberías simplemente cargar la fecha tal cual 01/01/2025 cuando se envía la función altafactura_F1_F2_R4_R5_verifactu realiza la conversión.

Ya me lo confirmaras.

Saludos !

DarkDudae 03-02-2025 12:10:03

Cita:

Empezado por seccion_31 (Mensaje 561643)
1) Alguien ha conseguido hacer funcionar el httprio desde una DLL ? si fuera asi, y tuviera el codigo, lo cambiaria a funcionamiento por DLL que me parece mas elegante.

¿Qué problema te da exactamente?

seccion_31 03-02-2025 12:33:46

Cita:

Empezado por DarkDudae (Mensaje 561666)
¿Qué problema te da exactamente?

en la DLL error de proteccion general. justo al llamar la funcion de enviar. El mismo codigo en un ejecutable sin problemas.

googleando en algunos sitios lei que no se podia, pero siempre hay que asegurarse.

ramherfer 03-02-2025 16:10:28

Cita:

Empezado por seccion_31 (Mensaje 561654)
ramherfer

Creo que estas suministrando la fecha en el record factura.actual.fechaFactura con el formato 01-01-2025 cuando deberías simplemente cargar la fecha tal cual 01/01/2025 cuando se envía la función altafactura_F1_F2_R4_R5_verifactu realiza la conversión.

Ya me lo confirmaras.

Saludos !

Efectivamente. Al verlo en las hojas excel con formato dd-mm-aaaa pues pasaba la fecha con el mismo formato.
Ok, corrijo la modificación y realizada.

nincillo 03-02-2025 17:00:37

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.

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.

Muchas gracias por este gran aporte.

Voy a intentar compilar tanto la versión D7 como la "moderna" a ver si puedo compilar sin problemas y a partir de ahí empezar a adaptarlo a mi programa.

¿No has podido hacer la parte del envío utilizando D7 y por eso has optado a hacerlo con versiones más modernas?. Yo en su momento, conseguí hacer pruebas de envío, pero el problema lo tenía con el TLS de windows 7. Si el mismo ejecutable lo lanzaba desde un Windows 10 si que parecía funcionar...

Un saludo.

seccion_31 04-02-2025 06:53:48

Cita:

Empezado por nincillo (Mensaje 561677)
Muchas gracias por este gran aporte.

Voy a intentar compilar tanto la versión D7 como la "moderna" a ver si puedo compilar sin problemas y a partir de ahí empezar a adaptarlo a mi programa.

¿No has podido hacer la parte del envío utilizando D7 y por eso has optado a hacerlo con versiones más modernas?. Yo en su momento, conseguí hacer pruebas de envío, pero el problema lo tenía con el TLS de windows 7. Si el mismo ejecutable lo lanzaba desde un Windows 10 si que parecía funcionar...

Un saludo.

No pude hacerlo con D7, ya importando el WSDL creo que tuve problemas, copie la unidad ya importada y habia un monton de tipos que D7 no reconocia, y hasta ahi.

Lo dicho, si alguien sabe como hacer funcionar la llamada SOAP desde una DLL y que no de error general que me avise.

Y me gustaria que alguien probara a usar un archivo PFX en lugar de usar el certificado desde el almacen.

Saludos y gracias !

DarkDudae 04-02-2025 15:29:32

He encontrado un pequeño error en la aplicación servidora.

Si intentas cotejar una factura simple (que por ende no tiene ni cliente ni NIF) arroja una excepción en las líneas:

Código Delphi [-]
cliente             :=res.RegistroRespuestaConsultaFactuSistemaFacturacion[j].DatosRegistroFacturacion.Destinatarios[0].NombreRazon;
clienteNIF          :=res.RegistroRespuestaConsultaFactuSistemaFacturacion[j].DatosRegistroFacturacion.Destinatarios[0].NIF;

Se puede solucionar con un try - except, pero creo que así es mucho mejor:

Código Delphi [-]
if Assigned(res.RegistroRespuestaConsultaFactuSistemaFacturacion[j].DatosRegistroFacturacion.Destinatarios) then
begin
   cliente             :=res.RegistroRespuestaConsultaFactuSistemaFacturacion[j].DatosRegistroFacturacion.Destinatarios[0].NombreRazon;
   clienteNIF          :=res.RegistroRespuestaConsultaFactuSistemaFacturacion[j].DatosRegistroFacturacion.Destinatarios[0].NIF;
end;

Saludos

seccion_31 05-02-2025 06:59:02

gracias DarkDudae

voy a incoporar la corrección y en un tiempo, quizas dos semanas publicare una nueva version.

¿tenemos alguna sugerencia para seguir mejorando el componente?

Voy a retirar el campo "situacion", porque creo que no se usa, y asi libero espacio de la pila.
Corregire las fechas cuando entreguen la fecha de emision con - en lugar de /

Hay un indicador que se llama incidencia, que se puede activar manual, o automaticamente, cuando la fecha de alguna factura es diferente a la del dia.
Habra otro indicador que se llamara primerRegistro si se detecta primer registro en el envio
-->Ambos indicadores, deberian poder ser consultados antes del envio.

(Es una lastima no poder encapsularlo en una DLL, mejoraría mucho)

Habria que probar el certificado pfx

Y hay que añadir mas casos a la generación de la facturación, en especial la de exentos de iva. ¿hay alguien por aqui que domine el tema?

Saludos !

Quim Herrera 05-02-2025 07:44:09

Cita:

Empezado por seccion_31 (Mensaje 561643)
Hay algunas cosas que me gustaria comentar

1) Alguien ha conseguido hacer funcionar el httprio desde una DLL ? si fuera asi, y tuviera el codigo, lo cambiaria a funcionamiento por DLL que me parece mas elegante.

2) ¿Alguien ha probado el componente, indicando en vez del nombre del certificado el nombre de un archivo.pfx y en passwordCertificado su contraseña?

Saludos !

Hola seccion_31 ,
El código del certificado para archivo pfx funciona perfectamente tanto para .pfx como para .p12.
Lo he probado en un servicio de windows que estoy haciendo en delphi 10.2.
Muchas gracias por el aporte!
Saludos,

seccion_31 05-02-2025 08:14:23

hola Quim Herrera !

¿estas seguro que funciona?

ahora mirando la funcion:
Código Delphi [-]
Funcion: procedure TEventosWebNode.WebNodeBeforePost(const HTTPReqResp: THTTPReqResp;
Unidad: uVerifactuFuncs

Yo creo que esto fallara:

Código Delphi [-]
 PFX := TFile.ReadAllBytes('ArchivoDelCertificado.PFX');

Deberia ser:

Código Delphi [-]
  PFX := TFile.ReadAllBytes( cert );


He añadido la extension .P12 para reconocer el archivo

¿puedes confirmarlo por fa?

Slds !

Quim Herrera 05-02-2025 08:31:17

Cita:

Empezado por seccion_31 (Mensaje 561728)
hola Quim Herrera !

¿estas seguro que funciona?

ahora mirando la funcion:

Funcion: procedure TEventosWebNode.WebNodeBeforePost(const HTTPReqResp: THTTPReqResp;
Unidad: uVerifactuFuncs


Yo creo que esto fallara:

PFX := TFile.ReadAllBytes('ArchivoDelCertificado.PFX');

Deberia ser:

PFX := TFile.ReadAllBytes( cert );


He añadido la extension .P12 para reconocer el archivo

¿puedes confirmarlo por fa?

Slds !


Exacto, hay que cambiar
Código Delphi [-]
PFX := TFile.ReadAllBytes('ArchivoDelCertificado.PFX' );
por
Código Delphi [-]
PFX := TFile.ReadAllBytes( cert );
y ya funciona.

Saludos,

seccion_31 05-02-2025 08:34:24

Cuida que: hay que hacer algun cambio mas en la funcion consultar (para que reconoca el PFX), y en los "ifs" para que soporten las dos extensiones.

Ya lo he modificado, perfecto.

gracias !

ramherfer 05-02-2025 13:07:25

Estoy probando el certificado por fichero y contraseña asignandole el path del archivo del archivo de certificdado a la variable VerifactuD7.Certificado y la contraseña en VerifactuD7.passwordCertificado.
No se si es lo correcto, pero me da un error al cotejar.
He realizado la corrección PFX := TFile.ReadAllBytes('ArchivoDelCertificado.PFX' ); por PFX := TFile.ReadAllBytes( cert ); en el servidor antes de hacer la prueba.
Un saludo!

seccion_31 05-02-2025 13:58:38

ramherfer

sustituye esta funcion: uVerifactuFuncs y recompila el servidor B10

Código:

function consultar(sesion:integer; var resultado:TConsultaResultado):boolean;
var
  consulta          : ConsultaFactuSistemaFacturacion;                  // Objeto a enviar
  res              : RespuestaConsultaFactuSistemaFacturacionType;    // Respuesta tras el envio

  HTTPRIO1          : THTTPRIO;

  j                : integer;

  direccion_envio,  estado  : string;

  eventos      : TEventosHttpPrio;
  eventosWebNode: TEventosWebNode;
begin
      consulta:=ConsultaFactuSistemaFacturacion.Create;

      consulta.Cabecera:=CabeceraConsultaSf.Create;
      consulta.Cabecera.ObligadoEmision:=ObligadoEmisionConsultaType.Create;
      consulta.Cabecera.ObligadoEmision.NombreRazon:=sesiones[sesion].inicio.emisor.NombreRazonEmisor;
      consulta.Cabecera.ObligadoEmision.NIF:=sesiones[sesion].inicio.emisor.nifEmisor;
      consulta.FiltroConsulta:=LRFiltroRegFacturacionType.Create;
      consulta.FiltroConsulta.PeriodoImputacion:=PeriodoImputacionType.Create;
      consulta.FiltroConsulta.PeriodoImputacion.Ejercicio:=resultado.Cabecera.ejercicio;
      consulta.FiltroConsulta.PeriodoImputacion.Periodo:=veriFactuPeriodo( resultado.Cabecera.periodo );

      if resultado.Cabecera.NumSerieFactura='' then
      begin
          consulta.FiltroConsulta.FechaExpedicionFactura.RangoFechaExpedicion.Desde:=verifactuFecha(datetoStr(resultado.Cabecera.dfecha));
          consulta.FiltroConsulta.FechaExpedicionFactura.RangoFechaExpedicion.Hasta:=verifactuFecha(datetoStr(resultado.Cabecera.hfecha));
      end
      else
      begin
          consulta.FiltroConsulta.NumSerieFactura:=resultado.Cabecera.NumSerieFactura;
      end;

      eventos:=TEventosHttpPrio.Create;

      eventos.fileNameBefore  :=sesiones[sesion].saveXMLenvio;
      eventos.fileNameAfter  :=sesiones[sesion].saveXMLResult;

      eventosWebNode:=TEventosWebNode.Create;
      eventosWebNode.sesion:=sesion;

      HTTPRIO1:=THTTPRIO.create(nil);
      HTTPRIO1.onBeforeExecute:=eventos.BeforeExecute;
      HTTPRIO1.onAfterExecute :=eventos.AfterExecute;

      // Cargar certificado del disco
      if ( pos('.PFX',uppercase(sesiones[sesion].inicio.nombreCertificado))<>0) or
        ( pos('.P12',uppercase(sesiones[sesion].inicio.nombreCertificado))<>0) then
          HTTPRIO1.HTTPWebNode.onBeforePost:=eventosWebNode.WebNodeBeforePost;

      // --> envío pre-produccion:  'https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP';
      try
          // Cargar certificado del almacen
          if ( pos('.PFX',uppercase(sesiones[sesion].inicio.nombreCertificado))=0) and
            ( pos('.P12',uppercase(sesiones[sesion].inicio.nombreCertificado))=0) then
            HTTPRIO1.HTTPWebNode.ClientCertificate.SerialNum := Buscar_Certificado_SERIAL( sesiones[sesion].inicio.nombreCertificado );  // coloca el certificado

          direccion_envio :=sesiones[sesion].inicio.direccion_envio;

          res:=  RespuestaConsultaFactuSistemaFacturacionType.Create;
          res:=  GetsfPortTypeVerifactu( false, direccion_envio , HTTPRIO1 ).ConsultaFactuSistemaFacturacion( consulta ); // Enviarlo !

          // resultado del envio:
          resultado.ConDatos:=(res.ResultadoConsulta=ResultadoConsultaType.ConDatos);
          resultado.error  :=false;
          resultado.errorDes:='';


          procesarConsulta(res,resultado );
      except
      on E:Exception do
      begin
          resultado.ConDatos:=false;
          resultado.error:=true;
          resultado.errorDes:=Format('(%s)-%s',[E.ClassName, E.Message]);
          result:=false;
          exit;
      end;

            // Finalmente:
            // HTTPRIO1.free;  //<- no puede ser destruido con NIL como constructor
            //eventos.Free;
      end;
      result:=true;
end;


seccion_31 05-02-2025 14:26:51

Voy a incorporarle el tema de las facturas exentas

Con lo que ya hay programado, para el desglose del IVA necesito saber el texto de las diferentes leyes, para al menos ajustar la clave de exencion automatica para las de exportacion UE, fuera de UE, y canarias correctamente.

E1 Exenta por el artículo 20
E2 Exenta por el artículo 21 (canarias, y fuera la UE)
E3 Exenta por el artículo 22
E4 Exenta por los artículos 23 y 24
E5 Exenta por el artículo 25 (exportacion a la UE)
E6 Exenta por otros

Me gustaria saber un pequeño texto resumen de los articulos.

A ver si alguien me puede aclarar este tema x favor.

Slds !

ramherfer 05-02-2025 17:18:11

Cita:

Empezado por seccion_31 (Mensaje 561742)
ramherfer

sustituye esta funcion: uVerifactuFuncs y recompila el servidor B10

Código:

function consultar(sesion:integer; var resultado:TConsultaResultado):boolean;
var
  consulta          : ConsultaFactuSistemaFacturacion;                  // Objeto a enviar
  res              : RespuestaConsultaFactuSistemaFacturacionType;    // Respuesta tras el envio

  HTTPRIO1          : THTTPRIO;

  j                : integer;

  direccion_envio,  estado  : string;

  eventos      : TEventosHttpPrio;
  eventosWebNode: TEventosWebNode;
begin
      consulta:=ConsultaFactuSistemaFacturacion.Create;

      consulta.Cabecera:=CabeceraConsultaSf.Create;
      consulta.Cabecera.ObligadoEmision:=ObligadoEmisionConsultaType.Create;
      consulta.Cabecera.ObligadoEmision.NombreRazon:=sesiones[sesion].inicio.emisor.NombreRazonEmisor;
      consulta.Cabecera.ObligadoEmision.NIF:=sesiones[sesion].inicio.emisor.nifEmisor;
      consulta.FiltroConsulta:=LRFiltroRegFacturacionType.Create;
      consulta.FiltroConsulta.PeriodoImputacion:=PeriodoImputacionType.Create;
      consulta.FiltroConsulta.PeriodoImputacion.Ejercicio:=resultado.Cabecera.ejercicio;
      consulta.FiltroConsulta.PeriodoImputacion.Periodo:=veriFactuPeriodo( resultado.Cabecera.periodo );

      if resultado.Cabecera.NumSerieFactura='' then
      begin
          consulta.FiltroConsulta.FechaExpedicionFactura.RangoFechaExpedicion.Desde:=verifactuFecha(datetoStr(resultado.Cabecera.dfecha));
          consulta.FiltroConsulta.FechaExpedicionFactura.RangoFechaExpedicion.Hasta:=verifactuFecha(datetoStr(resultado.Cabecera.hfecha));
      end
      else
      begin
          consulta.FiltroConsulta.NumSerieFactura:=resultado.Cabecera.NumSerieFactura;
      end;

      eventos:=TEventosHttpPrio.Create;

      eventos.fileNameBefore  :=sesiones[sesion].saveXMLenvio;
      eventos.fileNameAfter  :=sesiones[sesion].saveXMLResult;

      eventosWebNode:=TEventosWebNode.Create;
      eventosWebNode.sesion:=sesion;

      HTTPRIO1:=THTTPRIO.create(nil);
      HTTPRIO1.onBeforeExecute:=eventos.BeforeExecute;
      HTTPRIO1.onAfterExecute :=eventos.AfterExecute;

      // Cargar certificado del disco
      if ( pos('.PFX',uppercase(sesiones[sesion].inicio.nombreCertificado))<>0) or
        ( pos('.P12',uppercase(sesiones[sesion].inicio.nombreCertificado))<>0) then
          HTTPRIO1.HTTPWebNode.onBeforePost:=eventosWebNode.WebNodeBeforePost;

      // --> envío pre-produccion:  'https://prewww1.aeat.es/wlpl/TIKE-CONT/ws/SistemaFacturacion/VerifactuSOAP';
      try
          // Cargar certificado del almacen
          if ( pos('.PFX',uppercase(sesiones[sesion].inicio.nombreCertificado))=0) and
            ( pos('.P12',uppercase(sesiones[sesion].inicio.nombreCertificado))=0) then
            HTTPRIO1.HTTPWebNode.ClientCertificate.SerialNum := Buscar_Certificado_SERIAL( sesiones[sesion].inicio.nombreCertificado );  // coloca el certificado

          direccion_envio :=sesiones[sesion].inicio.direccion_envio;

          res:=  RespuestaConsultaFactuSistemaFacturacionType.Create;
          res:=  GetsfPortTypeVerifactu( false, direccion_envio , HTTPRIO1 ).ConsultaFactuSistemaFacturacion( consulta ); // Enviarlo !

          // resultado del envio:
          resultado.ConDatos:=(res.ResultadoConsulta=ResultadoConsultaType.ConDatos);
          resultado.error  :=false;
          resultado.errorDes:='';


          procesarConsulta(res,resultado );
      except
      on E:Exception do
      begin
          resultado.ConDatos:=false;
          resultado.error:=true;
          resultado.errorDes:=Format('(%s)-%s',[E.ClassName, E.Message]);
          result:=false;
          exit;
      end;

            // Finalmente:
            // HTTPRIO1.free;  //<- no puede ser destruido con NIL como constructor
            //eventos.Free;
      end;
      result:=true;
end;


Funciona perfectamente con fichero de certificado.pfx. He integrado en la aplicación los dos metodos de certificación, para que se utilice el que más convenga, aunque con fichero pfx o p12 implica menos dependencias de otros componentes, por lo tanto menos trabajo de implantación de la versión. Yo al arrancar la aplicación verifico la fecha de vencimiento del certificado para lanzar un aviso cuando quedan menos de 60 días. Esto utilizando el nombre del certificado y capicom. Voy a ver la forma de hacerlo con el pfx.

seccion_31 05-02-2025 21:02:43

ya tengo implementado por decir algo las facturas exentas, añadiendo un campo al desglose de iva, con el identificador de la exencion, pero ...

hasta aqui llegamos, porque no me aclaro con el valor ClaveRegimen (mis conocimientos fiscales son muy limitados)

Si no estoy equivocado:

Si la exencion es la E2 ClaveRegimen va a 02. exportacion ¿pero siempre debe tomar ese valor? ¿la E2 solo se usa para exportacion fuera de la UE? (o canarias)
Si la exencion es la E5 ClaveRegimen va a 01. factura UE ¿pero siempre debe tomar ese valor? ¿la E5 solo se usa para facturas UE?

Con E6 (otra) puede ir a ClaveRegimen 01, pero ¿se puede calcular ClaveRegimen segun el valor de la exencion?

¿
E1
E3
E4
?

Y aqui me paro hasta ver x favor, quien nos puede aclarar este tema.

Saludos !

DarkDudae 05-02-2025 22:12:30

Cita:

Empezado por seccion_31 (Mensaje 561767)
ya tengo implementado por decir algo las facturas exentas, añadiendo un campo al desglose de iva, con el identificador de la exencion, pero ...

hasta aqui llegamos, porque no me aclaro con el valor ClaveRegimen (mis conocimientos fiscales son muy limitados)

Parece que no hay conexión directa entre la clave del régimen y el motivo de la excenxión de IVA. Te paso la informsción que he encontrado:

Tabla de Claves de Régimen (ClaveRegimen)

Este campo indica el régimen de IVA aplicable a la factura.

ClaveRegimen Descripción
01 Régimen General
02 Régimen Especial de Recargo de Equivalencia
03 Régimen Especial de Agricultura, Ganadería y Pesca
04 Régimen Especial de Bienes Usados, Objetos de Arte, Antigüedades y Objetos de Colección
05 Régimen Especial de Agencias de Viaje
06 Régimen Especial del Criterio de Caja
07 Régimen Especial del Grupo de Entidades
08 Régimen Especial del Oro de Inversión
09 Régimen Especial de Agencias de Viajes que actúan como Mediadores en nombre y por cuenta ajena
10 Régimen de Comercio Intracomunitario
11 Régimen aplicable a las Ventas a Distancia y determinadas entregas de bienes y prestaciones de servicios
12 Régimen especial del IVA para Trabajadores Autónomos Extranjeros en España

Por otro lado, tenemos los motivos de la excenxión.

Tabla de Motivos de Exención (E1-E6) (Campo: CausaExencion)

Código Descripción
E1 Operaciones exentas por el artículo 20 de la Ley del IVA (ej. sanidad, educación, seguros, servicios financieros, alquiler de viviendas).
E2 Operaciones no sujetas por reglas de localización (servicios prestados fuera de España según los artículos 69, 70 y 72 de la Ley del IVA).
E3 Operaciones sujetas y exentas por el artículo 21 (exportaciones de bienes fuera de la UE).
E4 Operaciones sujetas y exentas por el artículo 22 (zonas francas, depósitos aduaneros y otros regímenes especiales).
E5 Operaciones sujetas y exentas por el artículo 23 (Régimen de viajeros, es decir, devoluciones de IVA a turistas no residentes en la UE).
E6 Operaciones sujetas y exentas por los artículos 24 y 25 (entregas intracomunitarias de bienes y servicios).

Ejemplo:

Si vendes un producto a una empresa en Alemania (operación intracomunitaria), la configuración correcta sería:
• ClaveRegimen = 10 (Comercio Intracomunitario)
• Motivo de Exención = E6 (Entrega intracomunitaria exenta de IVA)

Si emites una factura exenta de IVA por una exportación, usarías ClaveRegimen = 01 (régimen general) y motivo de exención = E3.

En ambos casos al TipoImpositivo le meteríamos el 0.

DarkDudae 05-02-2025 22:50:56

Edito: Perdón por el mensaje anterior. El campo del motivo está en el SII pero no en el Verifactu… igual se podría añadir junto con la descripción en el detalle…. pero no parece quedar claro…

seccion_31 06-02-2025 08:07:41

Cita:

Empezado por DarkDudae (Mensaje 561770)
Edito: Perdón por el mensaje anterior. El campo del motivo está en el SII pero no en el Verifactu… igual se podría añadir junto con la descripción en el detalle…. pero no parece quedar claro…

En el SII es asi:

3.6. ¿Cómo se registra una Entrega Intracomunitaria de Bienes?
Se anotará la factura emitida al cliente comunitario en el Libro registro de Facturas
Expedidas procediendo a su identificación mediante la clave 2 en el campo de tipos de
Identificación en el país de residencia “IDType” y su Número de Operador
Intracomunitario en el campo "ID". El campo “CodigoPais” no será obligatorio.
Por otra parte, la base imponible de la factura se incluirá en el campo de tipo de
operación “Exenta” dentro del bloque “Entrega”. Como causa de exención se
consignará la clave “E5: Exenta por el artículo 25”.


3.7. ¿Cómo se registra una Exportación?
La operación se anota en el Libro Registro de Facturas Expedidas.

-> En el campo “Clave Régimen especial o Trascendencia” se consignará el valor 2.

Deberá identificarse al cliente – en caso de ser extranjero- mediante el “Código país” y
las claves 3 “Pasaporte”, 4 “Documento oficial de identificación expedido por el país o
territorio de residencia”, 5 “Certificado de residencia” ó 6 “Otro documento probatorio”
del campo “IDType”.
Por otra parte, la base imponible de la factura se incluirá en el campo de tipo de
operación “Exenta” dentro del bloque “Entrega”. Como causa de exención se
consignará la clave E2 “Exenta por el artículo 21

Fuente: https://sede.agenciatributaria.gob.e...5/FAQs_v05.pdf



Entonces en verifactu tendriamos:

Exportaciones: articulo 21, por tanto: E3 ¿aqui incluiriamos canarias?

Intracomunitarias: articulo 25, por tanto E6

seccion_31 06-02-2025 10:09:04

entonces lo indicado por DarkDudae y lo que he correlacionado con el SII, en principio coinciden.

Eso, nos asegura las exenciones para canarias, UE, y fuera de UE, en una facturacion "normal".


El problema viene con el resto de exenciones, por ejemplo facturar temas medicos, ongs, deportivos, educativos, culturales etc...

¿Podemos aclarar este tema?

Saludos !

DarkDudae 06-02-2025 10:43:32

Cita:

Empezado por seccion_31 (Mensaje 561781)
entonces lo indicado por DarkDudae y lo que he correlacionado con el SII, en principio coinciden.

Eso, nos asegura las exenciones para canarias, UE, y fuera de UE, en una facturacion "normal".


El problema viene con el resto de exenciones, por ejemplo facturar temas medicos, ongs, deportivos, educativos, culturales etc...

¿Podemos aclarar este tema?

Saludos !

Entiendo que para ventas desde la península a Canarias, estaríamos hablando de una operación general 01 con tipo de excención E03.

Para las operaciones que mencionas, creo que todas serían el tipo E04:

Tipo de Exención,ClaveRegimen en VeriFactu,Base Legal
Servicios médicos y sanitarios,04,Art. 20. Uno. 2º Ley IVA
Servicios educativos y formación,04,Art. 20. Uno. 9º y 10º Ley IVA
Servicios sociales (ONG, entidades sin ánimo de lucro),04,Art. 20. Uno. 8º Ley IVA
Servicios deportivos o culturales exentos,04,Art. 20. Uno. 13º y 14º Ley IVA
Operaciones exentas relacionadas con seguros y finanzas,04,Art. 20. Uno. 16º y 18º Ley IVA
Operaciones exentas por razones de interés general (ej. asociaciones, fundaciones),04,Art. 20. Uno. 12º Ley IVA

ramherfer 06-02-2025 11:22:12

No se mucho de fiscalidad, pero entiendo que por lo que estais comentando el tipo de excención debería proporcionarlo la ficha del cliente ¿No?
Por lo tanto al servidor habría que informarle de estos datos, creo yo, en mi humilde opinión. Creo que automatizarlo totalmente es una locura

seccion_31 06-02-2025 11:28:56

Cita:

Empezado por DarkDudae (Mensaje 561783)
Entiendo que para ventas desde la península a Canarias, estaríamos hablando de una operación general 01 con tipo de excención E03.

Para las operaciones que mencionas, creo que todas serían el tipo E04:

Tipo de Exención,ClaveRegimen en VeriFactu,Base Legal
Servicios médicos y sanitarios,04,Art. 20. Uno. 2º Ley IVA
Servicios educativos y formación,04,Art. 20. Uno. 9º y 10º Ley IVA
Servicios sociales (ONG, entidades sin ánimo de lucro),04,Art. 20. Uno. 8º Ley IVA
Servicios deportivos o culturales exentos,04,Art. 20. Uno. 13º y 14º Ley IVA
Operaciones exentas relacionadas con seguros y finanzas,04,Art. 20. Uno. 16º y 18º Ley IVA
Operaciones exentas por razones de interés general (ej. asociaciones, fundaciones),04,Art. 20. Uno. 12º Ley IVA

¿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 alla de esto, ¿ya no se puede automatizar?:

¿Quizas habria que crear un array particular para exenciones y cubrir el resto de casos?

DarkDudae 07-02-2025 13:32:42

Nueva sugerencia para el componente:

Obtener fechas de caducidad de los certificados.

Para ello, bastaría con hacer una pequeña modificación en la función loadCertificados y en el tipo TCertificados.

Código Delphi [-]
function loadCertificados(aList, aFechas:TStringList):integer;
var
  hStore: HCERTSTORE;
  PrevContext, CurContext: PCERT_CONTEXT;
  cbSize: DWORD;
  SysTime: TSystemTime;
  sNombre: String;
begin
  aList.Clear;
  aFechas.Clear;
  Result := 0;
  hStore := CertOpenSystemStore(0, PChar('MY'));
  if hStore <> nil then begin
     PrevContext := nil;
     CurContext := CertEnumCertificatesInStore(hStore, PrevContext);
     while CurContext <> nil do begin
       sNombre := '';
       cbSize := CertGetNameString(CurContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nil, nil, 0);
       if cbSize > 0 then
       begin
          SetLength(sNombre, cbSize-1);
          CertGetNameString(CurContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, nil, PChar(sNombre), cbSize);
          aList.Add(sNombre);
          if FileTimeToSystemTime(CurContext^.pCertInfo^.NotAfter, SysTime) then
          begin
            AFechas.Add(datetimetostr(SystemTimeToDateTime(SysTime)));
          end;
       end;
       PrevContext := CurContext;
       CurContext  := CertEnumCertificatesInStore(hStore, PrevContext);
     end;
  end;
  result:=aList.count;
end;

ramherfer 07-02-2025 18:10:07

Buenas tardes.
¿Es posible que no me valide los nif's usando el pfx?

Con el nombre de certificado, si lo hace aunque no devuelve el nombre registrado en la AEAT, en resultado venía IDENTIFICADO o NO IDENTIFICADO
Un saludo,

seccion_31 10-02-2025 09:56:51

Cita:

Empezado por ramherfer (Mensaje 561841)
Buenas tardes.
¿Es posible que no me valide los nif's usando el pfx?

Con el nombre de certificado, si lo hace aunque no devuelve el nombre registrado en la AEAT, en resultado venía IDENTIFICADO o NO IDENTIFICADO
Un saludo,

Ya esta incorporado

Tambien soportara exentas (por otros motivos a exportacion, ue, y canarias) , en un array distinto a la de ivas, e inversión del sujeto pasivo en facturas nacionales. (eso si, toda la factura bajo inv.suje.pasivo)

La demo ha cambiado algo, y la excel para importar tambien.

Ademas de otros cambios y pequeños errores.

Creo que la semana que viene la subire

Saludos

seccion_31 10-02-2025 10:01:00

buenos dias DarkDudae !

¿ x favor, Puedes modificar el codigo para que directamente cargue SOOLO los certificados validos, evitando los caducados ?

NO tengo ninguno caducado para provar, y evitar el segundo parametro, y mas cambios.

Copiaria y pegaria tu codigo y ya, lo incorporo a la nueva version.

Saludos !

Matorral 10-02-2025 10:29:01

Buenos días ¡¡

Gracias a tod@s y sobretodo a Seccion31 por las aportaciones y por el enorme esfuerzo. De verdad que me dais la vida.
v:-)v

Cita:

Empezado por seccion_31 (Mensaje 561742)

sustituye esta funcion: uVerifactuFuncs y recompila el servidor B10

Código:

function consultar(sesion:integer; var resultado:TConsultaResultado):boolean;

.....

      // Cargar certificado del disco
      if ( pos('.PFX',uppercase(sesiones[sesion].inicio.nombreCertificado))<>0) or
        ( pos('.P12',uppercase(sesiones[sesion].inicio.nombreCertificado))<>0) then
          HTTPRIO1.HTTPWebNode.onBeforePost:=eventosWebNode.WebNodeBeforePost;

......

end;


Estoy utilizando Delphi 12 (no tengo Delphi 10 Berlin) para compilar el componente. Al reemplazar la función "consultar" me aparece un error en la línea

Código:

          HTTPRIO1.HTTPWebNode.onBeforePost:=eventosWebNode.WebNodeBeforePost;
En eventosWebNode.WebNodeBeforePost me dice "E2010: Incompatible types 'THTTPClient' and 'Pointer'"

y no la puedo recompilar (no se como corregir el error).

Podría alguien enviar el fichero VerifactuD7.bpl y dcp recompilados con la nueva funcion (o si algún moderador pudiera subirla al área de descarga )?

P.D.
Las aplicaciones las tengo en Delphi 7, y el componente VerifactuD7 lo había compilado en Delphi12 perfectamente, el fallo me da ahora al cambiar la función "consultar".

Muchas gracias¡¡

Matorral 10-02-2025 11:13:28

Perdonad¡¡¡

Pero creo que me he liado un "POCO".

La corrección de la función consultar es del servidor de envíos (ese no lo había compilado antes en Delphi 12, lo utilice tal cual lo había descargado).

O sea, que lo que necesitaría para poder seguir es el servidor (msgVerifactu.exe) con la corrección hecha.

Gracias y mil disculpas de nuevo.

DarkDudae 10-02-2025 12:14:30

Conseguido enviar desde DLL
 
Buenos días compañeros/as:

He conseguido enviar facturas desde una dll creada en Delphi 10.2 con llamadas desde Delphi 7.
Para hacer las pruebas, como primera aproximación simplemente he embebido el formulario de la demo 2 dentro de la dll para ver que pudiese enviar facturas, y efectivamente, puede, así como mantener el resto de funcionalidades.

Luego a modo extra he implementado la carga de certificados también usando la dll desde Delphi 7. Con esto no sé si verdaderamente sería necesaria una "aplicación servidora" ejecutándose en segundo plano.

Os paso el código:
Código Delphi 7 DLL

seccion_31 10-02-2025 12:29:16

Cita:

Empezado por DarkDudae (Mensaje 561876)
Buenos días compañeros/as:

He conseguido enviar facturas desde una dll creada en Delphi 10.2 con llamadas desde Delphi 7.
Para hacer las pruebas, como primera aproximación simplemente he embebido el formulario de la demo 2 dentro de la dll para ver que pudiese enviar facturas, y efectivamente, puede, así como mantener el resto de funcionalidades.

Luego a modo extra he implementado la carga de certificados también usando la dll desde Delphi 7. Con esto no sé si verdaderamente sería necesaria una "aplicación servidora" ejecutándose en segundo plano.

Os paso el código:
Código Delphi 7 DLL

perfecto, porque asi quedara mas elegante y seguro.

A ver si puedo descargarlo.

seccion_31 10-02-2025 12:30:52

Cita:

Empezado por Matorral (Mensaje 561874)
Perdonad¡¡¡

Pero creo que me he liado un "POCO".

La corrección de la función consultar es del servidor de envíos (ese no lo había compilado antes en Delphi 12, lo utilice tal cual lo había descargado).

O sea, que lo que necesitaría para poder seguir es el servidor (msgVerifactu.exe) con la corrección hecha.

Gracias y mil disculpas de nuevo.

Ese error lo tuve al reves cuando hice la implementacion usando codigo encontrado (hay un codigo gemelo para tu version de Delphi, pero no lo puedo implementar) . La semana que viene saldra el update del componente, ya sea en version ejecutable o dll visto el posteo de darkdudae.

saludos !

DarkDudae 10-02-2025 12:38:42

Cita:

Empezado por seccion_31 (Mensaje 561878)
perfecto, porque asi quedara mas elegante y seguro.

A ver si puedo descargarlo.

Perdonad, no había puesto el enlace en público y ahora Google dice que tiene que revisarlo :eek:

Voy a borrar el exe por si ese fuese el motivo.

DarkDudae 10-02-2025 12:44:23

Aquí lo tenéis:

DEMO LLAMADAS DESDE DLL

El pass de descompresión es: "clubdelphi"

Dentro tenéis los dos proyectos:

"verifactu_multi.dproj" creada con Delphi 10.2 (dll)
"Llamada_dll.dpr", con el código de un ejecutable desarrollado en Delphi 7 que interactua con la dll anterior.

ramherfer 10-02-2025 19:45:12

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,

DarkDudae 10-02-2025 19:59:43

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…
Un saludo,

Yo tengo pensadas dos aproximaciones:

1) Incluir un campo de ANULADA booleano a la tabla cabecera de facturas e incluirlo en la clave primaria. Adicionalmente se debería poner un campo de fecha/hora anulación.

O…

2) crear una tabla de STATUS de las facturas. En esta tabla podríamos almacenar Serie de factura, número de la misma, año fiscal, tipo de factura, si es alta, anulación, rectificación…, la huella, el csv, y demás datos que puedan interesar. Luego se relacionaria fácilmente esta tabla con la de cabeceras de las facturas.


La franja horaria es GMT +2. Ahora son las 21:22:35.

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