Generar XML

This commit is contained in:
Mauricio Baeza 2021-04-29 22:39:55 -05:00
parent bb3e921a54
commit b12525e475
16 changed files with 1703 additions and 9 deletions

View File

@ -34,6 +34,7 @@ class SATCertificate(object):
self._is_fiel = False
self._are_couple = False
self._is_valid_time = False
self._cer = b''
self._cer_pem = ''
self._cer_txt = ''
self._key_enc = b''
@ -78,6 +79,7 @@ class SATCertificate(object):
self._is_fiel = obj.extensions.get_extension_for_oid(
ExtensionOID.KEY_USAGE).value.key_agreement
self._cer = cer
self._cer_pem = obj.public_bytes(serialization.Encoding.PEM).decode()
self._cer_txt = ''.join(self._cer_pem.split('\n')[1:-2])
self._cer_modulus = obj.public_key().public_numbers().n
@ -181,6 +183,10 @@ class SATCertificate(object):
def is_valid_time(self):
return self._is_valid_time
@property
def cer(self):
return self._cer
@property
def cer_pem(self):
return self._cer_pem.encode()

237
source/api/util/cfdi_xml.py Normal file
View File

@ -0,0 +1,237 @@
#!/usr/bin/env python3
from datetime import datetime
import lxml.etree as ET
class CFDI(object):
_version = '3.3'
_prefix = 'cfdi'
_xmlns = 'http://www.sat.gob.mx/cfd/3'
_schema = f'{_xmlns} http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd'
_pagos = 'http://www.sat.gob.mx/Pagos'
NS = {'cfdi': 'http://www.sat.gob.mx/cfd/3'}
PAGOS = {
'version': '1.0',
'prefix': _pagos,
'ns': {'pago10': _pagos},
'schema': f' {_pagos} http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd',
}
_nomina = 'http://www.sat.gob.mx/nomina12'
NOMINA = {
'version': '1.2',
'prefix': _nomina,
'ns': {'nomina12': _nomina},
'schema': f' {_nomina} http://www.sat.gob.mx/sitio_internet/cfd/nomina/nomina12.xsd',
}
def __init__(self):
self.error = ''
self._root = None
@property
def xml(self):
cfdi = ET.tostring(self._root,
pretty_print=True, xml_declaration=True, encoding='utf-8')
return cfdi.decode()
def make_xml(self, data):
self._validate_data(data)
self._comprobante(data['comprobante'])
self._relacionados(data.get('relacionados', {}))
self._emisor(data['emisor'])
self._receptor(data['receptor'])
self._conceptos(data['conceptos'])
self._impuestos(data.get('impuestos', {}))
self._complementos(data.get('complementos', {}))
return
def stamp(self, cert, path_xslt):
xslt = open(path_xslt, 'rb')
transfor = ET.XSLT(ET.parse(xslt))
print(cert)
return
def _validate_data(self, data):
self._node_complement = False
self._exists_pagos = False
self._exists_nomina = False
if not 'complementos' in data:
return
complements = data['complementos']
self._exists_pagos = 'pagos' in complements
self._exists_nomina = 'nomina' in complements
if self._exists_pagos:
self._node_complement = True
self._schema += self.PAGOS['schema']
if self._exists_nomina:
self._node_complement = True
self._schema += self.NOMINA['schema']
return
def _comprobante(self, attr):
NSMAP = {
self._prefix: self._xmlns,
'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
}
if self._exists_pagos:
NSMAP.update(self.PAGOS['ns'])
if self._exists_nomina:
NSMAP.update(self.NOMINA['ns'])
attr_qname = ET.QName(
'http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')
schema = {attr_qname: self._schema}
if not 'Version' in attr:
attr['Version'] = self._version
if not 'Fecha' in attr:
attr['Fecha'] = datetime.now().isoformat()[:19]
node_name = f'{{{self._xmlns}}}Comprobante'
self._root = ET.Element(node_name, schema, **attr, nsmap=NSMAP)
return
def _relacionados(self, attr):
return
def _emisor(self, attr):
node_name = f'{{{self._xmlns}}}Emisor'
emisor = ET.SubElement(self._root, node_name, attr)
return
def _receptor(self, attr):
node_name = f'{{{self._xmlns}}}Receptor'
emisor = ET.SubElement(self._root, node_name, attr)
return
def _conceptos(self, data):
node_name = f'{{{self._xmlns}}}Conceptos'
conceptos = ET.SubElement(self._root, node_name)
for row in data:
complemento = row.pop('complemento', {})
taxes = row.pop('impuestos', {})
node_name = f'{{{self._xmlns}}}Concepto'
concepto = ET.SubElement(conceptos, node_name, row)
if not taxes:
continue
if taxes['traslados'] or taxes['retenciones']:
node_name = f'{{{self._xmlns}}}Impuestos'
impuestos = ET.SubElement(concepto, node_name)
if 'traslados' in taxes and taxes['traslados']:
node_name = f'{{{self._xmlns}}}Traslados'
traslados = ET.SubElement(impuestos, node_name)
node_name = f'{{{self._xmlns}}}Traslado'
for traslado in taxes['traslados']:
ET.SubElement(traslados, node_name, traslado)
if 'retenciones' in taxes and taxes['retenciones']:
node_name = f'{{{self._xmlns}}}Retenciones'
retenciones = ET.SubElement(impuestos, node_name)
node_name = f'{{{self._xmlns}}}Retencion'
for retencion in taxes['retenciones']:
ET.SubElement(retenciones, node_name, retencion)
return
def _impuestos(self, data):
if not data:
return
node_name = f'{{{self._xmlns}}}Impuestos'
retenciones = data.pop('retenciones', ())
traslados = data.pop('traslados', ())
taxes = ET.SubElement(self._root, node_name, data)
if retenciones:
node_name = f'{{{self._xmlns}}}Retenciones'
subnode = ET.SubElement(taxes, node_name)
node_name = f'{{{self._xmlns}}}Retencion'
for row in retenciones:
ET.SubElement(subnode, node_name, row)
if traslados:
node_name = f'{{{self._xmlns}}}Traslados'
subnode = ET.SubElement(taxes, node_name)
node_name = f'{{{self._xmlns}}}Traslado'
for row in traslados:
ET.SubElement(subnode, node_name, row)
return
def _complementos(self, data):
if not self._node_complement:
return
node_name = f'{{{self._xmlns}}}Complemento'
complemento = ET.SubElement(self._root, node_name)
if self._exists_pagos:
self._pagos(complemento, data['pagos'])
if self._exists_nomina:
self._nomina(complemento, data['nomina'])
return
def _pagos(self, complemento, data):
node_name = f"{{{self.PAGOS['prefix']}}}Pagos"
attr = {'Version': self.PAGOS['version']}
node_pagos = ET.SubElement(complemento, node_name, attr)
for pago in data:
documentos = pago.pop('documentos')
node_name = f"{{{self.PAGOS['prefix']}}}Pago"
node_pago = ET.SubElement(node_pagos, node_name, pago)
node_name = f"{{{self.PAGOS['prefix']}}}DoctoRelacionado"
for doc in documentos:
ET.SubElement(node_pago, node_name, doc)
return
def _nomina(self, complemento, data):
emisor = data.pop('emisor')
receptor = data.pop('receptor')
percepciones = data.pop('percepciones', {})
deducciones = data.pop('deducciones', {})
otros = data.pop('otros', ())
if not 'Version' in data:
data['Version'] = self.NOMINA['version']
node_name = f"{{{self.NOMINA['prefix']}}}Nomina"
node_nomina = ET.SubElement(complemento, node_name, data)
node_name = f"{{{self.NOMINA['prefix']}}}Emisor"
ET.SubElement(node_nomina, node_name, emisor)
node_name = f"{{{self.NOMINA['prefix']}}}Receptor"
ET.SubElement(node_nomina, node_name, receptor)
if percepciones:
attr = percepciones
percepciones = attr.pop('percepciones')
node_name = f"{{{self.NOMINA['prefix']}}}Percepciones"
node = ET.SubElement(node_nomina, node_name, attr)
node_name = f"{{{self.NOMINA['prefix']}}}Percepcion"
for percepcion in percepciones:
ET.SubElement(node, node_name, percepcion)
if deducciones:
attr = deducciones
deducciones = attr.pop('deducciones')
node_name = f"{{{self.NOMINA['prefix']}}}Deducciones"
node = ET.SubElement(node_nomina, node_name, attr)
node_name = f"{{{self.NOMINA['prefix']}}}Deduccion"
for deduccion in deducciones:
ET.SubElement(node, node_name, deduccion)
if otros:
node_name = f"{{{self.NOMINA['prefix']}}}OtrosPagos"
node = ET.SubElement(node_nomina, node_name)
node_name = f"{{{self.NOMINA['prefix']}}}OtroPago"
for otro in otros:
subsidio = otro.pop('subsidio', {})
sub_node = ET.SubElement(node, node_name, otro)
if subsidio:
sub_name = f"{{{self.NOMINA['prefix']}}}SubsidioAlEmpleo"
ET.SubElement(sub_node, sub_name, subsidio)
return

