From 3c5c597b81982699d3fd46d0df7a59fe9e2862de Mon Sep 17 00:00:00 2001 From: Mauricio Baeza Date: Sat, 3 Feb 2018 01:23:05 -0600 Subject: [PATCH] =?UTF-8?q?Generar=20PDF=20de=20N=C3=B3mina?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/app/controllers/util.py | 123 +++++++++++++++++++++++++++++++-- source/app/models/main.py | 1 + 2 files changed, 120 insertions(+), 4 deletions(-) diff --git a/source/app/controllers/util.py b/source/app/controllers/util.py index 99ca028..ec42e71 100644 --- a/source/app/controllers/util.py +++ b/source/app/controllers/util.py @@ -760,6 +760,12 @@ class LIBO(object): self._sheet.copyRange(nc.getCellAddress(), source.getRangeAddress()) return + def _clean_rows(self, row, count): + for i in range(count): + source = self._sheet.getRows().getByIndex(row + i) + source.clearContents(4) + return + def _copy_paste_rows(self, cell, count): dispatch = self._create_instance('com.sun.star.frame.DispatchHelper') @@ -937,7 +943,79 @@ class LIBO(object): return def _nomina(self, data): - print(data) + if not data: + return + + percepciones = data.pop('percepciones', []) + deducciones = data.pop('deducciones', []) + otrospagos = data.pop('otrospagos', []) + + for k, v in data.items(): + self._set_cell('{nomina.%s}' % k, v) + + count = len(percepciones) + if len(deducciones) > count: + count = len(deducciones) + count -= 1 + + first = True + for r in percepciones: + tipo = r.get('TipoPercepcion') + concepto = r.get('Concepto') + gravado = r.get('ImporteGravado') + exento = r.get('ImporteExento') + if first: + first = False + cell_1 = self._set_cell('{percepcion.TipoPercepcion}', tipo) + cell_2 = self._set_cell('{percepcion.Concepto}', concepto) + cell_3 = self._set_cell('{percepcion.ImporteGravado}', gravado, value=True) + cell_4 = self._set_cell('{percepcion.ImporteExento}', exento, value=True) + if count: + row = cell_1.getCellAddress().Row + 1 + self._sheet.getRows().insertByIndex(row, count) + self._copy_paste_rows(cell_1, count) + self._clean_rows(row, count) + else: + cell_1 = self._set_cell(v=tipo, cell=cell_1) + cell_2 = self._set_cell(v=concepto, cell=cell_2) + cell_3 = self._set_cell(v=gravado, cell=cell_3, value=True) + cell_4 = self._set_cell(v=exento, cell=cell_4, value=True) + + first = True + for r in deducciones: + tipo = r.get('TipoDeduccion') + concepto = r.get('Concepto') + importe = r.get('Importe') + if first: + first = False + cell_1 = self._set_cell('{deduccion.TipoDeduccion}', tipo) + cell_2 = self._set_cell('{deduccion.Concepto}', concepto) + cell_3 = self._set_cell('{deduccion.Importe}', importe, value=True) + else: + cell_1 = self._set_cell(v=tipo, cell=cell_1) + cell_2 = self._set_cell(v=concepto, cell=cell_2) + cell_3 = self._set_cell(v=importe, cell=cell_3, value=True) + + count = len(otrospagos) - 1 + first = True + for r in otrospagos: + tipo = r.get('TipoOtroPago') + concepto = r.get('Concepto') + importe = r.get('Importe') + if first: + first = False + cell_1 = self._set_cell('{otropago.TipoOtroPago}', tipo) + cell_2 = self._set_cell('{otropago.Concepto}', concepto) + cell_3 = self._set_cell('{otropago.Importe}', importe, value=True) + if count: + row = cell_1.getCellAddress().Row + 1 + self._sheet.getRows().insertByIndex(row, count) + self._copy_paste_rows(cell_1, count) + self._clean_rows(row, count) + else: + cell_1 = self._set_cell(v=tipo, cell=cell_1) + cell_2 = self._set_cell(v=concepto, cell=cell_2) + cell_3 = self._set_cell(v=importe, cell=cell_3, value=True) return def _render(self, data): @@ -1541,12 +1619,49 @@ def _ine(doc, version): return data -def _nomina(invoice, values): +def _nomina(doc, data, values, version_cfdi): is_nomina = values.get('is_nomina', False) if not is_nomina: return {} - return {'version': '1.2'} + version = values['version'] + + node_nomina = doc.find('{}Complemento/{}Nomina'.format( + PRE[version_cfdi], PRE['NOMINA'][version])) + if node_nomina is None: + return {} + info = CaseInsensitiveDict(node_nomina.attrib.copy()) + + node = node_nomina.find('{}Emisor'.format(PRE['NOMINA'][version])) + data['emisor'].update(CaseInsensitiveDict(node.attrib.copy())) + + node = node_nomina.find('{}Receptor'.format(PRE['NOMINA'][version])) + data['receptor'].update(CaseInsensitiveDict(node.attrib.copy())) + + node = node_nomina.find('{}Percepciones'.format(PRE['NOMINA'][version])) + if not node is None: + data['comprobante'].update(CaseInsensitiveDict(node.attrib.copy())) + info['percepciones'] = [] + for p in node.getchildren(): + info['percepciones'].append(CaseInsensitiveDict(p.attrib.copy())) + + node = node_nomina.find('{}Deducciones'.format(PRE['NOMINA'][version])) + if not node is None: + data['comprobante'].update(CaseInsensitiveDict(node.attrib.copy())) + info['deducciones'] = [] + for d in node.getchildren(): + info['deducciones'].append(CaseInsensitiveDict(d.attrib.copy())) + + node = node_nomina.find('{}OtrosPagos'.format(PRE['NOMINA'][version])) + if not node is None: + info['otrospagos'] = [] + for o in node.getchildren(): + info['otrospagos'].append(CaseInsensitiveDict(o.attrib.copy())) + n = o.find('{}SubsidioAlEmpleo'.format(PRE['NOMINA'][version])) + if not n is None: + info.update(CaseInsensitiveDict(n.attrib.copy())) + + return info def get_data_from_xml(invoice, values): @@ -1572,7 +1687,7 @@ def get_data_from_xml(invoice, values): del data['timbre']['version'] data['comprobante'].update(data['timbre']) - data['nomina'] = _nomina(invoice, values) + data['nomina'] = _nomina(doc, data, values, version) return data diff --git a/source/app/models/main.py b/source/app/models/main.py index fa2a0bb..d086fdf 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -6423,6 +6423,7 @@ class CfdiNomina(BaseModel): values['usocfdi'] = invoice.uso_cfdi values['receptor'] = {} values['fechadof'] = None + values['version'] = invoice.version_nomina return values