Buscar en este blog

lunes, 22 de abril de 2013

Libro de compra venta en formato plano


Para poder realizar el procesamiento de los libros de compras y ventas de una empresa es necesario que esta pueda entregarnos la información en un formato y estructura claros para poder realizar el proceso. Es verdad que existen varias formas de realizar este proceso, pero en este ejemplo se intenta definir un método genérico para quienes deseen implementar sus propios procesos de generación de la información IECV.

Para tales efectos generaremos un ejemplo de como estructurar un archivo plano para recopilar la información del cliente.

El por que un archivo plano?

Una de las ventajas de utilizar un archivo plano para realizar la carga de datos, es la simpleza y comodidad que esto conlleva al cliente, pues no debe invertir mucho tiempo y esfuerzo en crear estos archivos versus otras tecnologías. La mayoría de los clientes no presentan muchos problemas al momento de generar estos archivos planos, pero si al momento de pedirles la misma información en un formato XML.

Problema

El cliente x necesita construir sus libros de compra y venta electrónicos. Para tales efectos el disponible de toda la información necesaria en archivos planos para su procesamiento. Estos archivos planos son el resultado de una consulta SQL a su base de datos donde deposita la información contable de su empresa.
El cliente prefiere no dar acceso a su base de datos para el trabajo directo de extracción de los datos, sino más bien está interesado en enviar estos archivos planos a la empresa que le ofrece el servicio de facturación electrónica para que ellos interpreten la data y creen los libros.
El cliente necesita que se le especifique cual es el formato necesario para que la empresa de facturación electrónica pueda leer su información.

Análisis

Para poder generar los archivos planos con la información necesaria se debe identificar los diferentes cuerpos del archivo a generar. Particularmente en los archivos electrónicos de compras y ventas esta es la estructura más adecuada a utilizar:

Elementos que componen la estructura del archivo plano deberían ser:

1000 Carátula para información electrónica de compra y ventas
2000 Resumen Segmento/Periodo
2100 Sub Resumen Segmento/Periodo (Explicación en Metodología)
2200 Sub Resumen Segmento/Periodo (Explicación en Metodología)
3000 Detalle
3100 Sub Detalle (Explicación en Metodología)
3200 Sub Detalle (Explicación en Metodología)

Donde el índice numérico identifica el segmento del libro, de esta forma se estandariza la construcción de los libros y su posterior lectura e interpretación. El siguiente es el detalle de los diferentes segmentos del documento.

1000: Carátula
Contiene datos generales de la información del envío

2000: Resumen Segmento/Periodo
Contiene los totales por tipo de documento inserto en el libro.

2100: Sub Resumen Segmento/Periodo
Representa datos adicionales o tablas de contenido que están asociadas al registro del Resumen Segmento/Periodo.

3000: Detalle
Detalle de cada documento individual incluso los documentos anulados electrónicos o no.

3100: Sub Detalle
Representa datos adicionales  o tablas de contenido que están asociadas al registro  detalle.

Metodología

Definida la estructura que debería asumir el  archivo plano del cliente, es necesario agregar la información (DATA) para su procesamiento. Para lograr esto debemos utilizar la metodología del SII acerca de la forma y fondo de los datos que necesita para procesar los libros. Esto nos permitirá generar un archivo fuertemente tipificado tanto para poder leer la data del cliente como también, para su posterior procesamiento y envío al SII.

NOTA:
La verdad es que puede utilizar la metodología que Ud. crea necesaria, yo utilizo la estructura del SII, pero no debe ser una norma, sino mas bien una guía. Para desarrollar este ejemplo utilizare la descripción del SII para armar la carátula del libro, pero como ya le explique Ud. Puede utilizar la metodología que Ud considere mejor.


El resultado de aplicar esta estructura nos arrojará un archivo como este:

















El largo del archivo dependerá de los registros detalle que el cliente tenga para procesar.


Agregar datos a la estructura Carátula.

Ahora bien sabiendo cual es la estructura del archivo es necesario agregar la información del libro, para esto utilizaré el detalle de campos que suministra el SII para crear la carátula del documento suponiendo que este es un libro de Ventas.

Según el SII este es el detalle de cómo esta compuesta la carátula de libro de Ventas:

  1. Rut Contribuyente
  2. Rut Enviador
  3. Periodo Tributario
  4. Fecha Resolución
  5. Número Resolución
  6. Tipo de Operación
  7. Tipo de Libro
  8. Tipo de Envío
  9. Número de segmento
  10. Folio de Notificación
  11. Código de autorización de reemplazo de libro electrónico

Ahora completaré la información de la carátula utilizando mis datos y pondré la descripción a su lado para que entienda que tipo de datos se debe agregar. Cada dato lo separaré con un caracteres '|'. Recuerde, lo importante aquí son los datos y no las descripciones.

Libro plano I












Ahora voy a quitar las descripciones y los retorno de carros utilizados para formatear el ejercicio.






Finalmente quitaremos los caracteres '|' para dejar nuestra cadena limpia:






Posterior a esto ya podríamos construir nuestro archivo intermedio, este nos permitirá extraer la información utilizando los elementos de xslt. Para tales efectos debemos tomar la linea actual ( Carátula ) y llevarlo a formato xml tal como se muestra en la siguiente imagen:







Ahora puede transformar este documento xml utilizando un documento de transformación xslt como este:







 



 
  
 
 
  
 
 
  
 
 
  
 
 
  
 
 
  
 
 
  
 
 
  
 





El resultado de dicha transformación regresará lo siguiente:



    9999999-9
    8888888-8
    2013-01
    2013-01-01
    123456
    VENTA
    MENSUAL
    TOTAL



Donde podemos ver que los datos estructurados en el documento plano ahora se encuentran disponibles en el archivo xml parcial.

Este es un ejemplo simple de como transformar sus datos, pudiendo en todo caso realizar esta misma operación de distintas formas según necesite. Solo proponemos esta por su simplicidad.


Agregar datos a la estructura Resumen/Segmento



Para agregar datos a esta estructura es necesario tener en consideración el tipo de servicio que se ofrece al cliente del libro. Puesto que las empresas que ofrecen Facturación Electrónica pueden o no generar este apartado utilizando la información del cliente. En la mayoría de los casos los clientes calculan sus propios resúmenes de datos en su  contabilidad y luego los plasman en los archivos planos enviados a las empresas facturadoras. Pero si no es así es una buena fuente de valor agregado para las empresas facturadoras.

En el caso que el cliente envíe los datos en el archivo plano, secuencia es muy parecida a la de generación de la caratula.

LIbros Compra Venta IECV Procesamiento


Flujo de procesamiento de libros de compra y venta.

Les presento en esta página un pequeño flujo de como crear los libros de compra y venta (IECV) exigidos por el SII en Chile. La cual se explicará paso a paso. El objetivo de este ejemplo es ayudar a los desarrolladores .Net que necesitan comprender como realizar este proceso utilizando la experiencia de aquellos que ya construimos este flujo.

Se debe indicar que existe varios métodos para realizar esta tarea, sin perjuicio que una u otra sea mas eficiente, pero se expondrá aquí quizás una de las formas mas elegantes de realizar el proceso. Si alguien difiere de esta opinión puede sin lugar a dudas dejar su comentario. Siempre se agradece una visión diferente de las cosas.

Este flujo podría ser actualizado con el tiempo así que les dejo la url para que puedan verlo Aquí
 

Flujo basico de generación de Libros compra y venta IECV


Libro Compra Venta en formato Plano.

Corresponde a la responsabilidad del cliente de crear su archivo plano con un formato y codificación correcta para el efectivo procesamiento de la información suministrada. Indicamos como construir el archivo plano con un formato claro para el procesamiento correcto de la información.
Ver mas.... 


#1 Validación de elementos del libro Formato Codificación.

Define la forma y el fondo del archivo plano a procesar, como se encuentra estructurado, cual es el formato esperado y como se accede  a los datos relevantes de los libros de compra y venta.


#2 Generación de archivo Intermedio en formato XML

Describe el por que de la generación intermedia del archivo de compra y ventas en formato xml. La técnica expuesta utiliza plantillas xslt para transformar la información de los libros en su representación XML.


#3 Generación de archivo IECV en formato Definitivo (XML)

Describe el cómo generar el archivo IECV definitivo a partir del archivo intermedio.


#4 Validación del schema del libro.

Describe el cómo realizar la validación del libro de compra y ventas(IECV), utilizando el schema proporcionado por el SII. Esta validación es necesaria para poder enviar el libro en forma y fondo al SII. Para mayor información baje el schema del libro Aquí.


#5 Validación de IVA según el SII

Describe el cómo realizar la validación de IVA de cada registro según el SII, El resultado de esta operación puede dar como resultado la aprobación o rechazo del libro. Bajar documento explicativo del SII Aquí.


#6 Validación de registros según capa de negocios

Determina que elementos de validación se agregarán al proceso según la capa de negocios según la empresa que construya los libros de compra y venta.

#7 Libro de Compra y Venta en Formato XML

Resultado de la operación de generación del libro de compra y ventas ( IECV ), en formato xml.



jueves, 18 de abril de 2013

Codificación correcta de DTE y IECV en ISO-8859-1



Codificación correcta de DTE y IECV en ISO-8859-1


Problema

Se requiere generar los archivos DTE o IECV de un determinado cliente. Este envía archivos planos con la información necesaria para construir dichos documentos. Estos archivos planos pueden estar codificados en formatos tales como: : UTF-8, ANSI, UTF-16, UNICODE.

Al momento de leer estos archivos planos para extraer la información de ellos muchas veces la lectura de los mismos arroja errores de caracteres que se pierden o no pueden ser leídos por pertenecer a codificaciones distintas a las que realmente se necesitan. Un ejemplo de esto sería el envío de un archivo plano en formato UNIX.

La perdida de caracteres o la mala interpretación de los mismos repercute al momento de realizar cualquier procesamiento sobre ellos, dando lugar a errores al momento de generar nuestros archivos de salida.

Ejemplo:

Si tenemos una cadena de caracteres como la siguiente,

“El griego antiguo(Ἀρχαία Ἑλληνική Arkhaía Hellēnikḗ) se refiere al idioma griego que existió…”

He intentamos leer esta información utilizando la codificación ISO-8859-1 obtendríamos lo siguiente:

“El griego antiguo((err)(err)(err)(err)(err)(err) (err)(err)(err)(err)(err)(err)(err)(err) Arkhaía Hell(err)nik(err)) ) se refiere al idioma griego que existió…”

Este es un caso extremo para presentar el problema, de todas formas ilustra el cómo pueden perderse caracteres al momento de realizar nuestros procesamientos.

Si llevamos este ejemplo a la vida real de la Factura Electrónica podríamos encontrarnos con este tipo de despliegue en nuestros archivos.

<RznSoc>CONSTRUCTORA RE¥ACA SA</RznSoc>

Donde el caracter ¥ no pertenece realmente al valor del tag, si no que, fue leído erróneamente al momento de su proceso. Posteriormente fue plasmado en un documento IECV.



Análisis

Para evitar tener este tipo de problemas  es necesario crear una clase que permita leer el archivo plano enviado por el cliente y validar el set de caracteres antes de ser procesado. De esta forma podremos saber de ante mano que debemos arreglar o si todo está en condiciones para iniciar nuestro proceso.


  •  La clase debe poder leer un archivo plano independiente del set de caracteres utilizado para su construcción.

  •  Se debe leer cada línea del archivo para establecer detenidamente donde hay problemas.

  •  La clase debe entregar el número de línea del archivo, el contenido y cuantos errores de conversión encontró.

Bueno como siempre, aqui les dejo la clase para que puedan analizarla y agregarla a sus proyectos.

Clase C# ReplacementFallback ISO-8859-1

NOTA: La clase es operativa pero no esta completamente terminada.

Comentarios del desarrollo.

Para poder rescatar la mayoría de los caracteres que se encuentran disponibles en los archivos planos, es necesario indicar al objeto StreamReader que sistema de codificación se utilizara para abrir el archivo, en este caso yo utilice la codificación UTF-8. Esto le indica al procesador que abra el archivo simulando el envío de un cliente en este formato.


#region Ejemplo de lectura de un archivo plano enviado por un cliente

   ////
   //// Cree el encoding base para abrir el archivo
   Encoding utf = Encoding.UTF8;

   ////
   //// Abra el archivo plano utilizando la codificación
   //// Donde uri representa la fullpath del archivo plano,
   //// ejemplo: 'c:\\archivoPlano.txt'
   using (StreamReader sr = new StreamReader(uri, utf ))
   {
      
         ////
         //// Aquí lea el archivo ..........  
         //// Supondremos que este archivo solo tiene una linea.
         while( sr.Peek()!=-1 )
         {
             string lineaOriginal = sr.ReadLine();
         }

   }

#endregion 


Esa operación nos regresará la siguiente linea:

"El griego antiguo(Ἀρχαία Ἑλληνική Arkhaía Hellēnikḗ)"

Ahora bien para poder determinar que caracteres de esta cadena son suceptibles de ser representados en la codificación ISO-8859-1 debemos comprobar los bytes representativos, para esto podemos utilizar la siguiente secuencia:



#region Secuencia de comprobación de caracteres ISO-8859-1

   ////
   //// Bibliotecas
   using System;
   using System.Collections.Generic;
   using System.Linq;
   using System.Text; 
   using System.IO;

   ////
   //// Esta linea representa la linea leída desde el archivo plano
   //// en la rutina anterior.
   string lineaOriginal = "El griego antiguo(Ἀρχαία Ἑλληνική Arkhaía Hellēnikḗ)";

   ////
   //// Cree el encoding de la Factura Electrónica.
   //// Indicamos que cuando no pueda interpretar un caracter
   //// deje en su lugar:(err). Esto nos ayudará a contar los 
   //// caracteres no validos.
   Encoding iso = Encoding.GetEncoding("ISO-8859-1",
                                          new EncoderReplacementFallback("(err)"),
                                             new DecoderReplacementFallback("(error)"));

   ////
   //// Cree un arreglo de bytes del mismo tamaño de la cadena original
   //// Para almacenar el resultado de la codificacion.
   byte[] clonLineaOriginal = new byte[iso.GetByteCount(lineaOriginal)];

   ////
   //// Transforme la cadena original a su representacion ISO-8859-1 en bytes
   int numberOfEncodedBytes = iso.GetBytes(lineaOriginal, 0, lineaOriginal.Length, clonLineaOriginal , 0);

   ////
   //// Recupere los caracteres codificados en ISO-8859-1
   string lineaNueva = iso.GetString(clonLineaOriginal);


   ////
   //// Ahora finalizada la codificacion de los caracteres podemos 
   //// contar aquellos que no corresponden a la codificacion ISO-8859-1
   string pattern = @"\(err\)";
   MatchCollection mc = Regex.Matches(lineaCodificada, pattern);




#endregion 

El resultado de aplicar esta rutina nos entregará la siguiente información:

Linea Original:
El griego antiguo(Ἀρχαία Ἑλληνική Arkhaía Hellēnikḗ)

Linea Codificada:
El griego antiguo((err)(err)(err)(err)(err)(err) (err)(err)(err)(err)(err)(err)(err)(err) Arkhaía Hell(err)nik(err)) 

Errores   
La cantidad de errores de transformación de caracteres es 16, este valor se accede desde
mc.Count

Conclusión:

Con esta información y utilizando estas rutinas podría construír uno o dos funciones que le permitieran validar los caracteres de sus archivos planos antes de procesarlos y generar documentos electrónicos tributarios. No entraré en detalles de como realizar este proceso, pero de todas formas les deje un link con una pequeña clase que podría ayudarlos a crear las suyas.


martes, 2 de abril de 2013

Como recuperar el TOKEN del SII

Cómo recuperar el TOKEN del SII


Bueno finalmente solo está faltando la recuperación del TOKEN del SII para poder autenticado en el SII. El TOKEN no es otra cosa que una cadena de caracteres que indica que el proceso de autenticación fue satisfactorio, lo que significa para nosotros que ya podemos operar en el SII sin necesidad de ingresar tu User y Password.
Para poder recuperar el Token es necesario contar con la clase GetTokenFromSeedService la cual expone el método GetToken(). Si no dispones de ella te recomiendo que leas el tutorial completo para saber cómo crearla. De todas formas les dejo el link para que la bajen y puedan agregarla directamente a sus proyectos.

Obtener clase GetTokenFromSeedService



También debe contar con el documento xml que representa la semilla firmada. Un ejemplo de ella es este código:





1234567890123










8slcL05kmrM8NGw4I9NSfRqYA9E=


jlbzatIIBLW8AjH++5uVTTrGIMVwGButuoAR88y/hvSc1+6/eW1K864fK3cKi76oArqk7lAM4pPokoXme0JT/hRXXGo6ecuKzO18z2WfPWwgnN0f3ac03TDu7PwfqiDG9mhQpYfIkNp6GNJIiqlg9PG2w1fOJ1QoypsrQmKq6YU=



