Ir al contenido


Foto

AFIP Argentina: Consultas al padron de contribuyentes

AFIP Argentina CUIT CUIL

  • Por favor identifícate para responder
31 respuestas en este tema

#1 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 21 enero 2016 - 05:22

Hola
 
Como se puede ver en este post, existe un WebService de la AFIP que permite, entre otras cosas, realizar consultas por Numero de CUIT/DNI/etc para obtener datos de los contribuyentes registrados
 
Se trata de un servidor REST, asi que es bastante sencillo implementar las operaciones GET
Lo que quiza es medio "engorroso", es convertir el JSON y meterlo dentro de clases Delphi
Esta tarde me dedique a esto. Lamentablemente lo hice con Delphi 10 Seattle, porque queria probar los nuevos componentes TNetHttpClient y la biblioteca System.JSON; creo que ambos estan disponibles a partir de XE8, sino 10 Seattle
 
Aun asi, el codigo es facilmente adaptable (creo) para usarlo con Indy y alguna otra biblioteca Json (incluso las que venian con Delphi antes, creo que la unidad era Rest.Json)
 
Pueden obtener el codigo en mi repositorio o seguir directamente este enlace
Tambien subí la documentacion
 
Implemente solo 3 metodos, hay algunos mas que quiza implemente mas adelante (lo mismo que una version compatible con los Delphi anteriores basada en Indy)


delphi
  1. ConsultaNroDocumento(NroDocumento: string)

Devuelve todos los CUIT, CUIL, etc asociados a NroDocumento (DNI). La AFIP llama a estos numeros los "Id" de las personas


delphi
  1. ObtenerConstancia(Cuit/Cuil/Cdi: string/Int64)

Curioso metodo. Devuelve un archivo en formato PDF con la Constancia de Inscripción emitida por AFIP o con un texto indicando motivo por el cual esa constancia no pudo ser emitida.


delphi
  1. ConsultaPersona(const Cuit/Cuil/Cdi: string)

Este metodo devuelve una interface con una numerosa cantidad de campos, por ejemplo, razon social o nombre, domicilio fiscal, fecha inscripcion, estado inscripcion (activa, inactiva), si es persona fisica o juridica, etc
 
 
Saludos
  • 2

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 21 enero 2016 - 06:04

Muchas gracias por la aportación amigo Agustín, estoy seguro que será de gran ayuda para la implementación de dichas consultas.

(y)

Saludos
  • 0

#3 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 21 enero 2016 - 07:27

La verdad fue mi primera experiencia usando tanto Json como Rest; y no se si sera asi en todos lados, pero la respuesta en json que devuelve la Afip es una porqueria

 

Me explico, cuando un objeto no tiene cierto valor, en la respuesta dicho campo no existe; y es una porqueria porque el codigo queda asi:

 


php
  1. JsonValue := Json.GetValue('algunCampo');
  2. if JsonValue <> NIL then
  3. Objeto.AlgunCampo := Json.Value;

Eso repetido n veces donde n es la cantidad de campos

 

No es mucho mas sencillo para todos devolver el campo vacio? Si, esta vacio, pero al menos no hay que andar "preguntando"; hace el codigo mas largo, queda con un nivel de sangrado mayor (el cual me molesta) y mas dificil de leer

 

Al menos a mi, me resulta muy sucio

 

Saludos


  • 0

#4 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 21 enero 2016 - 10:39

Yo he estado usando un servidor REST y sus respuestas en JSON, aunque aún no tengo bien definido el proyecto, me parece una buena oportunidad de aprender.

 

Con éste proyecto se podrá recuperar el contenido de mi botácora y aceptar comentarios a través de un plugin de Wordpress, ya veremos hasta donde llego..

 

Saludos


  • 0

#5 Nikolas

Nikolas

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 604 mensajes
  • LocationMar del Plata / Bs As / Argentina

Escrito 22 enero 2016 - 07:30

muy buena info Agustin, gracias! (y)


  • 0

#6 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 24 enero 2016 - 07:25

muy buena info Agustin, gracias! (y)

Hola agustin... yo use desde el post de facturacion electronica en argentina que hay en el foro pyafipws y de hecho tiene una libreria perl solo a partir del CUIT busca datos personales y fiscales. Estos ultimos permiten conocer la condicion frente al iva y por ende el tipo de factura a emitir se calcula de la responsabilidad tributaria del vendedor y de esta.
Pero tu estas utilizando el webservice mas directo digamos el de la afip.

Otra idea que comparto es por ejemplo... al agregar un cliente al sistema se buscab los datos por CUIL. Lo mismo hago con los cheques de mi aplicacion con el titular del mismo. Se obtiene el domicilio, localidad etc...

