Suministro Inmediato de Informacion - SII

hmpaquito
Posts: 1200
Joined: Thu Oct 30, 2008 2:37 pm

Re: Suministro Inmediato de Informacion - SII

Post by hmpaquito »

PRIMERO.- Un par de videos

Vídeo muy didactivo explicando el funcionamiento del SII
https://www.youtube.com/watch?v=xbIf9O706DM


Conferencia con preguntas y respuestas.
https://www.youtube.com/watch?v=Kl8T9zpEYn0


SEGUNDO- Petición
Me gustaría que alguien que ya ha utilizado harbour + SOAP para transmitir informacion en archivos xml, nos diera su punto de vista y nos explicara, al menos por encima, qué hacer:
Instalacion de SOAP toolkit + instalacion certificado, etc. Sintaxis para envio y sintaxis para recepcion. Necesitamos (al menos yo) un empujón.

Saludos
horacio
Posts: 1270
Joined: Wed Jun 21, 2006 12:39 am
Location: Capital Federal Argentina

Re: Suministro Inmediato de Informacion - SII

Post by horacio »

Supongo que la e-factura es parecido en todo el mundo. Si es así no necesitas instalar nada ya que las funciones que necesitas están incluidas en harbour , salvo openssl para firmar el certificado de acceso. Si necesitas un ejemplo yo tengo un desarrollo para Argentina.

Saludos
hmpaquito
Posts: 1200
Joined: Thu Oct 30, 2008 2:37 pm

Re: Suministro Inmediato de Informacion - SII

Post by hmpaquito »

horacio,

Gracias por contestar.
El SII no tiene que ver con la e-factura.
El SII es un gran trasvase de datos desde los administrados hacia la admón. pública.
Incluye facturas, recibidas y emitidas, pero por lo que he visto por ahí, puede incluir cobros y pagos, etc. En el futuro podría incluir otros datos.

Para comunicarnos con la agencia estatal necesitamos establecer comunicaciones SOAP, tanto de subida como de bajada.

Así que si tienes experiencia en SOAP, con posibilidad de uso de certificados digitales, sería de ayuda que nos explicases como lo haces.

Saludos
User avatar
AngelSalom
Posts: 664
Joined: Fri Oct 07, 2005 7:38 am
Location: Vinaros (Castellón ) - España
Contact:

Re: Suministro Inmediato de Informacion - SII

Post by AngelSalom »

hmpaquito wrote:PRIMERO.- Un par de videos

Vídeo muy didactivo explicando el funcionamiento del SII
https://www.youtube.com/watch?v=xbIf9O706DM


Conferencia con preguntas y respuestas.
https://www.youtube.com/watch?v=Kl8T9zpEYn0


SEGUNDO- Petición
Me gustaría que alguien que ya ha utilizado harbour + SOAP para transmitir informacion en archivos xml, nos diera su punto de vista y nos explicara, al menos por encima, qué hacer:
Instalacion de SOAP toolkit + instalacion certificado, etc. Sintaxis para envio y sintaxis para recepcion. Necesitamos (al menos yo) un empujón.

Saludos

Bravo por los vídeos, esta noche los miraré con calma.
En cuanto a harbour + SOAP ... yo personalmente estoy totalmente en blanco, cero experiencia ... aunque aprendo rápido :D :D
Angel Salom
http://www.visionwin.com
---------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.0
horacio
Posts: 1270
Joined: Wed Jun 21, 2006 12:39 am
Location: Capital Federal Argentina

Re: Suministro Inmediato de Informacion - SII

Post by horacio »

Les mando una rutina para conectarse con el web-service y obtener el Ticket de acceso ( TA ).

Code: Select all

