Initial import from ash-technology/l10n_cz_extra

Czech QR Payment (SPAYD) module for Odoo 19
- Generates Czech standard QR codes for invoices
- Compatible with all major Czech banking apps

Cloned from: https://github.com/ash-technology/l10n_cz_extra

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
Tomas
2026-08-25 00:46:20 +02:00
commit 3049aba8c3
16 changed files with 356 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
🇬🇧 [English version](README.md)
# QR platby v českém prostředí
Modul přidává na faktury QR kód pro rychlou platbu mobilem. Kódy jsou ve formátu SPAYD
* **Způsob zadání bankovního účtu** Česká bankovní účty zadávejte do standardního pole Odoo v českém formátu, např. `123-456/0800`
![Zadání bankovního účtu](static/description/bank_account.png)
* **Zahraniční účty:** Pokud se jedná o zahraniční účty, do stejného pole (standardní pole v Odoo) můžete zadat IBAN.
* **Podpora měny:** Český QR kód se generuje pro faktury v měně CZK. Pro zahraniční platby je ponechán původní QR kód Odoo.
#### Často kladené dotazy (FAQ)
**QR kód se na faktuře negeneruje**
Ujistěte se, že v konfiguraci aplikace **Fakturace** máte zaškrtnutou volbu **QR kódy**
![Nastavení QR kódů](static/description/qr_payment_settings.png)
**QR kód se na faktuře vygeneruje, ale jeho načtení hlásí chybu**
Zkontrolujte, zda máte na hlavní společnosti zadaný bankovní účet pro českou měnu. Podívejte se na část "Způsob zadání bankovního účtu" výše.
---
## O modulu
Tento modul je vyvíjen a spravován společností **[Ash technology s.r.o.](https://www.ashtechnology.eu)**, oficiálním partnerem Odoo v České republice.
Modul je zdarma a open-source. Uvítáme vaši zpětnou vazbu a návrhy na vylepšení – pokud váš nápad pomůže komunitě, rádi ho zapracujeme.
**Kontakt:**
- Web: [www.ashtechnology.eu](https://www.ashtechnology.eu)
- Email: info@ashtechnology.eu
Pro zakázkový vývoj v Odoo nebo větší projekty nás neváhejte kontaktovat.
---
*Odoo je ochranná známka společnosti Odoo S.A.*
+38
View File
@@ -0,0 +1,38 @@
🇨🇿 [Česká verze](README.cs.md)
# Czech QR Payments
This module adds QR codes to invoices for quick mobile payments. The codes are in SPAYD format, compatible with all major Czech banking apps.
* **Bank account format:** Enter Czech bank accounts in the standard Odoo field using the Czech format, e.g., `123-456/0800`
![Bank Account Entry](static/description/bank_account_en.png)
* **Foreign accounts:** For foreign accounts, you can enter IBAN in the same field (standard Odoo field).
* **Currency support:** Czech QR codes are generated for invoices in CZK currency. For foreign payments, the original Odoo QR code is preserved.
## Frequently Asked Questions (FAQ)
**The QR code is not generated on the invoice**
Make sure you have the **QR Codes** option enabled in the **Invoicing** app configuration.
![QR Code Settings](static/description/qr_payment_settings_en.png)
**The QR code is generated on the invoice, but scanning it results in an error**
Check whether a bank account for the Czech currency is set up for the main company. See "Bank account format" section above.
---
## About
This module is developed and maintained by **[Ash technology s.r.o.](https://www.ashtechnology.eu)**, an official Odoo partner based in the Czech Republic.
These modules are free and open-source. We welcome your feedback and feature requests – if your idea benefits the community, we're happy to include it.
**Contact us:**
- Web: [www.ashtechnology.eu](https://www.ashtechnology.eu)
- Email: info@ashtechnology.eu
For custom Odoo development or larger projects, feel free to reach out.
---
*Odoo is a trademark of Odoo S.A.*
+1
View File
@@ -0,0 +1 @@
from . import models
+33
View File
@@ -0,0 +1,33 @@
{
'name': 'Czech QR Payment (SPAYD)',
'version': '19.0.1.0.0',
'depends': ['account', 'base', 'l10n_cz'],
'countries': ['cz'],
'category': 'Accounting',
'summary': 'Add Czech standard QR codes for payment to your invoices.',
'description': """
Czech QR Payment Generator
==========================
Allow to generate czech banks compliant QR code for payment on the invoice, if the invoice currency is "CZK"
Key Features:
-------------
* **Standard SPAYD Support:** Fully compatible with all major Czech banking apps.
* **Smart IBAN Conversion:** Automatically converts local account numbers (e.g. 123-456/0800) to IBAN format.
* **Integration:** Works with standard Odoo invoice templates.
""",
'author': 'Ash technology s.r.o.',
'website': 'https://github.com/ash-technology/l10n_cz_extra',
'license': 'LGPL-3',
'external_dependencies': {
'python': ['qrcode'],
},
'data': [
'views/report_invoice.xml',
],
'installable': True,
'auto_install': False,
'application': False,
'images': ['static/description/qr_payment_main_screenshot.png'],
}
+20
View File
@@ -0,0 +1,20 @@
#. module: l10n_cz_extra
#: model:ir.model.fields,field_description:ash_cz_qr_payment.field_account_move__display_name
msgid "Display Name"
msgstr "Zobrazovaný název"
#. module: ash_cz_qr_payment
#: model:ir.model,name:ash_cz_qr_payment.model_account_move
msgid "Journal Entry"
msgstr "Účetní záznam"
#. module: ash_cz_qr_payment
#: model_terms:ir.ui.view,arch_db:ash_cz_qr_payment.report_invoice_document_cz
msgid "QR Payment"
msgstr "QR Platba"
#. module: ash_cz_qr_payment
#: model_terms:ir.ui.view,arch_db:ash_cz_qr_payment.report_invoice_document_cz
msgid "Scan this QR Code with<br/>your banking application"
msgstr "Naskenujte tento QR kód v bankovní aplikaci"
+1
View File
@@ -0,0 +1 @@
from . import account_move
+76
View File
@@ -0,0 +1,76 @@
import qrcode
import base64
import io
from odoo import models, api
class AccountMove(models.Model):
_inherit = 'account.move'
def get_cz_qr_code_base64(self):
""" Returns Base64 PNG image for the invoice PDF """
self.ensure_one()
if self.currency_id.name != 'CZK':
return False
# Find bank: 1. Matching CZK, 2. No currency set (default)
bank = self.company_id.partner_id.bank_ids.filtered(lambda b: b.currency_id == self.currency_id)[:1]
if not bank:
bank = self.company_id.partner_id.bank_ids.filtered(lambda b: not b.currency_id)[:1]
if not bank or not bank.acc_number:
return False
# Build SPAYD string
iban = self.cz_to_iban(bank.acc_number)
amount = '%.2f' % self.amount_residual
vs = ''.join(filter(str.isdigit, self.payment_reference or ''))[-10:]
spayd = f"SPD*1.0*ACC:{iban}*AM:{amount}*CC:CZK*X-VS:{vs}"
# Generate QR Image
qr = qrcode.make(spayd)
buf = io.BytesIO()
qr.save(buf, format="PNG")
return base64.b64encode(buf.getvalue()).decode('utf-8')
def cz_to_iban(self, acc_number):
"""
Converts '123-456/0800' or '456/0800' to a valid CZ IBAN.
"""
if not acc_number:
return ""
# Clean the input
clean_acc = acc_number.replace(" ", "")
# If already an IBAN, return it
if clean_acc.upper().startswith('CZ'):
return clean_acc.upper()
try:
# Split into [prefix-main, bank_code]
parts = clean_acc.split('/')
if len(parts) != 2:
return clean_acc # Fallback
bank_code = parts[1]
account_parts = parts[0].split('-')
if len(account_parts) == 2:
prefix = account_parts[0].zfill(6)
main = account_parts[1].zfill(10)
else:
prefix = "000000"
main = account_parts[0].zfill(10)
# 1. Start with Bank Code + Prefix + Main + Country Number (CZ=12, 35=Z) + 00
# Czech Republic code is 123500 (12 for C, 35 for Z)
check_string = f"{bank_code}{prefix}{main}123500"
# 2. Calculate checksum
checksum = 98 - (int(check_string) % 97)
checksum_str = str(checksum).zfill(2)
return f"CZ{checksum_str}{bank_code}{prefix}{main}"
except Exception:
return clean_acc
+2
View File
@@ -0,0 +1,2 @@
qrcode
Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

+115
View File
@@ -0,0 +1,115 @@
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span12">
<h2 class="oe_slogan">Czech QR Payment Generator</h2>
<h3 class="oe_slogan">SPAYD-compliant QR Codes for Invoices</h3>
<p class="oe_mt32 text-center">
Add Czech-standard QR codes to your invoices for instant mobile payments.
Compatible with all major Czech banking apps.
</p>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">Key Features</h2>
<div class="oe_span6">
<h3><b>SPAYD Standard</b></h3>
<p>Generate QR codes in the official Czech SPAYD format, fully compatible with:</p>
<ul>
<li>Ceska sporitelna</li>
<li>CSOB</li>
<li>Komercni banka</li>
<li>Raiffeisenbank</li>
<li>And all other major Czech banks</li>
</ul>
<p>Your customers can simply scan the code with their banking app and pay instantly.</p>
</div>
<div class="oe_span6">
<h3><b>Smart Account Format</b></h3>
<p>Enter Czech bank accounts in the familiar local format:</p>
<p><code>123-456/0800</code></p>
<p>The module automatically converts them to IBAN when generating the QR code.
Foreign accounts can be entered directly as IBAN.</p>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img class="img img-responsive" src="bank_account_en.png" alt="Bank account entry"/>
</div>
</div>
<div class="oe_span6">
<h3><b>Easy Setup</b></h3>
<p>Simply enter your bank account in the standard Odoo field using the Czech format.
No additional configuration needed.</p>
<p>The QR code appears automatically on invoices with CZK currency.</p>
<p><b>Note:</b> For foreign currency invoices, the original Odoo QR code is preserved.</p>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_span6">
<h3><b>Seamless Integration</b></h3>
<p>Works with standard Odoo invoice templates. No need to modify your existing reports.</p>
<p>The QR code is generated automatically and placed in the appropriate position on your invoices.</p>
</div>
<div class="oe_span6">
<div class="oe_demo oe_picture oe_screenshot">
<img class="img img-responsive" src="qr_payment_settings_en.png" alt="QR payment settings"/>
</div>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan">Frequently Asked Questions</h2>
<div class="oe_span12">
<p><b>The QR code is not appearing on my invoices</b></p>
<p>Make sure you have the <b>QR Codes</b> option enabled in your Invoicing app settings
(Settings &gt; Invoicing &gt; Customer Invoices &gt; QR Codes).</p>
<p class="oe_mt16"><b>Which currencies are supported?</b></p>
<p>Czech SPAYD QR codes are generated for invoices in CZK currency only.
For other currencies, the standard Odoo QR code format is used.</p>
</div>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<div class="oe_span12 text-center">
<h2 class="oe_slogan">About the Developer</h2>
<p>
This module is developed and maintained by <b>Ash technology s.r.o.</b>,
an official Odoo partner based in the Czech Republic.
</p>
<p>
This module is free and open-source. We welcome your feedback and feature requests –
if your idea benefits the community, we're happy to include it.
</p>
<p class="oe_mt16">
<b>Contact us:</b><br/>
Web: <a href="https://www.ashtechnology.eu">www.ashtechnology.eu</a><br/>
Email: info@ashtechnology.eu
</p>
<p class="oe_mt16">
For custom Odoo development or larger projects, feel free to reach out.
</p>
</div>
</div>
</section>
<section class="oe_container">
<div class="oe_row">
<div class="oe_span12 text-center">
<p><small>Odoo is a trademark of Odoo S.A.</small></p>
</div>
</div>
</section>
Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

+33
View File
@@ -0,0 +1,33 @@
<odoo>
<template id="report_invoice_document_cz" inherit_id="account.report_invoice_document">
<xpath expr="//div[@id='qrcode']" position="replace">
<t t-set="cz_qr_base64" t-value="o.get_cz_qr_code_base64()"/>
<t t-if="cz_qr_base64">
<div id="qrcode" class="d-flex mb-3 avoid-page-break-inside">
<div class="qrcode me-3">
<img t-att-src="'data:image/png;base64,%s' % cz_qr_base64" style="width:140px;height:140px;"/>
</div>
<div class="d-inline text-muted lh-sm fst-italic">
<p class="fw-bold mb-0" style="color: black;">QR Platba</p>
<p>Scan this QR Code with<br/>your banking application</p>
</div>
</div>
</t>
<t t-else="">
<div id="qrcode" class="d-flex mb-3 avoid-page-break-inside" t-if="o.display_qr_code and o.amount_residual">
<div class="qrcode me-3" id="qrcode_image">
<t t-set="qr_code_url" t-value="o._generate_qr_code(silent_errors=True)"/>
<p t-if="qr_code_url" class="position-relative mb-0">
<img t-att-src="qr_code_url"/>
<img src="/account/static/src/img/Odoo_logo_O.svg" id="qrcode_odoo_logo" class="top-50 start-50 position-absolute bg-white border border-3 rounded-circle"/>
</p>
</div>
<div class="d-inline text-muted lh-sm fst-italic" id="qrcode_info" t-if="qr_code_url">
<p>Scan this QR Code with<br/>your banking application</p>
</div>
</div>
</t>
</xpath>
</template>
</odoo>