From 62a0a8269994f0f711d314263723ad8e14ea1e77 Mon Sep 17 00:00:00 2001 From: Mauricio Baeza Date: Tue, 8 Jun 2021 22:54:59 -0500 Subject: [PATCH] Refactory class for read and write CFDIs --- source/app/controllers/pycfdi.py | 67 +++++++++++++++++++++++++ source/app/controllers/utils.py | 19 +++++-- source/static/js/controller/products.js | 17 +++++-- 3 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 source/app/controllers/pycfdi.py diff --git a/source/app/controllers/pycfdi.py b/source/app/controllers/pycfdi.py new file mode 100644 index 0000000..956d57f --- /dev/null +++ b/source/app/controllers/pycfdi.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 + +import lxml.etree as ET +from requests.structures import CaseInsensitiveDict as CIDict + + +NS_CFDI = { + 'cfdi': 'http://www.sat.gob.mx/cfd/3', + 'tfd': 'http://www.sat.gob.mx/TimbreFiscalDigital', + 'nomina12': 'http://www.sat.gob.mx/nomina12', +} +PRE = '/cfdi:Comprobante' + + +class CfdiRead(object): + + def __init__(self, source): + self._source = source + self._data = {} + self._error = '' + self._rfc_emisor = '' + self._rfc_receptor = '' + self._parse() + + @property + def source(self): + return self._source + + @property + def data(self): + return self._data + + @property + def rfc_emisor(self): + return self._rfc_emisor + + @property + def rfc_receptor(self): + return self._rfc_receptor + + @property + def error(self): + return self._error + + def _parse(self): + self._tree = ET.fromstring(self.source) + self._data['cfdi'] = dict(self._tree.attrib) + + node_name = f'{PRE}/cfdi:Emisor' + self._data['emisor'] = self._get_attr(node_name) + self._rfc_emisor = self._data['emisor']['Rfc'] + + node_name = f'{PRE}/cfdi:Receptor' + self._data['receptor'] = self._get_attr(node_name) + self._rfc_receptor = self._data['receptor']['Rfc'] + + return + + def _get_attr(self, node_name): + node = self._tree.xpath(node_name, namespaces=NS_CFDI)[0] + attr = dict(node.attrib) + return attr + + + +class CfdiWrite(object): + pass diff --git a/source/app/controllers/utils.py b/source/app/controllers/utils.py index a5bb457..a181e01 100644 --- a/source/app/controllers/utils.py +++ b/source/app/controllers/utils.py @@ -59,6 +59,9 @@ from .pacs.cfdi_cert import SATCertificate from .pacs import PACComercioDigital from .pacs import PACFinkok +# ~ v2 +from .pycfdi import CfdiRead + LOG_FORMAT = '%(asctime)s - %(levelname)s - %(message)s' LOG_DATE = '%d/%m/%Y %H:%M:%S' @@ -779,11 +782,21 @@ def read_csv(path, args={'delimiter': '|'}): return rows -def _products_from_xml(obj): - return {'status': 'server', 'data': {'uno': 1}} +def _products_from_xml(rfc, data): + result = {'status': 'server', 'error': ''} + cfdi = CfdiRead(data) + + if not DEBUG and rfc != cfdi.rfc_receptor: + msg = f'El receptor no es: {rfc}' + result['error'] = msg + return result + + result['data'] = cfdi.data + + return result def upload_file(rfc, opt, file_obj): if opt == 'productsadd': - result = _products_from_xml(file_obj) + result = _products_from_xml(rfc, file_obj.file.read()) return result diff --git a/source/static/js/controller/products.js b/source/static/js/controller/products.js index cff0e67..e6d50a3 100644 --- a/source/static/js/controller/products.js +++ b/source/static/js/controller/products.js @@ -481,7 +481,8 @@ function cmd_upload_products_from_xml_click(){ return } - msg = '¿Estás seguro de importar este archivo?' + msg = '¿Estás seguro de importar este archivo?

\ + Si hay datos previos seran reemplazados.' webix.confirm({ title: 'Importar Productos', ok: 'Si', @@ -505,6 +506,16 @@ function up_products_from_xml_upload_complete(response){ } $$('win_add_products_from_xml').close() - msg = 'Archivo subido correctamente.\n\nComenzando importación.' - msg_ok(msg) + + if(response.error){ + msg_error(response.error) + return + } + + var data = response.data + + var html = '' + html += data.emisor.Nombre + ' (' + data.emisor.Rfc + ')' + $$('lbl_partner').setValue(html) + }