Skip to content

Implementar una nueva versión de CFDI

Enrique Díaz Alvarez edited this page Aug 8, 2017 · 19 revisions

Una vez que el SAT publica una nueva versión de CFDI publica una serie de documentos útiles a nivel programación (Anexo 20), principalmente:

  • Estructura del CFDI a través de un archivo XML Schema Definition (archivo XSD)
  • Archivos de transformación XSLT

Con estos archivos podremos implementar una nueva versión de CFDI en la librería. Los pasos son los siguientes:

1. Generar las clases que hagan referencia a la estructura del nuevo XML

Haciendo uso de la herramienta XML Data Binding de Delphi, creamos las clases necesarias para poder llenar el XML directamente desde una instancia de Delphi, para ello creamos la clase de la siguiente manera:

  1. Ingresamos a File..., New..., XML Data Binding
  2. Ingresamos como parámetro la definición del XSD (Ejemplo: cfdv33.xsd)
  3. Guardamos el archivo recién generado en el subdirectorio Versiones\ del proyecto con su respectivo nombre y convención: Facturacion.Comprobante%Version%.pas, por ejemplo: Facturacion.ComprobanteV33.pas. (Ejemplo)

Implementar convenciones esperadas por la librería

Para facilitar el uso de diferentes versiones de CFD/I en la librería deberás corroborar que la nueva clase que acabes de generar siga las siguientes convenciones:

  1. La interfase del comprobante debe llamarse IComprobanteFiscal%Version%, por ejemplo IComprobanteFiscalV33
  2. Toda referencia auto-generada por Delphi que sea IXMLComprobante deberá cambiarse por IComprobanteFiscal%Version% por ejemplo, en lugar de llamarse IXMLComprobante_Emisor, deberá llamarse IComprobanteFiscalV33_Emisor (Ejemplo).
  3. Cambiar los nombres de las clases que implementan las interfaces por los nombres de la convención, por ejemplo, cambiar TXMLComprobante por TComprobanteFiscalV33. (Nótese la T del principio) (Ejemplo).
  4. Cambiar los nombres de los métodos auto generados de creación y lectura de comprobantes, por ejemplo GetComprobante por GetComprobanteFiscal%Version%., NewComprobante por NewComprobanteFiscalV33 y LoadComprobante por LoadComprobanteFiscalV33 (Ejemplo)
  5. Implementar método establecerAtributosDeCFDI con la siguiente implementación (Ejemplo):
procedure establecerAtributosDeCFDI(comprobante: IComprobanteFiscalV33);
var
  documentoBase: IXMLDocument;
const
  _NODO_XSI     = 'xmlns:xsi';
  _NODO_SL      = 'xsi:schemaLocation';
  _NODO_VERSION = 'Version';
begin
  // Agregamos la auto identacion
  comprobante.OwnerDocument.Options := [doNodeAutoCreate, doAttrNull, doAutoPrefix, doNamespaceDecl, doNodeAutoIndent];

  if (comprobante.AttributeNodes.FindNode(_NODO_XSI) = nil) then
      comprobante.SetAttribute(_NODO_XSI,
                               'http://www.w3.org/2001/XMLSchema-instance');

  if (comprobante.AttributeNodes.FindNode(_NODO_SL) = nil) then
    comprobante.SetAttribute(_NODO_SL,
                            'http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd');

  if (comprobante.AttributeNodes.FindNode(_NODO_VERSION) = nil) then
    comprobante.Version := '3.3';
end;

NOTA: Verificar llenar los valores correctos de schemaLocation, Version, etc. según la version del CFDI que se esté implementado.

  1. Mandar llamar metodo establecerAtributosDeCFDI en el método AfterConstruction para que se llenen las propiedades de forma correspondiente (Ejemplo).
  2. Cambiar interface "padre" del comprobante por IComprobanteFiscal (Ejemplo).
  3. Incluir el Namespace de cfdi: en las rutinas de lectura/creación del CFDI (Ejemplo)
  4. Incluir el Namespace de cfdi: en las rutinas de creaciones de nodos hijo (ItemTags) (Ejemplo)

2. Generar clase para manejo del Timbre Fiscal Digital

Al igual que se hizo para el XML del Comprobante, haremos una clase usando el XML Data Binding Wizard de Delphi leyendo el archivo XSD que corresponda al Timbre Fiscal Digital, por ejemplo TimbreFiscalDigitalv11.xsd para la versión 3.3. Los pasos son los siguientes:

  1. Crear la clase usando el XML Data Binding Wizard con el XSD correspondiente del Timbre Fiscal Digital. (Ejemplo)
  2. Cambiar los nombres auto-generados para seguir la convención, por ejemplo IXMLTimbreFiscalDigital por ITimbreFiscalDigitalV32 (Ejemplo)
  3. Cambiar los nombres de los métodos de creación y lectura del timbre para incluir la versión, por ejemplo GetTimbreFiscalDigital por GetTimbreFiscalDigitalV33 (Ejemplo)
  4. Incluir el Namespace de tfd en los métodos de creación y lectura del XML del timbre (Ejemplo)
  5. Editar la interfase y clase correspondiente al nodo Complemento y agregar los métodos para la lectura del TimbreFiscal. (Ejemplo):
function GetTimbreFiscalDigital: ITimbreFiscalDigitalV33;
procedure SetTimbreFiscalDigital(const Value: ITimbreFiscalDigitalV33);
property TimbreFiscalDigital: ITimbreFiscalDigitalV33 read GetTimbreFiscalDigital write SetTimbreFiscalDigital;
  1. Agregar el registro del TimbreFiscalDigital como "hijo" del nodo complemento (Ejemplo)
  2. Agregar la funcionalidad para los métodos Set y Get del TimbreFiscalDigital (Ejemplo)
  3. Implementar el método AsignarTimbre el cual deberá anexar el nodo XML del TimbreFiscalDigital al comprobante (Ejemplo, Ejemplo 2).

3. Generar las clases auxiliares

El paso final consiste en crear las instancias correspondientes para generar la Cadena Original, el Sello y el Código de Barras Bi dimensional de acuerdo a la versión. El proceso de generación es muy sencillo, puedes ver cómo se generaron las diferentes clases para la versión 3.2: