diff --git a/requirements.txt b/requirements.txt
index 6e32811..d65df38 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -19,4 +19,3 @@ xmlsec
# pyusb
# pyserial
# qrcode
-
diff --git a/source/app/controllers/pycfdi.py b/source/app/controllers/pycfdi.py
index 956d57f..f098330 100644
--- a/source/app/controllers/pycfdi.py
+++ b/source/app/controllers/pycfdi.py
@@ -1,5 +1,8 @@
#!/usr/bin/env python3
+from decimal import Decimal, getcontext
+getcontext().prec = 6
+
import lxml.etree as ET
from requests.structures import CaseInsensitiveDict as CIDict
@@ -54,6 +57,10 @@ class CfdiRead(object):
self._data['receptor'] = self._get_attr(node_name)
self._rfc_receptor = self._data['receptor']['Rfc']
+ node_name = f'{PRE}/cfdi:Complemento/tfd:TimbreFiscalDigital'
+ self._data['timbre'] = self._get_attr(node_name)
+
+ self._parse_details()
return
def _get_attr(self, node_name):
@@ -61,6 +68,19 @@ class CfdiRead(object):
attr = dict(node.attrib)
return attr
+ def _parse_details(self):
+ node_name = f'{PRE}/cfdi:Conceptos/cfdi:Concepto'
+ details = self._tree.xpath(node_name, namespaces=NS_CFDI)
+ rows = []
+ for detail in details:
+ row = dict(detail.attrib)
+ for k, v in row.items():
+ if k in ('Cantidad', 'ValorUnitario', 'Descuento', 'Importe'):
+ row[k] = Decimal(v)
+ # ~ row['taxes'] = self._get_taxes(detail)
+ rows.append(row)
+ self._data['conceptos'] = rows
+ return
class CfdiWrite(object):
diff --git a/source/app/controllers/utils.py b/source/app/controllers/utils.py
index a181e01..05e04ae 100644
--- a/source/app/controllers/utils.py
+++ b/source/app/controllers/utils.py
@@ -792,6 +792,20 @@ def _products_from_xml(rfc, data):
return result
result['data'] = cfdi.data
+ products = result['data']['conceptos']
+ rows = []
+ for p in products:
+ row = {
+ 'key': p['NoIdentificacion'],
+ 'key_sat': p['ClaveProdServ'],
+ 'description': p['Descripcion'],
+ 'unit': p['Unidad'],
+ 'unit_value': p['ValorUnitario'],
+ 'import': p['Importe'],
+ 'cant': p['Cantidad'],
+ }
+ rows.append(row)
+ result['data']['conceptos'] = rows
return result
diff --git a/source/static/js/controller/products.js b/source/static/js/controller/products.js
index e6d50a3..05ebef1 100644
--- a/source/static/js/controller/products.js
+++ b/source/static/js/controller/products.js
@@ -512,10 +512,15 @@ function up_products_from_xml_upload_complete(response){
return
}
+ var grid = $$('grid_partner_products')
var data = response.data
var html = ''
html += data.emisor.Nombre + ' (' + data.emisor.Rfc + ')'
$$('lbl_partner').setValue(html)
+ grid.clearAll();
+ grid.parse(data.conceptos, 'json');
+ grid.refresh()
+
}
diff --git a/source/static/js/ui/products.js b/source/static/js/ui/products.js
index 5021d39..4f3a650 100644
--- a/source/static/js/ui/products.js
+++ b/source/static/js/ui/products.js
@@ -233,10 +233,10 @@ var grid_partner_products_cols = [
{id: 'key_sat', header:{text: 'Clave SAT', css: 'center'}, width: 100,
adjust: 'data'},
{id: 'description', header:{text: 'DescripciĆ³n', css: 'center'},
- fillspace: true, editor: 'popup'},
+ fillspace: true},
{id: "pedimento", header: 'Pedimento', editor: 'text', hidden: true},
{id: 'unit', header:{text: 'Unidad', css: 'center'}, width: 100,
- editor: 'select', options: 'values/unidades'},
+ adjust: 'data'},
{id: 'unit_value', header:{text: 'Valor Unitario', css: 'center'},
width: 100, format: format_currency, css: 'right', editor: 'text'},
//~ {id: 'descuento', header:{text: 'Descuento', css: 'center'},
@@ -245,7 +245,7 @@ var grid_partner_products_cols = [
//~ format: webix.i18n.priceFormat, css: 'right'},
{id: 'import', header:{text: 'Importe', css: 'center'}, width: 100,
format: webix.i18n.priceFormat, css: 'right'},
- {id: 'cantidad', header: {text: 'Cantidad', css: 'center'}, width: 50,
+ {id: 'cant', header: {text: 'Cantidad', css: 'center'}, width: 50,
format: webix.i18n.numberFormat, css: 'right', editor: 'text'},
{id: 'separate', header: '', width: 25},
{id: 'id_product', header: '', hidden: true},