Saludis

Enviado desde mi SM-G530M mediante Tapatalk
  • 0

#7 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 24 enero 2016 - 07:48

Te referis a http://www.sistemasa...tribuyentesAFIP ?

 

Viendo la documentacion parece que retorna lo mismo:

 


php
  1. Buscar(cuit): Realiza la búsqueda en la base de datos local de contribuyentes. Devuelve verdadero en caso de ejecución satisfactoria, falso en caso de error. Establece los atributos correspondientes. Ver Ejemplos.
  2.  
  3. Consultar(cuit): realiza la consulta online con AFIP y devulve los campos: cuit, dni, tipo_persona ("FISICA" o "JURIDICA"), tipo_doc (80: "CUIT", 96: "DNI", etc), estado ("ACTIVO"), denominacion, direccion, localidad, provincia, cod_postal, imp_iva, empleador, integrante_soc, cat_iva, monotributo, actividad_monotributo; domicilios, impuestos, actividades (listas) agregado a partir de la actualización 1.04a
  4.  
  5. DescargarConstancia(self, nro_doc, filename): realiza la consulta online con AFIP y descarga la constancia de inscripción en formato PDF (filename es el nombre de archivo a guardar, "constancia.pdf" predeterminado). Devuelve verdadero si no hubo inconveinentes, y establece el mensaje de error devuelto por AFIP en el campo Excepcion (si no sep udo descargar la constancia). agregado a partir de la actualización 1.05a


  • 0

#8 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 24 enero 2016 - 07:50

Te referis a http://www.sistemasa...tribuyentesAFIP ?

Viendo la documentacion parece que retorna lo mismo:


php
  1. Buscar(cuit): Realiza la búsqueda en la base de datos local de contribuyentes. Devuelve verdadero en caso de ejecución satisfactoria, falso en caso de error. Establece los atributos correspondientes. Ver Ejemplos.
  2.  
  3. Consultar(cuit): realiza la consulta online con AFIP y devulve los campos: cuit, dni, tipo_persona ("FISICA" o "JURIDICA"), tipo_doc (80: "CUIT", 96: "DNI", etc), estado ("ACTIVO"), denominacion, direccion, localidad, provincia, cod_postal, imp_iva, empleador, integrante_soc, cat_iva, monotributo, actividad_monotributo; domicilios, impuestos, actividades (listas) agregado a partir de la actualización 1.04a
  4.  
  5. DescargarConstancia(self, nro_doc, filename): realiza la consulta online con AFIP y descarga la constancia de inscripción en formato PDF (filename es el nombre de archivo a guardar, "constancia.pdf" predeterminado). Devuelve verdadero si no hubo inconveinentes, y establece el mensaje de error devuelto por AFIP en el campo Excepcion (si no sep udo descargar la constancia). agregado a partir de la actualización 1.05a

Exacto...

Enviado desde mi SM-G530M mediante Tapatalk
  • 0

#9 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 24 enero 2016 - 10:13

Es el mismo WebService, los datos son los mismos; lo que obtenes es la categoria de monotributo, habria que ver bien que retorna para un inscripto

 

Para obtener el resto de los datos hay que implementar el resto de los metodos, que serian estos:

 

https://soa.afip.gob...s/v1/impuestos/

https://soa.afip.gob...iasMonotributo/

 

Y similares

 

Despues es cruzar datos entre el id que te devuelve el primero y esto y ya esta

 

El problema es que la info esta incompleta, por ejemplo yo probe consultar un par de cuits que tengo de monotributos y me retorna por ej:
 


php
  1. categoriasMonotributo":[{"idImpuesto":20, "idCategoria" : 39},{"idImpuesto":21, "idCategoria" : 10}],"impuestos":[20,21]

Y si ejecuto el listado de impuestos, los impuestos con Id 20 y 21 no existen

 

y en categorias de monotributo, si tengo la la 39 "idCatMonotributo":39,"descCatMonotributo":"E LOCACIONES DE SERVICIO"

 

pero no la 10

 

Saludos


  • 0

#10 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 24 enero 2016 - 05:10

Hola de nuevo

 

He implementado los metodos que faltaban, los que segun la documentacion son del sistema "parametros", podria decirse que son "tablas auxiliares", o "tablas lookup"

 

- Impuestos

- Conceptos

- Caracterizaciones

- Etc

 

Tambien dado que alguna de estas consultas "demoran" un poquito porque devuelven mas informacion (actividades creo que devuelve unas 2500 tuplas) agregue una pequeña capa de persistencia

 

En realidad es una sencilla interface que cada desarrollador puede implementar como mas le guste y luego inyectarla en el constructor de la clase

 

Hay una implementacion de la interface a modo de ejemplo que utiliza colecciones (diccionarios) para almacenar la informacion en memoria

 

En el demo se puede ver que listar las 2500 tuplas en el memo, si hago la consulta a traves del web service, tarda unos 2,5 - 3 segundos, pero usando la info de la cache tarda 600 mseg

 

Luego tambien esta la posibilidad de aun asi "forzar" a que traiga los datos frescos del web services (los metodos tienen el parametro GetFromPersistent, por defecto a True) que indica si quiero traer los datos desde la clase de persistencia (true) o del webservice (false)

 

Lo que son consultas de datos de las personas no lo meti nada en la capa de persistencia porque es bastante rapido, es mucha menos la informacion que viene asi que no tiene sentido

 

 

Saludos


  • 2

#11 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 23 marzo 2016 - 05:40

hola..probe tu version descargada desde el repositorio..

 

primero tuve que agregar la carpeta vcl y la rtl al path del proyecto..uso delphi XE2.

 

Y obtengo un error:

 

error_zpsrh07iow5.png

 

muchas gracias


  • 0

#12 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.446 mensajes
  • LocationMéxico

Escrito 23 marzo 2016 - 06:13

hola..probe tu version descargada desde el repositorio..

 

primero tuve que agregar la carpeta vcl y la rtl al path del proyecto..uso delphi XE2.

 

Y obtengo un error:

 

 

 

muchas gracias

 

Lo mas probable es que sea una incompatibilidad de versión, estás usando XE2 y Agustín lo diseñó en Delphi 10 Seattle y pareciera que también funciona en XE8, pero XE2???

 

Saludos


  • 0

#13 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 23 marzo 2016 - 07:04

Hola giulichajari, es correcto lo que comenta Eliseo.

El problema es la característica record helper

El ayudante para los registros permite cierta "syntaxis sugar" a la hora de manipular registros, tipos primitivos y enumerativos

Lo que hay que hacer es adaptar los métodos. El siguiente es un ejemplo "en proza", estoy desde el teléfono ahora

Supongamos que tenemos un enumerativo para los valores tMasculino y tFemenino y queremos obtener una representación en string.

Con un ayudante de registro es posible escribir este código, siendo s una variable del enumerativo:

s.ToString

En las versiones anteriores a los record helper la única forma es definiendo una función " suelta ", por ejemplo

SexoToString(s)

Luego con más tranquilidad lo plasmo en código
  • 0

#14 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 23 marzo 2016 - 07:07

Por otra parte, también vas a tener problemas con los componentes NetHttp de XE8. He hecho pruebas con Delphi 2010 e Indy pero no logré comunicarme

En este hilo se puede ver más detalles, aunque quedó parado y no he hallado solución aún

http://www.clubdelph...ead.php?t=89714
  • 0

#15 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 24 marzo 2016 - 05:04

Por otra parte, también vas a tener problemas con los componentes NetHttp de XE8. He hecho pruebas con Delphi 2010 e Indy pero no logré comunicarme

En este hilo se puede ver más detalles, aunque quedó parado y no he hallado solución aún

http://www.clubdelph...ead.php?t=89714

Lo mas facil seria que descargue delphi xe10 y listo.. gracias igualmente... luego de descargarlo y probar el proyecto les comento

Enviado desde mi SM-G530M mediante Tapatalk
  • 0

#16 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 26 marzo 2016 - 02:57

Hola,

 

Con respecto a la bilbioteca Indy, como decimos por aca, "no doy pie con bola" asi que decidi dejarla aparcada

 

He optado por la biblioteca Synapse que es libre y muy sencilla de usar, y salio andando rapidamente, este es el codigo:


delphi
  1. uses
  2. httpsend,
  3. ssl_openssl,
  4. ssl_openssl_lib;
  5.  
  6. procedure TForm1.Button1Click(Sender: TObject);
  7. var
  8. AResponse: TStrings;
  9. begin
  10. AResponse := TStringList.Create;
  11. try
  12. HttpGetText('https://soa.afip.gob.ar/sr-padron/v2/persona/20370587192', AResponse);
  13. Memo1.Text := AResponse.Text;
  14. finally
  15. AResponse.Free;
  16. end;
  17. end;

Voy a refactorizar mi biblioteca para eliminar la dependencia con los componentes NetHttp client y permitir al usuario final injectar una interface que implemente los metodos que yo necesite

 

Saludos


  • 0

#17 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 26 marzo 2016 - 04:29

Saludos,
 
