diff --git a/source/app/controllers/cfdi_xml.py b/source/app/controllers/cfdi_xml.py index f01e117..0e93025 100644 --- a/source/app/controllers/cfdi_xml.py +++ b/source/app/controllers/cfdi_xml.py @@ -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 . import datetime from xml.etree import ElementTree as ET @@ -6,8 +22,6 @@ from xml.dom.minidom import parseString from logbook import Logger -#~ from settings import DEBUG - log = Logger('XML') CFDI_ACTUAL = 'cfdi33' @@ -64,6 +78,12 @@ SAT = { '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', }, + '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', + }, } @@ -403,6 +423,28 @@ class CFDI(object): atributos.update(datos['ine']) ET.SubElement(self._complemento, 'ine:INE', atributos) + if 'pagos' in datos: + complemento = ET.SubElement(self._cfdi, '{}:Complemento'.format(self._pre)) + pre = 'pago10' + datos = datos.pop('pagos') + pago = datos.pop('pago') + relacionados = datos.pop('relacionados') + + attributes = {} + attributes['xmlns:{}'.format(pre)] = \ + 'http://www.sat.gob.mx/Pagos' + attributes['xsi:schemaLocation'] = \ + 'http://www.sat.gob.mx/Pagos ' \ + 'http://www.sat.gob.mx/sitio_internet/cfd/Pagos/Pagos10.xsd' + attributes.update(datos) + pagos = ET.SubElement( + complemento, '{}:Pagos'.format(pre), attributes) + + node_pago = ET.SubElement(pagos, '{}:Pago'.format(pre), pago) + + for row in relacionados: + ET.SubElement(node_pago, '{}:DoctoRelacionado'.format(pre), row) + if 'ce' in datos: pre = 'cce11' datos = datos.pop('ce') diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py index 738f551..7cea456 100644 --- a/source/app/controllers/main.py +++ b/source/app/controllers/main.py @@ -527,3 +527,18 @@ class AppInvoicePay(object): 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 diff --git a/source/app/main.py b/source/app/main.py index 2edf61a..7c21cc2 100644 --- a/source/app/main.py +++ b/source/app/main.py @@ -17,7 +17,7 @@ from controllers.main import (AppEmpresas, AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios, AppDocumentos, AppFiles, AppPreInvoices, AppCuentasBanco, AppMovimientosBanco, AppTickets, AppStudents, AppEmployees, AppNomina, - AppInvoicePay + AppInvoicePay, AppCfdiPay ) @@ -56,7 +56,8 @@ api.add_route('/movbanco', AppMovimientosBanco(db)) api.add_route('/students', AppStudents(db)) api.add_route('/employees', AppEmployees(db)) api.add_route('/nomina', AppNomina(db)) -api.add_route('/cfdipay', AppInvoicePay(db)) +api.add_route('/invoicepay', AppInvoicePay(db)) +api.add_route('/cfdipay', AppCfdiPay(db)) # ~ Activa si usas waitress y NO estas usando servidor web diff --git a/source/app/models/main.py b/source/app/models/main.py index 7ef098a..6feecc0 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -1,7 +1,7 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # ~ 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 # ~ it under the terms of the GNU General Public License as published by @@ -1949,8 +1949,13 @@ class MovimientosBanco(BaseModel): class CfdiPagos(BaseModel): movimiento = ForeignKeyField(MovimientosBanco) + serie = TextField(default='') + folio = IntegerField(default=0) fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S']) fecha_timbrado = DateTimeField(null=True) + lugar_expedicion = TextField(default='') + tipo_relacion = TextField(default='') + uuid_relacionado = UUIDField(null=True) xml = TextField(default='') uuid = UUIDField(null=True) estatus = TextField(default='Guardado') @@ -1961,6 +1966,13 @@ class CfdiPagos(BaseModel): class Meta: order_by = ('movimiento',) + @classmethod + def new(cls, id_mov): + + row = {} + data = {'ok': True, 'row': row} + return data + class SATUsoCfdi(BaseModel): key = TextField(index=True, unique=True) @@ -7520,6 +7532,19 @@ def _migrate_tables(): if 'cancelado' in columns: migrations.append(migrator.drop_column('facturaspagos', 'cancelado')) + columns = [c.name for c in database_proxy.get_columns('cfdipagos')] + if not 'serie' in columns: + serie = TextField(default='') + folio = IntegerField(default=0) + lugar_expedicion = TextField(default='') + tipo_relacion = TextField(default='') + uuid_relacionado = UUIDField(null=True) + 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', 'tipo_relacion', tipo_relacion)) + migrations.append(migrator.add_column('cfdipagos', 'uuid_relacionado', uuid_relacionado)) + if migrations: with database_proxy.atomic() as txn: migrate(*migrations) diff --git a/source/app/settings.py b/source/app/settings.py index 8156b47..9e07c20 100644 --- a/source/app/settings.py +++ b/source/app/settings.py @@ -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 . import logbook import os diff --git a/source/static/js/controller/bancos.js b/source/static/js/controller/bancos.js index 8f9bfc5..288062b 100644 --- a/source/static/js/controller/bancos.js +++ b/source/static/js/controller/bancos.js @@ -711,7 +711,7 @@ function set_data_pay(row){ pay_description: row.descripcion }) - webix.ajax().get('/cfdipay', {'opt': 'related', 'id': row.id}, { + 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)