View File

@ -1,8 +1,19 @@
#!/usr/bin/env python3
import json
from datetime import datetime
from pathlib import Path
from secrets import token_hex
from django.core.exceptions import ObjectDoesNotExist
from django.utils.timezone import now
from ..conf import API_TOKEN
from .cfdi_cert import SATCertificate
from .cfdi_xml import CFDI
from ..models import Clients
CURRENT_DIR = Path(__file__).resolve().parent #.parent
def validate_token(token):
@ -46,9 +57,45 @@ def validate_client(post, files):
'rfc': rfc,
'token': token_hex(32),
'key': cert.key_enc,
'cer': cert.cer_pem,
'cer': cert.cer,
'serial_number': cert.serial_number,
'date_from': cert.not_before,
'date_to': cert.not_after,
}
return True, data
def validate_cfdi(post):
data = json.loads(post)
rfc = data['emisor']['Rfc']
try:
obj = Clients.objects.get(rfc=rfc)
except ObjectDoesNotExist:
msg = 'Emisor no existe'
return False, msg
if obj.date_to < now():
msg = 'Certificado vencido'
return False, msg
if rfc != obj.rfc:
msg = 'Documento no corresponde al RFC del emisor'
return False, msg
data = {'cfdi': data, 'emisor': obj}
return True, data
def send_stamp(data):
msg = ''
emisor = data['emisor']
path_xslt = CURRENT_DIR / 'xslt/cadena.xslt'
cert = SATCertificate(emisor.cer, emisor.key)
cfdi = CFDI()
cfdi.make_xml(data['cfdi'])
cfdi.stamp(cert, path_xslt)
return cfdi.xml, msg

