Generar PDF
This commit is contained in:
parent
981fdba5f4
commit
09e3b46eca
|
@ -9,3 +9,4 @@ bcrypt
|
||||||
python-dateutil
|
python-dateutil
|
||||||
zeep
|
zeep
|
||||||
chardet
|
chardet
|
||||||
|
pyqrcode
|
||||||
|
|
|
@ -18,7 +18,9 @@ from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
import uno
|
import uno
|
||||||
from com.sun.star.beans import PropertyValue
|
from com.sun.star.beans import PropertyValue
|
||||||
|
from com.sun.star.awt import Size
|
||||||
|
|
||||||
|
import pyqrcode
|
||||||
from dateutil import parser
|
from dateutil import parser
|
||||||
|
|
||||||
from .helper import CaseInsensitiveDict, NumLet
|
from .helper import CaseInsensitiveDict, NumLet
|
||||||
|
@ -538,6 +540,16 @@ class LIBO(object):
|
||||||
self._sd.SearchCaseSensitive = False
|
self._sd.SearchCaseSensitive = False
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _next_cell(self, cell):
|
||||||
|
col = cell.getCellAddress().Column
|
||||||
|
row = cell.getCellAddress().Row + 1
|
||||||
|
return self._sheet.getCellByPosition(col, row)
|
||||||
|
|
||||||
|
def _copy_cell(self, cell):
|
||||||
|
destino = self._next_cell(cell)
|
||||||
|
self._sheet.copyRange(destino.getCellAddress(), cell.getRangeAddress())
|
||||||
|
return destino
|
||||||
|
|
||||||
def _set_cell(self, k='', v=None, cell=None, value=False):
|
def _set_cell(self, k='', v=None, cell=None, value=False):
|
||||||
if k:
|
if k:
|
||||||
self._sd.setSearchString(k)
|
self._sd.setSearchString(k)
|
||||||
|
@ -575,30 +587,111 @@ class LIBO(object):
|
||||||
self._set_cell('{cfdi.%s}' % k, v)
|
self._set_cell('{cfdi.%s}' % k, v)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _emisor(self, data):
|
||||||
|
for k, v in data.items():
|
||||||
|
self._set_cell('{emisor.%s}' % k, v)
|
||||||
|
return
|
||||||
|
|
||||||
|
def _receptor(self, data):
|
||||||
|
for k, v in data.items():
|
||||||
|
self._set_cell('{receptor.%s}' % k, v)
|
||||||
|
return
|
||||||
|
|
||||||
|
def _conceptos(self, data):
|
||||||
|
first = True
|
||||||
|
for concepto in data:
|
||||||
|
key = concepto.get('noidentificacion', '')
|
||||||
|
description = concepto['descripcion']
|
||||||
|
unidad = concepto['unidad']
|
||||||
|
cantidad = concepto['cantidad']
|
||||||
|
valor_unitario = concepto['valorunitario']
|
||||||
|
importe = concepto['importe']
|
||||||
|
if first:
|
||||||
|
first = False
|
||||||
|
cell_1 = self._set_cell('{noidentificacion}', key)
|
||||||
|
cell_2 = self._set_cell('{descripcion}', description)
|
||||||
|
cell_3 = self._set_cell('{unidad}', unidad)
|
||||||
|
cell_4 = self._set_cell('{cantidad}', cantidad, value=True)
|
||||||
|
cell_5 = self._set_cell('{valorunitario}', valor_unitario, value=True)
|
||||||
|
cell_6 = self._set_cell('{importe}', importe, value=True)
|
||||||
|
return
|
||||||
|
|
||||||
|
def _totales(self, data):
|
||||||
|
currency = data['moneda']
|
||||||
|
|
||||||
|
cell_title = self._set_cell('{subtotal.titulo}', 'SubTotal')
|
||||||
|
value = data['subtotal']
|
||||||
|
cell_value = self._set_cell('{subtotal}', value, value=True)
|
||||||
|
cell_value.CellStyle = currency
|
||||||
|
|
||||||
|
#~ Si encuentra el campo {total}, se asume que los totales e impuestos
|
||||||
|
#~ están declarados de forma independiente cada uno
|
||||||
|
#~ if self._add_totales(xml):
|
||||||
|
#~ return
|
||||||
|
|
||||||
|
#~ Si no se encuentra, copia las celdas hacia abajo de
|
||||||
|
#~ {subtotal.titulo} y {subtotal}
|
||||||
|
if 'descuento' in data:
|
||||||
|
self._copy_cell(cell_title)
|
||||||
|
self._copy_cell(cell_value)
|
||||||
|
cell_title = self._set_cell(v='Descuento', cell=cell_title)
|
||||||
|
value = data['descuento']
|
||||||
|
cell_value = self._set_cell(v=value, cell=cell_value, value=True)
|
||||||
|
cell_value.CellStyle = currency
|
||||||
|
|
||||||
|
for tax in data['traslados']:
|
||||||
|
self._copy_cell(cell_title)
|
||||||
|
self._copy_cell(cell_value)
|
||||||
|
cell_title = self._set_cell(v=tax[0], cell=cell_title)
|
||||||
|
cell_value = self._set_cell(v=tax[1], cell=cell_value, value=True)
|
||||||
|
cell_value.CellStyle = currency
|
||||||
|
|
||||||
|
for tax in data['retenciones']:
|
||||||
|
self._copy_cell(cell_title)
|
||||||
|
self._copy_cell(cell_value)
|
||||||
|
cell_title = self._set_cell(v=tax[0], cell=cell_title)
|
||||||
|
cell_value = self._set_cell(v=tax[1], cell=cell_value, value=True)
|
||||||
|
cell_value.CellStyle = currency
|
||||||
|
|
||||||
|
for tax in data['taxlocales']:
|
||||||
|
self._copy_cell(cell_title)
|
||||||
|
self._copy_cell(cell_value)
|
||||||
|
cell_title = self._set_cell(v=tax[0], cell=cell_title)
|
||||||
|
cell_value = self._set_cell(v=tax[1], cell=cell_value, value=True)
|
||||||
|
cell_value.CellStyle = currency
|
||||||
|
|
||||||
|
self._copy_cell(cell_title)
|
||||||
|
self._copy_cell(cell_value)
|
||||||
|
cell_title = self._set_cell(v='Total', cell=cell_title)
|
||||||
|
value = data['total']
|
||||||
|
cell_value = self._set_cell(v=value, cell=cell_value, value=True)
|
||||||
|
cell_value.CellStyle = currency
|
||||||
|
return
|
||||||
|
|
||||||
def _timbre(self, data):
|
def _timbre(self, data):
|
||||||
for k, v in data.items():
|
for k, v in data.items():
|
||||||
self._set_cell('{timbre.%s}' % k, v)
|
self._set_cell('{timbre.%s}' % k, v)
|
||||||
#~ pd = self._sheet.getDrawPage()
|
pd = self._sheet.getDrawPage()
|
||||||
#~ image = self._template.createInstance('com.sun.star.drawing.GraphicObjectShape')
|
image = self._template.createInstance('com.sun.star.drawing.GraphicObjectShape')
|
||||||
#~ image.GraphicURL = data['path_cbb']
|
image.GraphicURL = data['path_cbb']
|
||||||
#~ pd.add(image)
|
pd.add(image)
|
||||||
#~ s = Size()
|
s = Size()
|
||||||
#~ s.Width = 4500
|
s.Width = 4250
|
||||||
#~ s.Height = 4500
|
s.Height = 4500
|
||||||
#~ image.setSize(s)
|
image.setSize(s)
|
||||||
#~ image.Anchor = self._set_cell('{timbre.cbb}')
|
image.Anchor = self._set_cell('{timbre.cbb}')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def _render(self, data):
|
def _render(self, data):
|
||||||
self._set_search()
|
self._set_search()
|
||||||
self._comprobante(data['comprobante'])
|
self._comprobante(data['comprobante'])
|
||||||
#~ self._emisor(data['emisor'])
|
self._emisor(data['emisor'])
|
||||||
#~ self._receptor(data['receptor'])
|
self._receptor(data['receptor'])
|
||||||
#~ self._conceptos(data['conceptos'])
|
self._conceptos(data['conceptos'])
|
||||||
|
self._totales(data['totales'])
|
||||||
self._timbre(data['timbre'])
|
self._timbre(data['timbre'])
|
||||||
self._cancelado(False)
|
self._cancelado(data['cancelada'])
|
||||||
#~ self._clean()
|
self._clean()
|
||||||
return
|
return
|
||||||
|
|
||||||
def pdf(self, path, data):
|
def pdf(self, path, data):
|
||||||
|
@ -609,9 +702,14 @@ class LIBO(object):
|
||||||
|
|
||||||
self._render(data)
|
self._render(data)
|
||||||
|
|
||||||
|
path = '{}.ods'.format(tempfile.mkstemp()[1])
|
||||||
|
self._template.storeToURL(self._path_url(path), ())
|
||||||
|
doc = self._doc_open(path, {'Hidden': True})
|
||||||
|
|
||||||
options = {'FilterName': 'calc_pdf_Export'}
|
options = {'FilterName': 'calc_pdf_Export'}
|
||||||
path = tempfile.mkstemp()[1]
|
path = tempfile.mkstemp()[1]
|
||||||
self._template.storeToURL(self._path_url(path), self._set_properties(options))
|
doc.storeToURL(self._path_url(path), self._set_properties(options))
|
||||||
|
doc.close(True)
|
||||||
self._template.close(True)
|
self._template.close(True)
|
||||||
|
|
||||||
return self._read(path)
|
return self._read(path)
|
||||||
|
@ -637,22 +735,23 @@ def get_dict(data):
|
||||||
def to_letters(value, moneda):
|
def to_letters(value, moneda):
|
||||||
monedas = {
|
monedas = {
|
||||||
'MXN': 'peso',
|
'MXN': 'peso',
|
||||||
|
'USD': 'dólar',
|
||||||
|
'EUR': 'euro',
|
||||||
}
|
}
|
||||||
return NumLet(value, monedas[moneda]).letras
|
return NumLet(value, monedas[moneda]).letras
|
||||||
|
|
||||||
|
|
||||||
def get_qr(data):
|
def get_qr(data):
|
||||||
scale = 10
|
|
||||||
path = tempfile.mkstemp()[1]
|
path = tempfile.mkstemp()[1]
|
||||||
code = QRCode(data, mode='binary')
|
qr = pyqrcode.create(data, mode='binary')
|
||||||
code.png(path, scale)
|
qr.png(path, scale=7)
|
||||||
return path
|
return path
|
||||||
|
|
||||||
|
|
||||||
def _comprobante(values):
|
def _comprobante(values, options):
|
||||||
data = CaseInsensitiveDict(values)
|
data = CaseInsensitiveDict(values)
|
||||||
del data['certificado']
|
del data['certificado']
|
||||||
#~ print (data)
|
|
||||||
data['totalenletras'] = to_letters(float(data['total']), data['moneda'])
|
data['totalenletras'] = to_letters(float(data['total']), data['moneda'])
|
||||||
if data['version'] == '3.3':
|
if data['version'] == '3.3':
|
||||||
tipos = {
|
tipos = {
|
||||||
|
@ -662,7 +761,116 @@ def _comprobante(values):
|
||||||
}
|
}
|
||||||
data['tipodecomprobante'] = tipos.get(data['tipodecomprobante'])
|
data['tipodecomprobante'] = tipos.get(data['tipodecomprobante'])
|
||||||
data['lugarexpedicion'] = 'C.P. Expedición: {}'.format(data['lugarexpedicion'])
|
data['lugarexpedicion'] = 'C.P. Expedición: {}'.format(data['lugarexpedicion'])
|
||||||
|
data['metododepago'] = options['metododepago']
|
||||||
|
data['formadepago'] = options['formadepago']
|
||||||
|
data['moneda'] = options['moneda']
|
||||||
|
|
||||||
|
data['tipocambio'] = 'Tipo de Cambio: $ {:0.2f}'.format(
|
||||||
|
float(data['tipocambio']))
|
||||||
|
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def _emisor(doc, version, values):
|
||||||
|
node = doc.find('{}Emisor'.format(PRE[version]))
|
||||||
|
data = CaseInsensitiveDict(node.attrib.copy())
|
||||||
|
node = node.find('{}DomicilioFiscal'.format(PRE[version]))
|
||||||
|
if not node is None:
|
||||||
|
data.update(node.attrib.copy())
|
||||||
|
data['regimenfiscal'] = values['regimenfiscal']
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def _receptor(doc, version, values):
|
||||||
|
node = doc.find('{}Receptor'.format(PRE[version]))
|
||||||
|
data = CaseInsensitiveDict(node.attrib.copy())
|
||||||
|
node = node.find('{}Domicilio'.format(PRE[version]))
|
||||||
|
if not node is None:
|
||||||
|
data.update(node.attrib.copy())
|
||||||
|
data['usocfdi'] = values['usocfdi']
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def _conceptos(doc, version):
|
||||||
|
data = []
|
||||||
|
conceptos = doc.find('{}Conceptos'.format(PRE[version]))
|
||||||
|
for c in conceptos.getchildren():
|
||||||
|
values = CaseInsensitiveDict(c.attrib.copy())
|
||||||
|
if version == '3.3':
|
||||||
|
values['noidentificacion'] = '{}\n(SAT {})'.format(
|
||||||
|
values['noidentificacion'], values['ClaveProdServ'])
|
||||||
|
values['unidad'] = '({}) {}'.format(
|
||||||
|
values['ClaveUnidad'], values['unidad'])
|
||||||
|
data.append(values)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def _totales(doc, cfdi, version):
|
||||||
|
data = {}
|
||||||
|
data['moneda'] = doc.attrib['Moneda']
|
||||||
|
data['subtotal'] = cfdi['subtotal']
|
||||||
|
if 'descuento' in cfdi:
|
||||||
|
data['descuento'] = cfdi['descuento']
|
||||||
|
data['total'] = cfdi['total']
|
||||||
|
|
||||||
|
tn = {
|
||||||
|
'001': 'ISR',
|
||||||
|
'002': 'IVA',
|
||||||
|
}
|
||||||
|
traslados = []
|
||||||
|
retenciones = []
|
||||||
|
taxlocales = []
|
||||||
|
|
||||||
|
imp = doc.find('{}Impuestos'.format(PRE[version]))
|
||||||
|
if imp is not None:
|
||||||
|
tmp = CaseInsensitiveDict(imp.attrib.copy())
|
||||||
|
for k, v in tmp.items():
|
||||||
|
data[k] = v
|
||||||
|
|
||||||
|
node = imp.find('{}Traslados'.format(PRE[version]))
|
||||||
|
if node is not None:
|
||||||
|
for n in node.getchildren():
|
||||||
|
tmp = CaseInsensitiveDict(n.attrib.copy())
|
||||||
|
if version == '3.3':
|
||||||
|
title = 'Traslado {} {}'.format(
|
||||||
|
tn.get(tmp['impuesto']), tmp['tasaocuota'])
|
||||||
|
else:
|
||||||
|
title = 'Traslado {} {}'.format(tmp['impuesto'], tmp['tasa'])
|
||||||
|
traslados.append((title, float(tmp['importe'])))
|
||||||
|
|
||||||
|
node = imp.find('{}Retenciones'.format(PRE[version]))
|
||||||
|
if node is not None:
|
||||||
|
for n in node.getchildren():
|
||||||
|
tmp = CaseInsensitiveDict(n.attrib.copy())
|
||||||
|
if version == '3.3':
|
||||||
|
title = 'Retención {} {}'.format(
|
||||||
|
tn.get(tmp['impuesto']), '')
|
||||||
|
else:
|
||||||
|
title = 'Retención {} {}'.format(tmp['impuesto'], '')
|
||||||
|
retenciones.append((title, float(tmp['importe'])))
|
||||||
|
|
||||||
|
#~ com = xml.find('%sComplemento' % PRE)
|
||||||
|
#~ if com is not None:
|
||||||
|
#~ otros = com.find('%sImpuestosLocales' % IMP_LOCAL)
|
||||||
|
#~ if otros is not None:
|
||||||
|
#~ for otro in list(otros):
|
||||||
|
#~ if otro.tag == '%sRetencionesLocales' % IMP_LOCAL:
|
||||||
|
#~ name = 'ImpLocRetenido'
|
||||||
|
#~ tasa = 'TasadeRetencion'
|
||||||
|
#~ else:
|
||||||
|
#~ name = 'ImpLocTrasladado'
|
||||||
|
#~ tasa = 'TasadeTraslado'
|
||||||
|
#~ title = '%s %s %%' % (otro.attrib[name], otro.attrib[tasa])
|
||||||
|
#~ value = otro.attrib['Importe']
|
||||||
|
#~ self._copy_cell(cell_title)
|
||||||
|
#~ self._copy_cell(cell_value)
|
||||||
|
#~ cell_title = self._set_cell(v=title, cell=cell_title)
|
||||||
|
#~ cell_value = self._set_cell(v=value, cell=cell_value, value=True)
|
||||||
|
#~ cell_value.CellStyle = currency
|
||||||
|
|
||||||
|
data['traslados'] = traslados
|
||||||
|
data['retenciones'] = retenciones
|
||||||
|
data['taxlocales'] = taxlocales
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
@ -679,23 +887,29 @@ def _timbre(doc, version, values):
|
||||||
values['rfc_receptor'],
|
values['rfc_receptor'],
|
||||||
total_s,
|
total_s,
|
||||||
node.attrib['UUID'])
|
node.attrib['UUID'])
|
||||||
#~ data['path_cbb'] = get_qr(qr_data)
|
data['path_cbb'] = get_qr(qr_data)
|
||||||
data['cadenaoriginal'] = CADENA.format(**node.attrib)
|
data['cadenaoriginal'] = CADENA.format(**node.attrib)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def get_data(invoice, rfc):
|
def get_data(invoice, rfc, values):
|
||||||
name = '{}_factura.ods'.format(rfc.lower())
|
name = '{}_factura.ods'.format(rfc.lower())
|
||||||
path = get_path_template(name)
|
path = get_path_template(name)
|
||||||
|
|
||||||
values = {}
|
|
||||||
data = {'cancelada': invoice.cancelada}
|
data = {'cancelada': invoice.cancelada}
|
||||||
doc = parse_xml(invoice.xml)
|
doc = parse_xml(invoice.xml)
|
||||||
data['comprobante'] = _comprobante(doc.attrib.copy())
|
data['comprobante'] = _comprobante(doc.attrib.copy(), values)
|
||||||
version = data['comprobante']['version']
|
version = data['comprobante']['version']
|
||||||
values['rfc_emisor'] = '123'
|
data['emisor'] = _emisor(doc, version, values)
|
||||||
values['rfc_receptor'] = '456'
|
data['receptor'] = _receptor(doc, version, values)
|
||||||
values['total'] = data['comprobante']['total']
|
data['conceptos'] = _conceptos(doc, version)
|
||||||
data['timbre'] = _timbre(doc, version, values)
|
data['totales'] = _totales(doc, data['comprobante'], version)
|
||||||
|
|
||||||
|
options = {
|
||||||
|
'rfc_emisor': data['emisor']['rfc'],
|
||||||
|
'rfc_receptor': data['receptor']['rfc'],
|
||||||
|
'total': data['comprobante']['total'],
|
||||||
|
}
|
||||||
|
data['timbre'] = _timbre(doc, version, options)
|
||||||
|
|
||||||
return path, data
|
return path, data
|
||||||
|
|
|
@ -110,6 +110,9 @@ class SATRegimenes(BaseModel):
|
||||||
(('key', 'name'), True),
|
(('key', 'name'), True),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '({}) {}'.format(self.key, self.name)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_(cls, ids):
|
def get_(cls, ids):
|
||||||
if isinstance(ids, int):
|
if isinstance(ids, int):
|
||||||
|
@ -458,6 +461,9 @@ class SATFormaPago(BaseModel):
|
||||||
(('key', 'name'), True),
|
(('key', 'name'), True),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return 'Forma de pago: ({}) {}'.format(self.key, self.name)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_activos(cls, values):
|
def get_activos(cls, values):
|
||||||
field = SATFormaPago.id
|
field = SATFormaPago.id
|
||||||
|
@ -496,6 +502,9 @@ class SATMonedas(BaseModel):
|
||||||
(('key', 'name'), True),
|
(('key', 'name'), True),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return 'Moneda: ({}) {}'.format(self.key, self.name)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_activos(cls):
|
def get_activos(cls):
|
||||||
rows = (SATMonedas
|
rows = (SATMonedas
|
||||||
|
@ -543,6 +552,9 @@ class SATUsoCfdi(BaseModel):
|
||||||
(('key', 'name'), True),
|
(('key', 'name'), True),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return 'Uso del CFDI: ({}) {}'.format(self.key, self.name)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_activos(cls, values):
|
def get_activos(cls, values):
|
||||||
field = SATUsoCfdi.id
|
field = SATUsoCfdi.id
|
||||||
|
@ -943,39 +955,6 @@ class Facturas(BaseModel):
|
||||||
def _get_data_cfdi_to_pdf(self, xml, cancel, version):
|
def _get_data_cfdi_to_pdf(self, xml, cancel, version):
|
||||||
pre_nomina = PRE['NOMINA'][version]
|
pre_nomina = PRE['NOMINA'][version]
|
||||||
|
|
||||||
data['comprobante']['letters'] = NumerosLetras().letters(
|
|
||||||
float(data['comprobante']['total'])).upper()
|
|
||||||
|
|
||||||
data['year'] = data['comprobante']['fecha'][0:4]
|
|
||||||
data['month'] = data['comprobante']['fecha'][5:7]
|
|
||||||
|
|
||||||
node = doc.find('{}Emisor'.format(pre))
|
|
||||||
data['emisor'] = node.attrib.copy()
|
|
||||||
rfc_emisor = data['emisor']['rfc']
|
|
||||||
node = node.find('{}DomicilioFiscal'.format(pre))
|
|
||||||
if not node is None:
|
|
||||||
data['emisor'].update(node.attrib.copy())
|
|
||||||
|
|
||||||
node = doc.find('{}Receptor'.format(pre))
|
|
||||||
data['receptor'] = node.attrib.copy()
|
|
||||||
rfc_receptor = data['receptor']['rfc']
|
|
||||||
node = node.find('{}Domicilio'.format(pre))
|
|
||||||
if not node is None:
|
|
||||||
data['receptor'].update(node.attrib.copy())
|
|
||||||
|
|
||||||
data['conceptos'] = []
|
|
||||||
conceptos = doc.find('{}Conceptos'.format(pre))
|
|
||||||
for c in conceptos.getchildren():
|
|
||||||
data['conceptos'].append(c.attrib.copy())
|
|
||||||
|
|
||||||
node = doc.find('{}Complemento/{}TimbreFiscalDigital'.format(pre, PRE['TIMBRE']))
|
|
||||||
data['timbre'] = node.attrib.copy()
|
|
||||||
total_s = '%017.06f' % float(doc.attrib['total'])
|
|
||||||
qr_data = '?re=%s&rr=%s&tt=%s&id=%s' % (
|
|
||||||
rfc_emisor, rfc_receptor, total_s, node.attrib['UUID'])
|
|
||||||
data['timbre']['path_cbb'] = get_qr(node.attrib['UUID'], qr_data)
|
|
||||||
data['timbre']['cadenaoriginal'] = CADENA.format(**node.attrib)
|
|
||||||
|
|
||||||
data['nomina'] = {}
|
data['nomina'] = {}
|
||||||
node = doc.find('{}Complemento/{}Nomina'.format(pre, pre_nomina))
|
node = doc.find('{}Complemento/{}Nomina'.format(pre, pre_nomina))
|
||||||
if not node is None:
|
if not node is None:
|
||||||
|
@ -1026,6 +1005,29 @@ class Facturas(BaseModel):
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def _get_not_in_xml(self, invoice):
|
||||||
|
values = {}
|
||||||
|
obj = SATRegimenes.get(SATRegimenes.key==invoice.regimen_fiscal)
|
||||||
|
values['regimenfiscal'] = str(obj)
|
||||||
|
|
||||||
|
obj = SATUsoCfdi.get(SATUsoCfdi.key==invoice.uso_cfdi)
|
||||||
|
values['usocfdi'] = str(obj)
|
||||||
|
|
||||||
|
mp = {
|
||||||
|
'PUE': 'Pago en una sola exhibición',
|
||||||
|
'PPD': 'Pago en parcialidades o diferido',
|
||||||
|
}
|
||||||
|
values['metododepago'] = 'Método de Pago: ({}) {}'.format(
|
||||||
|
invoice.metodo_pago, mp[invoice.metodo_pago])
|
||||||
|
|
||||||
|
obj = SATFormaPago.get(SATFormaPago.key==invoice.forma_pago)
|
||||||
|
values['formadepago'] = str(obj)
|
||||||
|
|
||||||
|
obj = SATMonedas.get(SATMonedas.key==invoice.moneda)
|
||||||
|
values['moneda'] = str(obj)
|
||||||
|
|
||||||
|
return values
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_pdf(cls, id, rfc):
|
def get_pdf(cls, id, rfc):
|
||||||
obj = Facturas.get(Facturas.id==id)
|
obj = Facturas.get(Facturas.id==id)
|
||||||
|
@ -1033,7 +1035,8 @@ class Facturas(BaseModel):
|
||||||
if obj.uuid is None:
|
if obj.uuid is None:
|
||||||
return b'', name
|
return b'', name
|
||||||
|
|
||||||
path, data = util.get_data(obj, rfc)
|
values = cls._get_not_in_xml(cls, obj)
|
||||||
|
path, data = util.get_data(obj, rfc, values)
|
||||||
doc = util.to_pdf(path, data)
|
doc = util.to_pdf(path, data)
|
||||||
return doc, name
|
return doc, name
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue