From 8877de2cef7041ff12a71b9a576fb4aaa3c996c0 Mon Sep 17 00:00:00 2001 From: dusker Date: Thu, 16 Apr 2026 06:48:46 +0000 Subject: [PATCH] Add EPC QR code to make bank transactions easier (#61) See https://de.wikipedia.org/wiki/EPC-QR-Code#EPC-QR-Code_f%C3%BCr_%C3%9Cberweisung_erstellen for more information about the EPC coding Co-authored-by: dusker Reviewed-on: https://git.ezgg-ev.de/Vereins-IT/ezgg-lan-manager/pulls/61 Co-authored-by: dusker Co-committed-by: dusker --- requirements.txt | Bin 218 -> 122 bytes src/ezgg_lan_manager/pages/Account.py | 14 +++++++-- .../services/AccountingService.py | 28 ++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index d2dea2e3f934aebec47d8fe918599e0abf17e341..3032219675c7eadb333898927cec661218200a84 100644 GIT binary patch literal 122 zcmW-ZK?=h#3000v9tOtsaYG5bQXP51OVSl*qU H@BsV*c!no9 literal 218 zcmYL@K?=e^3`O5s@FK_-%#)dk#7ji2?*32YAS&+4o_DuV-_xD!HYAQbR3+6H None: self.banking_info_revealer_open = not self.banking_info_revealer_open @@ -36,7 +42,7 @@ class AccountPage(Component): self.paypal_info_revealer_open = not self.paypal_info_revealer_open def build(self) -> Component: - if not self.user and not self.balance: + if not self.user or not self.payment_qr_image: return Column( MainViewContentBox( ProgressCircle( @@ -85,6 +91,10 @@ class AccountPage(Component): margin=0, margin_bottom=1, align_x=0.5 + ), + Image(self.payment_qr_image, + min_width=20, + min_height=20 ) ), margin=2, diff --git a/src/ezgg_lan_manager/services/AccountingService.py b/src/ezgg_lan_manager/services/AccountingService.py index 07bc0a9..cf40ee3 100644 --- a/src/ezgg_lan_manager/services/AccountingService.py +++ b/src/ezgg_lan_manager/services/AccountingService.py @@ -1,4 +1,6 @@ +import io import logging +import qrcode from collections.abc import Callable from datetime import datetime from decimal import Decimal, ROUND_DOWN @@ -74,3 +76,29 @@ class AccountingService: return "0.00 €" rounded_decimal = str(euros.quantize(Decimal(".01"), rounding=ROUND_DOWN)) return f"{rounded_decimal} €" + + @staticmethod + def make_payment_qr_image(beneficiary_name, beneficiary_bic, beneficiary_iban, text, amount_euros=None) -> bytes: + text = text.replace("\n",";") + amount_formatted = "EUR{:.2f}".format(amount_euros) if amount_euros else "" + epc_text = f"""BCD +002 +1 +SCT +{beneficiary_bic} +{beneficiary_name} +{beneficiary_iban} +{amount_formatted} + + +{text} +""" + qr = qrcode.QRCode( + version=6, + error_correction=qrcode.constants.ERROR_CORRECT_M, + ) + qr.add_data(epc_text) + img = qr.make_image() + img_bytes = io.BytesIO() + img.save(img_bytes) + return img_bytes.getvalue()