GRUPO EXECOM DE CHIAPAS SA DE CV Complementos y Addendas Definición y uso en MaxiComercio Última actualización 23/05/2011 En este documento se describen los elementos adicionales que se pueden incluir en la estructura XML del comprobante fiscal digital.
Contenido Objetivo... 3 Complemento... 3 Integración del Complemento en MaxiComercio... 3 Nombre y ubicación del archivo... 3 Código de ejemplo para integrar el Complemento para CFD... 4 Código de ejemplo para integrar el Complemento para CFDI... 5 Activar integración del complemento... 7 Complemento concepto... 9 Integración del Complemento concepto en MaxiComercio... 9 Nombre y ubicación del archivo... 9 Código de ejemplo para integrar el Complemento concepto para CFD... 10 Código de ejemplo para integrar el Complemento concepto para CFDI... 11 Activar integración del complemento concepto... 13 Addenda... 14 Qué es?... 14 Para qué sirve?... 14 Qué información contiene?... 14 Ejemplo en MaxiComercio... 15 Script para integración de la Addenda... 15 Activar Addenda... 23 Generar CFD/CFDI... 23 Addenda MaxiComercio... 25 Elementos que conforman la Addenda de MaxiComercio... 25 Activar Addenda de MaxiComercio... 32 Especificaciones descritas en el anexo 20 de la Resolución Miscelánea Fiscal publicado el 23 de septiembre de 2010... 34 2
Objetivo Describir las características de los elementos adicionales que se pueden integrar en el comprobante fiscal digital y ejemplificar su uso con MaxiComercio, mostrando la configuración y la creación de scripts que permiten manipular los nuevos nodos. El código fuente en este documento es únicamente un ejemplo de uso, el contenido depende de cada usuario respetando las reglas establecidas por el SAT. Complemento El complemento es un nodo adicional dentro de la estructura principal del comprobante, el cual deberá incluir elementos que estan reglamentados por el SAT solo para aquellos contribuyentes que tengan la obligación de acuerdo a la Resolución Miscelánea Fiscal vigente. Este nodo se integrará de la siguiente manera: Para CFD: <Comprobante> <Complemento> </ Complemento> </Comprobante> Para CFDI: <cfdi:comprobante> <cfdi:complemento> </cfdi:complemento> </cfdi:comprobante> Las reglas de uso de los complementos se deben consultar en el portal del SAT http://www.sat.gob.mx. Integración del Complemento en MaxiComercio Nombre y ubicación del archivo Para crear el contenido del Complemento deberá programar sus características a través de un script de la siguiente manera: Cree un nuevo archivo JavaScript con el siguiente nombre: complemento.js. Coloque el archivo en la carpeta del repositorio: MaxiComercio\CFD\Complemento para CFD o MaxiComercio\CFDI\Complemento para CFDI. Escriba el código necesario para crear el Complemento. Podrá usar todos los objetos del script cfd.js para CFD y cfdi.js para CFDI. 3
Código de ejemplo para integrar el Complemento para CFD //estan disponibles todos los objetos de cfd.js //más las siguientes variables globales /* venta; //objeto EDOFX.Venta //Si el cfd es de una CxC entonces el objeto sera nulo pkventa;//clave primaria de la tabla venta //Si el cfd es de una CxC entonces el objeto sera nulo cxc; //objeto EDOFX.DCXC //Si el cfd es de una Venta entonces el objeto sera nulo pkcxc; //clave primaria de la tabla DCXC //Si el cfd es de una Venta entonces el objeto sera nulo cfd; */ //objeto gecfd.ccfd actual //llamada para la ejecución de la función integrarcomplemento(); //Contenido de la función principal function integrarcomplemento(){ //retornar verdadero para continuar var complemento,element,e2; //Nodo Complemento complemento=nuevoelemento("complemento"); if(complemento==null) return 0; //Nodo Adicional element=nuevoelemento("nodoejemplo") if(element==null) return 0; element.prefix="ecc"; //prefijo element.uri="http://www.sat.gob.mx/ecc"; //namespace //Agregar atributos element.setmyattribute("atributo1","valor del atributo"); complemento.elements.add(element); element=nuevoelemento("nododos") if(element==null) return 0; element.prefix="ecc"; //prefijo element.uri="http://www.sat.gob.mx/ecc"; //namespace //Agregar atributos element.setmyattribute("atributoej2","valor del atributo"); complemento.elements.add(element); //Definir los NamceSpaces necesarios: // cfd.new_xmlns(name,value); // cfd.new_schemalocation(location); cfd.new_xmlns("xmlns:ecc","http://www.sat.gob.mx/ecc"); cfd.new_schemalocation("http://www.sat.gob.mx/ecc"); cfd.new_schemalocation("http://www.sat.gob.mx/sitio_internet/cfd/ecc/ecc.xsd"); //Agregar complemento al comprobante cfd.complemento=complemento.getelement(cfd.cfdxmldocument); return -1; 4
//función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; Código de ejemplo para integrar el Complemento para CFDI //estan disponibles todos los objetos de cfdi.js //más las siguientes variables globales /* venta; //objeto EDOFX.Venta //Si el cfdi es de una CxC entonces el objeto sera nulo pkventa;//clave primaria de la tabla venta //Si el cfd es de una CxC entonces el objeto sera nulo cxc; //objeto EDOFX.DCXC //Si el cfdi es de una Venta entonces el objeto sera nulo pkcxc; //clave primaria de la tabla DCXC //Si el cfd es de una Venta entonces el objeto sera nulo ocfd; */ //objeto gecfd.ccfd actual //llamada para la ejecución de la función integrarcomplemento(); //Contenido de la función principal function integrarcomplemento(){ //retornar verdadero para continuar var complemento,element,e2; //Nodo Complemento complemento=nuevoelemento("complemento"); if(complemento==null) return 0; complemento.prefix=proccess.getdefault_cfdi_prefix(); //prefijo para cfdi complemento.uri=proccess.getdefault_cfdi_uri(); //namespace asociado al prefijo //Nodo Adicional element=nuevoelemento("nodoejemplo") if(element==null) return 0; element.prefix="ecc"; //prefijo element.uri="http://www.sat.gob.mx/ecc"; //namespace //Agregar atributos element.setmyattribute("atributo1","valor del atributo"); complemento.elements.add(element); element=nuevoelemento("nododos") if(element==null) return 0; element.prefix="ecc"; //prefijo element.uri="http://www.sat.gob.mx/ecc"; //namespace //Agregar atributos element.setmyattribute("atributoej2","valor del atributo"); complemento.elements.add(element); 5
//Definir los NamceSpaces necesarios: // ocfd.new_xmlns(name,value); // ocfd.new_schemalocation(location); ocfd.new_xmlns("xmlns:ecc","http://www.sat.gob.mx/ecc"); ocfd.new_schemalocation("http://www.sat.gob.mx/ecc"); ocfd.new_schemalocation("http://www.sat.gob.mx/sitio_internet/cfd/ecc/ecc.xsd"); //Agregar complemento al comprobante ocfd.complemento=complemento.getelement(ocfd.cfdxmldocument); return -1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; 6
Activar integración del complemento Para activar la integración del Complemento ingrese al panel de control/facturación electrónica. En la siguiente ventana haga clic en el botón General. En la siguiente ventana seleccione la pestaña Adicionales y marque la casilla Incluir elemento <Complemento>. Haga clic en el botón Aceptar y reinicie la conexión del sistema, con esta configuración el complemento se incluira para cada comprobante generado de tipo CFD o CFDI. 7
8
Complemento concepto El complemento concepto es un nodo adicional dentro de la estructura del comprobante que se incluye en el nodo Concepto, el cual deberá incluir elementos que estan reglamentados por el SAT solo para aquellos contribuyentes que tengan la obligación de acuerdo a la Resolución Miscelánea Fiscal vigente. Este nodo se integrará de la siguiente manera: Para CFD: <Comprobante> <Conceptos> <Concepto> < ComplementoConcepto > </ComplementoConcepto > </Concepto > </Conceptos > </Comprobante> Para CFDI: <cfdi:comprobante> <cfdi:conceptos> <cfdi:concepto> <cfdi:complementoconcepto > </cfdi:complementoconcepto > </cfdi:concepto > </cfdi:conceptos > </cfdi:comprobante> Las reglas de uso de los complementos para conceptos se deben consultar en el portal del SAT http://www.sat.gob.mx. Integración del Complemento concepto en MaxiComercio Nombre y ubicación del archivo Para crear el contenido del Complemento concepto deberá programar sus características a través de un script de la siguiente manera: Cree un nuevo archivo JavaScript y asigne el nombre con el siguiente formato: cconcepto_codigoproducto. El código del producto deberá ser el que está registrado en el sistema. Por ejemplo si el producto al que se requiere agregar el complemento tiene el código 1000800, entonces el nombre del archivo deberá ser cconcepto_1000800.js. Coloque el archivo en la carpeta del repositorio: MaxiComercio\CFD\Producto para CFD o MaxiComercio\CFDI\Producto para CFDI. Escriba el código necesario para crear el Complemento del concepto. Podrá usar todos los objetos del script cfd.js para CFD y cfdi.js para CFDI. 9
Código de ejemplo para integrar el Complemento concepto para CFD //estan disponibles todos los objetos de cfd.js //más las siguientes variables globales /* venta; //objeto EDOFX.Venta //Si el cfd es de una CxC entonces el objeto sera nulo pkventa;//clave primaria de la tabla venta //Si el cfd es de una CxC entonces el objeto sera nulo cxc; //objeto EDOFX.DCXC //Si el cfd es de una Venta entonces el objeto sera nulo pkcxc; //clave primaria de la tabla DCXC //Si el cfd es de una Venta entonces el objeto sera nulo cfd; concepto; */ //objeto gecfd.ccfd actual //objeto gecfd.cconceoto actual // OPCIONAL: concepto.complementoconcepto //O MIN 0 MAX 1 //concepto.complementoconcepto.complemento=null; //llamada para la ejecución de la función integrarcomplementoconcepto(); //Contenido de la función principal function integrarcomplementoconcepto(){ //retornar verdadero para continuar var ComplementoConcepto,element,e2; //Nodo ComplementoConcepto ComplementoConcepto=nuevoElemento("ComplementoConcepto"); if(complementoconcepto==null) return 0; //Nodo Adicional element=nuevoelemento("nodoejemplo") if(element==null) return 0; element.prefix="ecc"; //prefijo element.uri="http://www.sat.gob.mx/ecc"; //namespace //Agregar atributos element.setmyattribute("atributo1","valor del atributo"); ComplementoConcepto.Elements.Add(element); element=nuevoelemento("nododos") if(element==null) return 0; element.prefix="ecc"; //prefijo element.uri="http://www.sat.gob.mx/ecc"; //namespace //Agregar atributos element.setmyattribute("atributoej2","valor del atributo"); ComplementoConcepto.Elements.Add(element); //Definir los NamceSpaces necesarios: // cfd.new_xmlns(name,value); // cfd.new_schemalocation(location); cfd.new_xmlns("xmlns:ecc","http://www.sat.gob.mx/ecc"); cfd.new_schemalocation("http://www.sat.gob.mx/ecc"); cfd.new_schemalocation("http://www.sat.gob.mx/sitio_internet/cfd/ecc/ecc.xsd"); 10
//Agregar complementoconcepto al concepto actual concepto.complementoconcepto.complemento=complementoconcepto.getelement(cfd.cfdxmldo cument); return -1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; Código de ejemplo para integrar el Complemento concepto para CFDI //estan disponibles todos los objetos de cfdi.js //más las siguientes variables globales /* venta; //objeto EDOFX.Venta //Si el cfdi es de una CxC entonces el objeto sera nulo pkventa;//clave primaria de la tabla venta //Si el cfd es de una CxC entonces el objeto sera nulo cxc; //objeto EDOFX.DCXC //Si el cfdi es de una Venta entonces el objeto sera nulo pkcxc; //clave primaria de la tabla DCXC //Si el cfd es de una Venta entonces el objeto sera nulo ocfd; concepto; */ //objeto gecfd.ccfd actual //objeto gecfd.cconceoto actual // OPCIONAL: concepto.complementoconcepto //O MIN 0 MAX 1 //concepto.complementoconcepto.complemento=null; //llamada para la ejecución de la función integrarcomplementoconcepto(); //Contenido de la función principal function integrarcomplementoconcepto(){ //retornar verdadero para continuar var ComplementoConcepto,element,e2; //Nodo ComplementoConcepto ComplementoConcepto=nuevoElemento("ComplementoConcepto"); if(complementoconcepto==null) return 0; ComplementoConcepto.Prefix=proccess.getDefault_cfdi_Prefix(); //prefijo para cfdi ComplementoConcepto.URI=proccess.getDefault_cfdi_URI(); //namespace asociado al prefijo 11
//Nodo Adicional element=nuevoelemento("nodoejemplo") if(element==null) return 0; element.prefix="ecc"; //prefijo element.uri="http://www.sat.gob.mx/ecc"; //namespace //Agregar atributos element.setmyattribute("atributo1","valor del atributo"); ComplementoConcepto.Elements.Add(element); element=nuevoelemento("nododos") if(element==null) return 0; element.prefix="ecc"; //prefijo element.uri="http://www.sat.gob.mx/ecc"; //namespace //Agregar atributos element.setmyattribute("atributoej2","valor del atributo"); ComplementoConcepto.Elements.Add(element); //Definir los NamceSpaces necesarios: // cfd.new_xmlns(name,value); // cfd.new_schemalocation(location); ocfd.new_xmlns("xmlns:ecc","http://www.sat.gob.mx/ecc"); ocfd.new_schemalocation("http://www.sat.gob.mx/ecc"); ocfd.new_schemalocation("http://www.sat.gob.mx/sitio_internet/cfd/ecc/ecc.xsd"); //Agregar complementoconcepto al concepto actual concepto.complementoconcepto.complemento=complementoconcepto.getelement(ocfd.cfdxmld ocument); return -1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; 12
Activar integración del complemento concepto Seleccione el producto en el módulo de inventarios dentro del BackOffice del sistema. Haga clic en editar y seleccione la pestaña Inventario y suministro. Maque la casilla Incluir complemento concepto en Comprobante Fiscal Digital y guarde los cambios. Esto activará la generación del complemento del concepto actual. 13
Addenda Qué es? La Addenda es un elemento adicional que se puede agregar a la estructura principal del XML de un CFD o CFDI. Este elemento se crea como <Addenda></Addenda> para el caso de CFD y <cfdi:addenda></cfdi:addenda> para un comprobante de tipo CFDI. El contenido dentro del elemento Addenda puede ser XML, texto plano o formato binario. Para el caso de XML en el contenido de la Addenda se deberá tomar en cuenta las especificaciones para la generación de contenido XML. La especificación de namespaces es opcional. Si el contenido es texto plano se ingresará dentro del nodo Addenda sin usar caracteres reservados en las especificaciones para XML. Para evitar posibles conflictos el contenido deberá estar en formato UTF8. Si se desea agregar datos en formato binario, este puede ser un archivo por ejemplo, se deberá convertir en formato Base64 para poder ingresarlo como una cadena imprimible de caracteres. Para qué sirve? El nodo opcional Addenda se puede usar para agregar cualquier tipo de información adicional que se quiera compartir en el comprobante. El principal propósito es controlar mejor la información a través de medios digitales y facilitar la carga de información a los sistemas a través del XML del comprobante. La Addenda es útil para enviar información usando el mismo comprobante XML sin necesidad de enviar archivos digitales por separado cuando necesitamos compartir mas información. Qué información contiene? El contenido de la Addenda puede ser el que se desee sin restricciones ya que no tiene validez fiscal. La información puede ser del Proveedor (Emisor) o del Cliente (Receptor), como por ejemplo: información de la dirección de envío de la mercancía, datos adicionales del producto como números de series y lotes, datos del vendedor, número de orden de compra del cliente, fechas de vencimiento del documento, etc. 14
Ejemplo en MaxiComercio Script para integración de la Addenda Nombre y ubicación del archivo Para crear una Addenda deberá programar sus características a través de un script de la siguiente manera: Cree un nuevo archivo JavaScript y asigne el nombre con el siguiente formato: addenda_codigocliente. El código del cliente deberá ser el que está registrado en el sistema. Por ejemplo si el cliente al que se requiere agregar una Addenda tiene el código 1000500, entonces el nombre del archivo deberá ser addenda_1000500.js. Coloque el archivo en la carpeta del repositorio: MaxiComercio\CFD\Cliente para CFD o MaxiComercio\CFDI\Cliente para CFDI. Escriba el código necesario para crear la Addenda. Podrá usar todos los objetos del script cfd.js para CFD y cfdi.js para CFDI. Código de ejemplo para agregar addenda en formato XML para CFD: 1. Addenda XML sin definición de namespace //están disponibles todos los objetos de cfd.js //más las siguientes variables globales /* venta; //objeto EDOFX.Venta //Si el cfd es de una CxC entonces el objeto sera nulo pkventa;//clave primaria de la tabla venta //Si el cfd es de una CxC entonces el objeto sera nulo cxc; //objeto EDOFX.DCXC //Si el cfd es de una Venta entonces el objeto sera nulo pkcxc; //clave primaria de la tabla DCXC //Si el cfd es de una Venta entonces el objeto sera nulo cfd; */ //objeto gecfd.ccfd actual //llamada par la ejecución de la función integraraddenda(); //Contenido de la función principal function integraraddenda(){ //retornar verdadero para continuar var addenda,element,e2; //Nodo <Addenda> //Nodo principal necesario addenda=nuevoelemento("addenda"); if(addenda==null) return 0; //Nodo <MiCliente> //Nuevo nodo element=nuevoelemento("micliente"); if(element==null) return 0; addenda.elements.add(element); //Nodo <InfomacionAdicional> //Nodo dentro de <MiCliente> 15
e2=nuevoelemento("infomacionadicional"); if(e2==null) return 0; //Agregar atributos e2.setmyattribute("numproveedor","850001254"); e2.setmyattribute("notas","ejemplo de addenda"); element.elements.add(e2); //agregar la addenda al comprobante cfd.addenda=addenda.getelement(cfd.cfdxmldocument); return 1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; 2. Addenda XML con definición de namespace //llamada par la ejecución de la función integraraddenda(); //Contenido de la función principal function integraraddenda(){ //retornar verdadero para continuar var addenda,element,e2; //Nodo <Addenda> //Nodo principal necesario addenda=nuevoelemento("addenda"); if(addenda==null) return 0; //Nodo <MiCliente> //Nuevo nodo element=nuevoelemento("micliente"); if(element==null) return 0; element.prefix="otro"; //todos los nodos internos del elemento Addenda deben tener el prefijo element.uri="http://www.misitio.mx/minamespace"; //todos los nodos internos del elemento Addenda deben el valor URI //agrear NameSpaces element.setmyattribute("xmlns:otro","http://www.misitio.mx/minamespace"); element.setmyattribute("schemalocation","http://www.misitio.mx/minamespace http://www.misitio.mx/minamespace/minamespace.xsd"); element.getattribute("schemalocation").schemalocation=true; addenda.elements.add(element); //Nodo <InfomacionAdicional> //Nodo dentro de <MiCliente> 16
e2=nuevoelemento("infomacionadicional"); if(e2==null) return 0; e2.prefix="otro"; e2.uri="http://www.misitio.mx/minamespace"; //Agregar atributos e2.setmyattribute("numproveedor","850001254"); e2.setmyattribute("notas","ejemplo de addenda"); element.elements.add(e2); //agregar la addenda al comprobante cfd.addenda=addenda.getelement(cfd.cfdxmldocument); return 1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; Código de ejemplo para agregar addenda en Texto plano para CFD //llamada par la ejecución de la función integraraddenda(); //Contenido de la función principal function integraraddenda(){ //retornar verdadero para continuar var addenda,element,e2; //Nodo <Addenda> //Nodo principal necesario addenda=nuevoelemento("addenda"); if(addenda==null) return 0; //Nuevo nodo de texto element=nuevoelemento(""); if(element==null) return 0; element.textnode=true; element.value="texto de ejemplo en addenda. & <El contenido> puede tener caracteres especiales ya que se transformará a UTF-8"; addenda.elements.add(element); //agregar la addenda al comprobante cfd.addenda=addenda.getelement(cfd.cfdxmldocument); return 1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; 17
Código de ejemplo para agregar Addenda en Base64 para formato binario en CFD //llamada par la ejecución de la función integraraddenda(); //Contenido de la función principal function integraraddenda(){ //retornar verdadero para continuar var addenda,element,e2; var archivo; //Nodo <Addenda> //Nodo principal necesario addenda=nuevoelemento("addenda"); if(addenda==null) return 0; //Nuevo nodo de texto element=nuevoelemento(""); if(element==null) return 0; element.textnode=true; //Cargar el contenido binario desde un archivo archivo="c:\\miarchivo.pdf"; element.value=proccess.dobase64fromfile(archivo); if(element.value=="") { ebasic.emsgbox("el contenido del archivo para incluir en addenda esta vacío",6); return 0; //Cargar el contenido binario desde una cadena //element.value=proccess.dobase64fromstring("contenido de la addenda"); addenda.elements.add(element); //agregar la addenda al comprobante cfd.addenda=addenda.getelement(cfd.cfdxmldocument); return 1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; 18
Código de ejemplo para agregar addenda en formato XML para CFDI 1. Addenda XML sin definición de namespace //estan disponibles todos los objetos de cfdi.js //mas las siguientes variables globales /* TIPO; //1=venta 2=cxc archivoxml_timbrado; //ubicacion del archivo xml del cfdi timbrado pkcfd; pkventa; pkcxc; pkcliente; codigocliente; nombrecliente; */ //llamada par la ejecución de la función integraraddenda(); //Contenido de la función principal function integraraddenda(){ //retornar verdadero para continuar var addenda,element,e2; //Nodo <Addenda> //Nodo principal necesario addenda=nuevoelemento("addenda"); if(addenda==null) return 0; addenda.prefix=proccess.getdefault_cfdi_prefix(); //prefijo para cfdi addenda.uri=proccess.getdefault_cfdi_uri(); //namespace asociado al prefijo //Nodo <MiCliente> //Nuevo nodo element=nuevoelemento("micliente"); if(element==null) return 0; addenda.elements.add(element); //Nodo <InfomacionAdicional> //Nodo dentro de <MiCliente> e2=nuevoelemento("infomacionadicional"); if(e2==null) return 0; //Agregar atributos e2.setmyattribute("numproveedor","850001254"); e2.setmyattribute("notas","ejemplo de addenda"); element.elements.add(e2); //agregar la addenda al comprobante if(proccess.setaddendainxmlcfdi(archivoxml_timbrado,addenda)){ return -1; else{ return 0; return 1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); 19
if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; 1. Addenda XML con definición de namespace //llamada par la ejecución de la función integraraddenda(); //Contenido de la función principal function integraraddenda(){ //retornar verdadero para continuar var addenda,element,e2; //Nodo <Addenda> //Nodo principal necesario addenda=nuevoelemento("addenda"); if(addenda==null) return 0; addenda.prefix=proccess.getdefault_cfdi_prefix(); //prefijo para cfdi addenda.uri=proccess.getdefault_cfdi_uri(); //namespace asociado al prefijo //Nodo <MiCliente> //Nuevo nodo element=nuevoelemento("micliente"); if(element==null) return 0; element.prefix="otro"; //todos los nodos internos del elemento Addenda deben tener el prefijo element.uri="http://www.misitio.mx/minamespace"; //todos los nodos internos del elemento Addenda deben el valor URI //agrear NameSpaces element.setmyattribute("xmlns:otro","http://www.misitio.mx/minamespace"); element.setmyattribute("schemalocation","http://www.misitio.mx/minamespace http://www.misitio.mx/minamespace/minamespace.xsd"); element.getattribute("schemalocation").schemalocation=true; addenda.elements.add(element); //Nodo <InfomacionAdicional> //Nodo dentro de <MiCliente> e2=nuevoelemento("infomacionadicional"); if(e2==null) return 0; e2.prefix="otro"; e2.uri="http://www.misitio.mx/minamespace"; //Agregar atributos e2.setmyattribute("numproveedor","850001254"); e2.setmyattribute("notas","ejemplo de addenda"); element.elements.add(e2); //agregar la addenda al comprobante if(proccess.setaddendainxmlcfdi(archivoxml_timbrado,addenda)){ return -1; else{ return 0; 20
return 1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; Código de ejemplo para agregar addenda en Texto plano para CFDI //llamada par la ejecución de la función integraraddenda(); //Contenido de la función principal function integraraddenda(){ //retornar verdadero para continuar var addenda,element,e2; //Nodo <Addenda> //Nodo principal necesario addenda=nuevoelemento("addenda"); if(addenda==null) return 0; addenda.prefix=proccess.getdefault_cfdi_prefix(); //prefijo para cfdi addenda.uri=proccess.getdefault_cfdi_uri(); //namespace asociado al prefijo //Nuevo nodo de texto element=nuevoelemento(""); if(element==null) return 0; element.textnode=true; element.value="texto de ejemplo en addenda. & <El contenido> puede tener caracteres especiales ya que se transformará a UTF-8"; addenda.elements.add(element); //agregar la addenda al comprobante if(proccess.setaddendainxmlcfdi(archivoxml_timbrado,addenda)){ return -1; else{ return 0; return 1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; 21
Código de ejemplo para agregar Addenda en Base64 para formato binario en CFDI //llamada par la ejecución de la función integraraddenda(); //Contenido de la función principal function integraraddenda(){ //retornar verdadero para continuar var addenda,element,e2; var archivo; //Nodo <Addenda> //Nodo principal necesario addenda=nuevoelemento("addenda"); if(addenda==null) return 0; addenda.prefix=proccess.getdefault_cfdi_prefix(); //prefijo para cfdi addenda.uri=proccess.getdefault_cfdi_uri(); //namespace asociado al prefijo //Nuevo nodo de texto element=nuevoelemento(""); if(element==null) return 0; element.textnode=true; //Cargar el contenido binario desde un archivo archivo="c:\\miarchivo.pdf"; element.value=proccess.dobase64fromfile(archivo); if(element.value=="") { ebasic.emsgbox("el contenido del archivo para incluir en addenda esta vacío",6); return 0; //Cargar el contenido binario desde una cadena //element.value=proccess.dobase64fromstring("contenido de la addenda"); addenda.elements.add(element); //agregar la addenda al comprobante if(proccess.setaddendainxmlcfdi(archivoxml_timbrado,addenda)){ return -1; else{ return 0; return 1; //función para crear un nuevo nodo function nuevoelemento(nombre){ if(nombre==null) Nombre=""; var newe=ebasic.ecreateobject("gecfd.cmyelement"); if(esinvalido(newe,"no se pudo crear el elemento "+Nombre+". Error al crear objeto gecfd.cmyelement.")) return null; newe.name=nombre; return newe; 22
Activar Addenda Para activar la integración de la addenda deberá editar los datos del cliente y marcar la casilla: Incluir addenda en Comprobante Fiscal Digital. Generar CFD/CFDI Después de haber creado el archivo para la Addenda y activarla en el formulario de clientes podrá generar el comprobante y se incluirá la Addenda en el nodo <Addenda> del comprobante. La addenda no se toma en cuenta en la validación del comprobante, sin embargo, deberá estar creada correctamente y tener el formato adecuado de acuerdo al tipo de contenido: XML, texto o binario. El resultado de la integración de la Addenda usando datos de ejemplo con el código indicado arriba para XML sin namespaces sería el siguiente: 23
24
Addenda MaxiComercio La Addenda de MaxiComercio incluye información general de la venta la cual permitirá el registro rápido de compras en el sistema MaxiComercio del cliente. Elementos que conforman la Addenda de MaxiComercio A continuación se describen los nodos y sus respectivos atributos contenidos en la Addenda de MaxiComercio. Definición de cada uno de los elementos *El valor depende del tipo dato. **El valor depende del tipo de entidad de MaxiComercio. R: El nodo o atributo es Requerido. O: El nodo o atributo es Opcional. <Maxicomercio> Version R:Double * Versión de la addenda Nodos Nombre Info Venta Descripción R:Información general del comprobante y addenda R:Datos de la venta <Info> Notas_partida_concepto R:Bool 1/0 Indica que la descripción del concepto tiene incluidas las notas de la partida. Serie_lote_parte R:Bool 1/0 Indica que en el nodo <Parte> del concepto se incluyen los números de lotes o series del producto. Si el producto tiene serie y lotes únicamente se integran las series. <Venta> Documento R:Long ** Tipo de documento (entidad cdocumentos). Referencia R:String * Referencia de la venta Fecha R:Date * Fecha de la venta Subtotal R:Double * Sumatoria del Precio*Cantidad del detalle de 25
venta. Descuento1 R:Double * Sumatoria de Descuento1 del detalle de venta Descuento2 R:Double * Sumatoria de Descuento2 del detalle de venta Impuesto1 R:Double * Sumatoria de Impuesto1 del detalle de venta Impuesto2 R:Double * Sumatoria de Impuesto2 del detalle de venta Impuesto3 R:Double * Sumatoria de Impuesto3 del detalle de venta Impuesto4 R:Double * Sumatoria de Impuesto4 del detalle de venta Tipocambio R:Double * Tipo de cambio de la divisa usada. Domicilioentrega O:String * Domicilio de entrega capturado al realizar la venta. Txtguia O:String * Numero de guía especificado en la venta. Fembarque R:Date * Fecha de embarque Fentrega R:Date * Fecha de entrega Vencimiento R:Date * Fecha de vencimiento del documento Formapago R:Long ** Forma de pago (entidad cformaspago) Statusentrega R:Long ** Status de entrega de la mercancía (entidad cstatusenrega) Statusfinanciero R:Long ** Status financiero del documento (entidad csatatusfinancieros) Notas O:String * Notas de la venta Nodos Nombre Divisa Folio Cconsumo Cliente Agente Repartidor Porteador Movcaja Detalles Descripción R:Divisa de la venta R:Datos del folio R:Centro de consumo asignado a la venta R:Información del cliente O:Información del agente O:Información del repartidor O:Información del porteador O:Información del cobro en caja R:Detalles de la venta <Venta.Divisa> Codigo R:String * Código de la divisa asignada a la venta Descripcion R:String * Descripción de la divisa asignada a la venta 26
<Venta.Folio> Numero R:Long * Número de folio del sistema Serie R:String * Serie del sistema <Venta.Cconsumo> Codigo R:String * Identificador del centro de consumo Descripcion R:String * Descripción Notas O:String * Notas Nodos Nombre Almacen Descripción R: Almacén asociado al centro de consumo <Venta.Cconsumo.Almacen> Codigo R:String * Código Descripcion R:String * Descripción Email O:String * E-mail Fax O:String * Fax Telefonos O:String * Teléfonos Website O:String * Pagina web <Venta.Cliente> Codigo R:String * Identificador del cliente Nombre R:String * Nombre del cliente Rfc R:String * RFC del cliente Monedero R:Double * Saldo en monedero electrónico Limitecredito R:Double * Monto límite de crédito Puntos R:Double * Cantidad de puntos Saldo R:Double * Saldo actual del cliente Saldopuntos R:Double * Saldo actual en puntos Nodos 27
Nombre Tipocliente Descripción R: Información del tipo de cliente. <Venta.Cliente.Tipocliente> Codigo R:String * Código Descripcion R:String * Descripción Notas O:String * Notas <Venta.Agente> Codigo R:String * Código Nombre R:String * Nombre Email O:String * E-mail Telefono O:String * Teléfono Notas O:String * Notas <Venta.Repartidor> Codigo R:String * Código Nombre R:String * Nombre Email O:String * E-mail Telefono O:String * Teléfono Notas O:String * Notas <Venta.Porteador> Codigo R:String * Código Descripcion R:String * Descripción Notas O:String * Notas 28
<Venta.Movcaja> Efectivo R:Double * Cantidad pagada en efectivo Tarjetas R:Double * Cantidad pagada en tarjetas de crédito o debito Vales R:Double * Cantidad pagada en vales Depositos R:Double * Cantidad pagada en depósitos Cheques R:Double * Cantidad pagada en cheques Tipocambio R:Double * Valor del tipo de cambio de la divisa del pago. <Venta.Detalles> Nodos Nombre Dventa Descripción R: Información del producto vendido. <Venta.Detalles.Dventa> Cantidad R:Double * Cantidad vendida de producto asociado Unidad R:String * Unidad de venta Factor R:Double * Factor correspondiente a la unidad Precio R:Double * Precio del producto Descuento1 R:Double * Descuento1 Descuento2 R:Double * Descuento2 Impuesto1 R:Double * Impuesto1 Impuesto2 R:Double * Impuesto2 Impuesto3 R:Double * Impuesto3 Impuesto4 R:Double * Impuesto4 Tipocambio R:Double * Tipo de cambio correspondiente a la divisa de la venta Notas O:String * Notas de la partida Nodos Nombre Producto Descripción R: Información del producto vendido. <Venta.Detalles.Dventa.Producto> Codigo R:String * Código Descripcion R:String * Descripción 29
Codbar1 O:String * Código de barras 1 Codbar2 O:String * Código de barras 2 Codbar3 O:String * Código de barras 3 Diasentrega R:Double * Número de días de entrega del producto Ppuntos R:Double * Precio en puntos Reqlote R:Bool 1/0 Indica si requiere lote o no. Reqserie R:Bool 1/0 Indica si requiere serie o no. Iclase R:Long ** Clase de elemento (entidad cclaseproducto) Notas O:String * Notas del producto Nodos Nombre Tipoimpuesto Linea Marca Departamento Lotes Series Descripción R: Información del impuesto asociado al producto O: Información de la línea del producto O: Información de la marca del producto O: Información del departamento del producto O: Información de los números de lote. Se incluye solo si el producto tiene lote. O: Información de los números de serie. Se incluye solo si el producto tiene serie y no tiene lote. <Venta.Detalles.Dventa.Producto.Tipoimpuesto> Nombre R:String * Nombre del impuesto I1Venta R:String * Porcentajes de impuesto para interior y frontera, por ejemplo: %p1 %p2. P1 es el impuesto para interior y p2 es el impuesto para frontera. I2Venta R:String * Porcentajes de impuesto para interior y frontera, por ejemplo: %p1 %p2. P1 es el impuesto para interior y p2 es el impuesto para frontera. I3Venta R:String * Porcentajes de impuesto para interior y frontera, por ejemplo: %p1 %p2. P1 es el impuesto para interior y p2 es el impuesto para frontera. I4Venta R:String * Porcentajes de impuesto para interior y frontera, por ejemplo: %p1 %p2. P1 es el impuesto para interior y p2 es el impuesto para frontera. <Venta.Detalles.Dventa.Producto.Linea> Codigo R:String * Código Descripcion R:String * Descripción 30
* <Venta.Detalles.Dventa.Producto.Marca> Codigo R:String * Código Descripcion R:String * Descripción <Venta.Detalles.Dventa.Producto.Departamento> Codigo R:String * Código Descripcion R:String * Descripción <Venta.Detalles.Dventa.Producto.Lotes> Nodos Nombre Lote Descripción R:Información del lote del producto vendido <Venta.Detalles.Dventa.Producto.Lotes.Lote> Numero R:String * Número del lote Fcaducidad R:String * Fecha de caducidad del lote (puede que no se haya capturado por lo que tendrá la misma fecha de creación de la venta) Cantidad R:Double * Cantidad de productos Nodos Nombre Series Descripción O: Información de números de serie del producto vendido. <Venta.Detalles.Dventa.Producto.Lotes.Lote.Series> <Venta.Detalles.Dventa.Producto.Series> Nodos 31
Nombre Serie Descripción R:Información de la serie <Venta.Detalles.Dventa.Producto.Lotes.Lote.Series.Serie> o <Venta.Detalles.Dventa.Producto.Series.Serie> Numero R:String * Número de serie vendido Notas O:String * Notas de la serie Activar Addenda de MaxiComercio Para activar la integración de la Addenda de MaxiComercio ingrese al panel de control/facturación electrónica. En la siguiente ventana haga clic en el botón General. 32
Seleccione la pestaña Adicionales y haga clic en el botón Configuración avanzada. Se mostrará una ventana donde podrá marcar la casilla Incluir Addenda de MaxiComercio si el cliente no tiene asignada una. Reinicie la conexión de MaxiComercio para que los cambios tengan efecto. Esta opcion activará la integración de la addenda de MaxiComercio, y ésta solo se agregará en el XML cuando el cliente no tenga una Addenda configurada. 33
Especificaciones descritas en el anexo 20 de la Resolución Miscelánea Fiscal publicado el 23 de septiembre de 2010 B. Uso de la facilidad de nodos opcionales <Complemento> y <ComplementoConcepto> El estándar del comprobante fiscal digital incluye dos elementos definidos como de tipo abierto que servirán para integrar nodos adicionales, definidos por el Servicio de Administración Tributaria al cuerpo del comprobante. A diferencia del nodo Addenda, estos nodos si son de uso fiscal por lo que su contenido será reglamentado por la autoridad para ser utilizados por los contribuyentes que cuenten con alguna facilidad particular dispuesta en la Resolución Miscelánea Fiscal vigente, incluyendo los datos complementarios solicitados en dichos nodos de acuerdo al sector o actividad específica. Las reglas de uso de aquellos complementos disponibles estarán publicados en el sitio de Comprobantes Fiscales Digitales dentro del portal del SAT http://www.sat.gob.mx Reglas generales de uso: 1. Dentro de estos nodos de complemento se integrarán al comprobante los elementos adicionales necesarios de acuerdo con el formato definido por el SAT como requerido por la actividad específica del contribuyente. 2. La integración de estos elementos adicionales se hará siguiendo los siguientes lineamientos: a. Se integrarán idénticos los nodos complementarios requeridos dentro del nodo designado, según sea el caso requerido en la regla de la Resolución Miscelánea Fiscal aplicable. b. El Contribuyente deberá sujetarse a la estructura de estos nodos complementarios, teniendo cuidado de especificar las referencias necesarias al namespace del complemento que se utilice, de acuerdo a los estándares definidos y publicados por el SAT. c. Esto implica que si el contribuyente requiere utilizar esta funcionalidad complementaria deberá definir el namespace correspondiente dentro del nodo Comprobante, así como referenciar la ubicación pública del esquema xsd correspondiente. Por ejemplo, asumiendo que el contribuyente requiere integrar el namespace http://www.sat.gob.mx/cfd/ecc el cual se define mediante el esquema público definido en http://www.sat.gob.mx/schemas/cfd/ecc/ecc.xsd se vincularía de la siguiente forma: < cfdi:comprobante xmlns:xsi=http://www.w3.org/2001/xmlschema-instance xmlns:cfdi= http://www.sat.gob.mx/cfd/3 xmlns:ecc="http://www.sat.gob.mx/ecc" xsi:schemalocation=" http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv3.xsd http://www.sat.gob.mx/ecc http://www.sat.gob.mx/sitio_internet/cfd/ecc/ecc.xsd". </ cfdi:comprobante> Nota: El ejemplo mostrado es para un CFDI, en el caso de un CFD no se incluirá el encabezado del namespace cfdi en el cuerpo del comprobante. La línea que especifica xml:xsi= http://www.w3.org/2001/xmlschema-instance indica que se está usando validación mediante el estándar de esquema XSD. La línea que especifica xmlns:cfdi= http://www.sat.gob.mx/cfd/3 hace referencia al namespace de comprobantes. La línea que especifica xmlns:ecc= http://www.sat.gob.mx/ecc/ hace referencia al namespace adicional del complemento. Finalmente la línea que especifica xsi:schemalocation hace referencia a los dos namespaces usados, marcando adicionalmente la ubicación de los esquemas xsd que definen las especificaciones de cada namespace. En caso de que se requiriera agregar otros namespaces adicionales, el mecanismo sería agregar una línea tipo xmlns definiendo el namespace y expresando nuevamente el namespace y ubicación de su definición dentro del atributo xsi:schemalocation Cabe aclarar que los nodos básicos del comprobante fiscal digital por internet (CFDI) a diferencia de un CFD deberán llevar el encabezado del namespace publicado por el SAT. Por ejemplo el siguiente: <cfdi:comprobante> <cfdi:emisor/> 34
</cfdi:comprobante> Cada complemento tendrá definida su propia regla para inclusión en la cadena original, la cual, en caso de existir, se integrará en el lugar correspondiente de acuerdo a lo expresado en los rubros I.C y II.B del presente anexo. C. Uso de la facilidad de ensobretado <Addenda> La facilidad de ensobretado consiste en ofrecer un mecanismo a aquellos contribuyentes que desean utilizar otros formatos electrónicos de forma adicional y no substituta al establecido dentro del Anexo 20 Rubro I.B y II.A. Su objeto es permitir que el envío de dichos formatos adicionales se integre dentro del cuerpo del estándar de comprobante fiscal digital definido por el SAT, facilitando el transporte de los formatos e información adicional, evitando con ello envíos paralelos. Su mecánica de uso es el siguiente: 1. Se genera la información adicional en el formato particular del contribuyente. 2. Se genera el comprobante fiscal digital en el estándar definido por el SAT y se agregará el nodo o elemento de < cfdi:addenda>posterior a que el servicio de certificación de los proveedores autorizados sea exitoso, como información adicional. 3. Dentro del nodo de <cfdi:addenda> se expresa el formato particular del contribuyente siguiendo los siguientes lineamientos: a. Si el formato es XML se transcriben idénticos los nodos adicionales requeridos dentro del nodo < cfdi:addenda>. Si el contribuyente desea sujetar estos nodos adicionales a un diccionario o estándar específico, podrá hacerlo teniendo cuidado de especificar las referencias necesarias al namespace del formato utilizado, de acuerdo a los estándares definidos por el consorcio W3. Esto implica que si el contribuyente desea utilizar esta funcionalidad adicional deberá definir su nuevo namespace dentro del propio nodo de la Addenda publicando la ruta del esquema XSD para validación, por ejemplo: <cfdi:comprobante xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:cfdi= http://www.sat.gob.mx/cfd/3 xsi:schemalocation=" http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv3.xsd. <cfdi:addenda> xmlns:otro="http://www.misitio.mx/mins" xsi:schemalocation=" http://www.misitio.mx/mins http://www.misitio.mx/mins/mins.xsd" <otro:minodo miatributo= valor /> </cfdi:addenda> </cfdi:comprobante> Nota: El ejemplo mostrado es para un CFDI, en el caso de un CFD no se incluirá el encabezado del namespace cfdi en el cuerpo del comprobante. La línea que especifica xml:xsi= http://www.w3.org/2001/xmlschema-instance indica que se está usando validación mediante el estándar de esquema XSD. La línea que especifica xmlns:cfdi= http://www.sat.gob.mx/cfd/3 hace referencia al namespace de comprobantes fiscales digitales por internet, la línea que especifica xmlns=http://www.sat.gob.mx/cfd/2 hace referencia al namespace de comprobantes fiscales digitales. La línea que especifica xmlns:otro= http://www.misitio.mx/mins hace referencia al namespace adicional definido por el contribuyente La línea que especifica xsi:schemalocation hace referencia a los dos namespaces usados, marcando adicionalmente la ubicación de los esquemas xsd que definen las especificaciones de cada namespace. El primer par corresponde al namespace y ubicación del esquema definido por el SAT y el segundo par corresponde al namespace y ubicación definido por el contribuyente para sus propios fines. Finalmente, el nodo que aparece en la Addenda tiene el encabezado otro: que corresponde al encabezado definido dentro de sí mismo. En caso de que se requiriera agregar otros namespaces adicionales, el mecanismo sería agregar una línea tipo xmlns definiendo el namespace y expresando nuevamente el namespace y ubicación de su definición dentro del atributo xsi:schemalocation Cabe aclarar que los nodos básicos del comprobante deberán llevar encabezado del namespace publicado por el SAT al ser estos basados en el namespace por omisión (sólo para un CFDI). Por ejemplo el siguiente: <cfdi:comprobante> <cfdi:emisor/> </cfdi:comprobante> b. Si el formato es texto plano, se expresa idéntico dentro del nodo Addenda teniendo 35
cuidado de no usar caracteres reservados según la especificación de XML según los planteamientos del consorcio W3. Si el formato es binario, se deberá expresar como una cadena de caracteres codificados en formato Base 64. 36