CFDI con JAVA y XMLBeans.

Buen día, espero que esto le sea de utilidad a alguien de esta tan excelsa comunidad.

En días pasados se ha hablado mucho de las reformas que en México se han venido aplicando, una de ellas es la reforma fiscal que obliga a las empresas a expedir CFDI del recibo de nómina que "normalmente" se le da al trabajador, para lo cual en la empresa donde laboro se me encomendó la labor de investigar que es lo que se tenía que hacer para cumplir con esta obligación, así que sin mas preámbulos vamos a lo que requiere la tan temida Facturación Electronica de este comprobante...

Primero que nada existen unos PAC (Proveedores Autorizados de Certificación) que nos timbrarán los comprobantes fiscales, ¿A que me refiero?, si, si no mal recuerdo en épocas pasadas cuando tenias una empresa y requerías expedir facturas buscabas una imprenta autorizada para hacer blocks foliados, previamente autorizados por la instancia legal correspondiente, para el caso es lo mismo, solo que no es una imprenta ni te van a imprimir tus facturas electrónicas, los PAC están, si no estoy mal informado, obligados a proporcionarte el servicio de timbrado de tu comprobante, así como también de la gestión de los mismos por periodos que varían entre los 5 meses y 3 años e incluso mas, según leí en algunos sitios de estos proveedores. Están obligados a proporcionarte la información necesaria para que tu logres generar el famoso layout que ellos manejan para el procesamiento del comprobante, o en su defecto te proporcionarán la aplicación que genere el mismo, en muchos de los casos si no es que en la mayoría, el layout solicitado por el PAC o generado por esta aplicación es un XML que contiene toda la información que lleva el CFDI autorizado por el SAT.

Una vez que el PAC timbra el XML te lo regresa y si quieres te imprime el PDF, que bueno, también él está obligado a hacerlo,

Cuando esta en tu poder entregas ambos al cliente o trabajador según sea el caso, había quienes no entregaban el XML según que por que la factura no se la había pagado el cliente pero eso es absurdo por que leí que en algún lugar remoto de la pagina del SAT puedes descargarlo si lo necesitas.

Hasta aquí todo va claro, pero, ¿qué datos contiene el XML autorizado por el SAT?, bueno, pues existe en sitio del SAT una sección donde te explican los requisitos de las facturas electrónicas el cual pongo aquí a su disposición para mas información acerca de este comprobante, http://www.sat.gob.mx/sitio_internet/asistencia_contribuyente/principian....

Navegando el sitio batallé para encontrar de que se trataba el XML y es en base a un XSD que también proporcionan en este sitio, las ligas fue difícil encontrarlas en el sitio del SAT debido a que la información que proporcionaban aquí y en otras paginas era muy poca o confusa. Aquí les pongo los archivos XSD para CFDI vigente desde 01/01/2017 y para el Complemento de Nomina vigente desde 01/01/2017, Los cuales necesitaremos para generar las clases de cada XSD y formar el XML final válido.

Agrego una ruta donde vienen todos los requisitos del CFDI de nómina según el SAT Vigentes desde el 01/01/2017

Además agrego el ANEXO 20 Vigente desde l 01/01/2017 el cual que es imprescindible su dominio.

Encontré una "Guía" para elaborar un recibo de nómina, la cual después complementé con lo que encontré en este sitio Solucion Factible en el cual me basé para el desarrollo de la herramienta que me permitiera cumplir con el objetivo final que era crear el XML del CFDI con Complemento de Nómina y ahí mismo en en la parte baja se encuentra una ws para validar el comprobante generado.

Bueno dicho esto pasemos a la parte técnica utilizando XMLBeans.

  • Descarga los XSD.
  • Descarga el XMLBeans, yo lo ubiqué en C:.
  • Dentro de la carpeta que pusiste en C: del xmlbeans existe una que se llama bin, ahi pega los XSD que descargaste anteriormente.
  • Ejecuta el siguiente comando.
    c:\xmlbeans\bin>scomp.cmd -compiler “[Ruta a jdk]\bin\javac.exe” cfdv33.xsd -out cfdv33.jar
  • Esto generará el archivo cfdv33.jar que contiene las clases que corresponden al esquema XML. Registra este jar así como las librerías de XMLBeans en tu proyecto del IDE que estés utilizando. Para el caso tienes que hacerlo con los 2 XSD descargados.

Ahora describo a continuación la forma en la que se trabaja con XMLBeans.

  • Creas la clase GeneraCFDI y tu método main.
  • Dentro del main creas el documento
            ComprobanteDocument comprobanteDocument = ComprobanteDocument.Factory.newInstance(); //Documento
            Comprobante comprobante = comprobanteDocument.addNewComprobante();//Comprobante
            XmlCursor cursorComprobante = comprobante.newCursor();//cursor para ubicar secciones dentro del comprobante
            QName locationComprobante = new QName("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation");
            cursorComprobante.setAttributeText(locationComprobante, "http://www.sat.gob.mx/cfd/3 <a href="http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"" title="http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"">http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"</a>);
  • En la "Guia" para generar el CFDI vienen los diferentes items con los que esta compuesto tanto el comprobante como el complemento, revisalos y tienes que setear todo como a continuación muestro.
    //datos del comprobante
     comprobante.setVersion("3.3");
            comprobante.setSerie("HDS");
            comprobante.setFolio("3");
            comprobante.setFecha(null);
            comprobante.setTipoDeComprobante(null);
            comprobante.setFormaDePago("PAGO EN UNA SOLA EXHIBICIÓN");
    ...
    ...
    ...
  • Cuando termines de setear los del comprobante haz lo mismo pero con los de nomina.
    Complemento complemento = comprobante.addNewComplemento();//para setearlo mas adelante con nominaDocument
    NominaDocument nominaDocument = NominaDocument.Factory.newInstance();
            Nomina nomina = nominaDocument.addNewNomina();
            XmlCursor cursorNomina = nomina.newCursor();
    ...
  • Una vez que concluyes de setear los datos para el comprobante y el complemento nomina agrega nomina a la sección complemento del comprobante.
    complemento.set(nominaDocument);

    Genera codigo XML

            XmlOptions xmlOptions = new XmlOptions();
            HashMap namespaces = new HashMap();
  • Determina los prefijos que deban ser según el XSD proporcionado por el SAT
            namespaces.put("http://www.sat.gob.mx/cfd/3", "cfdi");
            ...
            xmlOptions.setSaveSuggestedPrefixes(namespaces);
            xmlOptions.setSavePrettyPrint();
            xmlOptions.setSavePrettyPrintIndent(4);
  • Imprime el XML
            String xmlStr = comprobanteDocument.xmlText(xmlOptions);
            crearArchivoXML(xmlStr);

Si leiste toda la entrada de este blog y analisaste todas y cada una de sus ligas encontrarás un lugar donde puedes validar el XML que se imprime y es 100% valido.

Suerte y que la iluminación llegue a tu mente.

"La suerte solo favorece a quien la acompaña con su esfuerzo y no al que pretende quedarse quieto y que todo lo sea dado por que si"

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

bien!

Gracias por toda la información. Me gustaría mencionar que Java ya cuenta con una herramienta similar que se llama JAXB y que permite hacer las mismas operaciones de generaciones de clases de entidad, marshalling y unmarshalling. Incluso algunos IDEs traen wizards que facilitan un poco el proceso.

Imagen de Nopalin

Hay muchas maneras de hacer

Hay muchas maneras de hacer eso, en lo particular utilizo una libreria llamada simple-xml framework donde tu definies todos los objetos y no una herramienta lo hace por ti, en fin cada quien sus gustos.

Saludos

Imagen de Grios

Excelente!

Sin duda esta es una publicación de referencia obligada para quienes llegan nuevos al tema de la facturación electrónica.

Imagen de nomarlegnar

Intenté hacerlo así y me

Nopalin Intenté hacerlo así y me tropecé con la validación del XML del comprobante que no era OK, asi que empecé a buscar otras alternativas, y me topé con esta que lo hace tal cual se requiere, me funcionó y cumplo con compartirlo, espero te sirva...
Saludos!

Imagen de nomarlegnar

Será bueno investigar como se

Dustredob... Será bueno investigar como se utilizaría esa herramienta... gracias.. Saludos!

Imagen de nomarlegnar

Grios, gracias espero te

Grios, gracias espero te sirva...

Imagen de nomarlegnar

Grios, gracias espero te

Grios, gracias espero te sirva...

Imagen de nomarlegnar

Encontré una buena fuente que complementa esta...

Aqui muesra como agregar el certificado y otras cosas, en lo personal no la eh utilizado pero espero pueda servir, si alguien la usa comente si funciona...

Software Guru

Excelente para Java 1.4

Personalmente preferiría una solución con JAX-B, lo cual implicaría menos líneas de código, y dependiendo de la implementación, podría ser mucho más veloz.

Sin duda esto que se presenta aquí tendría que usarse en Java 1.4, porque no se cuentan con las anotaciones...