//----------------------------------------------------------------------------//
Function Opc_PidoElTicketDeAcceso()

    Local cBat
    Local nHandle
    Local aRespuesta
    Local lRetorno        := .t.
    Local cCert              
    Local cPrivateKey    
    Local cSource        
    Local cDestinationDn  
    Local cUniqueId          := '1432505199'    // > VER DE DONDE LO OBTENGO    * NUMERO QUE IDENTIFICA EL REQUERIMIENTO, TIENE QUE SER DISTINTO CADA VEZ
    Local cGenerationTime := TimeFMT( HB_DateTime(), -1 ) // - 1Hs
    Local cExpirationTime := TimeFMT( HB_DateTime(), 1 )  // + 1Hs
    Local cService       := 'wsfe'          // El nombre del servicio WS al que solicita un TA ( "wdepmovimientos", "wsfe" )
    Local cXML               := ''              // Variable donde Armo el XML
    Local cCMS               := ''                  // Variable donde esta el XML y su Firma Electronica
    Local cTRA               := ''              // Ticket de requerimiento de Acceso
    Local cCMS_Base64    := ''              // Variable donde esta el CMS Codificado en Base64
    Local cCmdSign       := ''              // Comando para llamar a OpenSsl y Generar la Firma del Archivo XML
    Local cPathOpenSsl    := Alltrim( GetPvProfString( "Openssl","Path","c:\openssl-win32\bin", Memvar -> o : cIni ) ) // Donde Tengo Instalado OpenSsl
    Local cRespuesta      := ''
    Memvar o

    cCert            := Hb_CurDrive() + ':\' + CurDir() + '\reingart.crt' // Certificado Digital
    cPrivateKey      := Hb_CurDrive() + ':\' + CurDir() + '\reingart.key' // llave privada que se corresponde con el certificado digital
    cSource          := 'C=AR, O=PyAfipWs-Sistemas Agiles, SERIALNUMBER=CUIT 20267565393, CN=Mariano Reingart' 
    cDestinationDn  := 'cn=wsaahomo,o=afip,c=ar,serialNumber=CUIT 33693450239'


    * Armo El Archivo Xml con el mensaje del TRA (LoginTicketRequest.xml)

    cXml += '<?xml version="1.0" encoding="UTF-8"?>' + CRLF
    cXml += '<loginTicketRequest version="1.0">' + CRLF
    cXml += '  <header>'  + CRLF
    cXml += '    <source>' + cSource + '</source>' + CRLF
    cXml += '    <destination>' + cDestinationDn + '</destination>' + CRLF
    cXml += '    <uniqueId>' + cUniqueId + '</uniqueId>' + CRLF
    cXml += '    <generationTime>' + cGenerationTime + '</generationTime>' + CRLF
    cXml += '    <expirationTime>' + cExpirationTime + '</expirationTime>' + CRLF
    cXml += '  </header>' + CRLF
    cXml += '  <service>' + cService + '</service>' + CRLF
    cXml += '</loginTicketRequest>' + CRLF

    * Grabo el Archivo XML con el Nombre TRA.xml
    If( ( nHandle := fcreate( Hb_CurDrive() + ':\' + CurDir() + '\TRA.xml', 0 ) ) == -1 )
        MsgStop( 'NO se pudo crear TRA.xml' )
        Return( .f. )
    Else
        fWrite( nHandle, cXml )
        fClose( nHandle )
    End

    * Genero la Firma Electronica de TRA.xml en el Archivo TRA.tmp 

    cCmdSign := 'openssl smime' +;
                    ' -sign' +;
                    ' -in ' + 'TRA.xml' +;       // Archivo XML a Firmar
                    ' -out ' + 'TRA.tmp' +;      // Archivo con la Firma
                    ' -signer ' + cCert +;       // 
                    ' -inkey ' + cPrivateKey + ; // 
                    ' -outform ' + 'DER'  +;     // Lo Graba en Binario ('PEM' lo graba como numeros con 4 lineas de titulos)
                    ' -nodetach'                 // NO se Incluye el Archivo Original en la Salida
    
    cBat := ''
    cBat += 'path ' + cPathOpenSsl + CRLF
    cBat += cCmdSign   + CRLF
    If( !File( hb_CurDrive() + ':\' + CurDir() + "\FirmoXML.bat" ) )        
        Hb_MemoWrit( 'FirmoXML.bat', cBat )
    End
    * Ejecuto el BAT para Generar TRA.tmp con la Firma 
    //HB_run( 'FirmoXML.bat' )
    ShellExecute( o : oWndMain : hWnd,,'FirmoXML.bat',,, 0  )      // 
    cCMS := MemoRead( 'TRA.tmp' ) // Leo el Archivo Firmado 

    * Codifico en base64
    cCMS_Base64 := hb_base64Encode( cCMS ) // Funci¢n de Harbour

    * Llamo al WS de Autenticaci¢n (WSAA)
    cRespuesta := LlamoAlWSAA( cCMS_Base64 )
    Hb_MemoWrit( Hb_CurDrive() + ':\' + CurDir() + '\TA.xml', cRespuesta )

    * Muestro el contenido del XML RECIBIDO
    aRespuesta := Opc_LeeRespuesta( cRespuesta, 'TA' )
    If( Empty( aRespuesta ) )
        cCadenaError := 'Error al obtener el ticket de acceso'   
        lRetorno := .f.
    End 
    Return( lRetorno )

//----------------------------------------------------------------------------//
Function LlamoAlWSAA( c_CMS_Base64 )

    Local cWSAA_URL
    Local cXml       := ''
    Local oWSAA      := ''
    Local cRespuesta := ''
    Memvar o
    
    cWSAA_URL  := 'https://wsaahomo.afip.gov.ar/ws/services/LoginCms'

    oWSAA  := CreateObject( 'MSXML2.XMLHTTP' )
    If( Empty( oWSAA ) )
        MsgStop( 'NO se Pudo Crear el Objeto oWSAA; se Cancela el Programa' )
        Return( .f. )
    End
    * Armo el XML con el TRA
    cXml += '<?xml version="1.0" encoding="UTF-8"?>' + CRLF
    cXml += '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' + CRLF
    cXml += '<soap:Body>' + CRLF
    cXml += '    <loginCms xmlns="http://wsaa.view.sua.dvadac.desein.afip.gov">' + CRLF
    cXml += '    <in0>' + c_CMS_Base64 + '</in0>' + CRLF
    cXml += '    </loginCms>' + CRLF
    cXml += '</soap:Body>' + CRLF
    cXml += '</soap:Envelope>' + CRLF

    * Llamo al Webservice y defino Opciones
    oWSAA : Open( 'POST', cWSAA_URL, .f. )
    oWSAA : SetRequestHeader( "SOAPAction:", "None" )
    oWSAA : SetRequestHeader( "Content-Type", "text/xml;charset=UTF-8" )

    * Envio el Archivo y Recibo la Respuesta del WS
    oWSAA : Send( cXml )

    * Si el status es diferente a 200, ocurri¢ alg£n error de conectividad con el WS ---
     cRespuesta := oWSAA : ResponseText
    if( Empty( cRespuesta ) )
        MsgStop( "Error; cRespuesta esta VACIO" )
    End

    * Por las Dudas de que la Respuesta venga en Formato RAW
    If( !Empty( cRespuesta ) )
        If( '<' $ cRespuesta ) // <
            cRespuesta := StrTran( cRespuesta, '<', '<' )
        End
        If( '>' $ cRespuesta ) // >
            cRespuesta := StrTran( cRespuesta, '>', '>' )
        End
        If( '"' $ cRespuesta ) // "
            cRespuesta := StrTran( cRespuesta, '"', '"' )
        End
        If( '&apos;' $ cRespuesta ) // \
            cRespuesta := StrTran( cRespuesta, '&apos;', '\' )
        End
        If( '&' $ cRespuesta ) // &
            cRespuesta := StrTran( cRespuesta, '&', '&' )
        End
    End
    * Hago mas legible el XML

    cRespuesta := StrTran( cRespuesta, '><', '>' + CRLF + '<' )

    * Dicen que si no se borra el Objeto, despues de un tiempo se incrementa mucho
    * el uso de memoria por parte del programa. No lo constate, pero por las dudas
    oWSAA  := NIL
    Release oWSAA
    Return( cRespuesta )

Saludos
hmpaquito
Posts: 1200
Joined: Thu Oct 30, 2008 2:37 pm

Re: Suministro Inmediato de Informacion - SII

Post by hmpaquito »

horacio,


Muy buen trozo de código.

El SII (Suministro Inmediato de Información) por lo que he leido necesita "certificarse"... no se si con el web service o con que.
También me parece que el xml ha de ir sin firmar.

Gracias
User avatar
thefull
Posts: 720
Joined: Fri Oct 07, 2005 7:42 am
Location: Barcelona
Contact:

Re: Suministro Inmediato de Informacion - SII

Post by thefull »

Buenas
Si esto será obligatorio a nivel de facturación, seguramente el marrón me caerá a mí en mi empresa.
¿ Para emitir una factura será obligatorio hacerlo via webservices ?

Para mí no es mucho problema , a nivel de montar el parser y el leer la respuesta.
El tema estará como funciona el tema de certificados, por experiencia en otros países, TODOS se lo han montado a su bola.
No sé si el certificado es un privado que generas y envias la clave publica a la hacienda, como hacen en portugal, etc., este tema es el que
suena dar un poco más la lata.

Pero mi consejo, de verdad, si no queréis tener problemas o dolores de cabeza, es intentar , si es posible, usar un tercero, e implementas la solución
de un tercero.
Esto te evitará tener que conocerte la legislación o _ que produzcan en el protocolo. Claro que esto también tiene un coste a tener en cuenta.

En Mexico y Brasil usamos esta formula, en Argentina / Panana vamos con impresoras fiscales, pero en Portugal lo tenemos
desarrollado directo, y cuando cambian algo, nos avisa el propio cliente, para hacer las modificaciones oportunas.

Así, que tenerlo en cuenta, que en España, nos la liaran parda, como no podria ser ni esperar otra cosa ;-)
Saludos
Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
xmanuel
Posts: 613
Joined: Sun Jun 15, 2008 7:47 pm
Location: Sevilla
Contact:

Re: Suministro Inmediato de Informacion - SII

Post by xmanuel »

A jorobarse toca!!!
:lol:
______________________________________________________________________________
Sevilla - Andalucía
hmpaquito
Posts: 1200
Joined: Thu Oct 30, 2008 2:37 pm

Re: Suministro Inmediato de Informacion - SII

Post by hmpaquito »

Hola,
¿ Para emitir una factura será obligatorio hacerlo via webservices ?

Las facturas emitidas y recibidas han de ser enviadas al web service en los siguientes 8 dias a su emision. El año q viene seran 4 dias.

Usar soft de 3ros ? Los terceros probablemente solo ahorren el tema de las comunicaciones.

Nos ayudaras al menos en la parte del parser y la comunicacion ? :)

Salu2

Pd. El asunto es urgente si caemos en la cuenta q las fras del primer semestre TAMBIEN han de ser enviadas...y que pasará si se exige algún dato q no tenemos implementado en el ERP ? :(
User avatar
thefull
Posts: 720
Joined: Fri Oct 07, 2005 7:42 am
Location: Barcelona
Contact:

Re: Suministro Inmediato de Informacion - SII

Post by thefull »

Ole ole
Pues acabo de preguntar, y tendré que empezar cuanto antes, para ir ganando tiempo al tiempo.

En fin, si os parece cuando tenga un esqueleto , podemos usar github para colaborar.

Saludos Cordiales
Saludos
Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
User avatar
AngelSalom
Posts: 664
Joined: Fri Oct 07, 2005 7:38 am
Location: Vinaros (Castellón ) - España
Contact:

Re: Suministro Inmediato de Informacion - SII

Post by AngelSalom »

¡Bravo! ¡Bravo! :mrgreen: :mrgreen: Siempre viene bien una mano experta, gracias.
Angel Salom
http://www.visionwin.com
---------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.0
hmpaquito
Posts: 1200
Joined: Thu Oct 30, 2008 2:37 pm

Re: Suministro Inmediato de Informacion - SII

Post by hmpaquito »

Genial !

Yo me apunto.

Mi experiencia en GitHub es cero, pero no importa... que para eso somos informáticos... para aprender cosas nuevas ;-)

Hasta donde yo sé, y a día y hora de ahora mismo, los documentos "obligatorios" a tratar serían:

1) Facturas Emitidas
2) Facturas Recibidas
3) Bienes de Inversión
4) Determinadas Operaciones Intracomunitarias.


Esperemos que no sea obligatorio el tratamiento de los documentos Cobros y Pagos.

Así pues, para 1, 2, 3, 4 se les aplicaría los procesos de

1. Suministro (Envio)
2. Consulta
3. Anulacion


¿ Quien más se apunta ? :D
User avatar
AngelSalom
Posts: 664
Joined: Fri Oct 07, 2005 7:38 am
Location: Vinaros (Castellón ) - España
Contact:

Re: Suministro Inmediato de Informacion - SII

Post by AngelSalom »

Bueno, yo también ... por si no había quedado claro :lol: :lol:
Angel Salom
http://www.visionwin.com
---------------------------------------------
fwh 19.05 - harbour 3.2 - bcc 7.0
quim
Posts: 27
Joined: Mon Apr 11, 2011 6:22 pm

Re: Suministro Inmediato de Informacion - SII

Post by quim »

Buenos dias

Mi apoyo al proyecto
  • Cuando empezamos ?
    Por dónde ?
    Lista de tareas ?
Saludos
User avatar
thefull
Posts: 720
Joined: Fri Oct 07, 2005 7:42 am
Location: Barcelona
Contact:

Re: Suministro Inmediato de Informacion - SII

Post by thefull »

Buenas,

Estoy analizando la información que habéis proporcionado, y decir que esta gente de AET , ostras, técnicamente impecable a nivel de XSD, pero enrevesados a más no poder.
Os explico el camino que voy a seguir , ya realizadas nn otras implementaciones que tenemos.

La idea básicamente , a su nivel más básico, para que lo entendais, es crear las clases que nos facilitarán la construcción automaticamente del XML y su envio.
Para nosotros, como programadores, será totalmente transparente, solo nos preocuparemos de montar los objetos con nuestra información.

A modo de ejemlo:

Code: Select all

Function test()
  
  Local oFacturaEmitidas

  oFacturaEmitidas := SuministroLRFacturasEmitidas():New()
  oFacturaEmitidas:oCabecera:oTitular:NombreRazon :=  "La razon social"
  oFacturaEmitidas:oCabecera:oTitular:NIF := "A0101010101"

   while TengoFacturas
          oFactura := oFactura():New()
         // ... aqui datos ...
         oFacturaEmitidas:Add( oFactura )
  end while

  if  oFacturaEmitidas:SendSoap()
      ? "Ey, todo bien"
  else
     ?  "Analizar respuesta" ,  oFacturaEmitidas:oResponse
  endif
 
RETURN nil
 
Como podéis ver, no veréis nada, simplemente, alimentaremos nuestros objectos que sera compatibles con la Agencia Tributaria, cada cual con sus datos desde Dbf , Sql, lo que sea.
Este nivel de encapsulamiento es el que llevo años con los webservices y la verdad es que funciona muy bien.
¿ Y como se hace esto ?

Muy simple, la idea es replicar en clases la definicion del XSD, por poner un ejemplo, la clase SuministroLRFacturasEmitidas

Code: Select all

/*
Sii - Suministro Inmediato de Información, compuesto por datos de contexto y una secuencia de 1 o más registros. 
*Facturas emitidas
*/
CLASS SuministroLRFacturasEmitidas FROM ResponseSoap
      DATA Operacion INIT "siiLR:SuministroLRFacturasEmitidas"   
      DATA oCabecera
      DATA aoRegistroLRFacturasEmitidas 
      
      METHOD New() CONSTRUCTOR
      METHOD Add( oRegistroLRFacturasEmitidas ) INLINE aadd(::aoRegistroLRFacturasEmitidas, oRegistroLRFacturasEmitidas )
      METHOD WriteXML( pNode, NameSpace )

END CLASS
METHOD New() CLASS SuministroInformacion
    ::oCabecera := Cabecera():New()
    ::aoRegistroLRFacturasEmitidas := {}
RETURN Self

METHOD WriteXML( pNode, NameSpace ) CLASS SuministroInformacion
      Local oFactura, pList

      if !empty( NameSpace )
         ::NameSpace := NameSpace 
      endif
         
      pNode := ::CreateXML( )
      
      ::oCabecera:WriteXML( pNode ) 
      
      if !empty( ::aoRegistroLRFacturasEmitidas )
         for each oFactura in ::aoRegistroLRFacturasEmitidas
             pList = mxmlNewElement( pNode, ::NameSpace + "RegistroLRFacturasEmitidas" )
             oFactura:WriteXML( pList, ::NameSpace )
         next
      endif   

RETURN NIL
 
A través del method WriteXML, cada clase SOLO va escribir la parte del XML que le toca. De esta manera, cualquier modificación del esquema va a ser instantánea.
Veamos pues la clase Cabecera, que a su vez contiene la clase Titular ;

Code: Select all

CLASS Cabecera
      DATA IDVersionSii INI "0.4"
      DATA oTitular 
      DATA TipoComunicacion INIT "A0" // Enum A0, A1, A4

      METHOD New() CONSTRUCTOR
      METHOD WriteXML( pNode, NameSpace )

END CLASS

METHOD New() CLASS Cabecera
      ::oTitular := PersonaFisicaJuridicaESType():New()
RETURN Self

METHOD WriteXML( pNode, NameSpace ) CLASS Cabecera
      Local pParent
      
      pParent = mxmlNewElement( pNode, NameSpace + "Cabecera" )
      SetNodeValue( pParent , NameSpace + "IDVersionSii", ::IDVersionSii )
      SetNodeValue( pParent , NameSpace + "TipoComunicacion", ::TipoComunicacion )
     
      ::oTitular:WriteXML( pParent, NameSpace )

RETURN NIL


/*
  Datos de una persona física o jurídica Española con un NIF asociado
*/
CLASS PersonaFisicaJuridicaESType
      DATA NombreRazon        
      DATA NIFRepresentante   // Optional
      DATA NIF

      METHOD New() CONSTRUCTOR
      METHOD WriteXML( pNode, NameSpace )

END CLASS

METHOD New() CLASS PersonaFisicaJuridicaESType
RETURN Self

METHOD WriteXML( pNode, NameSpace ) CLASS PersonaFisicaJuridicaESType
    Local pParent

    pParent = mxmlNewElement( pNode, NameSpace + "Titular" )

    SetNodeValue( pParent , NameSpace + "NombreRazon", ::NombreRazon )
    SetNodeValue( pParent , NameSpace + "NIF", ::NIF )
    if !empty( ::NIFRepresentante )
        SetNodeValue( pParent , NameSpace + "NIFRepresentante", ::NIFRepresentante )
    endif    

RETURN NIL


function SetNodeValue( pNode , cKey, uValue )
    Local hTree

    if uValue != NIL
       hTree := mxmlNewElement( pNode, cKey )
       mxmlNewText( hTree, 0, cValtoChar( uValue ) )
    endif   

return hTree
 
Pues así, con todo lo demás ;-)
La clase ResponseSoap, se encarga de crear el XML y enviarlo, pero el patrón es siempre el mismo, crear la clase correspondiente, y que haga solo lo que le toca.
Esto es asi, porque, por ejemplo, la clase titular, se usará en otras partes, PERO NO TENEMOS QUE HACER NADA, PUES YA LA TENEMOS, solo instanciarla donde nos haga falta.

Si creéis que podéis mejorar este sistema, quedo a la escucha de alguna alternativa mejor.

Saludos Cordiales
Saludos
Rafa Carmona ( rafa.thefullARROBAgmail.com___quitalineas__)
Post Reply