PDF from Carta Porte v3
This commit is contained in:
parent
7f129b84b2
commit
29bfb42abc
|
@ -30,6 +30,7 @@ import requests
|
|||
import sqlite3
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import textwrap
|
||||
import threading
|
||||
|
@ -44,7 +45,6 @@ from pathlib import Path
|
|||
from xml.etree import ElementTree as ET
|
||||
from xml.dom.minidom import parseString
|
||||
|
||||
|
||||
try:
|
||||
import uno
|
||||
from com.sun.star.beans import PropertyValue
|
||||
|
@ -52,9 +52,20 @@ try:
|
|||
from com.sun.star.view.PaperFormat import LETTER
|
||||
APP_LIBO = True
|
||||
except ImportError:
|
||||
APP_LIBO = False
|
||||
path_fun = '/usr/lib/libreoffice/program/fundamentalrc'
|
||||
path_uno = '/usr/lib/libreoffice/program/'
|
||||
os.environ['URE_BOOTSTRAP'] = f'vnd.sun.star.pathname:{path_fun}'
|
||||
os.environ['UNO_PATH'] = path_uno
|
||||
sys.path.append(path_uno)
|
||||
try:
|
||||
import uno
|
||||
from com.sun.star.beans import PropertyValue
|
||||
from com.sun.star.awt import Size
|
||||
from com.sun.star.view.PaperFormat import LETTER
|
||||
APP_LIBO = True
|
||||
except ImportError:
|
||||
APP_LIBO = False
|
||||
|
||||
# ~ import pyqrcode
|
||||
from dateutil import parser
|
||||
from lxml import etree
|
||||
|
||||
|
@ -69,7 +80,6 @@ from settings import DEBUG, MV, log, template_lookup, COMPANIES, DB_SAT, \
|
|||
PATH_XMLSEC, TEMPLATE_CANCEL, DEFAULT_SAT_PRODUCTO, DECIMALES, DIR_FACTURAS
|
||||
|
||||
from settings import USAR_TOKEN, API, DECIMALES_TAX
|
||||
# ~ from .configpac import AUTH
|
||||
|
||||
|
||||
from .utils import get_qr
|
||||
|
@ -951,6 +961,7 @@ class LIBO(object):
|
|||
return
|
||||
|
||||
# ~ print(data)
|
||||
qr = data.pop('qr', False)
|
||||
figuras = data.pop('figuras')
|
||||
mercancias = data.pop('mercancias')
|
||||
detalle = mercancias.pop('detalle')
|
||||
|
@ -1019,7 +1030,27 @@ class LIBO(object):
|
|||
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=peso, cell=cell_5)
|
||||
if qr:
|
||||
self._timbre_carta(qr)
|
||||
return
|
||||
|
||||
def _timbre_carta(self, qr):
|
||||
pd = self._sheet.getDrawPage()
|
||||
image = self._template.createInstance('com.sun.star.drawing.GraphicObjectShape')
|
||||
gp = self._create_instance('com.sun.star.graphic.GraphicProvider')
|
||||
pd.add(image)
|
||||
|
||||
instance = 'com.sun.star.io.SequenceInputStream'
|
||||
stream = self._create_instance(instance)
|
||||
stream.initialize((uno.ByteSequence(qr.getvalue()),))
|
||||
properties = self._set_properties({'InputStream': stream})
|
||||
image.Graphic = gp.queryGraphic(properties)
|
||||
|
||||
s = Size()
|
||||
s.Width = 4000
|
||||
s.Height = 4000
|
||||
image.setSize(s)
|
||||
image.Anchor = self._set_cell('{cp.qr}')
|
||||
return
|
||||
|
||||
def _comercio_exterior(self, data):
|
||||
|
@ -1690,7 +1721,7 @@ def to_pdf(data, emisor_rfc, ods=False, pdf_from='1'):
|
|||
version = f'{version}_cn_{version_nomina}'
|
||||
|
||||
if 'carta_porte' in data:
|
||||
default = 'plantilla_factura_ccp.ods'
|
||||
default = 'plantilla_ccp.ods'
|
||||
version = '{}_ccp_{}'.format(version, data['carta_porte']['version'])
|
||||
|
||||
if data.get('pagos', False):
|
||||
|
@ -1844,24 +1875,6 @@ def to_letters(value, currency):
|
|||
return NumLet(value, currency).letras
|
||||
|
||||
|
||||
# ~ def get_qr(data, p=True):
|
||||
# ~ qr = pyqrcode.create(data, mode='binary')
|
||||
# ~ if p:
|
||||
# ~ path = get_path_temp('.qr')
|
||||
# ~ qr.png(path, scale=7)
|
||||
# ~ return path
|
||||
|
||||
# ~ buffer = io.BytesIO()
|
||||
# ~ qr.png(buffer, scale=8)
|
||||
# ~ return base64.b64encode(buffer.getvalue()).decode()
|
||||
|
||||
|
||||
# ~ def get_qr2(data, kind='svg'):
|
||||
# ~ buffer = io.BytesIO()
|
||||
# ~ segno.make(data).save(buffer, kind=kind, scale=8, border=2)
|
||||
# ~ return buffer
|
||||
|
||||
|
||||
def _get_relacionados(doc, version):
|
||||
node = doc.find('{}CfdiRelacionados'.format(PRE[version]))
|
||||
if node is None:
|
||||
|
@ -3146,7 +3159,8 @@ def parse_xml2(xml_str):
|
|||
|
||||
|
||||
def get_idccp():
|
||||
uuid_v4 = uuid.uuid4()
|
||||
custom_uuid_str = f"CCC{uuid_v4.hex[3:8].upper()}-{uuid_v4.hex[8:12].upper()}-{uuid_v4.hex[12:16].upper()}-{uuid_v4.hex[16:20].upper()}-{uuid_v4.hex[20:32].upper()}"
|
||||
uuid4 = str(uuid.uuid4()).upper()
|
||||
custom_uuid_str = f'CCC{uuid4[3:]}'
|
||||
# ~ custom_uuid_str = f"CCC{uuid_v4.hex[3:8].upper()}-{uuid_v4.hex[8:12].upper()}-{uuid_v4.hex[12:16].upper()}-{uuid_v4.hex[16:20].upper()}-{uuid_v4.hex[20:32].upper()}"
|
||||
return custom_uuid_str
|
||||
|
||||
|
|
|
@ -261,9 +261,11 @@ class CfdiToDict(object):
|
|||
'cfdi4.0': 'http://www.sat.gob.mx/cfd/4',
|
||||
}
|
||||
NS = {
|
||||
'tfd': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
||||
'divisas': 'http://www.sat.gob.mx/divisas',
|
||||
'leyendasFisc': 'http://www.sat.gob.mx/leyendasFiscales',
|
||||
'cartaporte20': 'http://www.sat.gob.mx/CartaPorte20',
|
||||
'cartaporte30': 'http://www.sat.gob.mx/CartaPorte30',
|
||||
'nomina12': 'http://www.sat.gob.mx/nomina12',
|
||||
'cce20': 'http://www.sat.gob.mx/ComercioExterior20',
|
||||
}
|
||||
|
@ -397,11 +399,23 @@ class CfdiToDict(object):
|
|||
self.version = self._root.attrib['Version']
|
||||
ns = f'cfdi{self.version}'
|
||||
self.NS['cfdi'] = self.NS_VERSION[ns]
|
||||
self._timbre_fiscal()
|
||||
self._informacion_global()
|
||||
self._receptor()
|
||||
self._complementos()
|
||||
return
|
||||
|
||||
def _timbre_fiscal(self):
|
||||
path = '//tfd:TimbreFiscalDigital'
|
||||
data = self._root.xpath(path, namespaces=self.NS)
|
||||
if not data:
|
||||
return
|
||||
|
||||
data = data[0]
|
||||
attr = CaseInsensitiveDict(data.attrib)
|
||||
self._fecha_timbrado = attr['FechaTimbrado']
|
||||
return
|
||||
|
||||
def _informacion_global(self):
|
||||
self._values['informacion_global'] = {}
|
||||
|
||||
|
@ -514,10 +528,75 @@ class CfdiToDict(object):
|
|||
|
||||
self._values['carta_porte'] = values
|
||||
|
||||
self._complemento_carta_porte(complemento)
|
||||
self._complemento_comercio_exterior(complemento)
|
||||
|
||||
return
|
||||
|
||||
def _complemento_carta_porte(self, complemento):
|
||||
path = '//cartaporte30:CartaPorte'
|
||||
carta_porte = complemento.xpath(path, namespaces=self.NS)
|
||||
if carta_porte:
|
||||
self._get_carta_porte_3(carta_porte)
|
||||
return
|
||||
|
||||
def _get_carta_porte_3(self, carta_porte):
|
||||
URL = 'https://verificacfdi.facturaelectronica.sat.gob.mx/verificaccp/default.aspx'
|
||||
PRE = '//cartaporte30'
|
||||
values = CaseInsensitiveDict(carta_porte[0].attrib)
|
||||
idccp = values['idccp']
|
||||
for node in carta_porte[0]:
|
||||
if 'FiguraTransporte' in node.tag:
|
||||
figuras = CaseInsensitiveDict(node[0].attrib)
|
||||
figuras['TipoFigura'] = self.tipo_figura[figuras['TipoFigura']]
|
||||
values['figuras'] = figuras
|
||||
elif 'Mercancias' in node.tag:
|
||||
mercancias = CaseInsensitiveDict(node.attrib)
|
||||
detalle = [CaseInsensitiveDict(n.attrib)
|
||||
for n in node if 'Mercancia' in n.tag]
|
||||
values['mercancias'] = {
|
||||
'mercancias': mercancias,
|
||||
'detalle': detalle,
|
||||
}
|
||||
|
||||
path = f'{PRE}:Autotransporte'
|
||||
node_auto = node.xpath(path, namespaces=self.NS)[0]
|
||||
values_auto = CaseInsensitiveDict(node_auto.attrib)
|
||||
values['autotransporte'] = values_auto
|
||||
|
||||
path = f'{PRE}:IdentificacionVehicular'
|
||||
node_tmp = node_auto.xpath(path, namespaces=self.NS)[0]
|
||||
values_auto = CaseInsensitiveDict(node_tmp.attrib)
|
||||
values['autotransporte'].update(values_auto)
|
||||
|
||||
path = f'{PRE}:Seguros'
|
||||
node_tmp = node_auto.xpath(path, namespaces=self.NS)[0]
|
||||
values_auto = CaseInsensitiveDict(node_tmp.attrib)
|
||||
values['autotransporte'].update(values_auto)
|
||||
|
||||
path = f'{PRE}:Remolques'
|
||||
try:
|
||||
node_tmp = node_auto.xpath(path, namespaces=self.NS)[0][0]
|
||||
values_auto = CaseInsensitiveDict(node_tmp.attrib)
|
||||
values['autotransporte'].update(values_auto)
|
||||
except IndexError:
|
||||
pass
|
||||
elif 'Ubicaciones' in node.tag:
|
||||
ubicaciones = []
|
||||
for n in node:
|
||||
ubicacion = CaseInsensitiveDict(n.attrib)
|
||||
if ubicacion['TipoUbicacion'] == 'Origen':
|
||||
fecha_origen = ubicacion['FechaHoraSalidaLlegada']
|
||||
ubicacion['domicilio'] = self._set_carta_porte_domicilio(
|
||||
CaseInsensitiveDict(n[0].attrib))
|
||||
ubicaciones.append(ubicacion)
|
||||
values['FechaOrigen'] = fecha_origen
|
||||
values['ubicaciones'] = ubicaciones
|
||||
qr_data = f'{URL}?IdCCP={idccp}&FechaOrig={fecha_origen}&FechaTimb={self._fecha_timbrado}'
|
||||
values['qr'] = get_qr(qr_data, 'png')
|
||||
self._values['carta_porte'] = values
|
||||
return
|
||||
|
||||
def _complemento_comercio_exterior(self, complemento):
|
||||
path = '//cce20:ComercioExterior'
|
||||
comercio_exterior = complemento.xpath(path, namespaces=self.NS)
|
||||
|
|
|
@ -4823,16 +4823,6 @@ class Facturas(BaseModel):
|
|||
obj = SATTipoRelacion.get(SATTipoRelacion.key==invoice.tipo_relacion)
|
||||
values['tiporelacion'] = str(obj)
|
||||
|
||||
# ~ use_packing = Configuracion.get_bool('chk_use_packing')
|
||||
# ~ if use_packing:
|
||||
# ~ w = FacturasDetalle.factura == invoice
|
||||
# ~ q = (FacturasDetalle
|
||||
# ~ .select(FacturasDetalle.empaques)
|
||||
# ~ .where(w)
|
||||
# ~ .order_by(FacturasDetalle.id.asc())
|
||||
# ~ .tuples())
|
||||
# ~ values['pakings'] = [str(int(r[0])) for r in q]
|
||||
|
||||
return values
|
||||
|
||||
def _get_not_in_xml2(self, invoice, data):
|
||||
|
|
|
@ -882,68 +882,9 @@ function guardar_y_timbrar(values){
|
|||
|
||||
var usar_cartaporte = $$('chk_cfdi_usar_cartaporte').getValue()
|
||||
if(usar_cartaporte){
|
||||
//~ var total_distance = 0.00
|
||||
//~ var total_weight = 0.00
|
||||
//~ var cartaporte = {
|
||||
//~ TranspInternac: $$('lst_carta_TranspInternac').getValue(),
|
||||
//~ TotalDistRec: total_distance,
|
||||
//~ }
|
||||
//~ var ubicaciones = $$('grid_carta_ubicaciones').data.getRange()
|
||||
//~ ubicaciones.forEach(function(row, index){
|
||||
//~ delete row['id']
|
||||
//~ delete row['delete']
|
||||
//~ if(row['DistanciaRecorrida']){
|
||||
//~ total_distance += parseFloat(row['DistanciaRecorrida'])
|
||||
//~ }
|
||||
//~ })
|
||||
//~ cartaporte['TotalDistRec'] = total_distance
|
||||
//~ cartaporte['ubicaciones'] = ubicaciones
|
||||
|
||||
//~ var row = $$('grid_carta_autotransporte').data.getRange()[0]
|
||||
//~ var autotransporte = {
|
||||
//~ PermSCT: row['PermSCT'],
|
||||
//~ NumPermisoSCT: row['NumPermisoSCT'],
|
||||
//~ identificacion: {
|
||||
//~ ConfigVehicular: row['ConfigVehicular'],
|
||||
//~ PlacaVM: row['PlacaVM'],
|
||||
//~ AnioModeloVM: row['AnioModeloVM'],
|
||||
//~ },
|
||||
//~ seguros: {
|
||||
//~ AseguraRespCivil: row['AseguraRespCivil'],
|
||||
//~ PolizaRespCivil: row['PolizaRespCivil'],
|
||||
//~ },
|
||||
//~ remolque: {
|
||||
//~ SubTipoRem: row['SubTipoRem'],
|
||||
//~ Placa: row['Placa'],
|
||||
//~ }
|
||||
//~ }
|
||||
|
||||
//~ var mercancias = $$('grid_carta_mercancias').data.getRange()
|
||||
//~ mercancias.forEach(function(row, index){
|
||||
//~ delete row['id']
|
||||
//~ delete row['delete']
|
||||
//~ row['Cantidad'] = String(row['Cantidad'])
|
||||
//~ row['ValorMercancia'] = String(row['ValorMercancia'])
|
||||
//~ if(row['PesoEnKg']){
|
||||
//~ total_weight += parseFloat(row['PesoEnKg'])
|
||||
//~ }
|
||||
//~ })
|
||||
//~ var mercancias = {
|
||||
//~ 'PesoBrutoTotal': 0.00,
|
||||
//~ 'UnidadPeso': $$('lst_carta_UnidadPeso').getValue(),
|
||||
//~ 'NumTotalMercancias': String(mercancias.length),
|
||||
//~ mercancias: mercancias,
|
||||
//~ autotransporte: autotransporte,
|
||||
//~ }
|
||||
//~ cartaporte['mercancias'] = mercancias
|
||||
|
||||
//~ var tiposfigura = $$('grid_carta_tipos_figuras').data.getRange()
|
||||
//~ tiposfigura.forEach(function(row, index){
|
||||
//~ delete row['id']
|
||||
//~ })
|
||||
//~ cartaporte['tiposfigura'] = tiposfigura
|
||||
var result = _get_values_carta_porte()
|
||||
data['cartaporte'] = result.values
|
||||
$$('chk_cfdi_usar_cartaporte').setValue(false)
|
||||
}
|
||||
|
||||
var usar_comercioe = $$('chk_cfdi_usar_comercioe').getValue()
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue