222 lines
7.8 KiB
Python
222 lines
7.8 KiB
Python
|
# -*- 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.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
|
||
|
@AccountTestInvoicingCommon.setup_country('ch')
|
||
|
def setUpClass(cls):
|
||
|
super().setUpClass()
|
||
|
|
||
|
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]))
|