From 1aa6540ac1ecb380d242c161e156e20ee997e460 Mon Sep 17 00:00:00 2001 From: Mauricio Baeza Date: Tue, 29 Jun 2021 19:07:55 -0500 Subject: [PATCH] Change pyqrcode for segno --- requirements.txt | 5 ++-- source/app/controllers/helper.py | 3 +- source/app/controllers/util.py | 49 +++++++++++++++++++------------- source/app/controllers/utils.py | 8 ++++++ source/app/models/main.py | 3 +- 5 files changed, 45 insertions(+), 23 deletions(-) diff --git a/requirements.txt b/requirements.txt index d65df38..33aa2ec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,13 +8,14 @@ bcrypt python-dateutil zeep chardet -pyqrcode -pypng reportlab psycopg2-binary cryptography xmlsec +segno +# pyqrcode +# pypng # python-escpos # pyusb # pyserial diff --git a/source/app/controllers/helper.py b/source/app/controllers/helper.py index 6c11337..433d000 100644 --- a/source/app/controllers/helper.py +++ b/source/app/controllers/helper.py @@ -1,5 +1,6 @@ #!/usr/bin/env python3 +import io import os import re import smtplib @@ -597,7 +598,7 @@ class TemplateInvoice(BaseDocTemplate): p = Paragraph(v, ps) ls.append(p) - cbb = Image(data['path_cbb']) + cbb = Image(data['cbb']) cbb.drawHeight = 4 * cm cbb.drawWidth = 4 * cm diff --git a/source/app/controllers/util.py b/source/app/controllers/util.py index 2084c9b..e75f510 100644 --- a/source/app/controllers/util.py +++ b/source/app/controllers/util.py @@ -54,7 +54,7 @@ try: except ImportError: APP_LIBO = False -import pyqrcode +# ~ import pyqrcode from dateutil import parser from lxml import etree @@ -73,6 +73,7 @@ from settings import USAR_TOKEN, API, DECIMALES_TAX # ~ v2 +import segno from .pacs.cfdi_cert import SATCertificate from settings import ( @@ -844,21 +845,28 @@ class LIBO(object): if self._es_pre or self._is_ticket: return + qr = data.pop('cbb') for k, v in data.items(): self._set_cell('{timbre.%s}' % k, v) pd = self._sheet.getDrawPage() image = self._template.createInstance('com.sun.star.drawing.GraphicObjectShape') gp = self._create_instance('com.sun.star.graphic.GraphicProvider') - # ~ image.GraphicURL = data['path_cbb'] pd.add(image) - properties = self._set_properties({'URL': self._path_url(data['path_cbb'])}) + # ~ image.GraphicURL = data['path_cbb'] + # ~ properties = self._set_properties({'URL': self._path_url(data['path_cbb'])}) + + 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 = 4150 s.Height = 4500 image.setSize(s) image.Anchor = self._set_cell('{timbre.cbb}') - _kill(data['path_cbb']) + # ~ _kill(data['path_cbb']) return def _donataria(self, data): @@ -1490,19 +1498,13 @@ def to_pdf_from_json(rfc, version, data): if exists(path_logo): data['emisor']['logo2'] = path_logo - path_cbb = data['timbre']['path_cbb'] - path = get_path_temp() - - pdf = TemplateInvoice(path) + buffer = io.BytesIO() + pdf = TemplateInvoice(buffer) pdf.custom_styles = custom_styles pdf.data = data pdf.render() - data = read_file(path) - _kill(path) - _kill(path_cbb) - - return data + return buffer.getvalue() def format_currency(value, currency, digits=2): @@ -1616,6 +1618,12 @@ def get_qr(data, p=True): 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: @@ -1851,7 +1859,7 @@ def _totales(doc, cfdi, version): return data -def _timbre(doc, version, values): +def _timbre(doc, version, values, pdf_from='1'): CADENA = '||{version}|{UUID}|{FechaTimbrado}|{selloCFD}|{noCertificadoSAT}||' if version == '3.3': CADENA = '||{Version}|{UUID}|{FechaTimbrado}|{SelloCFD}|{NoCertificadoSAT}||' @@ -1869,7 +1877,11 @@ def _timbre(doc, version, values): } qr_data = '{url}{uuid}{emisor}{receptor}{total}{sello}'.format(**qr_data) - data['path_cbb'] = get_qr(qr_data) + if pdf_from == '1': + data['cbb'] = get_qr2(qr_data) + else: + data['cbb'] = get_qr2(qr_data, 'png') + data['cadenaoriginal'] = CADENA.format(**data) return data @@ -1998,7 +2010,7 @@ def _cfdipays(doc, data, version): return info -def get_data_from_xml(invoice, values): +def get_data_from_xml(invoice, values, pdf_from='1'): data = {'cancelada': invoice.cancelada, 'donativo': False} if hasattr(invoice, 'donativo'): data['donativo'] = invoice.donativo @@ -2017,7 +2029,7 @@ def get_data_from_xml(invoice, values): 'rfc_receptor': data['receptor']['rfc'], 'total': data['comprobante']['total'], } - data['timbre'] = _timbre(doc, version, options) + data['timbre'] = _timbre(doc, version, options, pdf_from) del data['timbre']['version'] data['comprobante'].update(data['timbre']) @@ -2026,9 +2038,8 @@ def get_data_from_xml(invoice, values): if data['pagos']: data['pays'] = _cfdipays(doc, data, version) data['pakings'] = values.get('pakings', []) - # ~ data['version'] = values['version'] - # ~ data['version'] = version data['el.version'] = values['el.version'] + return data diff --git a/source/app/controllers/utils.py b/source/app/controllers/utils.py index 0341169..cda350a 100644 --- a/source/app/controllers/utils.py +++ b/source/app/controllers/utils.py @@ -21,6 +21,7 @@ import collections import csv import datetime import getpass +import io import json import logging import math @@ -60,6 +61,7 @@ from .pacs import PACComercioDigital from .pacs import PACFinkok # ~ v2 +import segno from .pycfdi import CfdiRead @@ -826,3 +828,9 @@ def upload_file(rfc, opt, file_obj): if opt == 'productsadd': result = _products_from_xml(rfc, file_obj.file.read()) return result + + +def get_qr(data): + buffer = io.BytesIO() + segno.make(data).save(buffer, kind='svg', scale=8, border=2) + return buffer.getvalue() diff --git a/source/app/models/main.py b/source/app/models/main.py index 13906ff..32054f2 100644 --- a/source/app/models/main.py +++ b/source/app/models/main.py @@ -4222,7 +4222,7 @@ class Facturas(BaseModel): values = cls._get_not_in_xml(cls, obj, emisor) #Tmp to v2 - data = util.get_data_from_xml(obj, values) + data = util.get_data_from_xml(obj, values, pdf_from) data.update(utils.CfdiToDict(obj.xml).values) doc = util.to_pdf(data, emisor.rfc, pdf_from=pdf_from) @@ -4343,6 +4343,7 @@ class Facturas(BaseModel): ) cbb = util.get_qr(qr_data, False) data['cbb'] = f'data:image/png;base64,{cbb}' + # ~ data['cbb'] = utils.get_qr(qr_data) return data