Generador de XML en C# para Linux
Generador de XML en C# para Linux
Puedes encontrar el código fuente completo en el repositorio de GitLab: Generador de XML en C# para Linux en GitLab.
Este proyecto se gestó, debido a que un colega desarrollador necesitaba una orientación de como generar Documentos Tributarios Electrónicos, pero sin timbre y sin firma, puesto que era para inter-actuar con otra herramienta llamada DTEPLANOWS. Los desarrolladores C# no tenían nociones de como generar XML y se me contactó a mi persona para asesorar. Así que hice un desarrollo lo más rápido posible. Uno de los problemas que tuve que afrontar es que me pedían que el código fuera C# para windows, lo cual a mi me dificultó, puesto que uso sólo linux. Esta situación hizo que tuviera que leer de manera express algo de C# y preparar el entorno de desarrollo en este lenguaje, en este caso leí información sobre .NET CORE, lo cual no es muy común en mi día a día. Por fortuna el código se pudo generar en Windows, posteriormente decidí expandir las funcionalidades del proyecto añadiendo funciones como:
- Timbrado de Documentos Tributarios Electrónicos (Guías de Despacho, Facturas Electrónicas, Boletas, Notas de Crédito y Débito)
- Funciones de Firma electrónica con Certificado Digital Tributario.
- Envío de Documentos Tributarios Electrónicos al Servicio de Impuestos Internos
Ejemplo de Uso
using System; using System.Collections; using System.IO; using System.Text; using System.Xml; class Program{ // See https://aka.ms/new-console-template for more information public static void Main(){ //IDENTIFICO EL TIPO DE DOCUMENTO A CREAR IdDTE objIDDTE = new IdDTE(); //suponiendo que voy a crear a una factura objIDDTE.setTipodte(39); objIDDTE.setFechaemision("2024-01-09"); objIDDTE.setNumdte(1064); objIDDTE.setIndservicio(3); objIDDTE.setIndmntneto(0); // EN CASO DE QUE EL DOCUMENTO SEA UNA GUIA DE DESPACHO //consultar documentacion sii, para ver los valores objIDDTE.setTipodespacho(0); // VALOR 1 SI EL DESPACHO POR CUENTA DEL RECEPTOR objIDDTE.setIndtraslado(0); // VALOR 1 si operacion constituye venta // COLOCO LOS DATOS DEL EMISOR Emisor objEmisor = new Emisor(); objEmisor.setRutemisor("76040308-3"); objEmisor.setRsemisor("PRUEBA"); objEmisor.setFecharesol("2016-04-25"); objEmisor.setDiremisor("URMENETA 305 OFIC 513"); objEmisor.setCiuemisor("PUERTO MONTT"); objEmisor.setCmnaemisor("PUERTO MONTT"); objEmisor.setGiroemisor("SERVICIOS INFORMATICOS"); objEmisor.setTelefono("56975883420"); objEmisor.setNumresol(0); //COLOCO LOS DATOS DEL RECEPTOR Receptor objReceptor = new Receptor(); objReceptor.setRutreceptor("77813960-K"); objReceptor.setRsreceptor("AMULEN CONSULTORES LTDA"); objReceptor.setGiroreceptor("ASESORIAS TRIBUTARIAS"); objReceptor.setCmnareceptor("PUERTO MONTT"); objReceptor.setCiureceptor("PUERTO MONTT"); objReceptor.setDirreceptor("URMENETA 30F OFICINA 513"); // DEFINO LOS TOTALES DEL DOCUMENTO Totales objTotales = new Totales(); objTotales.setMontoneto(500000); objTotales.setMontoexento(0); objTotales.setTasaiva(19); objTotales.setMontoiva(95000); objTotales.setMontototal(595000); List<ImptoReten> arrayimpuesto = new List<ImptoReten>(); // SI HAY UN IMPTO RETENIDO /* ImptoReten objImptoReten = new ImptoReten(); objImptoReten.setMontoimp(1); objImptoReten.setTipoimp(15); objImptoReten.setTasaimp(19); arrayimpuesto.Add(objImptoReten); */ /* AGREGO LOS DETALLES DEL DOCUMENTOS */ List<Detalle> arraylistdetalle = new List<Detalle>(); Detalle objDetalle = new Detalle(); objDetalle.setNrolinea(1); objDetalle.setNmbitem("SERVIDOR HP"); objDetalle.setPrcitem(595000); objDetalle.setQtyitem(1); objDetalle.setMontoitem(595000); objDetalle.setTpocodigo("INT"); objDetalle.setVlrcodigo("1"); objDetalle.setDescuentomonto(0); objDetalle.setDescuentopct(0); objDetalle.setIndexe(0); objDetalle.setCodimpadic(0); arraylistdetalle.Add(objDetalle); List<DscRcgGlobal> arraylistdscrcgblobales = new List<DscRcgGlobal>(); // en caso de existir descuentos globales /* DscRcgGlobal objDscRcgGlobal = new DscRcgGlobal(); objDscRcgGlobal.setNrolindr(1); objDscRcgGlobal.setTpomov("D"); objDscRcgGlobal.setGlosaDr("DESCUENTO GLOBAL"); objDscRcgGlobal.setTpovalor("%"); objDscRcgGlobal.setValordr(7); arraylistdscrcgblobales.Add(objDscRcgGlobal); */ // AGREGO EL NODO DE REFERENCIA // ESTE NODO ES OPCIONAL EN LAS FACTURAS Y GUIAS. NO OBSTANTE ES REQUERIDO EN NOTAS DE CREDITO O DEBITO Referencia objReferencia = new Referencia(); objReferencia.setNrolinref(1); objReferencia.setCodref(0) ; objReferencia.setFchref("2023-05-23"); objReferencia.setTpodocref(801); objReferencia.setFolioref(1); objReferencia.setRazonref("ORDEN DE COMPRA"); List<Referencia> arraylistreferencia = new List<Referencia>(); arraylistreferencia.Add(objReferencia); //INICIALIZO UN OBJETO DEL TIPO DOCUMENTO DteModel objDTE = new DteModel(); objDTE.setIddte(objIDDTE); objDTE.setEmisor(objEmisor); objDTE.setReceptor(objReceptor); objDTE.setTotales(objTotales); objDTE.setImptoreten(arrayimpuesto); //agrego los detalles previamente cargados objDTE.setDetalle(arraylistdetalle); objDTE.setDscrcgglobal(arraylistdscrcgblobales); objDTE.setReferencia(arraylistreferencia); Console.WriteLine("Hello, World!"); //UNA VEZ REUNIDO LOS OBJETOS INICIO LA SECUENCIA XML if(objIDDTE.getTipodte()==41 | objIDDTE.getTipodte()==39 ){ xmlDTEBOLETA objXML = new xmlDTEBOLETA(); objXML.crearXML(objDTE,"ejemplodte.xml"); /* public void GeneraEnvio(string aux_tipodte,string nombredte, string pathdte, string rutusuario, string aux_rutemisor, string aux_numresol, string aux_fecharesol) */ }else{ xmlDTE objXML = new xmlDTE(); objXML.crearXML(objDTE,"ejemplodte.xml"); } /* preparo la secuencia de trimbrado con las llaves caf */ Timbre objTimbre = new Timbre(); objTimbre.CreaTimbre("ejemplodte.xml","/home/esteban/appdte/CAF/","76040308"); /* PREPARO LAS SECUENCIA DE FIRMA DEL DOCUMENTO TRIBUTARIO */ SignXML objFirma = new SignXML(); objFirma.signXML("ejemplodte.xml","ejemplodte.xml", "F1064T39", "Documento"); /* UNA VEZ CREADO EL DOCUMENTO PROCEDO A ENVOLVERLO EN UN SOBRE ELECTRONICO Y LO FIRMO */ EnvioBOLETA objEnvio = new EnvioBOLETA(); objEnvio.GeneraEnvio("39","ejemplodte.xml","13968481-8","76040308-3","0","2016-04-25"); objEnvio.addBOLETA("ejemplodte.xml"); SignXML objFirma2 = new SignXML(); objFirma2.signXML("ENVejemplodte.xml","ENVejemplodte.xml", "SetDoc", "SetDTE"); /* SemillaDTE objSemilla = new SemillaDTE(); string valorsemilla = objSemilla.GetSeed("maullin.sii.cl"); Token objToken = new Token(); objToken.GetToken(valorsemilla,"","","","maullin.sii.cl"); */ /* PROCEDO A LA AUTENCION DEL SERVIO DE ENVIO DE BOLETAS */ SemillaBOLETA objSemillaBOLETA = new SemillaBOLETA(); string valorsemilla = objSemillaBOLETA.GetSeed(); TokenBoleta objToken = new TokenBoleta(); string valortoken = objToken.GetToken(valorsemilla,"","","","apicert.sii.cl"); /* public string UpBoleta(string valorToken, string nombreDTE, string rutEmisor, string rutUsuario, string postboleta) */ UpBoletaSII objUpload = new UpBoletaSII(); objUpload.UpBoleta(valortoken,"ENVejemplodte.xml","76040308-3","13968481-8","pangal.sii.cl"); } }
Impacto y Aprendizaje
Este proyecto me permitió ampliar mis horizontes al trabajar con C# y .NET Core, lenguajes y herramientas que no son comunes en mi flujo de trabajo diario. A través de la experiencia, no solo logré cumplir con los requisitos del cliente, sino que también adquirí valiosos conocimientos sobre la integración de tecnologías en un entorno multiplataforma (Linux y Windows). Además, pude poner en práctica mis habilidades de programación para la creación de documentos XML y la integración con sistemas de firma electrónica y timbrado, algo que ha sido de gran utilidad en mis proyectos posteriores relacionados con la facturación electrónica.
Aunque este proyecto comenzó con un enfoque didáctico, se transformó en una solución funcional que los desarrolladores de C# utilizaron para implementar las funciones que necesitaban. Al final, el resultado fue satisfactorio tanto para mí como para el cliente, ya que se lograron automatizar procesos clave en la generación y gestión de Documentos Tributarios Electrónicos.
Comentarios
Publicar un comentario