Me termine dando por vencido con Indy (he probado con las diferentes versiones, la 9, la 10, buscado en internet y no hay caso :()
 
He decidido darle una oportunidad a la biblioteca Synapse que es OpenSource. Con esta biblioteca no he tenido ningun problema para realizar las invocaciones GET
 
El siguiente paso fue eliminar las dependencias con los componentes NetHttpClient
 
He declarado una interface en la unidad Afip.PublicAPI.HttpClient y delegado la implementacion al usuario:


delphi
  1. IHttpClient = interface
  2. ['{AFA99837-6CBB-4111-A268-D8AB8E4CD8DD}']
  3.   function HttpGetText(const AUrl: string): string;
  4.   function HttpGetBinary(const AUrl: string): TStream;
  5. end;

  
Cualquier clase que implemente IHttpClient le sirve a mi clase TAfipQuery para comunicarse con el servidor REST
 
Se proveen dos implementaciones:
 
- La que ya teniamos hasta ahora, usando los components NetHttpClient
 
Esa implementacion la he movido a la unidad Afip.PublicAPI.NetHttpClient; esta encapsulado dentro de la clase TNativeHttpClient
 
- La nueva implementacion usando la biblioteca Synapse, en la unidad Afip.PublicAPI.SynapseHttpClient
 
He incluido tambien en el repo la propia biblioteca Synapse, con solo agregar la ruta en Delphi, ya esta listo para funcionar
 
 

... \AFIP\Third-Party\Synapse


  
El constructor de TAfipQuery ahora requiere una referencia a una interface de este tipo (dependency injection)


delphi
  1. constructor Create(const AHttpClient: IHttpClient; const APersister: IPersister_Afip = NIL);

  
Y eleva una excepcion si le pasamos NIL...
 


delphi
  1. constructor TAfipQuery.Create(const AHttpClient: IHttpClient; const APersister: IPersister_Afip = NIL);
  2. begin
  3.   if AHttpClient = NIL then
  4.     raise Exception.CreateFmt('%s.Create :: AHttpClient is NIL', [ClassName]);

 
He eliminado las funciones que operaban (por asi llamarlo de una manera) "al estilo static", o de funcion de clase (class function) porque ahora no tengo mas el constructor por defecto y no quiero seguir acoplando dependencias
 
Por ultimo he actualizado el demo para que cumpla con esta refactorizacion; tambien he incluido la posibilidad de usar una u otra biblioteca en tiempo de ejecucion (Synapse o NetHttp)
 
La biblioteca Synapse deberia funcionar con versiones mas antiguas de Delphi e incluso FPC (Lazarus)


Editado por Agustin Ortu, 26 marzo 2016 - 04:33 .

  • 0

#18 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 28 marzo 2016 - 11:45

hola amigo Agustin.. entonces no utilizaste el WSDL Importer? en su lugar la libreria synapse, que manda al servidor de la AFIP un dato como parametro, como el dni y consume el servicio? Tambien serviria Synapse para enviar una factura completa?

 

Gracias


  • 0

#19 Agustin Ortu

Agustin Ortu

    Advanced Member

  • Moderadores
  • PipPipPip
  • 831 mensajes
  • LocationArgentina

Escrito 28 marzo 2016 - 11:58

giulichajari
 
Hasta donde tengo entendido, el WSDL importer sirve para servidores SOAP (como el caso de la factura electronica); en este caso la comunicacion es mediante XML
 
Este servicio de la AFIP esta implementado mediante un servidor REST y el intercambio de datos es en formato JSON
 
No creo que el WSDL importer sirva en este caso; me parece que lo correcto seria usar el REST Debugger, como se explica acá

 

La herramienta es gratuita y puede descargarse en este enlace

 

La gracia de este depurador es que se pueden ejecutar las peticiones REST, ver el resultado y luego copiar los componentes a un formulario y hasta te los adapta en un TDataSet (bueno eso es lo que entendi segun el tutorial)


  • 0

#20 giulichajari

giulichajari

    Advanced Member

  • Miembros
  • PipPipPip
  • 477 mensajes

Escrito 28 marzo 2016 - 12:40

Claro.. yo lo habia implementado a lo del padron pero cn pyafipws que tiene una libreria para esto.
Y lo que veo es que utiliza programacion orientada a objetos.. muy bien..

obtengo este error:

 

[dcc32 Fatal Error] Afip.PublicAPI.SynapseHttpClient.pas(9): F2613 Unit 'httpsend' not found.

 

osea debo descargar synapse jejej...


  • 0





Etiquetado también con una o más de estas palabras: AFIP, Argentina, CUIT, CUIL

IP.Board spam blocked by CleanTalk.