Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   SII -Nuevo sistema de la Agencia Tributaria española de envío de datos vía Webservice (https://www.clubdelphi.com/foros/showthread.php?t=91252)

newtron 13-12-2016 19:17:43

SII -Nuevo sistema de la Agencia Tributaria española de envío de datos vía Webservice
 
Hola a tod@s.

Pues eso, la semana pasada la Agencia Tributaria española ha sacado una nueva ley por la que determinadas empresas que hacen la declaración del I.V.A. mensual deben de enviar los datos de facturación en un plazo máximo de 4 días desde la emisión o la anotación de la factura en cuestión. Este envío de información se hará mediante webservices y la verdad es que a mi me ha pillado fuera de juego con tema.

¿Alguien ha visto ya algo sobre este asunto en particular? ¿Algún tutorial o algo donde pueda enterarme mínimamente cómo va el tema este de los webservices con Delphi? porque actualmente estoy nulo sobre esto.

Gracias y un saludo

Casimiro Notevi 13-12-2016 19:56:42

Había leido que de momento solo será aplicable a grandes empresas, ¿ahora es para todas?

AgustinOrtu 13-12-2016 20:19:47

Por que te preocupa? Documentacion del webservice? Que protocolo usa? Ellos deberian darte el tutorial y la especificacion de su webservice

Al González 13-12-2016 20:34:15

Un servicio Web normalmente se representa con una interfaz, que para fines prácticos es como una clase de las de toda la vida.

En Delphi, usa la opción de menú Import WSDL, especificando la URL y demás datos que te proporciona la agencia tributaria. Eso generará una unidad .pas con el código Delphi necesario para que desde tu proyecto puedas escribir algo como:

...
WSFactura.NIF := '....';
WSFactura.IVA := 100;
WSFactura.Enviar;
...

Por falta de tiempo no puedo extenderme más, pero seguro que no te quedarás aquí. Hay bastante material en otros hilos del Club, además de las siguientes respuestas de los compañeros.

¡Saludos!

fjcg02 13-12-2016 22:01:02

Al tiene razón, suena todo muy rimbombante, pero al final sigues el procedimiento, te conectas , importas el WSDL y se te crea una unidad con todas las funciones que puedes emplear.

Lo contrastas con la documentación y empiezas a hacer pruebas. Te tendrán que indicar los pasos para conectarte, hacer una consulta, un envío, ... y comprobar que lo que has enviado se ha recibido correctamente.

Si no te da problemas, en una mañana tendrías que estar haciendo pruebas.

Un saludo

newtron 14-12-2016 09:54:37

Cita:

Empezado por Casimiro Notevi (Mensaje 511726)
Había leido que de momento solo será aplicable a grandes empresas, ¿ahora es para todas?

En principio se aplica a todas las grandes empresas y a las que, por distintos motivos, hagan las declaraciones de IVA mensual en vez de trimestral. La verdad es que en mi caso son unos pocos clientes pero aunque solo tuviera uno ya tendría que adaptar los programas a esto y por otro lado me da en la nariz que todo esto al final acabará implantándose para la mayoría de las empresas.

Cita:

Empezado por AgustinOrtu (Mensaje 511728)
Por que te preocupa? Documentacion del webservice? Que protocolo usa? Ellos deberian darte el tutorial y la especificacion de su webservice

Me preocupa porque es un "jardín" en el que nunca me he metido y no tengo la más mínima idea ni de cómo va ni cómo empezar.

Al, fjcg02 gracias por vuestras respuestas, habrá que ir empezando a ver cómo va todo este asunto.

Iré haciendo alguna prueba y si me atasco ya os comento.

Gracias a todos.

Nasca 14-12-2016 10:35:02

Nos vamos a divertir bastante con esta jugada con puente y alevosía de la A.Tributaria :mad:

En este caso concreto los procedimientos del Webservice se limitan a recibir un archivo xml de entrada y devolver una respuesta también en xml. Del tipo:

Código:

        <wsdl:operation name="SuministroLRFacturasEmitidas">

            <wsdl:input message="siiWdsl:EntradaSuministroLRFacturasEmitidas"/>

            <wsdl:output message="siiWdsl:RespuestaSuministroLRFacturasEmitidas"/>

        </wsdl:operation>

No hay funciones ni propiedades de utilidad real. Esto te permite obviar en Delphi el WSDL y SOAP. Se puede utilizar el wsdl solo como referencia.

La parte mas interesante del proceso es autentificar con certificado de usuario aceptado por la Agencia Tributaria y el no depender de SOAP te permite opciones mas directas y flexibles.

newtron 14-12-2016 10:36:24

Hola de nuevo.

Si algún amable forero le echara un vistazo a este documento distribuido por la Agencia Tributaria y me dijera si hay todo lo necesario para poner en marcha el tema se lo agradecería.

Saludos

newtron 14-12-2016 10:39:13

Cita:

Empezado por Nasca (Mensaje 511742)
No hay funciones ni propiedades de utilidad real. Esto te permite obviar en Delphi el WSDL y SOAP. Se puede utilizar el wsdl solo como referencia.

La parte mas interesante del proceso es autentificar con certificado de usuario aceptado por la Agencia Tributaria y el no depender de SOAP te permite opciones mas directas y flexibles.

Gracias Nasca pero no me entero. ¿Algún ejemplo disponible para ver cómo va este asunto?

Gracias

Nasca 14-12-2016 10:43:50

Cita:

Empezado por newtron (Mensaje 511743)
Hola de nuevo.

Si algún amable forero le echara un vistazo a este documento distribuido por la Agencia Tributaria y me dijera si hay todo lo necesario para poner en marcha el tema se lo agradecería.

Usa ese documento para hacerte una idea general del procedimiento pero para implementar mejor olvídate de él y tira de la documentación técnica que hay referida en el wsdl:

https://www2.agenciatributaria.gob.e...diatoInfo.wsdl
https://www2.agenciatributaria.gob.e...nformacion.xsd
https://www2.agenciatributaria.gob.e...ministroLR.xsd
https://www2.agenciatributaria.gob.e...ConsultaLR.xsd
https://www2.agenciatributaria.gob.e...ConsultaLR.xsd
https://www2.agenciatributaria.gob.e...Suministro.xsd


Al final es la última palabra al respecto. Está en pleno desarrollo y cambiando constantemente. Los documentos explicativos como el que indicas se quedarán desactualizados pronto.
Establecer un sistema que te permita descargar las últimas versiones y ver si se han producido cambios viene muy bien.

newtron 15-12-2016 13:42:48

Ok.

Me he creado un proyecto nuevo, he picado en File-Other-WSDL Importer, introduzco la dirección "https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroInmediatoInfo.wsdl" y me crea una unidad nueva llamada "SuministroInmediatoInfo". Hasta aquí todo sin problemas.

Por otro lado he insertado un componente HTTPRIO1 y lo he configurado con la dirección que he puesto anteriormente, el puerto y el servicio.

Ahora toca enviar datos de una factura (por ejemplo) y recibir el resultado (si es ok la comunicación o no). Imagino que será con la función "SuministroLRFacturasEmitidas" pero no sé qué parámetros pasarle.

¿Alguien me orienta?

Saludos

Nasca 15-12-2016 14:00:55

Antes de poder enviar peticiones, revisa esquemas xsd o baja SOAPUI o plugins SOAP para un navegador para ello, tendrás que resolver el tema de la comunicación.

Las comunicaciones son SSL, por https, y además autentificadas con certificado digital de FNMT o similar.

newtron 15-12-2016 16:44:43

Creo que si me lo hubieras dicho en chino mandarín me hubiera enterado de algo. :D

fjcg02 15-12-2016 17:26:21

Tienes que analizar las funciones que te proporciona la unidad que te ha creado.
Con esas funciones, tendrás que saber qué parámetros necesitas y de qué tipo son. Con ellas deberás de ser capaz de conectarte, hacer login, hacer peticiones de información, hacer subidas de información, ... y además saber qué códigos devuelve cada una de ellas para saber si han ido bien o mal.

En los casos en que los he utilizado, siempre revisando la documentación, hago lo siguiente:
url de conexión, la que te diga la documentación.
certificado o nombre de usuario, o lo que sea.
crear la variable que devuelve los datos. Si es un string, posteriormente hay que pasarla a xml o lo que necesites en tu caso.

El proceso suele ser así:
datos de conexión. La url que te digan. No es la ".wsdl", será algo así
https://www.agencia.factura:8080/services/facturae
Login, a través de la función/funciones de la unidad que has creado.
Si va bien, hacer petición. El resultado suele quedar en una variable. tendrás funciones en la unidad que has creado.
procesar variable. Este tema ya es tuyo, lo que quieras hacer.
desconexión. a través de las funciones de la nueva unidad.

Yo creo que no tienes que utilizar ningún componente HTTPRIO1.

Si puedes publicar la unidad que te ha creado, te podemos dar pistas de por dónde pegan los tiros. Pero como ya he comentado, hay que tirar de documentación.

Un saludo

newtron 15-12-2016 17:35:57

Ok, imagino que esto será de dominio público.

La unidad tiene así como 6600 líneas y no puedo pegarla aquí, la adjunto aquí.

Gracias y un saludo

bucanero 15-12-2016 18:55:48

Hola foro,

Voy a intentar aportar algo al respecto, no uso ese WS de la AEAT por lo que no se exactamente los parámetros que hay que rellenar, pero si he importado WS de otros portales con un funcionamiento parecido.

Tras importar el WS del link de la AEAT y generar la correspondiente unit, el funcionamiento debería de ser algo así:

Código Delphi [-]
var
  ASuministroLRFacturasEmitidas:SuministroLRFacturasEmitidas;
  ARegistroLRFacturasEmitidas:Array_Of_LRfacturasEmitidasType;
begin
  try
    //se crea un array con el numero de facturas que se van a emitir
    //en este ejemplo solo 1, pero pueden ser mas
    SetLength(ARegistroLRFacturasEmitidas, 1);

    //se introducen los datos de cada una de las facturas
    ARegistroLRFacturasEmitidas[0].IDFactura:='tu  numero de factura';

    // ... rellenar aqui el resto de datos necesarios
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.  := ... ;
    ARegistroLRFacturasEmitidas[0].PeriodoImpositivo. := ... ; 
    



    //se crea el objeto que se va a enviar
    ASuministroLRFacturasEmitidas := SuministroLRFacturasEmitidas.Create;
    ASuministroLRFacturasEmitidas.Cabecera.Titular.NombreRazon:='tu nombre';
    ASuministroLRFacturasEmitidas.Cabecera.Titular.NIF:='tu nif';

    //Un valor de la lista TipoComuniacion. Ver en la documentacion
    ASuministroLRFacturasEmitidas.Cabecera.TipoComunicacion:='A4';

    //se añade el array de facturas creado anteriormente
    ASuministroLRFacturasEmitidas.RegistroLRFacturasEmitidas:=ARegistroLRFacturasEmitidas;

    try
      // se hace la llamada a la funcion suministrada por el WS
      GetsiiSOAP.SuministroLRFacturasEmitidas(ASuministroLRFacturasEmitidas);
    except
      On E:Exception do
        //El proceso de envio dio error
        MessageDlg(E.Message, mtError, [mbOK], 0);
    end;
  finally
    // se eliminan los objetos creados
    ASuministroLRFacturasEmitidas.Free;
    setLength(ARegistroLRFacturasEmitidas, 0);
  end;
end;

Espero que esto pueda aportar algo de luz al tema

Un Saludo

newtron 16-12-2016 18:11:51

Gracias bucanero.

Haré pruebas con ese código a ver qué pasa.

Saludos

RUBEN_SP 19-12-2016 11:06:01

Hola Newtron. Tengo el mismo problema que tu.

Probaste el código de Bucanero? Que Tal?

Saludos

newtron 19-12-2016 12:12:10

Hola.

Estoy haciendo pruebas y creo que los tiros no van exactamente por ahí, lo que hay que enviar son ficheros XML (creo). De una forma o de otra, cuando intento ejecutar el código que amablemente nos ha puesto el colega bucanero no me compila, en la primera línea:

Código Delphi [-]
    //se introducen los datos de cada una de las facturas
    ARegistroLRFacturasEmitidas[0].IDFactura:='tu  numero de factura';

me da el error: E2010 Incompatible types: 'IDFacturaExpedidaType' and 'string'

... sigo probando.

Casimiro Notevi 19-12-2016 12:20:23

¿Puede ser un identificador de la factura, no el número en sí, y que luego habrá otro campo para el número?
Código:

ARegistroLRFacturasEmitidas[0].IDFactura:=1;
ARegistroLRFacturasEmitidas[0].¿NumFactura?:='A123';

Solo es una suposición.

newtron 19-12-2016 12:36:01

Cita:

Empezado por Casimiro Notevi (Mensaje 511867)
¿Puede ser un identificador de la factura, no el número en sí, y que luego habrá otro campo para el número?
Código:

ARegistroLRFacturasEmitidas[0].IDFactura:=1;
ARegistroLRFacturasEmitidas[0].¿NumFactura?:='A123';

Solo es una suposición.

No, lo que dice es que al campo "ARegistroLRFacturasEmitidas[0].IDFactura" sólo se le puede asignar una variable de tipo IDFacturaExpedidaType, no un string ni un integer, etc.

Edito:

Estoy pensando e igual suelto una tontería.... ¿hay forma de asignarle un fichero XML con unas características determinadas a la variable ARegistroLRFacturasEmitidas?

fjcg02 19-12-2016 12:50:39

Hola Newtron,
según la documentación que aportas, el "idFactura" del "RegistroLRFacturasEmitidas" debe ser :
IDEmisorFactura: (NIF) NIF asociado al emisor de la factura. FormatoNIF(9)
NumSerieFacturaEmisor: Número+Serie que identifica a la factura emitida. Alfanumérico(60)
NumSerieFacturaEmisorResumenFin: Número+serie que identifica a la ultima factura cuando el Tipo de Factura es un asiento resumen de facturas. Alfanumérico(60)
FechaExpedicionFacturaEmisor:Fecha de expedición de la factura. Fecha(dd-mm-yyyy)
( página 55 de la documentación)

Por lo que he leido, hay que montar un xml con los formatos que te ponen. Una vez lo tengas montado, haces la conexión y en la función de llamada lo metes como parámetro. Luedo te da la respuesta.

Según lo que he entendido, es como montar un cuaderno bancario de cobros y pagos ( el 19 suele ser el más habitual ), pero en vez de usar un fichero de texto, utilizar el xml con el formato que te ponen en la documentación.

El arte es ir montando el código para que coja tus datos de la aplicación, monte el xml, y haga la conexión a la agencia.

Saludos

newtron 19-12-2016 12:54:08

Cita:

Empezado por fjcg02 (Mensaje 511869)
Hola Newtron,
según la documentación que aportas, el "idFactura" del "RegistroLRFacturasEmitidas" debe ser :
IDEmisorFactura: (NIF) NIF asociado al emisor de la factura. FormatoNIF(9)
NumSerieFacturaEmisor: Número+Serie que identifica a la factura emitida. Alfanumérico(60)
NumSerieFacturaEmisorResumenFin: Número+serie que identifica a la ultima factura cuando el Tipo de Factura es un asiento resumen de facturas. Alfanumérico(60)
FechaExpedicionFacturaEmisor:Fecha de expedición de la factura. Fecha(dd-mm-yyyy)
( página 55 de la documentación)

Por lo que he leido, hay que montar un xml con los formatos que te ponen. Una vez lo tengas montado, haces la conexión y en la función de llamada lo metes como parámetro. Luedo te da la respuesta.

Según lo que he entendido, es como montar un cuaderno bancario de cobros y pagos ( el 19 suele ser el más habitual ), pero en vez de usar un fichero de texto, utilizar el xml con el formato que te ponen en la documentación.

El arte es ir montando el código para que coja tus datos de la aplicación, monte el xml, y haga la conexión a la agencia.

Saludos

Gracias, ¿y un pequeño ejemplo de cómo se hace la conexión y la función de llamada sería posible?

Saludos

bucanero 19-12-2016 13:02:22

Hola foro, aqui el codigo de llamada un poco mas desarrollado:

Código Delphi [-]
var
  ASuministroLRFacturasEmitidas:SuministroLRFacturasEmitidas;
  ARegistroLRFacturasEmitidas:Array_Of_LRfacturasEmitidasType;
begin
  try
    //se crea un array con el numero de facturas que se van a emitir
    //en este ejemplo solo 1, pero pueden ser mas
    SetLength(ARegistroLRFacturasEmitidas, 1);

    //se introducen los datos de cada una de las facturas
//    for i := Low(ARegistroLRFacturasEmitidas) to High(ARegistroLRFacturasEmitidas) do begin

    ARegistroLRFacturasEmitidas[0].IDFactura.IDEmisorFactura.NIF  :='123456789X';             // NIFType         =  type string;
    ARegistroLRFacturasEmitidas[0].IDFactura.NumSerieFacturaEmisor:='algo';                   // TextoIDFacturaType =  type string;
    ARegistroLRFacturasEmitidas[0].IDFactura.NumSerieFacturaEmisorResumenFin:='y algo mas';   // TextoIDFacturaType =  type string;
    ARegistroLRFacturasEmitidas[0].IDFactura.FechaExpedicionFacturaEmisor:='15/12/2016';      // fecha           =  type string;

    // ... rellenar aqui el resto de datos necesarios, no se exactamente a que se corresponden,
    // hay que mirar la documentacion correspondiente, algunos de estos datos pueden ser  tambien classes
    // con mas estructuras de datos
    (*
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.DatosInmueble:=...;          //tipo DatosInmueble2
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.ImporteTransmisionSujetoAIVA://tipo  ImporteSgn12_2Type
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.EmitidaPorTerceros:          //tipo  EmitidaPorTercerosType
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.Contraparte:                 //tipo  PersonaFisicaJuridicaType
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.TipoDesglose:                //tipo  TipoDesglose2
    (**)

    ARegistroLRFacturasEmitidas[0].PeriodoImpositivo.Ejercicio:='2016';               //YearType:  type string;
    ARegistroLRFacturasEmitidas[0].PeriodoImpositivo.periodo  :=TipoPeriodoType(11);  //  TipoPeriodoType = ( _01, _02, _03, _04, _05, _06, _07, _08, _09, _10, _11, _12, _0A);

//    end;


    //se crea el objeto que se va a enviar
    ASuministroLRFacturasEmitidas := SuministroLRFacturasEmitidas.Create;
    ASuministroLRFacturasEmitidas.Cabecera.Titular.NombreRazon:='tu nombre'; //creo que esto puede ser el nombre del cliente
    ASuministroLRFacturasEmitidas.Cabecera.Titular.NIF:='tu nif';            // y esto el CIF del cliente

    //Un valor de la lista TipoComuniacion. Ver en la documentacion
    ASuministroLRFacturasEmitidas.Cabecera.TipoComunicacion:=ClaveTipoComunicacionType(1); // definida como   ClaveTipoComunicacionType = (A0, A1, A4);

    //se añade el array de facturas creado anteriormente
    ASuministroLRFacturasEmitidas.RegistroLRFacturasEmitidas:=ARegistroLRFacturasEmitidas;

    try
      // se hace la llamada a la funcion suministrada por el WS
      GetsiiSOAP.SuministroLRFacturasEmitidas(ASuministroLRFacturasEmitidas);
    except
      On E:Exception do
        //El proceso de envio dio error
        MessageDlg(E.Message, mtError, [mbOK], 0);
    end;
  finally
    // se eliminan los objetos creados
    ASuministroLRFacturasEmitidas.Free;
    setLength(ARegistroLRFacturasEmitidas, 0);
  end;


Este código compila sin problemas, pero los parámetros hay que ver en la propia documentación a que corresponden y cuales son opcionales u obligatorios. Las partes de información de facturación desabilitadas pueden a su vez ser mas classes con mas propiedades.

Un Saludo

fjcg02 19-12-2016 14:12:33

newtron,
no tengo código, simplemente me llamó la atención la pregunta y he leido los links que pusiste. No me dedico a ésto.

el chiste es montar los xml con los formatos que te dan ( en la propia documentación te muestran esquemáticamente cómo quedaría el árbol del xml, y luego hacer la llamada a la superfunción que hace todo.

Código Delphi [-]
SuministroLRFacturasEmitidas(const SuministroLRFacturasEmitidas: SuministroLRFacturasEmitidas): RespuestaLRFacturasEmitidas

todas las clases las tienes definidas en la unidad SuministroInmediatoInfo.pas

En este caso SuministroLRFacturasEmitidas para la llamada y RespuestaLRFacturasEmitidas para la respuesta.

Neftali [Germán.Estévez] 19-12-2016 15:22:50

Cita:

Empezado por newtron (Mensaje 511866)
me da el error: E2010 Incompatible types: 'IDFacturaExpedidaType' and 'string'

¿Puede ser porque el IDFactura no es un tipo simple?
Tal y como está en el documento que han adjuntado más arriba...

Código Delphi [-]
  LRfacturasEmitidasType = class(RegistroSii)
  private
    FIDFactura: IDFacturaExpedidaType;
    FFacturaExpedida: FacturaExpedidaType;
  public
    destructor Destroy; override;
  published
    property IDFactura:       IDFacturaExpedidaType  read FIDFactura write FIDFactura;
    property FacturaExpedida: FacturaExpedidaType    read FFacturaExpedida write FFacturaExpedida;
  end;

Y el tipo IDFacturaExpedidaType está definido tal que así:

Código Delphi [-]

  // ************************************************************************ //
  // XML       : IDFacturaExpedidaType, global, 
  // Namespace : https://www2.agenciatributaria.gob.e...nformacion.xsd
  // ************************************************************************ //
  IDFacturaExpedidaType = class(TRemotable)
  private
    FIDEmisorFactura: IDEmisorFactura3;
    FNumSerieFacturaEmisor: TextoIDFacturaType;
    FNumSerieFacturaEmisorResumenFin: TextoIDFacturaType;
    FNumSerieFacturaEmisorResumenFin_Specified: boolean;
    FFechaExpedicionFacturaEmisor: fecha;
    procedure SetNumSerieFacturaEmisorResumenFin(Index: Integer; const ATextoIDFacturaType: TextoIDFacturaType);
    function  NumSerieFacturaEmisorResumenFin_Specified(Index: Integer): boolean;
  public
    destructor Destroy; override;
  published
    property IDEmisorFactura:                 IDEmisorFactura3    read FIDEmisorFactura write FIDEmisorFactura;
    property NumSerieFacturaEmisor:           TextoIDFacturaType  read FNumSerieFacturaEmisor write FNumSerieFacturaEmisor;
    property NumSerieFacturaEmisorResumenFin: TextoIDFacturaType  Index (IS_OPTN) read FNumSerieFacturaEmisorResumenFin write SetNumSerieFacturaEmisorResumenFin stored NumSerieFacturaEmisorResumenFin_Specified;
    property FechaExpedicionFacturaEmisor:    fecha               read FFechaExpedicionFacturaEmisor write FFechaExpedicionFacturaEmisor;
  end;

Es un comentario.

newtron 19-12-2016 16:50:31

Bucanero, fjcg02, Neftali, gracias por vuestros comentarios.

Estoy probando el nuevo código de Bucanero y, en la primera línea

Código Delphi [-]
    ARegistroLRFacturasEmitidas[0].IDFactura.IDEmisorFactura.NIF  :='123456789X';             // NIFType         =  type string;

me da un error "Access Violation".

Sigo probando.

Saludos

bucanero 19-12-2016 17:01:55

como ha comentado Neftali, son objetos de tipo class(TRemotable), y necesitas crearlos antes de llamar a sus elementos, yo suelo añadir en la propia clase la funcion create al propio objeto con la propiedad override, para dejar el código mas limpio,

Código Delphi [-]
var
  i:LongInt;
  ASuministroLRFacturasEmitidas:SuministroLRFacturasEmitidas;
  ARegistroLRFacturasEmitidas:Array_Of_LRfacturasEmitidasType;
  result:RespuestaLRFacturasEmitidas;
begin
  try
    //se crea un array con el numero de facturas que se van a emitir
    //en este ejemplo solo 1, pero pueden ser mas
    SetLength(ARegistroLRFacturasEmitidas, 1);

    //se introducen los datos de cada una de las facturas
//    for i := Low(ARegistroLRFacturasEmitidas) to High(ARegistroLRFacturasEmitidas) do begin

    //Se crean todas las estructuras de datos de la consulta
    ARegistroLRFacturasEmitidas[0]:=LRfacturasEmitidasType.Create;
    ARegistroLRFacturasEmitidas[0].IDFactura:=IDFacturaExpedidaType.create;
    ARegistroLRFacturasEmitidas[0].FacturaExpedida:=FacturaExpedidaType.create;

    (*
    //aqui tambien hay que crear el resto de objetos que haya que enviar
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.DatosInmueble:= ;                              //array of DatosInmuebleType;
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.ImporteTransmisionSujetoAIVA:= ;               //ImporteSgn12_2Type =  type string;

    ARegistroLRFacturasEmitidas[0].FacturaExpedida.EmitidaPorTerceros:=EmitidaPorTercerosType(0); //EmitidaPorTercerosType = (S, N);
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.Contraparte:= PersonaFisicaJuridicaType.create;
    // ARegistroLRFacturasEmitidas[0].FacturaExpedida.TipoDesglose:= TipoDesglose2.create;
    //...
    (**)

    ARegistroLRFacturasEmitidas[0].PeriodoImpositivo:=PeriodoImpositivo.Create;

    With ARegistroLRFacturasEmitidas[0].IDFactura do begin
       IDEmisorFactura:= IDEmisorFactura3.create;
       IDEmisorFactura.NIF  :='123456789X';             // NIFType         =  type string;
       NumSerieFacturaEmisor:='algo';                   // TextoIDFacturaType =  type string;
       NumSerieFacturaEmisorResumenFin:='y algo mas';   // TextoIDFacturaType =  type string;
       FechaExpedicionFacturaEmisor:='15/12/2016';      // fecha           =  type string;
    end;

(*
    // ... rellenar aqui el resto de datos necesarios, no se exactamente a que se corresponden,
    // hay que mirar la documentacion correspondiente, algunos de estos datos pueden ser  tambien classes
    // con mas estructuras de datos

    ARegistroLRFacturasEmitidas[0].FacturaExpedida.DatosInmueble:=...;          //tipo DatosInmueble2
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.ImporteTransmisionSujetoAIVA://tipo  ImporteSgn12_2Type
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.EmitidaPorTerceros:          //tipo  EmitidaPorTercerosType
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.Contraparte:                 //tipo  PersonaFisicaJuridicaType
    ARegistroLRFacturasEmitidas[0].FacturaExpedida.TipoDesglose:                //tipo  TipoDesglose2

(**)
    ARegistroLRFacturasEmitidas[0].PeriodoImpositivo.Ejercicio:='2016';         //YearType:  type string;

    //  TipoPeriodoType = ( _01, _02, _03, _04, _05, _06, _07, _08, _09, _10, _11, _12, _0A);
    ARegistroLRFacturasEmitidas[0].PeriodoImpositivo.periodo  :=TipoPeriodoType(11);

//    end;

    //se crea el objeto que se va a enviar
    ASuministroLRFacturasEmitidas := SuministroLRFacturasEmitidas.Create;
    ASuministroLRFacturasEmitidas.Cabecera := CabeceraSii.Create;
    ASuministroLRFacturasEmitidas.Cabecera.titular := PersonaFisicaJuridicaESType.Create;

    ASuministroLRFacturasEmitidas.Cabecera.Titular.NombreRazon:='tu nombre'; //creo que esto puede ser el nombre del cliente
    ASuministroLRFacturasEmitidas.Cabecera.Titular.NIF:='tu nif';            // y esto el CIF del cliente

    //Un valor de la lista TipoComuniacion. Ver en la documentacion
    // definida como   ClaveTipoComunicacionType = (A0, A1, A4);
    ASuministroLRFacturasEmitidas.Cabecera.TipoComunicacion:=ClaveTipoComunicacionType(1);

    //se añade el array de facturas creado anteriormente
    ASuministroLRFacturasEmitidas.RegistroLRFacturasEmitidas:=ARegistroLRFacturasEmitidas;

    try
      // se hace la llamada a la funcion suministrada por el WS
      result := GetsiiSOAP.SuministroLRFacturasEmitidas(ASuministroLRFacturasEmitidas);

      //mostrar los resultados devueltos por la llamada
      for i := low(result.RespuestaLinea) to High(result.RespuestaLinea) do begin
        with result.RespuestaLinea[i] do begin
          Memo1.lines.add('factura: ' + IDFactura.NumSerieFacturaEmisor + ' ' + IDFactura.NumSerieFacturaEmisorResumenFin + ' ' + IDFactura.FechaExpedicionFacturaEmisor);
          //si el estado no es correcto, se muestran los errores
          if EstadoRegistro <> EstadoRegistroType(0) then begin
            Memo1.lines.add('Error no.: ' + InttoStr(CodigoErrorRegistro));
            Memo1.lines.add(DescripcionErrorRegistro);
          end;
        end;
      end;
    except
      On E:Exception do
        //El proceso de envio dio error
        MessageDlg(E.Message, mtError, [mbOK], 0);
    end;
  finally
    // se eliminan los objetos creados
    ASuministroLRFacturasEmitidas.Free;
    result.Free;
  end;

Este codigo, salvo la llamada, que no quiero hacerla por que los datos introducidos no son validos, no da access Violation

Neftali [Germán.Estévez] 19-12-2016 17:19:15

Se trata de hacerlo en orden inverso.
Ir creando los objetos a medidas que los vas necesitando....

Código Delphi [-]
var
  ASuministroLRFacturasEmitidas:SuministroLRFacturasEmitidas;
  ARegistroLRFacturasEmitidas:Array_Of_LRfacturasEmitidasType;
  IDFact:IDFacturaExpedidaType;
  IDEmisorFact:IDEmisorFactura3;
begin
  try
    //se crea un array con el numero de facturas que se van a emitir
    //en este ejemplo solo 1, pero pueden ser mas
    SetLength(ARegistroLRFacturasEmitidas, 1);

    // Crear el emisor
    IDEmisorFact := IDEmisorFactura3.Create();
    IDEmisorFact.NIF := '12345678M';

    // Crear
    IDFact := IDFacturaExpedidaType.Create();
    IDFact.IDEmisorFactura := IDEmisorFact;
    IDFact.NumSerieFacturaEmisor := 'Texto factura';
    IDFact.NumSerieFacturaEmisorResumenFin := 'Num serie fact. ';
    IDFact.FechaExpedicionFacturaEmisor := '31/12/2016';

    //se introducen los datos de cada una de las facturas
    ARegistroLRFacturasEmitidas[1].IDFactura := IDFact;
    ARegistroLRFacturasEmitidas[1].FacturaExpedida := ...

Se me han adelantado...

newtron 19-12-2016 17:40:28

Bucanero, Neftali, gracias por vuestra respuesta.

Efectivamente ya no da errores. Como yo soy más lanzado no he tenido problemas en hacer la llamada "a ver qué pasa", y en principio me decía: Invalid url 'xxxxxxxxx'

Echando un vistazo al código veo que esa url está informada en este trozo de código:

Código Delphi [-]
function GetsiiSOAP(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): siiSOAP;
const
  defWSDL = 'https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroInmediatoInfo.wsdl';
  defURL  = 'xxxxxxxxxxx';
  defSvc  = 'siiService';
  defPrt  = 'SuministroFacturasPruebas';
var
  RIO: THTTPRIO;
begin


En principio he pensado que habría que sustituir 'xxxxxxxxxxxx' por alguna url válida y he mirado en la documentación algo relacionado con esto pero no he encontrado nada. Luego me he dado cuenta de que dependiendo del parámetro "UseWSDL" si está en True o False coge la constante defWSDL o defURL así que he cambiado el valor a true de la definición de la función

Código Delphi [-]
function GetsiiSOAP(UseWSDL: Boolean=System.True; Addr: string=''; HTTPRIO: THTTPRIO = nil): siiSOAP;

con lo cual ahora coge el valor de defWSDL y hace correctamente la llamada (parece) pero, claro, ahora me dice que se requiere un certificado para completar la autenticación del cliente.

Yo tengo un certificado instalado pero imagino que esto no se entera. ¿Hay alguna forma de informar del certificado?

Saludos

Edito:

También he cambiado el valor de defPrt = 'SuministroFacturas' a 'SuministroFacturasPruebas' para hacer las pruebas.

newtron 09-01-2017 13:03:42

Hola a tod@s y Feliz Año.

¿Hay algún avance sobre este tema? Lo que quedaba era poder hacer la llamada informando de alguna manera del certificado digital con el que se hace la llamada.

Saludos

newtron 09-01-2017 17:22:01

He encontrado este enlace en el que se ve un ejemplo de llamada incluyendo un certificado usando CAPICOM.

Si alguien le quiere echar un vistazo yo seguiré haciendo pruebas a ver si resuelvo algo.

Saludos

Virman 10-01-2017 16:40:08

Un usuario de esa página dice que no funciona en Delphi, alguno lo ha probado?

Virman 11-01-2017 10:45:11

SuministroLRFactirasEmitidasRequest
 
Saludos, estoy tratando de enviar una factura emitida pero al llamar a la función:

GetsiiSOAP.SuministroLRFacturasEmitidas

Me pide como parámetro un objeto del tipo SuministroLRFacturasEmitidasRequest. He creado uno pasándole como parámetro ASuministroLRFacturasEmitidas en el constructor de FacturasEmitidasRequest, pero a la hora de hacer la llamada a la función SuministroLRFacturasEmitidas, me retorna error al generar el documento XML:

Error al serializar el cuerpo del mensaje SuministroLRFacturasEmitidasRequest: 'Error al generar el documento XML.'.

Alguna sugerencia o ayuda?

newtron 11-01-2017 16:36:50

Cita:

Empezado por Virman (Mensaje 512283)
Saludos, estoy tratando de enviar una factura emitida pero al llamar a la función:

GetsiiSOAP.SuministroLRFacturasEmitidas

Me pide como parámetro un objeto del tipo SuministroLRFacturasEmitidasRequest. He creado uno pasándole como parámetro ASuministroLRFacturasEmitidas en el constructor de FacturasEmitidasRequest, pero a la hora de hacer la llamada a la función SuministroLRFacturasEmitidas, me retorna error al generar el documento XML:

Error al serializar el cuerpo del mensaje SuministroLRFacturasEmitidasRequest: 'Error al generar el documento XML.'.

Alguna sugerencia o ayuda?

¿Has probado el ejemplo que hay en este mismo hilo?

De una forma o de otra ahora mismo el asunto está bloqueado a falta de saber cómo hacer la llamada usando un certificado digital instalado en el ordenador.

Saludos

Virman 11-01-2017 18:43:16

Cita:

Empezado por newtron (Mensaje 512285)
¿Has probado el ejemplo que hay en este mismo hilo?

De una forma o de otra ahora mismo el asunto está bloqueado a falta de saber cómo hacer la llamada usando un certificado digital instalado en el ordenador.

Saludos

Sí, lo probé y obtengo como bien comentas error con el certificado digital. También estoy haciendo un por en C# del código, por lo que se agradecen todos vuestros comentarios y ayuda.

Virman 13-01-2017 13:44:43

Información AEAT
 
Os adjunto el mensaje que me ha enviado la AEAT ante la pregunta de cómo obtener un certificado de pruebas o usar un certificado digital existente para el envío de Facturas Emitidas, Facturas Recibidas y Pago Recibidas:

No existe certificado de pruebas.

La presentación podrá ser efectuada por el obligado tributario, un apoderado suyo a este trámite ó un colaborador social, que deberá disponer de un certificado electrónico reconocido. Por tanto, el uso de los servicios requiere tener instalado un certificado electrónico reconocido admitido por la Agencia Tributaria, en el ordenador desde el que se produzca el envío de la información. Dicho certificado podrá ser de Persona Física ó de Persona Jurídica. Todos los NIFs se tienen que validar contra la Base de Datos Centralizada de la AEAT.

No se debe firmar el envío. No hay que inscribir el certificado en ningún censo.

Consulte la ayuda para la obtención del certificado electrónico

Atentamente,
AEAT

Si alguien consigue mandar una factura por favor que me ayude, porque yo sólo obtengo error 403: Error de identificación. No se detecta certificado digital o no se ha seleccionado correctamente. Aún cuando añado un certificado al objeto siiSoap.

newtron 13-01-2017 17:28:38

La AEAT no te va a ayudar en gran cosa en este asunto, como bien te dicen tienes que tener instalado un certificado digital válido para poder hacer la llamada.

Yo creo que la "madre del cordero" está en manejar el evento "OnBeforePost" del componente "THTTPRIO" para asignar el certificado digital correspondiente tal y como aparece en el link de ejemplo que he puesto. Yo lo que todavía no veo claro es la unidad "SignCertificate" que aparece en el ejemplo que no he sido todavía capaz de encontrar la forma de instalar o sustituir por otra similar.

Saludos

newtron 18-01-2017 19:42:03

1 Archivos Adjunto(s)
Amig@s.

Un antiguo usuario del foro (que por lo visto ya no tiene la cuenta activa por no haberla usado en muuuuuuuuuucho tiempo), después de leer este hilo, ha tenido el detalle de ponerse en contacto conmigo por mail para echarme una mano y adaptar el proyecto de ejemplo que estamos intentando sacar adelante para resolver el tema del Suministro Inmediato de Información (SII) de la AEAT, cosa que todos tendremos que agradecerle.

Ahora, tengo dos noticias, una buena y otra mala. La buena es que adjunto el proyecto con las modificaciones necesarias para, antes de hacer la llamada al webservice, asignar el certificado con el que se va a hacer la misma. La mala es que el proyecto está en la versión Berlín de Delphi, imagino que funcionará a partir de las versiones XE... en adelante pero no he conseguido de forma fácil encontrar las unidades similares (si es que las hay) para Delphi 2007 por ejemplo.

Espero que con esto podamos seguir adelante con la tarea de conseguir efectuar la llamada al dichoso webservice.

Saludos.

keys 24-01-2017 10:42:06

Hola A todos! Lo primero decir que me produce cierta alegría encontrar gente en este mundo que se esta pegando también con el nuevo sistema inmediato de información del AEAT desde delphi. Creía que era el único es este mundo. :o

Yo no voy tan adelantando como vosotros, estoy en el punto de generar los ficheros xml para mandar a la Aeat. En la información de la AEAT hay dos ficheros XSD SuministroInformacion.xsd y SuministroLR.xsd, cada uno con la definicion de dos namespace. Pero luego hay que generar un único fichero xml con los dos namespaces dentro.

Mi pregunta es como puedo generar un unico fichero xml, ya que el xml data binding sólo me deja generar el fichero de uno en uno.

Un Saludo y gracias y procurare aportar lo que pueda.


La franja horaria es GMT +2. Ahora son las 15:47:56.

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