From 2d1e083247c2d48e2ab908a28b21a24f8ad40617 Mon Sep 17 00:00:00 2001 From: James Addison Date: Mon, 18 Dec 2023 15:26:08 +0000 Subject: [PATCH 1/2] payments: relocate shared EPC QR generation code --- apps/common/epc.py | 37 ++++++++++++++++++++++++++ apps/payments/invoice.py | 37 +------------------------- tests/{test_invoice.py => test_epc.py} | 2 +- 3 files changed, 39 insertions(+), 37 deletions(-) create mode 100644 apps/common/epc.py rename tests/{test_invoice.py => test_epc.py} (92%) diff --git a/apps/common/epc.py b/apps/common/epc.py new file mode 100644 index 000000000..81f642196 --- /dev/null +++ b/apps/common/epc.py @@ -0,0 +1,37 @@ +from io import BytesIO + +from markupsafe import Markup +from segno import helpers + + +def make_epc_qrfile(payment, **kwargs): + qrfile = BytesIO() + # TODO: this isn't currently used. Need to fetch IBAN from payment.recommended_destination + # and name from somewhere - maybe config rather than hard-coding. + qr = helpers.make_epc_qr( + name="EMF Festivals Ltd", + iban=payment.recommended_destination.iban, + amount=payment.amount, + reference=payment.bankref, + encoding=1, + ) + qr.save(qrfile, **kwargs) + qrfile.seek(0) + return qrfile + + +def qrfile_to_svg(qrfile): + return Markup(qrfile.getvalue().decode("utf-8")) + + +def format_inline_epc_qr(payment): + qrfile = make_epc_qrfile( + payment, + kind="svg", + svgclass=None, + omitsize=True, + xmldecl=False, + svgns=False, + nl=False, + ) + return qrfile_to_svg(qrfile) diff --git a/apps/payments/invoice.py b/apps/payments/invoice.py index db941c4c5..f2088388f 100644 --- a/apps/payments/invoice.py +++ b/apps/payments/invoice.py @@ -1,5 +1,4 @@ from decimal import Decimal -from io import BytesIO import logging import shutil import os.path @@ -15,8 +14,6 @@ send_file, ) from flask_login import login_required, current_user -from markupsafe import Markup -from segno import helpers from sqlalchemy.sql.functions import func from wtforms import TextAreaField, SubmitField @@ -24,6 +21,7 @@ from ..common.receipt import render_pdf from models.product import Product, PriceTier from models.purchase import Purchase +from ..common.epc import format_inline_epc_qr from ..common.forms import Form from . import get_user_payment_or_abort from . import payments @@ -31,39 +29,6 @@ logger = logging.getLogger(__name__) -def make_epc_qrfile(payment, **kwargs): - qrfile = BytesIO() - # TODO: this isn't currently used. Need to fetch IBAN from payment.recommended_destination - # and name from somewhere - maybe config rather than hard-coding. - qr = helpers.make_epc_qr( - name="EMF Festivals Ltd", - iban=payment.recommended_destination.iban, - amount=payment.amount, - reference=payment.bankref, - encoding=1, - ) - qr.save(qrfile, **kwargs) - qrfile.seek(0) - return qrfile - - -def qrfile_to_svg(qrfile): - return Markup(qrfile.getvalue().decode("utf-8")) - - -def format_inline_epc_qr(payment): - qrfile = make_epc_qrfile( - payment, - kind="svg", - svgclass=None, - omitsize=True, - xmldecl=False, - svgns=False, - nl=False, - ) - return qrfile_to_svg(qrfile) - - class InvoiceForm(Form): company = TextAreaField("Company name") update = SubmitField("Update") diff --git a/tests/test_invoice.py b/tests/test_epc.py similarity index 92% rename from tests/test_invoice.py rename to tests/test_epc.py index 831eacca0..bbaf8a345 100644 --- a/tests/test_invoice.py +++ b/tests/test_epc.py @@ -1,6 +1,6 @@ from pyzbar.pyzbar import decode -from apps.payments.invoice import format_inline_epc_qr +from apps.common.epc import format_inline_epc_qr from models.payment import BankPayment from tests._utils import render_svg From 3d0abb52b3bbab5fe979439c671e0032c86cd13b Mon Sep 17 00:00:00 2001 From: James Addison Date: Mon, 18 Dec 2023 15:31:10 +0000 Subject: [PATCH 2/2] payments: add type-hinting to EPC QR code --- apps/common/epc.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/apps/common/epc.py b/apps/common/epc.py index 81f642196..7866776dd 100644 --- a/apps/common/epc.py +++ b/apps/common/epc.py @@ -1,14 +1,16 @@ from io import BytesIO from markupsafe import Markup -from segno import helpers +from segno import QRCode, helpers +from models.payment import BankPayment -def make_epc_qrfile(payment, **kwargs): + +def make_epc_qrfile(payment: BankPayment, **kwargs) -> BytesIO: qrfile = BytesIO() # TODO: this isn't currently used. Need to fetch IBAN from payment.recommended_destination # and name from somewhere - maybe config rather than hard-coding. - qr = helpers.make_epc_qr( + qr: QRCode = helpers.make_epc_qr( name="EMF Festivals Ltd", iban=payment.recommended_destination.iban, amount=payment.amount, @@ -20,11 +22,11 @@ def make_epc_qrfile(payment, **kwargs): return qrfile -def qrfile_to_svg(qrfile): +def qrfile_to_svg(qrfile: BytesIO) -> str: return Markup(qrfile.getvalue().decode("utf-8")) -def format_inline_epc_qr(payment): +def format_inline_epc_qr(payment: BankPayment) -> str: qrfile = make_epc_qrfile( payment, kind="svg",