View File

@ -0,0 +1,345 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:cfdi="http://www.sat.gob.mx/cfd/3" xmlns:cce11="http://www.sat.gob.mx/ComercioExterior11" xmlns:donat="http://www.sat.gob.mx/donat" xmlns:divisas="http://www.sat.gob.mx/divisas" xmlns:implocal="http://www.sat.gob.mx/implocal" xmlns:leyendasFisc="http://www.sat.gob.mx/leyendasFiscales" xmlns:pfic="http://www.sat.gob.mx/pfic" xmlns:tpe="http://www.sat.gob.mx/TuristaPasajeroExtranjero" xmlns:nomina12="http://www.sat.gob.mx/nomina12" xmlns:registrofiscal="http://www.sat.gob.mx/registrofiscal" xmlns:pagoenespecie="http://www.sat.gob.mx/pagoenespecie" xmlns:aerolineas="http://www.sat.gob.mx/aerolineas" xmlns:valesdedespensa="http://www.sat.gob.mx/valesdedespensa" xmlns:consumodecombustibles="http://www.sat.gob.mx/consumodecombustibles" xmlns:notariospublicos="http://www.sat.gob.mx/notariospublicos" xmlns:vehiculousado="http://www.sat.gob.mx/vehiculousado" xmlns:servicioparcial="http://www.sat.gob.mx/servicioparcialconstruccion" xmlns:decreto="http://www.sat.gob.mx/renovacionysustitucionvehiculos" xmlns:destruccion="http://www.sat.gob.mx/certificadodestruccion" xmlns:obrasarte="http://www.sat.gob.mx/arteantiguedades" xmlns:ine="http://www.sat.gob.mx/ine" xmlns:iedu="http://www.sat.gob.mx/iedu" xmlns:ventavehiculos="http://www.sat.gob.mx/ventavehiculos" xmlns:terceros="http://www.sat.gob.mx/terceros" xmlns:pago10="http://www.sat.gob.mx/Pagos">
<!-- Con el siguiente método se establece que la salida deberá ser en texto -->
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<xsl:include href="utilerias.xslt"/>
<xsl:include href="comercioexterior11.xslt"/>
<xsl:include href="leyendasFisc.xslt"/>
<xsl:include href="nomina12.xslt"/>
<xsl:include href="implocal.xslt"/>
<xsl:include href="donat11.xslt"/>
<xsl:include href="ine11.xslt"/>
<xsl:include href="iedu.xslt"/>
<xsl:include href="pagos10.xslt"/>
<xsl:include href="divisas.xslt"/>
<!--
<xsl:include href="ecc11.xslt"/>
<xsl:include href="pfic.xslt"/>
<xsl:include href="TuristaPasajeroExtranjero.xslt"/>
<xsl:include href="cfdiregistrofiscal.xslt"/>
<xsl:include href="pagoenespecie.xslt"/>
<xsl:include href="aerolineas.xslt"/>
<xsl:include href="valesdedespensa.xslt"/>
<xsl:include href="consumodecombustibles.xslt"/>
<xsl:include href="notariospublicos.xslt"/>
<xsl:include href="vehiculousado.xslt"/>
<xsl:include href="servicioparcialconstruccion.xslt"/>
<xsl:include href="renovacionysustitucionvehiculos.xslt"/>
<xsl:include href="certificadodedestruccion.xslt"/>
<xsl:include href="obrasarteantiguedades.xslt"/>
<xsl:include href="ventavehiculos11.xslt"/>
<xsl:include href="terceros11.xslt"/>
-->
<!-- Aquí iniciamos el procesamiento de la cadena original con su | inicial y el terminador || -->
<xsl:template match="/">|<xsl:apply-templates select="/cfdi:Comprobante"/>||</xsl:template>
<!-- Aquí iniciamos el procesamiento de los datos incluidos en el comprobante -->
<xsl:template match="cfdi:Comprobante">
<!-- Iniciamos el tratamiento de los atributos de comprobante -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Version"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Serie"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Folio"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Fecha"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@FormaPago"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NoCertificado"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CondicionesDePago"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@SubTotal"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Descuento"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Moneda"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TipoCambio"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Total"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoDeComprobante"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@MetodoPago"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@LugarExpedicion"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Confirmacion"/>
</xsl:call-template>
<!--
Llamadas para procesar al los sub nodos del comprobante
-->
<xsl:apply-templates select="./cfdi:CfdiRelacionados"/>
<xsl:apply-templates select="./cfdi:Emisor"/>
<xsl:apply-templates select="./cfdi:Receptor"/>
<xsl:apply-templates select="./cfdi:Conceptos"/>
<xsl:apply-templates select="./cfdi:Impuestos"/>
<xsl:for-each select="./cfdi:Complemento">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Manejador de nodos tipo CFDIRelacionados -->
<xsl:template match="cfdi:CfdiRelacionados">
<!-- Iniciamos el tratamiento de los atributos del CFDIRelacionados -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoRelacion"/>
</xsl:call-template>
<xsl:for-each select="./cfdi:CfdiRelacionado">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@UUID"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<!-- Manejador de nodos tipo Emisor -->
<xsl:template match="cfdi:Emisor">
<!-- Iniciamos el tratamiento de los atributos del Emisor -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Rfc"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Nombre"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@RegimenFiscal"/>
</xsl:call-template>
</xsl:template>
<!-- Manejador de nodos tipo Receptor -->
<xsl:template match="cfdi:Receptor">
<!-- Iniciamos el tratamiento de los atributos del Receptor -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Rfc"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Nombre"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ResidenciaFiscal"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumRegIdTrib"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@UsoCFDI"/>
</xsl:call-template>
</xsl:template>
<!-- Manejador de nodos tipo Conceptos -->
<xsl:template match="cfdi:Conceptos">
<!-- Llamada para procesar los distintos nodos tipo Concepto -->
<xsl:for-each select="./cfdi:Concepto">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!--Manejador de nodos tipo Concepto-->
<xsl:template match="cfdi:Concepto">
<!-- Iniciamos el tratamiento de los atributos del Concepto -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ClaveProdServ"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NoIdentificacion"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Cantidad"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ClaveUnidad"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Unidad"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Descripcion"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ValorUnitario"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Descuento"/>
</xsl:call-template>
<!-- Manejo de sub nodos de información Traslado de Conceptos:Concepto:Impuestos:Traslados-->
<xsl:for-each select="./cfdi:Impuestos/cfdi:Traslados/cfdi:Traslado">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Base"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Impuesto"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoFactor"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TasaOCuota"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Importe"/>
</xsl:call-template>
</xsl:for-each>
<!-- Manejo de sub nodos de Retencion por cada una de los Conceptos:Concepto:Impuestos:Retenciones-->
<xsl:for-each select="./cfdi:Impuestos/cfdi:Retenciones/cfdi:Retencion">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Base"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Impuesto"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoFactor"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TasaOCuota"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe"/>
</xsl:call-template>
</xsl:for-each>
<!-- Manejo de los distintos sub nodos de información aduanera de forma indistinta a su grado de dependencia -->
<xsl:for-each select="./cfdi:InformacionAduanera">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Llamada al manejador de nodos de CuentaPredial en caso de existir -->
<xsl:if test="./cfdi:CuentaPredial">
<xsl:apply-templates select="./cfdi:CuentaPredial"/>
</xsl:if>
<!-- Llamada al manejador de nodos de ComplementoConcepto en caso de existir -->
<xsl:if test="./cfdi:ComplementoConcepto">
<xsl:apply-templates select="./cfdi:ComplementoConcepto"/>
</xsl:if>
<!-- Llamada al manejador de nodos de Parte en caso de existir -->
<xsl:for-each select=".//cfdi:Parte">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Manejador de nodos tipo Información Aduanera -->
<xsl:template match="cfdi:InformacionAduanera">
<!-- Manejo de los atributos de la información aduanera -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumeroPedimento"/>
</xsl:call-template>
</xsl:template>
<!-- Manejador de nodos tipo Información CuentaPredial -->
<xsl:template match="cfdi:CuentaPredial">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Numero"/>
</xsl:call-template>
</xsl:template>
<!-- Manejador de nodos tipo ComplementoConcepto -->
<xsl:template match="cfdi:ComplementoConcepto">
<xsl:for-each select="./*">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Manejador de nodos tipo Parte -->
<xsl:template match="cfdi:Parte">
<!-- Iniciamos el tratamiento de los atributos de Parte-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ClaveProdServ"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NoIdentificacion"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Cantidad"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Unidad"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Descripcion"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ValorUnitario"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Importe"/>
</xsl:call-template>
<!-- Manejador de nodos tipo InformacionAduanera-->
<xsl:for-each select=".//cfdi:InformacionAduanera">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Manejador de nodos tipo Complemento -->
<xsl:template match="cfdi:Complemento">
<xsl:for-each select="./*">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Manejador de nodos tipo Domicilio fiscal -->
<xsl:template match="cfdi:Impuestos">
<!-- Manejo de sub nodos de Retencion por cada una de los Impuestos:Retenciones-->
<xsl:for-each select="./cfdi:Retenciones/cfdi:Retencion">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Impuesto"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe"/>
</xsl:call-template>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de TotalImpuestosRetenidos-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalImpuestosRetenidos"/>
</xsl:call-template>
<!-- Manejo de sub nodos de información Traslado de Impuestos:Traslados-->
<xsl:for-each select="./cfdi:Traslados/cfdi:Traslado">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Impuesto"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoFactor"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TasaOCuota"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe"/>
</xsl:call-template>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de TotalImpuestosTrasladados-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalImpuestosTrasladados"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:cce11="http://www.sat.gob.mx/ComercioExterior11">
<xsl:template match="cce11:ComercioExterior">
<!--Manejador de nodos tipo ComercioExterior-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Version" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@MotivoTraslado" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoOperacion" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ClaveDePedimento" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CertificadoOrigen" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumCertificadoOrigen" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroExportadorConfiable" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Incoterm" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Subdivision" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Observaciones" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TipoCambioUSD" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalUSD" />
</xsl:call-template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia -->
<xsl:apply-templates select="./cce11:Emisor" />
<xsl:for-each select="./cce11:Propietario">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:apply-templates select="./cce11:Receptor" />
<xsl:for-each select="./cce11:Destinatario">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:apply-templates select="./cce11:Mercancias" />
</xsl:template>
<xsl:template match="cce11:Emisor">
<!-- Iniciamos el tratamiento de los atributos de cce11:Emisor-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Curp" />
</xsl:call-template>
<xsl:apply-templates select="./cce11:Domicilio" />
</xsl:template>
<xsl:template match="cce11:Propietario">
<!-- Tratamiento de los atributos de cce11:Propietario-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumRegIdTrib" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ResidenciaFiscal" />
</xsl:call-template>
</xsl:template>
<xsl:template match="cce11:Receptor">
<!-- Tratamiento de los atributos de cce11:Receptor-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumRegIdTrib" />
</xsl:call-template>
<xsl:apply-templates select="./cce11:Domicilio" />
</xsl:template>
<xsl:template match="cce11:Destinatario">
<!-- Tratamiento de los atributos de cce11:Destinatario-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumRegIdTrib" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Nombre" />
</xsl:call-template>
<!-- Manejo de los nodos dependientes -->
<xsl:for-each select="./cce11:Domicilio">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="cce11:Mercancias">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:for-each select="./cce11:Mercancia">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="cce11:Domicilio">
<!-- Iniciamos el tratamiento de los atributos de cce11:Domicilio-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Calle" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroExterior" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroInterior" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Colonia" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Localidad" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Referencia" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Municipio" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Estado" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Pais" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@CodigoPostal" />
</xsl:call-template>
</xsl:template>
<xsl:template match="cce11:Mercancia">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NoIdentificacion" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@FraccionArancelaria" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CantidadAduana" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@UnidadAduana" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ValorUnitarioAduana" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ValorDolares" />
</xsl:call-template>
<xsl:for-each select="./cce11:DescripcionesEspecificas">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="cce11:DescripcionesEspecificas">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Marca" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Modelo" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@SubModelo" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumeroSerie" />
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:divisas="http://www.sat.gob.mx/divisas">
<!-- Manejador de nodos tipo divisas:Divisas -->
<xsl:template match="divisas:Divisas">
<!-- Iniciamos el tratamiento de los atributos de divisas:Divisas -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@version"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@tipoOperacion"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:donat="http://www.sat.gob.mx/donat">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<!-- Manejador de nodos tipo donat:Donatarias -->
<xsl:template match="donat:Donatarias">
<!-- Iniciamos el tratamiento de los atributos de donat:Donatarias -->
<xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@version"/></xsl:call-template>
<xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@noAutorizacion"/></xsl:call-template>
<xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@fechaAutorizacion"/></xsl:call-template>
<xsl:call-template name="Requerido"><xsl:with-param name="valor" select="./@leyenda"/></xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:iedu="http://www.sat.gob.mx/iedu">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<!-- Manejador de nodos tipo iedu -->
<xsl:template match="iedu:instEducativas">
<!--Iniciamos el tratamiento de los atributos de instEducativas -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@version"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@nombreAlumno"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@CURP"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@nivelEducativo"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@autRVOE"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@rfcPago"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:implocal="http://www.sat.gob.mx/implocal">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<!-- Manejador de nodos tipo implocal -->
<xsl:template match="implocal:ImpuestosLocales">
<!--Iniciamos el tratamiento de los atributos de ImpuestosLocales -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@version"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TotaldeRetenciones"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TotaldeTraslados"/>
</xsl:call-template>
<xsl:for-each select="implocal:RetencionesLocales">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ImpLocRetenido"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TasadeRetencion"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe"/>
</xsl:call-template>
</xsl:for-each>
<xsl:for-each select="implocal:TrasladosLocales">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ImpLocTrasladado"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TasadeTraslado"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe"/>
</xsl:call-template>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ine="http://www.sat.gob.mx/ine">
<xsl:template match="ine:INE">
<!--Manejador de nodos tipo INE-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Version" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoProceso" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TipoComite" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@IdContabilidad" />
</xsl:call-template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia -->
<xsl:for-each select="./ine:Entidad">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="ine:Entidad">
<!--Manejador de nodos tipo Entidad-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ClaveEntidad" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Ambito" />
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de ine:Contabilidad-->
<xsl:for-each select="./ine:Contabilidad">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Contabilidad-->
<xsl:template match="ine:Contabilidad">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@IdContabilidad" />
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:leyendasFisc="http://www.sat.gob.mx/leyendasFiscales">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
<!-- Manejador de nodos tipo leyendasFiscales -->
<xsl:template match="leyendasFisc:LeyendasFiscales">
<!--Iniciamos el tratamiento de los atributos del complemento LeyendasFiscales -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@version"/>
</xsl:call-template>
<!-- Manejo de los atributos de las leyendas Fiscales-->
<xsl:for-each select="./leyendasFisc:Leyenda">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Manejador de nodos tipo Información de las leyendas -->
<xsl:template match="leyendasFisc:Leyenda">
<!-- Manejo de los atributos de la leyenda -->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@disposicionFiscal"/>
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@norma"/>
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@textoLeyenda"/>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,412 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:nomina12="http://www.sat.gob.mx/nomina12">
<xsl:template match="nomina12:Nomina">
<!--Manejador de nodos tipo Nomina-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Version" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoNomina" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@FechaPago" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@FechaInicialPago" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@FechaFinalPago" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumDiasPagados" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalPercepciones" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalDeducciones" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalOtrosPagos" />
</xsl:call-template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia -->
<xsl:for-each select="./nomina12:Emisor">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:for-each select="./nomina12:Receptor">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:for-each select="./nomina12:Percepciones">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:for-each select="./nomina12:Deducciones">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:for-each select="./nomina12:OtrosPagos">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:for-each select="./nomina12:Incapacidades">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="nomina12:Emisor">
<!--Manejador de nodos tipo nomina12:Emisor-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Curp" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RegistroPatronal" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RfcPatronOrigen" />
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de nomina12:EntidadSNCF-->
<xsl:for-each select="./nomina12:EntidadSNCF">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia EntidadSNCF-->
<xsl:template match="nomina12:EntidadSNCF">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@OrigenRecurso" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@MontoRecursoPropio" />
</xsl:call-template>
</xsl:template>
<xsl:template match="nomina12:Receptor">
<!--Manejador de nodos tipo nomina12:Receptor-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Curp" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumSeguridadSocial" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@FechaInicioRelLaboral" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Antigüedad" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoContrato" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Sindicalizado" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TipoJornada" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoRegimen" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumEmpleado" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Departamento" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Puesto" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RiesgoPuesto" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PeriodicidadPago" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Banco" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CuentaBancaria" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@SalarioBaseCotApor" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@SalarioDiarioIntegrado" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ClaveEntFed" />
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de nomina12:SubContratacion-->
<xsl:for-each select="./nomina12:SubContratacion">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia SubContratacion-->
<xsl:template match="nomina12:SubContratacion">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@RfcLabora" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PorcentajeTiempo" />
</xsl:call-template>
</xsl:template>
<xsl:template match="nomina12:Percepciones">
<!--Manejador de nodos tipo nomina12:Percepciones-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalSueldos" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalSeparacionIndemnizacion" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalJubilacionPensionRetiro" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TotalGravado" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TotalExento" />
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de nomina12:Percepcion-->
<xsl:for-each select="./nomina12:Percepcion">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de nomina12:JubilacionPensionRetiro-->
<xsl:for-each select="./nomina12:JubilacionPensionRetiro">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de nomina12:SeparacionIndemnizacion-->
<xsl:for-each select="./nomina12:SeparacionIndemnizacion">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Percepcion-->
<xsl:template match="nomina12:Percepcion">
<!--Manejador de nodos tipo nomina12:Percepcion-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoPercepcion" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Clave" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Concepto" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ImporteGravado" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ImporteExento" />
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de nomina12:AccionesOTitulos-->
<xsl:for-each select="./nomina12:AccionesOTitulos">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de nomina12:HorasExtra-->
<xsl:for-each select="./nomina12:HorasExtra">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia AccionesOTitulos-->
<xsl:template match="nomina12:AccionesOTitulos">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ValorMercado" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@PrecioAlOtorgarse" />
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia HorasExtra-->
<xsl:template match="nomina12:HorasExtra">
<!-- Iniciamos el manejo de los nodos dependientes -->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Dias" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoHoras" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@HorasExtra" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@ImportePagado" />
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia JubilacionPensionRetiro-->
<xsl:template match="nomina12:JubilacionPensionRetiro">
<!--Manejador de nodos tipo nomina12:JubilacionPensionRetiro-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalUnaExhibicion" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalParcialidad" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@MontoDiario" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@IngresoAcumulable" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@IngresoNoAcumulable" />
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia SeparacionIndemnizacion-->
<xsl:template match="nomina12:SeparacionIndemnizacion">
<!--Manejador de nodos tipo nomina12:JubilacionPensionRetiro-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TotalPagado" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@NumAñosServicio" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@UltimoSueldoMensOrd" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@IngresoAcumulable" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@IngresoNoAcumulable" />
</xsl:call-template>
</xsl:template>
<xsl:template match="nomina12:Deducciones">
<!--Manejador de nodos tipo nomina12:Deducciones-->
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalOtrasDeducciones" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalImpuestosRetenidos" />
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de nomina12:Deduccion-->
<xsl:for-each select="./nomina12:Deduccion">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Deduccion-->
<xsl:template match="nomina12:Deduccion">
<!--Manejador de nodos tipo nomina12:Deduccion-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoDeduccion" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Clave" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Concepto" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe" />
</xsl:call-template>
</xsl:template>
<xsl:template match="nomina12:OtrosPagos">
<!-- Iniciamos el tratamiento de los atributos de nomina12:OtroPago-->
<xsl:for-each select="./nomina12:OtroPago">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia OtroPago-->
<xsl:template match="nomina12:OtroPago">
<!--Manejador de nodos tipo nomina12:OtroPago-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoOtroPago" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Clave" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Concepto" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe" />
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de nomina12:SubsidioAlEmpleo-->
<xsl:for-each select="./nomina12:SubsidioAlEmpleo">
<xsl:apply-templates select="."/>
</xsl:for-each>
<!-- Iniciamos el tratamiento de los atributos de nomina12:CompensacionSaldosAFavor-->
<xsl:for-each select="./nomina12:CompensacionSaldosAFavor">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia SubsidioAlEmpleo-->
<xsl:template match="nomina12:SubsidioAlEmpleo">
<!--Manejador de nodos tipo nomina12:SubsidioAlEmpleo-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@SubsidioCausado" />
</xsl:call-template>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia CompensacionSaldosAFavor-->
<xsl:template match="nomina12:CompensacionSaldosAFavor">
<!--Manejador de nodos tipo nomina12:CompensacionSaldosAFavor-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@SaldoAFavor" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Año" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@RemanenteSalFav" />
</xsl:call-template>
</xsl:template>
<xsl:template match="nomina12:Incapacidades">
<!-- Iniciamos el tratamiento de los atributos de nomina12:Incapacidades-->
<xsl:for-each select="./nomina12:Incapacidad">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia Incapacidad-->
<xsl:template match="nomina12:Incapacidad">
<!--Manejador de nodos tipo nomina12:Incapacidad-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@DiasIncapacidad" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoIncapacidad" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ImporteMonetario" />
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:pago10="http://www.sat.gob.mx/Pagos">
<xsl:template match="pago10:Pagos">
<!--Manejador de Atributos Pagos-->
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Version" />
</xsl:call-template>
<!-- Iniciamos el manejo de los elementos hijo en la secuencia -->
<xsl:for-each select="./pago10:Pago">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="pago10:Pago">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@FechaPago" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@FormaDePagoP" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@MonedaP" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TipoCambioP" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Monto" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumOperacion" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RfcEmisorCtaOrd" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NomBancoOrdExt" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CtaOrdenante" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@RfcEmisorCtaBen" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CtaBeneficiario" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TipoCadPago" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CertPago" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@CadPago" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@SelloPago" />
</xsl:call-template>
<!-- Iniciamos el tratamiento de los atributos de pago10:DocumentoRelacionado-->
<xsl:for-each select="./pago10:DoctoRelacionado">
<xsl:apply-templates select="."/>
</xsl:for-each>
<xsl:for-each select="./pago10:Impuestos">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="pago10:DoctoRelacionado">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@IdDocumento" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Serie" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@Folio" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@MonedaDR" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TipoCambioDR" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@MetodoDePagoDR" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@NumParcialidad" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ImpSaldoAnt" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ImpPagado" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@ImpSaldoInsoluto" />
</xsl:call-template>
</xsl:template>
<xsl:template match="pago10:Impuestos">
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalImpuestosRetenidos" />
</xsl:call-template>
<xsl:call-template name="Opcional">
<xsl:with-param name="valor" select="./@TotalImpuestosTrasladados" />
</xsl:call-template>
<xsl:apply-templates select="./pago10:Retenciones"/>
<xsl:apply-templates select="./pago10:Traslados"/>
</xsl:template>
<xsl:template match="pago10:Retenciones">
<xsl:for-each select="./pago10:Retencion">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="pago10:Traslados">
<xsl:for-each select="./pago10:Traslado">
<xsl:apply-templates select="."/>
</xsl:for-each>
</xsl:template>
<xsl:template match="pago10:Retencion">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Impuesto" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe" />
</xsl:call-template>
</xsl:template>
<xsl:template match="pago10:Traslado">
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Impuesto" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TipoFactor" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@TasaOCuota" />
</xsl:call-template>
<xsl:call-template name="Requerido">
<xsl:with-param name="valor" select="./@Importe" />
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<!-- Manejador de datos requeridos -->
<xsl:template name="Requerido">
<xsl:param name="valor"/>|<xsl:call-template name="ManejaEspacios">
<xsl:with-param name="s" select="$valor"/>
</xsl:call-template>
</xsl:template>
<!-- Manejador de datos opcionales -->
<xsl:template name="Opcional">
<xsl:param name="valor"/>
<xsl:if test="$valor">|<xsl:call-template name="ManejaEspacios"><xsl:with-param name="s" select="$valor"/></xsl:call-template></xsl:if>
</xsl:template>
<!-- Normalizador de espacios en blanco -->
<xsl:template name="ManejaEspacios">
<xsl:param name="s"/>
<xsl:value-of select="normalize-space(string($s))"/>
</xsl:template>
</xsl:stylesheet>

