From 8e75a6cc16436694928ed7ef53f85197a9bfe7bf Mon Sep 17 00:00:00 2001 From: Mauricio Baeza Date: Fri, 16 Feb 2018 22:16:46 -0600 Subject: [PATCH] Fix - Issue #190 --- source/app/controllers/cfdi_xml.py | 6 ---- source/app/controllers/util.py | 33 ++++++++++++++++++- source/app/models/main.py | 52 ++++++++++++++++++++++++++---- 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/source/app/controllers/cfdi_xml.py b/source/app/controllers/cfdi_xml.py index 1692db4..23be3e6 100644 --- a/source/app/controllers/cfdi_xml.py +++ b/source/app/controllers/cfdi_xml.py @@ -213,12 +213,6 @@ class CFDI(object): conceptos = ET.SubElement(self._cfdi, '{}:Conceptos'.format(self._pre)) for row in reversed(datos): - # ~ print (row['Descripcion']) - # ~ xml = escape(xml.encode('ascii', 'xmlcharrefreplace').decode('utf-8'), False) - # ~ row['Descripcion'] = escape(row['Descripcion'].replace('\n', ' '), False) - # ~ row['Descripcion'] = row['Descripcion'].replace('\n', ' ') - # ~ print (row['Descripcion']) - complemento = {} if 'complemento' in row: complemento = row.pop('complemento') diff --git a/source/app/controllers/util.py b/source/app/controllers/util.py index 6100ece..db09fa6 100644 --- a/source/app/controllers/util.py +++ b/source/app/controllers/util.py @@ -767,7 +767,7 @@ class LIBO(object): def _clean_rows(self, row, count): for i in range(count): source = self._sheet.getRows().getByIndex(row + i) - source.clearContents(4) + source.clearContents(5) return def _copy_paste_rows(self, cell, count): @@ -961,6 +961,7 @@ class LIBO(object): percepciones = data.pop('percepciones', []) deducciones = data.pop('deducciones', []) otrospagos = data.pop('otrospagos', []) + incapacidades = data.pop('incapacidades', []) for k, v in data.items(): if k.lower() in ('totalpercepciones', 'totaldeducciones', @@ -1032,6 +1033,28 @@ class LIBO(object): 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(incapacidades) - 1 + first = True + for r in incapacidades: + tipo = r.get('TipoIncapacidad') + days = r.get('DiasIncapacidad') + importe = r.get('ImporteMonetario') + if first: + first = False + cell_1 = self._set_cell('{incapacidad.TipoIncapacidad}', tipo) + cell_2 = self._set_cell('{incapacidad.DiasIncapacidad}', days) + cell_3 = self._set_cell('{incapacidad.ImporteMonetario}', 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): @@ -1175,6 +1198,7 @@ class LIBO(object): 'fecha_pago', 'fecha_inicial_pago', 'fecha_final_pago', + 'relacionados', ) data = tuple([dict(zip(fields, r[1:])) for r in rows[2:]]) return data, '' @@ -1409,6 +1433,7 @@ def _comprobante(doc, options): if is_nomina: data['formadepago'] = options['formadepago'] data['periodicidaddepago'] = options['periodicidaddepago'] + data['tiporelacion'] = options.get('tiporelacion', '') return data if data['version'] == '3.3': @@ -1707,6 +1732,12 @@ def _nomina(doc, data, values, version_cfdi): if not n is None: info.update(CaseInsensitiveDict(n.attrib.copy())) + node = node_nomina.find('{}Incapacidades'.format(PRE['NOMINA'][version])) + if not node is None: + info['incapacidades'] = [] + for i in node.getchildren(): + info['incapacidades'].append(CaseInsensitiveDict(i.attrib.copy())) + return info diff --git a/source/app/models/main.py b/source/app/models/main.py index ea245b1..edae9fa 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -3248,7 +3248,6 @@ class Facturas(BaseModel): if invoice.tipo_relacion: obj = SATTipoRelacion.get(SATTipoRelacion.key==invoice.tipo_relacion) values['tiporelacion'] = str(obj) - print(values['tiporelacion']) receptor = Socios.select().where(Socios.id==invoice.cliente.id).dicts()[0] values['receptor'] = {} @@ -5923,6 +5922,26 @@ class CfdiNomina(BaseModel): return new + def _get_relacionados(values): + rows = values.split('|') + msg = '' + uuids = [] + for row in rows: + sf = row.split('-') + if len(sf) == 1: + msg = 'Formato incorrecto en CFDI relacionado: SERIE-FOLIO' + return [], msg + try: + obj = CfdiNomina.get( + CfdiNomina.serie==sf[0], CfdiNomina.folio==int(sf[1])) + except CfdiNomina.DoesNotExist: + msg = 'No existe el CFDI relacionado: {}'.format(row) + return [], msg + + uuids.append({'cfdi_origen': obj.id}) + + return uuids, msg + def _validate_nomina(self, row): sn = {'si': True, 'no': False} data = row.copy() @@ -5938,6 +5957,11 @@ class CfdiNomina(BaseModel): msg = 'RFC: {}, Tipo de NĂ³mina no existe: {}'.format(row['tipo_nomina']) return {}, msg + if data['relacionados']: + data['relacionados'], msg = self._get_relacionados(data['relacionados']) + if msg: + return {}, msg + data['serie'] = self._get_serie(self) data['folio'] = self._get_folio(self, data['serie']) data['forma_pago'] = DEFAULT_SAT_NOMINA['FORMA_PAGO'] @@ -6170,6 +6194,10 @@ class CfdiNomina(BaseModel): util.log_file('nomina', msg) continue + relacionados = new_nomina.pop('relacionados', '') + if relacionados: + new_nomina['tipo_relacion'] = '04' + new_percepciones, total_percepciones, msg = \ self._validate_percepciones(self, hp, percepciones[i]) if msg: @@ -6236,6 +6264,9 @@ class CfdiNomina(BaseModel): for row in new_incapacidades: row['cfdi'] = obj CfdiNominaIncapacidad.create(**row) + for row in relacionados: + row['cfdi'] = obj + CfdiNominaRelacionados.create(**row) concepto = { 'cfdi': obj, @@ -6321,11 +6352,11 @@ class CfdiNomina(BaseModel): if cfdi.descuento: comprobante['Descuento'] = FORMAT.format(cfdi.descuento) - # ~ if invoice.tipo_relacion: - # ~ relacionados = { - # ~ 'tipo': invoice.tipo_relacion, - # ~ 'cfdis': FacturasRelacionadas.get_(invoice), - # ~ } + if cfdi.tipo_relacion: + relacionados = { + 'tipo': cfdi.tipo_relacion, + 'cfdis': CfdiNominaRelacionados.get_(cfdi), + } cfdi_emisor = { 'Rfc': emisor.rfc, @@ -6666,6 +6697,7 @@ class CfdiNomina(BaseModel): obj = SATPeriodicidadPago.get(SATPeriodicidadPago.id==invoice.empleado.periodicidad_pago) values['periodicidaddepago'] = '{} ({})'.format(obj.name, obj.key) + values['tiporelacion'] = invoice.tipo_relacion values['usocfdi'] = invoice.uso_cfdi values['receptor'] = {} values['fechadof'] = None @@ -6885,6 +6917,14 @@ class CfdiNominaRelacionados(BaseModel): class Meta: order_by = ('cfdi',) + @classmethod + def get_(cls, cfdi): + query = (CfdiNominaRelacionados + .select() + .where(CfdiNominaRelacionados.cfdi==cfdi) + ) + return [str(r.cfdi_origen.uuid) for r in query] + def authenticate(args): respuesta = {'login': False, 'msg': 'No Autorizado', 'user': ''}