Buscar en este blog

viernes, 26 de enero de 2018

(VirtualPAC) Cancelación de documentos en CFDI 3.3

Esta es una duda recurrente de todos nuestros usuarios: ¿ Puedo cancelar facturas ?, ¿ Cuando no voy a poder ? ¿ Como se cancelan las facturas CFDI  3.3 ?

En este articulo trataré de contestar a tus preguntas de acuerdo a lo que ha estado publicando el SAT con respecto a cancelación de CFDI 3.3 y a la interfaz de cancelación implementada en VirtualXML.

Lo primero, ¿ como cancelo facturas con VirtualXML ?

Muy sencillo: VirtualXML provee de la función VirtualXML_CancelaUUID() que se encarga de cancelar facturas en el portal del SAT.

De acuerdo a la documentación, esta función tiene la siguiente sintaxis :

VirtualXML_CancelaUUID(
 szUser,
 szEmisor,
 szCert,
 szKey,
 szPwd,
 szUuid,
 szOut)

Donde:
  • szUser: Es tu clave de usuario VirtualPAC 
  • szEmisor: Es el RFC del emisor que desea cancelar la factura
  • szCert: Es la ruta y nombre del archivo .CER del CSD. 
  • szKey: Es la ruta y nombre del archivo .KEY del CSD.
  • szPwd: Es el password del archivo KEY
  • szUuid: es el UUID del CFDI que se quiere cancelar 
  • szOut: Es el nombre de un archivo de texto donde el proceso de cancelación pondrá el(los) mensaje(s) devuelto(s) por el SAT.
Tenemos que tomar en cuenta que tanto el servicio de VirtualPAC, como el PAC, simplemente son pasarelas de comunicación entre el emisor que desea cancelar una factura y el servicio de cancelaciones del SAT, por lo tanto, todos los mensajes que recibas de proceso de cancelación son generados directamente por el SAT y ninguno de nuestros PACs ni nosotros mismos podemos hacer nada al respecto cuando el SAT te rechaza una cancelación o te indica que el servicio no está disponible.

El valor de retorno de la función está almacenado en el archivo de texto definido como último parámetro de la función, los posibles valores de retorno básicos que nosotros tenemos de una manera u otra controlados son:
  • UUID correctamente cancelado
  • UUID cancelado con anterioridad
  • UUID no encontrado en los registros del SAT (hay que esperar hasta 72 horas)
También pueden aparecer otros mensajes como Servicio No disponible intente mas tarde, Servicio fuera de horario, Servicio no existe, Error de Autenticación, etc. estos mensajes son generados directamente por el servidor del SAT y no hay nada que podamos hacer al respecto mas que esperar a que el servicio se regularice.

Como verás es muy fácil cancelar facturas CFDI incluso por medios automatizados como nuestra función de cancelación, pero fue esta facilidad de poder cancelar a diestra y siniestra lo que ocasionó problemas a muchos receptores que de buena fe confiaron en que sus emisores tenían las facturas vigentes cuando en realidad esas facturas se habían cancelado.

Lo que tenemos que tomar en cuenta, es que el SAT quiere evitar a toda costa que se cancelen indibidamente CFDIs de Ingreso sin que el receptor se entere porque en los modelos anteriores de CFDI, un emisor podía cancelar el CFDI sin avisar al receptor y este erroneamente lo hacía deducible cuando ya estaba cancelado en los registros del SAT.

Por otro lado también tenemos la picarezca de algunos malos emisores que a fin de reducir el pago de impuestos mensuales cancelaban arbitrariamente los documentos CFDI y el receptor se enteraba de que el documento estaba cancelado cuando le caía una revisión del SAT.

A fin de evitar esto, el SAT implementó dos mecanismos para tratar de reducir la cancelación indiscriminada de CFDIs para la nueva versión 3.3.

La primer medida es el COMPLEMENTO DE PAGOS PARCIALES 1.0, del cual hablaremos en otra ocasión, y la segunda medida es, simplemente, no dejar cancelar documentos, o mas bien, complicar el tema de la cancelación a fin de evitar que los emisores cancelen CFDIs sin previa autorización del receptor.

A partir del 1 de Julio de 2018 NO SE PODRAN CANCELAR CFDIs de Ingreso cuyo importe supere los $5,000.00 pesos (IVA incluído) a menos que se realicen las siguientes operaciones:

  • Entar en el portal SAT del contribuyente que desea cancelar una factura (emisor) usando la FIEL o la clave CIEC.
  • Una vez en el portal, el emisor deberá enviar al receptor, mediante el uso del BUZON TRIBUTARIO una solicitud de cancelación en la cual deberá incluir el UUID del documento en cuestión y una breve explicación de porqué desea cancelar el documento.
  • El receptor tendrá un plazo de 72 horas para contestar la solicitud de cancelación, en el supuesto de que el receptor no conteste dentro de las 72 horas posteriores a la recepción del documento, se dará por autorizada la cancelación y el emisor podrá cancelar MANUALMENTE, desde el portal de cancelación de facturas del SAT, el documento deseado usando los archivos de CSD (Certificado de Sello Digital) que tenga vigentes.
  • En caso de que el receptor se niegue a la cancelación del documento, el emisor tendrá que emitir la nota de crédito correspondiente o bien establecer un mecanismo alterno, definido por el propio emisor, para evitar que la factura emitida sea tomada en cuenta como ingreso.
Esto quiere decir, que si quieres cancelar una factura de mas de $5,000.00 pesos, deberás realizar una labor burocrática sujeta a que el receptor decida que puedes cancelar o no una factura, todo este proceso deberá de hacerse manualmente y por lo mismo vamos a tener que estar pendientes todos los dias del Buzón Tributario para ver si tenemos solicitudes de cancelación o bien se han resueltos las solicitudes hechas por nosotros a otros emisores.

¿ Se pueden cancelar CFDIs 3.3 sin necesidad de pedir autorización ?

Si, claro que se puede, en este momento y hasta la entrada en vigor del nuevo mecanismo (supuestamente el 1 de Julio de 2018) tu podrás seguir cancelando tus comprobantes fiscales CFDI 3.3 sin importar el tipo (I, E, T ó N) usando la función VirtualXML_CancelaUUID() de VirtualXML como lo haz venido haciendo desde el año 2014.

Cuando entre en vigor el nuevo mecanismo aplicarán nuevas reglas que hasta donde se sabe son:

  • Se podrán cancelar CFDI de Nomina, Traslado o Egreso sin necesidad de autorización por parte del receptor, tanto de manera manual, en el portal SAT, como de manera automática con la función VirtualXML_CancelaUUID().
  • Se podrán cancelar CFDI de Ingreso sin necesidad de autorización si el importe del documento es menor de $5,000.00 IVA incluido.
  • Se podrán cancelar CFDI de Ingreso sin limite de importe y sin necesidad de autorización si se emitieron al RFC genérico para público en general XAXX010101000, al RFC genérico para extranjeros XEXX010101000 o bien a un contribuyente del Régimen de Incorporación Fiscal (RIF).
  • Y todos los supuestos anteriores SIEMPRE Y CUANDO NO HAYAN PASADO MAS DE 72 HORAS DE LA EMISIÓN DEL COMPROBANTE.
Como verás la idea básica es que el receptor del documento sea el que resulte menos afectado y tú como emisor tienes una serie de obstáculos para cancelar tu documento bajo el nuevo esquema, en primer lugar tenemos la restricción de las 72 horas de plazo depués de la emisión, en segundo lugar y por lógica, no puedes pedir autorización de cancelación al público en general (no sabes quienes fueron) ni tampoco a un extenjero (no tienen buzón tributario) y todos los contribuyentes del RIF están perfectamente identificados en la LCO.

¿ Donde juega la "sustitución de documento" en todo este relajo ?

La sustitución de documento es simplemente una formalidad para informar al SAT que un nuevo documento toma el lugar de otro, pero esto no implica que el documento original queda automáticamente cancelado.

En estricta teoría, un documento debe ser cancelado y luego ser sustituido por otro con los datos y/o montos correctos, lo que quiere decir que un recibo de pagos, un recibo de nomina y un comprobante de traslado se pueden cancelar, y luego referenciar en la sección "documentos relacionados" del CFDI el(los) número(s) de UUID que el nuevo documento sustituye, esta regla aplica también a los comprobantes de ingreso, ya que supuestamente, si el receptor te autoriza, podrás poner como referencia el UUID del documento cancelado cuando se emite un nuevo comprobante de ingresos.

¿ Cual es la manera mas eficiente de evitar una cancelación de facturas ?, bueno, existen varios métodos, como por ejemplo remisionar en vez de facturar y emitir la factura una vez recibido el pago y entregada la mercancía (esto además te evita el complemento de pagos), otro método sería la emisión de notas de crédito que no le gustan a la mayoría de los contadores porque no se pueden aplicar sino hasta el final del ejercicio y por otro lado generan saldos a favor de los clientes.

Como verás a partir de 1 de Julio se complica un poco mas el CFDI 3.3 con al entrada en vigor de este nuevo mecanismo de cancelación, pero además con la entrada también de sanciones por el mal uso de las claves de los catálogos.

No hay que preocuparse de más, aun hay tiempo de seguir afinando la implementación del modelo CFDI 3.3 en las empresas, pero no hay que dejar de lado estos pequeños detalles a tomar en cuenta en la operación de los esquemas de facturación.




jueves, 25 de enero de 2018

(VitualPAC) La multa por no usar la clave correcta en tu facturación es de .....

Una de las cosas que ha tenido prórroga en cuanto al nuevo CFDI 3.3 es el uso de las claves del catálogo de productos y servicios, ya que a partir del 1 de Enero y hasta el 1 de Julio del 2018 estamos en una especie de "periodo de pruebas" para ir ajustando el modelo CFDI 3.3, por lo que no todo es obligatorio de momemento como el nuevo esquema de cancelaciones, el uso del Complemento de Pagos 1.0 y el uso del catálogo de productos y servicios.

