diff --git a/source/app/controllers/cfdi_xml.py b/source/app/controllers/cfdi_xml.py index 2da8ff7..ec369ee 100644 --- a/source/app/controllers/cfdi_xml.py +++ b/source/app/controllers/cfdi_xml.py @@ -150,7 +150,7 @@ class CFDI(object): if datos['complementos']: if 'ine' in datos['complementos']: self._ine = True - self._pagos = datos['complementos'].get('pagos', False) + self._pagos = bool(datos['complementos'].get('pagos', False)) if 'nomina' in datos: self._is_nomina = True @@ -196,9 +196,15 @@ class CFDI(object): attributes[name] = SAT['nomina']['xmlns'] 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'] + \ schema_locales + schema_donativo + schema_ine + schema_edu + \ - schema_nomina + schema_nomina + schema_pagos attributes.update(datos) if not 'Version' in attributes: @@ -426,22 +432,12 @@ class CFDI(object): 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') 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) - + pre = SAT['pagos']['prefix'] + attributes = {'Version': SAT['pagos']['version']} pagos = ET.SubElement( - complemento, '{}:Pagos'.format(pre), attributes) - + 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) diff --git a/source/app/models/main.py b/source/app/models/main.py index 717c00a..4efec8a 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -214,6 +214,8 @@ def get_doc(type_doc, id, rfc): data, file_name = util.get_log('nomina') elif type_doc == 'nompdf': data, file_name = CfdiNomina.get_pdf(id, rfc) + elif type_doc == 'xmlpago': + data, file_name = CfdiPagos.get_file_xml(id) return data, file_name, content_type @@ -5352,14 +5354,14 @@ class CfdiPagos(BaseModel): data = {'ok': True, 'row': row, 'new': True} return data - def _get_related_xml(self, id_mov): + 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.tipo_cambio.alias('TipoCambioDR'), Facturas.metodo_pago.alias('MetodoDePagoDR'), FacturasPagos.numero.alias('NumParcialidad'), FacturasPagos.saldo_anterior.alias('ImpSaldoAnt'), @@ -5370,10 +5372,11 @@ class CfdiPagos(BaseModel): .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['TipoCambioDR'] = FORMAT.format(r['TipoCambioDR']) r['ImpSaldoAnt'] = FORMAT.format(r['ImpSaldoAnt']) r['ImpPagado'] = FORMAT.format(r['ImpPagado']) r['ImpSaldoInsoluto'] = FORMAT.format(r['ImpSaldoInsoluto']) @@ -5432,12 +5435,14 @@ class CfdiPagos(BaseModel): 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': mov.cuenta.moneda.key, + 'MonedaP': currency, 'Monto': FORMAT.format(mov.deposito), - 'relacionados': self._get_related_xml(self, invoice.movimiento), + 'relacionados': related_docs, } complementos = {'pagos': pagos} @@ -5466,9 +5471,30 @@ class CfdiPagos(BaseModel): obj.xml = self._generate_xml(self, obj, auth) obj.estatus = 'Generada' obj.save() - # ~ result = util.timbra_xml(obj.xml, auth) - data = {'ok': True, 'row': {}} - return data + 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']) @@ -5488,6 +5514,13 @@ class CfdiPagos(BaseModel): .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 + @classmethod def get_values(cls, values): opt = values.pop('opt') diff --git a/source/static/js/controller/bancos.js b/source/static/js/controller/bancos.js index 5e85daf..2ab53dd 100644 --- a/source/static/js/controller/bancos.js +++ b/source/static/js/controller/bancos.js @@ -41,6 +41,7 @@ var bancos_controllers = { $$('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() } @@ -800,6 +801,7 @@ function update_grid_cfdi_pay(row){ } 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, { @@ -810,8 +812,10 @@ function send_stamp_cfdi_pay(id_mov){ success:function(text, data, XmlHttpRequest){ result = data.json(); if(result.ok){ - msg = 'Factura timbrada correctamente' - msg_ok(msg) + g.updateItem(result.id, result.row) + msg_ok(result.msg) + }else{ + msg_error(result.msg) } } }) @@ -870,3 +874,19 @@ function cmd_pay_stamp_click(){ 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'){ + //~ get_pdf(row.id) + //~ }else if(id.column == 'email'){ + //~ enviar_correo(row) + //~ } + +} diff --git a/source/static/js/ui/bancos.js b/source/static/js/ui/bancos.js index 78611c3..5d161af 100644 --- a/source/static/js/ui/bancos.js +++ b/source/static/js/ui/bancos.js @@ -114,7 +114,7 @@ var grid_cfdi_este_deposito_cols = [ ] -var grid_cfdi_pago_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}, @@ -210,7 +210,7 @@ var grid_cfdi_pay = { autoheight: true, resizeColumn: true, headermenu: true, - columns: grid_cfdi_pago_cols, + columns: grid_cfdi_pay_cols, on:{ 'data->onStoreUpdated':function(){ this.data.each(function(obj, i){ diff --git a/source/xslt/cadena.xslt b/source/xslt/cadena.xslt index 8ed4715..81d45ac 100644 --- a/source/xslt/cadena.xslt +++ b/source/xslt/cadena.xslt @@ -12,6 +12,7 @@ + diff --git a/source/xslt/pagos10.xslt b/source/xslt/pagos10.xslt new file mode 100644 index 0000000..98b41f2 --- /dev/null +++ b/source/xslt/pagos10.xslt @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +