Parse details from CFDI
This commit is contained in:
parent
62a0a82699
commit
dc61d3b010
|
@ -19,4 +19,3 @@ xmlsec
|
||||||
# pyusb
|
# pyusb
|
||||||
# pyserial
|
# pyserial
|
||||||
# qrcode
|
# qrcode
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from decimal import Decimal, getcontext
|
||||||
|
getcontext().prec = 6
|
||||||
|
|
||||||
import lxml.etree as ET
|
import lxml.etree as ET
|
||||||
from requests.structures import CaseInsensitiveDict as CIDict
|
from requests.structures import CaseInsensitiveDict as CIDict
|
||||||
|
|
||||||
|
@ -54,6 +57,10 @@ class CfdiRead(object):
|
||||||
self._data['receptor'] = self._get_attr(node_name)
|
self._data['receptor'] = self._get_attr(node_name)
|
||||||
self._rfc_receptor = self._data['receptor']['Rfc']
|
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
|
return
|
||||||
|
|
||||||
def _get_attr(self, node_name):
|
def _get_attr(self, node_name):
|
||||||
|
@ -61,6 +68,19 @@ class CfdiRead(object):
|
||||||
attr = dict(node.attrib)
|
attr = dict(node.attrib)
|
||||||
return attr
|
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):
|
class CfdiWrite(object):
|
||||||
|
|
|
@ -792,6 +792,20 @@ def _products_from_xml(rfc, data):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
result['data'] = cfdi.data
|
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
|
return result
|
||||||
|
|
||||||
|
|
|
@ -512,10 +512,15 @@ function up_products_from_xml_upload_complete(response){
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var grid = $$('grid_partner_products')
|
||||||
var data = response.data
|
var data = response.data
|
||||||
|
|
||||||
var html = '<span class="webix_icon fa-user"></span><span class="lbl_partner">'
|
var html = '<span class="webix_icon fa-user"></span><span class="lbl_partner">'
|
||||||
html += data.emisor.Nombre + ' (' + data.emisor.Rfc + ')</span>'
|
html += data.emisor.Nombre + ' (' + data.emisor.Rfc + ')</span>'
|
||||||
$$('lbl_partner').setValue(html)
|
$$('lbl_partner').setValue(html)
|
||||||
|
|
||||||
|
grid.clearAll();
|
||||||
|
grid.parse(data.conceptos, 'json');
|
||||||
|
grid.refresh()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -233,10 +233,10 @@ var grid_partner_products_cols = [
|
||||||
{id: 'key_sat', header:{text: 'Clave SAT', css: 'center'}, width: 100,
|
{id: 'key_sat', header:{text: 'Clave SAT', css: 'center'}, width: 100,
|
||||||
adjust: 'data'},
|
adjust: 'data'},
|
||||||
{id: 'description', header:{text: 'Descripción', css: 'center'},
|
{id: 'description', header:{text: 'Descripción', css: 'center'},
|
||||||
fillspace: true, editor: 'popup'},
|
fillspace: true},
|
||||||
{id: "pedimento", header: 'Pedimento', editor: 'text', hidden: true},
|
{id: "pedimento", header: 'Pedimento', editor: 'text', hidden: true},
|
||||||
{id: 'unit', header:{text: 'Unidad', css: 'center'}, width: 100,
|
{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'},
|
{id: 'unit_value', header:{text: 'Valor Unitario', css: 'center'},
|
||||||
width: 100, format: format_currency, css: 'right', editor: 'text'},
|
width: 100, format: format_currency, css: 'right', editor: 'text'},
|
||||||
//~ {id: 'descuento', header:{text: 'Descuento', css: 'center'},
|
//~ {id: 'descuento', header:{text: 'Descuento', css: 'center'},
|
||||||
|
@ -245,7 +245,7 @@ var grid_partner_products_cols = [
|
||||||
//~ format: webix.i18n.priceFormat, css: 'right'},
|
//~ format: webix.i18n.priceFormat, css: 'right'},
|
||||||
{id: 'import', header:{text: 'Importe', css: 'center'}, width: 100,
|
{id: 'import', header:{text: 'Importe', css: 'center'}, width: 100,
|
||||||
format: webix.i18n.priceFormat, css: 'right'},
|
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'},
|
format: webix.i18n.numberFormat, css: 'right', editor: 'text'},
|
||||||
{id: 'separate', header: '', width: 25},
|
{id: 'separate', header: '', width: 25},
|
||||||
{id: 'id_product', header: '', hidden: true},
|
{id: 'id_product', header: '', hidden: true},
|
||||||
|
|
Loading…
Reference in New Issue