Imagen de nomarlegnar

OK

OK... de cualquier forma espero que esta información les sirva, así como también aprovecho el comentario para hacer de su conocimiento que en este tema el dominio del Anexo20 es imprescindible... Suerte...

(ENLACE ACTUALIZADO AL 2017)

Duda

mi codigo:

  1. ComprobanteDocument doc = ComprobanteDocument.Factory.newInstance();
  2.             Comprobante comp = doc.addNewComprobante();            
  3.             XmlCursor cursor = comp.newCursor();
  4.             QName location = new QName("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation", "xsi");
  5.             cursor.setAttributeText(location, "http://www.sat.gob.mx/cfd/3 <a href="http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv3.xsd"" title="http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv3.xsd"">http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv3.xsd"</a>);
  6.             cursor.toNextToken();
  7.             cursor.insertNamespace("cfdi", "http://www.sat.gob.mx/cfd/3");
  8.             comp.setVersion("3.2");
  9.             comp.setSerie("A");
  10.          ........

después genero la leyenda fiscal:

  1. LeyendasFiscalesDocument docLeyenda= LeyendasFiscalesDocument.Factory.newInstance();
  2.             LeyendasFiscales leyendasFiscales= docLeyenda.addNewLeyendasFiscales();
  3.             XmlCursor cursor1 = leyendasFiscales.newCursor();
  4.             QName location1 = new QName("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation", "xsi");
  5.             cursor1.setAttributeText(location1, "http://www.sat.gob.mx/leyendasFiscales <a href="http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd"" title="http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd"">http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd"</a>);
  6.             cursor1.toNextToken();
  7.             cursor1.insertNamespace("leyendasFisc", "http://www.sat.gob.mx/leyendasFiscales");
  8.             //cursor1.insertNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
  9.             leyendasFiscales.setVersion("1.0");
  10.             Leyenda[] leyendas = new Leyenda[1];
  11.             leyendas[0] =leyendasFiscales.addNewLeyenda();
  12.             leyendas[0].setDisposicionFiscal("IVA");
  13.             leyendas[0].setNorma("Artículo 32, fracción III");
  14.             leyendas[0].setTextoLeyenda("Impuesto retenido de conformidad con la Ley del Impuesto al Valor Agregado");
  15.             leyendasFiscales.setLeyendaArray(leyendas);

despues realizo el :

  1. Complemento comple=comp.addNewComplemento() ;
  2.             //Node node=comple.getDomNode();
  3.             //node=leyendasFiscales.getDomNode().cloneNode(true);
  4.             comple.set(leyendasFiscales);

este es mi resultado:

  1.   -<cfdi:Complemento version="1.0" xsi:schemaLocation="http://www.sat.gob.mx/leyendasFiscales <a href="http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd"" title="http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd"">http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd"</a> xmlns:leyendasFisc="http://www.sat.gob.mx/leyendasFiscales"><leyendasFisc:Leyenda textoLeyenda="Impuesto retenido de conformidad con la Ley del Impuesto al Valor Agregado" norma="Artículo 32, fracción III" disposicionFiscal="IVA"/></cfdi:Complemento></cfdi:Comprobante>

Pero lo correcto es asi:

  1.   -<cfdi:Complemento>
  2.       <leyendasFisc:LeyendasFiscales  version="1.0" xsi:schemaLocation="http://www.sat.gob.mx/leyendasFiscales       <a href="http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd"" title="http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd"">http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd"</a> xmlns:leyendasFisc="http://www.sat.gob.mx/leyendasFiscales">  
  3.                <leyendasFisc:Leyenda textoLeyenda="Impuesto retenido de conformidad con la Ley del Impuesto al Valor Agregado" norma="Artículo 32, fracción III" disposicionFiscal="IVA"/>
  4.       </leyendasFisc:LeyendasFiscales>
  5.    </cfdi:Complemento>
  6. </cfdi:Comprobante>

jo

Por favor ayuda

Imagen de nomarlegnar

si no estoy mal

verifica lo siguiente:

Complemento comple=comp.addNewComplemento() ;
            //Node node=comple.getDomNode();
            //node=leyendasFiscales.getDomNode().cloneNode(true);
            comple.set(leyendasFiscales);

para el caso me parece debería quedar así...

Complemento comple=comp.addNewComplemento() ;
            //Node node=comple.getDomNode();
            //node=leyendasFiscales.getDomNode().cloneNode(true);
            comple.set(docLeyenda);

Debido a que lo que debes setear es todo el complemento y si el complemento es en tu caso LeyendasFiscales tendrias que entonces agregar a comple el LeyendasFiscalesDocument que creaste con el nombre docLeyenda no solamente lo que este contenga osea leyendasFiscales

Suerte, comenta si se soluciona por favor.

Si funciono

El

  1. comple.set(docLeyenda);

si funciono. Gracias.

Menos código que lo que había hecho y por no haber leído detalladamente tu ejemplo:

  1. NodeList childList = comp.getDomNode().getChildNodes();
  2.  //el ciclo solo para saver el index del nodo Complemente solo para estar seguro.
  3.             for(int i=0;i<childList.getLength();i++){
  4.                 System.out.println(childList.item(i).getNodeName());
  5.             }
  6.              Node clon =childList.item(2).getOwnerDocument().importNode(leyendasFiscales.getDomNode(),true);
  7.              childList.item(2).appendChild(clon);
Imagen de rafuru

Password con el Key

Hola!

Estoy implementando la generacion del XML y en general esta funcionando bien, gracias a esta y otras guias.

Pero me saltó una duda:

Para generar el Sello, es necesaria una llave privada y el xml, pero para generar la llave privada se necesita el archivo KEY del contribuyente y su password.

Es conveniente esto?, es decir, pedir y registrar ése password en nuestras DB o algo asi?

Imagen de nomarlegnar

Pues...

Pienso que eso de almacenar esta información en tu bd ya depende de ti, puesto a que el CSD y el KEY cambian cada determinado tiempo, por diversas razones, despues no habría uniformidad en los datos y de igual forma a ti de nada te serviría almacenarlos, me explico??

Por ejemplo acá en mi trabajo yo solo utilizo una carpeta contenedora de estos archivos, y así si tienes muchos clientes pues no estaría de mas generarles una a cada uno para que no te confundas...

Peeeero si te refieres a una vez timbrado almacenar el XML en la BD, el XML no trae passwors ni contraseñas solamente cadenas que se generan en forma aleatoria con ayuda de los últimos métodos que se encuentran en este post y la información del timbrado, pues no estaría de más ya que tienes un respaldo asegurado en tu BD de todo el comprobante XML timbrado... y puedes reeimprimirlo las veces que quieras, mas desconozco si exista algún problema con hacienda al momento de alguna auditoría ya que el comprobante que ellos timbran tiene una fecha y una hora y muy probablemente al momento de reimprimirlo por lo menos la fecha de creación del archivo que generas desde tu aplicación tenga otra fecha de creación distinta... pero esto ya se me hace como muy engorroso que suceda, sin embargo no habría que descartarlo.

Espero haberte ayudado.

Imagen de rafuru

Si, al final opte por cifrar

Si, al final opte por cifrar y persistir la contraseña del emisor en una BD :) ,muchas gracias.

Ahora, no se si tengan chance de ayudarme, quiero cancelar una factura con mi pac, éste me dice que envie esto:

certificadoPKCS12_Base64: Cadena que contiene **Pfx en formato Base64, del CSD del emisor con el que se sellaron los comprobantes.

Lo que no se es a que se refiere con PFX, estuve investigando y encontre a este amigo que hizo un procedimiento: https://groups.google.com/d/msg/vfp-factura-electronica-mexico/EGviMyvlB...

Pero no se como llevarlo a java :/ , yo estaba usando el mismo metodo que uso para generar un certificado base 64 al facturar, pero al parecer no funciona

Imagen de nomarlegnar

Caray

La vdd no tengo idea en este momento de a que se refiera...

Acá de mi lado para cancelar una factura unicamente el PAC me pide cambiar un estatus a una cadena integrada que el mismo me solicitó de TRUE a FALSE y con eso me cancela los timbres...

Casualmente el objetivo de la entrada me sirvió poco, pero para el año que entra nos timbraremos directamente con el SAT asi que esto nos va a servir a todos los que lo hagamos directamente con ellos...

Haré un comercial sin querer queriendo para http://solucionfactible.com/, que me han resultado muy accesibles, tienen mucho soporte via web, telefono y mail.

Imagen de nomarlegnar

O si a lo que te refieres

es leer la sección donde se encuentra ese dato para después proporcionarlo tal vez esto te pueda servir...
http://www.javamexico.org/blogs/nomarlegnar/leer_xml_de_un_cfdi_para_dar...

Suerte y comenta si te sirve.

Imagen de jasistemas

En mi caso, genero el sello

En mi caso, genero el sello con el CSD del emisor accediendo directamente al .key sin necesidad de convertirlo con openssl.