Lo que no te dijeron es que si no aplicas correctamente la clave del catálogo de productos en tus facturas y sigues usando la clave 01010101 (sin definir), como muchos de nuestros usuarios nos han confesado que usan "para salir del paso",  el SAT te va premiar con una bonita multa de:

  • Persona física: de 1,240 pesos a 2,410 pesos.
  • Persona moral: de 13,5470 pesos a 77,580 pesos y en caso de reincidencia el fisco podrá clausurar sus actividades de tres a 15 días.
  • Donataria autorizada: de 12,070 pesos a 69,000 pesos y en caso de reincidencia se le revocará su autorización.
(fuente: Blog DFacturE)

¿ Me van a multar si no pongo la clave correcta ?, si, pero no ahora, estas multas tendrán vigencia a partir del 1 de Julio de 2018.

 Ooops... entonces  ¿ como empiezo ?, si yo vendo mas de 1,000 articulos distintos, tengo una ferretería, tienda al por mayor, refaccionaria, farmacia ¿ Tengo que clasificar todos mis productos y servicios de acuerdo al catálogo ?.... pues va a ser que sí.

No te angusties, aún hay tiempo, si te encuentras en esta situación, lo mas fácil es recurir a la clasificación que te den tus proveedores, mismos que en su facturación ya deben de incluir la clasificación de sus productos en base al catálogo de productos y servicios publicado por el SAT., puedes utilizar esta misma clasificación para ti.

Si eres fabricante o productor, entonces tendrás que buscar dentro del catálogo la clave que mas se acerque a lo que fabricas y para ello hemos escrito otro artículo en este blog, titulado "Localiza la clave de tu producto o servicio con CiberCAT", mismo que te enseñará el uso de nuestra herramienta CiberCAT.

No esperes hasta ultimo momento o peor aún, a que te pongan una multa, empieza hoy mismo a clasificar tus productos y/o servicios usando nuestra herramienta CiberCAT.... ES TOTALEMENTE GRATUITA !!!!!.

miércoles, 24 de enero de 2018

(VirtualPAC) Nuevo tratamiento para los mensajes de error.

El día de hoy liberamos una pequeña modificación en la forma en que VirtualPAC maneja los mensajes de error que devuelve el servicio de timbrado, a fin de que puedas indentificar y resolver dichos errores de una manera mas rápida.

En el artículo "El mejor archivo de autoayuda: VirtualXML.LOG" comentábamos que para el nuevo CFDI 3.3 y para los complementos nuevos: Nómina 1.2, Comercio Exterior 1.1 y Complemento de Recepción de pagos 1.0, que son XMLs condicionales, el SAT había publicado una "matriz de errores" para cada complemento y para el CFDI 3.3, que no es mas que una hoja de Excel que trae información acerca de la validación que el PAC debe realizar y en caso de que dicha validación falle, el mensaje de error que debe devolver, dichas matrices de validación las puedes descargar de:


Dentro de la arquitectura interna de VirtualPAC, a partir de hoy 24 de Enero 2018, hemos implementado que dentro del mensaje de error que te devuelve el servicio, se incluya también el código de error dentro de la matriz de validación, de tal forma que tu puedas consultar directamente la matriz de validación y ver posibles soluciones a tu problema.

A partir de hoy todos los mensajes de error lleva en prefijo:

ClaveError Mensaje

Ejemplo:

CFDI33132 Este RFC del receptor no existe en la lista de RFC inscritos no cancelados del SAT 

Donde ClaveError a su vez está compuesto de:

TipoXML ClaveError

 Del ejemplo anterior:

 CFDI33   132

TipoXML te indicará en que parte del XML está el error y lo identificas por las siguientes letras:
  1. CFDI33 = Documento XML CFDI33 (nodo comprobante)
  2. NOM = XML del complemento de Nómina 1.2
  3. CCE = XML del complemento de Comercio Exterior 1.1
  4. CRP = XML del complemento de Recepción de Pagos 1.0
Así pues, si obtengo un mensaje de error que diga:

CRP219 El campo TipoCambioDR no se debe registrar.

Aunque el mensaje de error sea lo suficientemente explícito, si quiero mas información sobre este error, entonces puedo ir a la hoja de Excel que contenga la matriz de errores, en este caso del Complemento de Recepción de Pagos 1.1 y buscar en la columna Código de Error CRP219:


Como verás además de darte mas información detallada del error, te dice exactamente en que nodo y atributo está el error:

 pago10:Pagos/pago10:Pago/pago10:DoctoRelacionado

TipoCambioDR

Así es mucho mas fácil entender donde nos estamos equivocando.

La matriz de errores es muy útil sin duda, te invito a que la descargues y la tengas a mano para resolver tus dudas en el uso de VirtualXML.

Espero que esta modificación en el servicio y este artículo sean utilidas para que puedas resolver mas rápido tus errores.

lunes, 22 de enero de 2018

(CiberCAT) Localiza la clave de tu producto o servicio con CiberCAT

Cuando entró en vigencia la nueva versión 3.3 de CFDI, uno de los grandes problemas que presentó fue el "famoso" catálogo de productos y servicios del SAT.

El nuevo esquema CFDI 3.3 te fuerza a clasificar el producto que vendes o el servicio que otorgas dentro de una lista o "catálogo" publicado por el SAT.

El susodicho catálogo de productos y servicios del SAT está integrado por mas de 52,000 elementos, dentro de los cuales, en estricta teoría, se engloban TODOS los productos y servicios que se ofertan en nuestro país.

No conforme con los 52,000 elementos del catálogo de productos y servicios, el SAT te obliga a clasificar además la unidad de medida de tu producto o servicio, de acuerdo a un segundo catálogo de "unidades de medida" mas pequeño ("solo" tiene 2,424 elementos) también publicado por el mismo SAT.

Estos 2 catálogos junto con el resto de los catálogos para ser utilizados en CFDI 3.3 son publicados por el SAT en un hoja de Excel y a partir ahí hay que buscarse la vida para encontrar entre los 52,000 elementos del catálogo lo que mas se aproxime al bien o servicio por el cual pretendes emitir una factura.

Adicionalmente a esto, el SAT te proporciona una versión en línea para que puedas buscar el código del producto o servicio que ofreces para incluirlo en tu factura.

Esta versión te va llevando por la clasificación del SAT empezando por productos o servicios, familias, categorías, etc. hasta que llegas a mas o menos lo que quieres facturar.

Ventaja: está en línea y lo puedes consultar cuando quieras, desventaja: es tremendamente lento para realizar las búsquedas.

En vista de lo anterior, decidimos crear nuestro propio consultador de estos catálogos que fuera mas rápido, intuitivo y eficiente de lo que es la página que el SAT te proporciona para esto.

Nuestro programa de consulta se llama CiberCAT y lo puedes descargar haciendo click en el link, es totalmente gratuito y lo puedes distribuir también sin costo entre tus usuarios sea o no clientes de VirtualPAC. A nosotros nos ha ahorrado mucho tiempo para ayudar a nuestros usuarios a encontrar la clasificación de su productos y a nosotros mismos por lo que decidimos donarlo al dominio público.

No es un programa nada elaborado pero si muy útil,  es tan simple que no quisimos sobrecargarlo con un programa de instalación, tampoco tienes que tener una versión especial de Windows, ni copiar componentes que luego quedan regados por todo el disco duro, su instalación es muy simple: Haz una carpeta en el disco duro de tu computadora, copia y extrae el contenido del archivo .ZIP que acabas de descargar en esa carpeta  y dale doble click al icono de CiberCAT.


La interfaz es muy simple, consiste en 2 pestañas, cada una contiene un catálogo distinto, la primera tiene el catálogo de productos y servicios, la seguna el catálogo de unidades de medida:

 

El contenido del cada catálogo es básicamente lo que el SAT tiene publicado en la hoja de Excel.

El uso del catálogo es simple, haciendo click sobre la cabecera de la columna esta se ordenará ya sea por la clave del producto o de la unidad (dependiendo del catálogo) o bien se ordenará por descripción. Solo se puede realizar ordenación sobre estas 2 columnas.

Veamos ahora la parte interesante de esta herramienta que son las búsquedas y para ello utilizaremos el interruptor que encontrarás  en la barra de botones:

Este interruptor te permitirá activar o desactivar la barra de filtro del listado de los catálogos, interruptor a la izquierda = Sin filtros, interruptor a la derecha = Filtro activo.

Cuando los filtros se encuentra activos verás que en la cabecera de todas y cada una de las columnas del listado se abre un pequeño espacio que dice: Escribir texto aquí:



Haz exactamente lo que indica: Posiciona el cursor sobre los espacios de filtro, escribe una palabra relacionada a lo que estás buscando y CiberCAT buscará la palabra que hayas tecleado dentro del contenido de la columna sobre la cual hayas escrito sin importar si la palabra está al principio, al final o en medio del contenido de la columna y además lo hace EXTREMADAMENTE RAPIDO.

Otra cosa interesante que puedes hacer es combinar filtros de distintas columnas, por ejemplo, la palabra "Médico" combinada con una parte de la clave de "servicios:" para el catálogo de productos:


El filtro del catálogo permanece activo mientras exista un valor en los campos de filtrado de cada columna.

¿ Y que pasa cuando ya localicé algo que se aproxima a lo que necesito ?

Si ya localizaste la clave de producto o servicio o bien de la unidad de medida que necesitas puedes hacer 3 cosas:

  1. Imprimirlo
  2. Exportarlo a Excel
  3. Copiar la clave al porta papeles
