jueves, 25 de octubre de 2018

How to reset a remote git repository to remove all commits

Delete the .git directory locally and recreate the git repostory:
$ cd (project-directory)
$ git init
$ (add some files)
$ git add .
$ git commit -m 'Initial commit'
Push to remote server, overwriting. Remember you're going to mess everyone else up doing this so you better be the only client.
$ git remote add origin <url>
$ git push --force --set-upstream origin master

domingo, 21 de octubre de 2018

How to Create an Executable JAR with Maven

In this quick article we will focus on packaging a Maven project into an executable Jar file. In order to create an executable jar, we don’t need any additional dependencies. We just need to create Maven Java project, and have at least one class with the main(…) method.

We also need to make sure that our pom.xml contains the the following elements:
<build>
    <finalName>anjus-invoicing-${project.version}</finalName>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <appendAssemblyId>false</appendAssemblyId>
                <archive>
                    <manifest>
                        <mainClass>com.rolandopalermo.example.Main</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>assembly</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

viernes, 19 de octubre de 2018

Generación de número CUFE con Java

Siguiendo con la serie de artículos relacionados con Facturación Electrónica en Colombia, les comparto una función para la generación del número CUFE en Java.
public static String calculateInvoiceCUFE(String numFac, String fechaFac, String horaFac, String valFac,
   String valImp1, String valImp2, String valImp3, String valPag, String nitOFE, String tipAdq, String numAdq,
   String clTec) {
  StringBuilder sb = new StringBuilder("");
  sb.append(numFac);
  sb.append(fechaFac);
  sb.append(horaFac);
  sb.append(valFac);
  sb.append(CodImp1);
  if (StringUtils.isEmpty(valImp1)) {
   sb.append("0.00");
  } else {
   sb.append(valImp1);
  }
  sb.append(CodImp2);
  if (StringUtils.isEmpty(valImp2)) {
   sb.append("0.00");
  } else {
   sb.append(valImp2);
  }
  sb.append(CodImp3);
  if (StringUtils.isEmpty(valImp3)) {
   sb.append("0.00");
  } else {
   sb.append(valImp3);
  }
  sb.append(valPag);
  sb.append(nitOFE);
  sb.append(tipAdq);
  sb.append(numAdq);
  sb.append(clTec);
  return DigestUtils.sha1Hex(sb.toString());
 }
Es importante agregar la siguiente dependencia:
<dependency>
 <groupId>commons-codec</groupId>
 <artifactId>commons-codec</artifactId>
 <version>1.11</version>
</dependency>

jueves, 18 de octubre de 2018

Facturacion Electrónica en Colombia

Conocido es por todos que hoy en día la facturación electrónica es ya una realidad en Colombia. Se han realizado planes piloto con diversas empresas y en la actualidad ya es una necesidad acogerse a esta nueva tecnología tributaria.

En este artículo, no voy a entrar en detalle en las resoluciones y leyes emitidas por la entidad regulatoria en Colombia, la DIAN, sin embargo como desarrollador de software, me causa un profundo malestar la pésima documentación que acompaña a las normas que obligan a las empresas a facturar de manera electrónica.

Y es que no es una novedad que instituciones como el SRI en Ecuador, la SUNAT en Perú o la DIAN en Colombia pongan trabas con pésimos canales de resolución de dudas y mala documentación. A veces me planteo la interrogante de cómo es que planifican la puesta en marcha a nivel nacional de proyectos tan grandes con tan poca o nula documentación.

En mi experiencia, leyendo un manual técnico y entendido el esquema funcional del proceso, se debería estar apto para emitir comprobantes electrónicos en no más de un mes, sin embargo nos tapamos con trabas como el tener que leer un PDF que nos habla de un servicio web de tipo SOAP para consultas de facturas y terminar dándonos cuenta que en ningún momento nos indicaron cuál es el WSDL (Si bien son términos muy técnicos, los lectores que desarrollarán software entenderán la gravedad de esto).

Podría disponer de líneas y líneas en mi blog para hablar de la mala experiencia que puede resultar implementar facturación electrónica en Sudamérica pues la diversidad de manuales no versionados sumado a la poca organización de la información y la indisponibilidad de enlaces y URL's puede, a veces, hacernos arrepentir de haber emprendido este tipo de desarrollos. Sin embargo, el propósito de este artículo es clarificar de cierta manera cuales son los pasos que se debe seguir en Colombia.

El siguiente esquema funcional representa el flujo que se sigue para autorizar o en otras palabras, dar validez tributaria, a una factura electrónica en Colombia.


Básicamente, son dos los servicios Web que nos permiten autorizar una factura, el de recepción y el de consulta. Cada uno tiene un WSDL diferente además de estar configurados para ser consumidos mediante WS-Security. Los enlaces los muestro a continuación:

https://facturaelectronica.dian.gov.co/habilitacion/B2BIntegrationEngine/FacturaElectronica/facturaElectronica.wsdl

https://facturaelectronica.dian.gov.co/habilitacion/B2BIntegrationEngine/FacturaElectronica/consultaDocumentos.wsdl

Los pasos a seguir son:

1. Generar XML
Para generar los archivos XML, a diferencia de Ecuador, debemos utilizar el esquema UBL 2.0. En este punto recomiendo no utilizar librerías externas y mejor generar los documentos XML de manera manual utilizando las clases del paquete org.w3c.dom.

2. Firmar XML
Para firmar el documento XML, una excelente librería para Java es xades4j. La dependencia de maven es la siguiente:
<dependency>
 <groupId>com.googlecode.xades4j</groupId>
 <artifactId>xades4j</artifactId>
 <version>1.5.0</version>
</dependency>
En la sección de issues en su página de github podemos encontrar diversas consultas en donde también sugieren cómo implementar la firma electrónica según los estándares de Colombia.

3. Enviar XML firmado a la DIAN
Este paso es nuestra primera interacción con la DIAN. En este servicio se valida la estructura del documento XML así como la firma digital. Es importante recordar que el SOAP request deberá tener como cabecera el objeto de WS-Security. A continuación muestro un ejemplo de request:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
    <SOAP-ENV:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" S:mustUnderstand="1">
            <wsse:UsernameToken>
                <wsse:Username><!--- Proporcionado por la DIAN --></wsse:Username>
                <wsse:Password><!--- Proporcionado por la DIAN --></wsse:Password>
                <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                <!--- Hora en que se realiza la petición en formato yyyy-MM-ddTHH:mm:ssZ -->
                </wsu:Created>
                <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis200401-wss-soap-message-security1.0#Base64Binary">
                <!--- Secuencia aleatoria codificada en base 64 -->
                </wsse:Nonce>
            </wsse:UsernameToken>
        </wsse:Security>
    </SOAP-ENV:Header>
    <S:Body>
        <EnvioFacturaElectronicaPeticion xmlns="http://www.dian.gov.co/servicios/facturaelectronica/ReportarFactura">
            <NIT><!--- NIT del facturador --></NIT>
            <InvoiceNumber><!--- Número secuencial de la factura --></InvoiceNumber>
            <IssueDate><!--- Fecha de emisión de la factura en formato yyyy-MM-ddTHH:mm:ss --></IssueDate>
            <Document><!--- Archivo ZIP codificado en base 64 --></Document>
        </EnvioFacturaElectronicaPeticion>
    </S:Body>
</S:Envelope>

4. Validar Factura
En caso el código de respuesta del servicio anterior sea 200, el siguiente paso es comprobar que la factura tenga validez tributaria. Al igual que la llamada anterior, la estructura de la petición para este servicio también considera la cabecera de tipo wS-Security.
Este paso es nuestra primera interacción con la DIAN. Es importante recordar que el SOAP request deberá tener como cabecera el objeto de WS-Security. A continuación muestro un ejemplo de request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:con="http://www.dian.gov.co/servicios/facturaelectronica/ConsultaDocumentos">
   <soapenv:Header>
        <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
            <wsse:UsernameToken>
                <wsse:Username><!--- Proporcionado por la DIAN --></wsse:Username>
                <wsse:Password><!--- Proporcionado por la DIAN --></wsse:Password>
                <wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
                <!--- Hora en que se realiza la petición en formato yyyy-MM-ddTHH:mm:ssZ -->
                </wsu:Created>
                <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis200401-wss-soap-message-security1.0#Base64Binary">
                <!--- Secuencia aleatoria codificada en base 64 -->
                </wsse:Nonce>
            </wsse:UsernameToken>
        </wsse:Security>
    </soapenv:Header>
    <soapenv:Body>
        <con:ConsultaResultadoValidacionDocumentosPeticion>
            <con:TipoDocumento>
            <!--- Parámetros enviados con error, el tipo de documento debe ser 
            1 = Factura, 
            2 = Nota Débito, 
            3 = Nota Crédito -->
            </con:TipoDocumento>
            <con:NumeroDocumento>
            <!--- Número secuencial de la factura -->
            </con:NumeroDocumento>
            <con:NitEmisor><!--- NIT del facturador --></con:NitEmisor>
            <con:FechaGeneracion>
            <!--- Fecha de emisión de la factura en formato yyyy-MM-ddTHH:mm:ss -->
            </con:FechaGeneracion>
            <con:IdentificadorSoftware>
            <!--- Proporcionado por la DIAN -->
            </con:IdentificadorSoftware>
            <con:CUFE>
            <!--- El valor del CUFE es obligatorio cuando el tipo de documento es 1 = 'INVOICE' -->
            </con:CUFE>
        </con:ConsultaResultadoValidacionDocumentosPeticion>
    </soapenv:Body>
</soapenv:Envelope>

5. Comunicar factura
Como paso final, en caso de tener como código de transacción 200, ya podemos enviar la factura en formato ZIP junto con el PDF correspondiente al receptor.

Finalmente les comparto la información de un taller que estamos impartiendo para capacitar a desarrolladores Java en la implementación de este tipo de aplicaciones.

Espero esta información les sea de mucha utilidad y quedo presto a resolver interrogantes adicionales que podrán dejar en la caja de comentarios.