Para ello use codigo fuente puro C publicado aqui·

http://www.jensign.com/opensslkey/opensslkey.cs

Imagen de nomarlegnar

Excelente

Excelente jasistemas, me encanta tu aporte, complemeta la entrada en esta parte, te agradezco y espero te sirva la info que expongo.

Imagen de jasistemas

Para Rufaru:Al parecer la

Para Rufaru:
Al parecer la "solicitud de cancelacion" es la misma que estan solicitando la mayoria de los PACs, el xml firmado difiere al sellado de un CFDI donde solo se sella una cadena original.

En el caso de las cancelaciones se usa el "enveloped signature", donde se firma todo el documento, con .net pude hacerlo al menos ya la firma me esta saliendo valida, solo me falta probar vs el webservice de Edicom para un cliente, el desarrollo lo hice con .net.

EDICOM tiene 2 formas de cancelar con sus metodos de webservice, ya sea enviando el PFX (que incluye llave publica y privada), o bien firmando la solicitud (el xml).

Cuando cuentas con el .key y .cer por separado como te los da el SAT se dice que esta en formato "DER", en formato PKCS12 se trata de un .pfx a donde se integran tanto la llave publica como privada (lo armas con openssl creo), mas info aqui:
http://publikaccion.blogspot.mx/2007/05/tipos-de-formatos-de-certificado...

El XML armado debe tener este formato:
https://sites.google.com/a/facturadorelectronico.com/ayuda/home/timbrado...

En mi caso, luego de armar el XML, procedi al firmado accediendo con RSA de VB.NET a la llave privada (.key) y generando el signature, nodo que luego se agrega al XML.

Posteriormente el XML armado se codifica a base 64 (que es como lo pide Edicom). Si estas interesado en la DLL (que aun estoy probando) contactame por email jasistemas@hotmail.com

Problema con XMLBEANS

Buen dia, antes que nada muchas gracis por sus aportaciones las cuales son muy valiosas, soy apenas un desarrollador novato recien grauduado, pero me interesa mucho el tema del CFDI, actualmente tengo una aplicacion basica creada en java utilizando el IDE Netbeans y wampserver, deseo integrarle la herramienta de CFDI para ampliar el proyecto, eh visitado muchos foros de discucion y este es uno de las mas completos que encontre, quisiera ser parte de este, a la vez deseo contribuir, pero ahora me estoy presentando en algunos problemas, bueno en realidad iniciando o retomando el proyecto pero ahora con la integracion del CFDI me encontre con el problema de que no logro compilar el archivo cfdv32.xsd, eh revisado cada ruta lo eh descargado y vuelto a colocar en la subcarpeta bin y sigue surgiendo errores, de esta manera solicito saber si alguien de esta comunidad puede colaborarme con la entrega del archivo cfdv32.jar para poder proseguir con el proyecto

no sella de la misma forma con netbeans que con java

Tengo mi clase la cual se encarga de firmar. la corro con netbeans y todo perfecto.
Pero cuando genero el jar y lo ejecuto con java al parecer sella mal (me lo dice el pac) y lo comprobé con
el validador de solucionfactible.

utilizo Openssl de apache:
http://juliusdavies.ca/commons-ssl/download.html

A alguien ya le paso esto???

Ayuda, ya le moví aquí, allá y sigue igual.

Ayuda por favor !!!!

No se que mas hacer. por favor, que investigo?

Haz una traza

Hace mucho tiempo tuve algunos problemas similares. Hice una traza de los datos que estoy trabajando y sobre lo que observaba hacia mis correcciones. Lo mas típico es que los acentos se muetren "raros" en la cadena original debido a que el charset del contenido es distinto al que debes de utilizar.

Si no tienes un error especifico, imprime tus datos cada que los modifiques. verifica la cadena original, ya que esa es la base del cifrado.

cambie esta parte

cambie esta parte
sign.update(cadenaOriginal.getBytes("UTF-8"));
por
sign.update(cadenaOriginal.getBytes());

le quite el "UTF-8" y funciona tanto netbeans y con el jar.

ahora tengo otro problema.

el pac me regresa en un String el xml ya con el timbre, y yo lo guardo en un archivo con el siguiente código

     final Formatter nuevoarchivo;
                nuevoarchivo = new Formatter(rutaSalida);
                nuevoarchivo.format(((recepcion.getXml() != null) ? recepcion.getXml().getValue().replaceAll("[\n\r]", "") : "Error crítico"));
                nuevoarchivo.close();

