CFDI 4.0
This commit is contained in:
commit
24777f691e
|
@ -22,6 +22,7 @@ vedev/
|
||||||
# Virtualenv
|
# Virtualenv
|
||||||
.env/
|
.env/
|
||||||
virtual/
|
virtual/
|
||||||
|
env
|
||||||
|
|
||||||
docs/build
|
docs/build
|
||||||
cache/
|
cache/
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
v 2.0.0 [31-Mar-2022]
|
||||||
|
----------------------
|
||||||
|
- Primera versión de timbrado con CFDI4
|
||||||
|
- **IMPORTANTE** NO intentes timbrar si **antes** no has validado en nuestro demo que puedes timbrar tus CFDIs habituales.
|
||||||
|
|
||||||
|
|
||||||
v 1.47.0 [28-Mar-2022]
|
v 1.47.0 [28-Mar-2022]
|
||||||
----------------------
|
----------------------
|
||||||
- Mejora: Soporte basico para complemento Comercio Exterior.
|
- Mejora: Soporte basico para complemento Comercio Exterior.
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[ ] Permitir más de un remolque en la Carta Porte
|
||||||
|
[ ] Representación impresa de Comercio Exterior
|
|
@ -0,0 +1,18 @@
|
||||||
|
prefacturasdetalle;
|
||||||
|
prefacturasimpuestos;
|
||||||
|
prefacturas;
|
||||||
|
|
||||||
|
ticketsimpuestos;
|
||||||
|
ticketsdetalle;
|
||||||
|
tickets;
|
||||||
|
|
||||||
|
facturasrelacionadas;
|
||||||
|
facturaspersonalizados;
|
||||||
|
facturaspagos;
|
||||||
|
facturasimpuestos;
|
||||||
|
facturasdetalle;
|
||||||
|
facturascomplementos;
|
||||||
|
facturas;
|
||||||
|
|
||||||
|
cfdipagos;
|
||||||
|
movimientosbanco;
|
|
@ -25,16 +25,21 @@ from logbook import Logger
|
||||||
|
|
||||||
|
|
||||||
log = Logger('XML')
|
log = Logger('XML')
|
||||||
CFDI_ACTUAL = 'cfdi33'
|
CFDI_ACTUAL = 'cfdi40'
|
||||||
NOMINA_ACTUAL = 'nomina12'
|
NOMINA_ACTUAL = 'nomina12'
|
||||||
|
|
||||||
|
DEFAULT = {
|
||||||
|
'exportacion': '01',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SAT = {
|
SAT = {
|
||||||
'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
|
||||||
'cfdi32': {
|
'cfdi40': {
|
||||||
'version': '3.2',
|
'version': '4.0',
|
||||||
'prefix': 'cfdi',
|
'prefix': 'cfdi',
|
||||||
'xmlns': 'http://www.sat.gob.mx/cfd/3',
|
'xmlns': 'http://www.sat.gob.mx/cfd/4',
|
||||||
'schema': 'http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd',
|
'schema': 'http://www.sat.gob.mx/cfd/4 http://www.sat.gob.mx/sitio_internet/cfd/4/cfdv40.xsd',
|
||||||
},
|
},
|
||||||
'cfdi33': {
|
'cfdi33': {
|
||||||
'version': '3.3',
|
'version': '3.3',
|
||||||
|
@ -42,6 +47,12 @@ SAT = {
|
||||||
'xmlns': 'http://www.sat.gob.mx/cfd/3',
|
'xmlns': 'http://www.sat.gob.mx/cfd/3',
|
||||||
'schema': 'http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd',
|
'schema': 'http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd',
|
||||||
},
|
},
|
||||||
|
'cfdi32': {
|
||||||
|
'version': '3.2',
|
||||||
|
'prefix': 'cfdi',
|
||||||
|
'xmlns': 'http://www.sat.gob.mx/cfd/3',
|
||||||
|
'schema': 'http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd',
|
||||||
|
},
|
||||||
'nomina11': {
|
'nomina11': {
|
||||||
'version': '1.1',
|
'version': '1.1',
|
||||||
'prefix': 'nomina',
|
'prefix': 'nomina',
|
||||||
|
@ -80,10 +91,10 @@ SAT = {
|
||||||
'schema': ' http://www.sat.gob.mx/iedu http://www.sat.gob.mx/sitio_internet/cfd/iedu/iedu.xsd',
|
'schema': ' http://www.sat.gob.mx/iedu http://www.sat.gob.mx/sitio_internet/cfd/iedu/iedu.xsd',
|
||||||
},
|
},
|
||||||
'pagos': {
|
'pagos': {
|
||||||
'version': '1.0',
|
'version': '2.0',
|
||||||
'prefix': 'pago10',
|
'prefix': 'pago20',
|
||||||
'xmlns': 'http://www.sat.gob.mx/Pagos',
|
'xmlns': 'http://www.sat.gob.mx/Pagos20',
|
||||||
'schema': ' http://www.sat.gob.mx/Pagos http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd',
|
'schema': ' http://www.sat.gob.mx/Pagos20 http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos20.xsd',
|
||||||
},
|
},
|
||||||
'divisas': {
|
'divisas': {
|
||||||
'version': '1.0',
|
'version': '1.0',
|
||||||
|
@ -140,6 +151,7 @@ class CFDI(object):
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
self._comprobante(datos['comprobante'])
|
self._comprobante(datos['comprobante'])
|
||||||
|
self._informacion_global(datos['global'])
|
||||||
self._relacionados(datos['relacionados'])
|
self._relacionados(datos['relacionados'])
|
||||||
self._emisor(datos['emisor'])
|
self._emisor(datos['emisor'])
|
||||||
self._receptor(datos['receptor'])
|
self._receptor(datos['receptor'])
|
||||||
|
@ -270,9 +282,21 @@ class CFDI(object):
|
||||||
if not 'Fecha' in attributes:
|
if not 'Fecha' in attributes:
|
||||||
attributes['Fecha'] = self._now()
|
attributes['Fecha'] = self._now()
|
||||||
|
|
||||||
|
# ~ cfdi4
|
||||||
|
if not 'Exportacion' in attributes:
|
||||||
|
attributes['Exportacion'] = DEFAULT['exportacion']
|
||||||
|
|
||||||
self._cfdi = ET.Element('{}:Comprobante'.format(self._pre), attributes)
|
self._cfdi = ET.Element('{}:Comprobante'.format(self._pre), attributes)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _informacion_global(self, datos):
|
||||||
|
if not datos:
|
||||||
|
return
|
||||||
|
|
||||||
|
node_name = '{}:InformacionGlobal'.format(self._pre)
|
||||||
|
node = ET.SubElement(self._cfdi, node_name, datos)
|
||||||
|
return
|
||||||
|
|
||||||
def _relacionados(self, datos):
|
def _relacionados(self, datos):
|
||||||
if not datos or not datos['tipo'] or not datos['cfdis']:
|
if not datos or not datos['tipo'] or not datos['cfdis']:
|
||||||
return
|
return
|
||||||
|
@ -292,6 +316,7 @@ class CFDI(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
def _receptor(self, datos):
|
def _receptor(self, datos):
|
||||||
|
datos['Nombre'] = datos['Nombre'].upper()
|
||||||
node_name = '{}:Receptor'.format(self._pre)
|
node_name = '{}:Receptor'.format(self._pre)
|
||||||
emisor = ET.SubElement(self._cfdi, node_name, datos)
|
emisor = ET.SubElement(self._cfdi, node_name, datos)
|
||||||
return
|
return
|
||||||
|
@ -553,14 +578,41 @@ class CFDI(object):
|
||||||
|
|
||||||
if 'pagos' in datos:
|
if 'pagos' in datos:
|
||||||
datos = datos.pop('pagos')
|
datos = datos.pop('pagos')
|
||||||
|
totales = datos.pop('totales')
|
||||||
relacionados = datos.pop('relacionados')
|
relacionados = datos.pop('relacionados')
|
||||||
|
taxes_pay = datos.pop('taxes_pay')
|
||||||
pre = SAT['pagos']['prefix']
|
pre = SAT['pagos']['prefix']
|
||||||
|
|
||||||
attributes = {'Version': SAT['pagos']['version']}
|
attributes = {'Version': SAT['pagos']['version']}
|
||||||
pagos = ET.SubElement(
|
pagos = ET.SubElement(
|
||||||
self._complemento, '{}:Pagos'.format(pre), attributes)
|
self._complemento, '{}:Pagos'.format(pre), attributes)
|
||||||
|
|
||||||
|
ET.SubElement(pagos, '{}:Totales'.format(pre), totales)
|
||||||
|
|
||||||
node_pago = ET.SubElement(pagos, '{}:Pago'.format(pre), datos)
|
node_pago = ET.SubElement(pagos, '{}:Pago'.format(pre), datos)
|
||||||
for row in relacionados:
|
for row in relacionados:
|
||||||
ET.SubElement(node_pago, '{}:DoctoRelacionado'.format(pre), row)
|
taxes = row.pop('taxes')
|
||||||
|
node = ET.SubElement(node_pago, f'{pre}:DoctoRelacionado', row)
|
||||||
|
node_tax = ET.SubElement(node, f'{pre}:ImpuestosDR')
|
||||||
|
if taxes['retenciones']:
|
||||||
|
node = ET.SubElement(node_tax, f'{pre}:RetencionesDR')
|
||||||
|
for tax in taxes['retenciones']:
|
||||||
|
ET.SubElement(node, f'{pre}:RetencionDR', tax)
|
||||||
|
if taxes['traslados']:
|
||||||
|
node = ET.SubElement(node_tax, f'{pre}:TrasladosDR')
|
||||||
|
for tax in taxes['traslados']:
|
||||||
|
ET.SubElement(node, f'{pre}:TrasladoDR', tax)
|
||||||
|
|
||||||
|
node_tax = ET.SubElement(node_pago, f'{pre}:ImpuestosP')
|
||||||
|
if taxes_pay['retenciones']:
|
||||||
|
node = ET.SubElement(node_tax, f'{pre}:RetencionsP')
|
||||||
|
for key, importe in taxes_pay['retenciones'].items():
|
||||||
|
attr = {'ImpuestoP': key, 'ImporteP': importe}
|
||||||
|
ET.SubElement(node, f'{pre}:RetencionP', attr)
|
||||||
|
if taxes_pay['traslados']:
|
||||||
|
node = ET.SubElement(node_tax, f'{pre}:TrasladosP')
|
||||||
|
for key, tax in taxes_pay['traslados'].items():
|
||||||
|
ET.SubElement(node, f'{pre}:TrasladoP', tax)
|
||||||
|
|
||||||
if 'leyendas' in datos:
|
if 'leyendas' in datos:
|
||||||
pre = SAT['leyendas']['prefix']
|
pre = SAT['leyendas']['prefix']
|
||||||
|
|
|
@ -797,3 +797,27 @@ class AppSATUnidadesPeso(object):
|
||||||
user = req.env['beaker.session']['userobj']
|
user = req.env['beaker.session']['userobj']
|
||||||
req.context['result'] = self._db.sat_unidades_peso_post(values, user)
|
req.context['result'] = self._db.sat_unidades_peso_post(values, user)
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
|
||||||
|
class AppSATRegimenes(object):
|
||||||
|
|
||||||
|
def __init__(self, db):
|
||||||
|
self._db = db
|
||||||
|
|
||||||
|
def on_get(self, req, resp):
|
||||||
|
values = req.params
|
||||||
|
user = req.env['beaker.session']['userobj']
|
||||||
|
req.context['result'] = self._db.sat_regimenes_get(values, user)
|
||||||
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
|
||||||
|
class AppSociosRegimenes(object):
|
||||||
|
|
||||||
|
def __init__(self, db):
|
||||||
|
self._db = db
|
||||||
|
|
||||||
|
def on_get(self, req, resp):
|
||||||
|
values = req.params
|
||||||
|
user = req.env['beaker.session']['userobj']
|
||||||
|
req.context['result'] = self._db.socios_regimenes_get(values, user)
|
||||||
|
resp.status = falcon.HTTP_200
|
||||||
|
|
|
@ -41,6 +41,12 @@ logging.getLogger('requests').setLevel(logging.ERROR)
|
||||||
|
|
||||||
TIMEOUT = 10
|
TIMEOUT = 10
|
||||||
|
|
||||||
|
NAMESPACES = {
|
||||||
|
'3.3': 'http://www.sat.gob.mx/cfd/3',
|
||||||
|
'4.0': 'http://www.sat.gob.mx/cfd/4',
|
||||||
|
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def pretty_print_POST(req):
|
def pretty_print_POST(req):
|
||||||
"""
|
"""
|
||||||
|
@ -63,7 +69,7 @@ class PACComercioDigital(object):
|
||||||
ws = 'https://{}.comercio-digital.mx/{}'
|
ws = 'https://{}.comercio-digital.mx/{}'
|
||||||
api = 'https://app2.comercio-digital.mx/{}'
|
api = 'https://app2.comercio-digital.mx/{}'
|
||||||
URL = {
|
URL = {
|
||||||
'timbra': ws.format('ws', 'timbre/timbrarV5.aspx'),
|
'timbra': ws.format('ws', 'timbre4/timbrarV5'),
|
||||||
'cancel': ws.format('cancela', 'cancela4/cancelarUuid'),
|
'cancel': ws.format('cancela', 'cancela4/cancelarUuid'),
|
||||||
'cancelxml': ws.format('cancela', 'cancela4/cancelarXml'),
|
'cancelxml': ws.format('cancela', 'cancela4/cancelarXml'),
|
||||||
'status': ws.format('cancela', 'arws/consultaEstatus'),
|
'status': ws.format('cancela', 'arws/consultaEstatus'),
|
||||||
|
@ -78,7 +84,7 @@ class PACComercioDigital(object):
|
||||||
'702': '702 Error rfc/empresa invalido',
|
'702': '702 Error rfc/empresa invalido',
|
||||||
}
|
}
|
||||||
NS_CFDI = {
|
NS_CFDI = {
|
||||||
'cfdi': 'http://www.sat.gob.mx/cfd/3',
|
'cfdi': 'http://www.sat.gob.mx/cfd/4',
|
||||||
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +92,7 @@ class PACComercioDigital(object):
|
||||||
ws = 'https://pruebas.comercio-digital.mx/{}'
|
ws = 'https://pruebas.comercio-digital.mx/{}'
|
||||||
ws6 = 'https://pruebas6.comercio-digital.mx/arws/{}'
|
ws6 = 'https://pruebas6.comercio-digital.mx/arws/{}'
|
||||||
URL = {
|
URL = {
|
||||||
'timbra': ws.format('timbre/timbrarV5.aspx'),
|
'timbra': ws.format('timbre4/timbrarV5'),
|
||||||
'cancel': ws.format('cancela4/cancelarUuid'),
|
'cancel': ws.format('cancela4/cancelarUuid'),
|
||||||
'cancelxml': ws.format('cancela4/cancelarXml'),
|
'cancelxml': ws.format('cancela4/cancelarXml'),
|
||||||
'status': ws6.format('consultaEstatus'),
|
'status': ws6.format('consultaEstatus'),
|
||||||
|
@ -175,26 +181,29 @@ class PACComercioDigital(object):
|
||||||
info['key'] = base64.b64encode(info['key_enc']).decode()
|
info['key'] = base64.b64encode(info['key_enc']).decode()
|
||||||
info['cer'] = base64.b64encode(info['cer_ori']).decode()
|
info['cer'] = base64.b64encode(info['cer_ori']).decode()
|
||||||
|
|
||||||
NS_CFDI = {
|
|
||||||
'cfdi': 'http://www.sat.gob.mx/cfd/3',
|
|
||||||
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
|
||||||
}
|
|
||||||
tree = ET.fromstring(cfdi.encode())
|
tree = ET.fromstring(cfdi.encode())
|
||||||
|
version = tree.attrib['Version']
|
||||||
|
|
||||||
|
namespaces = {
|
||||||
|
'cfdi': NAMESPACES[version],
|
||||||
|
'tdf': NAMESPACES['tdf'],
|
||||||
|
}
|
||||||
|
|
||||||
tipo = tree.xpath(
|
tipo = tree.xpath(
|
||||||
'string(//cfdi:Comprobante/@TipoDeComprobante)',
|
'string(//cfdi:Comprobante/@TipoDeComprobante)',
|
||||||
namespaces=NS_CFDI)
|
namespaces=namespaces)
|
||||||
total = tree.xpath(
|
total = tree.xpath(
|
||||||
'string(//cfdi:Comprobante/@Total)',
|
'string(//cfdi:Comprobante/@Total)',
|
||||||
namespaces=NS_CFDI)
|
namespaces=namespaces)
|
||||||
rfc_emisor = tree.xpath(
|
rfc_emisor = tree.xpath(
|
||||||
'string(//cfdi:Comprobante/cfdi:Emisor/@Rfc)',
|
'string(//cfdi:Comprobante/cfdi:Emisor/@Rfc)',
|
||||||
namespaces=NS_CFDI)
|
namespaces=namespaces)
|
||||||
rfc_receptor = tree.xpath(
|
rfc_receptor = tree.xpath(
|
||||||
'string(//cfdi:Comprobante/cfdi:Receptor/@Rfc)',
|
'string(//cfdi:Comprobante/cfdi:Receptor/@Rfc)',
|
||||||
namespaces=NS_CFDI)
|
namespaces=namespaces)
|
||||||
uid = tree.xpath(
|
uid = tree.xpath(
|
||||||
'string(//cfdi:Complemento/tdf:TimbreFiscalDigital/@UUID)',
|
'string(//cfdi:Complemento/tdf:TimbreFiscalDigital/@UUID)',
|
||||||
namespaces=NS_CFDI)
|
namespaces=namespaces)
|
||||||
data = (
|
data = (
|
||||||
f"USER={auth['user']}",
|
f"USER={auth['user']}",
|
||||||
f"PWDW={auth['pass']}",
|
f"PWDW={auth['pass']}",
|
||||||
|
|
|
@ -74,7 +74,7 @@ class PACFinkok(object):
|
||||||
WS = 'https://facturacion.finkok.com/servicios/soap/{}.wsdl'
|
WS = 'https://facturacion.finkok.com/servicios/soap/{}.wsdl'
|
||||||
NS_TYPE = 'ns1'
|
NS_TYPE = 'ns1'
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
WS = 'http://demo-facturacion.finkok.com/servicios/soap/{}.wsdl'
|
WS = 'https://demo-facturacion.finkok.com/servicios/soap/{}.wsdl'
|
||||||
NS_TYPE = 'ns0'
|
NS_TYPE = 'ns0'
|
||||||
URL = {
|
URL = {
|
||||||
'quick_stamp': False,
|
'quick_stamp': False,
|
||||||
|
|
|
@ -78,9 +78,11 @@ import segno
|
||||||
from .pacs.cfdi_cert import SATCertificate
|
from .pacs.cfdi_cert import SATCertificate
|
||||||
|
|
||||||
from settings import (
|
from settings import (
|
||||||
|
CFDI_VERSIONS,
|
||||||
EXT,
|
EXT,
|
||||||
MXN,
|
MXN,
|
||||||
PATHS,
|
PATHS,
|
||||||
|
PRE_DEFAULT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -636,6 +638,12 @@ class LIBO(object):
|
||||||
self._set_cell('{cfdi.%s}' % k, v)
|
self._set_cell('{cfdi.%s}' % k, v)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _informacion_global(self, data):
|
||||||
|
for k, v in data.items():
|
||||||
|
print(k, v)
|
||||||
|
self._set_cell('{cfdi.%s}' % k, v)
|
||||||
|
return
|
||||||
|
|
||||||
def _emisor(self, data):
|
def _emisor(self, data):
|
||||||
for k, v in data.items():
|
for k, v in data.items():
|
||||||
self._set_cell('{emisor.%s}' % k, v)
|
self._set_cell('{emisor.%s}' % k, v)
|
||||||
|
@ -873,8 +881,6 @@ class LIBO(object):
|
||||||
image = self._template.createInstance('com.sun.star.drawing.GraphicObjectShape')
|
image = self._template.createInstance('com.sun.star.drawing.GraphicObjectShape')
|
||||||
gp = self._create_instance('com.sun.star.graphic.GraphicProvider')
|
gp = self._create_instance('com.sun.star.graphic.GraphicProvider')
|
||||||
pd.add(image)
|
pd.add(image)
|
||||||
# ~ image.GraphicURL = data['path_cbb']
|
|
||||||
# ~ properties = self._set_properties({'URL': self._path_url(data['path_cbb'])})
|
|
||||||
|
|
||||||
instance = 'com.sun.star.io.SequenceInputStream'
|
instance = 'com.sun.star.io.SequenceInputStream'
|
||||||
stream = self._create_instance(instance)
|
stream = self._create_instance(instance)
|
||||||
|
@ -883,11 +889,11 @@ class LIBO(object):
|
||||||
image.Graphic = gp.queryGraphic(properties)
|
image.Graphic = gp.queryGraphic(properties)
|
||||||
|
|
||||||
s = Size()
|
s = Size()
|
||||||
s.Width = 4150
|
s.Width = 4000
|
||||||
s.Height = 4500
|
s.Height = 4000
|
||||||
image.setSize(s)
|
image.setSize(s)
|
||||||
image.Anchor = self._set_cell('{timbre.cbb}')
|
image.Anchor = self._set_cell('{timbre.cbb}')
|
||||||
# ~ _kill(data['path_cbb'])
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def _donataria(self, data):
|
def _donataria(self, data):
|
||||||
|
@ -1119,6 +1125,8 @@ class LIBO(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
def _cfdipays(self, data):
|
def _cfdipays(self, data):
|
||||||
|
version = data['Version']
|
||||||
|
|
||||||
related = data.pop('related', [])
|
related = data.pop('related', [])
|
||||||
for k, v in data.items():
|
for k, v in data.items():
|
||||||
if k.lower() in ('monto',):
|
if k.lower() in ('monto',):
|
||||||
|
@ -1221,6 +1229,7 @@ class LIBO(object):
|
||||||
pakings = data.pop('pakings', [])
|
pakings = data.pop('pakings', [])
|
||||||
|
|
||||||
self._comprobante(data['comprobante'])
|
self._comprobante(data['comprobante'])
|
||||||
|
self._informacion_global(data['informacion_global'])
|
||||||
self._emisor(data['emisor'])
|
self._emisor(data['emisor'])
|
||||||
self._receptor(data['receptor'])
|
self._receptor(data['receptor'])
|
||||||
self._conceptos(data['conceptos'], pakings)
|
self._conceptos(data['conceptos'], pakings)
|
||||||
|
@ -1358,6 +1367,7 @@ class LIBO(object):
|
||||||
'codigo_postal',
|
'codigo_postal',
|
||||||
'notas',
|
'notas',
|
||||||
'correo',
|
'correo',
|
||||||
|
'regimen_fiscal',
|
||||||
)
|
)
|
||||||
rows = tuple([dict(zip(fields, r)) for r in data[1:]])
|
rows = tuple([dict(zip(fields, r)) for r in data[1:]])
|
||||||
msg = 'Empleados importados correctamente'
|
msg = 'Empleados importados correctamente'
|
||||||
|
@ -1553,36 +1563,40 @@ class LIBO(object):
|
||||||
|
|
||||||
def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
|
def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
|
||||||
rfc = data['emisor']['rfc']
|
rfc = data['emisor']['rfc']
|
||||||
default = 'plantilla_factura.ods'
|
|
||||||
if DEBUG:
|
if DEBUG:
|
||||||
rfc = emisor_rfc
|
rfc = emisor_rfc
|
||||||
|
|
||||||
version = data['comprobante']['version']
|
version = data['comprobante']['version']
|
||||||
|
default = f'plantilla_factura_{version}.ods'
|
||||||
|
|
||||||
if 'nomina' in data and data['nomina']:
|
if 'nomina' in data and data['nomina']:
|
||||||
default = 'plantilla_nomina.ods'
|
version_nomina = data['nomina']['version']
|
||||||
version = '{}_{}'.format(data['nomina']['version'], version)
|
default = f'plantilla_nomina_{version}_{version_nomina}.ods'
|
||||||
|
version = f'{version}_cn_{version_nomina}'
|
||||||
|
|
||||||
if 'carta_porte' in data:
|
if 'carta_porte' in data:
|
||||||
default = 'plantilla_factura_cp.ods'
|
default = 'plantilla_factura_ccp.ods'
|
||||||
version = '{}_cp_{}'.format(version, data['carta_porte']['version'])
|
version = '{}_ccp_{}'.format(version, data['carta_porte']['version'])
|
||||||
|
|
||||||
pagos = ''
|
|
||||||
if data.get('pagos', False):
|
if data.get('pagos', False):
|
||||||
version = '1.0'
|
version_pagos = data['pays']['version']
|
||||||
pagos = 'pagos_'
|
default = f'plantilla_pagos_{version}_{version_pagos}.ods'
|
||||||
|
version = f'{version}_cp_{version_pagos}'
|
||||||
|
|
||||||
if pdf_from == '2':
|
if pdf_from == '2':
|
||||||
return to_pdf_from_json(rfc, version, data)
|
return to_pdf_from_json(rfc, version, data)
|
||||||
|
|
||||||
|
donativo = ''
|
||||||
|
if data['donativo']:
|
||||||
|
donativo = '_donativo'
|
||||||
|
|
||||||
|
template_name = f'{rfc.lower()}_{version}.ods'
|
||||||
|
# ~ print('T', template_name, default)
|
||||||
|
|
||||||
if APP_LIBO:
|
if APP_LIBO:
|
||||||
app = LIBO()
|
app = LIBO()
|
||||||
if app.is_running:
|
if app.is_running:
|
||||||
donativo = ''
|
path = get_template_ods(template_name, default)
|
||||||
if data['donativo']:
|
|
||||||
donativo = '_donativo'
|
|
||||||
name = '{}_{}{}{}.ods'.format(rfc.lower(), pagos, version, donativo)
|
|
||||||
path = get_template_ods(name, default)
|
|
||||||
if path:
|
if path:
|
||||||
return app.pdf(path, data, ods)
|
return app.pdf(path, data, ods)
|
||||||
|
|
||||||
|
@ -1662,10 +1676,11 @@ def html_to_pdf(data):
|
||||||
|
|
||||||
|
|
||||||
def import_employees(rfc):
|
def import_employees(rfc):
|
||||||
|
msg = 'No se pudo cargar el archivo'
|
||||||
name = '{}_employees.ods'.format(rfc.lower())
|
name = '{}_employees.ods'.format(rfc.lower())
|
||||||
path = _join(PATH_MEDIA, 'tmp', name)
|
path = _join(PATH_MEDIA, 'tmp', name)
|
||||||
if not is_file(path):
|
if not is_file(path):
|
||||||
return ()
|
return (), msg
|
||||||
|
|
||||||
msg = 'LibreOffice no se pudo iniciar'
|
msg = 'LibreOffice no se pudo iniciar'
|
||||||
if APP_LIBO:
|
if APP_LIBO:
|
||||||
|
@ -1754,7 +1769,7 @@ def _comprobante(doc, options):
|
||||||
data['tiporelacion'] = options.get('tiporelacion', '')
|
data['tiporelacion'] = options.get('tiporelacion', '')
|
||||||
return data
|
return data
|
||||||
|
|
||||||
if data['version'] == '3.3':
|
if data['version'] in CFDI_VERSIONS:
|
||||||
tipos = {
|
tipos = {
|
||||||
'I': 'ingreso',
|
'I': 'ingreso',
|
||||||
'E': 'egreso',
|
'E': 'egreso',
|
||||||
|
@ -1839,7 +1854,7 @@ def _receptor(doc, version, values):
|
||||||
return data
|
return data
|
||||||
|
|
||||||
data['usocfdi'] = values['usocfdi']
|
data['usocfdi'] = values['usocfdi']
|
||||||
data.update(values['receptor'])
|
# ~ data.update(values['receptor'])
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
@ -1857,7 +1872,7 @@ def _conceptos(doc, version, options):
|
||||||
data.append(values)
|
data.append(values)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if version == '3.3':
|
if version in CFDI_VERSIONS:
|
||||||
if 'noidentificacion' in values:
|
if 'noidentificacion' in values:
|
||||||
values['noidentificacion'] = '{}\n(SAT {})'.format(
|
values['noidentificacion'] = '{}\n(SAT {})'.format(
|
||||||
values['noidentificacion'], values['ClaveProdServ'])
|
values['noidentificacion'], values['ClaveProdServ'])
|
||||||
|
@ -1921,7 +1936,7 @@ def _totales(doc, cfdi, version):
|
||||||
# ~ for n in node.getchildren():
|
# ~ for n in node.getchildren():
|
||||||
for n in list(node):
|
for n in list(node):
|
||||||
tmp = CaseInsensitiveDict(n.attrib.copy())
|
tmp = CaseInsensitiveDict(n.attrib.copy())
|
||||||
if version == '3.3':
|
if version in CFDI_VERSIONS:
|
||||||
tasa = round(float(tmp['tasaocuota']), DECIMALES)
|
tasa = round(float(tmp['tasaocuota']), DECIMALES)
|
||||||
title = 'Traslado {} {}'.format(tn.get(tmp['impuesto']), tasa)
|
title = 'Traslado {} {}'.format(tn.get(tmp['impuesto']), tasa)
|
||||||
else:
|
else:
|
||||||
|
@ -1933,7 +1948,7 @@ def _totales(doc, cfdi, version):
|
||||||
# ~ for n in node.getchildren():
|
# ~ for n in node.getchildren():
|
||||||
for n in list(node):
|
for n in list(node):
|
||||||
tmp = CaseInsensitiveDict(n.attrib.copy())
|
tmp = CaseInsensitiveDict(n.attrib.copy())
|
||||||
if version == '3.3':
|
if version in CFDI_VERSIONS:
|
||||||
title = 'Retención {} {}'.format(
|
title = 'Retención {} {}'.format(
|
||||||
tn.get(tmp['impuesto']), '')
|
tn.get(tmp['impuesto']), '')
|
||||||
else:
|
else:
|
||||||
|
@ -1965,7 +1980,7 @@ def _totales(doc, cfdi, version):
|
||||||
|
|
||||||
def _timbre(doc, version, values, pdf_from='1'):
|
def _timbre(doc, version, values, pdf_from='1'):
|
||||||
CADENA = '||{version}|{UUID}|{FechaTimbrado}|{selloCFD}|{noCertificadoSAT}||'
|
CADENA = '||{version}|{UUID}|{FechaTimbrado}|{selloCFD}|{noCertificadoSAT}||'
|
||||||
if version == '3.3':
|
if version in CFDI_VERSIONS:
|
||||||
CADENA = '||{Version}|{UUID}|{FechaTimbrado}|{SelloCFD}|{NoCertificadoSAT}||'
|
CADENA = '||{Version}|{UUID}|{FechaTimbrado}|{SelloCFD}|{NoCertificadoSAT}||'
|
||||||
node = doc.find('{}Complemento/{}TimbreFiscalDigital'.format(
|
node = doc.find('{}Complemento/{}TimbreFiscalDigital'.format(
|
||||||
PRE[version], PRE['TIMBRE']))
|
PRE[version], PRE['TIMBRE']))
|
||||||
|
@ -2095,19 +2110,53 @@ def _nomina(doc, data, values, version_cfdi):
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
def _get_info_pays_2(node):
|
||||||
|
pre_pays = PRE_DEFAULT['PAGOS']['PRE']
|
||||||
|
data = CaseInsensitiveDict(node.attrib.copy())
|
||||||
|
|
||||||
|
path = f"{pre_pays}Totales"
|
||||||
|
totales = node.find(path)
|
||||||
|
data.update(CaseInsensitiveDict(totales.attrib.copy()))
|
||||||
|
|
||||||
|
path = f"{pre_pays}Pago"
|
||||||
|
node_pay = node.find(path)
|
||||||
|
data.update(CaseInsensitiveDict(node_pay.attrib.copy()))
|
||||||
|
|
||||||
|
related = []
|
||||||
|
for n in node_pay:
|
||||||
|
attr = CaseInsensitiveDict(n.attrib.copy())
|
||||||
|
if attr:
|
||||||
|
attr['metododepagodr'] = ''
|
||||||
|
related.append(attr)
|
||||||
|
|
||||||
|
data['related'] = related
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
def _cfdipays(doc, data, version):
|
def _cfdipays(doc, data, version):
|
||||||
node = doc.find('{}Complemento/{}Pagos'.format(PRE[version], PRE['pagos']))
|
#todo: Obtener versión de complemento
|
||||||
|
if version == '4.0':
|
||||||
|
pre_pays = PRE_DEFAULT['PAGOS']['PRE']
|
||||||
|
path = f"{PRE[version]}Complemento/{pre_pays}Pagos"
|
||||||
|
node = doc.find(path)
|
||||||
|
else:
|
||||||
|
node = doc.find('{}Complemento/{}Pagos'.format(PRE[version], PRE['pagos']))
|
||||||
|
|
||||||
if node is None:
|
if node is None:
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
info = CaseInsensitiveDict(node.attrib.copy())
|
if version == '4.0':
|
||||||
related = []
|
info = _get_info_pays_2(node)
|
||||||
for n1 in node:
|
else:
|
||||||
info.update(CaseInsensitiveDict(n1.attrib.copy()))
|
info = CaseInsensitiveDict(node.attrib.copy())
|
||||||
for n2 in n1:
|
related = []
|
||||||
related.append(CaseInsensitiveDict(n2.attrib.copy()))
|
for n1 in node:
|
||||||
|
info.update(CaseInsensitiveDict(n1.attrib.copy()))
|
||||||
|
for n2 in n1:
|
||||||
|
related.append(CaseInsensitiveDict(n2.attrib.copy()))
|
||||||
|
|
||||||
info['related'] = related
|
info['related'] = related
|
||||||
|
|
||||||
data['comprobante']['totalenletras'] = to_letters(
|
data['comprobante']['totalenletras'] = to_letters(
|
||||||
float(info['monto']), info['monedap'])
|
float(info['monto']), info['monedap'])
|
||||||
|
@ -2120,6 +2169,7 @@ def get_data_from_xml(invoice, values, pdf_from='1'):
|
||||||
data = {'cancelada': invoice.cancelada, 'donativo': False}
|
data = {'cancelada': invoice.cancelada, 'donativo': False}
|
||||||
if hasattr(invoice, 'donativo'):
|
if hasattr(invoice, 'donativo'):
|
||||||
data['donativo'] = invoice.donativo
|
data['donativo'] = invoice.donativo
|
||||||
|
|
||||||
doc = parse_xml(invoice.xml)
|
doc = parse_xml(invoice.xml)
|
||||||
data['comprobante'] = _comprobante(doc, values)
|
data['comprobante'] = _comprobante(doc, values)
|
||||||
version = data['comprobante']['version']
|
version = data['comprobante']['version']
|
||||||
|
@ -2226,11 +2276,33 @@ class UpFile(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
def save_template(rfc, opt, file_obj):
|
||||||
|
result = {'status': 'error', 'ok': False}
|
||||||
|
|
||||||
|
name_template = f'{rfc}{opt}'
|
||||||
|
path_template = _join(PATH_MEDIA, 'templates', name_template)
|
||||||
|
|
||||||
|
if save_file(path_template, file_obj.file.read()):
|
||||||
|
result = {'status': 'server', 'name': file_obj.filename, 'ok': True}
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
def upload_file(rfc, opt, file_obj):
|
def upload_file(rfc, opt, file_obj):
|
||||||
rfc = rfc.lower()
|
rfc = rfc.lower()
|
||||||
tmp = file_obj.filename.split('.')
|
tmp = file_obj.filename.split('.')
|
||||||
ext = tmp[-1].lower()
|
ext = tmp[-1].lower()
|
||||||
|
|
||||||
|
versions = ('_3.2.ods',
|
||||||
|
'_3.3.ods', '_3.3_cn_1.2.ods', '_3.3_ccp_2.0.ods',
|
||||||
|
'_4.0.ods',
|
||||||
|
'_4.0_cn_1.2.ods',
|
||||||
|
'_4.0_cp_2.0.ods',
|
||||||
|
'_4.0_ccp_2.0.ods',
|
||||||
|
'_4.0_cd_1.1.ods')
|
||||||
|
if opt in versions:
|
||||||
|
return save_template(rfc, opt, file_obj)
|
||||||
|
|
||||||
EXTENSIONS = {
|
EXTENSIONS = {
|
||||||
'txt_plantilla_factura_32': EXT['ODS'],
|
'txt_plantilla_factura_32': EXT['ODS'],
|
||||||
'txt_plantilla_factura_33': EXT['ODS'],
|
'txt_plantilla_factura_33': EXT['ODS'],
|
||||||
|
|
|
@ -55,7 +55,7 @@ from dateutil import parser
|
||||||
|
|
||||||
from .cfdi_xml import CFDI
|
from .cfdi_xml import CFDI
|
||||||
|
|
||||||
from settings import DEBUG, DB_COMPANIES, PATHS, TEMPLATE_CANCEL, RFCS
|
from settings import DEBUG, DB_COMPANIES, PATHS, TEMPLATE_CANCEL, RFCS, PRE
|
||||||
|
|
||||||
from .pacs.cfdi_cert import SATCertificate
|
from .pacs.cfdi_cert import SATCertificate
|
||||||
from .pacs import PACComercioDigital
|
from .pacs import PACComercioDigital
|
||||||
|
@ -88,6 +88,7 @@ PACS = {
|
||||||
'finkok': PACFinkok,
|
'finkok': PACFinkok,
|
||||||
'comercio': PACComercioDigital,
|
'comercio': PACComercioDigital,
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_CFDI = {
|
NS_CFDI = {
|
||||||
'cfdi': 'http://www.sat.gob.mx/cfd/3',
|
'cfdi': 'http://www.sat.gob.mx/cfd/3',
|
||||||
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
||||||
|
@ -255,11 +256,15 @@ class SendMail(object):
|
||||||
|
|
||||||
|
|
||||||
class CfdiToDict(object):
|
class CfdiToDict(object):
|
||||||
|
NS_VERSION = {
|
||||||
|
'cfdi3.3': 'http://www.sat.gob.mx/cfd/3',
|
||||||
|
'cfdi4.0': 'http://www.sat.gob.mx/cfd/4',
|
||||||
|
}
|
||||||
NS = {
|
NS = {
|
||||||
'cfdi': 'http://www.sat.gob.mx/cfd/3',
|
|
||||||
'divisas': 'http://www.sat.gob.mx/divisas',
|
'divisas': 'http://www.sat.gob.mx/divisas',
|
||||||
'leyendasFisc': 'http://www.sat.gob.mx/leyendasFiscales',
|
'leyendasFisc': 'http://www.sat.gob.mx/leyendasFiscales',
|
||||||
'cartaporte20': 'http://www.sat.gob.mx/CartaPorte20',
|
'cartaporte20': 'http://www.sat.gob.mx/CartaPorte20',
|
||||||
|
'nomina12': 'http://www.sat.gob.mx/nomina12',
|
||||||
}
|
}
|
||||||
tipo_figura = {
|
tipo_figura = {
|
||||||
'01': '[01] Operador',
|
'01': '[01] Operador',
|
||||||
|
@ -267,6 +272,53 @@ class CfdiToDict(object):
|
||||||
'03': '[03] Arrendador',
|
'03': '[03] Arrendador',
|
||||||
'04': '[04] Notificado',
|
'04': '[04] Notificado',
|
||||||
}
|
}
|
||||||
|
REGIMEN_FISCAL = {
|
||||||
|
'601': '[601] General de Ley Personas Morales',
|
||||||
|
'603': '[603] Personas Morales con Fines no Lucrativos',
|
||||||
|
'605': '[605] Sueldos y Salarios e Ingresos Asimilados a Salarios',
|
||||||
|
'606': '[606] Arrendamiento',
|
||||||
|
'607': '[607] Régimen de Enajenación o Adquisición de Bienes',
|
||||||
|
'608': '[608] Demás ingresos',
|
||||||
|
'610': '[610] Residentes en el Extranjero sin Establecimiento Permanente en México',
|
||||||
|
'611': '[611] Ingresos por Dividendos (socios y accionistas)',
|
||||||
|
'612': '[612] Personas Físicas con Actividades Empresariales y Profesionales',
|
||||||
|
'614': '[614] Ingresos por intereses',
|
||||||
|
'615': '[615] Régimen de los ingresos por obtención de premios',
|
||||||
|
'616': '[616] Sin obligaciones fiscales',
|
||||||
|
'620': '[620] Sociedades Cooperativas de Producción que optan por diferir sus ingresos',
|
||||||
|
'621': '[621] Incorporación Fiscal',
|
||||||
|
'622': '[622] Actividades Agrícolas, Ganaderas, Silvícolas y Pesqueras',
|
||||||
|
'623': '[623] Opcional para Grupos de Sociedades',
|
||||||
|
'624': '[624] Coordinados',
|
||||||
|
'625': '[625] Régimen de las Actividades Empresariales con ingresos a través de Plataformas Tecnológicas',
|
||||||
|
'626': '[626] Régimen Simplificado de Confianza',
|
||||||
|
}
|
||||||
|
USO_CFDI = {
|
||||||
|
'G01': '[G01] Adquisición de mercancías.',
|
||||||
|
'G02': '[G02] Devoluciones, descuentos o bonificaciones.',
|
||||||
|
'G03': '[G03] Gastos en general.',
|
||||||
|
'I01': '[I01] Construcciones.',
|
||||||
|
'I02': '[I02] Mobiliario y equipo de oficina por inversiones.',
|
||||||
|
'I03': '[I03] Equipo de transporte.',
|
||||||
|
'I04': '[I04] Equipo de computo y accesorios.',
|
||||||
|
'I05': '[I05] Dados, troqueles, moldes, matrices y herramental.',
|
||||||
|
'I06': '[I06] Comunicaciones telefónicas.',
|
||||||
|
'I07': '[I07] Comunicaciones satelitales.',
|
||||||
|
'I08': '[I08] Otra maquinaria y equipo.',
|
||||||
|
'D01': '[D01] Honorarios médicos, dentales y gastos hospitalarios.',
|
||||||
|
'D02': '[D02] Gastos médicos por incapacidad o discapacidad.',
|
||||||
|
'D03': '[D03] Gastos funerales.',
|
||||||
|
'D04': '[D04] Donativos.',
|
||||||
|
'D05': '[D05] Intereses reales efectivamente pagados por créditos hipotecarios (casa habitación).',
|
||||||
|
'D06': '[D06] Aportaciones voluntarias al SAR.',
|
||||||
|
'D07': '[D07] Primas por seguros de gastos médicos.',
|
||||||
|
'D08': '[D08] Gastos de transportación escolar obligatoria.',
|
||||||
|
'D09': '[D09] Depósitos en cuentas para el ahorro, primas que tengan como base planes de pensiones.',
|
||||||
|
'D10': '[D10] Pagos por servicios educativos (colegiaturas).',
|
||||||
|
'S01': '[S01] Sin efectos fiscales.',
|
||||||
|
'CP01': '[CP01] Pagos',
|
||||||
|
'CN01': '[CN01] Nómina',
|
||||||
|
}
|
||||||
PAISES = {
|
PAISES = {
|
||||||
'MEX': 'México',
|
'MEX': 'México',
|
||||||
}
|
}
|
||||||
|
@ -305,8 +357,30 @@ class CfdiToDict(object):
|
||||||
'YUC': 'Yucatán',
|
'YUC': 'Yucatán',
|
||||||
'ZAC': 'Zacatecas',
|
'ZAC': 'Zacatecas',
|
||||||
}
|
}
|
||||||
|
PERIODICIDAD = {
|
||||||
|
'01': '[01] Diario',
|
||||||
|
'02': '[02] Semanal',
|
||||||
|
'03': '[03] Quincenal',
|
||||||
|
'04': '[04] Mensual',
|
||||||
|
'05': '[05] Bimestral',
|
||||||
|
}
|
||||||
|
MESES = {
|
||||||
|
'01': '[01] Enero',
|
||||||
|
'02': '[02] Febrero',
|
||||||
|
'03': '[03] Marzo',
|
||||||
|
'04': '[04] Abril',
|
||||||
|
'05': '[05] Mayo',
|
||||||
|
'06': '[06] Junio',
|
||||||
|
'07': '[07] Julio',
|
||||||
|
'08': '[08] Agosto',
|
||||||
|
'09': '[09] Septiembre',
|
||||||
|
'10': '[10] Octubre',
|
||||||
|
'11': '[11] Noviembre',
|
||||||
|
'12': '[12] Diciembre',
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, xml):
|
def __init__(self, xml):
|
||||||
|
self.version = ''
|
||||||
self._values = {
|
self._values = {
|
||||||
'leyendas': (),
|
'leyendas': (),
|
||||||
}
|
}
|
||||||
|
@ -318,9 +392,42 @@ class CfdiToDict(object):
|
||||||
return self._values
|
return self._values
|
||||||
|
|
||||||
def _get_values(self):
|
def _get_values(self):
|
||||||
|
self.version = self._root.attrib['Version']
|
||||||
|
ns = f'cfdi{self.version}'
|
||||||
|
self.NS['cfdi'] = self.NS_VERSION[ns]
|
||||||
|
self._informacion_global()
|
||||||
|
self._receptor()
|
||||||
self._complementos()
|
self._complementos()
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _informacion_global(self):
|
||||||
|
self._values['informacion_global'] = {}
|
||||||
|
|
||||||
|
path = '//cfdi:InformacionGlobal'
|
||||||
|
data = self._root.xpath(path, namespaces=self.NS)
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
|
||||||
|
data = data[0]
|
||||||
|
attr = CaseInsensitiveDict(data.attrib)
|
||||||
|
|
||||||
|
value = f"Periodicidad Factura Global: {self.PERIODICIDAD[attr['Periodicidad']]} "
|
||||||
|
value += f"del mes {self.MESES[attr['Meses']]} "
|
||||||
|
value += f"del año {attr['Año']}"
|
||||||
|
self._values['informacion_global'] = {'informacion_global': value}
|
||||||
|
return
|
||||||
|
|
||||||
|
def _receptor(self):
|
||||||
|
path = '//cfdi:Receptor'
|
||||||
|
receptor = self._root.xpath(path, namespaces=self.NS)[0]
|
||||||
|
attr = CaseInsensitiveDict(receptor.attrib)
|
||||||
|
attr['usocfdi'] = self.USO_CFDI[attr['UsoCFDI']]
|
||||||
|
if self.version == '4.0':
|
||||||
|
attr['domiciliofiscal'] = attr['DomicilioFiscalReceptor']
|
||||||
|
attr['regimenfiscal'] = self.REGIMEN_FISCAL[attr['RegimenFiscalReceptor']]
|
||||||
|
self._values['receptor'] = attr
|
||||||
|
return
|
||||||
|
|
||||||
def _set_carta_porte_domicilio(self, data):
|
def _set_carta_porte_domicilio(self, data):
|
||||||
municipio = data['Municipio']
|
municipio = data['Municipio']
|
||||||
estado = self.ESTADOS[data['Estado']]
|
estado = self.ESTADOS[data['Estado']]
|
||||||
|
@ -332,6 +439,14 @@ class CfdiToDict(object):
|
||||||
path = '//cfdi:Complemento'
|
path = '//cfdi:Complemento'
|
||||||
complemento = self._root.xpath(path, namespaces=self.NS)[0]
|
complemento = self._root.xpath(path, namespaces=self.NS)[0]
|
||||||
|
|
||||||
|
path = '//nomina12:Nomina'
|
||||||
|
nomina = complemento.xpath(path, namespaces=self.NS)
|
||||||
|
if nomina:
|
||||||
|
for node in nomina[0]:
|
||||||
|
if 'Receptor' in node.tag:
|
||||||
|
attr = CaseInsensitiveDict(node.attrib)
|
||||||
|
self._values['receptor'].update(attr)
|
||||||
|
|
||||||
path = '//divisas:Divisas'
|
path = '//divisas:Divisas'
|
||||||
divisas = complemento.xpath(path, namespaces=self.NS)
|
divisas = complemento.xpath(path, namespaces=self.NS)
|
||||||
if divisas:
|
if divisas:
|
||||||
|
@ -725,6 +840,9 @@ def xml_cancel(xml, auth, cert, name):
|
||||||
|
|
||||||
|
|
||||||
def get_client_balance(auth, rfc=''):
|
def get_client_balance(auth, rfc=''):
|
||||||
|
if not auth:
|
||||||
|
return 'p/c'
|
||||||
|
|
||||||
pac = PACS[auth['pac']]()
|
pac = PACS[auth['pac']]()
|
||||||
balance = pac.client_balance(auth, rfc)
|
balance = pac.client_balance(auth, rfc)
|
||||||
if pac.error:
|
if pac.error:
|
||||||
|
@ -760,8 +878,10 @@ def make_xml(data, certificado):
|
||||||
|
|
||||||
def get_pac_by_rfc(cfdi):
|
def get_pac_by_rfc(cfdi):
|
||||||
tree = ET.fromstring(cfdi.encode())
|
tree = ET.fromstring(cfdi.encode())
|
||||||
|
version = tree.attrib['Version']
|
||||||
|
namespaces = {'cfdi': PRE[version][1:-1], 'tdf': PRE['TIMBRE'][1:-1]}
|
||||||
path = 'string(//cfdi:Complemento/tdf:TimbreFiscalDigital/@RfcProvCertif)'
|
path = 'string(//cfdi:Complemento/tdf:TimbreFiscalDigital/@RfcProvCertif)'
|
||||||
rfc_pac = tree.xpath(path, namespaces=NS_CFDI)
|
rfc_pac = tree.xpath(path, namespaces=namespaces)
|
||||||
return RFCS[rfc_pac]
|
return RFCS[rfc_pac]
|
||||||
|
|
||||||
|
|
||||||
|
@ -827,17 +947,20 @@ def cancel_xml_sign(invoice, args, auth, certificado):
|
||||||
|
|
||||||
def _get_data_sat(xml):
|
def _get_data_sat(xml):
|
||||||
BF = 'string(//*[local-name()="{}"]/@{})'
|
BF = 'string(//*[local-name()="{}"]/@{})'
|
||||||
NS_CFDI = {'cfdi': 'http://www.sat.gob.mx/cfd/3'}
|
# ~ NS_CFDI = {'cfdi': 'http://www.sat.gob.mx/cfd/3'}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tree = ET.fromstring(xml.encode())
|
tree = ET.fromstring(xml.encode())
|
||||||
|
version = tree.attrib['Version']
|
||||||
|
namespaces = {'cfdi': PRE[version][1:-1]}
|
||||||
|
|
||||||
emisor = escape(
|
emisor = escape(
|
||||||
tree.xpath('string(//cfdi:Emisor/@rfc)', namespaces=NS_CFDI) or
|
tree.xpath('string(//cfdi:Emisor/@rfc)', namespaces=namespaces) or
|
||||||
tree.xpath('string(//cfdi:Emisor/@Rfc)', namespaces=NS_CFDI)
|
tree.xpath('string(//cfdi:Emisor/@Rfc)', namespaces=namespaces)
|
||||||
)
|
)
|
||||||
receptor = escape(
|
receptor = escape(
|
||||||
tree.xpath('string(//cfdi:Receptor/@rfc)', namespaces=NS_CFDI) or
|
tree.xpath('string(//cfdi:Receptor/@rfc)', namespaces=namespaces) or
|
||||||
tree.xpath('string(//cfdi:Receptor/@Rfc)', namespaces=NS_CFDI)
|
tree.xpath('string(//cfdi:Receptor/@Rfc)', namespaces=namespaces)
|
||||||
)
|
)
|
||||||
total = tree.get('total') or tree.get('Total')
|
total = tree.get('total') or tree.get('Total')
|
||||||
uuid = tree.xpath(BF.format('TimbreFiscalDigital', 'UUID'))
|
uuid = tree.xpath(BF.format('TimbreFiscalDigital', 'UUID'))
|
||||||
|
|
|
@ -25,6 +25,8 @@ from controllers.main import (AppEmpresas,
|
||||||
AppWareHouse,
|
AppWareHouse,
|
||||||
AppWareHouseProduct,
|
AppWareHouseProduct,
|
||||||
AppSATUnidadesPeso,
|
AppSATUnidadesPeso,
|
||||||
|
AppSATRegimenes,
|
||||||
|
AppSociosRegimenes,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,6 +80,8 @@ api.add_route('/warehouseproduct', AppWareHouseProduct(db))
|
||||||
api.add_route('/ticketsdetails', AppTicketsDetails(db))
|
api.add_route('/ticketsdetails', AppTicketsDetails(db))
|
||||||
api.add_route('/users', AppUsers(db))
|
api.add_route('/users', AppUsers(db))
|
||||||
api.add_route('/satunidadespeso', AppSATUnidadesPeso(db))
|
api.add_route('/satunidadespeso', AppSATUnidadesPeso(db))
|
||||||
|
api.add_route('/satregimenes', AppSATRegimenes(db))
|
||||||
|
api.add_route('/sociosregimenes', AppSociosRegimenes(db))
|
||||||
|
|
||||||
|
|
||||||
session_options = {
|
session_options = {
|
||||||
|
|
|
@ -526,6 +526,12 @@ class StorageEngine(object):
|
||||||
def sat_unidades_peso_post(self, args, user):
|
def sat_unidades_peso_post(self, args, user):
|
||||||
return main.SATUnidadesPeso.post(args, user)
|
return main.SATUnidadesPeso.post(args, user)
|
||||||
|
|
||||||
|
def sat_regimenes_get(self, filters, user):
|
||||||
|
return main.SATRegimenes.get_data(filters, user)
|
||||||
|
|
||||||
|
def socios_regimenes_get(self, filters, user):
|
||||||
|
return main.SociosRegimenes.get_data(filters, user)
|
||||||
|
|
||||||
# Companies only in MV
|
# Companies only in MV
|
||||||
def _get_empresas(self, values):
|
def _get_empresas(self, values):
|
||||||
return main.companies_get()
|
return main.companies_get()
|
||||||
|
|
|
@ -32,9 +32,9 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
from controllers import util
|
from controllers import util
|
||||||
|
|
||||||
from settings import log, COMPANIES, VERSION, PATH_CP, PRE, CURRENT_CFDI, \
|
from settings import log, COMPANIES, VERSION, PATH_CP, PRE, \
|
||||||
INIT_VALUES, DEFAULT_PASSWORD, DECIMALES, IMPUESTOS, DEFAULT_SAT_PRODUCTO, \
|
INIT_VALUES, DEFAULT_PASSWORD, DECIMALES, IMPUESTOS, DEFAULT_SAT_PRODUCTO, \
|
||||||
CANCEL_SIGNATURE, PUBLIC, DEFAULT_SERIE_TICKET, CURRENT_CFDI_NOMINA, \
|
CANCEL_SIGNATURE, PUBLIC, DEFAULT_SERIE_TICKET, \
|
||||||
DEFAULT_SAT_NOMINA, DECIMALES_TAX, TITLE_APP, MV, DECIMALES_PRECIOS, \
|
DEFAULT_SAT_NOMINA, DECIMALES_TAX, TITLE_APP, MV, DECIMALES_PRECIOS, \
|
||||||
DEFAULT_CFDIPAY, CURRENCY_MN
|
DEFAULT_CFDIPAY, CURRENCY_MN
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@ from settings import (
|
||||||
IS_MV,
|
IS_MV,
|
||||||
MXN,
|
MXN,
|
||||||
PATHS,
|
PATHS,
|
||||||
|
PRE_DEFAULT,
|
||||||
URL,
|
URL,
|
||||||
VALUES_PDF,
|
VALUES_PDF,
|
||||||
VERSION as VERSION_EMPRESA_LIBRE,
|
VERSION as VERSION_EMPRESA_LIBRE,
|
||||||
|
@ -466,7 +467,7 @@ class Configuracion(BaseModel):
|
||||||
'chk_config_codigo_barras',
|
'chk_config_codigo_barras',
|
||||||
'chk_config_precio_con_impuestos',
|
'chk_config_precio_con_impuestos',
|
||||||
'chk_llevar_inventario',
|
'chk_llevar_inventario',
|
||||||
'chk_use_packing',
|
# ~ 'chk_use_packing',
|
||||||
'chk_multi_stock',
|
'chk_multi_stock',
|
||||||
)
|
)
|
||||||
data = (Configuracion
|
data = (Configuracion
|
||||||
|
@ -692,8 +693,6 @@ class Configuracion(BaseModel):
|
||||||
)
|
)
|
||||||
elif keys['fields'] == 'templates':
|
elif keys['fields'] == 'templates':
|
||||||
fields = (
|
fields = (
|
||||||
'txt_plantilla_factura_32',
|
|
||||||
'txt_plantilla_factura_33',
|
|
||||||
'txt_plantilla_factura_html',
|
'txt_plantilla_factura_html',
|
||||||
'txt_plantilla_factura_css',
|
'txt_plantilla_factura_css',
|
||||||
'txt_plantilla_factura_json',
|
'txt_plantilla_factura_json',
|
||||||
|
@ -939,6 +938,26 @@ class SATRegimenes(BaseModel):
|
||||||
)
|
)
|
||||||
return tuple(rows)
|
return tuple(rows)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_actives(cls, filters, user):
|
||||||
|
where = ((SATRegimenes.activo==True) & (SATRegimenes.fisica==True))
|
||||||
|
if (filters['morales']=='true'):
|
||||||
|
where = ((SATRegimenes.activo==True) & (SATRegimenes.moral==True))
|
||||||
|
|
||||||
|
rows = (SATRegimenes
|
||||||
|
.select(
|
||||||
|
SATRegimenes.id,
|
||||||
|
SATRegimenes.name.alias('value'))
|
||||||
|
.where(where)
|
||||||
|
.dicts()
|
||||||
|
)
|
||||||
|
return tuple(rows)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_data(cls, filters, user):
|
||||||
|
opt = filters['opt']
|
||||||
|
return getattr(cls, f'_get_{opt}')(filters, user)
|
||||||
|
|
||||||
|
|
||||||
class Emisor(BaseModel):
|
class Emisor(BaseModel):
|
||||||
rfc = TextField(unique=True)
|
rfc = TextField(unique=True)
|
||||||
|
@ -1027,8 +1046,6 @@ class Emisor(BaseModel):
|
||||||
'ong_autorizacion': obj.autorizacion,
|
'ong_autorizacion': obj.autorizacion,
|
||||||
'ong_fecha': obj.fecha_autorizacion,
|
'ong_fecha': obj.fecha_autorizacion,
|
||||||
'ong_fecha_dof': obj.fecha_dof,
|
'ong_fecha_dof': obj.fecha_dof,
|
||||||
# ~ 'correo_timbrado': obj.correo_timbrado,
|
|
||||||
# ~ 'token_timbrado': obj.token_timbrado,
|
|
||||||
'token_soporte': obj.token_soporte,
|
'token_soporte': obj.token_soporte,
|
||||||
'emisor_registro_patronal': obj.registro_patronal,
|
'emisor_registro_patronal': obj.registro_patronal,
|
||||||
'regimenes': [row.id for row in obj.regimenes]
|
'regimenes': [row.id for row in obj.regimenes]
|
||||||
|
@ -1745,7 +1762,7 @@ class SATImpuestos(BaseModel):
|
||||||
tipo = 'R'
|
tipo = 'R'
|
||||||
|
|
||||||
row = {
|
row = {
|
||||||
'key': IMPUESTOS.get(values['impuesto']),
|
'key': IMPUESTOS.get(values['impuesto'], '000'),
|
||||||
'name': values['impuesto'],
|
'name': values['impuesto'],
|
||||||
'tipo': tipo,
|
'tipo': tipo,
|
||||||
'tasa': abs(tasa),
|
'tasa': abs(tasa),
|
||||||
|
@ -2744,6 +2761,7 @@ class Socios(BaseModel):
|
||||||
uso_cfdi = ForeignKeyField(SATUsoCfdi, null=True)
|
uso_cfdi = ForeignKeyField(SATUsoCfdi, null=True)
|
||||||
tags = ManyToManyField(Tags, related_name='socios_tags')
|
tags = ManyToManyField(Tags, related_name='socios_tags')
|
||||||
plantilla = TextField(default='')
|
plantilla = TextField(default='')
|
||||||
|
regimen_fiscal = TextField(default='')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
t = '{} ({})'
|
t = '{} ({})'
|
||||||
|
@ -2787,6 +2805,13 @@ class Socios(BaseModel):
|
||||||
if fields['pais'] != 'México':
|
if fields['pais'] != 'México':
|
||||||
fields['pais'] = fields['pais'].upper()
|
fields['pais'] = fields['pais'].upper()
|
||||||
|
|
||||||
|
if 'regimenes' in fields:
|
||||||
|
fields['regimenes'] = utils.loads(fields['regimenes'])
|
||||||
|
if isinstance(fields['regimenes'], list):
|
||||||
|
fields['regimenes'] = tuple(map(int, fields['regimenes']))
|
||||||
|
else:
|
||||||
|
fields['regimenes'] = (fields['regimenes'],)
|
||||||
|
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -2802,18 +2827,9 @@ class Socios(BaseModel):
|
||||||
str(CondicionesPago.get(id=row['condicion_pago']))
|
str(CondicionesPago.get(id=row['condicion_pago']))
|
||||||
row['partner_balance'] = row.pop('saldo_cliente')
|
row['partner_balance'] = row.pop('saldo_cliente')
|
||||||
row['partner_email_fp'] = row.pop('correo_facturasp')
|
row['partner_email_fp'] = row.pop('correo_facturasp')
|
||||||
|
row['regimenes'] = SociosRegimenes.get_by_socio(row['id'])
|
||||||
return row
|
return row
|
||||||
|
|
||||||
#~ return {'data': data['rows'][:100], 'pos':0, 'total_count': 1300}
|
|
||||||
#~ start = 0
|
|
||||||
#~ count = 0
|
|
||||||
#~ end = 100
|
|
||||||
#~ if values:
|
|
||||||
#~ {'start': '100', 'count': '100', 'continue': 'true'}
|
|
||||||
#~ start = int(values['start'])
|
|
||||||
#~ cont = int(values['count'])
|
|
||||||
#~ end = start + count
|
|
||||||
|
|
||||||
total = Socios.select().count()
|
total = Socios.select().count()
|
||||||
|
|
||||||
rows = (Socios
|
rows = (Socios
|
||||||
|
@ -2829,19 +2845,23 @@ class Socios(BaseModel):
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_by_client(cls, values):
|
def get_by_client(cls, values):
|
||||||
id = int(values.get('id', 0))
|
id = int(values.get('id', 0))
|
||||||
|
|
||||||
if id:
|
if id:
|
||||||
row = (Socios
|
row = (Socios
|
||||||
.select(
|
.select(
|
||||||
Socios.id, Socios.nombre, Socios.rfc,
|
Socios.id, Socios.nombre, Socios.rfc,
|
||||||
SATFormaPago.key.alias('forma_pago'),
|
SATFormaPago.key.alias('forma_pago'),
|
||||||
SATUsoCfdi.key.alias('uso_cfdi'))
|
SATUsoCfdi.key.alias('uso_cfdi'),
|
||||||
|
Socios.codigo_postal)
|
||||||
.join(SATFormaPago, JOIN.LEFT_OUTER).switch(Socios)
|
.join(SATFormaPago, JOIN.LEFT_OUTER).switch(Socios)
|
||||||
.join(SATUsoCfdi, JOIN.LEFT_OUTER).switch(Socios)
|
.join(SATUsoCfdi, JOIN.LEFT_OUTER).switch(Socios)
|
||||||
.where((Socios.id==id) & (Socios.es_cliente==True))
|
.where((Socios.id==id) & (Socios.es_cliente==True))
|
||||||
.dicts()
|
.dicts()
|
||||||
)
|
)
|
||||||
if len(row):
|
if len(row):
|
||||||
return {'ok': True, 'row': row[0]}
|
client = row[0]
|
||||||
|
client['regimenes'] = SociosRegimenes.get_by_key(client['id'])
|
||||||
|
return {'ok': True, 'row': client}
|
||||||
return {'ok': False}
|
return {'ok': False}
|
||||||
|
|
||||||
name = values.get('name', '')
|
name = values.get('name', '')
|
||||||
|
@ -2849,7 +2869,8 @@ class Socios(BaseModel):
|
||||||
rows = (Socios
|
rows = (Socios
|
||||||
.select(Socios.id, Socios.nombre, Socios.rfc,
|
.select(Socios.id, Socios.nombre, Socios.rfc,
|
||||||
SATFormaPago.key.alias('forma_pago'),
|
SATFormaPago.key.alias('forma_pago'),
|
||||||
SATUsoCfdi.key.alias('uso_cfdi'))
|
SATUsoCfdi.key.alias('uso_cfdi'),
|
||||||
|
Socios.codigo_postal)
|
||||||
.join(SATFormaPago, JOIN.LEFT_OUTER).switch(Socios)
|
.join(SATFormaPago, JOIN.LEFT_OUTER).switch(Socios)
|
||||||
.join(SATUsoCfdi, JOIN.LEFT_OUTER).switch(Socios)
|
.join(SATUsoCfdi, JOIN.LEFT_OUTER).switch(Socios)
|
||||||
.where((Socios.es_cliente==True & Socios.es_activo==True) &
|
.where((Socios.es_cliente==True & Socios.es_activo==True) &
|
||||||
|
@ -2863,6 +2884,7 @@ class Socios(BaseModel):
|
||||||
def add(cls, values):
|
def add(cls, values):
|
||||||
accounts = util.loads(values.pop('accounts', '[]'))
|
accounts = util.loads(values.pop('accounts', '[]'))
|
||||||
fields = cls._clean(cls, values)
|
fields = cls._clean(cls, values)
|
||||||
|
regimenes = fields.pop('regimenes', ())
|
||||||
|
|
||||||
w = ((Socios.rfc==fields['rfc']) & (Socios.slug==fields['slug']))
|
w = ((Socios.rfc==fields['rfc']) & (Socios.slug==fields['slug']))
|
||||||
if Socios.select().where(w).exists():
|
if Socios.select().where(w).exists():
|
||||||
|
@ -2892,6 +2914,16 @@ class Socios(BaseModel):
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
for regimen in regimenes:
|
||||||
|
try:
|
||||||
|
fields = {
|
||||||
|
'socio': obj,
|
||||||
|
'regimen': regimen,
|
||||||
|
}
|
||||||
|
SociosRegimenes.create(**fields)
|
||||||
|
except IntegrityError:
|
||||||
|
pass
|
||||||
|
|
||||||
row = {
|
row = {
|
||||||
'id': obj.id,
|
'id': obj.id,
|
||||||
'rfc': obj.rfc,
|
'rfc': obj.rfc,
|
||||||
|
@ -2905,6 +2937,8 @@ class Socios(BaseModel):
|
||||||
def actualizar(cls, values, id):
|
def actualizar(cls, values, id):
|
||||||
fields = cls._clean(cls, values)
|
fields = cls._clean(cls, values)
|
||||||
fields.pop('accounts', '')
|
fields.pop('accounts', '')
|
||||||
|
regimenes = fields.pop('regimenes', ())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
q = Socios.update(**fields).where(Socios.id==id)
|
q = Socios.update(**fields).where(Socios.id==id)
|
||||||
q.execute()
|
q.execute()
|
||||||
|
@ -2913,6 +2947,19 @@ class Socios(BaseModel):
|
||||||
data = {'ok': False, 'row': {}, 'new': True, 'msg': msg}
|
data = {'ok': False, 'row': {}, 'new': True, 'msg': msg}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
obj = Socios.get(Socios.id==id)
|
||||||
|
q = SociosRegimenes.delete().where(SociosRegimenes.socio==id)
|
||||||
|
q.execute()
|
||||||
|
for regimen in regimenes:
|
||||||
|
try:
|
||||||
|
fields = {
|
||||||
|
'socio': obj,
|
||||||
|
'regimen': regimen,
|
||||||
|
}
|
||||||
|
SociosRegimenes.create(**fields)
|
||||||
|
except IntegrityError:
|
||||||
|
pass
|
||||||
|
|
||||||
obj = Socios.get(Socios.id==id)
|
obj = Socios.get(Socios.id==id)
|
||||||
row = {
|
row = {
|
||||||
'id': id,
|
'id': id,
|
||||||
|
@ -2934,6 +2981,8 @@ class Socios(BaseModel):
|
||||||
|
|
||||||
q = SociosCuentasBanco.delete().where(SociosCuentasBanco.socio==id)
|
q = SociosCuentasBanco.delete().where(SociosCuentasBanco.socio==id)
|
||||||
q.execute()
|
q.execute()
|
||||||
|
q = SociosRegimenes.delete().where(SociosRegimenes.socio==id)
|
||||||
|
q.execute()
|
||||||
q = Socios.delete().where(Socios.id==id)
|
q = Socios.delete().where(Socios.id==id)
|
||||||
return bool(q.execute())
|
return bool(q.execute())
|
||||||
|
|
||||||
|
@ -3040,6 +3089,52 @@ class SociosCuentasBanco(BaseModel):
|
||||||
return account.socio == invoice.cliente
|
return account.socio == invoice.cliente
|
||||||
|
|
||||||
|
|
||||||
|
class SociosRegimenes(BaseModel):
|
||||||
|
socio = ForeignKeyField(Socios)
|
||||||
|
regimen = ForeignKeyField(SATRegimenes)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
indexes = (
|
||||||
|
(('socio', 'regimen'), True),
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_by_key(cls, socio, user=None):
|
||||||
|
fields = (SATRegimenes.key.alias('id'), SATRegimenes.name.alias('value'))
|
||||||
|
where = (SociosRegimenes.socio == socio)
|
||||||
|
regimenes = (SociosRegimenes
|
||||||
|
.select(*fields)
|
||||||
|
.where(where)
|
||||||
|
.join(SATRegimenes).switch(SociosRegimenes)
|
||||||
|
.dicts()
|
||||||
|
)
|
||||||
|
return tuple(regimenes)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_by_socio(cls, socio, user=None):
|
||||||
|
fields = (SATRegimenes.id,)
|
||||||
|
where = (SociosRegimenes.socio == socio)
|
||||||
|
regimenes = (SociosRegimenes
|
||||||
|
.select(*fields)
|
||||||
|
.where(where)
|
||||||
|
.join(SATRegimenes).switch(SociosRegimenes)
|
||||||
|
.tuples()
|
||||||
|
)
|
||||||
|
regimenes = [r[0] for r in regimenes]
|
||||||
|
return regimenes
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _get_by_id(cls, filters, user):
|
||||||
|
id = int(filters['id'])
|
||||||
|
return cls.get_by_key(id)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_data(cls, filters, user):
|
||||||
|
# ~ print('FILERS', filters)
|
||||||
|
opt = filters['opt']
|
||||||
|
return getattr(cls, f'_get_{opt}')(filters, user)
|
||||||
|
|
||||||
|
|
||||||
class Contactos(BaseModel):
|
class Contactos(BaseModel):
|
||||||
socio = ForeignKeyField(Socios)
|
socio = ForeignKeyField(Socios)
|
||||||
titulo = ForeignKeyField(TipoTitulo)
|
titulo = ForeignKeyField(TipoTitulo)
|
||||||
|
@ -3615,7 +3710,6 @@ class Sucursales(BaseModel):
|
||||||
def _create(cls, args):
|
def _create(cls, args):
|
||||||
try:
|
try:
|
||||||
values = utils.loads(args)
|
values = utils.loads(args)
|
||||||
print(values)
|
|
||||||
Sucursales.create(**values)
|
Sucursales.create(**values)
|
||||||
result = {'ok': True}
|
result = {'ok': True}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -3806,6 +3900,7 @@ class Productos(BaseModel):
|
||||||
cantidad_empaque = DecimalField(default=0.0, max_digits=14, decimal_places=4,
|
cantidad_empaque = DecimalField(default=0.0, max_digits=14, decimal_places=4,
|
||||||
auto_round=True)
|
auto_round=True)
|
||||||
is_discontinued = BooleanField(default=False)
|
is_discontinued = BooleanField(default=False)
|
||||||
|
objeto_impuesto = TextField(default='02')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
order_by = ('descripcion',)
|
order_by = ('descripcion',)
|
||||||
|
@ -3829,6 +3924,7 @@ class Productos(BaseModel):
|
||||||
Productos.descuento,
|
Productos.descuento,
|
||||||
Productos.inventario,
|
Productos.inventario,
|
||||||
Productos.existencia,
|
Productos.existencia,
|
||||||
|
Productos.objeto_impuesto,
|
||||||
)
|
)
|
||||||
where = (
|
where = (
|
||||||
(Productos.es_activo==True) &
|
(Productos.es_activo==True) &
|
||||||
|
@ -3908,7 +4004,8 @@ class Productos(BaseModel):
|
||||||
Productos.valor_unitario,
|
Productos.valor_unitario,
|
||||||
Productos.descuento,
|
Productos.descuento,
|
||||||
Productos.inventario,
|
Productos.inventario,
|
||||||
Productos.existencia)
|
Productos.existencia,
|
||||||
|
Productos.objeto_impuesto)
|
||||||
.join(SATUnidades).switch(Productos)
|
.join(SATUnidades).switch(Productos)
|
||||||
.where((Productos.es_activo==True) &
|
.where((Productos.es_activo==True) &
|
||||||
((Productos.clave==clave) | (Productos.codigo_barras==clave)))
|
((Productos.clave==clave) | (Productos.codigo_barras==clave)))
|
||||||
|
@ -4081,7 +4178,8 @@ class Productos(BaseModel):
|
||||||
Productos.inventario,
|
Productos.inventario,
|
||||||
Productos.existencia,
|
Productos.existencia,
|
||||||
Productos.minimo,
|
Productos.minimo,
|
||||||
Productos.cantidad_empaque.alias('cant_by_packing'),
|
Productos.objeto_impuesto,
|
||||||
|
# ~ Productos.cantidad_empaque.alias('cant_by_packing'),
|
||||||
)
|
)
|
||||||
.where(Productos.id==id).dicts()[0]
|
.where(Productos.id==id).dicts()[0]
|
||||||
)
|
)
|
||||||
|
@ -4344,7 +4442,7 @@ class RangosPrecios(BaseModel):
|
||||||
|
|
||||||
class Facturas(BaseModel):
|
class Facturas(BaseModel):
|
||||||
cliente = ForeignKeyField(Socios)
|
cliente = ForeignKeyField(Socios)
|
||||||
version = TextField(default=CURRENT_CFDI)
|
version = TextField(default=PRE_DEFAULT['CFDI']['VERSION'])
|
||||||
serie = TextField(default='')
|
serie = TextField(default='')
|
||||||
folio = BigIntegerField(default=0)
|
folio = BigIntegerField(default=0)
|
||||||
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
|
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
|
||||||
|
@ -4389,6 +4487,9 @@ class Facturas(BaseModel):
|
||||||
egreso_anticipo = BooleanField(default=False)
|
egreso_anticipo = BooleanField(default=False)
|
||||||
tipo_relacion = TextField(default='')
|
tipo_relacion = TextField(default='')
|
||||||
error = TextField(default='')
|
error = TextField(default='')
|
||||||
|
exportacion = TextField(default='01')
|
||||||
|
receptor_regimen = TextField(default='')
|
||||||
|
periodicidad = TextField(default='')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
order_by = ('fecha',)
|
order_by = ('fecha',)
|
||||||
|
@ -4620,23 +4721,33 @@ class Facturas(BaseModel):
|
||||||
obj = SATTipoRelacion.get(SATTipoRelacion.key==invoice.tipo_relacion)
|
obj = SATTipoRelacion.get(SATTipoRelacion.key==invoice.tipo_relacion)
|
||||||
values['tiporelacion'] = str(obj)
|
values['tiporelacion'] = str(obj)
|
||||||
|
|
||||||
receptor = Socios.select().where(Socios.id==invoice.cliente.id).dicts()[0]
|
# ~ use_packing = Configuracion.get_bool('chk_use_packing')
|
||||||
values['receptor'] = {}
|
# ~ if use_packing:
|
||||||
for k, v in receptor.items():
|
# ~ w = FacturasDetalle.factura == invoice
|
||||||
values['receptor'][k] = v
|
# ~ q = (FacturasDetalle
|
||||||
|
# ~ .select(FacturasDetalle.empaques)
|
||||||
use_packing = Configuracion.get_bool('chk_use_packing')
|
# ~ .where(w)
|
||||||
if use_packing:
|
# ~ .order_by(FacturasDetalle.id.asc())
|
||||||
w = FacturasDetalle.factura == invoice
|
# ~ .tuples())
|
||||||
q = (FacturasDetalle
|
# ~ values['pakings'] = [str(int(r[0])) for r in q]
|
||||||
.select(FacturasDetalle.empaques)
|
|
||||||
.where(w)
|
|
||||||
.order_by(FacturasDetalle.id.asc())
|
|
||||||
.tuples())
|
|
||||||
values['pakings'] = [str(int(r[0])) for r in q]
|
|
||||||
|
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
def _get_not_in_xml2(self, invoice, data):
|
||||||
|
fields = (
|
||||||
|
Socios.calle,
|
||||||
|
Socios.no_exterior,
|
||||||
|
Socios.no_interior,
|
||||||
|
Socios.colonia,
|
||||||
|
Socios.municipio,
|
||||||
|
Socios.estado,
|
||||||
|
Socios.pais,
|
||||||
|
)
|
||||||
|
where = (Socios.id==invoice.cliente.id)
|
||||||
|
partner = Socios.select(*fields).where(where).dicts()[0]
|
||||||
|
data['receptor'].update(partner)
|
||||||
|
return
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_pdf(cls, id, rfc, sync=True):
|
def get_pdf(cls, id, rfc, sync=True):
|
||||||
try:
|
try:
|
||||||
|
@ -4654,7 +4765,9 @@ class Facturas(BaseModel):
|
||||||
|
|
||||||
#Tmp to v2
|
#Tmp to v2
|
||||||
data = util.get_data_from_xml(obj, values, pdf_from)
|
data = util.get_data_from_xml(obj, values, pdf_from)
|
||||||
|
|
||||||
data.update(utils.CfdiToDict(obj.xml).values)
|
data.update(utils.CfdiToDict(obj.xml).values)
|
||||||
|
cls._get_not_in_xml2(cls, obj, data)
|
||||||
|
|
||||||
doc = util.to_pdf(data, emisor.rfc, pdf_from=pdf_from)
|
doc = util.to_pdf(data, emisor.rfc, pdf_from=pdf_from)
|
||||||
|
|
||||||
|
@ -5021,7 +5134,9 @@ class Facturas(BaseModel):
|
||||||
'id': obj.cliente.id,
|
'id': obj.cliente.id,
|
||||||
'nombre': obj.cliente.nombre,
|
'nombre': obj.cliente.nombre,
|
||||||
'rfc': obj.cliente.rfc,
|
'rfc': obj.cliente.rfc,
|
||||||
|
'codigo_postal': obj.cliente.codigo_postal,
|
||||||
'notas': obj.notas,
|
'notas': obj.notas,
|
||||||
|
'regimenes': SociosRegimenes.get_by_key(obj.cliente.id)
|
||||||
}
|
}
|
||||||
invoice = {
|
invoice = {
|
||||||
'tipo_comprobante': obj.tipo_comprobante,
|
'tipo_comprobante': obj.tipo_comprobante,
|
||||||
|
@ -5197,12 +5312,11 @@ class Facturas(BaseModel):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def _calculate_totals(self, invoice, products, tipo_comprobante, user):
|
def _calculate_totals(self, invoice, products, tipo_comprobante, user):
|
||||||
tax_locales = Configuracion.get_bool('chk_config_tax_locales')
|
tax_locales = Configuracion.get_bool('chk_config_tax_locales')
|
||||||
tax_locales_truncate = Configuracion.get_bool('chk_config_tax_locales_truncate')
|
tax_locales_truncate = Configuracion.get_bool('chk_config_tax_locales_truncate')
|
||||||
tax_decimals = Configuracion.get_bool('chk_config_tax_decimals')
|
tax_decimals = Configuracion.get_bool('chk_config_tax_decimals')
|
||||||
use_packing = Configuracion.get_bool('chk_use_packing')
|
# ~ use_packing = Configuracion.get_bool('chk_use_packing')
|
||||||
|
|
||||||
subtotal = 0
|
subtotal = 0
|
||||||
descuento_cfdi = 0
|
descuento_cfdi = 0
|
||||||
|
@ -5237,9 +5351,9 @@ class Facturas(BaseModel):
|
||||||
precio_final = valor_unitario - descuento
|
precio_final = valor_unitario - descuento
|
||||||
importe = round(cantidad * precio_final, DECIMALES)
|
importe = round(cantidad * precio_final, DECIMALES)
|
||||||
|
|
||||||
if use_packing and p.cantidad_empaque:
|
# ~ if use_packing and p.cantidad_empaque:
|
||||||
product['empaques'] = utils.round_up(
|
# ~ product['empaques'] = utils.round_up(
|
||||||
cantidad / float(p.cantidad_empaque))
|
# ~ cantidad / float(p.cantidad_empaque))
|
||||||
|
|
||||||
product['cantidad'] = cantidad
|
product['cantidad'] = cantidad
|
||||||
product['valor_unitario'] = valor_unitario
|
product['valor_unitario'] = valor_unitario
|
||||||
|
@ -5519,7 +5633,14 @@ class Facturas(BaseModel):
|
||||||
tax_decimals = Configuracion.get_bool('chk_config_tax_decimals')
|
tax_decimals = Configuracion.get_bool('chk_config_tax_decimals')
|
||||||
decimales_precios = Configuracion.get_bool('chk_config_decimales_precios')
|
decimales_precios = Configuracion.get_bool('chk_config_decimales_precios')
|
||||||
invoice_by_ticket = Configuracion.get_bool('chk_config_invoice_by_ticket')
|
invoice_by_ticket = Configuracion.get_bool('chk_config_invoice_by_ticket')
|
||||||
is_global = (invoice.cliente.rfc == RFCS['PUBLIC']) and invoice_by_ticket
|
is_global = bool(invoice.periodicidad)
|
||||||
|
|
||||||
|
data_global = {}
|
||||||
|
if is_global:
|
||||||
|
now = utils.now()
|
||||||
|
data_global['Periodicidad'] = invoice.periodicidad
|
||||||
|
data_global['Meses'] = now.strftime('%m')
|
||||||
|
data_global['Año'] = now.strftime('%Y')
|
||||||
|
|
||||||
frm_vu = FORMAT
|
frm_vu = FORMAT
|
||||||
if decimales_precios:
|
if decimales_precios:
|
||||||
|
@ -5586,11 +5707,15 @@ class Facturas(BaseModel):
|
||||||
'Nombre': emisor.nombre,
|
'Nombre': emisor.nombre,
|
||||||
'RegimenFiscal': invoice.regimen_fiscal,
|
'RegimenFiscal': invoice.regimen_fiscal,
|
||||||
}
|
}
|
||||||
|
|
||||||
receptor = {
|
receptor = {
|
||||||
'Rfc': invoice.cliente.rfc,
|
'Rfc': invoice.cliente.rfc,
|
||||||
'Nombre': invoice.cliente.nombre,
|
'Nombre': invoice.cliente.nombre,
|
||||||
'UsoCFDI': invoice.uso_cfdi,
|
'UsoCFDI': invoice.uso_cfdi,
|
||||||
|
'DomicilioFiscalReceptor': invoice.cliente.codigo_postal,
|
||||||
|
'RegimenFiscalReceptor': invoice.receptor_regimen
|
||||||
}
|
}
|
||||||
|
|
||||||
if invoice.cliente.tipo_persona == 4:
|
if invoice.cliente.tipo_persona == 4:
|
||||||
if invoice.cliente.pais:
|
if invoice.cliente.pais:
|
||||||
receptor['ResidenciaFiscal'] = invoice.cliente.pais
|
receptor['ResidenciaFiscal'] = invoice.cliente.pais
|
||||||
|
@ -5612,11 +5737,13 @@ class Facturas(BaseModel):
|
||||||
'NoIdentificacion': key,
|
'NoIdentificacion': key,
|
||||||
'Cantidad': FORMAT.format(row.cantidad),
|
'Cantidad': FORMAT.format(row.cantidad),
|
||||||
'ClaveUnidad': row.unidad,
|
'ClaveUnidad': row.unidad,
|
||||||
'Unidad': SATUnidades.get(SATUnidades.key==row.unidad).name[:20],
|
|
||||||
'Descripcion': row.descripcion,
|
'Descripcion': row.descripcion,
|
||||||
'ValorUnitario': frm_vu.format(row.valor_unitario),
|
'ValorUnitario': frm_vu.format(row.valor_unitario),
|
||||||
'Importe': FORMAT.format(row.importe),
|
'Importe': FORMAT.format(row.importe),
|
||||||
}
|
}
|
||||||
|
if not is_global:
|
||||||
|
concepto['Unidad'] = SATUnidades.get(SATUnidades.key==row.unidad).name[:20]
|
||||||
|
|
||||||
if row.descuento:
|
if row.descuento:
|
||||||
concepto['Descuento'] = FORMAT.format(row.descuento)
|
concepto['Descuento'] = FORMAT.format(row.descuento)
|
||||||
|
|
||||||
|
@ -5701,6 +5828,16 @@ class Facturas(BaseModel):
|
||||||
taxes['retenciones'] = retenciones
|
taxes['retenciones'] = retenciones
|
||||||
|
|
||||||
concepto['impuestos'] = taxes
|
concepto['impuestos'] = taxes
|
||||||
|
|
||||||
|
# cfdi4
|
||||||
|
if not is_global:
|
||||||
|
concepto['ObjetoImp'] = row.producto.objeto_impuesto
|
||||||
|
else:
|
||||||
|
if taxes:
|
||||||
|
concepto['ObjetoImp'] = '02'
|
||||||
|
else:
|
||||||
|
concepto['ObjetoImp'] = '01'
|
||||||
|
|
||||||
conceptos.append(concepto)
|
conceptos.append(concepto)
|
||||||
|
|
||||||
impuestos = {}
|
impuestos = {}
|
||||||
|
@ -5749,11 +5886,14 @@ class Facturas(BaseModel):
|
||||||
|
|
||||||
if tax_decimals:
|
if tax_decimals:
|
||||||
xml_importe = FORMAT_TAX.format(tax.importe)
|
xml_importe = FORMAT_TAX.format(tax.importe)
|
||||||
|
xml_tax_base = FORMAT_TAX.format(tax.base)
|
||||||
else:
|
else:
|
||||||
xml_importe = FORMAT.format(tax.importe)
|
xml_importe = FORMAT.format(tax.importe)
|
||||||
|
xml_tax_base = FORMAT.format(tax.base)
|
||||||
|
|
||||||
if tax.impuesto.tipo == 'T':
|
if tax.impuesto.tipo == 'T':
|
||||||
traslado = {
|
traslado = {
|
||||||
|
"Base": xml_tax_base,
|
||||||
"Impuesto": tax.impuesto.key,
|
"Impuesto": tax.impuesto.key,
|
||||||
"TipoFactor": tipo_factor,
|
"TipoFactor": tipo_factor,
|
||||||
"TasaOCuota": str(tax.impuesto.tasa),
|
"TasaOCuota": str(tax.impuesto.tasa),
|
||||||
|
@ -5793,6 +5933,7 @@ class Facturas(BaseModel):
|
||||||
'donativo': donativo,
|
'donativo': donativo,
|
||||||
'edu': is_edu,
|
'edu': is_edu,
|
||||||
'complementos': complementos,
|
'complementos': complementos,
|
||||||
|
'global': data_global,
|
||||||
}
|
}
|
||||||
|
|
||||||
return utils.make_xml(data, certificado)
|
return utils.make_xml(data, certificado)
|
||||||
|
@ -6434,7 +6575,7 @@ class PreFacturas(BaseModel):
|
||||||
}
|
}
|
||||||
|
|
||||||
data['comprobante'] = obj
|
data['comprobante'] = obj
|
||||||
data['comprobante']['version'] = CURRENT_CFDI
|
data['comprobante']['version'] = PRE_DEFAULT['CFDI']['VERSION']
|
||||||
data['comprobante']['folio'] = str(data['comprobante']['folio'])
|
data['comprobante']['folio'] = str(data['comprobante']['folio'])
|
||||||
data['comprobante']['seriefolio'] = '{}-{}'.format(
|
data['comprobante']['seriefolio'] = '{}-{}'.format(
|
||||||
data['comprobante']['serie'], data['comprobante']['folio'])
|
data['comprobante']['serie'], data['comprobante']['folio'])
|
||||||
|
@ -6893,6 +7034,8 @@ class PreFacturasDetalle(BaseModel):
|
||||||
'rfc': q.cliente.rfc,
|
'rfc': q.cliente.rfc,
|
||||||
'forma_pago': q.forma_pago,
|
'forma_pago': q.forma_pago,
|
||||||
'uso_cfdi': q.uso_cfdi,
|
'uso_cfdi': q.uso_cfdi,
|
||||||
|
'codigo_postal': q.cliente.codigo_postal,
|
||||||
|
'regimenes': SociosRegimenes.get_by_key(q.cliente.id),
|
||||||
'notas': q.notas,
|
'notas': q.notas,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7140,6 +7283,7 @@ class CfdiPagos(BaseModel):
|
||||||
error = TextField(default='')
|
error = TextField(default='')
|
||||||
cancelada = BooleanField(default=False)
|
cancelada = BooleanField(default=False)
|
||||||
fecha_cancelacion = DateTimeField(null=True)
|
fecha_cancelacion = DateTimeField(null=True)
|
||||||
|
receptor_regimen = TextField(default='')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
order_by = ('movimiento',)
|
order_by = ('movimiento',)
|
||||||
|
@ -7263,6 +7407,7 @@ class CfdiPagos(BaseModel):
|
||||||
|
|
||||||
partner = related[0].factura.cliente
|
partner = related[0].factura.cliente
|
||||||
partner_name = related[0].factura.cliente.nombre
|
partner_name = related[0].factura.cliente.nombre
|
||||||
|
receptor_regimen = related[0].factura.receptor_regimen
|
||||||
|
|
||||||
emisor = Emisor.select()[0]
|
emisor = Emisor.select()[0]
|
||||||
# ~ regimen_fiscal = related[0].factura.regimen_fiscal
|
# ~ regimen_fiscal = related[0].factura.regimen_fiscal
|
||||||
|
@ -7302,6 +7447,7 @@ class CfdiPagos(BaseModel):
|
||||||
fields['folio'] = self._get_folio(self, serie)
|
fields['folio'] = self._get_folio(self, serie)
|
||||||
fields['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
fields['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
||||||
fields['regimen_fiscal'] = regimen_fiscal
|
fields['regimen_fiscal'] = regimen_fiscal
|
||||||
|
fields['receptor_regimen'] = receptor_regimen
|
||||||
|
|
||||||
with database_proxy.atomic() as txn:
|
with database_proxy.atomic() as txn:
|
||||||
obj = CfdiPagos.create(**fields)
|
obj = CfdiPagos.create(**fields)
|
||||||
|
@ -7319,7 +7465,92 @@ class CfdiPagos(BaseModel):
|
||||||
data = {'ok': True, 'row': row, 'new': True}
|
data = {'ok': True, 'row': row, 'new': True}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def _get_taxes_by_pay(self, pay, taxes_pay):
|
||||||
|
invoice = Facturas.get(Facturas.uuid==pay['IdDocumento'])
|
||||||
|
impuestos = {}
|
||||||
|
traslados = []
|
||||||
|
retenciones = []
|
||||||
|
|
||||||
|
where = (FacturasImpuestos.factura==invoice)
|
||||||
|
taxes = FacturasImpuestos.select().where(where)
|
||||||
|
|
||||||
|
tax_proporcion = pay['ImpPagado'] / invoice.total
|
||||||
|
# ~ print('Total', invoice.total)
|
||||||
|
# ~ print('Pagado', pay['ImpPagado'])
|
||||||
|
# ~ print('proporcion', tax_proporcion)
|
||||||
|
|
||||||
|
for tax in taxes:
|
||||||
|
if tax.impuesto.key == '000':
|
||||||
|
# ~ tasa = str(round(tax.impuesto.tasa * 100, 2))
|
||||||
|
# ~ simporte = FORMAT.format(tax.importe)
|
||||||
|
# ~ if tax.impuesto.tipo == 'T':
|
||||||
|
# ~ traslado = {
|
||||||
|
# ~ 'ImpLocTrasladado': tax.impuesto.name,
|
||||||
|
# ~ 'TasadeTraslado': tasa,
|
||||||
|
# ~ 'Importe': simporte,
|
||||||
|
# ~ }
|
||||||
|
# ~ locales_trasladados.append(traslado)
|
||||||
|
# ~ total_locales_trasladados += tax.importe
|
||||||
|
# ~ else:
|
||||||
|
# ~ retencion = {
|
||||||
|
# ~ 'ImpLocRetenido': tax.impuesto.name,
|
||||||
|
# ~ 'TasadeRetencion': tasa,
|
||||||
|
# ~ 'Importe': simporte,
|
||||||
|
# ~ }
|
||||||
|
# ~ locales_retenciones.append(retencion)
|
||||||
|
# ~ total_locales_retenciones += tax.importe
|
||||||
|
continue
|
||||||
|
|
||||||
|
tipo_factor = 'Tasa'
|
||||||
|
if tax.impuesto.factor != 'T':
|
||||||
|
tipo_factor = 'Cuota'
|
||||||
|
|
||||||
|
import_dr = round(tax.importe * tax_proporcion, 2)
|
||||||
|
# ~ xml_importe = FORMAT.format(tax.importe)
|
||||||
|
xml_importe = FORMAT.format(import_dr)
|
||||||
|
base_dr = round(tax.base * tax_proporcion, 2)
|
||||||
|
# ~ xml_tax_base = FORMAT.format(tax.base)
|
||||||
|
xml_tax_base = FORMAT.format(base_dr)
|
||||||
|
|
||||||
|
values = {
|
||||||
|
"BaseDR": xml_tax_base,
|
||||||
|
"ImpuestoDR": tax.impuesto.key,
|
||||||
|
"TipoFactorDR": tipo_factor,
|
||||||
|
"TasaOCuotaDR": str(tax.impuesto.tasa),
|
||||||
|
"ImporteDR": xml_importe,
|
||||||
|
}
|
||||||
|
tax_key = tax.impuesto.key
|
||||||
|
if tax.impuesto.tipo == 'T':
|
||||||
|
traslados.append(values)
|
||||||
|
if tax_key in taxes_pay['traslados']:
|
||||||
|
# ~ taxes_pay['traslados'][tax_key]['ImporteP'] += tax.importe
|
||||||
|
taxes_pay['traslados'][tax_key]['ImporteP'] += import_dr
|
||||||
|
else:
|
||||||
|
values = {
|
||||||
|
# ~ "BaseP": tax.base,
|
||||||
|
"BaseP": base_dr,
|
||||||
|
"ImpuestoP": tax.impuesto.key,
|
||||||
|
"TipoFactorP": tipo_factor,
|
||||||
|
"TasaOCuotaP": str(tax.impuesto.tasa),
|
||||||
|
# ~ "ImporteP": tax.importe,
|
||||||
|
"ImporteP": import_dr,
|
||||||
|
}
|
||||||
|
taxes_pay['traslados'][tax_key] = values
|
||||||
|
else:
|
||||||
|
retenciones.append(values)
|
||||||
|
if tax_key in taxes_pay['retenciones']:
|
||||||
|
taxes_pay['retenciones'][tax_key] += tax.importe
|
||||||
|
else:
|
||||||
|
taxes_pay['retenciones'][tax_key] = tax.importe
|
||||||
|
|
||||||
|
impuestos['traslados'] = traslados
|
||||||
|
impuestos['retenciones'] = retenciones
|
||||||
|
|
||||||
|
return impuestos
|
||||||
|
|
||||||
def _get_related_xml(self, id_mov, currency):
|
def _get_related_xml(self, id_mov, currency):
|
||||||
|
TAX_IVA_16 = '002|0.160000'
|
||||||
|
|
||||||
filters = (FacturasPagos.movimiento==id_mov)
|
filters = (FacturasPagos.movimiento==id_mov)
|
||||||
related = tuple(FacturasPagos.select(
|
related = tuple(FacturasPagos.select(
|
||||||
Facturas.uuid.alias('IdDocumento'),
|
Facturas.uuid.alias('IdDocumento'),
|
||||||
|
@ -7336,13 +7567,21 @@ class CfdiPagos(BaseModel):
|
||||||
.where(filters)
|
.where(filters)
|
||||||
.dicts())
|
.dicts())
|
||||||
|
|
||||||
|
taxes_pay = {'retenciones': {}, 'traslados': {}, 'totales': {}}
|
||||||
|
|
||||||
for r in related:
|
for r in related:
|
||||||
|
r['taxes'] = self._get_taxes_by_pay(self, r, taxes_pay)
|
||||||
# ~ print('\n\nMONEDA', currency, r['MonedaDR'])
|
# ~ print('\n\nMONEDA', currency, r['MonedaDR'])
|
||||||
r['IdDocumento'] = str(r['IdDocumento'])
|
r['IdDocumento'] = str(r['IdDocumento'])
|
||||||
r['Folio'] = str(r['Folio'])
|
r['Folio'] = str(r['Folio'])
|
||||||
r['NumParcialidad'] = str(r['NumParcialidad'])
|
r['NumParcialidad'] = str(r['NumParcialidad'])
|
||||||
r['TipoCambioDR'] = FORMAT6.format(r['TipoCambioDR'])
|
r['TipoCambioDR'] = FORMAT6.format(r['TipoCambioDR'])
|
||||||
r['MetodoDePagoDR'] = DEFAULT_CFDIPAY['WAYPAY']
|
# ~ r['MetodoDePagoDR'] = DEFAULT_CFDIPAY['WAYPAY']
|
||||||
|
|
||||||
|
# REVISAR
|
||||||
|
r['EquivalenciaDR'] = '1'
|
||||||
|
r['ObjetoImpDR'] = '02'
|
||||||
|
|
||||||
r['ImpSaldoAnt'] = FORMAT.format(r['ImpSaldoAnt'])
|
r['ImpSaldoAnt'] = FORMAT.format(r['ImpSaldoAnt'])
|
||||||
r['ImpPagado'] = FORMAT.format(r['ImpPagado'])
|
r['ImpPagado'] = FORMAT.format(r['ImpPagado'])
|
||||||
if round(r['ImpSaldoInsoluto'], 2) == 0.0:
|
if round(r['ImpSaldoInsoluto'], 2) == 0.0:
|
||||||
|
@ -7354,7 +7593,28 @@ class CfdiPagos(BaseModel):
|
||||||
if not r['Serie']:
|
if not r['Serie']:
|
||||||
del r['Serie']
|
del r['Serie']
|
||||||
|
|
||||||
return related
|
total_tax_iva_16_base = 0
|
||||||
|
total_tax_iva_16_importe = 0
|
||||||
|
|
||||||
|
for key, importe in taxes_pay['retenciones'].items():
|
||||||
|
taxes_pay['retenciones'][key] = FORMAT.format(importe)
|
||||||
|
for k, tax in taxes_pay['traslados'].items():
|
||||||
|
tax_type = taxes_pay['traslados'][k]['ImpuestoP']
|
||||||
|
tax_tasa = taxes_pay['traslados'][k]['TasaOCuotaP']
|
||||||
|
tax_base = taxes_pay['traslados'][k]['BaseP']
|
||||||
|
importe = taxes_pay['traslados'][k]['ImporteP']
|
||||||
|
if f'{tax_type}|{tax_tasa}' == TAX_IVA_16:
|
||||||
|
total_tax_iva_16_base += tax_base
|
||||||
|
total_tax_iva_16_importe += importe
|
||||||
|
taxes_pay['traslados'][k]['BaseP'] = FORMAT.format(tax_base)
|
||||||
|
taxes_pay['traslados'][k]['ImporteP'] = FORMAT.format(importe)
|
||||||
|
|
||||||
|
taxes_pay['totales'] = {
|
||||||
|
'TotalTrasladosBaseIVA16': FORMAT.format(total_tax_iva_16_base),
|
||||||
|
'TotalTrasladosImpuestoIVA16': FORMAT.format(total_tax_iva_16_importe),
|
||||||
|
}
|
||||||
|
|
||||||
|
return related, taxes_pay
|
||||||
|
|
||||||
def _generate_xml(self, invoice):
|
def _generate_xml(self, invoice):
|
||||||
emisor = Emisor.select()[0]
|
emisor = Emisor.select()[0]
|
||||||
|
@ -7367,9 +7627,9 @@ class CfdiPagos(BaseModel):
|
||||||
cfdi['Folio'] = str(invoice.folio)
|
cfdi['Folio'] = str(invoice.folio)
|
||||||
cfdi['Fecha'] = invoice.fecha.isoformat()[:19]
|
cfdi['Fecha'] = invoice.fecha.isoformat()[:19]
|
||||||
cfdi['NoCertificado'] = certificado.serie
|
cfdi['NoCertificado'] = certificado.serie
|
||||||
# ~ cfdi['Certificado'] = cert.cer_txt
|
|
||||||
cfdi['SubTotal'] = '0'
|
cfdi['SubTotal'] = '0'
|
||||||
cfdi['Moneda'] = DEFAULT_CFDIPAY['CURRENCY']
|
cfdi['Moneda'] = DEFAULT_CFDIPAY['CURRENCY']
|
||||||
|
# ~ cfdi['TipoCambio'] = DEFAULT_CFDIPAY['TC']
|
||||||
cfdi['Total'] = '0'
|
cfdi['Total'] = '0'
|
||||||
cfdi['TipoDeComprobante'] = invoice.tipo_comprobante
|
cfdi['TipoDeComprobante'] = invoice.tipo_comprobante
|
||||||
cfdi['LugarExpedicion'] = invoice.lugar_expedicion
|
cfdi['LugarExpedicion'] = invoice.lugar_expedicion
|
||||||
|
@ -7390,6 +7650,8 @@ class CfdiPagos(BaseModel):
|
||||||
'Rfc': invoice.socio.rfc,
|
'Rfc': invoice.socio.rfc,
|
||||||
'Nombre': invoice.socio.nombre,
|
'Nombre': invoice.socio.nombre,
|
||||||
'UsoCFDI': DEFAULT_CFDIPAY['USED'],
|
'UsoCFDI': DEFAULT_CFDIPAY['USED'],
|
||||||
|
'DomicilioFiscalReceptor': invoice.socio.codigo_postal,
|
||||||
|
'RegimenFiscalReceptor': invoice.receptor_regimen
|
||||||
}
|
}
|
||||||
if invoice.socio.tipo_persona == 4:
|
if invoice.socio.tipo_persona == 4:
|
||||||
if invoice.socio.pais:
|
if invoice.socio.pais:
|
||||||
|
@ -7404,19 +7666,23 @@ class CfdiPagos(BaseModel):
|
||||||
'Descripcion': DEFAULT_CFDIPAY['DESCRIPTION'],
|
'Descripcion': DEFAULT_CFDIPAY['DESCRIPTION'],
|
||||||
'ValorUnitario': '0',
|
'ValorUnitario': '0',
|
||||||
'Importe': '0',
|
'Importe': '0',
|
||||||
|
'ObjetoImp': '01',
|
||||||
},)
|
},)
|
||||||
|
|
||||||
impuestos = {}
|
impuestos = {}
|
||||||
|
|
||||||
mov = invoice.movimiento
|
mov = invoice.movimiento
|
||||||
currency = mov.moneda
|
currency = mov.moneda
|
||||||
related_docs = self._get_related_xml(self, invoice.movimiento, currency)
|
related_docs, taxes_pay = self._get_related_xml(self, invoice.movimiento, currency)
|
||||||
|
totales = taxes_pay.pop('totales')
|
||||||
pagos = {
|
pagos = {
|
||||||
'FechaPago': mov.fecha.isoformat()[:19],
|
'FechaPago': mov.fecha.isoformat()[:19],
|
||||||
'FormaDePagoP': mov.forma_pago.key,
|
'FormaDePagoP': mov.forma_pago.key,
|
||||||
'MonedaP': currency,
|
'MonedaP': currency,
|
||||||
|
'TipoCambioP': '1',
|
||||||
'Monto': FORMAT.format(mov.deposito),
|
'Monto': FORMAT.format(mov.deposito),
|
||||||
'relacionados': related_docs,
|
'relacionados': related_docs,
|
||||||
|
'taxes_pay': taxes_pay,
|
||||||
}
|
}
|
||||||
if mov.numero_operacion:
|
if mov.numero_operacion:
|
||||||
pagos['NumOperacion'] = mov.numero_operacion
|
pagos['NumOperacion'] = mov.numero_operacion
|
||||||
|
@ -7431,10 +7697,12 @@ class CfdiPagos(BaseModel):
|
||||||
pagos['RfcEmisorCtaBen'] = mov.cuenta.banco.rfc
|
pagos['RfcEmisorCtaBen'] = mov.cuenta.banco.rfc
|
||||||
pagos['CtaBeneficiario'] = mov.cuenta.cuenta
|
pagos['CtaBeneficiario'] = mov.cuenta.cuenta
|
||||||
|
|
||||||
|
|
||||||
if currency != CURRENCY_MN:
|
if currency != CURRENCY_MN:
|
||||||
pagos['TipoCambioP'] = FORMAT_TAX.format(mov.tipo_cambio)
|
pagos['TipoCambioP'] = FORMAT_TAX.format(mov.tipo_cambio)
|
||||||
|
|
||||||
|
totales['MontoTotalPagos'] = pagos['Monto']
|
||||||
|
pagos['totales'] = totales
|
||||||
|
|
||||||
complementos = {'pagos': pagos}
|
complementos = {'pagos': pagos}
|
||||||
data = {
|
data = {
|
||||||
'comprobante': cfdi,
|
'comprobante': cfdi,
|
||||||
|
@ -7446,6 +7714,7 @@ class CfdiPagos(BaseModel):
|
||||||
'donativo': {},
|
'donativo': {},
|
||||||
'edu': False,
|
'edu': False,
|
||||||
'complementos': complementos,
|
'complementos': complementos,
|
||||||
|
'global': {},
|
||||||
}
|
}
|
||||||
return utils.make_xml(data, certificado)
|
return utils.make_xml(data, certificado)
|
||||||
|
|
||||||
|
@ -7565,6 +7834,8 @@ class CfdiPagos(BaseModel):
|
||||||
target = emisor.rfc + '/' + str(obj.fecha)[:7].replace('-', '/')
|
target = emisor.rfc + '/' + str(obj.fecha)[:7].replace('-', '/')
|
||||||
values = cls._get_not_in_xml(cls, obj, emisor)
|
values = cls._get_not_in_xml(cls, obj, emisor)
|
||||||
data = util.get_data_from_xml(obj, values)
|
data = util.get_data_from_xml(obj, values)
|
||||||
|
data['informacion_global'] = {}
|
||||||
|
|
||||||
obj = SATFormaPago.get(SATFormaPago.key==data['pays']['FormaDePagoP'])
|
obj = SATFormaPago.get(SATFormaPago.key==data['pays']['FormaDePagoP'])
|
||||||
data['pays']['formadepago'] = '{} ({})'.format(obj.name, obj.key)
|
data['pays']['formadepago'] = '{} ({})'.format(obj.name, obj.key)
|
||||||
doc = util.to_pdf(data, emisor.rfc)
|
doc = util.to_pdf(data, emisor.rfc)
|
||||||
|
@ -8167,6 +8438,7 @@ class Tickets(BaseModel):
|
||||||
@classmethod
|
@classmethod
|
||||||
def invoice(cls, values, user):
|
def invoice(cls, values, user):
|
||||||
is_invoice_day = util.get_bool(values['is_invoice_day'])
|
is_invoice_day = util.get_bool(values['is_invoice_day'])
|
||||||
|
periodicidad = values['periodicidad']
|
||||||
id_client = int(values['client'])
|
id_client = int(values['client'])
|
||||||
tickets = util.loads(values['tickets'])
|
tickets = util.loads(values['tickets'])
|
||||||
invoice_by_ticket = Configuracion.get_bool('chk_config_invoice_by_ticket')
|
invoice_by_ticket = Configuracion.get_bool('chk_config_invoice_by_ticket')
|
||||||
|
@ -8183,12 +8455,21 @@ class Tickets(BaseModel):
|
||||||
return data
|
return data
|
||||||
else:
|
else:
|
||||||
client = Socios.get(Socios.id==id_client)
|
client = Socios.get(Socios.id==id_client)
|
||||||
|
periodicidad = ''
|
||||||
|
|
||||||
if client.forma_pago is None:
|
if client.forma_pago is None:
|
||||||
msg = 'La Forma de Pago del cliente, no esta asignada'
|
msg = 'La Forma de Pago del cliente, no esta asignada'
|
||||||
data = {'ok': False, 'msg': msg}
|
data = {'ok': False, 'msg': msg}
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
try:
|
||||||
|
receptor_regimen = SociosRegimenes.get_by_key(client)[0]['id']
|
||||||
|
except Exception as e:
|
||||||
|
log.error(e)
|
||||||
|
msg = 'Error al obtener el Regimen Fiscal del receptor'
|
||||||
|
data = {'ok': False, 'msg': msg}
|
||||||
|
return data
|
||||||
|
|
||||||
payment_type = cls._get_payment_type(cls, tickets)
|
payment_type = cls._get_payment_type(cls, tickets)
|
||||||
|
|
||||||
emisor = Emisor.select()[0]
|
emisor = Emisor.select()[0]
|
||||||
|
@ -8196,15 +8477,13 @@ class Tickets(BaseModel):
|
||||||
data['cliente'] = client
|
data['cliente'] = client
|
||||||
data['serie'] = cls._get_serie(cls, user, True)
|
data['serie'] = cls._get_serie(cls, user, True)
|
||||||
data['folio'] = cls._get_folio_invoice(cls, data['serie'])
|
data['folio'] = cls._get_folio_invoice(cls, data['serie'])
|
||||||
# ~ data['forma_pago'] = client.forma_pago.key
|
|
||||||
data['forma_pago'] = payment_type
|
data['forma_pago'] = payment_type
|
||||||
data['tipo_cambio'] = 1.00
|
data['tipo_cambio'] = 1.00
|
||||||
data['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
data['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
||||||
if client.uso_cfdi is None:
|
data['uso_cfdi'] = client.uso_cfdi.key
|
||||||
data['uso_cfdi'] = 'P01'
|
|
||||||
else:
|
|
||||||
data['uso_cfdi'] = client.uso_cfdi.key
|
|
||||||
data['regimen_fiscal'] = emisor.regimenes[0].key
|
data['regimen_fiscal'] = emisor.regimenes[0].key
|
||||||
|
data['receptor_regimen'] = receptor_regimen
|
||||||
|
data['periodicidad'] = periodicidad
|
||||||
|
|
||||||
with database_proxy.atomic() as txn:
|
with database_proxy.atomic() as txn:
|
||||||
obj = Facturas.create(**data)
|
obj = Facturas.create(**data)
|
||||||
|
@ -8669,6 +8948,7 @@ class Empleados(BaseModel):
|
||||||
codigo_postal = TextField(default='')
|
codigo_postal = TextField(default='')
|
||||||
notas = TextField(default='')
|
notas = TextField(default='')
|
||||||
correo = TextField(default='')
|
correo = TextField(default='')
|
||||||
|
regimen_fiscal = TextField(default='')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
order_by = ('nombre_completo',)
|
order_by = ('nombre_completo',)
|
||||||
|
@ -8720,10 +9000,10 @@ class Empleados(BaseModel):
|
||||||
obj = Empleados.create(**data)
|
obj = Empleados.create(**data)
|
||||||
en += 1
|
en += 1
|
||||||
|
|
||||||
msg = 'Empleados encontrados: {}<BR>'.format(len(rows))
|
msg = 'Empleados:<BR><BR>Encontrados: {}<BR>'.format(len(rows))
|
||||||
msg += 'Empleados nuevos: {}<BR>'.format(en)
|
msg += 'Nuevos: {}<BR>'.format(en)
|
||||||
msg += 'Empleados actualizados: {}<BR>'.format(ea)
|
msg += 'Actualizados: {}<BR>'.format(ea)
|
||||||
msg += 'Empleados no importados: {}'.format(len(rows) - en - ea)
|
msg += 'No importados: {}'.format(len(rows) - en - ea)
|
||||||
return {'ok': True, 'msg': msg}
|
return {'ok': True, 'msg': msg}
|
||||||
|
|
||||||
def _get(self):
|
def _get(self):
|
||||||
|
@ -8755,13 +9035,13 @@ class Empleados(BaseModel):
|
||||||
try:
|
try:
|
||||||
q = Empleados.delete().where(Empleados.id==id)
|
q = Empleados.delete().where(Empleados.id==id)
|
||||||
return bool(q.execute())
|
return bool(q.execute())
|
||||||
except IntegrityError:
|
except Exception as e:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class CfdiNomina(BaseModel):
|
class CfdiNomina(BaseModel):
|
||||||
empleado = ForeignKeyField(Empleados)
|
empleado = ForeignKeyField(Empleados)
|
||||||
version = TextField(default=CURRENT_CFDI)
|
version = TextField(default=PRE_DEFAULT['CFDI']['VERSION'])
|
||||||
serie = TextField(default='N')
|
serie = TextField(default='N')
|
||||||
folio = IntegerField(default=0)
|
folio = IntegerField(default=0)
|
||||||
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
|
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
|
||||||
|
@ -8802,7 +9082,7 @@ class CfdiNomina(BaseModel):
|
||||||
acuse = TextField(default='')
|
acuse = TextField(default='')
|
||||||
tipo_relacion = TextField(default='')
|
tipo_relacion = TextField(default='')
|
||||||
error = TextField(default='')
|
error = TextField(default='')
|
||||||
version_nomina = TextField(default=CURRENT_CFDI_NOMINA)
|
version_nomina = TextField(default=PRE_DEFAULT['NOMINA']['VERSION'])
|
||||||
registro_patronal = TextField(default='')
|
registro_patronal = TextField(default='')
|
||||||
rfc_patron_origen = TextField(default='')
|
rfc_patron_origen = TextField(default='')
|
||||||
tipo_nomina = ForeignKeyField(SATTipoNomina)
|
tipo_nomina = ForeignKeyField(SATTipoNomina)
|
||||||
|
@ -9441,7 +9721,7 @@ class CfdiNomina(BaseModel):
|
||||||
comprobante['Serie'] = cfdi.serie
|
comprobante['Serie'] = cfdi.serie
|
||||||
comprobante['Folio'] = str(cfdi.folio)
|
comprobante['Folio'] = str(cfdi.folio)
|
||||||
comprobante['Fecha'] = cfdi.fecha.isoformat()[:19]
|
comprobante['Fecha'] = cfdi.fecha.isoformat()[:19]
|
||||||
comprobante['FormaPago'] = cfdi.forma_pago
|
# ~ comprobante['FormaPago'] = cfdi.forma_pago
|
||||||
comprobante['NoCertificado'] = certificado.serie
|
comprobante['NoCertificado'] = certificado.serie
|
||||||
comprobante['Certificado'] = certificado.cer_txt
|
comprobante['Certificado'] = certificado.cer_txt
|
||||||
comprobante['SubTotal'] = FORMAT.format(cfdi.subtotal)
|
comprobante['SubTotal'] = FORMAT.format(cfdi.subtotal)
|
||||||
|
@ -9468,6 +9748,8 @@ class CfdiNomina(BaseModel):
|
||||||
receptor = {
|
receptor = {
|
||||||
'Rfc': cfdi.empleado.rfc,
|
'Rfc': cfdi.empleado.rfc,
|
||||||
'Nombre': cfdi.empleado.nombre_completo,
|
'Nombre': cfdi.empleado.nombre_completo,
|
||||||
|
'DomicilioFiscalReceptor': cfdi.empleado.codigo_postal,
|
||||||
|
'RegimenFiscalReceptor': cfdi.empleado.regimen_fiscal,
|
||||||
'UsoCFDI': cfdi.uso_cfdi,
|
'UsoCFDI': cfdi.uso_cfdi,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9481,6 +9763,7 @@ class CfdiNomina(BaseModel):
|
||||||
'Descripcion': row.descripcion,
|
'Descripcion': row.descripcion,
|
||||||
'ValorUnitario': FORMAT.format(row.valor_unitario),
|
'ValorUnitario': FORMAT.format(row.valor_unitario),
|
||||||
'Importe': FORMAT.format(row.importe),
|
'Importe': FORMAT.format(row.importe),
|
||||||
|
'ObjetoImp': '01',
|
||||||
}
|
}
|
||||||
if row.descuento:
|
if row.descuento:
|
||||||
concepto['Descuento'] = FORMAT.format(row.descuento)
|
concepto['Descuento'] = FORMAT.format(row.descuento)
|
||||||
|
@ -9841,7 +10124,11 @@ class CfdiNomina(BaseModel):
|
||||||
return b'', name
|
return b'', name
|
||||||
|
|
||||||
values = cls._get_not_in_xml(cls, obj, emisor)
|
values = cls._get_not_in_xml(cls, obj, emisor)
|
||||||
|
|
||||||
data = util.get_data_from_xml(obj, values)
|
data = util.get_data_from_xml(obj, values)
|
||||||
|
|
||||||
|
data.update(utils.CfdiToDict(obj.xml).values)
|
||||||
|
|
||||||
doc = util.to_pdf(data, emisor.rfc)
|
doc = util.to_pdf(data, emisor.rfc)
|
||||||
|
|
||||||
# ~ if sync:
|
# ~ if sync:
|
||||||
|
@ -10405,10 +10692,10 @@ def authenticate(args):
|
||||||
def get_cp(cp):
|
def get_cp(cp):
|
||||||
con = sqlite3.connect(PATH_CP)
|
con = sqlite3.connect(PATH_CP)
|
||||||
cursor = con.cursor()
|
cursor = con.cursor()
|
||||||
sql = """
|
sql = """SELECT estado, municipio, clave, colonia, key_estado
|
||||||
SELECT colonia, municipio, estado, municipios.id_municipio
|
FROM codigos, colonias, municipios, estados
|
||||||
FROM colonias, municipios, estados
|
WHERE codigos.id_colonia=colonias.id
|
||||||
WHERE colonias.id_municipio=municipios.id
|
AND codigos.id_municipio=municipios.id
|
||||||
AND municipios.id_estado=estados.id
|
AND municipios.id_estado=estados.id
|
||||||
AND cp=?
|
AND cp=?
|
||||||
ORDER BY colonia"""
|
ORDER BY colonia"""
|
||||||
|
@ -10420,15 +10707,18 @@ def get_cp(cp):
|
||||||
data = {}
|
data = {}
|
||||||
if rows:
|
if rows:
|
||||||
data = {
|
data = {
|
||||||
'estado': rows[0][2],
|
'estado': rows[0][0],
|
||||||
'municipio': rows[0][1],
|
'municipio': rows[0][1],
|
||||||
'key_municipio': str(rows[0][3]).zfill(3),
|
'key_municipio': rows[0][2],
|
||||||
|
'key_estado': rows[0][4],
|
||||||
}
|
}
|
||||||
print(data)
|
|
||||||
if len(rows) == 1:
|
if len(rows) == 1:
|
||||||
data['colonia'] = rows[0][0]
|
data['colonia'] = rows[0][3]
|
||||||
else:
|
else:
|
||||||
data['colonia'] = [r[0] for r in rows]
|
data['colonia'] = [r[3] for r in rows]
|
||||||
|
|
||||||
|
print('CP', cp, data)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
@ -10546,6 +10836,7 @@ def _crear_tablas(rfc):
|
||||||
PartnerInvoices,
|
PartnerInvoices,
|
||||||
WareHouseProduct,
|
WareHouseProduct,
|
||||||
SATUnidadesPeso,
|
SATUnidadesPeso,
|
||||||
|
SociosRegimenes,
|
||||||
]
|
]
|
||||||
log.info('Creando tablas...')
|
log.info('Creando tablas...')
|
||||||
database_proxy.create_tables(tablas, True)
|
database_proxy.create_tables(tablas, True)
|
||||||
|
@ -10604,6 +10895,7 @@ def _migrate_tables(rfc=''):
|
||||||
PartnerInvoices,
|
PartnerInvoices,
|
||||||
WareHouseProduct,
|
WareHouseProduct,
|
||||||
SATUnidadesPeso,
|
SATUnidadesPeso,
|
||||||
|
SociosRegimenes,
|
||||||
]
|
]
|
||||||
log.info('Creando tablas nuevas...')
|
log.info('Creando tablas nuevas...')
|
||||||
database_proxy.create_tables(tablas, True)
|
database_proxy.create_tables(tablas, True)
|
||||||
|
@ -10647,6 +10939,10 @@ def _migrate_tables(rfc=''):
|
||||||
correo_facturasp = TextField(default='')
|
correo_facturasp = TextField(default='')
|
||||||
migrations.append(
|
migrations.append(
|
||||||
migrator.add_column('socios', 'correo_facturasp', correo_facturasp))
|
migrator.add_column('socios', 'correo_facturasp', correo_facturasp))
|
||||||
|
if not 'regimen_fiscal' in columns:
|
||||||
|
regimen_fiscal = TextField(default='')
|
||||||
|
migrations.append(
|
||||||
|
migrator.add_column('socios', 'regimen_fiscal', regimen_fiscal))
|
||||||
|
|
||||||
columns = [c.name for c in database_proxy.get_columns('folios')]
|
columns = [c.name for c in database_proxy.get_columns('folios')]
|
||||||
if not 'plantilla' in columns:
|
if not 'plantilla' in columns:
|
||||||
|
@ -10696,6 +10992,9 @@ def _migrate_tables(rfc=''):
|
||||||
migrations.append(migrator.add_column('cfdipagos', 'socio_id', socio))
|
migrations.append(migrator.add_column('cfdipagos', 'socio_id', socio))
|
||||||
migrations.append(migrator.drop_column('cfdipagos', 'cancelado'))
|
migrations.append(migrator.drop_column('cfdipagos', 'cancelado'))
|
||||||
migrations.append(migrator.add_column('cfdipagos', 'cancelada', cancelada))
|
migrations.append(migrator.add_column('cfdipagos', 'cancelada', cancelada))
|
||||||
|
if not 'receptor_regimen' in columns:
|
||||||
|
receptor_regimen = TextField(default='')
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'receptor_regimen', receptor_regimen))
|
||||||
|
|
||||||
if not 'fecha_cancelacion' in columns:
|
if not 'fecha_cancelacion' in columns:
|
||||||
fecha_cancelacion = DateTimeField(null=True)
|
fecha_cancelacion = DateTimeField(null=True)
|
||||||
|
@ -10729,6 +11028,10 @@ def _migrate_tables(rfc=''):
|
||||||
is_discontinued = BooleanField(default=False)
|
is_discontinued = BooleanField(default=False)
|
||||||
migrations.append(migrator.add_column(
|
migrations.append(migrator.add_column(
|
||||||
table, 'is_discontinued', is_discontinued))
|
table, 'is_discontinued', is_discontinued))
|
||||||
|
if not 'objeto_impuesto' in columns:
|
||||||
|
objeto_impuesto = TextField(default='02')
|
||||||
|
migrations.append(migrator.add_column(table, 'objeto_impuesto', objeto_impuesto))
|
||||||
|
|
||||||
if 'almacen_id' in columns:
|
if 'almacen_id' in columns:
|
||||||
migrations.append(migrator.drop_column(table, 'almacen_id'))
|
migrations.append(migrator.drop_column(table, 'almacen_id'))
|
||||||
|
|
||||||
|
@ -10745,6 +11048,15 @@ def _migrate_tables(rfc=''):
|
||||||
if not 'divisas' in columns:
|
if not 'divisas' in columns:
|
||||||
divisas = TextField(default='')
|
divisas = TextField(default='')
|
||||||
migrations.append(migrator.add_column(table, 'divisas', divisas))
|
migrations.append(migrator.add_column(table, 'divisas', divisas))
|
||||||
|
if not 'exportacion' in columns:
|
||||||
|
new_field = TextField(default='01')
|
||||||
|
migrations.append(migrator.add_column(table, 'exportacion', new_field))
|
||||||
|
if not 'receptor_regimen' in columns:
|
||||||
|
receptor_regimen = TextField(default='')
|
||||||
|
migrations.append(migrator.add_column(table, 'receptor_regimen', receptor_regimen))
|
||||||
|
if not 'periodicidad' in columns:
|
||||||
|
periodicidad = TextField(default='')
|
||||||
|
migrations.append(migrator.add_column(table, 'periodicidad', periodicidad))
|
||||||
|
|
||||||
table = 'almacenes'
|
table = 'almacenes'
|
||||||
columns = [c.name for c in database_proxy.get_columns(table)]
|
columns = [c.name for c in database_proxy.get_columns(table)]
|
||||||
|
@ -10772,6 +11084,13 @@ def _migrate_tables(rfc=''):
|
||||||
warehouse = ForeignKeyField(Almacenes, null=True, to_field=Almacenes.id)
|
warehouse = ForeignKeyField(Almacenes, null=True, to_field=Almacenes.id)
|
||||||
migrations.append(migrator.add_column(table, field, warehouse))
|
migrations.append(migrator.add_column(table, field, warehouse))
|
||||||
|
|
||||||
|
table = 'empleados'
|
||||||
|
field = 'regimen_fiscal'
|
||||||
|
columns = [c.name for c in database_proxy.get_columns(table)]
|
||||||
|
if not field in columns:
|
||||||
|
regimen_fiscal = TextField(default='')
|
||||||
|
migrations.append(migrator.add_column(table, field, regimen_fiscal))
|
||||||
|
|
||||||
if migrations:
|
if migrations:
|
||||||
with database_proxy.atomic() as txn:
|
with database_proxy.atomic() as txn:
|
||||||
migrate(*migrations)
|
migrate(*migrations)
|
||||||
|
@ -10779,7 +11098,24 @@ def _migrate_tables(rfc=''):
|
||||||
Configuracion.add({'version': VERSION})
|
Configuracion.add({'version': VERSION})
|
||||||
|
|
||||||
log.info('Tablas migradas correctamente...')
|
log.info('Tablas migradas correctamente...')
|
||||||
_importar_valores('', rfc)
|
# ~ _importar_valores('', rfc)
|
||||||
|
|
||||||
|
log.info('Actualizando valores...')
|
||||||
|
try:
|
||||||
|
q = SATRegimenes.update(**{'activo': True}).where(SATRegimenes.key=='616')
|
||||||
|
q.execute()
|
||||||
|
except Exception as e:
|
||||||
|
log.error(e)
|
||||||
|
else:
|
||||||
|
log.info('Valores actualizados...')
|
||||||
|
|
||||||
|
try:
|
||||||
|
q = SATEstados.update(**{'key': 'CMX'}).where(SATEstados.key=='DIF')
|
||||||
|
q.execute()
|
||||||
|
except Exception as e:
|
||||||
|
log.error(e)
|
||||||
|
else:
|
||||||
|
log.info('Valores actualizados...')
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,8 @@ except ImportError:
|
||||||
|
|
||||||
|
|
||||||
DEBUG = DEBUG
|
DEBUG = DEBUG
|
||||||
VERSION = '1.47.0'
|
VERSION = '2.0.0'
|
||||||
|
|
||||||
EMAIL_SUPPORT = ('soporte@empresalibre.mx',)
|
EMAIL_SUPPORT = ('soporte@empresalibre.mx',)
|
||||||
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)
|
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)
|
||||||
|
|
||||||
|
@ -127,25 +128,45 @@ if 'win' in sys.platform:
|
||||||
PATH_XMLSEC = os.path.join(PATH_BIN, 'xmlsec.exe')
|
PATH_XMLSEC = os.path.join(PATH_BIN, 'xmlsec.exe')
|
||||||
|
|
||||||
|
|
||||||
|
PRE_DEFAULT = {
|
||||||
|
'CFDI': {'VERSION': '4.0', 'PRE': '{http://www.sat.gob.mx/cfd/4}'},
|
||||||
|
'NOMINA': {'VERSION': '1.2', 'PRE': '{http://www.sat.gob.mx/nomina12}'},
|
||||||
|
'PAGOS': {'VERSION': '2.0', 'PRE': '{http://www.sat.gob.mx/Pagos20}'},
|
||||||
|
'TIBRE': {'VERSION': '1.1', 'PRE': '{http://www.sat.gob.mx/TimbreFiscalDigital}'},
|
||||||
|
}
|
||||||
|
|
||||||
|
pre2 ='{http://www.sat.gob.mx/cfd/2}'
|
||||||
|
pre3 ='{http://www.sat.gob.mx/cfd/3}'
|
||||||
|
PRE_HISTORY = {
|
||||||
|
'CFDI': {'2.0': pre2, '2.2': pre2,
|
||||||
|
'3.0': pre3, '3.2': pre3, '3.3': pre3},
|
||||||
|
'NOMINA': {'1.1': '{http://www.sat.gob.mx/nomina}'},
|
||||||
|
'PAGOS': {'1.0': '{http://www.sat.gob.mx/Pagos}'},
|
||||||
|
}
|
||||||
|
|
||||||
PRE = {
|
PRE = {
|
||||||
'2.0': '{http://www.sat.gob.mx/cfd/2}',
|
'2.0': '{http://www.sat.gob.mx/cfd/2}',
|
||||||
'2.2': '{http://www.sat.gob.mx/cfd/2}',
|
'2.2': '{http://www.sat.gob.mx/cfd/2}',
|
||||||
'3.0': '{http://www.sat.gob.mx/cfd/3}',
|
'3.0': '{http://www.sat.gob.mx/cfd/3}',
|
||||||
'3.2': '{http://www.sat.gob.mx/cfd/3}',
|
'3.2': '{http://www.sat.gob.mx/cfd/3}',
|
||||||
'3.3': '{http://www.sat.gob.mx/cfd/3}',
|
'3.3': '{http://www.sat.gob.mx/cfd/3}',
|
||||||
|
'4.0': '{http://www.sat.gob.mx/cfd/4}',
|
||||||
'TIMBRE': '{http://www.sat.gob.mx/TimbreFiscalDigital}',
|
'TIMBRE': '{http://www.sat.gob.mx/TimbreFiscalDigital}',
|
||||||
'DONATARIA': '{http://www.sat.gob.mx/donat}',
|
'DONATARIA': '{http://www.sat.gob.mx/donat}',
|
||||||
'INE': '{http://www.sat.gob.mx/ine}',
|
'INE': '{http://www.sat.gob.mx/ine}',
|
||||||
'LOCALES': '{http://www.sat.gob.mx/implocal}',
|
'LOCALES': '{http://www.sat.gob.mx/implocal}',
|
||||||
'NOMINA': {
|
'NOMINA': {
|
||||||
'1.1': '{http://www.sat.gob.mx/nomina}',
|
'1.1': '{http://www.sat.gob.mx/nomina}',
|
||||||
'1.2': '{http://www.sat.gob.mx/nomina12}',
|
|
||||||
},
|
},
|
||||||
'pagos': '{http://www.sat.gob.mx/Pagos}',
|
'PAGOS': {
|
||||||
|
'1.0': '{http://www.sat.gob.mx/Pagos}',
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CURRENT_CFDI = '3.3'
|
# To delete
|
||||||
CURRENT_CFDI_NOMINA = '1.2'
|
# ~ CURRENT_CFDI = '4.0'
|
||||||
|
# ~ CURRENT_CFDI_NOMINA = '1.2'
|
||||||
|
|
||||||
DECIMALES = 2
|
DECIMALES = 2
|
||||||
DECIMALES_TAX = 4
|
DECIMALES_TAX = 4
|
||||||
DECIMALES_PRECIOS = 4
|
DECIMALES_PRECIOS = 4
|
||||||
|
@ -168,7 +189,8 @@ DEFAULT_CFDIPAY = {
|
||||||
'TYPE': 'P',
|
'TYPE': 'P',
|
||||||
'WAYPAY': 'PPD',
|
'WAYPAY': 'PPD',
|
||||||
'CURRENCY': 'XXX',
|
'CURRENCY': 'XXX',
|
||||||
'USED': 'P01',
|
'TC': '1',
|
||||||
|
'USED': 'CP01',
|
||||||
'KEYSAT': '84111506',
|
'KEYSAT': '84111506',
|
||||||
'UNITKEY': 'ACT',
|
'UNITKEY': 'ACT',
|
||||||
'DESCRIPTION': 'Pago',
|
'DESCRIPTION': 'Pago',
|
||||||
|
@ -181,7 +203,7 @@ PUBLIC = 'Público en general'
|
||||||
DEFAULT_SAT_NOMINA = {
|
DEFAULT_SAT_NOMINA = {
|
||||||
'SERIE': 'N',
|
'SERIE': 'N',
|
||||||
'FORMA_PAGO': '99',
|
'FORMA_PAGO': '99',
|
||||||
'USO_CFDI': 'P01',
|
'USO_CFDI': 'CN01',
|
||||||
'CLAVE': '84111505',
|
'CLAVE': '84111505',
|
||||||
'UNIDAD': 'ACT',
|
'UNIDAD': 'ACT',
|
||||||
'DESCRIPCION': 'Pago de nómina',
|
'DESCRIPCION': 'Pago de nómina',
|
||||||
|
@ -193,6 +215,7 @@ CURRENCY_MN = 'MXN'
|
||||||
|
|
||||||
# ~ v2
|
# ~ v2
|
||||||
CANCEL_VERSION = ('3.3', '4.0')
|
CANCEL_VERSION = ('3.3', '4.0')
|
||||||
|
CFDI_VERSIONS = CANCEL_VERSION
|
||||||
|
|
||||||
IS_MV = MV
|
IS_MV = MV
|
||||||
DB_COMPANIES = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'rfc.db'))
|
DB_COMPANIES = os.path.abspath(os.path.join(BASE_DIR, '..', 'db', 'rfc.db'))
|
||||||
|
|
BIN
source/db/cp.db
BIN
source/db/cp.db
Binary file not shown.
|
@ -104,7 +104,7 @@
|
||||||
{"key": "611", "name": "Ingresos por Dividendos (socios y accionistas)", "fisica": true, "activo": false},
|
{"key": "611", "name": "Ingresos por Dividendos (socios y accionistas)", "fisica": true, "activo": false},
|
||||||
{"key": "612", "name": "Personas Físicas con Actividades Empresariales y Profesionales", "fisica": true, "activo": true, "default": true},
|
{"key": "612", "name": "Personas Físicas con Actividades Empresariales y Profesionales", "fisica": true, "activo": true, "default": true},
|
||||||
{"key": "614", "name": "Ingresos por intereses", "fisica": true, "activo": true},
|
{"key": "614", "name": "Ingresos por intereses", "fisica": true, "activo": true},
|
||||||
{"key": "616", "name": "Sin obligaciones fiscales", "fisica": true, "activo": false},
|
{"key": "616", "name": "Sin obligaciones fiscales", "fisica": true, "activo": true},
|
||||||
{"key": "620", "name": "Sociedades Cooperativas de Producción que optan por diferir sus ingresos", "moral": true, "activo": false},
|
{"key": "620", "name": "Sociedades Cooperativas de Producción que optan por diferir sus ingresos", "moral": true, "activo": false},
|
||||||
{"key": "621", "name": "Incorporación Fiscal", "fisica": true, "activo": true},
|
{"key": "621", "name": "Incorporación Fiscal", "fisica": true, "activo": true},
|
||||||
{"key": "622", "name": "Actividades Agrícolas, Ganaderas, Silvícolas y Pesqueras", "fisica": true, "moral": true, "activo": false},
|
{"key": "622", "name": "Actividades Agrícolas, Ganaderas, Silvícolas y Pesqueras", "fisica": true, "moral": true, "activo": false},
|
||||||
|
@ -682,7 +682,10 @@
|
||||||
{"key": "D08", "name": "Gastos de transportación escolar obligatoria.", "activo": false},
|
{"key": "D08", "name": "Gastos de transportación escolar obligatoria.", "activo": false},
|
||||||
{"key": "D09", "name": "Depósitos en cuentas para el ahorro, primas que tengan como base planes de pensiones.", "activo": false},
|
{"key": "D09", "name": "Depósitos en cuentas para el ahorro, primas que tengan como base planes de pensiones.", "activo": false},
|
||||||
{"key": "D10", "name": "Pagos por servicios educativos (colegiaturas)", "activo": true},
|
{"key": "D10", "name": "Pagos por servicios educativos (colegiaturas)", "activo": true},
|
||||||
{"key": "P01", "name": "Por definir", "moral": true, "activo": true}
|
{"key": "P01", "name": "Por definir", "moral": true, "activo": true},
|
||||||
|
{"key": "S01", "name": "Sin efectos fiscales.", "moral": true, "activo": true},
|
||||||
|
{"key": "CP01", "name": "Pagos", "moral": true, "activo": true},
|
||||||
|
{"key": "CN01", "name": "Nómina", "moral": true, "activo": true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -728,7 +731,7 @@
|
||||||
"pais": "MEX"
|
"pais": "MEX"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "DIF",
|
"key": "CMX",
|
||||||
"name": "Ciudad de M\u00e9xico",
|
"name": "Ciudad de M\u00e9xico",
|
||||||
"pais": "MEX"
|
"pais": "MEX"
|
||||||
},
|
},
|
||||||
|
|
|
@ -76,15 +76,13 @@ var controllers = {
|
||||||
//~ Opciones
|
//~ Opciones
|
||||||
tb_options = $$('tab_options').getTabbar()
|
tb_options = $$('tab_options').getTabbar()
|
||||||
tb_options.attachEvent('onChange', tab_options_change)
|
tb_options.attachEvent('onChange', tab_options_change)
|
||||||
$$('txt_plantilla_factura_32').attachEvent('onItemClick', txt_plantilla_factura_32_click)
|
|
||||||
$$('txt_plantilla_factura_33').attachEvent('onItemClick', txt_plantilla_factura_33_click)
|
|
||||||
$$('txt_plantilla_factura_html').attachEvent('onItemClick', txt_plantilla_factura_html_click)
|
$$('txt_plantilla_factura_html').attachEvent('onItemClick', txt_plantilla_factura_html_click)
|
||||||
$$('txt_plantilla_factura_json').attachEvent('onItemClick', txt_plantilla_factura_json_click)
|
$$('txt_plantilla_factura_json').attachEvent('onItemClick', txt_plantilla_factura_json_click)
|
||||||
$$('txt_plantilla_factura_css').attachEvent('onItemClick', txt_plantilla_factura_css_click)
|
$$('txt_plantilla_factura_css').attachEvent('onItemClick', txt_plantilla_factura_css_click)
|
||||||
$$('txt_plantilla_ticket').attachEvent('onItemClick', txt_plantilla_ticket_click)
|
$$('txt_plantilla_ticket').attachEvent('onItemClick', txt_plantilla_ticket_click)
|
||||||
$$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click)
|
//~ $$('txt_plantilla_donataria').attachEvent('onItemClick', txt_plantilla_donataria_click)
|
||||||
$$('txt_plantilla_nomina1233').attachEvent('onItemClick', txt_plantilla_nomina1233_click)
|
//~ $$('txt_plantilla_nomina1233').attachEvent('onItemClick', txt_plantilla_nomina1233_click)
|
||||||
$$('txt_plantilla_pagos10').attachEvent('onItemClick', txt_plantilla_pagos10_click)
|
//~ $$('txt_plantilla_pagos10').attachEvent('onItemClick', txt_plantilla_pagos10_click)
|
||||||
$$('make_pdf_from').attachEvent('onChange', opt_make_pdf_from_on_change)
|
$$('make_pdf_from').attachEvent('onChange', opt_make_pdf_from_on_change)
|
||||||
$$('cmd_template_upload').attachEvent('onItemClick', cmd_template_upload_click)
|
$$('cmd_template_upload').attachEvent('onItemClick', cmd_template_upload_click)
|
||||||
|
|
||||||
|
@ -503,7 +501,9 @@ function set_config_templates(){
|
||||||
success: function(text, data, xhr) {
|
success: function(text, data, xhr) {
|
||||||
var values = data.json()
|
var values = data.json()
|
||||||
Object.keys(values).forEach(function(key){
|
Object.keys(values).forEach(function(key){
|
||||||
show(key, values[key])
|
if(key!='txt_plantilla_donataria'){
|
||||||
|
show(key, values[key])
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -1181,42 +1181,42 @@ function txt_plantilla_factura_json_click(e){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function txt_plantilla_donataria_click(e){
|
//~ function txt_plantilla_donataria_click(e){
|
||||||
|
|
||||||
var body_elements = [
|
//~ var body_elements = [
|
||||||
{cols: [{width: 100}, {view: 'uploader', id: 'up_template', autosend: true, link: 'lst_files',
|
//~ {cols: [{width: 100}, {view: 'uploader', id: 'up_template', autosend: true, link: 'lst_files',
|
||||||
value: 'Seleccionar archivo', upload: '/files/txt_plantilla_donataria',
|
//~ value: 'Seleccionar archivo', upload: '/files/txt_plantilla_donataria',
|
||||||
width: 200}, {width: 100}]},
|
//~ width: 200}, {width: 100}]},
|
||||||
{view: 'list', id: 'lst_files', type: 'uploader', autoheight:true,
|
//~ {view: 'list', id: 'lst_files', type: 'uploader', autoheight:true,
|
||||||
borderless: true},
|
//~ borderless: true},
|
||||||
{},
|
//~ {},
|
||||||
{cols: [{}, {view: 'button', label: 'Cerrar', autowidth: true,
|
//~ {cols: [{}, {view: 'button', label: 'Cerrar', autowidth: true,
|
||||||
click:("$$('win_template').close();")}, {}]}
|
//~ click:("$$('win_template').close();")}, {}]}
|
||||||
]
|
//~ ]
|
||||||
|
|
||||||
var w = webix.ui({
|
//~ var w = webix.ui({
|
||||||
view: 'window',
|
//~ view: 'window',
|
||||||
id: 'win_template',
|
//~ id: 'win_template',
|
||||||
modal: true,
|
//~ modal: true,
|
||||||
position: 'center',
|
//~ position: 'center',
|
||||||
head: 'Subir Plantilla Donataria',
|
//~ head: 'Subir Plantilla Donataria',
|
||||||
body: {
|
//~ body: {
|
||||||
view: 'form',
|
//~ view: 'form',
|
||||||
elements: body_elements,
|
//~ elements: body_elements,
|
||||||
}
|
//~ }
|
||||||
})
|
//~ })
|
||||||
|
|
||||||
w.show()
|
//~ w.show()
|
||||||
|
|
||||||
$$('up_template').attachEvent('onUploadComplete', function(response){
|
//~ $$('up_template').attachEvent('onUploadComplete', function(response){
|
||||||
if(response.ok){
|
//~ if(response.ok){
|
||||||
$$('txt_plantilla_donataria').setValue(response.name)
|
//~ $$('txt_plantilla_donataria').setValue(response.name)
|
||||||
msg_ok('Plantilla cargada correctamente')
|
//~ msg_ok('Plantilla cargada correctamente')
|
||||||
}else{
|
//~ }else{
|
||||||
msg_error(response.name)
|
//~ msg_error(response.name)
|
||||||
}
|
//~ }
|
||||||
})
|
//~ })
|
||||||
}
|
//~ }
|
||||||
|
|
||||||
|
|
||||||
function txt_plantilla_nomina1233_click(e){
|
function txt_plantilla_nomina1233_click(e){
|
||||||
|
@ -1257,42 +1257,42 @@ function txt_plantilla_nomina1233_click(e){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function txt_plantilla_pagos10_click(e){
|
//~ function txt_plantilla_pagos10_click(e){
|
||||||
|
|
||||||
var body_elements = [
|
//~ var body_elements = [
|
||||||
{cols: [{width: 100}, {view: 'uploader', id: 'up_template',
|
//~ {cols: [{width: 100}, {view: 'uploader', id: 'up_template',
|
||||||
autosend: true, link: 'lst_files', value: 'Seleccionar archivo',
|
//~ autosend: true, link: 'lst_files', value: 'Seleccionar archivo',
|
||||||
upload: '/files/txt_plantilla_pagos10', width: 200}, {width: 100}]},
|
//~ upload: '/files/txt_plantilla_pagos10', width: 200}, {width: 100}]},
|
||||||
{view: 'list', id: 'lst_files', type: 'uploader', autoheight:true,
|
//~ {view: 'list', id: 'lst_files', type: 'uploader', autoheight:true,
|
||||||
borderless: true},
|
//~ borderless: true},
|
||||||
{},
|
//~ {},
|
||||||
{cols: [{}, {view: 'button', label: 'Cerrar', autowidth: true,
|
//~ {cols: [{}, {view: 'button', label: 'Cerrar', autowidth: true,
|
||||||
click:("$$('win_template').close();")}, {}]}
|
//~ click:("$$('win_template').close();")}, {}]}
|
||||||
]
|
//~ ]
|
||||||
|
|
||||||
var w = webix.ui({
|
//~ var w = webix.ui({
|
||||||
view: 'window',
|
//~ view: 'window',
|
||||||
id: 'win_template',
|
//~ id: 'win_template',
|
||||||
modal: true,
|
//~ modal: true,
|
||||||
position: 'center',
|
//~ position: 'center',
|
||||||
head: 'Subir Plantilla Factura de Pago',
|
//~ head: 'Subir Plantilla Factura de Pago',
|
||||||
body: {
|
//~ body: {
|
||||||
view: 'form',
|
//~ view: 'form',
|
||||||
elements: body_elements,
|
//~ elements: body_elements,
|
||||||
}
|
//~ }
|
||||||
})
|
//~ })
|
||||||
|
|
||||||
w.show()
|
//~ w.show()
|
||||||
|
|
||||||
$$('up_template').attachEvent('onUploadComplete', function(response){
|
//~ $$('up_template').attachEvent('onUploadComplete', function(response){
|
||||||
if(response.ok){
|
//~ if(response.ok){
|
||||||
$$('txt_plantilla_pagos10').setValue(response.name)
|
//~ $$('txt_plantilla_pagos10').setValue(response.name)
|
||||||
msg_ok('Plantilla cargada correctamente')
|
//~ msg_ok('Plantilla cargada correctamente')
|
||||||
}else{
|
//~ }else{
|
||||||
msg_error(response.name)
|
//~ msg_error(response.name)
|
||||||
}
|
//~ }
|
||||||
})
|
//~ })
|
||||||
}
|
//~ }
|
||||||
|
|
||||||
|
|
||||||
function tab_options_change(nv, ov){
|
function tab_options_change(nv, ov){
|
||||||
|
|
|
@ -993,6 +993,8 @@ function send_stamp_cfdi_pay(id_mov){
|
||||||
var g = $$('grid_cfdi_pay')
|
var g = $$('grid_cfdi_pay')
|
||||||
var data = {'opt': 'stamp', 'id_mov': id_mov}
|
var data = {'opt': 'stamp', 'id_mov': id_mov}
|
||||||
|
|
||||||
|
var close = $$('chk_pay_close_when_stamp').getValue()
|
||||||
|
|
||||||
//~ ToDo Actualizar cantidad de facturas de pago en el movimiento
|
//~ ToDo Actualizar cantidad de facturas de pago en el movimiento
|
||||||
|
|
||||||
webix.ajax().sync().post('cfdipay', data, {
|
webix.ajax().sync().post('cfdipay', data, {
|
||||||
|
@ -1010,6 +1012,9 @@ function send_stamp_cfdi_pay(id_mov){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
$$('multi_bancos').setValue('banco_home')
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function save_cfdi_pay(form){
|
function save_cfdi_pay(form){
|
||||||
|
|
|
@ -291,6 +291,11 @@ function cmd_new_invoice_click(){
|
||||||
grid_totals.add({id: 1, concepto: 'SubTotal', importe: 0})
|
grid_totals.add({id: 1, concepto: 'SubTotal', importe: 0})
|
||||||
$$('cmd_cfdi_relacionados').disable()
|
$$('cmd_cfdi_relacionados').disable()
|
||||||
$$('multi_invoices').setValue('invoices_new')
|
$$('multi_invoices').setValue('invoices_new')
|
||||||
|
|
||||||
|
var lst = $$('lst_invoice_client_regimen')
|
||||||
|
lst.setValue('')
|
||||||
|
lst.getList().clearAll()
|
||||||
|
|
||||||
form.focus('search_client_name')
|
form.focus('search_client_name')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,19 +368,25 @@ function validate_invoice(values){
|
||||||
msg_error(msg)
|
msg_error(msg)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var tipo_comprobante = $$('lst_tipo_comprobante').getValue()
|
var tipo_comprobante = $$('lst_tipo_comprobante').getValue()
|
||||||
if(tipo_comprobante != 'T'){
|
if(tipo_comprobante != 'T'){
|
||||||
if(values.id_partner == 0){
|
if(values.id_partner == 0){
|
||||||
webix.UIManager.setFocus('search_client_name')
|
focus('search_client_name')
|
||||||
msg = 'Selecciona un cliente'
|
msg = 'Selecciona un cliente'
|
||||||
msg_error(msg)
|
msg_error(msg)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var regimen_fiscal = $$('lst_invoice_client_regimen').getValue()
|
||||||
|
if(!regimen_fiscal){
|
||||||
|
msg = 'El Regimen Fiscal del Cliente es obligatorio.'
|
||||||
|
msg_error(msg)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if(!grid.count()){
|
if(!grid.count()){
|
||||||
webix.UIManager.setFocus('search_product_id')
|
webix.UIManager.setFocus('search_product_id')
|
||||||
msg = 'Agrega al menos un producto o servicio'
|
msg = 'Agrega al menos un producto o servicio'
|
||||||
|
@ -685,6 +696,7 @@ function guardar_y_timbrar(values){
|
||||||
data['metodo_pago'] = $$('lst_metodo_pago').getValue()
|
data['metodo_pago'] = $$('lst_metodo_pago').getValue()
|
||||||
data['uso_cfdi'] = $$('lst_uso_cfdi').getValue()
|
data['uso_cfdi'] = $$('lst_uso_cfdi').getValue()
|
||||||
data['regimen_fiscal'] = $$('lst_regimen_fiscal').getValue()
|
data['regimen_fiscal'] = $$('lst_regimen_fiscal').getValue()
|
||||||
|
data['receptor_regimen'] = $$('lst_invoice_client_regimen').getValue()
|
||||||
data['relacionados'] = ids
|
data['relacionados'] = ids
|
||||||
data['tipo_relacion'] = tipo_relacion
|
data['tipo_relacion'] = tipo_relacion
|
||||||
data['anticipo'] = anticipo
|
data['anticipo'] = anticipo
|
||||||
|
@ -904,6 +916,12 @@ function search_client_by_id(id){
|
||||||
|
|
||||||
|
|
||||||
function set_client(row){
|
function set_client(row){
|
||||||
|
if(!row.codigo_postal){
|
||||||
|
msg = 'El cliente no tiene capturado su Código Postal, es obligatorio.'
|
||||||
|
msg_error(msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var form = $$('form_invoice')
|
var form = $$('form_invoice')
|
||||||
var html = '<span class="webix_icon fa-user"></span><span class="lbl_partner">'
|
var html = '<span class="webix_icon fa-user"></span><span class="lbl_partner">'
|
||||||
form.setValues({
|
form.setValues({
|
||||||
|
@ -913,6 +931,20 @@ function set_client(row){
|
||||||
html += row.nombre + ' (' + row.rfc + ')</span>'
|
html += row.nombre + ' (' + row.rfc + ')</span>'
|
||||||
$$('lbl_client').setValue(html)
|
$$('lbl_client').setValue(html)
|
||||||
$$('cmd_cfdi_relacionados').enable()
|
$$('cmd_cfdi_relacionados').enable()
|
||||||
|
|
||||||
|
var lst = $$('lst_invoice_client_regimen')
|
||||||
|
lst.getList().clearAll()
|
||||||
|
if(row.regimenes==undefined){
|
||||||
|
var options = {opt: 'by_id', id: row.id}
|
||||||
|
webix.ajax().sync().get('/sociosregimenes', options, function(text, data){
|
||||||
|
var values = data.json()
|
||||||
|
lst.getList().parse(values)
|
||||||
|
})
|
||||||
|
}else{
|
||||||
|
lst.getList().parse(row.regimenes)
|
||||||
|
}
|
||||||
|
lst.setValue(lst.getPopup().getList().getFirstId())
|
||||||
|
|
||||||
form.focus('search_product_id')
|
form.focus('search_product_id')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1204,11 +1236,9 @@ function grid_carta_ubicaciones_before_edit_stop(state, editor){
|
||||||
msg = 'No se encontró el C.P., asegurate de que sea correcto'
|
msg = 'No se encontró el C.P., asegurate de que sea correcto'
|
||||||
msg_error(msg)
|
msg_error(msg)
|
||||||
} else {
|
} else {
|
||||||
row['Estado'] = opt_carta_estados.find(x => x.value === values.estado).id
|
//~ row['Estado'] = opt_carta_estados.find(x => x.value === values.estado).id
|
||||||
|
row['Estado'] = values.key_estado
|
||||||
row['Municipio'] = values.key_municipio
|
row['Municipio'] = values.key_municipio
|
||||||
//~ $$('colonia').define('suggest', [])
|
|
||||||
//~ $$('colonia').define('suggest', values.colonia)
|
|
||||||
//~ $$('colonia').refresh()
|
|
||||||
g.refresh()
|
g.refresh()
|
||||||
msg_ok('Municipio:\n' + values.municipio)
|
msg_ok('Municipio:\n' + values.municipio)
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,10 +255,10 @@ function up_employees_upload_complete(response){
|
||||||
function delete_empleado(id){
|
function delete_empleado(id){
|
||||||
webix.ajax().del('/employees', {id: id}, function(text, xml, xhr){
|
webix.ajax().del('/employees', {id: id}, function(text, xml, xhr){
|
||||||
var msg = 'Empleado eliminado correctamente'
|
var msg = 'Empleado eliminado correctamente'
|
||||||
if (xhr.status == 200){
|
if(xhr.status == 200){
|
||||||
$$('grid_employees').remove(id);
|
$$('grid_employees').remove(id);
|
||||||
msg_ok(msg)
|
msg_ok(msg)
|
||||||
} else {
|
}else{
|
||||||
msg = 'El Empleado tiene recibos timbrados'
|
msg = 'El Empleado tiene recibos timbrados'
|
||||||
msg_error(msg)
|
msg_error(msg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,7 @@ function cmd_new_partner_click(id, e, node){
|
||||||
$$('partner_balance').define('readonly', !cfg_partners['chk_config_change_balance_partner'])
|
$$('partner_balance').define('readonly', !cfg_partners['chk_config_change_balance_partner'])
|
||||||
get_partner_banks()
|
get_partner_banks()
|
||||||
get_partner_accounts_bank(0)
|
get_partner_accounts_bank(0)
|
||||||
|
get_sat_regimenes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,6 +124,7 @@ function cmd_edit_partner_click(){
|
||||||
},
|
},
|
||||||
success: function(text, data, xhr){
|
success: function(text, data, xhr){
|
||||||
var values = data.json()
|
var values = data.json()
|
||||||
|
|
||||||
$$('form_partner').clearValidation()
|
$$('form_partner').clearValidation()
|
||||||
$$('form_partner').setValues(values)
|
$$('form_partner').setValues(values)
|
||||||
$$('forma_pago').getList().load('/values/formapago')
|
$$('forma_pago').getList().load('/values/formapago')
|
||||||
|
@ -132,8 +134,10 @@ function cmd_edit_partner_click(){
|
||||||
|
|
||||||
if(values.tipo_persona == 1){
|
if(values.tipo_persona == 1){
|
||||||
query = table_usocfdi.chain().find({fisica: true}).data()
|
query = table_usocfdi.chain().find({fisica: true}).data()
|
||||||
|
get_sat_regimenes()
|
||||||
}else if(values.tipo_persona == 2){
|
}else if(values.tipo_persona == 2){
|
||||||
query = table_usocfdi.chain().find({moral: true}).data()
|
query = table_usocfdi.chain().find({moral: true}).data()
|
||||||
|
get_sat_regimenes(true)
|
||||||
}else{
|
}else{
|
||||||
query = [{id: 'P01', value: 'Por definir'}]
|
query = [{id: 'P01', value: 'Por definir'}]
|
||||||
}
|
}
|
||||||
|
@ -145,12 +149,15 @@ function cmd_edit_partner_click(){
|
||||||
$$('cuenta_proveedor').enable()
|
$$('cuenta_proveedor').enable()
|
||||||
}
|
}
|
||||||
get_partner_accounts_bank(row['id'])
|
get_partner_accounts_bank(row['id'])
|
||||||
|
pause(250)
|
||||||
|
$$('lst_receptor_regimenes_fiscales').select(values.regimenes)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
$$('multi_partners').setValue('partners_new')
|
$$('multi_partners').setValue('partners_new')
|
||||||
$$('tab_partner').setValue('Datos Fiscales')
|
$$('tab_partner').setValue('Datos Fiscales')
|
||||||
get_partner_banks()
|
get_partner_banks()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -239,7 +246,17 @@ function cmd_save_partner_click(id, e, node){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ids_regimenes = $$('lst_receptor_regimenes_fiscales').getSelectedId()
|
||||||
|
if(values.tipo_persona < 3){
|
||||||
|
if(!ids_regimenes){
|
||||||
|
msg = 'Selecciona al menos un Regimen Fiscal'
|
||||||
|
msg_error(msg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
values['accounts'] = $$('grid_partner_account_bank').data.getRange()
|
values['accounts'] = $$('grid_partner_account_bank').data.getRange()
|
||||||
|
values['regimenes'] = ids_regimenes
|
||||||
|
|
||||||
webix.ajax().post('/partners', values, {
|
webix.ajax().post('/partners', values, {
|
||||||
error:function(text, data, XmlHttpRequest){
|
error:function(text, data, XmlHttpRequest){
|
||||||
|
@ -343,18 +360,28 @@ function opt_tipo_change(new_value, old_value){
|
||||||
$$('id_fiscal').define('value', '')
|
$$('id_fiscal').define('value', '')
|
||||||
show('id_fiscal', new_value == 4)
|
show('id_fiscal', new_value == 4)
|
||||||
|
|
||||||
|
$$('lst_receptor_regimenes_fiscales').clearAll()
|
||||||
|
var regimen_616 = {id: 11, value: 'Sin obligaciones fiscales'}
|
||||||
|
|
||||||
if (new_value == 1 || new_value == 2){
|
if (new_value == 1 || new_value == 2){
|
||||||
$$("rfc").define("value", "")
|
$$("rfc").define("value", "")
|
||||||
$$("rfc").define("readonly", false)
|
$$("rfc").define("readonly", false)
|
||||||
|
moral = false
|
||||||
|
if(new_value == 2){
|
||||||
|
moral = true
|
||||||
|
}
|
||||||
|
get_sat_regimenes(moral)
|
||||||
} else if (new_value == 3) {
|
} else if (new_value == 3) {
|
||||||
$$("rfc").define("value", RFC_PUBLICO)
|
$$("rfc").define("value", RFC_PUBLICO)
|
||||||
$$("nombre").define("value", PUBLICO)
|
$$("nombre").define("value", PUBLICO)
|
||||||
$$("rfc").define("readonly", true)
|
$$("rfc").define("readonly", true)
|
||||||
|
$$('lst_receptor_regimenes_fiscales').parse(regimen_616)
|
||||||
} else if (new_value == 4) {
|
} else if (new_value == 4) {
|
||||||
$$("rfc").define("value", RFC_EXTRANJERO)
|
$$("rfc").define("value", RFC_EXTRANJERO)
|
||||||
$$("rfc").define("readonly", true)
|
$$("rfc").define("readonly", true)
|
||||||
$$("pais").define("readonly", false)
|
$$("pais").define("readonly", false)
|
||||||
$$("pais").define("value", "")
|
$$("pais").define("value", "")
|
||||||
|
$$('lst_receptor_regimenes_fiscales').parse(regimen_616)
|
||||||
}
|
}
|
||||||
|
|
||||||
$$("nombre").refresh();
|
$$("nombre").refresh();
|
||||||
|
@ -372,10 +399,12 @@ function opt_tipo_change(new_value, old_value){
|
||||||
}else if (new_value == 2){
|
}else if (new_value == 2){
|
||||||
query = table_usocfdi.chain().find({moral: true}).data()
|
query = table_usocfdi.chain().find({moral: true}).data()
|
||||||
}else{
|
}else{
|
||||||
query = [{id: 'P01', value: 'Por definir'}]
|
query = [{id: 'S01', value: 'Sin efectos fiscales. '}]
|
||||||
}
|
}
|
||||||
$$('lst_uso_cfdi_socio').getList().parse(query)
|
$$('lst_uso_cfdi_socio').getList().parse(query)
|
||||||
$$('lst_uso_cfdi_socio').refresh()
|
$$('lst_uso_cfdi_socio').refresh()
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -619,3 +648,21 @@ function partner_delete_account_bank(row){
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function get_sat_regimenes(morales=false){
|
||||||
|
var data = {opt: 'actives', morales: morales}
|
||||||
|
webix.ajax().sync().get('/satregimenes', data, {
|
||||||
|
error: function(text, data, xhr) {
|
||||||
|
msg = 'Error al consultar'
|
||||||
|
msg_error(msg)
|
||||||
|
},
|
||||||
|
success: function(text, data, xhr) {
|
||||||
|
var values = data.json()
|
||||||
|
$$('lst_receptor_regimenes_fiscales').clearAll()
|
||||||
|
$$('lst_receptor_regimenes_fiscales').parse(values)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ function products_default_config(){
|
||||||
if(cfg_products['inventario']){
|
if(cfg_products['inventario']){
|
||||||
$$('grid_products').showColumn('existencia')
|
$$('grid_products').showColumn('existencia')
|
||||||
}
|
}
|
||||||
show('cant_by_packing', values.chk_use_packing)
|
//~ show('cant_by_packing', values.chk_use_packing)
|
||||||
show('cmd_show_exists', values.chk_multi_stock)
|
show('cmd_show_exists', values.chk_multi_stock)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -123,6 +123,7 @@ function cmd_edit_product_click(){
|
||||||
get_taxes()
|
get_taxes()
|
||||||
$$('unidad').getList().load('/values/unidades')
|
$$('unidad').getList().load('/values/unidades')
|
||||||
configurar_producto()
|
configurar_producto()
|
||||||
|
|
||||||
var grid = $$('grid_products')
|
var grid = $$('grid_products')
|
||||||
var row = grid.getSelectedItem()
|
var row = grid.getSelectedItem()
|
||||||
if(row == undefined){
|
if(row == undefined){
|
||||||
|
@ -131,9 +132,10 @@ function cmd_edit_product_click(){
|
||||||
}
|
}
|
||||||
|
|
||||||
$$('categoria').getList().load('/values/categorias')
|
$$('categoria').getList().load('/values/categorias')
|
||||||
webix.ajax().get('/products', {id:row['id']}, {
|
|
||||||
|
webix.ajax().get('/products', {id: row['id']}, {
|
||||||
error: function(text, data, xhr) {
|
error: function(text, data, xhr) {
|
||||||
msg_error()
|
msg_error(text)
|
||||||
},
|
},
|
||||||
success: function(text, data, xhr){
|
success: function(text, data, xhr){
|
||||||
var values = data.json()
|
var values = data.json()
|
||||||
|
@ -237,10 +239,10 @@ function cmd_save_product_click(id, e, node){
|
||||||
|
|
||||||
var values = form.getValues();
|
var values = form.getValues();
|
||||||
|
|
||||||
if(!isFinite(values.cant_by_packing)){
|
//~ if(!isFinite(values.cant_by_packing)){
|
||||||
msg_error('La cantidad por empaque debe ser un número')
|
//~ msg_error('La cantidad por empaque debe ser un número')
|
||||||
return
|
//~ return
|
||||||
}
|
//~ }
|
||||||
|
|
||||||
if(!validate_sat_key_product(values.clave_sat, false)){
|
if(!validate_sat_key_product(values.clave_sat, false)){
|
||||||
msg_error('La clave SAT no existe')
|
msg_error('La clave SAT no existe')
|
||||||
|
|
|
@ -611,12 +611,13 @@ function cmd_cancelar_ticket_click(){
|
||||||
|
|
||||||
function chk_is_invoice_day_change(new_value, old_value){
|
function chk_is_invoice_day_change(new_value, old_value){
|
||||||
var value = Boolean(new_value)
|
var value = Boolean(new_value)
|
||||||
|
|
||||||
show('fs_ticket_search_client', !value)
|
show('fs_ticket_search_client', !value)
|
||||||
|
enable('lst_periodicidad', value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function send_timbrar_invoice(id){
|
function send_timbrar_invoice(id){
|
||||||
//~ webix.ajax().get('/values/timbrar', {id: id, update: false}, function(text, data){
|
|
||||||
webix.ajax().post('invoices', {opt: 'timbrar', id: id, update: false}, function(text, data){
|
webix.ajax().post('invoices', {opt: 'timbrar', id: id, update: false}, function(text, data){
|
||||||
var values = data.json()
|
var values = data.json()
|
||||||
if(values.ok){
|
if(values.ok){
|
||||||
|
@ -683,6 +684,7 @@ function cmd_new_invoice_from_ticket_click(){
|
||||||
data['client'] = values.id_partner
|
data['client'] = values.id_partner
|
||||||
data['tickets'] = tickets
|
data['tickets'] = tickets
|
||||||
data['is_invoice_day'] = chk.getValue()
|
data['is_invoice_day'] = chk.getValue()
|
||||||
|
data['periodicidad'] = $$('lst_periodicidad').getValue()
|
||||||
data['opt'] = 'invoice'
|
data['opt'] = 'invoice'
|
||||||
|
|
||||||
msg = 'Todos los datos son correctos.<BR><BR>¿Estás seguro de generar esta factura?'
|
msg = 'Todos los datos son correctos.<BR><BR>¿Estás seguro de generar esta factura?'
|
||||||
|
|
|
@ -596,8 +596,18 @@ var type_make_pdf = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
//~ Templates
|
||||||
var opt_templates_cfdi = [
|
var opt_templates_cfdi = [
|
||||||
{id: '_3.3_cp_2.0.ods', value: 'CFDI v3.3 - Carta Porte 2.0'},
|
{id: '_4.0.ods', value: 'CFDI v4.0'},
|
||||||
|
{id: '_4.0_cn_1.2.ods', value: 'CFDI v4.0 - Nómina v1.2'},
|
||||||
|
{id: '_4.0_cp_2.0.ods', value: 'CFDI v4.0 - Pagos v2.0'},
|
||||||
|
{id: '_4.0_ccp_2.0.ods', value: 'CFDI v4.0 - Carta Porte v2.0'},
|
||||||
|
{id: '_4.0_cd_1.1.ods', value: 'CFDI v4.0 - Donativos v1.1'},
|
||||||
|
{id: '_3.3.ods', value: 'CFDI v3.3'},
|
||||||
|
{id: '_3.3_cn_1.2.ods', value: 'CFDI v3.3 - Nómina v1.2'},
|
||||||
|
{id: '_3.3_ccp_2.0.ods', value: 'CFDI v3.3 - Carta Porte v2.0'},
|
||||||
|
{id: '_3.3_cp_1.0.ods', value: 'CFDI v3.3 - Pagos v1.0'},
|
||||||
|
{id: '_3.2.ods', value: 'CFDI v3.2'},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -610,14 +620,6 @@ var options_templates = [
|
||||||
{},
|
{},
|
||||||
{maxWidth: 20} ]},
|
{maxWidth: 20} ]},
|
||||||
{maxHeight: 50},
|
{maxHeight: 50},
|
||||||
{cols: [{maxWidth: 20},
|
|
||||||
{view: 'search', id: 'txt_plantilla_factura_32', name: 'plantilla_factura_32',
|
|
||||||
label: 'Plantilla Factura v3.2 (ODS): ', labelPosition: 'top',
|
|
||||||
icon: 'file'}, {maxWidth: 25},
|
|
||||||
{view: 'search', id: 'txt_plantilla_factura_33', labelPosition: 'top',
|
|
||||||
label: 'Plantilla Factura v3.3 (ODS): ', icon: 'file'},
|
|
||||||
{maxWidth: 20} ]},
|
|
||||||
{maxHeight: 20},
|
|
||||||
{cols: [{maxWidth: 20},
|
{cols: [{maxWidth: 20},
|
||||||
{view: 'search', id: 'txt_plantilla_factura_html', name: 'plantilla_factura_html',
|
{view: 'search', id: 'txt_plantilla_factura_html', name: 'plantilla_factura_html',
|
||||||
label: 'Plantilla Factura v3.3 (HTML): ', labelPosition: 'top',
|
label: 'Plantilla Factura v3.3 (HTML): ', labelPosition: 'top',
|
||||||
|
@ -632,25 +634,19 @@ var options_templates = [
|
||||||
label: 'Plantilla Factura v3.3 (JSON): ', labelPosition: 'top',
|
label: 'Plantilla Factura v3.3 (JSON): ', labelPosition: 'top',
|
||||||
icon: 'file'}, {maxWidth: 25},
|
icon: 'file'}, {maxWidth: 25},
|
||||||
{}, {maxWidth: 20} ]},
|
{}, {maxWidth: 20} ]},
|
||||||
|
|
||||||
{maxHeight: 20},
|
|
||||||
{cols: [{maxWidth: 20},
|
|
||||||
{view: 'search', id: 'txt_plantilla_nomina1233', name: 'plantilla_nomina1233',
|
|
||||||
label: 'Plantilla Nomina v1.2 - Cfdi 3.3 (ODS): ', labelPosition: 'top',
|
|
||||||
icon: 'file'}, {maxWidth: 40}, {}]},
|
|
||||||
{maxHeight: 20},
|
|
||||||
{cols: [{maxWidth: 20},
|
|
||||||
{view: 'search', id: 'txt_plantilla_pagos10', name: 'plantilla_pagos10',
|
|
||||||
label: 'Plantilla Factura de Pagos v1.0 - Cfdi 3.3 (ODS): ',
|
|
||||||
labelPosition: 'top', icon: 'file'}, {maxWidth: 40}, {}]},
|
|
||||||
{maxHeight: 20},
|
{maxHeight: 20},
|
||||||
|
//~ {cols: [{maxWidth: 20},
|
||||||
|
//~ {view: 'search', id: 'txt_plantilla_pagos10', name: 'plantilla_pagos10',
|
||||||
|
//~ label: 'Plantilla Factura de Pagos v1.0 - Cfdi 3.3 (ODS): ',
|
||||||
|
//~ labelPosition: 'top', icon: 'file'}, {maxWidth: 40}, {}]},
|
||||||
|
//~ {maxHeight: 20},
|
||||||
{cols: [{maxWidth: 20},
|
{cols: [{maxWidth: 20},
|
||||||
{view: 'search', id: 'txt_plantilla_ticket', name: 'plantilla_ticket',
|
{view: 'search', id: 'txt_plantilla_ticket', name: 'plantilla_ticket',
|
||||||
label: 'Plantilla para Tickets (ODS): ', labelPosition: 'top',
|
label: 'Plantilla para Tickets (ODS): ', labelPosition: 'top',
|
||||||
icon: 'file'},
|
icon: 'file'},
|
||||||
{view: 'search', id: 'txt_plantilla_donataria', name: 'plantilla_donataria',
|
//~ {view: 'search', id: 'txt_plantilla_donataria', name: 'plantilla_donataria',
|
||||||
label: 'Plantilla Donataria (solo ONGs): ', labelPosition: 'top',
|
//~ label: 'Plantilla Donataria (solo ONGs): ', labelPosition: 'top',
|
||||||
icon: 'file'},
|
//~ icon: 'file'},
|
||||||
{}]},
|
{}]},
|
||||||
{maxHeight: 20},
|
{maxHeight: 20},
|
||||||
{cols: [{maxWidth: 20},
|
{cols: [{maxWidth: 20},
|
||||||
|
@ -832,7 +828,7 @@ var options_admin_products = [
|
||||||
|
|
||||||
|
|
||||||
var options_admin_complements = [
|
var options_admin_complements = [
|
||||||
{maxHeight: 20},
|
{maxHeight: 10},
|
||||||
{template: 'Complemento de Nómina', type: 'section'},
|
{template: 'Complemento de Nómina', type: 'section'},
|
||||||
{cols: [{maxWidth: 15},
|
{cols: [{maxWidth: 15},
|
||||||
{view: 'checkbox', id: 'chk_usar_nomina', labelWidth: 0,
|
{view: 'checkbox', id: 'chk_usar_nomina', labelWidth: 0,
|
||||||
|
@ -842,7 +838,7 @@ var options_admin_complements = [
|
||||||
{view: 'text', id: 'txt_config_nomina_folio', name: 'config_nomina_folio',
|
{view: 'text', id: 'txt_config_nomina_folio', name: 'config_nomina_folio',
|
||||||
label: 'Folio', labelWidth: 50, labelAlign: 'right'},
|
label: 'Folio', labelWidth: 50, labelAlign: 'right'},
|
||||||
{maxWidth: 15}]},
|
{maxWidth: 15}]},
|
||||||
{maxHeight: 20},
|
{maxHeight: 10},
|
||||||
{template: 'Complemento de Pagos', type: 'section'},
|
{template: 'Complemento de Pagos', type: 'section'},
|
||||||
{cols: [{maxWidth: 15},
|
{cols: [{maxWidth: 15},
|
||||||
{view: 'checkbox', id: 'chk_config_pagos', labelWidth: 0,
|
{view: 'checkbox', id: 'chk_config_pagos', labelWidth: 0,
|
||||||
|
@ -854,25 +850,25 @@ var options_admin_complements = [
|
||||||
{view: 'text', id: 'txt_config_cfdipay_folio', name: 'txt_config_cfdipay_serie',
|
{view: 'text', id: 'txt_config_cfdipay_folio', name: 'txt_config_cfdipay_serie',
|
||||||
label: 'Folio', labelWidth: 50, labelAlign: 'right'},
|
label: 'Folio', labelWidth: 50, labelAlign: 'right'},
|
||||||
{maxWidth: 15}]},
|
{maxWidth: 15}]},
|
||||||
{maxHeight: 20},
|
{maxHeight: 10},
|
||||||
{template: 'Complemento de Divisas', type: 'section'},
|
{template: 'Complemento de Divisas', type: 'section'},
|
||||||
{cols: [{maxWidth: 15},
|
{cols: [{maxWidth: 15},
|
||||||
{view: 'checkbox', id: 'chk_config_divisas', labelWidth: 0,
|
{view: 'checkbox', id: 'chk_config_divisas', labelWidth: 0,
|
||||||
labelRight: 'Usar complemento de divisas'},
|
labelRight: 'Usar complemento de divisas'},
|
||||||
{maxWidth: 15}]},
|
{maxWidth: 15}]},
|
||||||
{maxHeight: 20},
|
{maxHeight: 10},
|
||||||
{template: 'Complemento INE', type: 'section'},
|
{template: 'Complemento INE', type: 'section'},
|
||||||
{cols: [{maxWidth: 15},
|
{cols: [{maxWidth: 15},
|
||||||
{view: 'checkbox', id: 'chk_config_ine', labelWidth: 0,
|
{view: 'checkbox', id: 'chk_config_ine', labelWidth: 0,
|
||||||
labelRight: 'Usar el complemento INE'},
|
labelRight: 'Usar el complemento INE'},
|
||||||
{maxWidth: 15}]},
|
{maxWidth: 15}]},
|
||||||
{maxHeight: 20},
|
{maxHeight: 10},
|
||||||
{template: 'Complemento para escuelas EDU', type: 'section'},
|
{template: 'Complemento para escuelas EDU', type: 'section'},
|
||||||
{cols: [{maxWidth: 15},
|
{cols: [{maxWidth: 15},
|
||||||
{view: 'checkbox', id: 'chk_config_edu', labelWidth: 0,
|
{view: 'checkbox', id: 'chk_config_edu', labelWidth: 0,
|
||||||
labelRight: 'Usar el complemento EDU'},
|
labelRight: 'Usar el complemento EDU'},
|
||||||
{maxWidth: 15}]},
|
{maxWidth: 15}]},
|
||||||
{maxHeight: 20},
|
{maxHeight: 10},
|
||||||
{template: 'Complemento Leyendas Fiscales', type: 'section'},
|
{template: 'Complemento Leyendas Fiscales', type: 'section'},
|
||||||
{cols: [{maxWidth: 15},
|
{cols: [{maxWidth: 15},
|
||||||
{view: 'checkbox', id: 'chk_config_leyendas_fiscales', labelWidth: 0,
|
{view: 'checkbox', id: 'chk_config_leyendas_fiscales', labelWidth: 0,
|
||||||
|
@ -881,7 +877,7 @@ var options_admin_complements = [
|
||||||
type: 'form', align: 'center', autowidth: true, disabled: true},
|
type: 'form', align: 'center', autowidth: true, disabled: true},
|
||||||
{}, {maxWidth: 15}
|
{}, {maxWidth: 15}
|
||||||
]},
|
]},
|
||||||
{maxHeight: 20},
|
{maxHeight: 10},
|
||||||
{template: 'Complemento para Carta Porte', type: 'section'},
|
{template: 'Complemento para Carta Porte', type: 'section'},
|
||||||
{cols: [{maxWidth: 15},
|
{cols: [{maxWidth: 15},
|
||||||
{view: 'checkbox', id: 'chk_config_carta_porte', labelWidth: 0,
|
{view: 'checkbox', id: 'chk_config_carta_porte', labelWidth: 0,
|
||||||
|
@ -1174,6 +1170,7 @@ var admin_taxes = [
|
||||||
'CEDULAR',
|
'CEDULAR',
|
||||||
'CMIC',
|
'CMIC',
|
||||||
'SUPERVISION',
|
'SUPERVISION',
|
||||||
|
'MANO DE OBRA',
|
||||||
]
|
]
|
||||||
|
|
||||||
var admin_sat_impuestos = {cols: [{maxWidth: 15},
|
var admin_sat_impuestos = {cols: [{maxWidth: 15},
|
||||||
|
|
|
@ -347,6 +347,8 @@ var toolbar_bank_pay = [
|
||||||
type: 'iconButton', autowidth: true, icon: 'minus'},
|
type: 'iconButton', autowidth: true, icon: 'minus'},
|
||||||
{view: 'button', id: 'cmd_pay_delete', label: 'Eliminar',
|
{view: 'button', id: 'cmd_pay_delete', label: 'Eliminar',
|
||||||
type: 'iconButton', autowidth: true, icon: 'ban'},
|
type: 'iconButton', autowidth: true, icon: 'ban'},
|
||||||
|
{view: 'checkbox', id: 'chk_pay_close_when_stamp',
|
||||||
|
label: 'Cerrar al timbrar', tooltip: 'Cerrar al timbrar'},
|
||||||
{},
|
{},
|
||||||
{view: 'icon', click: '$$("multi_bancos").setValue("banco_home")',
|
{view: 'icon', click: '$$("multi_bancos").setValue("banco_home")',
|
||||||
icon: 'times-circle'}
|
icon: 'times-circle'}
|
||||||
|
|
|
@ -418,6 +418,7 @@ var suggest_partners = {
|
||||||
{id: 'rfc', adjust: 'data'},
|
{id: 'rfc', adjust: 'data'},
|
||||||
{id: 'forma_pago', hidden: true},
|
{id: 'forma_pago', hidden: true},
|
||||||
{id: 'uso_cfdi', hidden: true},
|
{id: 'uso_cfdi', hidden: true},
|
||||||
|
{id: 'codigo_postal', hidden: true},
|
||||||
],
|
],
|
||||||
dataFeed:function(text){
|
dataFeed:function(text){
|
||||||
if (text.length > 2){
|
if (text.length > 2){
|
||||||
|
@ -596,6 +597,10 @@ var controls_generate = [
|
||||||
autowidth:true},
|
autowidth:true},
|
||||||
{view: 'label', id: 'lbl_client', name: 'lbl_client',
|
{view: 'label', id: 'lbl_client', name: 'lbl_client',
|
||||||
label: 'Ninguno'},
|
label: 'Ninguno'},
|
||||||
|
]},
|
||||||
|
{cols: [{
|
||||||
|
view: 'richselect', id: 'lst_invoice_client_regimen',
|
||||||
|
label: 'Regimen Fiscal: ', labelWidth: 150, options: []}
|
||||||
]}
|
]}
|
||||||
]}},
|
]}},
|
||||||
{view: 'fieldset', label: 'Buscar Producto', body: {rows: [
|
{view: 'fieldset', label: 'Buscar Producto', body: {rows: [
|
||||||
|
@ -1388,7 +1393,6 @@ var win_carta_import_json = {
|
||||||
head: 'Importar Carta Porte JSON',
|
head: 'Importar Carta Porte JSON',
|
||||||
body: body_upload_carta_json,
|
body: body_upload_carta_json,
|
||||||
})
|
})
|
||||||
//~ $$('cmd_upload_invoice').attachEvent('onItemClick', cmd_upload_invoice_click)
|
|
||||||
$$('up_invoice_json').attachEvent('onAfterFileAdd', up_invoice_json_on_after_file_add)
|
$$('up_invoice_json').attachEvent('onAfterFileAdd', up_invoice_json_on_after_file_add)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ var controls_fiscales = [
|
||||||
{cols: [{view: 'text', id: 'no_interior', name: 'no_interior', width: 300,
|
{cols: [{view: 'text', id: 'no_interior', name: 'no_interior', width: 300,
|
||||||
label: 'No Interior: '},{}]},
|
label: 'No Interior: '},{}]},
|
||||||
{cols: [{view: 'search', id: 'codigo_postal', name: 'codigo_postal',
|
{cols: [{view: 'search', id: 'codigo_postal', name: 'codigo_postal',
|
||||||
width: 300, label: 'C.P.: ', attributes: {maxlength: 5}},{}]},
|
width: 300, label: 'C.P.: ', attributes: {maxlength: 5}, required: true},{}]},
|
||||||
{view: 'text', id: 'colonia', name: 'colonia', label: 'Colonia: '},
|
{view: 'text', id: 'colonia', name: 'colonia', label: 'Colonia: '},
|
||||||
{view: 'text', id: 'municipio', name: 'municipio', label: 'Municipio: '},
|
{view: 'text', id: 'municipio', name: 'municipio', label: 'Municipio: '},
|
||||||
{view: 'text', id: 'estado', name: 'estado', label: 'Estado: '},
|
{view: 'text', id: 'estado', name: 'estado', label: 'Estado: '},
|
||||||
|
@ -122,6 +122,12 @@ var controls_fiscales = [
|
||||||
{view: 'richselect', id: 'lst_uso_cfdi_socio', name: 'uso_cfdi_socio',
|
{view: 'richselect', id: 'lst_uso_cfdi_socio', name: 'uso_cfdi_socio',
|
||||||
label: 'Uso del CFDI', options: []},
|
label: 'Uso del CFDI', options: []},
|
||||||
{},
|
{},
|
||||||
|
]},
|
||||||
|
{template: 'Regimenes Fiscales', type: 'section'},
|
||||||
|
{cols: [
|
||||||
|
{view: 'list', id: 'lst_receptor_regimenes_fiscales', data: [],
|
||||||
|
select: 'multiselect', width: 600, height: 125, required: true},
|
||||||
|
{},
|
||||||
]}
|
]}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -159,7 +165,7 @@ var controls_others = [
|
||||||
label: 'Cuenta Proveedor: ', disabled: true}, {}]
|
label: 'Cuenta Proveedor: ', disabled: true}, {}]
|
||||||
},
|
},
|
||||||
{view: 'checkbox', name: 'es_ong', label: 'Es ONG: ', value: false},
|
{view: 'checkbox', name: 'es_ong', label: 'Es ONG: ', value: false},
|
||||||
{view: 'text', name: 'tags', label: 'Etiquetas',
|
{view: 'text', name: 'tags', label: 'Etiquetas', disabled: true,
|
||||||
tooltip: 'Utiles para filtrados rápidos. Separa por comas.'},
|
tooltip: 'Utiles para filtrados rápidos. Separa por comas.'},
|
||||||
{view: 'textarea' , height: 200, name: 'notas', label: 'Notas'},
|
{view: 'textarea' , height: 200, name: 'notas', label: 'Notas'},
|
||||||
]
|
]
|
||||||
|
|
|
@ -111,6 +111,14 @@ var suggest_sat_producto = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var opt_tax_object = [
|
||||||
|
{id: '01', value: '[01] No objeto de impuesto.'},
|
||||||
|
{id: '02', value: '[02] Sí objeto de impuesto.'},
|
||||||
|
{id: '03', value: '[03] Sí objeto del impuesto y no obligado al desglose.'},
|
||||||
|
{id: '04', value: '[04] Sí objeto del impuesto y no causa impuesto.'},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
var controls_generals = [
|
var controls_generals = [
|
||||||
{view: 'checkbox', id: 'es_activo_producto', name: 'es_activo_producto',
|
{view: 'checkbox', id: 'es_activo_producto', name: 'es_activo_producto',
|
||||||
label: 'Activo: ', value: true,
|
label: 'Activo: ', value: true,
|
||||||
|
@ -141,10 +149,14 @@ var controls_generals = [
|
||||||
{view: "richselect", id: "unidad", name: "unidad", label: "Unidad",
|
{view: "richselect", id: "unidad", name: "unidad", label: "Unidad",
|
||||||
width: 300, labelWidth: 130, labelAlign: "right", required: true,
|
width: 300, labelWidth: 130, labelAlign: "right", required: true,
|
||||||
invalidMessage: "La Unidad es requerida", options: []},
|
invalidMessage: "La Unidad es requerida", options: []},
|
||||||
{view: 'text', id: 'cant_by_packing', name: 'cant_by_packing',
|
{view: 'richselect', id: 'objeto_impuesto', name: 'objeto_impuesto', label: 'Objeto de Impuestos',
|
||||||
labelAlign: 'right', labelWidth: 150, inputAlign: "right",
|
width: 500, labelWidth: 150, labelAlign: "right", required: true,
|
||||||
label: 'Cantidad por empaque:'},
|
invalidMessage: 'Este campo es requerido', options: opt_tax_object},
|
||||||
{},
|
{},
|
||||||
|
//~ {view: 'text', id: 'cant_by_packing', name: 'cant_by_packing',
|
||||||
|
//~ labelAlign: 'right', labelWidth: 150, inputAlign: "right",
|
||||||
|
//~ label: 'Cantidad por empaque:'},
|
||||||
|
//~ {},
|
||||||
//~ {view: 'text', id: 'tags_producto', name: 'tags_producto',
|
//~ {view: 'text', id: 'tags_producto', name: 'tags_producto',
|
||||||
//~ labelAlign: 'right', label: 'Etiquetas',
|
//~ labelAlign: 'right', label: 'Etiquetas',
|
||||||
//~ placeholder: 'Separadas por comas'}
|
//~ placeholder: 'Separadas por comas'}
|
||||||
|
|
|
@ -233,9 +233,21 @@ var cells_new_ticket = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var opt_periodicidad = [
|
||||||
|
{id: '01', value: '[01] Diario'},
|
||||||
|
{id: '02', value: '[02] Semanal'},
|
||||||
|
{id: '03', value: '[03] Quincenal'},
|
||||||
|
{id: '04', value: '[04] Mensual'},
|
||||||
|
//~ {id: '05', value: '[05] Bimestral'},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
var toolbar_ticket_invoice = {view: 'toolbar', elements: [{},
|
var toolbar_ticket_invoice = {view: 'toolbar', elements: [{},
|
||||||
{view: 'checkbox', id: 'chk_is_invoice_day', labelWidth: 0, width: 150,
|
{view: 'checkbox', id: 'chk_is_invoice_day', labelWidth: 0, width: 150,
|
||||||
labelRight: 'Es factura del día'}, {},
|
labelRight: 'Es factura del día'},
|
||||||
|
{view: 'richselect', id: 'lst_periodicidad', labelWidth: 90, width: 250,
|
||||||
|
label: 'Periodicidad:', options: opt_periodicidad, value: '01', disabled: true},
|
||||||
|
{},
|
||||||
{view: 'button', id: 'cmd_close_ticket_invoice', label: 'Cerrar',
|
{view: 'button', id: 'cmd_close_ticket_invoice', label: 'Cerrar',
|
||||||
type: 'danger', autowidth: true, align: 'center'}
|
type: 'danger', autowidth: true, align: 'center'}
|
||||||
]}
|
]}
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,347 +1,401 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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">
|
<xsl:stylesheet version="2.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/4" 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: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:detallista="http://www.sat.gob.mx/detallista" xmlns:ecc12="http://www.sat.gob.mx/EstadoDeCuentaCombustible12" xmlns:consumodecombustibles11="http://www.sat.gob.mx/ConsumoDeCombustibles11" xmlns:gceh="http://www.sat.gob.mx/GastosHidrocarburos10" xmlns:ieeh="http://www.sat.gob.mx/IngresosHidrocarburos10" xmlns:cartaporte20="http://www.sat.gob.mx/CartaPorte20" xmlns:pago20="http://www.sat.gob.mx/Pagos20">
|
||||||
|
|
||||||
<!-- Con el siguiente método se establece que la salida deberá ser en texto -->
|
<!-- 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:output method="text" version="1.0" encoding="UTF-8" indent="no"/>
|
||||||
|
|
||||||
<xsl:include href="utilerias.xslt"/>
|
<xsl:include href="utilerias.xslt"/>
|
||||||
<xsl:include href="comercioexterior11.xslt"/>
|
<xsl:include href="nomina12.xslt"/>
|
||||||
<xsl:include href="leyendasFisc.xslt"/>
|
<xsl:include href="divisas.xslt"/>
|
||||||
<xsl:include href="nomina12.xslt"/>
|
<xsl:include href="ine11.xslt"/>
|
||||||
<xsl:include href="implocal.xslt"/>
|
<xsl:include href="iedu.xslt"/>
|
||||||
<xsl:include href="donat11.xslt"/>
|
<xsl:include href="leyendasFisc.xslt"/>
|
||||||
<xsl:include href="ine11.xslt"/>
|
<xsl:include href="cartaporte20.xslt"/>
|
||||||
<xsl:include href="iedu.xslt"/>
|
<xsl:include href="comercioexterior11.xslt"/>
|
||||||
<xsl:include href="pagos10.xslt"/>
|
<xsl:include href="donat11.xslt"/>
|
||||||
<xsl:include href="divisas.xslt"/>
|
<xsl:include href="pagos20.xslt"/>
|
||||||
<xsl:include href="servicioconstruccion.xslt"/>
|
<xsl:include href="implocal.xslt"/>
|
||||||
<xsl:include href="cartaporte20.xslt"/>
|
<!--
|
||||||
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/pfic/pfic.xslt"/>
|
||||||
<!--
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/TuristaPasajeroExtranjero/TuristaPasajeroExtranjero.xslt"/>
|
||||||
<xsl:include href="ecc11.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/cfdiregistrofiscal/cfdiregistrofiscal.xslt"/>
|
||||||
<xsl:include href="pfic.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/pagoenespecie/pagoenespecie.xslt"/>
|
||||||
<xsl:include href="TuristaPasajeroExtranjero.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/aerolineas/aerolineas.xslt"/>
|
||||||
<xsl:include href="cfdiregistrofiscal.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/valesdedespensa/valesdedespensa.xslt"/>
|
||||||
<xsl:include href="pagoenespecie.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/notariospublicos/notariospublicos.xslt"/>
|
||||||
<xsl:include href="aerolineas.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/vehiculousado/vehiculousado.xslt"/>
|
||||||
<xsl:include href="valesdedespensa.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/servicioparcialconstruccion/servicioparcialconstruccion.xslt"/>
|
||||||
<xsl:include href="consumodecombustibles.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/renovacionysustitucionvehiculos/renovacionysustitucionvehiculos.xslt"/>
|
||||||
<xsl:include href="notariospublicos.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/certificadodestruccion/certificadodedestruccion.xslt"/>
|
||||||
<xsl:include href="vehiculousado.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/arteantiguedades/obrasarteantiguedades.xslt"/>
|
||||||
<xsl:include href="servicioparcialconstruccion.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/ventavehiculos/ventavehiculos11.xslt"/>
|
||||||
<xsl:include href="renovacionysustitucionvehiculos.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/detallista/detallista.xslt"/>
|
||||||
<xsl:include href="certificadodedestruccion.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/EstadoDeCuentaCombustible/ecc12.xslt"/>
|
||||||
<xsl:include href="obrasarteantiguedades.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/consumodecombustibles/consumodeCombustibles11.xslt"/>
|
||||||
<xsl:include href="ventavehiculos11.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/GastosHidrocarburos10/GastosHidrocarburos10.xslt"/>
|
||||||
<xsl:include href="terceros11.xslt"/>
|
<xsl:include href="http://www.sat.gob.mx/sitio_internet/cfd/IngresosHidrocarburos10/IngresosHidrocarburos.xslt"/>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<!-- Aquí iniciamos el procesamiento de la cadena original con su | inicial y el terminador || -->
|
||||||
<!-- 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>
|
||||||
<xsl:template match="/">|<xsl:apply-templates select="/cfdi:Comprobante"/>||</xsl:template>
|
<!-- Aquí iniciamos el procesamiento de los datos incluidos en el comprobante -->
|
||||||
<!-- Aquí iniciamos el procesamiento de los datos incluidos en el comprobante -->
|
<xsl:template match="cfdi:Comprobante">
|
||||||
<xsl:template match="cfdi:Comprobante">
|
<!-- Iniciamos el tratamiento de los atributos de comprobante -->
|
||||||
<!-- Iniciamos el tratamiento de los atributos de comprobante -->
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@Version"/>
|
||||||
<xsl:with-param name="valor" select="./@Version"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:with-param name="valor" select="./@Serie"/>
|
||||||
<xsl:with-param name="valor" select="./@Serie"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:with-param name="valor" select="./@Folio"/>
|
||||||
<xsl:with-param name="valor" select="./@Folio"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@Fecha"/>
|
||||||
<xsl:with-param name="valor" select="./@Fecha"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:with-param name="valor" select="./@FormaPago"/>
|
||||||
<xsl:with-param name="valor" select="./@FormaPago"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@NoCertificado"/>
|
||||||
<xsl:with-param name="valor" select="./@NoCertificado"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:with-param name="valor" select="./@CondicionesDePago"/>
|
||||||
<xsl:with-param name="valor" select="./@CondicionesDePago"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@SubTotal"/>
|
||||||
<xsl:with-param name="valor" select="./@SubTotal"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:with-param name="valor" select="./@Descuento"/>
|
||||||
<xsl:with-param name="valor" select="./@Descuento"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@Moneda"/>
|
||||||
<xsl:with-param name="valor" select="./@Moneda"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:with-param name="valor" select="./@TipoCambio"/>
|
||||||
<xsl:with-param name="valor" select="./@TipoCambio"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@Total"/>
|
||||||
<xsl:with-param name="valor" select="./@Total"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@TipoDeComprobante"/>
|
||||||
<xsl:with-param name="valor" select="./@TipoDeComprobante"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:with-param name="valor" select="./@Exportacion"/>
|
||||||
<xsl:with-param name="valor" select="./@MetodoPago"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@MetodoPago"/>
|
||||||
<xsl:with-param name="valor" select="./@LugarExpedicion"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:with-param name="valor" select="./@LugarExpedicion"/>
|
||||||
<xsl:with-param name="valor" select="./@Confirmacion"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<!--
|
<xsl:with-param name="valor" select="./@Confirmacion"/>
|
||||||
Llamadas para procesar al los sub nodos del comprobante
|
</xsl:call-template>
|
||||||
-->
|
<!--
|
||||||
<xsl:apply-templates select="./cfdi:CfdiRelacionados"/>
|
Llamadas para procesar al los sub nodos del comprobante
|
||||||
<xsl:apply-templates select="./cfdi:Emisor"/>
|
-->
|
||||||
<xsl:apply-templates select="./cfdi:Receptor"/>
|
<xsl:apply-templates select="./cfdi:InformacionGlobal"/>
|
||||||
<xsl:apply-templates select="./cfdi:Conceptos"/>
|
<xsl:apply-templates select="./cfdi:CfdiRelacionados"/>
|
||||||
<xsl:apply-templates select="./cfdi:Impuestos"/>
|
<xsl:apply-templates select="./cfdi:Emisor"/>
|
||||||
<xsl:for-each select="./cfdi:Complemento">
|
<xsl:apply-templates select="./cfdi:Receptor"/>
|
||||||
<xsl:apply-templates select="."/>
|
<xsl:apply-templates select="./cfdi:Conceptos"/>
|
||||||
</xsl:for-each>
|
<xsl:apply-templates select="./cfdi:Impuestos"/>
|
||||||
</xsl:template>
|
<xsl:for-each select="./cfdi:Complemento">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
<!-- Manejador de nodos tipo CFDIRelacionados -->
|
</xsl:for-each>
|
||||||
<xsl:template match="cfdi:CfdiRelacionados">
|
</xsl:template>
|
||||||
<!-- Iniciamos el tratamiento de los atributos del CFDIRelacionados -->
|
|
||||||
<xsl:call-template name="Requerido">
|
<!-- Manejador de nodos tipo InformacionGlobal -->
|
||||||
<xsl:with-param name="valor" select="./@TipoRelacion"/>
|
<xsl:template match="cfdi:InformacionGlobal">
|
||||||
</xsl:call-template>
|
<!-- Iniciamos el tratamiento de los atributos del nodo tipo InformacionGlobal -->
|
||||||
<xsl:for-each select="./cfdi:CfdiRelacionado">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@Periodicidad"/>
|
||||||
<xsl:with-param name="valor" select="./@UUID"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:for-each>
|
<xsl:with-param name="valor" select="./@Meses"/>
|
||||||
</xsl:template>
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
<!-- Manejador de nodos tipo Emisor -->
|
<xsl:with-param name="valor" select="./@Año"/>
|
||||||
<xsl:template match="cfdi:Emisor">
|
</xsl:call-template>
|
||||||
<!-- Iniciamos el tratamiento de los atributos del Emisor -->
|
</xsl:template>
|
||||||
<xsl:call-template name="Requerido">
|
|
||||||
<xsl:with-param name="valor" select="./@Rfc"/>
|
<!-- Manejador de nodos tipo CFDIRelacionados -->
|
||||||
</xsl:call-template>
|
<xsl:template match="cfdi:CfdiRelacionados">
|
||||||
<xsl:call-template name="Opcional">
|
<!-- Iniciamos el tratamiento de los atributos del nodo tipo CFDIRelacionados -->
|
||||||
<xsl:with-param name="valor" select="./@Nombre"/>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:call-template>
|
<xsl:with-param name="valor" select="./@TipoRelacion"/>
|
||||||
<xsl:call-template name="Requerido">
|
</xsl:call-template>
|
||||||
<xsl:with-param name="valor" select="./@RegimenFiscal"/>
|
<xsl:for-each select="./cfdi:CfdiRelacionado">
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:template>
|
<xsl:with-param name="valor" select="./@UUID"/>
|
||||||
|
</xsl:call-template>
|
||||||
<!-- Manejador de nodos tipo Receptor -->
|
</xsl:for-each>
|
||||||
<xsl:template match="cfdi:Receptor">
|
</xsl:template>
|
||||||
<!-- Iniciamos el tratamiento de los atributos del Receptor -->
|
|
||||||
<xsl:call-template name="Requerido">
|
<!-- Manejador de nodos tipo Emisor -->
|
||||||
<xsl:with-param name="valor" select="./@Rfc"/>
|
<xsl:template match="cfdi:Emisor">
|
||||||
</xsl:call-template>
|
<!-- Iniciamos el tratamiento de los atributos del nodo tipo Emisor -->
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:with-param name="valor" select="./@Nombre"/>
|
<xsl:with-param name="valor" select="./@Rfc"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:with-param name="valor" select="./@ResidenciaFiscal"/>
|
<xsl:with-param name="valor" select="./@Nombre"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:with-param name="valor" select="./@NumRegIdTrib"/>
|
<xsl:with-param name="valor" select="./@RegimenFiscal"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:with-param name="valor" select="./@UsoCFDI"/>
|
<xsl:with-param name="valor" select="./@FacAtrAdquirente"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
|
</xsl:template>
|
||||||
</xsl:template>
|
|
||||||
|
<!-- Manejador de nodos tipo Receptor -->
|
||||||
<!-- Manejador de nodos tipo Conceptos -->
|
<xsl:template match="cfdi:Receptor">
|
||||||
<xsl:template match="cfdi:Conceptos">
|
<!-- Iniciamos el tratamiento de los atributos del nodo tipo Receptor -->
|
||||||
<!-- Llamada para procesar los distintos nodos tipo Concepto -->
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:for-each select="./cfdi:Concepto">
|
<xsl:with-param name="valor" select="./@Rfc"/>
|
||||||
<xsl:apply-templates select="."/>
|
</xsl:call-template>
|
||||||
</xsl:for-each>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:template>
|
<xsl:with-param name="valor" select="./@Nombre"/>
|
||||||
|
</xsl:call-template>
|
||||||
<!--Manejador de nodos tipo Concepto-->
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:template match="cfdi:Concepto">
|
<xsl:with-param name="valor" select="./@DomicilioFiscalReceptor"/>
|
||||||
<!-- Iniciamos el tratamiento de los atributos del Concepto -->
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:with-param name="valor" select="./@ClaveProdServ"/>
|
<xsl:with-param name="valor" select="./@ResidenciaFiscal"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:with-param name="valor" select="./@NoIdentificacion"/>
|
<xsl:with-param name="valor" select="./@NumRegIdTrib"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:with-param name="valor" select="./@Cantidad"/>
|
<xsl:with-param name="valor" select="./@RegimenFiscalReceptor"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:with-param name="valor" select="./@ClaveUnidad"/>
|
<xsl:with-param name="valor" select="./@UsoCFDI"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Opcional">
|
|
||||||
<xsl:with-param name="valor" select="./@Unidad"/>
|
</xsl:template>
|
||||||
</xsl:call-template>
|
|
||||||
<xsl:call-template name="Requerido">
|
<!-- Manejador de nodos tipo Conceptos -->
|
||||||
<xsl:with-param name="valor" select="./@Descripcion"/>
|
<xsl:template match="cfdi:Conceptos">
|
||||||
</xsl:call-template>
|
<!-- Llamada para procesar los distintos nodos tipo Concepto -->
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:for-each select="./cfdi:Concepto">
|
||||||
<xsl:with-param name="valor" select="./@ValorUnitario"/>
|
<xsl:apply-templates select="."/>
|
||||||
</xsl:call-template>
|
</xsl:for-each>
|
||||||
<xsl:call-template name="Requerido">
|
</xsl:template>
|
||||||
<xsl:with-param name="valor" select="./@Importe"/>
|
|
||||||
</xsl:call-template>
|
<!--Manejador de nodos tipo Concepto-->
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:template match="cfdi:Concepto">
|
||||||
<xsl:with-param name="valor" select="./@Descuento"/>
|
<!-- Iniciamos el tratamiento de los atributos del Concepto -->
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ClaveProdServ"/>
|
||||||
<!-- Manejo de sub nodos de información Traslado de Conceptos:Concepto:Impuestos:Traslados-->
|
</xsl:call-template>
|
||||||
<xsl:for-each select="./cfdi:Impuestos/cfdi:Traslados/cfdi:Traslado">
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@NoIdentificacion"/>
|
||||||
<xsl:with-param name="valor" select="./@Base"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@Cantidad"/>
|
||||||
<xsl:with-param name="valor" select="./@Impuesto"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@ClaveUnidad"/>
|
||||||
<xsl:with-param name="valor" select="./@TipoFactor"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:with-param name="valor" select="./@Unidad"/>
|
||||||
<xsl:with-param name="valor" select="./@TasaOCuota"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:with-param name="valor" select="./@Descripcion"/>
|
||||||
<xsl:with-param name="valor" select="./@Importe"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:for-each>
|
<xsl:with-param name="valor" select="./@ValorUnitario"/>
|
||||||
|
</xsl:call-template>
|
||||||
<!-- Manejo de sub nodos de Retencion por cada una de los Conceptos:Concepto:Impuestos:Retenciones-->
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:for-each select="./cfdi:Impuestos/cfdi:Retenciones/cfdi:Retencion">
|
<xsl:with-param name="valor" select="./@Importe"/>
|
||||||
<xsl:call-template name="Requerido">
|
</xsl:call-template>
|
||||||
<xsl:with-param name="valor" select="./@Base"/>
|
<xsl:call-template name="Opcional">
|
||||||
</xsl:call-template>
|
<xsl:with-param name="valor" select="./@Descuento"/>
|
||||||
<xsl:call-template name="Requerido">
|
</xsl:call-template>
|
||||||
<xsl:with-param name="valor" select="./@Impuesto"/>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:call-template>
|
<xsl:with-param name="valor" select="./@ObjetoImp"/>
|
||||||
<xsl:call-template name="Requerido">
|
</xsl:call-template>
|
||||||
<xsl:with-param name="valor" select="./@TipoFactor"/>
|
|
||||||
</xsl:call-template>
|
<!-- Manejo de sub nodos de información Traslado de Conceptos:Concepto:Impuestos:Traslados-->
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:for-each select="./cfdi:Impuestos/cfdi:Traslados/cfdi:Traslado">
|
||||||
<xsl:with-param name="valor" select="./@TasaOCuota"/>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:call-template>
|
<xsl:with-param name="valor" select="./@Base"/>
|
||||||
<xsl:call-template name="Requerido">
|
</xsl:call-template>
|
||||||
<xsl:with-param name="valor" select="./@Importe"/>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:call-template>
|
<xsl:with-param name="valor" select="./@Impuesto"/>
|
||||||
</xsl:for-each>
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
<!-- Manejo de los distintos sub nodos de información aduanera de forma indistinta a su grado de dependencia -->
|
<xsl:with-param name="valor" select="./@TipoFactor"/>
|
||||||
<xsl:for-each select="./cfdi:InformacionAduanera">
|
</xsl:call-template>
|
||||||
<xsl:apply-templates select="."/>
|
<xsl:call-template name="Opcional">
|
||||||
</xsl:for-each>
|
<xsl:with-param name="valor" select="./@TasaOCuota"/>
|
||||||
|
</xsl:call-template>
|
||||||
<!-- Llamada al manejador de nodos de CuentaPredial en caso de existir -->
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:if test="./cfdi:CuentaPredial">
|
<xsl:with-param name="valor" select="./@Importe"/>
|
||||||
<xsl:apply-templates select="./cfdi:CuentaPredial"/>
|
</xsl:call-template>
|
||||||
</xsl:if>
|
</xsl:for-each>
|
||||||
|
|
||||||
<!-- Llamada al manejador de nodos de ComplementoConcepto en caso de existir -->
|
<!-- Manejo de sub nodos de Retencion por cada una de los Conceptos:Concepto:Impuestos:Retenciones-->
|
||||||
<xsl:if test="./cfdi:ComplementoConcepto">
|
<xsl:for-each select="./cfdi:Impuestos/cfdi:Retenciones/cfdi:Retencion">
|
||||||
<xsl:apply-templates select="./cfdi:ComplementoConcepto"/>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:if>
|
<xsl:with-param name="valor" select="./@Base"/>
|
||||||
|
</xsl:call-template>
|
||||||
<!-- Llamada al manejador de nodos de Parte en caso de existir -->
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:for-each select=".//cfdi:Parte">
|
<xsl:with-param name="valor" select="./@Impuesto"/>
|
||||||
<xsl:apply-templates select="."/>
|
</xsl:call-template>
|
||||||
</xsl:for-each>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:template>
|
<xsl:with-param name="valor" select="./@TipoFactor"/>
|
||||||
|
</xsl:call-template>
|
||||||
<!-- Manejador de nodos tipo Información Aduanera -->
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:template match="cfdi:InformacionAduanera">
|
<xsl:with-param name="valor" select="./@TasaOCuota"/>
|
||||||
<!-- Manejo de los atributos de la información aduanera -->
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:with-param name="valor" select="./@NumeroPedimento"/>
|
<xsl:with-param name="valor" select="./@Importe"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
</xsl:template>
|
</xsl:for-each>
|
||||||
|
|
||||||
<!-- Manejador de nodos tipo Información CuentaPredial -->
|
<!-- Manejo de los distintos sub nodos a cuenta de terceros de forma indistinta a su grado de dependencia -->
|
||||||
<xsl:template match="cfdi:CuentaPredial">
|
<xsl:for-each select="./cfdi:ACuentaTerceros">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:apply-templates select="."/>
|
||||||
<xsl:with-param name="valor" select="./@Numero"/>
|
</xsl:for-each>
|
||||||
</xsl:call-template>
|
|
||||||
</xsl:template>
|
<!-- Manejo de los distintos sub nodos de información aduanera de forma indistinta a su grado de dependencia -->
|
||||||
|
<xsl:for-each select="./cfdi:InformacionAduanera">
|
||||||
<!-- Manejador de nodos tipo ComplementoConcepto -->
|
<xsl:apply-templates select="."/>
|
||||||
<xsl:template match="cfdi:ComplementoConcepto">
|
</xsl:for-each>
|
||||||
<xsl:for-each select="./*">
|
|
||||||
<xsl:apply-templates select="."/>
|
<!-- Llamada al manejador de nodos de CuentaPredial en caso de existir -->
|
||||||
</xsl:for-each>
|
<xsl:if test="./cfdi:CuentaPredial">
|
||||||
</xsl:template>
|
<xsl:apply-templates select="./cfdi:CuentaPredial"/>
|
||||||
|
</xsl:if>
|
||||||
<!-- Manejador de nodos tipo Parte -->
|
|
||||||
<xsl:template match="cfdi:Parte">
|
<!-- Llamada al manejador de nodos de ComplementoConcepto en caso de existir -->
|
||||||
<!-- Iniciamos el tratamiento de los atributos de Parte-->
|
<xsl:if test="./cfdi:ComplementoConcepto">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:apply-templates select="./cfdi:ComplementoConcepto"/>
|
||||||
<xsl:with-param name="valor" select="./@ClaveProdServ"/>
|
</xsl:if>
|
||||||
</xsl:call-template>
|
|
||||||
<xsl:call-template name="Opcional">
|
<!-- Llamada al manejador de nodos de Parte en caso de existir -->
|
||||||
<xsl:with-param name="valor" select="./@NoIdentificacion"/>
|
<xsl:for-each select=".//cfdi:Parte">
|
||||||
</xsl:call-template>
|
<xsl:apply-templates select="."/>
|
||||||
<xsl:call-template name="Requerido">
|
</xsl:for-each>
|
||||||
<xsl:with-param name="valor" select="./@Cantidad"/>
|
</xsl:template>
|
||||||
</xsl:call-template>
|
|
||||||
<xsl:call-template name="Opcional">
|
<!-- Manejador de nodos tipo ACuentaTerceros -->
|
||||||
<xsl:with-param name="valor" select="./@Unidad"/>
|
<xsl:template match="cfdi:ACuentaTerceros">
|
||||||
</xsl:call-template>
|
<!-- Manejo de los atributos del nodo tipo ACuentaTerceros -->
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:with-param name="valor" select="./@Descripcion"/>
|
<xsl:with-param name="valor" select="./@RfcACuentaTerceros"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:with-param name="valor" select="./@ValorUnitario"/>
|
<xsl:with-param name="valor" select="./@NombreACuentaTerceros"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:with-param name="valor" select="./@Importe"/>
|
<xsl:with-param name="valor" select="./@RegimenFiscalACuentaTerceros"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
<!-- Manejador de nodos tipo InformacionAduanera-->
|
<xsl:with-param name="valor" select="./@DomicilioFiscalACuentaTerceros"/>
|
||||||
<xsl:for-each select=".//cfdi:InformacionAduanera">
|
</xsl:call-template>
|
||||||
<xsl:apply-templates select="."/>
|
</xsl:template>
|
||||||
</xsl:for-each>
|
|
||||||
</xsl:template>
|
<!-- Manejador de nodos tipo Información Aduanera -->
|
||||||
|
<xsl:template match="cfdi:InformacionAduanera">
|
||||||
<!-- Manejador de nodos tipo Complemento -->
|
<!-- Manejo de los atributos de la información aduanera -->
|
||||||
<xsl:template match="cfdi:Complemento">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:for-each select="./*">
|
<xsl:with-param name="valor" select="./@NumeroPedimento"/>
|
||||||
<xsl:apply-templates select="."/>
|
</xsl:call-template>
|
||||||
</xsl:for-each>
|
</xsl:template>
|
||||||
</xsl:template>
|
|
||||||
|
<!-- Manejador de nodos tipo Información CuentaPredial -->
|
||||||
<!-- Manejador de nodos tipo Domicilio fiscal -->
|
<xsl:template match="cfdi:CuentaPredial">
|
||||||
<xsl:template match="cfdi:Impuestos">
|
<xsl:call-template name="Requerido">
|
||||||
<!-- Manejo de sub nodos de Retencion por cada una de los Impuestos:Retenciones-->
|
<xsl:with-param name="valor" select="./@Numero"/>
|
||||||
<xsl:for-each select="./cfdi:Retenciones/cfdi:Retencion">
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Requerido">
|
</xsl:template>
|
||||||
<xsl:with-param name="valor" select="./@Impuesto"/>
|
|
||||||
</xsl:call-template>
|
<!-- Manejador de nodos tipo ComplementoConcepto -->
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:template match="cfdi:ComplementoConcepto">
|
||||||
<xsl:with-param name="valor" select="./@Importe"/>
|
<xsl:for-each select="./*">
|
||||||
</xsl:call-template>
|
<xsl:apply-templates select="."/>
|
||||||
</xsl:for-each>
|
</xsl:for-each>
|
||||||
<!-- Iniciamos el tratamiento de los atributos de TotalImpuestosRetenidos-->
|
</xsl:template>
|
||||||
<xsl:call-template name="Opcional">
|
|
||||||
<xsl:with-param name="valor" select="./@TotalImpuestosRetenidos"/>
|
<!-- Manejador de nodos tipo Parte -->
|
||||||
</xsl:call-template>
|
<xsl:template match="cfdi:Parte">
|
||||||
<!-- Manejo de sub nodos de información Traslado de Impuestos:Traslados-->
|
<!-- Iniciamos el tratamiento de los atributos de Parte-->
|
||||||
<xsl:for-each select="./cfdi:Traslados/cfdi:Traslado">
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@ClaveProdServ"/>
|
||||||
<xsl:with-param name="valor" select="./@Impuesto"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@NoIdentificacion"/>
|
||||||
<xsl:with-param name="valor" select="./@TipoFactor"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@Cantidad"/>
|
||||||
<xsl:with-param name="valor" select="./@TasaOCuota"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:call-template name="Requerido">
|
<xsl:with-param name="valor" select="./@Unidad"/>
|
||||||
<xsl:with-param name="valor" select="./@Importe"/>
|
</xsl:call-template>
|
||||||
</xsl:call-template>
|
<xsl:call-template name="Requerido">
|
||||||
</xsl:for-each>
|
<xsl:with-param name="valor" select="./@Descripcion"/>
|
||||||
<!-- Iniciamos el tratamiento de los atributos de TotalImpuestosTrasladados-->
|
</xsl:call-template>
|
||||||
<xsl:call-template name="Opcional">
|
<xsl:call-template name="Opcional">
|
||||||
<xsl:with-param name="valor" select="./@TotalImpuestosTrasladados"/>
|
<xsl:with-param name="valor" select="./@ValorUnitario"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
</xsl:template>
|
<xsl:call-template name="Opcional">
|
||||||
</xsl:stylesheet>
|
<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="./@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>
|
||||||
|
<!-- 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>
|
||||||
|
|
|
@ -0,0 +1,347 @@
|
||||||
|
<?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="servicioconstruccion.xslt"/>
|
||||||
|
<xsl:include href="cartaporte20.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>
|
|
@ -0,0 +1,233 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<xsl:stylesheet version="2.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:pago20="http://www.sat.gob.mx/Pagos20">
|
||||||
|
|
||||||
|
<xsl:template match="pago20: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 de tipo Totales. -->
|
||||||
|
<xsl:for-each select="./pago20:Totales">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
|
||||||
|
<!-- Iniciamos el manejo de los elementos de tipo Pago. -->
|
||||||
|
<xsl:for-each select="./pago20:Pago">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<!-- Iniciamos el tratamiento de los atributos de pago20:Totales. -->
|
||||||
|
<xsl:template match="pago20:Totales">
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalRetencionesIVA" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalRetencionesISR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalRetencionesIEPS" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalTrasladosBaseIVA16" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalTrasladosImpuestoIVA16" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalTrasladosBaseIVA8" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalTrasladosImpuestoIVA8" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalTrasladosBaseIVA0" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalTrasladosImpuestoIVA0" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalTrasladosBaseIVAExento" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@MontoTotalPagos" />
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<!-- Iniciamos el tratamiento de los atributos de pago20:Pago -->
|
||||||
|
<xsl:template match="pago20: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 pago20:DocumentoRelacionado. -->
|
||||||
|
<xsl:for-each select="./pago20:DoctoRelacionado">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
|
||||||
|
<!-- Iniciamos el tratamiento de los atributos de pago20:ImpuestosP. -->
|
||||||
|
<xsl:for-each select="./pago20:ImpuestosP">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<!-- Iniciamos el tratamiento de los atributos de pago20:DoctoRelacionado. -->
|
||||||
|
<xsl:template match="pago20: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="./@EquivalenciaDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@NumParcialidad" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ImpSaldoAnt" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ImpPagado" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ImpSaldoInsoluto" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ObjetoImpDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<!-- Iniciamos el tratamiento de los atributos del subnodo ImpuestosDR-RetencionesDR-RetencionDR. -->
|
||||||
|
<xsl:for-each select="./pago20:ImpuestosDR/pago20:RetencionesDR/pago20:RetencionDR">
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@BaseDR"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ImpuestoDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@TipoFactorDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@TasaOCuotaDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ImporteDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:for-each>
|
||||||
|
|
||||||
|
<!-- Iniciamos el tratamiento de los atributos del subnodo ImpuestosDR-TrasladosDR-TrasladoDR. -->
|
||||||
|
<xsl:for-each select="./pago20:ImpuestosDR/pago20:TrasladosDR/pago20:TrasladoDR">
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@BaseDR"/>
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ImpuestoDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@TipoFactorDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TasaOCuotaDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@ImporteDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<!-- Iniciamos el tratamiento de los atributos de pago20:ImpuestosP. -->
|
||||||
|
<xsl:template match="pago20:ImpuestosP">
|
||||||
|
<xsl:apply-templates select="./pago20:RetencionesP"/>
|
||||||
|
<xsl:apply-templates select="./pago20:TrasladosP"/>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago20:RetencionesP">
|
||||||
|
<xsl:for-each select="./pago20:RetencionP">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago20:TrasladosP">
|
||||||
|
<xsl:for-each select="./pago20:TrasladoP">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago20:RetencionP">
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ImpuestoP" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ImporteP" />
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago20:TrasladoP">
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@BaseP" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@ImpuestoP" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@TipoFactorP" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TasaOCuotaP" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@ImporteP" />
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
|
@ -1,22 +1,22 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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">
|
<xsl:stylesheet version="2.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">
|
||||||
|
|
||||||
<!-- Manejador de datos requeridos -->
|
<!-- Manejador de datos requeridos -->
|
||||||
<xsl:template name="Requerido">
|
<xsl:template name="Requerido">
|
||||||
<xsl:param name="valor"/>|<xsl:call-template name="ManejaEspacios">
|
<xsl:param name="valor"/>|<xsl:call-template name="ManejaEspacios">
|
||||||
<xsl:with-param name="s" select="$valor"/>
|
<xsl:with-param name="s" select="$valor"/>
|
||||||
</xsl:call-template>
|
</xsl:call-template>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<!-- Manejador de datos opcionales -->
|
<!-- Manejador de datos opcionales -->
|
||||||
<xsl:template name="Opcional">
|
<xsl:template name="Opcional">
|
||||||
<xsl:param name="valor"/>
|
<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:if test="$valor">|<xsl:call-template name="ManejaEspacios"><xsl:with-param name="s" select="$valor"/></xsl:call-template></xsl:if>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<!-- Normalizador de espacios en blanco -->
|
<!-- Normalizador de espacios en blanco -->
|
||||||
<xsl:template name="ManejaEspacios">
|
<xsl:template name="ManejaEspacios">
|
||||||
<xsl:param name="s"/>
|
<xsl:param name="s"/>
|
||||||
<xsl:value-of select="normalize-space(string($s))"/>
|
<xsl:value-of select="normalize-space(string($s))"/>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
</xsl:stylesheet>
|
</xsl:stylesheet>
|
||||||
|
|
|
@ -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>
|
Loading…
Reference in New Issue