View File

@ -1,6 +1,7 @@
from django.http import HttpResponse, HttpResponseNotFound
from django.http import HttpResponse
from django.http import JsonResponse
from django.views import View
from django.core.exceptions import ObjectDoesNotExist
from .util import util
from .models import Clients
@ -11,10 +12,8 @@ def _validate_token(request):
return False
token = request.headers['Token']
if not util.validate_token(token):
return False
return True
result = util.validate_token(token)
return result
class ViewClients(View):
@ -58,12 +57,28 @@ class ViewClients(View):
return HttpResponse(status=401)
rfc = request.GET['rfc']
obj = Clients.objects.get(rfc=rfc)
try:
obj = Clients.objects.get(rfc=rfc)
except ObjectDoesNotExist:
msg = 'Cliente no existe'
return HttpResponse(msg, status=202)
obj.delete()
return HttpResponse()
class ViewCfdi(View):
def get(self, request):
return HttpResponse('ok')
def post(self, request):
if not _validate_token(request):
return HttpResponse(status=401)
result, data = util.validate_cfdi(request.body)
if not result:
return HttpResponse(data, status=202)
xml, msg = util.send_stamp(data)
if msg:
return HttpResponse(msg, status=202)
return HttpResponse(xml, status=201)

View File

@ -1,16 +1,78 @@
#!/usr/bin/env python3
import unittest
import warnings
import httpx
URL_API = 'http://127.0.0.1:8000/api/{}'
PATH_CERT = 'certificados/comercio.{}'
CFDI_MINIMO = {
"comprobante": {
"TipoCambio": "1",
"Moneda": "MXN",
"TipoDeComprobante": "I",
"LugarExpedicion": "06850",
"SubTotal": "1000.00",
"Total": "1160.00",
"FormaPago": "03",
"MetodoPago": "PUE",
},
"emisor": {
"Rfc": "EKU9003173C9",
"RegimenFiscal": "601",
},
"receptor": {
"Rfc": "BASM740115RW0",
"UsoCFDI": "G01"
},
"conceptos": [
{
"ClaveProdServ": "60121001",
"Cantidad": "1.0",
"ClaveUnidad": "KGM",
"Descripcion": "Asesoría en desarrollo",
"ValorUnitario": "1000.00",
"Importe": "1000.00",
"impuestos": {
"traslados": [
{
"Base": "1000.00",
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.160000",
"Importe": "160.00"
}
]
}
}
],
"impuestos": {
"TotalImpuestosTrasladados": "160.00",
"traslados": [
{
"Impuesto": "002",
"TipoFactor": "Tasa",
"TasaOCuota": "0.160000",
"Importe": "160.00"
}
]
}
}
def ignore_warnings(test_func):
def do_test(self, *args, **kwargs):
with warnings.catch_warnings():
warnings.simplefilter("ignore")
test_func(self, *args, **kwargs)
return do_test
class TestClients(unittest.TestCase):
def setUp(self):
print(f'In method: {self._testMethodName}')
self.url = URL_API.format('clients/')
def test_unauthorized_without_token(self):
@ -23,6 +85,7 @@ class TestClients(unittest.TestCase):
result = httpx.post(self.url, headers={'Token': '123'})
self.assertEqual(expected, result.status_code)
@ignore_warnings
def test_01_add_client(self):
expected = 201
headers = {'Token': '12345'}
@ -51,6 +114,37 @@ class TestClients(unittest.TestCase):
result = httpx.delete(self.url, headers=headers, params=params)
self.assertEqual(expected, result.status_code)
def test_04_delete_client_not_exists(self):
expected = 202
headers = {'Token': '12345'}
params = {'rfc': 'EKU900317321'}
result = httpx.delete(self.url, headers=headers, params=params)
self.assertEqual(expected, result.status_code)
class TestCfdi(unittest.TestCase):
def setUp(self):
print(f'In method: {self._testMethodName}')
self.url = URL_API.format('cfdi/')
# ~ def test_stamp_cfdi_emisor_not_exists(self):
# ~ expected = 202
# ~ msg = 'Emisor no existe'
# ~ headers = {'Token': '12345'}
# ~ cfdi = CFDI_MINIMO.copy()
# ~ cfdi['emisor']['Rfc'] = 'No_exists'
# ~ result = httpx.post(self.url, headers=headers, json=cfdi)
# ~ self.assertEqual(result.text, msg)
# ~ self.assertEqual(expected, result.status_code)
def test_stamp_cfdi(self):
expected = 201
headers = {'Token': '12345'}
result = httpx.post(self.url, headers=headers, json=CFDI_MINIMO)
print(result.text)
self.assertEqual(expected, result.status_code)
if __name__ == '__main__':
unittest.main()