Odoo18-Base/addons/l10n_ch/tests/test_swissqr.py

222 lines
7.8 KiB
Python
Raw Permalink Normal View History

2025-03-10 10:52:11 +07:00
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import time
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
from odoo.exceptions import UserError
from odoo.tests import tagged
from odoo.tools.misc import mod10r
CH_IBAN = 'CH15 3881 5158 3845 3843 7'
QR_IBAN = 'CH21 3080 8001 2345 6782 7'
@tagged('post_install_l10n', 'post_install', '-at_install')
class TestSwissQR(AccountTestInvoicingCommon):
@classmethod
def setUpClass(cls, chart_template_ref='ch'):
super().setUpClass(chart_template_ref=chart_template_ref)
def setUp(self):
super(TestSwissQR, self).setUp()
# Activate SwissQR in Swiss invoices
self.env['ir.config_parameter'].create(
{'key': 'l10n_ch.print_qrcode', 'value': '1'}
)
self.customer = self.env['res.partner'].create(
{
"name": "Partner",
"street": "Route de Berne 41",
"street2": "",
"zip": "1000",
"city": "Lausanne",
"country_id": self.env.ref("base.ch").id,
}
)
self.env.user.company_id.partner_id.write(
{
"street": "Route de Berne 88",
"street2": "",
"zip": "2000",
"city": "Neuchâtel",
"country_id": self.env.ref('base.ch').id,
}
)
self.product = self.env['product.product'].create({
'name': 'Customizable Desk',
})
self.invoice1 = self.create_invoice('base.CHF')
sale_journal = self.env['account.journal'].search([("type", "=", "sale")])
sale_journal.invoice_reference_model = "ch"
def create_invoice(self, currency_to_use='base.CHF'):
""" Generates a test invoice """
account = self.env['account.account'].search(
[('account_type', '=', 'asset_current')], limit=1
)
invoice = (
self.env['account.move']
.create(
{
'move_type': 'out_invoice',
'partner_id': self.customer.id,
'currency_id': self.env.ref(currency_to_use).id,
'date': time.strftime('%Y') + '-12-22',
'invoice_line_ids': [
(
0,
0,
{
'name': self.product.name,
'product_id': self.product.id,
'account_id': account.id,
'quantity': 1,
'price_unit': 42.0,
},
)
],
}
)
)
return invoice
def create_account(self, number):
""" Generates a test res.partner.bank. """
return self.env['res.partner.bank'].create(
{
'acc_number': number,
'partner_id': self.env.user.company_id.partner_id.id,
}
)
def swissqr_not_generated(self, invoice):
""" Prints the given invoice and tests that no Swiss QR generation is triggered. """
self.assertTrue(
invoice.partner_bank_id._get_error_messages_for_qr('ch_qr', invoice.partner_id, invoice.currency_id),
'No Swiss QR should be generated for this invoice',
)
def swissqr_generated(self, invoice, ref_type='NON'):
""" Ensure correct params for Swiss QR generation. """
self.assertFalse(
invoice.partner_bank_id._get_error_messages_for_qr('ch_qr', invoice.partner_id, invoice.currency_id), 'A Swiss QR can be generated'
)
if ref_type == 'QRR':
self.assertTrue(invoice.payment_reference)
struct_ref = invoice.payment_reference
unstr_msg = invoice.ref or invoice.name or ''
else:
struct_ref = ''
unstr_msg = invoice.payment_reference or invoice.ref or invoice.name or ''
unstr_msg = unstr_msg or invoice.number
payload = (
"SPC\n"
"0200\n"
"1\n"
"{iban}\n"
"K\n"
"company_1_data\n"
"Route de Berne 88\n"
"2000 Neuchâtel\n"
"\n\n"
"CH\n"
"\n\n\n\n\n\n\n"
"42.00\n"
"CHF\n"
"K\n"
"Partner\n"
"Route de Berne 41\n"
"1000 Lausanne\n"
"\n\n"
"CH\n"
"{ref_type}\n"
"{struct_ref}\n"
"{unstr_msg}\n"
"EPD"
).format(
iban=invoice.partner_bank_id.sanitized_acc_number,
ref_type=ref_type,
struct_ref=struct_ref or '',
unstr_msg=unstr_msg,
)
expected_params = {
'barcode_type': 'QR',
'barLevel': 'M',
'width': 256,
'height': 256,
'quiet': 1,
'mask': 'ch_cross',
'value': payload,
}
params = invoice.partner_bank_id._get_qr_code_generation_params(
'ch_qr', 42.0, invoice.currency_id, invoice.partner_id, unstr_msg, struct_ref
)
self.assertEqual(params, expected_params)
def test_swissQR_missing_bank(self):
self.invoice1.action_post()
self.swissqr_not_generated(self.invoice1)
def test_swissQR_iban(self):
# Now we add an account for payment to our invoice
# Here we don't use a structured reference
iban_account = self.create_account(CH_IBAN)
self.invoice1.partner_bank_id = iban_account
self.invoice1.action_post()
self.swissqr_generated(self.invoice1, ref_type="NON")
def test_swissQR_qriban(self):
# Now use a proper QR-IBAN, we are good to print a QR Bill
qriban_account = self.create_account(QR_IBAN)
self.assertTrue(qriban_account.l10n_ch_qr_iban)
self.invoice1.partner_bank_id = qriban_account
self.invoice1.action_post()
self.swissqr_generated(self.invoice1, ref_type="QRR")
def test_swiss_order_reference_qrr_for_qr_code(self):
"""
Test that the order reference is correctly generated for QR-Code
We summon the skipTest if Sale is not installed (instead of creating a whole module for one test)
"""
if 'sale.order' not in self.env:
self.skipTest('`sale` is not installed')
payment_custom = self.env['ir.module.module']._get('payment_custom')
if payment_custom.state != 'installed':
self.skipTest("payment_custom module is not installed")
provider = self.env['payment.provider'].create({
'name': 'Test',
'code': 'custom',
})
invoice_journal = self.env['account.journal'].search(
[('type', '=', 'sale'), ('company_id', '=', self.env.company.id)], limit=1)
invoice_journal.write({'invoice_reference_model': 'ch'})
order = self.env['sale.order'].create({
'name': "S00001",
'partner_id': self.env['res.partner'].search([("name", '=', 'Partner')])[0].id,
'order_line': [
(0, 0, {'product_id': self.product_a.id, 'price_unit': 100}),
],
})
payment_transaction = self.env['payment.transaction'].create({
'provider_id': provider.id,
'payment_method_id': self.env.ref('payment.payment_method_unknown').id,
'sale_order_ids': [order.id],
'partner_id': self.env['res.partner'].search([("name", '=', 'Partner')])[0].id,
'amount': 100,
'currency_id': self.env.company.currency_id.id,
})
payment_transaction._set_pending()
self.assertEqual(order.reference, mod10r(order.reference[:-1]))