Supongamos que te dedicas a vender coches, y ya hubicaste la sección del catálogo que trae los vehículos que es la 25101, ahora puedes imprimir todo el listado (recuerda que el filtro permanece) o bien exportarlo a Excel, para esto puedes utilizar estos 2 botones de la barra de herramientas:


Si seleccionas el icono de la impresora aparecerá la vista previa del informe y de ahi podrás enviarlo a impresora:



Si presionas el icono de Excel, el listado filtrado aparecerá en una hoja de cálculo:



Si no requieres exportar la información ni imprimirla y solo te interesa obtener la clave, haz click con el botón derecho del ratón sobre el elemento del listado cuya clave desees copiar al portapaples y verás aparecer un menú contextual donde además de enviar a imprimir o a Excel, podrás copiar la clave al portapapeles para llevarla a otra aplicación:


El comportamiento y funcionalidad de CiberCAT es el mismo para los 2 catálogos, en ambos puedes filtrar, exportar, imprimir y copiar al portapapeles de la misma forma.

Como verás la operación de CiberCAT es muy simple e intuitiva, el usuario se sentirá rápidamente identificado con la operación y lo mas importante: Localizará las claves en el catálogo por el nombre del producto o servicio o de la unidad de una manera mas rápida que usando el catálogo del SAT en línea.

¿ Que pasa si el SAT publica nuevos catálogos o modifica los existentes ?, no pasará nada, simplemente nosotros actualizaremos los catálogos y  podrás descargar la nueva versión actualizada.

Por último un tip: ¿ Quieres que CiberCAT viaje contigo ?, no hay problema, la descarga siempre está disponible en línea, o bien, si no tienes acceso a internet en un momento dado, copia el contenido de la carpeta donde lo tienes instalado a una memoria USB y llévalo contigo donde quieras, no requiere ningún componente adicional, el programa se ejecutará desde la USB como se ejecuta en el disco duro de tu computadora.


jueves, 18 de enero de 2018

(VirtualXML) El mejor archivo de autoayuda: VirtualXML.log

VirtualPAC es un ecosistema que tiene vida propia, con mas de 35,000 emisores registrados, emitiendo un promedio de 25 millones de facturas anuales, que son como 70,000 facturas diarias, de emisores de todo tipo, desde la pequeña tienda de la esquina, hasta el gran retailer, pasando por un sinfin de negocios y actividades profesionales.

Cada factura es un pequeño universo: que si las escuelas deben llevar el complemento concepto de IEDU, que si las agencias de coches usan 2 complementos, uno para autos nuevos y otro para autos usados, que si los honorarios médicos no llevan IVA, pero los otros honorarios llevan IVA y retención de ISR, que si los transportistas hacen retencion del 4% del IVA, que si los hoteles llevan complemento de otros y impuestos y derechos, que si las constructoras llevan un complemento especial si están construyendo vivienda, en fin, miles y miles de posibles combinaciones para un solo comprobante.

Cuando se diseñó VirtualXML, sabíamos que tarde o temprano, dado el volúmen de información que se maneja y por la ley de los grandes números, surgirían problemas y dudas en el uso de las funciones de VirtualXML para la correcta elaboración del XML del CFDI, ¿ usan los programadores correctamente las funciones ?, ¿ se utilizan valores correctos en los parámetros ?, si surge un error, ¿ es culpa del usuario o es culpa de la librería o es culpa del PAC ?; es por eso que decidimos implementar un sistema de "depuración" (debugger) en VirtualXML, que nos ayudara a dos cosas: la primera: revisar si el usuario utilizó correctamente la librería y la segunda, en caso de error, saber el como, cuando, donde y porqué del mismo. Ese sistema de depuración es una bitácora del procesamiento de un documento CFDI 3.3 y se llama: VirtualXML.LOG.

VirtualXML.LOG es un archivo de texto que comienza a generarse nada mas hacer una llamada a la funcion: VirtualXML_New(), a partir de que tu llames a esta función, ya sea usando la DLL de funciones o bien usando el EXE externo VirtualXML.EXE, el archivo de bitácora VirtualXML.LOG se irá escribiendo en disco con importante información sobre el procesamientoo del documento que estás creando.

En este artículo del blog te mostraré como interpretar el contenido de la bitácora VirtualXML.LOG, alguno que otro truco escondido de la librería y verás que es muy sencillo localizar y solucionar tu mismo la mayoría de los errores que te pueden surgir con el uso de VirtualXML.

El archivo de bitácora VirtualXML.LOG esta dividido en 5 secciones:
  1. Sección de versión del producto e información general
  2. Sección de uso de funciones
  3. Sección de procesamiento del documento
  4. Sección del XML generado
  5. Sección de resultados de la operación 
A continuación te explico sección por sección su contenido y como puedes utilizarlo para saber en que está mal (o bien) tu CFDI 3.3:


1. Sección de versión del producto e información general

Esta sección ocupa los primeros 5 renglones del archivo de bitácora VirtualXML.LOG y contiene algo similar a esto:

|*|VirtualXML|vxml180110v1.0.4.4 Plataforma: x86 XP2K3|*|
|*|TickCount Start|1454445656|*|
|*|Sistema|Microsoft Windows XP Professional Service Pack 3 (build 2600)|*|
|*|ejecutable|U:\Sistemas.Cla\Exe6\ZeuEkms.exe|*|
|*|hXml|30780528|*|


En esta sección la primer línea es la mas importante de todas porque nos indica LA FECHA de la DLL que estamos usando así como su número de versión:

|*|VirtualXML|vxml180110v1.0.4.4 Plataforma: x86 XP2K3|*|

Donde dice vxml180110v1.0.4.4 encontrarás la fecha de creación de la DLL, y por si no lo sabias, el 180110 es la fecha que en este caso corresponde al año 2018 (18) Enero (01) día 10, la DLL que generó este archivo VirtualXML.LOG es la publicada el 10 de Enero de 2018.

A continuación viene la versión del producto: 1.0.4.4 y finalmente para qué plataforma fue creada, en este caso x86 XP2K3 indica que estás usando la versión especial compilada para Windows XP y 2003 server, en caso de que estés usando la compilación para otros sistemas operativos, aparecerá Plataforma: x86 o Plataforma: x64, dependiendo de la versión de la DLL que estés usando.

Esto me lleva a realizar algunas pequeñas aclaraciones que me ha comentado algunos de nuestros usuarios:

- ¿ Porqué 2 versiones de la misma DLL ?.

Pues porque tuvimos que hacer una versión compilada de manera distinta para Windows XP y Windows 2003 Server. En algunas versiones de estos sistemas operativos antiguos el uso de la DLL o del EXE indicaba que no eran archivos Windows válidos cuando los ejecutabas, al final descubrimos que era la forma en que se compilaban los productos, lo que nos llevó a tener que compilar una versión para los sistemas operativos viejos, y otra versión para los sistemas operativos mas nuevos (Windows 7, 8, 10 y 2008 y 2016 Server).

Lo mas curioso es que el producto de compilación "estándar" funcionó bien en la mayoría de los Windows XP, pero en la mayoría de los 2003 Servers no funcionaba, probamos distintas combinaciones de Services Pack, y .NET framework pero nunca pudimos encontrar con lo que fallaba exactamente hasta que cambiamos los parámetros de compilación del código fuente en Visual Studio 2012 y el nuevo producto compilado funcionó sin problemas en estas versiones.

¿ Debes cambiar tu DLL "estandar" por la especial para WindowsXP/2003 Server ?, depende, prueba primero si la compilación estándar funciona con tu sistema operativo, si no lo hace, utiliza la compilación especial para los sistemas operativos antiguos.

-¿ Porqué no puedo usar la versión de 64 bits de VirtualXML.DLL si mi sistema operativo es de 64 bits ?:

El uso de las versiones de 64 bits no depende del Sistema Operativo sino del lenguaje de programación, erróneamente muchos usuarios piensan que si tienen sistemas operativos de 64 bits, solo pueden usar aplicaciones o componentes de 64 bits y eso en realidad no es cierto. El aprovechamiento de las DLLs de 32 o 64 btis depende del lenguaje de programación.

No todos los lenguajes de programación generan EXEs de 64 bits, nuestros usuarios de .NET y Delphi 7 en adelante, pueden generar exes de 64 bits que pueden utilizar las versiones de VirtualXML de 64bits, otros lenguajes como VB6, FoxPro, Harbour, etc, deberán utilizar las DLLs de 32 bits.

Regresando al tema, la siguiente linea:

|*|TickCount Start|1454445656|*|

Es un contador de "ticks" que usamos internamente para medir el tiempo que toma generar un comprobante CFDI, no tiene ningún uso fuera del interno.

La siguiente linea es obvia, versión del sistema operativo donde se ejecutó la DLL o el EXE externo de VirtualXML:

|*|Sistema|Microsoft Windows XP Professional Service Pack 3 (build 2600)|*|

Seguimos con el nombre del archivo EXE que mandó llamar a la DLL (no aparece en el caso del VirtualXML EXE externo:

|*|ejecutable|U:\Sistemas.Cla\Exe6\ZeuEkms.exe|*|

Y finalmente el valor del "handle", dirección de memoria de la computadora donde se almacena el XML que la ejecución de las funciones de VirtualXML han generado, en realidad para efectos de depuración del XML no sirve para nada y no se por qué no lo hemos quitado.

Como verás con esta información nuestra área de soporte puede saber si estás usando una DLL actualizada, en que versión del sistema operativo la estas ejecutando y si necesitarías utilizar la versión estándar de VirtualXML o la versión especial para Windows XP/2003 Server (por eso siempre les pido "mándame el archivo VirtualXML.LOG" ).


2. Sección de uso de las funciones:

Esta segunda sección nos indica qué funciones de VirtualXML utilizaste, en que orden las mandaste llamar y que parámetros utilizaste para cada función, es una copia exacta de lo que escribiste en tu programa solo que expresado de una manera distinta:

|>|VirtualXML_New|3.3|<|
|>|VirtualXML_SetVirtualPACInfo|demo_cibertec|demo|<|
|>|VirtualXML_SetComprobanteInfo_cfdi33|ING|73|%cb_date|01||100.00||MXN||116.00|I|PUE|20010||<|
|>|VirtualXML_SetComprobanteFecha|2018-01-12T17:26:21|<|
|>|VirtualXML_SetEmisorInfo_cfdi33|AAA010101AAA|PRUEBA|601|<|
|>|VirtualXML_SetReceptorInfo_cfdi33|ASY130611V91|A&A SYNERGY SADEC.V|||G03|<|

|>|VirtualXML_AddConcepto_cfdi33|80131501||1.00|H87|PIEZA UNITARIA|RENTA DE UN MES|100.00|100.00||<|
|>|VirtualXML_AddConceptoTraslado_cfdi33|100.00|002|Tasa|0.16|16.00|<|
|*|Info|Creating Concepto.Impuestos|*|
|>|VirtualXML_AddConceptoInformacionAduanera_cfdi33|16 22 4584 7 654321|<|
|>|VirtualXML_SetImpuestosInfo_cfdi33|16.00||<|
|>|VirtualXML_AddTraslado_cfdi33|002|Tasa|0.16|16.00|<|
|>|VirtualXML_ProcesaDocumento|C:\AAA010101AAA.CER|C:AAA010101AAA.KEY|12345678a|C:\XML\AAA010101AAA_ING_73.XML|<|


La información anterior nos permite reproducir en nuestras instalaciones la secuencia exacta del uso de las funciones de VirtualXML que tu utilizaste en tu programa, ya que el orden en el que se utilizan es tan importante como la lista de parámetros que usas.

¿ Como usamos esta sección para reproducir tu error ?, muy sencillo: a través de VirtualXML.EXE

VirtualXML.EXE es un "interprete" de las funciones de la librería VirtualXML.DLL que funciona desde la línea de comandos y utiliza un pseudolenguaje de programación basado en funciones (que son las mismas que VirtualXML.DLL) para generar un CFDI 3.3 sin necesidad de un programa o un lenguaje de programación, simplemente pones tus instrucciones en un archivo de texto, y ejecutas desde la línea de comandos:

c:\VirtualXML ArchivoDeTextoConInstrucciones.vxml

Y podemos firmar, sellar y timbrar TU documento en nuestras instalaciones.

¿ Como resolvemos el tema de los certificados ?, muy sencillo: utilizamos los certificados de demo para el RFC de pruebas AAA010101AAA, y lo que hacemos es simplemente editar el archivo de bitácora VirtualXML.LOG, seleccionar la sección de instrucciones, copiarla y pegarla en un nuevo archivo en blanco, cambiar las credenciales de VirtualPAC en la función VirtualXML_SetVirtualPACInfo() para utilizar nuestras credenciales de prueba, cambiamos el RFC del emisor por AAA010101AAA, y sustituimos los datos del certificado en la llamada a la función VirtualXML_ProcesaDocumento() por los certificados de pruebas.

Luego ejecutamos VirtualXML.EXE pasando como parámetro el nombre del archivo creado y vemos los resultados.

Usando esta sección podemos identificar si te equivocaste en el nombre de alguna función, mandaste un parámetro inválido, si estas usando todas las funciones correctamente y en general, damos un vistazo sobre la secuencia de instrucciones que seguiste para generar tu XML, es en esta sección donde te podemos corregir como usas la librería.


3. Sección de procesamiento del documento.

Esta sección es de uso interno para nosotros, y nos indica que pasos va siguiendo el procesamiento del XML para realizar primeramente el sellado y firmado del documento, es decir, generar el sello y la firma con tus certificados, esta sección se parece un poco a esto:

|*|finalCleanup|Inicia|*|
|*|finalCleanup.Addenda|Nodo.Removido|*|
|*|finalCleanup|Termina|*|
|*|Validando Documento|.....|*|
|*|Validacion|Addenda no encontrada ... OK|*|
|*|Firmando documento|.....|*|
|*|ValidaFechaRFC.safeRFC|GOAR720320KF7|*|
|*|Sello.cfdi33.SHA256|CxCXXy7/g4Bltqr30OlwThrvZYI5fcHzC/8t4wq63YIFCZQ+IA5Ogp8y0EnZash9IloSMXN3SLVR5fucNaSv7cehhyuu1A3X7T9XnmReg8+29Xq1ryD79fdn7kTTvUJB519jqOrZxPGb//vDmz3BUnXdEC4jHz6nGVh7Kuj93xrT+1rEnvgnewL3Bgvt0ftnndzkMrCTe/TPFGiqXbYA9F1EABuR8mKAH/MGB1WU43n18uOvEk37tgwFBdu/43J9ae4NYIi0vJCFXNISEK6PpfKSuFe2r9J/FZU0lKnlp5t58vRC/FkDsc6jlTiq+2vT4AigJkM5IVngwh9IWAvr3A==|*|
|*|SellaDocumento|OK|*|
|*|DocumentoFirmado|


Esta sección nos indica que funciones internas de la DLL va siguiendo el procesamiento del documento, como por ejemplo finalCleanup, Validacion, Firmado, obtención del sello digital en formato SHA256 y resultado del proceso de sellado digital y firmado del documento.

Si por alguna razón VirtualXML llegara a fallar durante este proceso, y el programa abortará su ejecución, esta sección nos indicará cual fue la última función que se ejecutó con éxito y podremos revisar el código fuente de la librería para ver donde y porqué no se ejecutó la función que causó el fallo.

Si todo el proceso de firmado y sellado fue exitoso, entonces tendremos la siguiente sección que es: 


3. Sección del XML generado.

En las primeras versiones de VirtualXML, allá por el año 2012, 2013, esta sección no existía, asumíamos que VirtuaXML no fallaba nunca y que siempre entregaba resultados exactos (lo cual era cierto para CFDI 3.2).

Con la entrada de la Nómina 1.2, el uso de catálogos y los nuevos XMLs condicionales, nos dimos cuenta de que incluir el XML tal cual lo había generado la librería, depués de firmarlo y sellarlo digitalmente y antes de enviarlo al PAC para generar el timbre fiscal digital, sería una gran idea para ayudarnos a depurar no solo la sintáxis, sino también el contenido del XML.

Un XML de CFDI pasa por 3 controles se seguridad, el primer control te lo da VirtualXML ya que las funciones que generan los distintos nodos y atributos del XML estan basadas en los XSD publicados por el SAT para CFDI 3.3 y todos sus complementos, por lo tanto VirtualXML, si lo tienes actualizado, generará y validará nodos y atributos de acuerdo a lo publicado con el SAT.

El segundo nivel de seguridad también lo da VirtualXML, al realizar el proceso de firmado digital del documento usando el archivo .CER de CSD (Certificado de sello digital) y sellando digitalmente el documento previa generación de la cadena original, digesto SHA256 y encriptamiento del mismo usando el algoritmo RSA Encrypt.

Estas dos primeras revisiones las realiza directamente VirtualXML y son transparentes para tí, tu no tienes que saber como generar la firma digital o el sello, VirtualXML lo hace por tí.

El tercer control de seguridad lo aplica el PAC sobre un XML que ya tiene que estar firmardo y sellado digitalmente; antes de generar el timbre fiscal digital, el PAC realiza una validación de forma, sintaxis y contendido del XML enviado, validación similar a la que hacía el SAT al documento en la versión 3.2, si por alguna razón esta validación llegara a fallar como por ejemplo con el error "el sello de comprobante no es válido", contar con el XML completo nos puede ayudar a determinar donde estuvo la falla en el contenido del archivo.

Existen herramientas como el editor oXygen XML que simplemente copiando el XML del archivo VirtualXML.LOG y pegándolo dentro de este editor te puede decir qué datos de los atributos son válidos y cuales no de acuerdo a los XSD publicados por el SAT.

Esta sección se ve mas o menos así dentro del archivo de bitácoraVirtualXML.LOG:

<CiberSAT5 PAC="VirtualPAC" usuario="demo_cibertec" servidor="demo">
    <cfdi:Comprobante xmlns:cfdi="http://www.sat.gob.mx/cfd/3" 

     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd" 
     Version="3.3" 
     Serie="ING" 
     Folio="73" 
     Fecha="2018-01-12T17:26:21" 
     Sello="." 
     FormaPago="01" 
     NoCertificado="12345678901234567890" 
     Certificado="." 
     SubTotal="100.00" 
     Moneda="MXN" 
     Total="116.00" 
     TipoDeComprobante="I" 
     MetodoPago="PUE" 
     LugarExpedicion="20010">
     <cfdi:Emisor Rfc="AAA010101AAA" Nombre="PRUEBA" RegimenFiscal="601"/>
     <cfdi:Receptor Rfc="ASY130611V91"

                    Nombre="A&amp;amp;A SYNERGY S. A DE C.V" UsoCFDI="G03"/>
        <cfdi:Conceptos>

            <cfdi:Concepto ClaveProdServ="80131501" 
                           Cantidad="1.00" 
                           ClaveUnidad="H87" 
                           Unidad="PIEZA UNITARIA" 
                           Descripcion="RENTA DE UN MES" 
                           ValorUnitario="100.00" Importe="100.00">
                <cfdi:Impuestos>
                    <cfdi:Traslados>
                        <cfdi:Traslado Base="100.00" 

                                      Impuesto="002" 
                                      TipoFactor="Tasa" 
                                      TasaOCuota="0.16" 
                                      Importe="16.00"/>
                    </cfdi:Traslados>
                </cfdi:Impuestos>
                <cfdi:InformacionAduanera NumeroPedimento="16 22 4584 7 654321"/>
            </cfdi:Concepto>
        </cfdi:Conceptos>
        <cfdi:Impuestos TotalImpuestosTrasladados="16.00">
            <cfdi:Traslados>

                 <cfdi:Traslado Impuesto="002" 
                                TipoFactor="Tasa" 
                                TasaOCuota="0.16" 
                                Importe="16.00"/>
            </cfdi:Traslados>
        </cfdi:Impuestos>
        <cfdi:Complemento>
            <tfd:TimbreFiscalDigital xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/cfd/TimbreFiscalDigital/TimbreFiscalDigitalv11.xsd" Version="1.1" UUID="00000000-0000-0000-0000-000000000000" FechaTimbrado="2011-01-01T00:00:00" RfcProvCertif="AAA010101AAA" SelloCFD="" NoCertificadoSAT="12345678901234567890" SelloSAT=""/>
        </cfdi:Complemento>
    </cfdi:Comprobante>

</CiberSAT5>

 Digamos que esta "vista previa" del XML nos va a  permitir hacer muchas cosas como por ejemplo validar un complemento o quitar y poner una addenda.

CiberTec recomienda ampliamente el uso del editor oXygen XML para realizar la revisión de estos XML generados con VirtualXML.

Este documento XML es el que VirtualXML envía a VirtualPAC y de ahí se envía al PAC para ser timbrado, y el resultado de la operación de timbrado se reporta en la última sección del archivo:


5. Sección de resultados de la operación:

La última sección del archivo de bitácora VirtualXML.LOG contiene los resultados de la operación de timbrado, cabe mencionar que todos los mensajes de error del XML no son reportados por VirtualXML ni por el servicio de VirtualPAC, es el PAC directamente el responsable de generar los mensajes de error.

El SAT provee al PAC de una "matriz de errores", esta matriz de validación le indica al PAC que debe validar del XML, y que error reportar cuando este se genera, eso está muy bien porque POR FIN, tenemos una lista de errores estándar para todos los PACs.

La matriz de validación es simplemente un archivo en Excel que incluso está publicado por el SAT y que puedes descargar haciendo click aqui: Matriz de errores CFDI 3.3.

Localizar el error en la matriz de errores es muy sencillo ya que solo son 98 posibles errores en todo el proceso del CFDI 3.3

 Si tu XML se timbró correctamente, entonces en esta sección debería de aparecer algo como esto:

*|Timbrando documento|.....|*|
|*|MODO|##### PROD ##### PROD ##### PROD ##### PROD ##### PROD ##### PROD ##### PROD ##### PROD ##### PROD ##### PROD #####|*|
|*|TFD.Version|1.1|*|
|*|GeneraCBB.qcode|https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=74413E69-3CC1-4079-B886-449CD10F00B8&re=AAA010101AAA&rr=CTE940531F58&tt=1102.000000&fe=uFiSSQ==|*|
|*|GeneraCBB.Arch.x86|Use external CiberCBB.dll|*|
|*|GeneraCBB.CiberCBB|Loaded|*|
|*|GeneraCBB.CiberCBB|Encode2File|*|
|*|GeneraCBB.CiberCBB|Free|*|
|*|GeneraCBB.CiberCBB|Bmp.Created|*|
|*|Resultado de proceso|VIRTUALXML_OK|*|
|>|VirtualXML_Free|<|

|*|BEGIN RESULTADOS|.....|*|
|*|VIRTUALXML_GET_DESCERROR|VIRTUALXML_OK|*|
|*|VIRTUALXML_GET_ERROR||*|
|*|VIRTUALXML_GET_CSDNUMBER|00001000000306430645|*|
|*|VIRTUALXML_GET_SELLO|MGDrLjB1CRBw1xRpxNw+6aG0Y962/ztZqFfqcDgU1/pmqTRt+CBr0uIjpvnCU8x0enSvJV9/YH8hi75TsrFF15Yda0uFPLWMSg8674Tc6Us8IPBQBmTi57CRVWwSNZkstvOynFXZMaX8yPx36PHAgQ20X4h5yFK/O3H5CH2t018=|*|
|*|VIRTUALXML_GET_CADENA|||3.3|A|8|2018-01-16T18:54:38|01|00001000000306430645|Contado Comercial|172.41|0.00|MXN|199.99|I|PUE|84623|MOME661206TN5|JOSE ELIGIO MORAN MIRANDA|612|ROMN711129S27|NOEMI ROJAS MERAZ|P01|30171708|1|MTR|Metro|Vidrio claro 3mm|172.41|172.41|172.41|002|Tasa|0.160000|27.58|002|Tasa|0.160000|27.58|27.58|||*|
|*|VIRTUALXML_GET_SATCSDNUMBER||*|
|*|VIRTUALXML_GET_SATSELLO||*|
|*|VIRTUALXML_GET_SATCADENA||*|
|*|VIRTUALXML_GET_SATUUID||*|
|*|VIRTUALXML_GET_SATFECHA||*|
|*|VIRTUALXML_GET_SATRFCPROVCERTIF||*|
|*|VIRTUALXML_GET_SATLEYENDA||*|
|*|VIRTUALXML_GET_CSDINI|150317201349Z|*|
|*|VIRTUALXML_GET_CSDFIN|190317201349Z|*|
|*|VIRTUALXML_GET_VPID|75419|*|
|*|VIRTUALXML_GET_DISP|95|*|
|*|VIRTUALXML_GET_DLLVERSION|vxml170816v1.0.3.5|*|
|*|VIRTUALXML_GET_FECHAXML|2018-01-16T18:54:38|*|
|*|VIRTUALXML_GET_WARN||*|
|*|VIRTUALXML_GET_PAC|DFA|*|
|*|VIRTUALXML_GET_REVISION|x86|*|
|*|END RESULTADOS|.....|*|

|*|TickCount End|5828836|*|


Este mensaje indica en que modalidad se timbró el documento: producción (PROD) o demo (DEMO), te indica también que versión del TFD (Timbre Fiscal Digital) usaste, en este caso la 1.1.

La siguiente parte de esta sección te indica como se generó el CBB (Código de Barras Bidimensional) de la factura:

|*|GeneraCBB.qcode|https://verificacfdi.facturaelectronica.sat.gob.mx/default.aspx?id=74413E69-3CC1-4079-B886-449CD10F00B8&re=AAA010101AAA&rr=CTE940531F58&tt=1102.000000&fe=uFiSSQ==|*|
|*|GeneraCBB.Arch.x86|Use external CiberCBB.dll|*|
|*|GeneraCBB.CiberCBB|Loaded|*|
|*|GeneraCBB.CiberCBB|Encode2File|*|
|*|GeneraCBB.CiberCBB|Free|*|
|*|GeneraCBB.CiberCBB|Bmp.Created|*|


Hagamos un breve paréntesis para explicar como VirtualPAC y VirtualXML manejan el tema de los códigos CBBs.

Si haz observado, cuando timbras exitosamente un documento obtienes dos códigos de barras bidimensionales (o QR Code) en 2 formatos gráficos distintos, uno en formato PNG y otro en formato BMP, ambos contienen la misma información aunque la imagen sea distinta, si tu aplicas un lector de códigos QR que puedes descargar a tu telefono (nosotros recomentadmos la app i-nigma para la lectura de los códigos de barras, está disponbile para Android y para iOS) verás que aunque la imagen sea distinta, el contenido es el mismo.

¿ Porqué generamos 2 códigos de barras en 2 formatos gráficos distintos ?, por compatibilidad, no por gusto, créanme si les digo que yo preferiría usar un solo código de barras (el PNG) pero los lenguajes de programación antiguos no siempre ofrecen soporte para manejar otros formatos gráficos que no sean BMPs y es por esa razón que generamos 2 archivos de CBB.

Lo interesante es quién genera cada código, el PNG es generado en el servicio de VirtualPAC, es decir en nuestros servidores de producción de timbrado, y es devuelto como respuesta a la petición de timbrado si esta fue exitosa, VirtualXML, del lado del usuario, lee la respuesta de VirtualPAC y escribe en disco la imagen PNG devuelta por el servicio de VirtualPAC.

Mientras que el archivo PNG se genera de manera remota, en nuestros servidores, el archivo BMP se genera de manera local en la computadora del usuario, y para generarse tiene 2 maneras: sin dependencias o con dependencias.

VirtualXML tiene construida su propia función para generar CBBs en formato BMP, dicha función es VirtualXML_GeneraCBB() que puedes usar desde tus programas para generar tus propios códigos de barras bidimensionales, solo sigue los parámetros de la documentación.

VirtualXML_GeneraCBB() puede generar los códigos de barras en formato BMP por sí misma ya que tiene interconstruída la rutina de generación de CBB byte por byte o bien, puede utilizar una "dependencia" en este caso de un viejo conocido que es la DLL CiberCBB.DLL misma que hemos venido utilizando desde los viejos tiempos del CFD, allá por el años 2010.

Si VirtualXML.DLL encuentra en el mismo directorio donde esté instalado la DLL CiberCBB.DLL entonces hará uso de esta para generar los códigos de barras bidimensionales (con depedencia), si no la encuentra, entonces utilizará la función interna nativa.

¿ Porqué 2 maneras de generar el mismo archivo ?, regresamos al tema de la compatibilidad, cuando desarrollamos estas funciones, detectamos que muchos lenguajes de programación viejos no podían leer el CBB en formato BMP generado por las funciones internas de VirtualXML, por lo que tuvimos que regresar a CiberCBB.DLL el cual genera BMPs compatibles con estos lenguajes viejos. Los lenguajes de programación mas modernos pueden utilizar ya sea la imagen en formato PNG o bien el BMP generado por las funciones internas de VirtualXML.

Por otro lado tenemos el tema de los 64 bits, debido a que no existe una versión de CiberCBB.DLL de 64 bits, la generación de los CBBs para los lenguajes de 64 bits tiene que hacerse mediante el uso de la función interna VirtualXML_GeneraCBB(), lo cual por otro lado no tiene ningún caso porque un lenguaje de 64 bits, por su puesto puede leer imágenes en formato PNG, pero pues ahí está para que lo use quien lo necesite.

Finalmente, si todo salió bien entonces veremos este mensaje:

|*|Resultado de proceso|VIRTUALXML_OK|*|

VIRTUALXML_OK indica que el proceso de timbrado del documento fue exitoso y a continuación veremos la lista de valores retornados por el proceso de timbrado, mismos valores puedes recuperar desde tu programa usando la función VirtualXML_GetValue()

|*|BEGIN RESULTADOS|.....|*|
|*|VIRTUALXML_GET_DESCERROR|VIRTUALXML_OK|*|
|*|VIRTUALXML_GET_ERROR||*|
|*|VIRTUALXML_GET_CSDNUMBER|00001000000306430645|*|
|*|VIRTUALXML_GET_SELLO|MGDrLjB1CRBw1xRpxNw+6aG0Y962/ztZqFfqcDgU1/pmqTRt+CBr0uIjpvnCU8x0enSvJV9/YH8hi75TsrFF15Yda0uFPLWMSg8674Tc6Us8IPBQBmTi57CRVWwSNZkstvOynFXZMaX8yPx36PHAgQ20X4h5yFK/O3H5CH2t018=|*|
|*|VIRTUALXML_GET_CADENA|||3.3|A|8|2018-01-16T18:54:38|01|00001000000306430645|Contado Comercial|172.41|0.00|MXN|199.99|I|PUE|84623|MOME661206TN5|JOSE ELIGIO MORAN MIRANDA|612|ROMN711129S27|NOEMI ROJAS MERAZ|P01|30171708|1|MTR|Metro|Vidrio claro 3mm|172.41|172.41|172.41|002|Tasa|0.160000|27.58|002|Tasa|0.160000|27.58|27.58|||*|
|*|VIRTUALXML_GET_SATCSDNUMBER||*|
|*|VIRTUALXML_GET_SATSELLO||*|
|*|VIRTUALXML_GET_SATCADENA||*|
|*|VIRTUALXML_GET_SATUUID||*|
|*|VIRTUALXML_GET_SATFECHA||*|
|*|VIRTUALXML_GET_SATRFCPROVCERTIF||*|
|*|VIRTUALXML_GET_SATLEYENDA||*|
|*|VIRTUALXML_GET_CSDINI|150317201349Z|*|
|*|VIRTUALXML_GET_CSDFIN|190317201349Z|*|
|*|VIRTUALXML_GET_VPID|75419|*|
|*|VIRTUALXML_GET_DISP|95|*|
|*|VIRTUALXML_GET_DLLVERSION|vxml170816v1.0.3.5|*|
|*|VIRTUALXML_GET_FECHAXML|2018-01-16T18:54:38|*|
|*|VIRTUALXML_GET_WARN||*|
|*|VIRTUALXML_GET_PAC|DFA|*|
|*|VIRTUALXML_GET_REVISION|x86|*|
|*|END RESULTADOS|.....|*|

Veamos ahora que pasa si tenemos un error en el proceso de timbrado.
Si surgió un error en el proceso de timbrado, en donde debería decir VIRTUALXML_OK se verá algo como esto:

|*|Resultado de proceso|VIRTUALXML_ERROR_SERVER|*|
|*|Msg|El RFC del emisor no se encuentra en la lista de contribuyentes|*|
|>|VirtualXML_Free|<|

O algo como esto:

|*|Resultado de proceso|VIRTUALXML_ERROR_SERVER|*|
|*|Msg|El valor del campo Importe que corresponde a Retención no se encuentra entre el limite inferior y superior permitido.|*|

El favorito de esta semana:

|Resultado de proceso|VIRTUALXML_ERROR_SERVER|*|
|*|Msg|El TipoDeComprobante es I,E o N, el importe registrado en el campo no es igual a la suma de los importes de los conceptos registrados.|*|

Otro error pero ahora con un complemento:

|*|Resultado de proceso|VIRTUALXML_ERROR_SERVER|*|
|*|Msg|El atributo cce11:ComercioExterior:Destinatario:NumRegIdTrib no tiene un valor que exista en el registro del país indicado en el atributo cce11:ComercioExterior:Destinatario:Domicilio:Pais.|*

La forma en que se reportan los errores ahora es estándar para todos los PACs gracias a la matriz de errores del SAT, por lo que no importa con que PAC timbres, cuando ocurra un error siempre se reportarán los mismos textos informativos.

Ahora bien, tengo un error, ¿ cómo lo soluciono ?

Te diría que es muy facil, porque el mismo error te explica donde te están fallando las cosas, por ejemplo el error "El RFC del emisor no se encuentra en la lista de contribuyentes" no es culpa ni tuya, ni mia, ni del PAC, en todo caso será culpa del contribuyente o bien del SAT que no actualizó correctamente la LCO, para mas información sobre este tema, lee mi artículo titulado: Este RFC del receptor no existe en la lista de RFC inscritos no cancelados del SAT

En el caso del error "El valor del campo Importe que corresponde a Retención no se encuentra entre el limite inferior y superior permitido" y del error "El TipoDeComprobante es I,E o N, el importe registrado en el campo Total no es igual a la suma de los importes de los conceptos registrados", ambos se deben a un error de cálculo en los importes ya sea de totales, impuestos retenidos o trasladados (los malditos redondeos), para mas información, lee mi artículo:Como redondear importes en CFDI 3.3 y no morir en el intento.

¿ Cuantos errores hay ?, según la matriz de errores del SAT existen 98 errores que pueden surgir por validación de CFDI 3.3, pero no son todos, los nuevos complementos como Nómina 1.2 y Comercio Exterior 1.1 tienen su propia matriz de errores, así que también te pueden aparecer errores de un complemento en específico como en el cuarto ejemplo que dice: "El atributo cce11:ComercioExterior:Destinatario:NumRegIdTrib no tiene un valor que exista en el registro del país indicado en el atributo cce11:ComercioExterior:Destinatario:Domicilio:Pais.", en este caso, es un error propio del complemento de Comercio Exterior 1.1 y deberemos consultar la matriz de error de dicho complemento para saber como solucionarlo.

Como verás el archivo VirtualXML.LOG es una gran herramienta de ayuda para saber si estas haciendo bien o mal tus XMLs y te puede ayudar a solucionar tus problemas de una manera rápida.


Un par de trucos interesantes con VirtualXML.LOG:

Para finalizar este artículo te voy a mostrar un par de cosas que puedes hacer con VirtualXML.LOG.

Un truco interesante para aprovechar el archivo VirtualXML.LOG consiste en cambiarle el nombre, de tal manera que puedas identificar el archivo de bitácora para cada caso en específico; imagina este escenario: estás trabajando en red y almacenando los XMLs de timbrado en el disco duro del servidor, cada proceso de generación de CFDI genera un archivo VirtuallXML.LOG que siempre tiene el mismo nombre, si varios usuarios concurrentes están generando facturas al mismo tiempo, los archivos se sobreescribirán uno sobre otro, de tal manera que no tienes manera de saber a que operación de timbrado pertence el archivo VirtualXML.LOG, pero esto se puede evitar cambiando el nombre y la ubicación  del archivo VirtualXML.LOG mediante la función VirtualXML_SetLogFile().

VirtualXML_SetLogFile() te permite cambiar el nombre y la ubcación del archivo VirtualXML.LOG, asi podras tener un archivo de bitácora individual para cada proceso de timbrado, suamemente útil para saber exactamente que errores obtienes por documento enviado a timbrar.

VirtualXML_SetLogFile() debe usarse INMEDIATEMENTE DESPUES de la llamada a la función VirtualXML_New() y una vez que hayas obtenido el handler del documento CFDI, ya que por default, al llamar a la funciónVirtualXML_New() se comienza a crear automáticamente un archivo con el nombre VirtualXML.LOG, y todo el proceso se irá almacenando en este archivo a menos que se utilice la funcion VirtualXML_SetLogFile(), si esta función se utiliza, VirtualXML copiará el contenido que lleve hasta el momento el archivo VirtualXML.LOG al archivo que hayas especificado en la función VirtualXML_SetLogFile() y continuará utilizando el nuevo archivo para almacenar los resultados. hasta la llamada a la funcion VirtualXML_Procesadocumento(). Usando este sencillo truco tendrás un archivo LOG distinto por cada proceso de timbrado que ejecutes.

Otro truco interesante consiste en ir guardando el contenido del archivo de bitácora "por partes" y esto se hace utilizando la función VirtualXML_Save()

Esta función te permite guardar el contenido del archivoVirtualXML.LOG  en cualquier momento en uno o varios archivos cuyo nombre tu puedes determinar usando el segundo parámetro de esta función.

Hasta aquí este artículo que espero que te sea de mucha utilidad, como dice el refrán: "ayúdate que yo te ayudaré" y sin duda el saber como usar el archivo VirtualXML.LOG te será de gran utilidad para resolver tus dudas de timbrado

jueves, 11 de enero de 2018

(VirtualPAC) Este RFC del receptor no existe en la lista de RFC inscritos no cancelados del SAT

De acuerdo a nuestras estadísticas, "Este RFC de receptor no existe en la lista de RFC inscritos no cancelados en el SAT" es el segundo mensaje de rechazo de timbrado mas frecuente dentro de CFDI 3.3, el primero, por si no te lo imaginabas es: "Comprobante fuera de vigencia de versión CFDI3.2 " (nunca falta el distraído que no se acordó de actualizar su versión a CFDI 3.3).

Curiosamente los orígenes de este error se remontan al año 2017, y mas específicamente a la entrada en vigor del complemento de Nómina 1.2; verás, el complemento de nómina 1.2 fue el primer complemento "condicional" que se implementó en CFDI, por "condicional" entendemos que los valores de los atributos afectan la existencia o no existencia de otros valores o nodos dentro del XML del comprobante fiscal digital, pero también este fue el primer complemento que implementó validaciones adicionales como la de los RFCs de los empleados.

Si recuerdan, en los primeros meses del años 2017, cuando preparabamos la nueva versión de VirtualXML para la nómina 1.2, hicimos mucho incapié e insistimos en que por favor, verificaran que los RFCs de sus empleados fueran correctos en las listas del SAT, algunos usuarios hicieron caso, otros no, lo cierto es que en algunos casos y con algunos clientes nos topamos con cosas tan curiosas como que el RFC: FOLR670417AB3 que se supone que era de Raúl Fonseca Linares, resultó que no existia en el SAT, la razón: que la persona a la que todos conocían por "Raulito el de contabilidad" no se llamaba Raul, sino Cándido Maclovio Fonseca Linares, pero como los hijos no tienen la culpa de los pecados de los padres, a Cándido Maclovio se le hizo facil hacerse llamar Raul y todos los conocían por ese nombre.

Otro caso interesante es del "Gelipe", trabajador del campo de una agrícola, de quien por su puesto. todos en el departamento de nóminas pensaban que se llamaba "Felipe", le tramitaron el RFC con el nombre de Felipe, pero resulta que en su acta de nacimiento efectivamente, en el registro civil aparecia como "Gelipe de Jesus" (curiosidades de la hermosa provincia mexicana).

Bien regresando al caso que nos atañe, el tema es que el SAT mantiene una lista llamada "LCO", (Lista de Contribuyentes con Obligaciones) en la cual aparecen TODOS los RFCs actualizados y vigentes de acuerdo a la lista del SAT y dicha lista es actualizada diariamente y enviada a los PACs 3 veces al día para que se utilice en la verificación de los RFC emisores y receptores de facturación.

En el esquema CFDI 3.3 el PAC tiene la obligación de verificar que el RFC del RECEPTOR exista en la LCO, si el RFC no existe, no será posible emitir el CFDI y deberá informarlo con el mensaje de error: "Este RFC de receptor no existe en la lista de RFC inscritos no cancelados en el SAT"

Debemos de tomar en cuenta una cosa importante, el hecho de que el RFC sea "válido" no implica que el RFC esté "vigente".... ¡ ha que caray !, ¿ no es lo mismo válido que vigente ?, pues va a ser que no, "válido" significa que el RFC sigue correctamente los lineamientos del formato especificado incluyendo el cálculo de la homoclave, pero "vigente" significa que el RFC, además de ser válido, está activo en los controles del SAT y con un estatus que le permita ser utilizado (no cancelado). En el 90% de los casos, los RFC que devuelven este mensaje de error es porque su estatus en los controles del SAT no es "vigente".

La correcta actualización de la LCO no es responsabilidad de nosotros (VirtualPAC), ni del PAC; todos los PACs reciben la lista directamente desde el SAT y tienen la obligación de mantenerla actualizada, cabe señalar que cada PAC actualiza su lista en distintos horarios, por lo que puede suceder que un documento que no se timbra en un PAC, si se timbra en otro PAC que tiene actualizada mas recientemente su LCO o viceversa.

Si un RFC receptor se marca como inexistente en la lista de RFCs inscritos, nuestro receptor tiene 3 alternativas:
  1.  Esperar a la siguiente actualización de la LCO (de 4 a 8 horas).
  2. Verificar vía internet en la página del SAT además de la validez, la vigencia de su RFC
  3. Darse  una vuelta por la oficina del SAT para ver el estatus del RFC.

Tenemos muchos casos de usuarios de VirtualPAC que "toda la vida" le han facturado al mismo cliente con el mismo RFC, y después de averiguar un  poco en el SAT resulta que "toda la vida" le han estado facturando a un RFC que es incorrecto, y como la gente está tan poco acostumbrada a usar los documentos digitales para realizar sus declaraciones de impuestos, pues "toda la vida" ha estado presentado mal sus declaraciones.

Espero que esta información te haya sido de utilidad para poder informar a tus receptores de documentos CFDI 3.3 los procedimientos a seguir cuando tengan el error de RFC inexistente.

miércoles, 10 de enero de 2018

(VirtualXML) Como facturar productos con importe cero (0.00)

Hace unos dias me llamó un buen amigo y cliente y me planteó la siguiente pregunta:

Uno de mis clientes vende artículos para el hogar, si compras mas de $500.00 te regala una escoba, la escoba debe de salir de inventario, por lo mismo la tengo que incluir en la factura, sin embargo, no me permite incluir un producto con un precio unitario de $0.00 pesos.

Y tiene razón, revisando los schemas de los XMLs de CFDI 3.3 me dí cuenta que el unico tipo de CFDI 3.3 que permite la facturación con importes de $0.00 pesos es el tipo de CFDI "T" comprobante de Traslado o Carta Porte, no es posible incluir conceptos con un valor de $0.00 en los comprobantes de Ingreso, Egreso o Nomina.

Dada mi ignorancia en el tema, mi solución fue sugerir a mi cliente que facturara la escoba en 0.01, total un centavo mas, un centavo menos al final no hacen gran diferencia (sobre todo si ya leiste el articulo anterior, o posterior, depende del orden en que leas el blog).

Unos días después me llama otro cliente y me dice.... Yo le vendo a Pemex y tengo unas partidas que FROZOSAMENTE tienen que ir con importe 0.00, porque así me lo pide Pemex.... ¿ que hago ?.

Una cosa es una escoba, y otra cosa es cumplirle los caprichos a Pemex, así que después de googlear un poco por ahi y por aquí, me encontré con una solución elegante y válida:

Aplicar un descuento por el importe total del producto ..... CLARO !!!!, si mi producto cuesta $100.00 y le aplico un descuento de $ 100.00 el importe queda en cero, por lo tanto se reflejara perfectamente en el XML y si se desea, en el documento impreso también.

Hice un par de pruebas, funcionaron pefectamente  y santo remedio, mi cliente pudo facturar con importe $0.00 a Pemex.

Obviamente esto tiene repercusiones, en la llamada a la función: VirtualXML_SetComprobanteInfo_cfdi33() deberás incluir la suma de los descuentos aplicados (como en todas las facturas) y en la función VirtualXML_AddConcepto_cfdi33(), en el último parámetro que es el que corresponde al descuento, deberás indicar una cantidad similar al importe (Cantidad x Precio Unitario) del producto.

Espero que este consejo te sea útil para poder facturar conceptos con importe $0.00 en CFDI 3.3

Actualización..... y ¿ Que pasa con los impuestos ?

 Muchos de ustedes depues de leer el artículo lo pusieron en marcha y adivinen que ..... pues que les falló, por una pequeña omisión de mi parte, olvidé mencionar el tema de los impuestos.

Cuando producto tiene un descuento del 100%, NO SE DEBEN APLICAR IMPUESTOS, esto quiere decir que no debes utilizar la función VirtualXML_AddConceptoTraslado_cfdi33(), es decir que los nodos de impuestos para un concepto con importe 0.00 no deben existir, lo cual es lógico porque no puedes tener una base de 0.00; obviamente si dentro de la misma factura tienes otros productos que si causen impuesto deberás indicarlo.

jueves, 4 de enero de 2018

(VirtualXML) Como redondear importes en CFDI 3.3 y no morir en el intento.

Uno de los principales problemas por los cuales nuestros usuarios nos consultan, es el famoso error:

"La suma de XXXXX no coincide con XXXX" o bien:
"El campo XXXX correspondiente a XXX no es igual a la suma de XXX"

Y el problema recurrente es...... Los malditos decimales.

En este primer articulo de nuestro nuevo blog, trataré de explicar la manera correcta de realizar el redondeo en las facturas CFDI 3.3

Lo primero a tomar en cuenta, es que bajo el nuevo esquema CFDI 3.3, el PAC (Proveedor Autorizado de Certificación), está obligado a revisar que las sumas y cálculos de la factura en general "cuadren" es decir, que las sumas y las operaciones matemáticas sean correctas, cosa que en la versión 3.2 no ocurría.

Otro aspecto importante a tomar en cuenta, es que para expresar los IMPORTES (cantidades monetarias básicamente),  estos deben de utilizar el número de decimales de la moneda con la que se expida la factura, de acuerdo con el catálogo publicado por el SAT.

En las versiones anteriores de CFDI podías utilizar hasta 6 dígitos decimales para expresar los importes de la factura, pero en CFDI 3.3 estas "limitado" a usar el número de decimales para la moneda de acuerdo al catálogo del SAT.

Las monedas mas comúnmente usadas para emitir facturas, además de los Pesos Mexicanos (MXN),son : Dólares Norteamericanos (USD), Dólares Canadienses (CAN), Euros (EUR) y en algunos casos las Libras Esterlinas (GBP) y según el catálogo del SAT, todas estas monedas deben utilizar 2 dígitos decimales para expresar los importes en la factura.

El problema viene cuando hay que calcular y redondear los decimales en los importes de la factura.

Veamos el siguiente ejemplo, supongamos que tenemos una factura con 3 artículos:

Articulo 1: $500.00 IVA Incluido
Articulo 2: $125.75 IVA Incluido
Articulo 3: $534.25 IVA incluido.

En este ejemplo, el total de la factura, puede parecer lógico es de: $1,160.00 pesos, es decir, de $1,000.00 mas IVA, pero vamos a analizarla articulo por articulo y nos vamos a encontrar con alguna sorpresa:

En CFDI 3.3, se debe realizar el cálculo de los impuestos POR CONCEPTO y no por el importe total de la factura, como se hacía en las versiones anteriores, y es en este punto donde surgen la mayoría de los problemas con el redondeo de las cantidades.

Analicemos nuestro primer articulo de $500.00 con IVA incluído:

En el nodo concepto, debemos expresar el IMPORTE del producto SIN el IVA, así que la operación matemática que manda la lógica, es realizar lo siguiente:

$500.00 (precio con IVA)  dividido entre 1.16 (para obtener el precio sin IVA) =  431.034482


Nota por favor que el precio sin IVA, tiene por lo menos 6 dígitos decimales y el catálogo del SAT es claro al respecto: los importes se expresan con el número de decimales de la moneda con la que se expide el documento, en este caso Pesos Mexicano (MXN) y 2 decimales.

En los primeros días del modelo CFDI 3.3, el SAT propuso una manera "irreal" (por no llamarla estúpida) de calcular los decimales para el nuevo modelo de facturación, afortunadamente dicha idea no prosperó, y ahora podemos realizar el "redondeo" mediante las funciones que nuestros propios lenguajes de programación nos proporcionan para ello, y en su mayoría utilizan una función llamada ROUND( cantidad, decimales).

En todos los lenguajes de programación existe una función similar a esta que recibe 2 parámetros, el primero es la cantidad a redondear y el segundo es el número de decimales que queremos para el redondeo, te tal manera que si yo hago algo como esto:

ROUND ( 431.034482, 2)

Obtendré:431.03

Y este es nuestro valor SIN IVA.

Es hora de calcular el IVA:

431.03 * 0.160000 = 68.9648

Que redondeado queda como: 68.97 ( el cuarto digito decimal, 8, sube a 5 el tercer digito decimal (4) y este 5 sube a 7 el segundo digito decimal) y que si sumamos a los 431.03 nos dará el importe correcto de $500.00:

431.03 + 68.97 = 500.00

En este caso la operación matemática fue correcta, porque 500.00 es una cantidad sin mucha complicación, veamos el segundo artículo:

Obtenemos el importe sin IVA

125.75 / 1.16 = 108.405172

Redondeamos:

ROUND( 108.405175, 2) = 108.41

Y ahora calculamos el IVA correspondiente:

108.41 * 0.16 = 17.3456

Redondeado:

ROUND( 17.3456, 2) = 17.35

Y si sumamos los 2 importes tenemos:

108.41 + 17.35 = 125.76

Houston.... tenemos un problema.... 1 centavo de diferencia para ser exactos.

Hasta aquí todo parecía perfecto, la mecánica de cálculo parecía estar clara, dividir, redondear, multiplicar, redondear y sumar ..... y obtener una diferencia de 1 centavo ......

¿ Que pasa con cualquier otra cantidad que tenga decimales ?:

Hagamos las mismas operaciones para el tercer artículo:

534.25 / 1.16 = 460.560344
ROUND(460.560344, 2) = 460.56 importe sin IVA

Calculo del IVA:

460.56 * 0.16 = 73.6896
ROUND(73.6896 ,2) = 73.69

Y ahora podemos observar que la suma del importe sin IVA mas el IVA calculado da:

460.56 + 73.69 =   534.25

Observamos que aqui no tenemos diferencia, luego entonces podemos concluir que no importa si el importe tiene centavos o no, puede que tengas o no diferencias.

Tenemos que tomar en cuenta una cosa importante: entre mas multiplicaciones y mas divisiones hagas, obtendrás muchas mas fracciones decimales contra las cuales luchar, así que para solucionar este problema, en vez de multiplicar y dividir, hagamos las cosas simples: sumas y restas:

Retomemos el segundo articulo de 125.75:

125.75 / 1.16 = 108.405172
ROUND(108.405172, 2) = 108.41 importe sin IVA

y ahora el IVA no provendrá de una multiplicación, sino de una resta:

125.75 - 108.41  =  17.34

Con lo cual, tendremos una suma perfecta en el calculo de los decimales:

108.41 + 17.34 = 125.75

Y la misma regla de la resta la podemos aplicar a los 2 casos anteriores:

500.00 - 431.03 = 68.97
125.75 - 108.41 = 17.34

Con los mismos resultados de la multiplicación y el redondeo a 2 decimales, y con esto garantizamos cálculos exactos a 2 decimales.

Compliquemos mas este ejemplo y digamos ahora que vamos a hacer un descuento del 5% sobre el total de la factura:

Calculemos el precio del producto sin IVA:

Articulo 1: 500.00 / 1.16 = 431.034482, Round(431.034482, 2) = 431.03
Articulo 2: 534.25 / 1.16 = 460.560344, Round(460.560344, 2) = 460.56
Articulo 3: 125.75 / 1.16 = 108.405172, Round(108.405172, 2) = 108.41

En CFDI 3.3 no puedes aplicar un descuento global sobre el total de la factura, si vamos a aplicar un descuento global, es necesario calcular el descuento individual por cada producto. Calculemos el 5% de descuento sobre el precio sin IVA de cada producto:

Articulo 1: 431.03 * 0.05 = 21.5515, Round(21.5515, 2) = 21.55
Articulo 2: 460.56 * 0.05 = 23.028, Round(23.028, 2) = 23.03
Articulo 3: 108.41 * 0.05 = 5.4205, Round(5.4205, 2) = 5.42

Nota que estoy dejando los descuentos a 2 decimales.

Calculemos ahora la "base" sobre la cual vamos determinar el impuesto, y esto lo haremos con una simple resta CON DOS DECIMALES:

Articulo 1: 431.03 - 21.55 = 409.48
Articulo 2: 460.56 - 23.03 = 437.53
Articulo 3: 108.41 - 5.42 = 102.99

Calculemos ahora el impuesto de 16% de IVA:

Articulo 1: 409.48 * 0.16 = 65.5168, Round(65.5168, 2) = 65.52
Articulo 2: 437.53 * 0.16 = 70.0048, Round(70.0048, 2) = 70.01
Articulo 3: 102.99 * 0.16 = 16.4784, Round(16.4784, 2) = 16.48

Y entonces tenemos como resultado para nuestro XML lo siguiente:

Subtotal = 431.03 + 460.56 + 108.41 = 1000.00
Descuento =21.55 + 23.03 + 5.42 = 50.00
Total Impuestos Trasladados = 65.52 + 70.01 + 16.48 =152.01 
Total = (1000.00 - 50) + 152.01 = 1,102.01

El Detalle manda, no el total:

Siguiendo esta sabia frase de mi amigo Mauricio Fragoso, como te habrás podido dar cuenta en los ejemplos anteriores, los importes totales de la factura los he calculado a partir de los detalles (conceptos) de la factura.

¿ Que hubiera pasado si los hubiera calculado sobre los totales ?

Veamos:

Articulo 1: $500.00 IVA Incluido
Articulo 2: $125.75 IVA Incluido
Articulo 3: $534.25 IVA incluido.

Total de la factura con IVA incuido: $1,160.00

Calculemos el importe sin IVA:

1,160 / 1.16 = 1000.00

Hasta aqui vamos biene.

Calculemos el descuento:

1,000.00 * 0.05 = 50.00

En este caso el importe del descuento es correcto.

Calculemos la base imponible:

1,000.00 - 50.00 =  950.00

Y calculando el impuesto:

950 * 0.16 = 152.00

Y nota como en este punto, tenemos 0.01 de diferencia contra el calculo hecho por concepto individual.

(1,000.00 - 50.00) + 152.00 = 1,102.00

Contra 1.102.01 calculados individualmente. Como verás existe una diferencia de 0.01 y este centavo de diferencia es lo que te va a causar los errores de cálculo mencionados al principio de este artículo.

¿ Cual es el calculo correcto ?

El realizado invididualmente.

¿ Cual es la formula mágica para un calculo correcto ?

La podemos resumir en lo siguiente:

Realiza los cálculos individuales por cada partida para los importes y para los impuestos (IVA y IEPS para traslados e ISR e ]IVA para retenciones) súmalos y utiliza estos importes para el Subtotal y el Total de Impuestos Retenidos y trasladados.

Si almacenas los datos de los conceptos en una tabla temporal o en un array en memoria, guárdalos con el número de decimales correcto ( 2 para nuestros ejemplos) y utiliza un campo o elemento individual del array para cada atributo, incluyendo, precio unitario, importe, impuestos trasladados y retenidos.

Reduce tanto como puedas el uso de multiplicaciones y divisiones, recuerda que entre mas multipliques y dividas, tendrás mas decimales para redondear, aunque obviamente hay situaciones en las que forzosamente tienes que multiplicar, como en el caso de la Cantidad X Precio Unitario, solo asegúrate de redondear después de realizar dicha multiplicación.

Mi padre es contador y cuando le estaba planteando este tema de los redondeos  en el CFDI 3.3, me dijo.... "suena lógico, a final de cuentas la contabilidad, toda ella, se expresa con 2 decimales, y en todas las operaciones monetarias que realizas todos los días únicamente manejas 2 dígitos decimales, si te compras un Gansito, cuesta 13.50, no 13.48564, no hay monedas fraccionarias de mas 2 digitos decimales" y creo que por ese lado tiene razón.

Espero que estos consejos te sirvan para reducir los errores de cállculo que puedas tener en tu implementación de CFDI 3.3 y te invito a seguir visitando este blog, donde semanalmente publicaré articulos interesantes sobre VirtualPAC, VirtualXML y facturación electroncia CFDI 3.3.