2Pb4kEB19m7NmOUYew9f36325yrTLTPMU7qzYG2A0/BsubxDdgQw2Op0x6zXvOVX
sYI9KkPXtD5orKJMjwxYRv9wUWdyiE776Rv4ljfJO7EQhIK1fDQDnPt0HefBS06Xzg2QLBvLR+pe1vc6C02Dr99v+lnLA8mnZiJlRHndhNU=

AQAB



MIIF1DCCBLygAwIBAgIDAQNtMA0GCSqGSIb3DQEBBQUAMIHGMQswCQYDVQQG
EwJDTDEYMBYGA1UEChMPQWNlcHRhLmNvbSBTLkEuMTgwNgYDVQQLEy9BdXRv
cmlkYWQgY2VydGlmaWNhZG9yYSBDbGFzZSAzIHBlcnNvbmEgbmF0dXJhbDFD
MEEGA1UEAxM6QWNlcHRhLmNvbSBBdXRvcmlkYWQgY2VydGlmaWNhZG9yYSBD
bGFzZSAzIHBlcnNvbmEgbmF0dXJhbDEeMBwGCSqGSIb3DQEJARYPaW5mb0Bh
Y2VwdGEuY29tMB4XDTAxMDkyNTIxMDgxMloXDTAyMDkyNTIxMDgxMlowgZ8x
CzAJBgNVBAYTAkNMMRgwFgYDVQQKEw9BY2VwdGEuY29tIFMuQS4xLDAqBgNV
BAsTI0NlcnRpZmljYWRvIENsYXNlIDMgUGVyc29uYSBOYXR1cmFsMRwwGgYJ
KoZIhvcNAQkBFg1uY2hlbGVAc2lpLmNsMSowKAYDVQQDEyFOSUNPTEFTIFpB
UFJJQU4gQ0hFTEVCSUZTS0kgQkFFWkEwgZ8wDQYJKoZIhvcNAQEBBQADgY0A
MIGJAoGBANj2+JBAdfZuzZjlGHsPX9+t9ucq0y0zzFO6s2BtgNPwbLm8Q3YE
MNjqdMes17zlV7GCPSpD17Q+aKyiTI8MWEb/cFFncohO++kb+JY3yTuxEISC
tXw0A5z7dB3nwUtOl84NkCwby0fqXtb3OgtNg6/fb/pZywPJp2YiZUR53YTV
AgMBAAGjggJyMIICbjAdBggrBgEEAbVrDwQRFg9BY2VwdGEuY29tIFMuQS4w
JQYDVR0RBB4wHKAaBggrBgEEAcEBAaAOFgwxMC40MTEuODcxLTIwDwYIKwYB
Jh0z1DR3Pl3xOiaFIjSXsQO2PSzcA3wZXYF+KDrMul8e5lAF2NNiLmMVtXEx
ZykMaTGGWS0ZETDhJmBwEZGpP4+lt/JhgwF1Sb6wdrXp7MFCJUc1Tj+/5JqH
1kP0E63/hVElrcP0g8Zn8Z+vr/PMGW1kKgE0IyS4iJ8eIhNSK5phFyKJUn0l
BmIZX7u89d5u7X8=





El cómo generar el archivo xml y cómo firmarlo se describe en el capitulo Como firmar la semilla del SII. Lo importante de este archivo es que debe ser pasado al método GetToken() En formato string, sin ningún tipo de modificaciones. Muchos de nosotros al trabajar con documentos xml tendemos a organizarlos de forma que su lectura sea clara para el desarrollador. Sin embargo los documentos xml al ser generados son solo representaciones de datos de forma lineal. En el caso de la semilla firmada esta debe ser pasada al método de la misma forma que se firmó, pues cualquier modificación entre ambos eventos invalidará la firma subyacente en el documento.

Ejemplo: Sí la semilla firmada se encuentra alojada en un objeto XmlDocument traspase el contenido usando este paso:




#region Recuperar TOKEN

   ////
   //// Suponiendo que el objeto XmlDocument ( XMLDOM ) contenga 
   //// la semilla firmada, esta debería ser la forma de recuperar
   //// el valor string.
   string signedSeed= XmlDocument.InnerXml;

   ////
   //// Luego asigne el valor al metodo GetToken()
   Proxys.Produccion.GetTokenFromSeedService gt = new Proxys.Produccion.GetTokenFromSeedService();
   string valorRespuesta = gt.getToken(signedSeed);


#endregion

El Resultado de valorRespuesta es el valor regresado por el SII que nos indicará si el proceso fue correcto.