pero de igual manera con netbeans al parecer se guarda bien lo abro con el internetExplorer pero
cuando trabajo con el jar no lo abre el internetExplorer para visualizarlo.

Ya lo solucione

 BufferedWriter out;
            try {
                out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(rutaFile), "UTF-8"));
                out.write("texto");
                out.close();
            } catch (IOException ex) {
            }

Gracias son grandes...

Imagen de nomarlegnar

Tarde pero sin sueño!

Lamento llegar tarde a contestar...

Resulta que el PAC timbra los archivos en UTF-8, probablemente ese es el principal problema al generar el XML.

Cuando ya tienes el CFDI timbrado efectivamente viene con el timbre fiscal digital y los JAR del CFD32 y NOMINA11 no funcionan correctamente debido a la inclusión del timbre por parte del SAT al XML del CFDI final, yo lo que hice fue copiar este XML en otro archivo y extraerle la linea del timbre para poder procesarlo correctamente. Obviamente deje intacto el original.

Me agrada saber que esta entrada en JavaMexico ha sido de gran utilidad para todos... yo batalle bastante para encontrar info al respecto y eso fue lo que me motivó a generar este humilde aporte.

Espero les siga sirviendo.

Imagen de nomarlegnar

CFDV32.jar y el NOMINA11.jar

https://drive.google.com/folderview?id=0B-xgtR5CbWoRTXhZNGpfR19jbmc&usp=...

aqui estan los dos el CFDV32.jar y el NOMINA11.jar

espero les sirvan saludos!!

Duda con cadena Original

Antes que nada, muchas gracias nomarlegnar por compartir información tan valiosa. Pasé semanas tratando de entender cómo se generaban los archivos XML y los sellados sin conseguirlo; en ocasiones encontraba alguna página indicando cómo hacerlo pero que no explicaban de la manera tan nítida como tu lo hiciste.

Por otra parte, ahora me encuentro ante otro problema relacionado con la facturación electrónica: la generación de la cadena original de la cual depende también el sello. Resulta que después de seguir las indicaciones de este blog (todo Ok) continué con las instrucciones de la página de Software Gurú (http://sg.com.mx/revista/31/generacion-cfdi-factura-desde-tus-apps#.U8wt...). Al ejecutar el método que genera la cadena original, veo que los acentos los pone con otros caracteres (ejemplo: México) y sé que esto afecta al sello.

Sé que el XML debe estar hecho en codificación UTF-8; he batallado para crear la cadena original en esta codificación y que se vean los caracteres correctamente, pero he fallado. No sé si alguien pueda ayudarme porque no sé que más hacer.

En mis últimos intentos la forma en que intenté remediar la cadena original fue:

public static String generarCadenaOriginal(final String xml) throws TransformerException{
System.out.println("Cadena (2): " + xml);
String cadenaOriginal="C:\\Users\\Juan Maya\\Documents\\empresa\\administrativo\\Cognointelia\\timbradi\\xslt\\cadenaoriginal_3_2.xslt";
StreamSource streamsource = new StreamSource(cadenaOriginal);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer xsltTransformer = transformerFactory.newTransformer(streamsource);
ByteArrayOutputStream output=new ByteArrayOutputStream();
xsltTransformer.transform(new StreamSource(new StringReader(xml)), new StreamResult(output));
byte[] output1=null;
try{
output1= output.toString().getBytes("UTF-8");
System.out.println("output 1: " + new String(output1) );
}catch(UnsupportedEncodingException e){
System.out.println("Error de codificacion: " + e.getMessage());
}

return new String(output1);
}

Y también:

Charset UTF_CHARSET=Charset.forName("UTF-8");
byte[] palabra_utf8 = xmlStr.getBytes(UTF_CHARSET);

String valueUTF8 = new String(xmlStr.getBytes(), "UTF-8");

Ninguno me ha funcionado.

De antemano, gracias.

Imagen de nomarlegnar

Espero que lo que te

Espero que lo que te comentaré te sirva...

A ver si te entendí...

Algunos de los parametros, datos e información con los que alimentas el XML son de tipo String, algunos de cuales contienen ACENTOS, y al momento de generar el archivo XML te aparecen caracteres erroneos tales como (ejemplo: México) , entonces pienso sería bueno que al momento de escribir el XML utilizaras el metodo getBytes(); (SOLO HASTA QUE ESCRIBAS EL XML).

public static void crearArchivoXML(String xmlStr) throws IOException {
        File datos = new File(ruta/archivo.xml);
        FileOutputStream writer;
        writer = new FileOutputStream(datos);                                
        writer.write( xmlStr.getBytes("UTF-8"));
        writer.write((EOL.getBytes("UTF-8")));
        writer.close();
}

espero que con esto salgas avante.. suerte!

Imagen de nomarlegnar

otra cosa...

cuando escribas código para que sea mas legible insértalo entre los tags < CODE >y< /CODE >...

mera recomendación...

Imagen de nomarlegnar

Checalo

checa

Sello invalido

Muchas gracias por tu respuesta. Disculpa que haya tardado en dar la mia, pero por cuestiones de trabajo anduve fuera y no pude revisar mi código.

Te comento, tengo prácticamente todo el código para generar una factura electrónica, pero el sellado me falla. Cuando escribí mi ultimo post, suponía que no estaba usando la codificación correcta (UTF-8), pero he llegado a la conclusión de que no es este el problema.

Ahondo en la situación: para sellar intenté usar SHA1 con RSA, pero cuando ocupo el validador de forma y sintaxis del SAT me dice que el sello del CFDI no es válido. Comparé la cadena original del validador contra la que genero y no veo diferencias. Después, hice una modificación a mi programa para que primero obtuviera la digestión del SHA-1 para, posteriormente, encriptarlo con RSA y lo que observo es que la digestión coincide, pero al momento de encriptarlo con RSA (y usar Base 64), el sello me sigue marcando como inválido por el validador.

¿Qué crees que pueda estar sucediendo? ¿Qué estaré haciendo mal?

Feliz día.

Problemas para descargar XMLBeans

Hola, buenas tardes, actualmente, quiero desarrollar una herramienta que me permita timbrar facturas, estoy utilizando este blog para entender cómo es que funciona y de ahí partir a desarrollar la propia. Mi duda es, ya ven que necesito el XMLBeans para poder trabajar, pero el detalle es que ingreso al sitio oficial y en el enlace de descargas, simplemente no puedo descargar el proyecto, ni fuentes ni binarios. Alguien podría apoyarme por favor??? De antemano agradezco las atenciones prestadas.

Re: descargar XMLBeans

Para descargar la librería de aquí: http://bit.ly/1F7KaHI o de acá: http://archive.apache.org/dist/xml/xmlbeans/

Imagen de magicokaka18

Problema al setear fecha e Impuesto

Hola, primero que nada agradecer este aporte que me fue de muchisima ayuda.

Tengo dos problemas, hice todo lo que está aquí. Mi problema es que al setear el impuesto me marca un error puesto que no acepta String sino Enum.

¿Cómo puedo pasarle ese parametro?
listt[0].setImpuesto("IVA"); --> Marca error puesto que no acepta String sino Enum pero no se como pasarle ese tipo de dato.

En fact.setFecha(Calendar.getInstance()); --> Aquí me genera una fecha con este formato yyyy-MM-dd'T'HH:mm:ss.00.00. Habrá algún problema al enviar al PAC este formato y no este: yyyy-MM-dd'T'HH:mm:ss.

Muchas gracias por sus respuestas.

Imagen de magicokaka18

Sigue los pasos

Hola, para descargar los XSD del sat busca en Google y son la primer opción. Depende el navegador que uses te muestra el XSD o te lo baja directamente. Si te lo muestra dale clic derecho en Guardar como y lo bajas.

De ahí baja el XMLBeans (yo usé la versión 2.6.0) y pegas este o estos XSD a la carpeta "bin" y ejecutas la sentencia en CMD que está aquí arriba en el tutorial. Eso te genera uno o unos JARS que pegas o importas a la carpeta LIB de tu proyecto y listo.

Imagen de nomarlegnar

Leer mas arriba

arriba pongo una liga de donde pueden descargar los JAR del nomina11 y cfdi32 ya generados...

Alguien podra Compartir el codigo de Generacion de factura.

Hola Amigos, como estan alguien podra compartir su codigo de Facturacion?

Este ejemplo esta claro y apoyado en este de Software Guru: http://sg.com.mx/revista/31/generacion-cfdi-factura-desde-tus-apps#.VyaT...

estan muy bien, solo que no hablan de los conceptos de la factura, entre otros.

Les agradezco infinitamente.

Saludos.

Hasta aqui logre avanzar, que

Hasta aqui logre avanzar, que mas me falta? la ultima linea que dice: crearArchivoXML(xmlStr); no me la reconoce(entiendo que no tengo el metodo, pero como seria? solo crear un archivo y guardarlo?)

En los conceptos necesito una propiedad que sea codigo del producto, como le haria?

Les agradezco cualquier comentario y/o sugerencia y/o orientacion

            ComprobanteDocument doc = ComprobanteDocument.Factory.newInstance();
            Comprobante comprobante = doc.addNewComprobante();

            XmlCursor cursor = comprobante.newCursor();
            QName location = new QName("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation", "xsi");
            cursor.setAttributeText(location, "http://www.sat.gob.mx/cfd/3 href=http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv3.xsd");
            cursor.toNextToken();
            cursor.insertNamespace("cfdi", "http://www.sat.gob.mx/cfd/3");
            comprobante.setVersion("3.2");
            comprobante.setSerie("A");
            comprobante.setFolio("1");
            comprobante.setFecha(Calendar.getInstance());
            comprobante.setFormaDePago("Pago en una sola exibicion");
            comprobante.setSubTotal(new BigDecimal(100));
            comprobante.setTotal(new BigDecimal(116));
            comprobante.setTipoDeComprobante(TipoDeComprobante.INGRESO);

            Emisor emisor = comprobante.addNewEmisor();
            emisor.setNombre("Software Guru");
            emisor.setRfc("AAA100010000");

            TUbicacionFiscal ubicacionFiscal = emisor.addNewDomicilioFiscal();
            ubicacionFiscal.setCalle("AAAAAAA1111");
            ubicacionFiscal.setNoExterior("999999999");
            ubicacionFiscal.setColonia("BBBBBBB1111");
            ubicacionFiscal.setCodigoPostal("CCCCCCC1111");
            ubicacionFiscal.setMunicipio("DDDDDD1111");
            ubicacionFiscal.setEstado("EEEEEE1111");
            ubicacionFiscal.setPais("FFFFF1111");
            emisor.setDomicilioFiscal(ubicacionFiscal);

            Receptor receptor = comprobante.addNewReceptor();
            receptor.setNombre("XXXXXXXXXXX");
            receptor.setRfc("EEEEEE44444");

            TUbicacion ubicacion = receptor.addNewDomicilio();
            ubicacionFiscal.setCalle("AAAAAAA1111");
            ubicacionFiscal.setNoExterior("999999999");
            ubicacionFiscal.setColonia("BBBBBBB1111");
            ubicacionFiscal.setCodigoPostal("CCCCCCC1111");
            ubicacionFiscal.setMunicipio("DDDDDD1111");
            ubicacionFiscal.setEstado("EEEEEE1111");
            ubicacionFiscal.setPais("FFFFF1111");
            receptor.setDomicilio(ubicacion);
            for (int i = 0; i < 4; i++) {
                Concepto concepto = comprobante.addConcepto();
                concepto.setCantidad(new BigDecimal(1.00));
                concepto.setDescripcion("AAAAAAA5555557777");
                concepto.setUnidad("Unidad");
                concepto.setImporte(new BigDecimal(300));
                concepto.setNoIdentificacion("C1");
            }
            Impuestos impuestos = comprobante.addNewImpuesto();
            impuestos.setTotalImpuestosTrasladados(new BigDecimal(50.00));

            //Generando el XML
            XmlOptions xmlOptions = new XmlOptions();
            HashMap namespaces = new HashMap();
            namespaces.put("http://www.sat.gob.mx/cfd/3", "cfdi");
            xmlOptions.setSaveSuggestedPrefixes(namespaces);
            xmlOptions.setSavePrettyPrint();
            xmlOptions.setSavePrettyPrintIndent(4);
            String xmlStr = doc.xmlText(xmlOptions);
            crearArchivoXML(xmlStr);

Imagen de nomarlegnar

CrearArchivo(xmlStr);

Ciertamente es un método que crea un Archivo XML...

El ejemplo está orientado a la generacion de un CFDI para nómina, para el caso que comentas, creo que requieres un complemento apropiado para tu comprobante, si esta fuera una factura basada en una venta de algunos productos por ejemplo... siendo, así me suena a que dentro del complemento correspondiente deberá haber subcomplementos que te permita agregar productos... no sé, sería cosa de investigar al respecto.
La entrada está basada en la liga de SG, también dentro de la información en la entrada vienen ligas de referecia al sitio del SAT y a otros sitios que te pueden ayudar a generar tu comprobante válido, deberás echarte un clavado a estas y ver por dónde, lamentablemente el código de la aplicación me es difícil proporcionartelo ya que no lo tengo actualmente.

Imagen de nomarlegnar

Actualizado

Entrada actualizada al 10/01/2017, espero les siga sirviendo como referencia para el CFDI.