forked from elmau/empresa-libre
Merge branch 'pagos' into develop
Soporte para complemento de pagos
This commit is contained in:
commit
b202827ee0
14
CHANGELOG.md
14
CHANGELOG.md
|
@ -1,3 +1,17 @@
|
||||||
|
v 1.12.0 [31-ago-2018]
|
||||||
|
----------------------
|
||||||
|
- Soporte para facturas (complemento) de pago.
|
||||||
|
|
||||||
|
* IMPORTANTE: Es necesario realizar una migración, despues de actualizar la rama principal.
|
||||||
|
|
||||||
|
```
|
||||||
|
git pull origin master
|
||||||
|
|
||||||
|
cd source/app/models
|
||||||
|
|
||||||
|
python main.py -m
|
||||||
|
```
|
||||||
|
|
||||||
v 1.11.1 [21-ago-2018]
|
v 1.11.1 [21-ago-2018]
|
||||||
----------------------
|
----------------------
|
||||||
- Fix - Quitar columna en tabla facturaspagos.
|
- Fix - Quitar columna en tabla facturaspagos.
|
||||||
|
|
|
@ -1,4 +1,20 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# ~ Empresa Libre
|
||||||
|
# ~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||||
|
# ~
|
||||||
|
# ~ This program is free software: you can redistribute it and/or modify
|
||||||
|
# ~ it under the terms of the GNU General Public License as published by
|
||||||
|
# ~ the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# ~ (at your option) any later version.
|
||||||
|
# ~
|
||||||
|
# ~ This program is distributed in the hope that it will be useful,
|
||||||
|
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# ~ GNU General Public License for more details.
|
||||||
|
# ~
|
||||||
|
# ~ You should have received a copy of the GNU General Public License
|
||||||
|
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
from xml.etree import ElementTree as ET
|
from xml.etree import ElementTree as ET
|
||||||
|
@ -6,8 +22,6 @@ from xml.dom.minidom import parseString
|
||||||
|
|
||||||
from logbook import Logger
|
from logbook import Logger
|
||||||
|
|
||||||
#~ from settings import DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
log = Logger('XML')
|
log = Logger('XML')
|
||||||
CFDI_ACTUAL = 'cfdi33'
|
CFDI_ACTUAL = 'cfdi33'
|
||||||
|
@ -64,6 +78,12 @@ SAT = {
|
||||||
'xmlns': 'http://www.sat.gob.mx/iedu',
|
'xmlns': 'http://www.sat.gob.mx/iedu',
|
||||||
'schema': ' http://www.sat.gob.mx/iedu http://www.sat.gob.mx/sitio_internet/cfd/ine/iedu.xsd',
|
'schema': ' http://www.sat.gob.mx/iedu http://www.sat.gob.mx/sitio_internet/cfd/ine/iedu.xsd',
|
||||||
},
|
},
|
||||||
|
'pagos': {
|
||||||
|
'version': '1.0',
|
||||||
|
'prefix': 'pago10',
|
||||||
|
'xmlns': 'http://www.sat.gob.mx/Pagos',
|
||||||
|
'schema': ' http://www.sat.gob.mx/Pagos http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd',
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,6 +99,7 @@ class CFDI(object):
|
||||||
self._donativo = False
|
self._donativo = False
|
||||||
self._ine = False
|
self._ine = False
|
||||||
self._edu = False
|
self._edu = False
|
||||||
|
self._pagos = False
|
||||||
self._is_nomina = False
|
self._is_nomina = False
|
||||||
self.error = ''
|
self.error = ''
|
||||||
|
|
||||||
|
@ -129,6 +150,7 @@ class CFDI(object):
|
||||||
if datos['complementos']:
|
if datos['complementos']:
|
||||||
if 'ine' in datos['complementos']:
|
if 'ine' in datos['complementos']:
|
||||||
self._ine = True
|
self._ine = True
|
||||||
|
self._pagos = bool(datos['complementos'].get('pagos', False))
|
||||||
|
|
||||||
if 'nomina' in datos:
|
if 'nomina' in datos:
|
||||||
self._is_nomina = True
|
self._is_nomina = True
|
||||||
|
@ -174,9 +196,15 @@ class CFDI(object):
|
||||||
attributes[name] = SAT['nomina']['xmlns']
|
attributes[name] = SAT['nomina']['xmlns']
|
||||||
schema_nomina = SAT['nomina']['schema']
|
schema_nomina = SAT['nomina']['schema']
|
||||||
|
|
||||||
|
schema_pagos = ''
|
||||||
|
if self._pagos:
|
||||||
|
name = 'xmlns:{}'.format(SAT['pagos']['prefix'])
|
||||||
|
attributes[name] = SAT['pagos']['xmlns']
|
||||||
|
schema_pagos = SAT['pagos']['schema']
|
||||||
|
|
||||||
attributes['xsi:schemaLocation'] = self._sat_cfdi['schema'] + \
|
attributes['xsi:schemaLocation'] = self._sat_cfdi['schema'] + \
|
||||||
schema_locales + schema_donativo + schema_ine + schema_edu + \
|
schema_locales + schema_donativo + schema_ine + schema_edu + \
|
||||||
schema_nomina
|
schema_nomina + schema_pagos
|
||||||
attributes.update(datos)
|
attributes.update(datos)
|
||||||
|
|
||||||
if not 'Version' in attributes:
|
if not 'Version' in attributes:
|
||||||
|
@ -403,6 +431,17 @@ class CFDI(object):
|
||||||
atributos.update(datos['ine'])
|
atributos.update(datos['ine'])
|
||||||
ET.SubElement(self._complemento, 'ine:INE', atributos)
|
ET.SubElement(self._complemento, 'ine:INE', atributos)
|
||||||
|
|
||||||
|
if 'pagos' in datos:
|
||||||
|
datos = datos.pop('pagos')
|
||||||
|
relacionados = datos.pop('relacionados')
|
||||||
|
pre = SAT['pagos']['prefix']
|
||||||
|
attributes = {'Version': SAT['pagos']['version']}
|
||||||
|
pagos = ET.SubElement(
|
||||||
|
self._complemento, '{}:Pagos'.format(pre), attributes)
|
||||||
|
node_pago = ET.SubElement(pagos, '{}:Pago'.format(pre), datos)
|
||||||
|
for row in relacionados:
|
||||||
|
ET.SubElement(node_pago, '{}:DoctoRelacionado'.format(pre), row)
|
||||||
|
|
||||||
if 'ce' in datos:
|
if 'ce' in datos:
|
||||||
pre = 'cce11'
|
pre = 'cce11'
|
||||||
datos = datos.pop('ce')
|
datos = datos.pop('ce')
|
||||||
|
|
|
@ -514,3 +514,31 @@ class AppDocumentos(object):
|
||||||
'attachment; filename={}'.format(file_name))
|
'attachment; filename={}'.format(file_name))
|
||||||
resp.content_type = content_type
|
resp.content_type = content_type
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
|
||||||
|
# ~ Revisado
|
||||||
|
class AppInvoicePay(object):
|
||||||
|
|
||||||
|
def __init__(self, db):
|
||||||
|
self._db = db
|
||||||
|
|
||||||
|
def on_get(self, req, resp):
|
||||||
|
values = req.params
|
||||||
|
req.context['result'] = self._db.get_invoicepay(values)
|
||||||
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
|
||||||
|
class AppCfdiPay(object):
|
||||||
|
|
||||||
|
def __init__(self, db):
|
||||||
|
self._db = db
|
||||||
|
|
||||||
|
def on_get(self, req, resp):
|
||||||
|
values = req.params
|
||||||
|
req.context['result'] = self._db.get_cfdipay(values)
|
||||||
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
def on_post(self, req, resp):
|
||||||
|
values = req.params
|
||||||
|
req.context['result'] = self._db.cfdipay(values)
|
||||||
|
resp.status = falcon.HTTP_200
|
||||||
|
|
|
@ -320,6 +320,9 @@ def get_template_ods(name, default='plantilla_factura.ods'):
|
||||||
if is_file(path):
|
if is_file(path):
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
if 'pagos' in name:
|
||||||
|
default='plantilla_pagos.ods'
|
||||||
|
|
||||||
path = _join(PATH_TEMPLATES, default)
|
path = _join(PATH_TEMPLATES, default)
|
||||||
if is_file(path):
|
if is_file(path):
|
||||||
return path
|
return path
|
||||||
|
@ -954,6 +957,9 @@ class LIBO(object):
|
||||||
|
|
||||||
self._set_cell('{total_cantidades}', str(self._total_cantidades))
|
self._set_cell('{total_cantidades}', str(self._total_cantidades))
|
||||||
|
|
||||||
|
if self._pagos:
|
||||||
|
return
|
||||||
|
|
||||||
cell_title = self._set_cell('{subtotal.titulo}', 'SubTotal')
|
cell_title = self._set_cell('{subtotal.titulo}', 'SubTotal')
|
||||||
value = data['subtotal']
|
value = data['subtotal']
|
||||||
cell_value = self._set_cell('{subtotal}', value, value=True)
|
cell_value = self._set_cell('{subtotal}', value, value=True)
|
||||||
|
@ -1150,16 +1156,114 @@ class LIBO(object):
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _cfdipays(self, data):
|
||||||
|
related = data.pop('related', [])
|
||||||
|
for k, v in data.items():
|
||||||
|
if k.lower() in ('monto',):
|
||||||
|
self._set_cell('{pago.%s}' % k, v, value=True)
|
||||||
|
else:
|
||||||
|
self._set_cell('{pago.%s}' % k, v)
|
||||||
|
|
||||||
|
col1 = []
|
||||||
|
col2 = []
|
||||||
|
col3 = []
|
||||||
|
col4 = []
|
||||||
|
col5 = []
|
||||||
|
col6 = []
|
||||||
|
col7 = []
|
||||||
|
col8 = []
|
||||||
|
col9 = []
|
||||||
|
count = len(related)
|
||||||
|
for i, doc in enumerate(related):
|
||||||
|
uuid = doc['IdDocumento'].upper()
|
||||||
|
serie = doc['Serie']
|
||||||
|
folio = doc['Folio']
|
||||||
|
metodo_pago = doc['MetodoDePagoDR']
|
||||||
|
moneda = doc['MonedaDR']
|
||||||
|
parcialidad = doc['NumParcialidad']
|
||||||
|
saldo_anterior = doc['ImpSaldoAnt']
|
||||||
|
importe_pagado = doc['ImpPagado']
|
||||||
|
saldo_insoluto = doc['ImpSaldoInsoluto']
|
||||||
|
if i == 0:
|
||||||
|
cell_1 = self._set_cell('{doc.uuid}', uuid)
|
||||||
|
cell_2 = self._set_cell('{doc.serie}', serie)
|
||||||
|
cell_3 = self._set_cell('{doc.folio}', folio)
|
||||||
|
cell_4 = self._set_cell('{doc.metodopago}', metodo_pago)
|
||||||
|
cell_5 = self._set_cell('{doc.moneda}', moneda)
|
||||||
|
cell_6 = self._set_cell('{doc.parcialidad}', parcialidad)
|
||||||
|
cell_7 = self._set_cell('{doc.saldoanterior}', saldo_anterior, value=True)
|
||||||
|
cell_8 = self._set_cell('{doc.importepagado}', importe_pagado, value=True)
|
||||||
|
cell_9 = self._set_cell('{doc.saldoinsoluto}', saldo_insoluto, value=True)
|
||||||
|
else:
|
||||||
|
col1.append((uuid,))
|
||||||
|
col2.append((serie,))
|
||||||
|
col3.append((folio,))
|
||||||
|
col4.append((metodo_pago,))
|
||||||
|
col5.append((moneda,))
|
||||||
|
col6.append((parcialidad,))
|
||||||
|
col7.append((float(saldo_anterior),))
|
||||||
|
col8.append((float(importe_pagado),))
|
||||||
|
col9.append((float(saldo_insoluto),))
|
||||||
|
|
||||||
|
if count == 1:
|
||||||
|
return
|
||||||
|
|
||||||
|
count -= 1
|
||||||
|
row1 = cell_1.getCellAddress().Row + 1
|
||||||
|
row2 = row1 + count - 1
|
||||||
|
self._sheet.getRows().insertByIndex(row1, count)
|
||||||
|
self._copy_paste_rows(cell_1, count)
|
||||||
|
|
||||||
|
# ~ style_7 = self._get_style(cell_7)
|
||||||
|
# ~ style_8 = self._get_style(cell_8)
|
||||||
|
# ~ style_9 = self._get_style(cell_9)
|
||||||
|
|
||||||
|
col = cell_1.getCellAddress().Column
|
||||||
|
target1 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
|
||||||
|
col = cell_2.getCellAddress().Column
|
||||||
|
target2 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
|
||||||
|
col = cell_3.getCellAddress().Column
|
||||||
|
target3 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
|
||||||
|
col = cell_4.getCellAddress().Column
|
||||||
|
target4 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
|
||||||
|
col = cell_5.getCellAddress().Column
|
||||||
|
target5 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
|
||||||
|
col = cell_6.getCellAddress().Column
|
||||||
|
target6 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
|
||||||
|
col = cell_7.getCellAddress().Column
|
||||||
|
target7 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
|
||||||
|
col = cell_8.getCellAddress().Column
|
||||||
|
target8 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
|
||||||
|
col = cell_9.getCellAddress().Column
|
||||||
|
target9 = self._sheet.getCellRangeByPosition(col, row1, col, row2)
|
||||||
|
|
||||||
|
target1.setFormulaArray(tuple(col1))
|
||||||
|
target2.setDataArray(tuple(col2))
|
||||||
|
target3.setFormulaArray(tuple(col3))
|
||||||
|
target4.setDataArray(tuple(col4))
|
||||||
|
target5.setDataArray(tuple(col5))
|
||||||
|
target6.setDataArray(tuple(col6))
|
||||||
|
target7.setDataArray(tuple(col7))
|
||||||
|
target8.setDataArray(tuple(col8))
|
||||||
|
target9.setDataArray(tuple(col9))
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
def _render(self, data):
|
def _render(self, data):
|
||||||
self._set_search()
|
self._set_search()
|
||||||
self._es_pre = data.pop('es_pre', False)
|
self._es_pre = data.pop('es_pre', False)
|
||||||
self._is_ticket = data.pop('is_ticket', False)
|
self._is_ticket = data.pop('is_ticket', False)
|
||||||
self._currency = data['totales']['moneda']
|
self._currency = data['totales']['moneda']
|
||||||
|
self._pagos = data.pop('pagos', False)
|
||||||
|
|
||||||
self._comprobante(data['comprobante'])
|
self._comprobante(data['comprobante'])
|
||||||
self._emisor(data['emisor'])
|
self._emisor(data['emisor'])
|
||||||
self._receptor(data['receptor'])
|
self._receptor(data['receptor'])
|
||||||
self._conceptos(data['conceptos'])
|
self._conceptos(data['conceptos'])
|
||||||
|
|
||||||
|
if self._pagos:
|
||||||
|
self._cfdipays(data['pays'])
|
||||||
|
|
||||||
if 'nomina' in data and data['nomina']:
|
if 'nomina' in data and data['nomina']:
|
||||||
self._nomina(data['nomina'])
|
self._nomina(data['nomina'])
|
||||||
else:
|
else:
|
||||||
|
@ -1167,6 +1271,7 @@ class LIBO(object):
|
||||||
self._timbre(data['timbre'])
|
self._timbre(data['timbre'])
|
||||||
self._donataria(data['donataria'])
|
self._donataria(data['donataria'])
|
||||||
self._ine(data['ine'])
|
self._ine(data['ine'])
|
||||||
|
|
||||||
self._cancelado(data['cancelada'])
|
self._cancelado(data['cancelada'])
|
||||||
self._clean()
|
self._clean()
|
||||||
return
|
return
|
||||||
|
@ -1444,13 +1549,17 @@ def to_pdf(data, emisor_rfc, ods=False):
|
||||||
if 'nomina' in data and data['nomina']:
|
if 'nomina' in data and data['nomina']:
|
||||||
version = '{}_{}'.format(data['nomina']['version'], version)
|
version = '{}_{}'.format(data['nomina']['version'], version)
|
||||||
|
|
||||||
|
pagos = ''
|
||||||
|
if data.get('pagos', False):
|
||||||
|
pagos = '_pagos_'
|
||||||
|
|
||||||
if APP_LIBO:
|
if APP_LIBO:
|
||||||
app = LIBO()
|
app = LIBO()
|
||||||
if app.is_running:
|
if app.is_running:
|
||||||
donativo = ''
|
donativo = ''
|
||||||
if data['donativo']:
|
if data['donativo']:
|
||||||
donativo = '_donativo'
|
donativo = '_donativo'
|
||||||
name = '{}_{}{}.ods'.format(rfc.lower(), version, donativo)
|
name = '{}_{}{}{}.ods'.format(rfc.lower(), pagos, version, donativo)
|
||||||
path = get_template_ods(name)
|
path = get_template_ods(name)
|
||||||
if path:
|
if path:
|
||||||
return app.pdf(path, data, ods)
|
return app.pdf(path, data, ods)
|
||||||
|
@ -1553,6 +1662,7 @@ def _comprobante(doc, options):
|
||||||
'I': 'ingreso',
|
'I': 'ingreso',
|
||||||
'E': 'egreso',
|
'E': 'egreso',
|
||||||
'T': 'traslado',
|
'T': 'traslado',
|
||||||
|
'P': 'pago',
|
||||||
}
|
}
|
||||||
data['tipodecomprobante'] = tipos.get(data['tipodecomprobante'])
|
data['tipodecomprobante'] = tipos.get(data['tipodecomprobante'])
|
||||||
data['lugarexpedicion'] = \
|
data['lugarexpedicion'] = \
|
||||||
|
@ -1854,6 +1964,27 @@ def _nomina(doc, data, values, version_cfdi):
|
||||||
return info
|
return info
|
||||||
|
|
||||||
|
|
||||||
|
def _cfdipays(doc, data, version):
|
||||||
|
node = doc.find('{}Complemento/{}Pagos'.format(PRE[version], PRE['pagos']))
|
||||||
|
if node is None:
|
||||||
|
return {}
|
||||||
|
|
||||||
|
info = CaseInsensitiveDict(node.attrib.copy())
|
||||||
|
related = []
|
||||||
|
for n1 in node:
|
||||||
|
info.update(CaseInsensitiveDict(n1.attrib.copy()))
|
||||||
|
for n2 in n1:
|
||||||
|
related.append(CaseInsensitiveDict(n2.attrib.copy()))
|
||||||
|
|
||||||
|
info['related'] = related
|
||||||
|
|
||||||
|
data['comprobante']['totalenletras'] = to_letters(
|
||||||
|
float(info['monto']), info['monedap'])
|
||||||
|
data['comprobante']['moneda'] = info['monedap']
|
||||||
|
|
||||||
|
return info
|
||||||
|
|
||||||
|
|
||||||
def get_data_from_xml(invoice, values):
|
def get_data_from_xml(invoice, values):
|
||||||
data = {'cancelada': invoice.cancelada, 'donativo': False}
|
data = {'cancelada': invoice.cancelada, 'donativo': False}
|
||||||
if hasattr(invoice, 'donativo'):
|
if hasattr(invoice, 'donativo'):
|
||||||
|
@ -1878,6 +2009,9 @@ def get_data_from_xml(invoice, values):
|
||||||
data['comprobante'].update(data['timbre'])
|
data['comprobante'].update(data['timbre'])
|
||||||
|
|
||||||
data['nomina'] = _nomina(doc, data, values, version)
|
data['nomina'] = _nomina(doc, data, values, version)
|
||||||
|
data['pagos'] = values.get('pagos', False)
|
||||||
|
if data['pagos']:
|
||||||
|
data['pays'] = _cfdipays(doc, data, version)
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,8 @@ from controllers.main import (AppEmpresas,
|
||||||
AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig,
|
AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig,
|
||||||
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
|
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
|
||||||
AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco,
|
AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco,
|
||||||
AppMovimientosBanco, AppTickets, AppStudents, AppEmployees, AppNomina
|
AppMovimientosBanco, AppTickets, AppStudents, AppEmployees, AppNomina,
|
||||||
|
AppInvoicePay, AppCfdiPay
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,6 +56,8 @@ api.add_route('/movbanco', AppMovimientosBanco(db))
|
||||||
api.add_route('/students', AppStudents(db))
|
api.add_route('/students', AppStudents(db))
|
||||||
api.add_route('/employees', AppEmployees(db))
|
api.add_route('/employees', AppEmployees(db))
|
||||||
api.add_route('/nomina', AppNomina(db))
|
api.add_route('/nomina', AppNomina(db))
|
||||||
|
api.add_route('/invoicepay', AppInvoicePay(db))
|
||||||
|
api.add_route('/cfdipay', AppCfdiPay(db))
|
||||||
|
|
||||||
|
|
||||||
# ~ Activa si usas waitress y NO estas usando servidor web
|
# ~ Activa si usas waitress y NO estas usando servidor web
|
||||||
|
|
|
@ -412,3 +412,13 @@ class StorageEngine(object):
|
||||||
|
|
||||||
def importar_bdfl(self):
|
def importar_bdfl(self):
|
||||||
return main.importar_bdfl()
|
return main.importar_bdfl()
|
||||||
|
|
||||||
|
# ~ Revisado
|
||||||
|
def get_invoicepay(self, values):
|
||||||
|
return main.FacturasPagos.get_values(values)
|
||||||
|
|
||||||
|
def get_cfdipay(self, values):
|
||||||
|
return main.CfdiPagos.get_values(values)
|
||||||
|
|
||||||
|
def cfdipay(self, values):
|
||||||
|
return main.CfdiPagos.post(values)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
# ~ Empresa Libre
|
# ~ Empresa Libre
|
||||||
# ~ Copyright (C) 2018 Mauricio Baeza Servin (web@correolibre.net)
|
# ~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||||
# ~
|
# ~
|
||||||
# ~ This program is free software: you can redistribute it and/or modify
|
# ~ This program is free software: you can redistribute it and/or modify
|
||||||
# ~ it under the terms of the GNU General Public License as published by
|
# ~ it under the terms of the GNU General Public License as published by
|
||||||
|
@ -34,7 +34,8 @@ from controllers import util
|
||||||
from settings import log, DEBUG, VERSION, PATH_CP, COMPANIES, PRE, CURRENT_CFDI, \
|
from settings import log, DEBUG, VERSION, PATH_CP, COMPANIES, PRE, CURRENT_CFDI, \
|
||||||
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, CURRENT_CFDI_NOMINA, \
|
||||||
DEFAULT_SAT_NOMINA, DECIMALES_TAX, TITLE_APP, MV, DECIMALES_PRECIOS
|
DEFAULT_SAT_NOMINA, DECIMALES_TAX, TITLE_APP, MV, DECIMALES_PRECIOS, \
|
||||||
|
DEFAULT_SERIE_CFDIPAY, DEFAULT_TYPE_CFDIPAY
|
||||||
|
|
||||||
|
|
||||||
FORMAT = '{0:.2f}'
|
FORMAT = '{0:.2f}'
|
||||||
|
@ -213,6 +214,10 @@ def get_doc(type_doc, id, rfc):
|
||||||
data, file_name = util.get_log('nomina')
|
data, file_name = util.get_log('nomina')
|
||||||
elif type_doc == 'nompdf':
|
elif type_doc == 'nompdf':
|
||||||
data, file_name = CfdiNomina.get_pdf(id, rfc)
|
data, file_name = CfdiNomina.get_pdf(id, rfc)
|
||||||
|
elif type_doc == 'xmlpago':
|
||||||
|
data, file_name = CfdiPagos.get_file_xml(id)
|
||||||
|
elif type_doc == 'pdfpago':
|
||||||
|
data, file_name = CfdiPagos.get_file_pdf(id)
|
||||||
|
|
||||||
return data, file_name, content_type
|
return data, file_name, content_type
|
||||||
|
|
||||||
|
@ -891,10 +896,15 @@ class Certificado(BaseModel):
|
||||||
rfc = TextField(default='')
|
rfc = TextField(default='')
|
||||||
desde = DateTimeField(null=True)
|
desde = DateTimeField(null=True)
|
||||||
hasta = DateTimeField(null=True)
|
hasta = DateTimeField(null=True)
|
||||||
|
es_fiel = BooleanField(default=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.serie
|
return self.serie
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_cert(cls, is_fiel=False):
|
||||||
|
return Certificado.get(Certificado.es_fiel==is_fiel)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_data(cls):
|
def get_data(cls):
|
||||||
obj = cls.get_(cls)
|
obj = cls.get_(cls)
|
||||||
|
@ -1933,11 +1943,13 @@ class MovimientosBanco(BaseModel):
|
||||||
.select(
|
.select(
|
||||||
MovimientosBanco.id,
|
MovimientosBanco.id,
|
||||||
MovimientosBanco.fecha,
|
MovimientosBanco.fecha,
|
||||||
|
SATFormaPago.name.alias('way_payment'),
|
||||||
MovimientosBanco.numero_operacion,
|
MovimientosBanco.numero_operacion,
|
||||||
MovimientosBanco.descripcion,
|
MovimientosBanco.descripcion,
|
||||||
MovimientosBanco.retiro,
|
MovimientosBanco.retiro,
|
||||||
MovimientosBanco.deposito,
|
MovimientosBanco.deposito,
|
||||||
MovimientosBanco.saldo)
|
MovimientosBanco.saldo)
|
||||||
|
.join(SATFormaPago).switch(MovimientosBanco)
|
||||||
.where(filtros)
|
.where(filtros)
|
||||||
.dicts()
|
.dicts()
|
||||||
)
|
)
|
||||||
|
@ -1945,21 +1957,6 @@ class MovimientosBanco(BaseModel):
|
||||||
return {'ok': True, 'rows': rows}
|
return {'ok': True, 'rows': rows}
|
||||||
|
|
||||||
|
|
||||||
class CfdiPagos(BaseModel):
|
|
||||||
movimiento = ForeignKeyField(MovimientosBanco)
|
|
||||||
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
|
|
||||||
fecha_timbrado = DateTimeField(null=True)
|
|
||||||
xml = TextField(default='')
|
|
||||||
uuid = UUIDField(null=True)
|
|
||||||
estatus = TextField(default='Guardado')
|
|
||||||
estatus_sat = TextField(default='')
|
|
||||||
notas = TextField(default='')
|
|
||||||
cancelado = BooleanField(default=False)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
order_by = ('movimiento',)
|
|
||||||
|
|
||||||
|
|
||||||
class SATUsoCfdi(BaseModel):
|
class SATUsoCfdi(BaseModel):
|
||||||
key = TextField(index=True, unique=True)
|
key = TextField(index=True, unique=True)
|
||||||
name = TextField(default='', index=True)
|
name = TextField(default='', index=True)
|
||||||
|
@ -5220,6 +5217,366 @@ class FacturasPagos(BaseModel):
|
||||||
cls._actualizar_saldo_cliente(cls, fac.cliente, importe * -1)
|
cls._actualizar_saldo_cliente(cls, fac.cliente, importe * -1)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _get_related(self, values):
|
||||||
|
id = int(values['id'])
|
||||||
|
filters = (FacturasPagos.movimiento==id)
|
||||||
|
|
||||||
|
rows = tuple(FacturasPagos
|
||||||
|
.select(
|
||||||
|
Facturas.id,
|
||||||
|
Facturas.serie,
|
||||||
|
Facturas.folio,
|
||||||
|
Facturas.uuid,
|
||||||
|
Facturas.fecha,
|
||||||
|
Facturas.tipo_comprobante,
|
||||||
|
Facturas.estatus,
|
||||||
|
Socios.nombre.alias('cliente'),
|
||||||
|
Facturas.total,
|
||||||
|
FacturasPagos.saldo,
|
||||||
|
FacturasPagos.importe,
|
||||||
|
)
|
||||||
|
.join(Facturas).switch(FacturasPagos)
|
||||||
|
.join(Socios, on=(Facturas.cliente==Socios.id))
|
||||||
|
.where(filters)
|
||||||
|
.dicts()
|
||||||
|
)
|
||||||
|
|
||||||
|
return {'ok': True, 'rows': rows}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_values(cls, values):
|
||||||
|
opt = values.pop('opt')
|
||||||
|
return getattr(cls, '_get_{}'.format(opt))(cls, values)
|
||||||
|
|
||||||
|
|
||||||
|
class CfdiPagos(BaseModel):
|
||||||
|
movimiento = ForeignKeyField(MovimientosBanco)
|
||||||
|
socio = ForeignKeyField(Socios)
|
||||||
|
serie = TextField(default='')
|
||||||
|
folio = IntegerField(default=0)
|
||||||
|
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
|
||||||
|
fecha_timbrado = DateTimeField(null=True)
|
||||||
|
tipo_comprobante = TextField(default=DEFAULT_TYPE_CFDIPAY)
|
||||||
|
lugar_expedicion = TextField(default='')
|
||||||
|
regimen_fiscal = TextField(default='')
|
||||||
|
tipo_relacion = TextField(default='')
|
||||||
|
uuid_relacionado = UUIDField(null=True)
|
||||||
|
xml = TextField(default='')
|
||||||
|
uuid = UUIDField(null=True)
|
||||||
|
estatus = TextField(default='Guardada')
|
||||||
|
estatus_sat = TextField(default='')
|
||||||
|
notas = TextField(default='')
|
||||||
|
error = TextField(default='')
|
||||||
|
cancelada = BooleanField(default=False)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
order_by = ('movimiento',)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def post(cls, values):
|
||||||
|
opt = values.pop('opt')
|
||||||
|
return getattr(cls, '_{}'.format(opt))(cls, values)
|
||||||
|
|
||||||
|
def _get_folio(self, serie):
|
||||||
|
folio = int(Configuracion.get_('txt_config_cfdipay_folio') or '0')
|
||||||
|
start = (CfdiPagos
|
||||||
|
.select(fn.Max(CfdiPagos.folio).alias('mf'))
|
||||||
|
.where(CfdiPagos.serie==serie)
|
||||||
|
.order_by(SQL('mf'))
|
||||||
|
.scalar())
|
||||||
|
|
||||||
|
if start is None:
|
||||||
|
next_folio = 1
|
||||||
|
else:
|
||||||
|
next_folio = start + 1
|
||||||
|
|
||||||
|
if folio > next_folio:
|
||||||
|
next_folio = folio
|
||||||
|
|
||||||
|
return next_folio
|
||||||
|
|
||||||
|
def _new(self, values):
|
||||||
|
id_mov = int(values['id_mov'])
|
||||||
|
|
||||||
|
filters = (FacturasPagos.movimiento==id_mov)
|
||||||
|
related = FacturasPagos.select().where(filters)
|
||||||
|
if not related:
|
||||||
|
msg = 'El pago no tiene facturas relacionadas'
|
||||||
|
data = {'ok': False, 'msg': msg}
|
||||||
|
return data
|
||||||
|
|
||||||
|
partner = tuple(set([f.factura.cliente.id for f in related]))
|
||||||
|
if len(partner) > 1:
|
||||||
|
msg = 'Facturas relacionadas a diferentes clientes'
|
||||||
|
data = {'ok': False, 'msg': msg}
|
||||||
|
return data
|
||||||
|
|
||||||
|
partner = partner[0]
|
||||||
|
partner_name = related[0].factura.cliente.nombre
|
||||||
|
regimen_fiscal = related[0].factura.regimen_fiscal
|
||||||
|
|
||||||
|
filters = (
|
||||||
|
(CfdiPagos.movimiento==id_mov) &
|
||||||
|
(CfdiPagos.cancelado==False)
|
||||||
|
)
|
||||||
|
previous = CfdiPagos.select().where(filters)
|
||||||
|
if previous:
|
||||||
|
previous = previous[0]
|
||||||
|
if previous.uuid:
|
||||||
|
msg = 'Hay una factura activa, es necesario cancelarla primero'
|
||||||
|
data = {'ok': False, 'msg': msg}
|
||||||
|
return data
|
||||||
|
else:
|
||||||
|
data = {'ok': True, 'new': False}
|
||||||
|
return data
|
||||||
|
|
||||||
|
emisor = Emisor.select()[0]
|
||||||
|
serie = Configuracion.get_('txt_config_cfdipay_serie') or DEFAULT_SERIE_CFDIPAY
|
||||||
|
fields = {}
|
||||||
|
fields['movimiento'] = id_mov
|
||||||
|
fields['socio'] = partner
|
||||||
|
fields['serie'] = serie
|
||||||
|
fields['folio'] = self._get_folio(self, serie)
|
||||||
|
fields['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
||||||
|
fields['regimen_fiscal'] = regimen_fiscal
|
||||||
|
|
||||||
|
with database_proxy.atomic() as txn:
|
||||||
|
obj = CfdiPagos.create(**fields)
|
||||||
|
|
||||||
|
row = {
|
||||||
|
'id': obj.id,
|
||||||
|
'serie': obj.serie,
|
||||||
|
'folio': obj.folio,
|
||||||
|
'uuid': obj.uuid,
|
||||||
|
'fecha': obj.fecha,
|
||||||
|
'tipo_comprobante': obj.tipo_comprobante,
|
||||||
|
'estatus': obj.estatus,
|
||||||
|
'cliente': partner_name,
|
||||||
|
}
|
||||||
|
data = {'ok': True, 'row': row, 'new': True}
|
||||||
|
return data
|
||||||
|
|
||||||
|
def _get_related_xml(self, id_mov, currency):
|
||||||
|
filters = (FacturasPagos.movimiento==id_mov)
|
||||||
|
related = tuple(FacturasPagos.select(
|
||||||
|
Facturas.uuid.alias('IdDocumento'),
|
||||||
|
Facturas.serie.alias('Serie'),
|
||||||
|
Facturas.folio.alias('Folio'),
|
||||||
|
Facturas.moneda.alias('MonedaDR'),
|
||||||
|
# ~ Facturas.tipo_cambio.alias('TipoCambioDR'),
|
||||||
|
# ~ Facturas.metodo_pago.alias('MetodoDePagoDR'),
|
||||||
|
FacturasPagos.numero.alias('NumParcialidad'),
|
||||||
|
FacturasPagos.saldo_anterior.alias('ImpSaldoAnt'),
|
||||||
|
FacturasPagos.importe.alias('ImpPagado'),
|
||||||
|
FacturasPagos.saldo.alias('ImpSaldoInsoluto'),
|
||||||
|
).join(Facturas).switch(FacturasPagos)
|
||||||
|
.where(filters)
|
||||||
|
.dicts())
|
||||||
|
|
||||||
|
for r in related:
|
||||||
|
# ~ print('\n\nMONEDA', currency, r['MonedaDR'])
|
||||||
|
r['IdDocumento'] = str(r['IdDocumento'])
|
||||||
|
r['Folio'] = str(r['Folio'])
|
||||||
|
r['NumParcialidad'] = str(r['NumParcialidad'])
|
||||||
|
# ~ r['TipoCambioDR'] = FORMAT.format(r['TipoCambioDR'])
|
||||||
|
r['MetodoDePagoDR'] = 'PDD'
|
||||||
|
r['ImpSaldoAnt'] = FORMAT.format(r['ImpSaldoAnt'])
|
||||||
|
r['ImpPagado'] = FORMAT.format(r['ImpPagado'])
|
||||||
|
r['ImpSaldoInsoluto'] = FORMAT.format(r['ImpSaldoInsoluto'])
|
||||||
|
|
||||||
|
return related
|
||||||
|
|
||||||
|
def _generate_xml(self, invoice, auth):
|
||||||
|
emisor = Emisor.select()[0]
|
||||||
|
cert = Certificado.get_cert()
|
||||||
|
|
||||||
|
cfdi = {}
|
||||||
|
related = {}
|
||||||
|
cfdi['Serie'] = invoice.serie
|
||||||
|
cfdi['Folio'] = str(invoice.folio)
|
||||||
|
cfdi['Fecha'] = invoice.fecha.isoformat()[:19]
|
||||||
|
cfdi['NoCertificado'] = cert.serie
|
||||||
|
cfdi['Certificado'] = cert.cer_txt
|
||||||
|
cfdi['SubTotal'] = '0'
|
||||||
|
cfdi['Moneda'] = 'XXX'
|
||||||
|
cfdi['Total'] = '0'
|
||||||
|
cfdi['TipoDeComprobante'] = invoice.tipo_comprobante
|
||||||
|
cfdi['LugarExpedicion'] = invoice.lugar_expedicion
|
||||||
|
|
||||||
|
if invoice.tipo_relacion:
|
||||||
|
related = {
|
||||||
|
'tipo': invoice.tipo_relacion,
|
||||||
|
'cfdis': (invoice.uuid_relacionado,),
|
||||||
|
}
|
||||||
|
|
||||||
|
emisor = {
|
||||||
|
'Rfc': emisor.rfc,
|
||||||
|
'Nombre': emisor.nombre,
|
||||||
|
'RegimenFiscal': invoice.regimen_fiscal,
|
||||||
|
}
|
||||||
|
|
||||||
|
receptor = {
|
||||||
|
'Rfc': invoice.socio.rfc,
|
||||||
|
'Nombre': invoice.socio.nombre,
|
||||||
|
'UsoCFDI': 'P01',
|
||||||
|
}
|
||||||
|
if invoice.socio.tipo_persona == 4:
|
||||||
|
if invoice.socio.pais:
|
||||||
|
receptor['ResidenciaFiscal'] = invoice.socio.pais
|
||||||
|
if invoice.socio.id_fiscal:
|
||||||
|
receptor['NumRegIdTrib'] = invoice.socio.id_fiscal
|
||||||
|
|
||||||
|
conceptos = ({
|
||||||
|
'ClaveProdServ': '84111506',
|
||||||
|
'Cantidad': '1',
|
||||||
|
'ClaveUnidad': 'ACT',
|
||||||
|
'Descripcion': 'Pago',
|
||||||
|
'ValorUnitario': '0',
|
||||||
|
'Importe': '0',
|
||||||
|
},)
|
||||||
|
|
||||||
|
impuestos = {}
|
||||||
|
|
||||||
|
mov = invoice.movimiento
|
||||||
|
currency = mov.cuenta.moneda.key
|
||||||
|
related_docs = self._get_related_xml(self, invoice.movimiento, currency)
|
||||||
|
pagos = {
|
||||||
|
'FechaPago': mov.fecha.isoformat()[:19],
|
||||||
|
'FormaDePagoP': mov.forma_pago.key,
|
||||||
|
'MonedaP': currency,
|
||||||
|
'Monto': FORMAT.format(mov.deposito),
|
||||||
|
'relacionados': related_docs,
|
||||||
|
}
|
||||||
|
|
||||||
|
complementos = {'pagos': pagos}
|
||||||
|
data = {
|
||||||
|
'comprobante': cfdi,
|
||||||
|
'relacionados': related,
|
||||||
|
'emisor': emisor,
|
||||||
|
'receptor': receptor,
|
||||||
|
'conceptos': conceptos,
|
||||||
|
'impuestos': impuestos,
|
||||||
|
'donativo': {},
|
||||||
|
'edu': False,
|
||||||
|
'complementos': complementos,
|
||||||
|
}
|
||||||
|
return util.make_xml(data, cert, auth)
|
||||||
|
|
||||||
|
def _stamp(self, values):
|
||||||
|
id_mov = int(values['id_mov'])
|
||||||
|
|
||||||
|
auth = Emisor.get_auth()
|
||||||
|
filters = (
|
||||||
|
(CfdiPagos.movimiento==id_mov) &
|
||||||
|
(CfdiPagos.uuid.is_null(True))
|
||||||
|
)
|
||||||
|
obj = CfdiPagos.get(filters)
|
||||||
|
obj.xml = self._generate_xml(self, obj, auth)
|
||||||
|
obj.estatus = 'Generada'
|
||||||
|
obj.save()
|
||||||
|
msg = 'Factura timbrada correctamente'
|
||||||
|
result = util.timbra_xml(obj.xml, auth)
|
||||||
|
if result['ok']:
|
||||||
|
obj.xml = result['xml']
|
||||||
|
obj.uuid = result['uuid']
|
||||||
|
obj.fecha_timbrado = result['fecha']
|
||||||
|
obj.estatus = 'Timbrada'
|
||||||
|
obj.error = ''
|
||||||
|
row = {'uuid': obj.uuid, 'estatus': 'Timbrada'}
|
||||||
|
else:
|
||||||
|
msg = result['error']
|
||||||
|
obj.estatus = 'Error'
|
||||||
|
obj.error = msg
|
||||||
|
row = {'estatus': 'Error'}
|
||||||
|
|
||||||
|
obj.save()
|
||||||
|
|
||||||
|
result = {
|
||||||
|
'ok': result['ok'],
|
||||||
|
'msg': msg,
|
||||||
|
'id': obj.id,
|
||||||
|
'row': row,
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _get_related(self, values):
|
||||||
|
id_mov = int(values['id_mov'])
|
||||||
|
filters = (
|
||||||
|
(CfdiPagos.movimiento==id_mov)
|
||||||
|
)
|
||||||
|
rows = tuple(CfdiPagos.select(
|
||||||
|
CfdiPagos.id,
|
||||||
|
CfdiPagos.serie,
|
||||||
|
CfdiPagos.folio,
|
||||||
|
CfdiPagos.uuid,
|
||||||
|
CfdiPagos.fecha,
|
||||||
|
CfdiPagos.tipo_comprobante,
|
||||||
|
CfdiPagos.estatus,
|
||||||
|
Socios.nombre.alias('cliente'),
|
||||||
|
).join(Socios).switch(CfdiPagos)
|
||||||
|
.where(filters).dicts())
|
||||||
|
return {'ok': True, 'rows': rows}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_file_xml(cls, id):
|
||||||
|
obj = CfdiPagos.get(CfdiPagos.id==id)
|
||||||
|
folio = str(obj.folio).zfill(6)
|
||||||
|
name = '{}{}_{}.xml'.format(obj.serie, folio, obj.socio.rfc)
|
||||||
|
return obj.xml, name
|
||||||
|
|
||||||
|
def _get_not_in_xml(self, invoice, emisor):
|
||||||
|
values = {}
|
||||||
|
|
||||||
|
values['notas'] = invoice.notas
|
||||||
|
values['fechadof'] = None
|
||||||
|
|
||||||
|
obj = SATRegimenes.get(SATRegimenes.key==invoice.regimen_fiscal)
|
||||||
|
values['regimenfiscal'] = str(obj)
|
||||||
|
|
||||||
|
obj = SATUsoCfdi.get(SATUsoCfdi.key=='P01')
|
||||||
|
values['usocfdi'] = str(obj)
|
||||||
|
|
||||||
|
values['moneda'] = 'XXX'
|
||||||
|
|
||||||
|
if invoice.tipo_relacion:
|
||||||
|
obj = SATTipoRelacion.get(SATTipoRelacion.key==invoice.tipo_relacion)
|
||||||
|
values['tiporelacion'] = str(obj)
|
||||||
|
|
||||||
|
receptor = Socios.select().where(Socios.id==invoice.socio.id).dicts()[0]
|
||||||
|
values['receptor'] = {}
|
||||||
|
for k, v in receptor.items():
|
||||||
|
values['receptor'][k] = v
|
||||||
|
|
||||||
|
values['pagos'] = True
|
||||||
|
return values
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_file_pdf(cls, id):
|
||||||
|
try:
|
||||||
|
emisor = Emisor.select()[0]
|
||||||
|
except IndexError:
|
||||||
|
return b'', 'sin_datos_de_emisor.pdf'
|
||||||
|
|
||||||
|
obj = CfdiPagos.get(CfdiPagos.id==id)
|
||||||
|
folio = str(obj.folio).zfill(6)
|
||||||
|
name = '{}{}_{}.pdf'.format(obj.serie, folio, obj.socio.rfc)
|
||||||
|
|
||||||
|
if obj.uuid is None:
|
||||||
|
return b'', name
|
||||||
|
|
||||||
|
values = cls._get_not_in_xml(cls, obj, emisor)
|
||||||
|
data = util.get_data_from_xml(obj, values)
|
||||||
|
obj = SATFormaPago.get(SATFormaPago.key==data['pays']['FormaDePagoP'])
|
||||||
|
data['pays']['formadepago'] = '{} ({})'.format(obj.name, obj.key)
|
||||||
|
doc = util.to_pdf(data, emisor.rfc)
|
||||||
|
|
||||||
|
return doc, name
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_values(cls, values):
|
||||||
|
opt = values.pop('opt')
|
||||||
|
return getattr(cls, '_get_{}'.format(opt))(cls, values)
|
||||||
|
|
||||||
|
|
||||||
class PreFacturasImpuestos(BaseModel):
|
class PreFacturasImpuestos(BaseModel):
|
||||||
factura = ForeignKeyField(PreFacturas)
|
factura = ForeignKeyField(PreFacturas)
|
||||||
|
@ -7487,6 +7844,35 @@ def _migrate_tables():
|
||||||
if 'cancelado' in columns:
|
if 'cancelado' in columns:
|
||||||
migrations.append(migrator.drop_column('facturaspagos', 'cancelado'))
|
migrations.append(migrator.drop_column('facturaspagos', 'cancelado'))
|
||||||
|
|
||||||
|
columns = [c.name for c in database_proxy.get_columns('certificado')]
|
||||||
|
if not 'es_fiel' in columns:
|
||||||
|
es_fiel = BooleanField(default=False)
|
||||||
|
migrations.append(migrator.add_column('certificado', 'es_fiel', es_fiel))
|
||||||
|
|
||||||
|
columns = [c.name for c in database_proxy.get_columns('cfdipagos')]
|
||||||
|
if not 'serie' in columns:
|
||||||
|
socio = ForeignKeyField(Socios, null=True, to_field=Socios.id)
|
||||||
|
serie = TextField(default='')
|
||||||
|
folio = IntegerField(default=0)
|
||||||
|
lugar_expedicion = TextField(default='')
|
||||||
|
regimen_fiscal = TextField(default='')
|
||||||
|
tipo_comprobante = TextField(default=DEFAULT_TYPE_CFDIPAY)
|
||||||
|
error = TextField(default='')
|
||||||
|
tipo_relacion = TextField(default='')
|
||||||
|
uuid_relacionado = UUIDField(null=True)
|
||||||
|
cancelada = BooleanField(default=False)
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'serie', serie))
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'folio', folio))
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'lugar_expedicion', lugar_expedicion))
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'regimen_fiscal', regimen_fiscal))
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'tipo_comprobante', tipo_comprobante))
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'error', error))
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'tipo_relacion', tipo_relacion))
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'uuid_relacionado', uuid_relacionado))
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'socio_id', socio))
|
||||||
|
migrations.append(migrator.drop_column('cfdipagos', 'cancelado'))
|
||||||
|
migrations.append(migrator.add_column('cfdipagos', 'cancelada', cancelada))
|
||||||
|
|
||||||
if migrations:
|
if migrations:
|
||||||
with database_proxy.atomic() as txn:
|
with database_proxy.atomic() as txn:
|
||||||
migrate(*migrations)
|
migrate(*migrations)
|
||||||
|
|
|
@ -1,4 +1,20 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# ~ Empresa Libre
|
||||||
|
# ~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||||
|
# ~
|
||||||
|
# ~ This program is free software: you can redistribute it and/or modify
|
||||||
|
# ~ it under the terms of the GNU General Public License as published by
|
||||||
|
# ~ the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# ~ (at your option) any later version.
|
||||||
|
# ~
|
||||||
|
# ~ This program is distributed in the hope that it will be useful,
|
||||||
|
# ~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# ~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# ~ GNU General Public License for more details.
|
||||||
|
# ~
|
||||||
|
# ~ You should have received a copy of the GNU General Public License
|
||||||
|
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import logbook
|
import logbook
|
||||||
import os
|
import os
|
||||||
|
@ -31,7 +47,7 @@ except ImportError:
|
||||||
|
|
||||||
|
|
||||||
DEBUG = DEBUG
|
DEBUG = DEBUG
|
||||||
VERSION = '1.11.1'
|
VERSION = '1.12.0'
|
||||||
EMAIL_SUPPORT = ('soporte@empresalibre.net',)
|
EMAIL_SUPPORT = ('soporte@empresalibre.net',)
|
||||||
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)
|
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)
|
||||||
|
|
||||||
|
@ -116,7 +132,8 @@ PRE = {
|
||||||
'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}',
|
'1.2': '{http://www.sat.gob.mx/nomina12}',
|
||||||
}
|
},
|
||||||
|
'pagos': '{http://www.sat.gob.mx/Pagos}',
|
||||||
}
|
}
|
||||||
|
|
||||||
CURRENT_CFDI = '3.3'
|
CURRENT_CFDI = '3.3'
|
||||||
|
@ -138,6 +155,8 @@ IMPUESTOS = {
|
||||||
}
|
}
|
||||||
DEFAULT_SAT_PRODUCTO = '01010101'
|
DEFAULT_SAT_PRODUCTO = '01010101'
|
||||||
DEFAULT_SERIE_TICKET = 'T'
|
DEFAULT_SERIE_TICKET = 'T'
|
||||||
|
DEFAULT_SERIE_CFDIPAY = 'FP'
|
||||||
|
DEFAULT_TYPE_CFDIPAY = 'P'
|
||||||
DIR_FACTURAS = 'facturas'
|
DIR_FACTURAS = 'facturas'
|
||||||
USAR_TOKEN = False
|
USAR_TOKEN = False
|
||||||
CANCEL_SIGNATURE = False
|
CANCEL_SIGNATURE = False
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
//~ Empresa Libre
|
||||||
|
//~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||||
|
//~
|
||||||
|
//~ This program is free software: you can redistribute it and/or modify
|
||||||
|
//~ it under the terms of the GNU General Public License as published by
|
||||||
|
//~ the Free Software Foundation, either version 3 of the License, or
|
||||||
|
//~ (at your option) any later version.
|
||||||
|
//~
|
||||||
|
//~ This program is distributed in the hope that it will be useful,
|
||||||
|
//~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
//~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
//~ GNU General Public License for more details.
|
||||||
|
//~
|
||||||
|
//~ You should have received a copy of the GNU General Public License
|
||||||
|
//~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
var msg = ''
|
var msg = ''
|
||||||
var msg_importe = ''
|
var msg_importe = ''
|
||||||
|
|
||||||
|
@ -7,6 +24,7 @@ var bancos_controllers = {
|
||||||
$$('lst_cuentas_banco').attachEvent('onChange', lst_cuentas_banco_change)
|
$$('lst_cuentas_banco').attachEvent('onChange', lst_cuentas_banco_change)
|
||||||
$$('cmd_agregar_retiro').attachEvent('onItemClick', cmd_agregar_retiro_click)
|
$$('cmd_agregar_retiro').attachEvent('onItemClick', cmd_agregar_retiro_click)
|
||||||
$$('cmd_agregar_deposito').attachEvent('onItemClick', cmd_agregar_deposito_click)
|
$$('cmd_agregar_deposito').attachEvent('onItemClick', cmd_agregar_deposito_click)
|
||||||
|
$$('cmd_complemento_pago').attachEvent('onItemClick', cmd_complemento_pago_click)
|
||||||
$$('cmd_guardar_retiro').attachEvent('onItemClick', cmd_guardar_retiro_click)
|
$$('cmd_guardar_retiro').attachEvent('onItemClick', cmd_guardar_retiro_click)
|
||||||
$$('cmd_guardar_deposito').attachEvent('onItemClick', cmd_guardar_deposito_click)
|
$$('cmd_guardar_deposito').attachEvent('onItemClick', cmd_guardar_deposito_click)
|
||||||
$$('cmd_cancelar_movimiento').attachEvent('onItemClick', cmd_cancelar_movimiento_click)
|
$$('cmd_cancelar_movimiento').attachEvent('onItemClick', cmd_cancelar_movimiento_click)
|
||||||
|
@ -20,6 +38,11 @@ var bancos_controllers = {
|
||||||
$$('filter_cuenta_year').attachEvent('onChange', filter_cuenta_change)
|
$$('filter_cuenta_year').attachEvent('onChange', filter_cuenta_change)
|
||||||
$$('filter_cuenta_month').attachEvent('onChange', filter_cuenta_change)
|
$$('filter_cuenta_month').attachEvent('onChange', filter_cuenta_change)
|
||||||
$$('filter_cuenta_dates').attachEvent('onChange', filter_cuenta_dates_change)
|
$$('filter_cuenta_dates').attachEvent('onChange', filter_cuenta_dates_change)
|
||||||
|
|
||||||
|
$$('cmd_pay_stamp').attachEvent('onItemClick', cmd_pay_stamp_click)
|
||||||
|
$$('cmd_pay_cancel').attachEvent('onItemClick', cmd_pay_cancel_click)
|
||||||
|
$$('grid_cfdi_pay').attachEvent('onItemClick', grid_cfdi_pay_click)
|
||||||
|
|
||||||
set_year_month()
|
set_year_month()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -666,8 +689,202 @@ function filter_cuenta_change(){
|
||||||
get_estado_cuenta()
|
get_estado_cuenta()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function filter_cuenta_dates_change(range){
|
function filter_cuenta_dates_change(range){
|
||||||
if(range.start != null && range.end != null){
|
if(range.start != null && range.end != null){
|
||||||
get_estado_cuenta(range)
|
get_estado_cuenta(range)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function set_data_pay(row){
|
||||||
|
var form = $$('form_bank_pay')
|
||||||
|
var dt = row.fecha.split(' ')
|
||||||
|
var grid = $$('grid_pay_related')
|
||||||
|
grid.clearAll()
|
||||||
|
|
||||||
|
set_way_payment('pay_way_payment')
|
||||||
|
var wp = table_waypayment.findOne({'value': row.way_payment})
|
||||||
|
|
||||||
|
form.setValues({
|
||||||
|
id_mov: row.id,
|
||||||
|
pay_date: dt[0],
|
||||||
|
pay_time: dt[1],
|
||||||
|
pay_reference: row.numero_operacion,
|
||||||
|
pay_way_payment: wp.id,
|
||||||
|
pay_import: row.deposito,
|
||||||
|
pay_description: row.descripcion
|
||||||
|
})
|
||||||
|
|
||||||
|
webix.ajax().get('/invoicepay', {'opt': 'related', 'id': row.id}, {
|
||||||
|
error:function(text, data, XmlHttpRequest){
|
||||||
|
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||||
|
msg_error(msg)
|
||||||
|
},
|
||||||
|
success:function(text, data, XmlHttpRequest){
|
||||||
|
var values = data.json()
|
||||||
|
if(values.ok){
|
||||||
|
grid.parse(values.rows, 'json')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$$('grid_cfdi_pay').clearAll()
|
||||||
|
webix.ajax().get('/cfdipay', {'opt': 'related', 'id_mov': row.id}, {
|
||||||
|
error:function(text, data, XmlHttpRequest){
|
||||||
|
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||||
|
msg_error(msg)
|
||||||
|
},
|
||||||
|
success:function(text, data, XmlHttpRequest){
|
||||||
|
var values = data.json()
|
||||||
|
if(values.ok){
|
||||||
|
$$('grid_cfdi_pay').parse(values.rows, 'json')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cmd_complemento_pago_click(){
|
||||||
|
var grid = $$('grid_cuentabanco')
|
||||||
|
|
||||||
|
var row = grid.getSelectedItem()
|
||||||
|
if(row == undefined){
|
||||||
|
msg_error('Selecciona un movimiento de depósito')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(row.descripcion == 'Saldo inicial'){
|
||||||
|
msg_error('No es posible generar un pago del Saldo Inicial')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(row.deposito == 0){
|
||||||
|
msg_error('Selecciona un movimiento de depósito')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
set_data_pay(row)
|
||||||
|
$$('multi_bancos').setValue('bank_pay')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function validate_cfdi_pay(form){
|
||||||
|
if(!form.validate()) {
|
||||||
|
msg_error('Valores inválidos')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var grid = $$('grid_pay_related')
|
||||||
|
if(grid.count() == 0){
|
||||||
|
msg_error('El depósito no tiene facturas relacionadas')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function update_grid_cfdi_pay(row){
|
||||||
|
var g = $$('grid_cfdi_pay')
|
||||||
|
|
||||||
|
g.add(result.row)
|
||||||
|
if (g.count() == 1){
|
||||||
|
g.adjustColumn('index')
|
||||||
|
g.adjustColumn('serie')
|
||||||
|
g.adjustColumn('folio')
|
||||||
|
g.adjustColumn('fecha')
|
||||||
|
g.adjustColumn('cliente')
|
||||||
|
g.adjustColumn('xml')
|
||||||
|
g.adjustColumn('pdf')
|
||||||
|
g.adjustColumn('email')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function send_stamp_cfdi_pay(id_mov){
|
||||||
|
var g = $$('grid_cfdi_pay')
|
||||||
|
var data = {'opt': 'stamp', 'id_mov': id_mov}
|
||||||
|
|
||||||
|
webix.ajax().sync().post('cfdipay', data, {
|
||||||
|
error:function(text, data, XmlHttpRequest){
|
||||||
|
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||||
|
msg_error(msg)
|
||||||
|
},
|
||||||
|
success:function(text, data, XmlHttpRequest){
|
||||||
|
result = data.json();
|
||||||
|
if(result.ok){
|
||||||
|
g.updateItem(result.id, result.row)
|
||||||
|
msg_ok(result.msg)
|
||||||
|
}else{
|
||||||
|
msg_error(result.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_cfdi_pay(form){
|
||||||
|
var values = form.getValues()
|
||||||
|
var data = {'opt': 'new', 'id_mov': values.id_mov}
|
||||||
|
|
||||||
|
webix.ajax().sync().post('cfdipay', data, {
|
||||||
|
error:function(text, data, XmlHttpRequest){
|
||||||
|
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||||
|
msg_error(msg)
|
||||||
|
},
|
||||||
|
success:function(text, data, XmlHttpRequest){
|
||||||
|
result = data.json();
|
||||||
|
if(result.ok){
|
||||||
|
if(result.new){
|
||||||
|
msg_ok('Factura guardada correctamente<BR>Enviando a timbrar...')
|
||||||
|
update_grid_cfdi_pay(result.row)
|
||||||
|
}else{
|
||||||
|
msg_ok('Enviando a timbrar...')
|
||||||
|
}
|
||||||
|
send_stamp_cfdi_pay(values.id_mov)
|
||||||
|
}else{
|
||||||
|
msg_error(result.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cmd_pay_stamp_click(){
|
||||||
|
var form = $$('form_bank_pay')
|
||||||
|
var title = 'Timbrar Factura de Pago'
|
||||||
|
msg = '¿Estás seguro de enviar a timbrar este pago?'
|
||||||
|
|
||||||
|
if (!validate_cfdi_pay(form)){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
webix.confirm({
|
||||||
|
title: title,
|
||||||
|
ok: 'Si',
|
||||||
|
cancel: 'No',
|
||||||
|
type: 'confirm-error',
|
||||||
|
text: msg,
|
||||||
|
callback:function(result){
|
||||||
|
if(result){
|
||||||
|
save_cfdi_pay(form)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cmd_pay_cancel_click(){
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function grid_cfdi_pay_click(id, e, node){
|
||||||
|
var row = this.getItem(id)
|
||||||
|
|
||||||
|
if(id.column == 'xml'){
|
||||||
|
location = '/doc/xmlpago/' + row.id
|
||||||
|
}else if(id.column == 'pdf'){
|
||||||
|
window.open('/doc/pdfpago/' + row.id, '_blank')
|
||||||
|
}else if(id.column == 'email'){
|
||||||
|
//~ enviar_correo(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,8 @@ function configuracion_inicial(){
|
||||||
add_config({'key': 'decimales_precios', 'value': values.decimales_precios})
|
add_config({'key': 'decimales_precios', 'value': values.decimales_precios})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
get_way_payment()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,20 @@
|
||||||
|
//~ Empresa Libre
|
||||||
|
//~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||||
|
//~
|
||||||
|
//~ This program is free software: you can redistribute it and/or modify
|
||||||
|
//~ it under the terms of the GNU General Public License as published by
|
||||||
|
//~ the Free Software Foundation, either version 3 of the License, or
|
||||||
|
//~ (at your option) any later version.
|
||||||
|
//~
|
||||||
|
//~ This program is distributed in the hope that it will be useful,
|
||||||
|
//~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
//~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
//~ GNU General Public License for more details.
|
||||||
|
//~
|
||||||
|
//~ You should have received a copy of the GNU General Public License
|
||||||
|
//~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
var PUBLICO = "Público en general";
|
var PUBLICO = "Público en general";
|
||||||
var RFC_PUBLICO = "XAXX010101000";
|
var RFC_PUBLICO = "XAXX010101000";
|
||||||
var RFC_EXTRANJERO = "XEXX010101000";
|
var RFC_EXTRANJERO = "XEXX010101000";
|
||||||
|
@ -16,6 +33,7 @@ var table_totals = db.addCollection('totals', {unique: ['tax']})
|
||||||
var table_series = db.addCollection('series')
|
var table_series = db.addCollection('series')
|
||||||
var table_usocfdi = db.addCollection('usocfdi')
|
var table_usocfdi = db.addCollection('usocfdi')
|
||||||
var table_relaciones = db.addCollection('relaciones')
|
var table_relaciones = db.addCollection('relaciones')
|
||||||
|
var table_waypayment = db.addCollection('waypayment')
|
||||||
|
|
||||||
var msg = ''
|
var msg = ''
|
||||||
|
|
||||||
|
@ -408,6 +426,21 @@ function get_forma_pago(control){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function get_way_payment(){
|
||||||
|
webix.ajax().get('/values/formapago', {key: true}, function(text, data){
|
||||||
|
var values = data.json()
|
||||||
|
table_waypayment.clear()
|
||||||
|
table_waypayment.insert(values)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function set_way_payment(control){
|
||||||
|
var values = table_waypayment.chain().data()
|
||||||
|
$$(control).getList().parse(values)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function validate_regexp(value, pattern){
|
function validate_regexp(value, pattern){
|
||||||
re = new RegExp(pattern, 'i');
|
re = new RegExp(pattern, 'i');
|
||||||
if(value.match(re)){
|
if(value.match(re)){
|
||||||
|
@ -443,3 +476,7 @@ function pause(milliseconds) {
|
||||||
var dt = new Date();
|
var dt = new Date();
|
||||||
while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
|
while ((new Date()) - dt <= milliseconds) { /* Do nothing */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//~ Revisado
|
||||||
|
|
||||||
|
|
|
@ -233,18 +233,38 @@ var emisor_otros_datos= [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
var emisor_certificado = [
|
var col_sello = {rows: [
|
||||||
{template: 'Certificado actual', type: 'section'},
|
{template: 'Certificado actual', type: 'section'},
|
||||||
{view: 'form', id: 'form_cert', rows: [
|
{view: 'form', id: 'form_cert', rows: [
|
||||||
{cols: [{view: 'text', id: 'cert_rfc', name: 'cert_rfc',
|
{cols: [{view: 'text', id: 'cert_rfc', name: 'cert_rfc',
|
||||||
label: 'RFC: ', readonly: true, placeholder: 'Ninguno'}, {}]},
|
label: 'RFC: ', readonly: true, placeholder: 'Ninguno'}]},
|
||||||
{cols: [{view: 'text', id: 'cert_serie', name: 'cert_serie',
|
{cols: [{view: 'text', id: 'cert_serie', name: 'cert_serie',
|
||||||
label: 'Serie: ', readonly: true, placeholder: 'Ninguno'}, {}]},
|
label: 'Serie: ', readonly: true, placeholder: 'Ninguno'}]},
|
||||||
{cols: [{view: 'text', id: 'cert_desde', name: 'cert_desde',
|
{cols: [{view: 'text', id: 'cert_desde', name: 'cert_desde',
|
||||||
label: 'Vigente desde: ', readonly: true}, {}]},
|
label: 'Vigente desde: ', readonly: true}]},
|
||||||
{cols: [{view: 'text', id: 'cert_hasta', name: 'cert_hasta',
|
{cols: [{view: 'text', id: 'cert_hasta', name: 'cert_hasta',
|
||||||
label: 'Vigente hasta: ', readonly: true}, {}]},
|
label: 'Vigente hasta: ', readonly: true}]},
|
||||||
]},
|
]}
|
||||||
|
]}
|
||||||
|
|
||||||
|
|
||||||
|
var col_fiel = {rows: [
|
||||||
|
{template: 'Fiel actual', type: 'section'},
|
||||||
|
{view: 'form', id: 'form_fiel', rows: [
|
||||||
|
{cols: [{view: 'text', id: 'fiel_rfc', name: 'fiel_rfc',
|
||||||
|
label: 'RFC: ', readonly: true, placeholder: 'Ninguno'}]},
|
||||||
|
{cols: [{view: 'text', id: 'fiel_serie', name: 'fiel_serie',
|
||||||
|
label: 'Serie: ', readonly: true, placeholder: 'Ninguno'}]},
|
||||||
|
{cols: [{view: 'text', id: 'fiel_desde', name: 'fiel_desde',
|
||||||
|
label: 'Vigente desde: ', readonly: true}]},
|
||||||
|
{cols: [{view: 'text', id: 'fiel_hasta', name: 'fiel_hasta',
|
||||||
|
label: 'Vigente hasta: ', readonly: true}]},
|
||||||
|
]}
|
||||||
|
]}
|
||||||
|
|
||||||
|
|
||||||
|
var emisor_certificado = [
|
||||||
|
{cols: [col_sello, col_fiel]},
|
||||||
{template: 'Cargar Certificado', type: 'section'},
|
{template: 'Cargar Certificado', type: 'section'},
|
||||||
{view: 'form', id: 'form_upload', rows: [
|
{view: 'form', id: 'form_upload', rows: [
|
||||||
{cols: [{},
|
{cols: [{},
|
||||||
|
|
|
@ -1,3 +1,18 @@
|
||||||
|
//~ Empresa Libre
|
||||||
|
//~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||||
|
//~
|
||||||
|
//~ This program is free software: you can redistribute it and/or modify
|
||||||
|
//~ it under the terms of the GNU General Public License as published by
|
||||||
|
//~ the Free Software Foundation, either version 3 of the License, or
|
||||||
|
//~ (at your option) any later version.
|
||||||
|
//~
|
||||||
|
//~ This program is distributed in the hope that it will be useful,
|
||||||
|
//~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
//~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
//~ GNU General Public License for more details.
|
||||||
|
//~
|
||||||
|
//~ You should have received a copy of the GNU General Public License
|
||||||
|
//~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
var toolbar_banco = [
|
var toolbar_banco = [
|
||||||
|
@ -26,6 +41,9 @@ var toolbar_movimientos_banco = [
|
||||||
{view: 'button', id: 'cmd_agregar_deposito', label: 'Depósito',
|
{view: 'button', id: 'cmd_agregar_deposito', label: 'Depósito',
|
||||||
type: 'iconButton', autowidth: true, icon: 'plus'},
|
type: 'iconButton', autowidth: true, icon: 'plus'},
|
||||||
{},
|
{},
|
||||||
|
{view: 'button', id: 'cmd_complemento_pago', label: 'Factura de Pago',
|
||||||
|
type: 'iconButton', autowidth: true, icon: 'file-code-o'},
|
||||||
|
{},
|
||||||
{view: 'button', id: 'cmd_cancelar_movimiento', label: 'Cancelar',
|
{view: 'button', id: 'cmd_cancelar_movimiento', label: 'Cancelar',
|
||||||
type: 'iconButton', autowidth: true, icon: 'ban'},
|
type: 'iconButton', autowidth: true, icon: 'ban'},
|
||||||
]
|
]
|
||||||
|
@ -35,6 +53,7 @@ var grid_cuentabanco_cols = [
|
||||||
{id: 'id', header:'ID', hidden: true},
|
{id: 'id', header:'ID', hidden: true},
|
||||||
{id: 'fecha', header: 'Fecha', width: 150},
|
{id: 'fecha', header: 'Fecha', width: 150},
|
||||||
{id: 'numero_operacion', header: 'Referencia'},
|
{id: 'numero_operacion', header: 'Referencia'},
|
||||||
|
{id: 'way_payment', header: 'Forma de Pago', hidden: true},
|
||||||
{id: 'descripcion', header: ['Descripción', {content: 'textFilter'}],
|
{id: 'descripcion', header: ['Descripción', {content: 'textFilter'}],
|
||||||
fillspace:true},
|
fillspace:true},
|
||||||
{id: 'retiro', header: ['Retiro', {content: 'numberFilter'}],
|
{id: 'retiro', header: ['Retiro', {content: 'numberFilter'}],
|
||||||
|
@ -95,6 +114,49 @@ var grid_cfdi_este_deposito_cols = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var grid_cfdi_pay_cols = [
|
||||||
|
{id: 'index', header: '#', adjust: 'data', css: 'right',
|
||||||
|
footer: {content: 'countRows', colspan: 3, css: 'right'}},
|
||||||
|
{id: "id", header:"ID", hidden:true},
|
||||||
|
{id: 'serie', header: ["Serie"], adjust: "data", sort: 'string'},
|
||||||
|
{id: 'folio', header: ['Folio'], adjust: 'data',
|
||||||
|
sort: 'int', css: 'right', footer: {text: 'Facturas', colspan: 3}},
|
||||||
|
{id: "uuid", header: ["UUID"], adjust: "data",
|
||||||
|
sort:"string", hidden:true},
|
||||||
|
{id: "fecha", header: ["Fecha y Hora"],
|
||||||
|
adjust: "data", sort: "string"},
|
||||||
|
{id: "tipo_comprobante", header: ["Tipo"],
|
||||||
|
adjust: 'header', sort: 'string'},
|
||||||
|
{id: "estatus", header: ["Estatus"],
|
||||||
|
adjust: "data", sort:"string"},
|
||||||
|
{id: 'cliente', header: ['Razón Social'], fillspace: true},
|
||||||
|
{id: 'xml', header: 'XML', adjust: 'data', template: get_icon('xml')},
|
||||||
|
{id: 'pdf', header: 'PDF', adjust: 'data', template: get_icon('pdf')},
|
||||||
|
{id: 'email', header: '', adjust: 'data', template: get_icon('email')}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var grid_pay_related_cols = [
|
||||||
|
{id: 'index', header: '#', adjust: 'data', css: 'right'},
|
||||||
|
{id: 'id', header: 'ID', hidden: true},
|
||||||
|
{id: 'serie', header: 'Serie', adjust: 'data'},
|
||||||
|
{id: 'folio', header: 'Folio', adjust: 'data', css: 'right'},
|
||||||
|
{id: 'uuid', header: 'UUID', width: 250, hidden: true},
|
||||||
|
{id: 'fecha', header: 'Fecha y Hora', width: 150, sort: 'date'},
|
||||||
|
{id: 'tipo_comprobante', header: 'Tipo', adjust: 'data'},
|
||||||
|
{id: 'estatus', header: 'Estatus', adjust: 'header'},
|
||||||
|
{id: 'cliente', header: ['Razón Social'], fillspace: true},
|
||||||
|
{id: 'total', header: ['Total'], width: 125, sort: 'int',
|
||||||
|
format: webix.i18n.priceFormat, css: 'right'},
|
||||||
|
{id: 'saldo', header: ['Saldo'], width: 125, sort: 'int',
|
||||||
|
format: webix.i18n.priceFormat, css: 'right', css: 'right',
|
||||||
|
footer: 'Importe Depósito'},
|
||||||
|
{id: 'importe', header: ['Este pago'], width: 125, sort: 'int',
|
||||||
|
format: webix.i18n.priceFormat, css: 'right',
|
||||||
|
footer: {content: 'summColumn', css: 'right'}},
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
var grid_cfdi_por_pagar = {
|
var grid_cfdi_por_pagar = {
|
||||||
view: 'datatable',
|
view: 'datatable',
|
||||||
id: 'grid_cfdi_por_pagar',
|
id: 'grid_cfdi_por_pagar',
|
||||||
|
@ -139,6 +201,47 @@ var grid_cfdi_este_deposito = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var grid_cfdi_pay = {
|
||||||
|
view: 'datatable',
|
||||||
|
id: 'grid_cfdi_pay',
|
||||||
|
select: 'row',
|
||||||
|
autoConfig: false,
|
||||||
|
adjust: true,
|
||||||
|
autoheight: true,
|
||||||
|
resizeColumn: true,
|
||||||
|
headermenu: true,
|
||||||
|
columns: grid_cfdi_pay_cols,
|
||||||
|
on:{
|
||||||
|
'data->onStoreUpdated':function(){
|
||||||
|
this.data.each(function(obj, i){
|
||||||
|
obj.index = i + 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var grid_pay_related = {
|
||||||
|
view: 'datatable',
|
||||||
|
id: 'grid_pay_related',
|
||||||
|
select: 'row',
|
||||||
|
autoConfig: false,
|
||||||
|
adjust: true,
|
||||||
|
autoheight: true,
|
||||||
|
resizeColumn: true,
|
||||||
|
headermenu: true,
|
||||||
|
footer: true,
|
||||||
|
columns: grid_pay_related_cols,
|
||||||
|
on:{
|
||||||
|
'data->onStoreUpdated':function(){
|
||||||
|
this.data.each(function(obj, i){
|
||||||
|
obj.index = i + 1
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var toolbar_banco_retiro = [
|
var toolbar_banco_retiro = [
|
||||||
{view: 'label', label: 'Agregar retiro de banco'},
|
{view: 'label', label: 'Agregar retiro de banco'},
|
||||||
{},
|
{},
|
||||||
|
@ -159,6 +262,19 @@ var toolbar_banco_deposito = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var toolbar_bank_pay = [
|
||||||
|
{view: 'label', label: 'Factura de pago'},
|
||||||
|
{},
|
||||||
|
{view: 'button', id: 'cmd_pay_stamp', label: 'Timbrar',
|
||||||
|
type: 'iconButton', autowidth: true, icon: 'ticket'},
|
||||||
|
{view: 'button', id: 'cmd_pay_cancel', label: 'Cancelar',
|
||||||
|
type: 'iconButton', autowidth: true, icon: 'ban'},
|
||||||
|
{},
|
||||||
|
{view: 'icon', click: '$$("multi_bancos").setValue("banco_home")',
|
||||||
|
icon: 'times-circle'}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
var controls_banco_retiro = [
|
var controls_banco_retiro = [
|
||||||
{view: 'toolbar', elements: toolbar_banco_retiro},
|
{view: 'toolbar', elements: toolbar_banco_retiro},
|
||||||
{cols: [
|
{cols: [
|
||||||
|
@ -229,6 +345,41 @@ var controls_banco_deposito = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var controls_bank_pay = [
|
||||||
|
{view: 'toolbar', elements: toolbar_bank_pay},
|
||||||
|
{view: 'label', label: '<b>Este depósito: </b>'},
|
||||||
|
{cols: [
|
||||||
|
{view: 'datepicker', id: 'pay_date', name: 'pay_date',
|
||||||
|
label: 'Fecha', format: '%d-%M-%Y', labelAlign: 'right',
|
||||||
|
required: true, invalidMessage: 'Selecciona una fecha',
|
||||||
|
labelWidth: 125, readonly: true},
|
||||||
|
{view: 'search', id: 'pay_time', name: 'pay_time', label: 'Hora',
|
||||||
|
icon: 'clock-o', labelAlign: 'right', required: true,
|
||||||
|
readonly: true,
|
||||||
|
invalidMessage: 'Captura una hora'},
|
||||||
|
{view: 'text', id: 'pay_reference', name: 'pay_reference',
|
||||||
|
label: 'Referencia', labelAlign: 'right', readonly: true},
|
||||||
|
]},
|
||||||
|
{cols: [
|
||||||
|
{view: 'richselect', id: 'pay_way_payment', readonly: true,
|
||||||
|
name: 'pay_way_payment', label: 'Forma de Pago', required: true,
|
||||||
|
options: [], labelWidth: 125, labelAlign: 'right'},
|
||||||
|
{view: 'currency', type: 'text', id: 'pay_import', name: 'pay_import',
|
||||||
|
label: 'Importe', labelAlign: 'right', required: true, readonly: true,
|
||||||
|
invalidMessage: 'Captura un valor númerico', inputAlign: 'right'}
|
||||||
|
]},
|
||||||
|
{cols: [
|
||||||
|
{view: 'textarea', id: 'pay_description', label: 'Descripción',
|
||||||
|
name: 'pay_description', labelAlign: 'right', required: true,
|
||||||
|
labelWidth: 125, height: 70, readonly: true},
|
||||||
|
]},
|
||||||
|
{view: 'label', label: '<b>Facturas de pago de este depósito: </b>'},
|
||||||
|
grid_cfdi_pay,
|
||||||
|
{view: 'label', label: '<b>Facturas relacionadas en este pago: </b>'},
|
||||||
|
grid_pay_related
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
var form_banco_retiro = {
|
var form_banco_retiro = {
|
||||||
type: 'space',
|
type: 'space',
|
||||||
responsive: true,
|
responsive: true,
|
||||||
|
@ -255,6 +406,19 @@ var form_banco_deposito = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var form_bank_pay = {
|
||||||
|
type: 'space',
|
||||||
|
responsive: true,
|
||||||
|
cols: [{
|
||||||
|
view: 'form',
|
||||||
|
id: 'form_bank_pay',
|
||||||
|
complexData: true,
|
||||||
|
scroll: true,
|
||||||
|
elements: controls_bank_pay,
|
||||||
|
}],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var multi_bancos = {
|
var multi_bancos = {
|
||||||
id: 'multi_bancos',
|
id: 'multi_bancos',
|
||||||
animate: true,
|
animate: true,
|
||||||
|
@ -266,7 +430,8 @@ var multi_bancos = {
|
||||||
grid_cuentabanco,
|
grid_cuentabanco,
|
||||||
]},
|
]},
|
||||||
{id: 'banco_retiro', rows: [form_banco_retiro]},
|
{id: 'banco_retiro', rows: [form_banco_retiro]},
|
||||||
{id: 'banco_deposito', rows: [form_banco_deposito]}
|
{id: 'banco_deposito', rows: [form_banco_deposito]},
|
||||||
|
{id: 'bank_pay', rows: [form_bank_pay]}
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//~ Empresa Libre
|
//~ Empresa Libre
|
||||||
//~ Copyright (C) 2018 Mauricio Baeza Servin (web@correolibre.net)
|
//~ Copyright (C) 2016-2018 Mauricio Baeza Servin (web@correolibre.net)
|
||||||
//~
|
//~
|
||||||
//~ This program is free software: you can redistribute it and/or modify
|
//~ This program is free software: you can redistribute it and/or modify
|
||||||
//~ it under the terms of the GNU General Public License as published by
|
//~ it under the terms of the GNU General Public License as published by
|
||||||
|
|
Binary file not shown.
|
@ -12,6 +12,7 @@
|
||||||
<xsl:include href="donat11.xslt"/>
|
<xsl:include href="donat11.xslt"/>
|
||||||
<xsl:include href="ine11.xslt"/>
|
<xsl:include href="ine11.xslt"/>
|
||||||
<xsl:include href="iedu.xslt"/>
|
<xsl:include href="iedu.xslt"/>
|
||||||
|
<xsl:include href="pagos10.xslt"/>
|
||||||
<!--
|
<!--
|
||||||
<xsl:include href="ecc11.xslt"/>
|
<xsl:include href="ecc11.xslt"/>
|
||||||
<xsl:include href="Divisas.xslt"/>
|
<xsl:include href="Divisas.xslt"/>
|
||||||
|
@ -30,7 +31,6 @@
|
||||||
<xsl:include href="obrasarteantiguedades.xslt"/>
|
<xsl:include href="obrasarteantiguedades.xslt"/>
|
||||||
<xsl:include href="ventavehiculos11.xslt"/>
|
<xsl:include href="ventavehiculos11.xslt"/>
|
||||||
<xsl:include href="terceros11.xslt"/>
|
<xsl:include href="terceros11.xslt"/>
|
||||||
<xsl:include href="Pagos10.xslt"/>
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:pago10="http://www.sat.gob.mx/Pagos">
|
||||||
|
|
||||||
|
<xsl:template match="pago10:Pagos">
|
||||||
|
<!--Manejador de Atributos Pagos-->
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@Version" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<!-- Iniciamos el manejo de los elementos hijo en la secuencia -->
|
||||||
|
<xsl:for-each select="./pago10:Pago">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago10:Pago">
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@FechaPago" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@FormaDePagoP" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@MonedaP" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TipoCambioP" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@Monto" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@NumOperacion" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@RfcEmisorCtaOrd" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@NomBancoOrdExt" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@CtaOrdenante" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@RfcEmisorCtaBen" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@CtaBeneficiario" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TipoCadPago" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@CertPago" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@CadPago" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@SelloPago" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<!-- Iniciamos el tratamiento de los atributos de pago10:DocumentoRelacionado-->
|
||||||
|
<xsl:for-each select="./pago10:DoctoRelacionado">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
<xsl:for-each select="./pago10:Impuestos">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago10:DoctoRelacionado">
|
||||||
|
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@IdDocumento" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@Serie" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@Folio" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@MonedaDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TipoCambioDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@MetodoDePagoDR" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@NumParcialidad" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@ImpSaldoAnt" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@ImpPagado" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@ImpSaldoInsoluto" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago10:Impuestos">
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalImpuestosRetenidos" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Opcional">
|
||||||
|
<xsl:with-param name="valor" select="./@TotalImpuestosTrasladados" />
|
||||||
|
</xsl:call-template>
|
||||||
|
|
||||||
|
<xsl:apply-templates select="./pago10:Retenciones"/>
|
||||||
|
<xsl:apply-templates select="./pago10:Traslados"/>
|
||||||
|
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago10:Retenciones">
|
||||||
|
<xsl:for-each select="./pago10:Retencion">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago10:Traslados">
|
||||||
|
<xsl:for-each select="./pago10:Traslado">
|
||||||
|
<xsl:apply-templates select="."/>
|
||||||
|
</xsl:for-each>
|
||||||
|
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago10:Retencion">
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@Impuesto" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@Importe" />
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:template>
|
||||||
|
|
||||||
|
<xsl:template match="pago10:Traslado">
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@Impuesto" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@TipoFactor" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@TasaOCuota" />
|
||||||
|
</xsl:call-template>
|
||||||
|
<xsl:call-template name="Requerido">
|
||||||
|
<xsl:with-param name="valor" select="./@Importe" />
|
||||||
|
</xsl:call-template>
|
||||||
|
</xsl:template>
|
||||||
|
</xsl:stylesheet>
|
Loading…
Reference in New Issue