PDF from CE in version 2.0

This commit is contained in:
El Mau 2024-01-24 13:45:23 -06:00
parent 510ebdd1e5
commit d925587a98
7 changed files with 86 additions and 3 deletions

View File

@ -1,3 +1,9 @@
v 2.2.0 [24-Ene-2024]
- Mejora: Soporte para complemento Comercio Exterior 2.0
- **IMPORTANTE**: Aunque no lo uses, esto afecta al JS de facturación, por
lo que tienes que forzar el refresco (CTRL+F5) si tienes algún problema.
v 2.1.0 [26-Dic-2023]
- Mejora: Se agrega filtro por día en facturas.

View File

@ -1 +1 @@
2.1.0
2.2.0

View File

@ -1022,6 +1022,51 @@ class LIBO(object):
return
def _comercio_exterior(self, data):
if not data:
return
emisor = data.pop('emisor')
receptor = data.pop('receptor')
mercancias = data.pop('mercancias')
for k, v in data.items():
self._set_cell(f'{{cce.{k}}}', v)
for k, v in emisor.items():
self._set_cell(f'{{cce.emisor.{k}}}', v)
for k, v in receptor.items():
self._set_cell(f'{{cce.receptor.{k}}}', v)
first = True
count = len(mercancias) - 1
for i, mercancia in enumerate(mercancias):
no_identificacion = mercancia['NoIdentificacion']
fraccion = mercancia['FraccionArancelaria']
unidad = mercancia['UnidadAduana']
cantidad = mercancia['CantidadAduana']
valor_unitario = mercancia['ValorUnitarioAduana']
valor_dolares = mercancia['ValorDolares']
if first:
first = False
cell_1 = self._set_cell('{cce.mercancia.noidentificacion}', no_identificacion)
cell_2 = self._set_cell('{cce.mercancia.fraccionarancelaria}', fraccion)
cell_3 = self._set_cell('{cce.mercancia.unidadaduana}', unidad)
cell_4 = self._set_cell('{cce.mercancia.cantidadaduana}', cantidad)
cell_5 = self._set_cell('{cce.mercancia.valorunitarioaduana}', valor_unitario)
cell_6 = self._set_cell('{cce.mercancia.valordolares}', valor_dolares)
if count > 0:
row = cell_1.CellAddress.Row + 1
self._sheet.getRows().insertByIndex(row, count)
self._copy_paste_rows(cell_1, count)
else:
cell_1 = self._set_cell(v=no_identificacion, cell=cell_1)
cell_2 = self._set_cell(v=fraccion, cell=cell_2)
cell_3 = self._set_cell(v=unidad, cell=cell_3)
cell_4 = self._set_cell(v=cantidad, cell=cell_4)
cell_5 = self._set_cell(v=valor_unitario, cell=cell_5)
cell_6 = self._set_cell(v=valor_dolares, cell=cell_6)
return
def _nomina(self, data):
if not data:
return
@ -1258,6 +1303,7 @@ class LIBO(object):
self._divisas(data.get('divisas', {}))
self._leyendas(data.get('leyendas', ''))
self._carta_porte(data.get('carta_porte', {}))
self._comercio_exterior(data.get('comercio_exterior', {}))
self._timbre(data['timbre'])
@ -1655,8 +1701,13 @@ def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
default = f'plantilla_donatarias_{version}_{version_donatarias}.ods'
version = f'{version}_cd_{version_donatarias}'
if 'comercio_exterior' in data:
version_cce = data['comercio_exterior']['version']
default = f'plantilla_cce_{version}_{version_cce}.ods'
version = f'{version}_cce_{version_cce}'
template_name = f'{rfc.lower()}_{version}.ods'
# ~ print('T', template_name, default)
# ~ print('\nT', template_name, default)
if APP_LIBO:
app = LIBO()
@ -2370,6 +2421,7 @@ def upload_file(rfc, opt, file_obj):
'_4.0_cp_2.0.ods',
'_4.0_ccp_2.0.ods',
'_4.0_cd_1.1.ods',
'_4.0_cce_2.0.ods',
'_4.0.json',
)
if opt in versions:

View File

@ -265,6 +265,7 @@ class CfdiToDict(object):
'leyendasFisc': 'http://www.sat.gob.mx/leyendasFiscales',
'cartaporte20': 'http://www.sat.gob.mx/CartaPorte20',
'nomina12': 'http://www.sat.gob.mx/nomina12',
'cce20': 'http://www.sat.gob.mx/ComercioExterior20',
}
tipo_figura = {
'01': '[01] Operador',
@ -513,6 +514,29 @@ class CfdiToDict(object):
self._values['carta_porte'] = values
self._complemento_comercio_exterior(complemento)
return
def _complemento_comercio_exterior(self, complemento):
path = '//cce20:ComercioExterior'
comercio_exterior = complemento.xpath(path, namespaces=self.NS)
if comercio_exterior:
values = CaseInsensitiveDict(comercio_exterior[0].attrib)
for node in comercio_exterior[0]:
if 'Emisor' in node.tag:
values['emisor'] = CaseInsensitiveDict(node.attrib)
values['emisor'].update(CaseInsensitiveDict(node[0].attrib))
elif 'Receptor' in node.tag:
values['receptor'] = CaseInsensitiveDict(node.attrib)
values['receptor'].update(CaseInsensitiveDict(node[0].attrib))
elif 'Mercancias' in node.tag:
mercancias = [
CaseInsensitiveDict(m.attrib) for m in node]
values['mercancias'] = mercancias
self._values['comercio_exterior'] = values
return

View File

@ -39,7 +39,7 @@ except ImportError:
DEBUG = DEBUG
VERSION = '2.1.0'
VERSION = '2.2.0'
EMAIL_SUPPORT = ('soporte@empresalibre.mx',)
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)

View File

@ -605,6 +605,7 @@ var opt_templates_cfdi = [
{id: '_4.0_cp_2.0.ods', value: 'CFDI v4.0 - Pagos v2.0'},
{id: '_4.0_ccp_2.0.ods', value: 'CFDI v4.0 - Carta Porte v2.0'},
{id: '_4.0_cd_1.1.ods', value: 'CFDI v4.0 - Donativos v1.1'},
{id: '_4.0_cce_2.0.ods', value: 'CFDI v4.0 - Comercio Exterior v2.0'},
{id: '_4.0.json', value: 'CFDI v4.0 - JSON'},
{id: '_3.3.ods', value: 'CFDI v3.3'},
{id: '_3.3_cn_1.2.ods', value: 'CFDI v3.3 - Nómina v1.2'},

Binary file not shown.