mirror of
https://github.com/bringout/oca-ocb-l10n_europe.git
synced 2026-04-27 02:42:07 +02:00
Initial commit: L10N_Europe packages
This commit is contained in:
commit
9803722600
2377 changed files with 380711 additions and 0 deletions
10
odoo-bringout-oca-ocb-l10n_ch/l10n_ch/tests/__init__.py
Normal file
10
odoo-bringout-oca-ocb-l10n_ch/l10n_ch/tests/__init__.py
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import test_ch_qr_code
|
||||
from . import test_swissqr
|
||||
from . import test_l10n_ch_isr_print
|
||||
from . import test_l10n_ch_qr_print
|
||||
from . import test_vendor_bill_isr
|
||||
from . import test_onchange_l10n_ch_postal
|
||||
from . import test_gen_isr_reference
|
||||
113
odoo-bringout-oca-ocb-l10n_ch/l10n_ch/tests/test_ch_qr_code.py
Normal file
113
odoo-bringout-oca-ocb-l10n_ch/l10n_ch/tests/test_ch_qr_code.py
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
# -*- coding:utf-8 -*-
|
||||
|
||||
from reportlab.graphics.barcode import createBarcodeDrawing
|
||||
|
||||
from odoo import Command
|
||||
from odoo.tests import tagged
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestSwissQRCode(AccountTestInvoicingCommon):
|
||||
""" Tests the generation of Swiss QR-codes on invoices
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref='l10n_ch.l10nch_chart_template'):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref)
|
||||
|
||||
cls.company_data['company'].qr_code = True
|
||||
cls.company_data['company'].country_id = None
|
||||
|
||||
cls.swiss_iban = cls.env['res.partner.bank'].create({
|
||||
'acc_number': 'CH15 3881 5158 3845 3843 7',
|
||||
'partner_id': cls.company_data['company'].partner_id.id,
|
||||
})
|
||||
|
||||
cls.swiss_qr_iban = cls.env['res.partner.bank'].create({
|
||||
'acc_number': 'CH21 3080 8001 2345 6782 7',
|
||||
'partner_id': cls.company_data['company'].partner_id.id,
|
||||
})
|
||||
|
||||
cls.ch_qr_invoice = cls.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': cls.partner_a.id,
|
||||
'currency_id': cls.env.ref('base.CHF').id,
|
||||
'partner_bank_id': cls.swiss_iban.id,
|
||||
'company_id': cls.company_data['company'].id,
|
||||
'payment_reference': "Papa a vu le fifi de lolo",
|
||||
'invoice_line_ids': [
|
||||
Command.create({
|
||||
'quantity': 1,
|
||||
'price_unit': 100,
|
||||
'tax_ids': [],
|
||||
})
|
||||
],
|
||||
})
|
||||
|
||||
def _assign_partner_address(self, partner):
|
||||
partner.write({
|
||||
'country_id': self.env.ref('base.ch').id,
|
||||
'street': "Crab street, 11",
|
||||
'city': "Crab City",
|
||||
'zip': "4242",
|
||||
})
|
||||
|
||||
def test_swiss_qr_code_generation(self):
|
||||
""" Check different cases of Swiss QR-code generation, when qr_method is
|
||||
specified beforehand.
|
||||
"""
|
||||
self.ch_qr_invoice.qr_code_method = 'ch_qr'
|
||||
|
||||
# First check with a regular IBAN
|
||||
with self.assertRaises(UserError, msg="It shouldn't be possible to generate a Swiss QR-code for partners without a complete Swiss address."):
|
||||
self.ch_qr_invoice._generate_qr_code()
|
||||
|
||||
# Setting the address should make it work
|
||||
self._assign_partner_address(self.ch_qr_invoice.company_id.partner_id)
|
||||
self._assign_partner_address(self.ch_qr_invoice.partner_id)
|
||||
|
||||
self.ch_qr_invoice._generate_qr_code()
|
||||
|
||||
# Now, check with a QR-IBAN as the payment account
|
||||
self.ch_qr_invoice.partner_bank_id = self.swiss_qr_iban
|
||||
|
||||
with self.assertRaises(UserError, msg="It shouldn't be possible to generate a Swiss QR-cde for a QR-IBAN without giving it a valid QR-reference as payment reference."):
|
||||
self.ch_qr_invoice._generate_qr_code()
|
||||
|
||||
# Assigning a QR reference should fix it
|
||||
self.ch_qr_invoice.payment_reference = '210000000003139471430009017'
|
||||
|
||||
# even if the invoice is not issued from Switzerland we want to generate the code
|
||||
self.ch_qr_invoice.company_id.partner_id.country_id = self.env.ref('base.fr')
|
||||
self.ch_qr_invoice._generate_qr_code()
|
||||
|
||||
def test_ch_qr_code_detection(self):
|
||||
""" Checks Swiss QR-code auto-detection when no specific QR-method
|
||||
is given to the invoice.
|
||||
"""
|
||||
self._assign_partner_address(self.ch_qr_invoice.company_id.partner_id)
|
||||
self._assign_partner_address(self.ch_qr_invoice.partner_id)
|
||||
self.ch_qr_invoice._generate_qr_code()
|
||||
self.assertEqual(self.ch_qr_invoice.qr_code_method, 'ch_qr', "Swiss QR-code generator should have been chosen for this invoice.")
|
||||
|
||||
def test_ch_qr_code_cross_mask(self):
|
||||
for width, height in ((64, 128), (128, 128), (256, 256), (512, 512)):
|
||||
barcode = createBarcodeDrawing('QR', value='', format='png', width=width, height=height)
|
||||
mask_to_apply = self.env['ir.actions.report'].get_available_barcode_masks()['ch_cross']
|
||||
mask_to_apply(width, height, barcode)
|
||||
zoom_x = width / (32 * (72 / 25.4))
|
||||
zoom_y = height / (32 * (72 / 25.4))
|
||||
self.assertEqual(
|
||||
[zoom_x, 0, 0, zoom_y, 0, 0],
|
||||
barcode.transform,
|
||||
)
|
||||
self.assertEqual(
|
||||
(0, 0, 90.70866141732284, 90.70866141732284),
|
||||
barcode.contents[0].getBounds(),
|
||||
)
|
||||
self.assertEqual(
|
||||
(38.45140157480315, 38.45140157480315, 52.25725984251969, 52.25725984251969),
|
||||
barcode.contents[1].getBounds(),
|
||||
)
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
|
||||
from odoo.tests import tagged
|
||||
|
||||
QR_IBAN = 'CH21 3080 8001 2345 6782 7'
|
||||
ISR_SUBS_NUMBER = "01-162-8"
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestGenISRReference(AccountTestInvoicingCommon):
|
||||
"""Check condition of generation of and content of the structured ref"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref="l10n_ch.l10nch_chart_template"):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref)
|
||||
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
|
||||
cls.bank = cls.env["res.bank"].create(
|
||||
{
|
||||
"name": "Alternative Bank Schweiz AG",
|
||||
"bic": "ALSWCH21XXX",
|
||||
}
|
||||
)
|
||||
cls.bank_acc_isr = cls.env["res.partner.bank"].create(
|
||||
{
|
||||
"acc_number": "ISR",
|
||||
"l10n_ch_isr_subscription_chf": "01-162-8",
|
||||
"bank_id": cls.bank.id,
|
||||
"partner_id": cls.partner_a.id,
|
||||
}
|
||||
)
|
||||
cls.bank_acc_qriban = cls.env["res.partner.bank"].create(
|
||||
{
|
||||
"acc_number": QR_IBAN,
|
||||
"bank_id": cls.bank.id,
|
||||
"partner_id": cls.partner_a.id,
|
||||
}
|
||||
)
|
||||
cls.product_a.taxes_id = cls.product_b.taxes_id = None
|
||||
cls.invoice = cls.init_invoice("out_invoice", products=cls.product_a+cls.product_b)
|
||||
|
||||
def test_isr(self):
|
||||
|
||||
self.invoice.partner_bank_id = self.bank_acc_isr
|
||||
self.invoice.name = "INV/01234567890"
|
||||
# Post invoice to have the expected amount due (amount_residual)
|
||||
self.invoice.action_post()
|
||||
|
||||
expected_isr = "000000000000000012345678903"
|
||||
expected_isr_spaced = "00 00000 00000 00001 23456 78903"
|
||||
expected_optical_line = "0100001297203>000000000000000012345678903+ 010001628>"
|
||||
self.assertEqual(self.invoice.l10n_ch_isr_number, expected_isr)
|
||||
self.assertEqual(self.invoice.l10n_ch_isr_number_spaced, expected_isr_spaced)
|
||||
self.assertEqual(self.invoice.l10n_ch_isr_optical_line, expected_optical_line)
|
||||
|
||||
def test_qrr(self):
|
||||
self.invoice.partner_bank_id = self.bank_acc_qriban
|
||||
|
||||
self.invoice.name = "INV/01234567890"
|
||||
|
||||
expected_isr = "000000000000000012345678903"
|
||||
expected_isr_spaced = "00 00000 00000 00001 23456 78903"
|
||||
self.assertEqual(self.invoice.l10n_ch_isr_number, expected_isr)
|
||||
self.assertEqual(self.invoice.l10n_ch_isr_number_spaced, expected_isr_spaced)
|
||||
# No need to check optical line, we have no use for it with QR-bill
|
||||
|
||||
def test_isr_long_reference(self):
|
||||
self.invoice.partner_bank_id = self.bank_acc_isr
|
||||
|
||||
self.invoice.name = "INV/123456789012345678901234567890"
|
||||
# Post invoice to have the expected amount due (amount_residual)
|
||||
self.invoice.action_post()
|
||||
|
||||
expected_isr = "567890123456789012345678901"
|
||||
expected_isr_spaced = "56 78901 23456 78901 23456 78901"
|
||||
expected_optical_line = "0100001297203>567890123456789012345678901+ 010001628>"
|
||||
self.assertEqual(self.invoice.l10n_ch_isr_number, expected_isr)
|
||||
self.assertEqual(self.invoice.l10n_ch_isr_number_spaced, expected_isr_spaced)
|
||||
self.assertEqual(self.invoice.l10n_ch_isr_optical_line, expected_optical_line)
|
||||
|
||||
def test_missing_isr_subscription_num(self):
|
||||
self.bank_acc_isr.l10n_ch_isr_subscription_chf = False
|
||||
|
||||
self.invoice.partner_bank_id = self.bank_acc_isr
|
||||
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_number)
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_number_spaced)
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_optical_line)
|
||||
|
||||
def test_missing_isr_subscription_num_in_wrong_field(self):
|
||||
self.bank_acc_isr.l10n_ch_isr_subscription_chf = False
|
||||
self.bank_acc_isr.l10n_ch_postal = ISR_SUBS_NUMBER
|
||||
|
||||
self.invoice.partner_bank_id = self.bank_acc_isr
|
||||
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_number)
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_number_spaced)
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_optical_line)
|
||||
|
||||
def test_no_bank_account(self):
|
||||
self.invoice.partner_bank_id = False
|
||||
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_number)
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_number_spaced)
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_optical_line)
|
||||
|
||||
def test_wrong_currency(self):
|
||||
self.invoice.partner_bank_id = self.bank_acc_isr
|
||||
self.invoice.currency_id = self.env.ref("base.BTN")
|
||||
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_number)
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_number_spaced)
|
||||
self.assertFalse(self.invoice.l10n_ch_isr_optical_line)
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
|
||||
from odoo.tests import tagged
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class ISRTest(AccountTestInvoicingCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref='l10n_ch.l10nch_chart_template'):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref)
|
||||
|
||||
def print_isr(self, invoice):
|
||||
try:
|
||||
invoice.action_invoice_sent()
|
||||
return True
|
||||
except ValidationError:
|
||||
return False
|
||||
|
||||
def test_l10n_ch_postals(self):
|
||||
|
||||
def assertBankAccountValid(account_number, expected_account_type, expected_postal=None):
|
||||
partner_bank = self.env['res.partner.bank'].create({
|
||||
'acc_number': account_number,
|
||||
'partner_id': self.partner_a.id,
|
||||
})
|
||||
expected_vals = {'acc_type': expected_account_type}
|
||||
if expected_postal is not None:
|
||||
expected_vals['l10n_ch_postal'] = expected_postal
|
||||
|
||||
self.assertRecordValues(partner_bank, [expected_vals])
|
||||
|
||||
assertBankAccountValid('010391391', 'postal', expected_postal='010391391')
|
||||
assertBankAccountValid('CH6309000000250097798', 'iban', expected_postal='25-9779-8')
|
||||
assertBankAccountValid('GR1601101250000000012300695', 'iban', expected_postal=False)
|
||||
|
||||
partner_bank = self.env['res.partner.bank'].create({
|
||||
'acc_number': '010391394',
|
||||
'partner_id': self.partner_a.id,
|
||||
})
|
||||
self.assertNotEqual(partner_bank.acc_type, 'postal')
|
||||
|
||||
def test_isr(self):
|
||||
isr_bank_account = self.env['res.partner.bank'].create({
|
||||
'acc_number': "ISR {} number",
|
||||
'partner_id': self.env.company.partner_id.id,
|
||||
'l10n_ch_isr_subscription_chf': '01-39139-1',
|
||||
})
|
||||
|
||||
invoice_chf = self.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': self.partner_a.id,
|
||||
'partner_bank_id': isr_bank_account.id,
|
||||
'currency_id': self.env.ref('base.CHF').id,
|
||||
'invoice_date': '2019-01-01',
|
||||
'invoice_line_ids': [(0, 0, {'product_id': self.product_a.id})],
|
||||
})
|
||||
invoice_chf.action_post()
|
||||
self.assertTrue(self.print_isr(invoice_chf))
|
||||
self.env.ref('base.EUR').active = True
|
||||
invoice_eur = self.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': self.partner_a.id,
|
||||
'partner_bank_id': isr_bank_account.id,
|
||||
'currency_id': self.env.ref('base.EUR').id,
|
||||
'invoice_date': '2019-01-01',
|
||||
'invoice_line_ids': [(0, 0, {'product_id': self.product_a.id})],
|
||||
})
|
||||
invoice_eur.action_post()
|
||||
#a normal invoice will still get printed
|
||||
self.assertTrue(self.print_isr(invoice_eur))
|
||||
# However, a isr bill can't be printed with those infos
|
||||
self.assertFalse(invoice_eur.l10n_ch_isr_valid)
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
import logging
|
||||
|
||||
from odoo.addons.account.tests.common import AccountTestInvoicingCommon
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tests import tagged
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class QRPrintTest(AccountTestInvoicingCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls, chart_template_ref='l10n_ch.l10nch_chart_template'):
|
||||
super().setUpClass(chart_template_ref=chart_template_ref)
|
||||
# the partner must be located in Switzerland.
|
||||
cls.partner = cls.env['res.partner'].create({
|
||||
'name': 'Bobby',
|
||||
'country_id': cls.env.ref('base.ch').id,
|
||||
})
|
||||
# The bank account must be QR-compatible
|
||||
cls.qr_bank_account = cls.env['res.partner.bank'].create({
|
||||
'acc_number': "CH4431999123000889012",
|
||||
'partner_id': cls.env.company.partner_id.id,
|
||||
'l10n_ch_isr_subscription_chf': '01-39139-1',
|
||||
})
|
||||
cls.correct_invoice_chf = cls.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': cls.partner.id,
|
||||
'partner_bank_id': cls.qr_bank_account.id,
|
||||
'currency_id': cls.env.ref('base.CHF').id,
|
||||
'invoice_date': '2019-01-01',
|
||||
'invoice_line_ids': [(0, 0, {'product_id': cls.product_a.id})],
|
||||
})
|
||||
|
||||
cls.correct_invoice_eur = cls.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': cls.partner.id,
|
||||
'partner_bank_id': cls.qr_bank_account.id,
|
||||
'currency_id': cls.env.ref('base.EUR').id,
|
||||
'invoice_date': '2019-01-01',
|
||||
'invoice_line_ids': [(0, 0, {'product_id': cls.product_a.id})],
|
||||
})
|
||||
|
||||
cls.wrong_partner_invoice = cls.env['account.move'].create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': cls.partner_a.id,
|
||||
'partner_bank_id': cls.qr_bank_account.id,
|
||||
'currency_id': cls.env.ref('base.EUR').id,
|
||||
'invoice_date': '2019-01-01',
|
||||
'invoice_line_ids': [(0, 0, {'product_id': cls.product_a.id})],
|
||||
})
|
||||
|
||||
def print_qr_bill(self, invoice):
|
||||
try:
|
||||
invoice.action_invoice_sent()
|
||||
return True
|
||||
except UserError as e:
|
||||
_logger.warning(e.name)
|
||||
return False
|
||||
|
||||
def test_print_qr(self):
|
||||
self.correct_invoice_chf.action_post()
|
||||
self.assertTrue(self.print_qr_bill(self.correct_invoice_chf))
|
||||
|
||||
#The QR can also be printed if the currency is EUR
|
||||
self.env.ref('base.EUR').active = True
|
||||
self.correct_invoice_eur.action_post()
|
||||
self.assertTrue(self.print_qr_bill(self.correct_invoice_eur))
|
||||
|
||||
#A normal invoice will be printed if the partner is not from Switzerland
|
||||
self.wrong_partner_invoice.action_post()
|
||||
self.assertTrue(self.print_qr_bill(self.wrong_partner_invoice))
|
||||
|
||||
#However, a qr bill can't be printed with those infos
|
||||
self.assertFalse(self.wrong_partner_invoice.l10n_ch_is_qr_valid)
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import Form, TransactionCase
|
||||
|
||||
|
||||
CH_ISR_ISSUER = '01-162-8'
|
||||
CH_IBAN = 'CH15 3881 5158 3845 3843 7'
|
||||
FR_IBAN = 'FR83 8723 4133 8709 9079 4002 530'
|
||||
CH_POST_IBAN = 'CH09 0900 0000 1000 8060 7'
|
||||
CH_POSTAL_ACC = '10-8060-7'
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestOnchangePostal(TransactionCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
|
||||
|
||||
cls.partner = cls.env['res.partner'].create({
|
||||
'name': 'Swiss Company',
|
||||
'street': 'Route de Berne 41',
|
||||
'zip': '1000',
|
||||
'city': 'Lausanne',
|
||||
'is_company': 1,
|
||||
'country_id': cls.env.ref('base.ch').id,
|
||||
})
|
||||
cls.ch_bank = cls.env['res.bank'].create({
|
||||
'name': 'Alternative Bank Schweiz AG',
|
||||
'bic': 'ALSWCH21XXX',
|
||||
})
|
||||
cls.post_bank = cls.env['res.bank'].search(
|
||||
[('bic', '=', 'POFICHBEXXX')])
|
||||
if not cls.post_bank:
|
||||
cls.post_bank = cls.env['res.bank'].create({
|
||||
'name': 'PostFinance AG',
|
||||
'bic': 'POFICHBEXXX',
|
||||
})
|
||||
|
||||
def new_partner_bank_form(self):
|
||||
form = Form(
|
||||
self.env['res.partner.bank'],
|
||||
view="l10n_ch.isr_partner_bank_form",
|
||||
)
|
||||
form.partner_id = self.partner
|
||||
return form
|
||||
|
||||
def test_onchange_acc_number_isr_issuer(self):
|
||||
"""The user entered ISR issuer number into acc_number
|
||||
|
||||
We detect and move it to l10n_ch_postal.
|
||||
It must be moved as it is not unique.
|
||||
"""
|
||||
bank_acc = self.new_partner_bank_form()
|
||||
bank_acc.acc_number = CH_ISR_ISSUER
|
||||
account = bank_acc.save()
|
||||
|
||||
self.assertEqual(
|
||||
account.acc_number,
|
||||
"{} {}".format(CH_ISR_ISSUER, self.partner.name)
|
||||
)
|
||||
self.assertEqual(account.l10n_ch_postal, CH_ISR_ISSUER)
|
||||
self.assertEqual(account.acc_type, 'postal')
|
||||
|
||||
def test_onchange_acc_number_postal(self):
|
||||
"""The user entered postal number into acc_number
|
||||
|
||||
We detect and copy it to l10n_ch_postal.
|
||||
"""
|
||||
bank_acc = self.new_partner_bank_form()
|
||||
bank_acc.acc_number = CH_POSTAL_ACC
|
||||
account = bank_acc.save()
|
||||
|
||||
self.assertEqual(account.acc_number, CH_POSTAL_ACC)
|
||||
self.assertEqual(account.l10n_ch_postal, CH_POSTAL_ACC)
|
||||
self.assertEqual(account.acc_type, 'postal')
|
||||
|
||||
def test_onchange_acc_number_iban_ch(self):
|
||||
bank_acc = self.new_partner_bank_form()
|
||||
bank_acc.acc_number = CH_IBAN
|
||||
account = bank_acc.save()
|
||||
|
||||
self.assertEqual(account.acc_number, CH_IBAN)
|
||||
self.assertFalse(account.l10n_ch_postal)
|
||||
self.assertEqual(account.acc_type, 'iban')
|
||||
|
||||
def test_onchange_acc_number_iban_ch_postfinance(self):
|
||||
"""The user enter a postal IBAN, postal number can be deduced"""
|
||||
bank_acc = self.new_partner_bank_form()
|
||||
bank_acc.acc_number = CH_POST_IBAN
|
||||
account = bank_acc.save()
|
||||
|
||||
self.assertEqual(account.acc_number, CH_POST_IBAN)
|
||||
self.assertEqual(account.l10n_ch_postal, CH_POSTAL_ACC)
|
||||
self.assertEqual(account.acc_type, 'iban')
|
||||
|
||||
def test_onchange_acc_number_iban_foreign(self):
|
||||
"""Check IBAN still works changed"""
|
||||
bank_acc = self.new_partner_bank_form()
|
||||
bank_acc.acc_number = FR_IBAN
|
||||
account = bank_acc.save()
|
||||
|
||||
self.assertEqual(account.acc_number, FR_IBAN)
|
||||
self.assertFalse(account.l10n_ch_postal)
|
||||
self.assertEqual(account.acc_type, 'iban')
|
||||
|
||||
def test_onchange_acc_number_none(self):
|
||||
"""Check misc format still works"""
|
||||
bank_acc = self.new_partner_bank_form()
|
||||
bank_acc.acc_number = 'anything'
|
||||
account = bank_acc.save()
|
||||
|
||||
self.assertEqual(account.acc_number, 'anything')
|
||||
self.assertFalse(account.l10n_ch_postal)
|
||||
self.assertEqual(account.acc_type, 'bank')
|
||||
223
odoo-bringout-oca-ocb-l10n_ch/l10n_ch/tests/test_swissqr.py
Normal file
223
odoo-bringout-oca-ocb-l10n_ch/l10n_ch/tests/test_swissqr.py
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
# -*- 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='l10n_ch.l10nch_chart_template'):
|
||||
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.assertFalse(
|
||||
invoice.partner_bank_id._eligible_for_qr_code('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.assertTrue(
|
||||
invoice.partner_bank_id._eligible_for_qr_code('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):
|
||||
# Let us test the generation of a SwissQR for an invoice, first by showing an
|
||||
# QR is included in the invoice is only generated when Odoo has all the data it needs.
|
||||
with self.assertRaises(UserError), self.cr.savepoint():
|
||||
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_isr_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,
|
||||
'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]))
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
from odoo.tests import Form, common, tagged
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
|
||||
CH_ISR_SUBSCRIPTION = "01-162-8"
|
||||
CH_POSTAL = "10-8060-7"
|
||||
CH_IBAN = "CH15 3881 5158 3845 3843 7"
|
||||
ISR_REFERENCE_GOOD = "16 00011 23456 78901 23456 78901"
|
||||
ISR_REFERENCE_ZEROS = "00 00000 00000 00001 23456 78903"
|
||||
ISR_REFERENCE_NO_ZEROS = "1 23456 78903"
|
||||
ISR_REFERENCE_BAD = "11 11111 11111 11111 11111 11111"
|
||||
|
||||
|
||||
@tagged('post_install_l10n', 'post_install', '-at_install')
|
||||
class TestVendorBillISR(common.TransactionCase):
|
||||
"""Check we can encode Vendor bills with ISR references
|
||||
|
||||
The ISR is a structured reference with a checksum.
|
||||
User are guided to ensure they don't encode wrong ISR references.
|
||||
Only vendors with ISR issuer accounts send ISR references.
|
||||
|
||||
ISR references can be received at least till 2022.
|
||||
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestVendorBillISR, cls).setUpClass()
|
||||
cls.abs_bank = cls.env["res.bank"].create(
|
||||
{"name": "Alternative Bank Schweiz", "bic": "ABSOCH22XXX"}
|
||||
)
|
||||
cls.supplier1 = cls.env["res.partner"].create({"name": "Supplier ISR"})
|
||||
cls.supplier2 = cls.env["res.partner"].create({"name": "Supplier postal"})
|
||||
cls.supplier3 = cls.env["res.partner"].create({"name": "Supplier IBAN"})
|
||||
|
||||
cls.bank_acc_isr = cls.env['res.partner.bank'].create({
|
||||
"acc_number": "ISR 01-162-8 Supplier ISR",
|
||||
"partner_id": cls.supplier1.id,
|
||||
"l10n_ch_postal": CH_ISR_SUBSCRIPTION,
|
||||
})
|
||||
cls.bank_acc_postal = cls.env['res.partner.bank'].create({
|
||||
"acc_number": CH_POSTAL,
|
||||
"partner_id": cls.supplier2.id,
|
||||
"l10n_ch_postal": CH_POSTAL,
|
||||
})
|
||||
cls.bank_acc_iban = cls.env['res.partner.bank'].create({
|
||||
"acc_number": CH_IBAN,
|
||||
"partner_id": cls.supplier2.id,
|
||||
"l10n_ch_postal": False,
|
||||
})
|
||||
|
||||
def test_isr_ref(self):
|
||||
"""Enter ISR reference with ISR subscription account number
|
||||
|
||||
The vendor bill can be saved.
|
||||
"""
|
||||
self.env.company.country_id = self.env.ref('base.ch')
|
||||
self.env.company.account_fiscal_country_id = self.env.company.country_id
|
||||
form = Form(self.env["account.move"].with_context(
|
||||
default_move_type="in_invoice"), view="l10n_ch.isr_invoice_form")
|
||||
form.partner_id = self.supplier1
|
||||
form.partner_bank_id = self.bank_acc_isr
|
||||
|
||||
form.payment_reference = ISR_REFERENCE_GOOD
|
||||
invoice = form.save()
|
||||
|
||||
self.assertFalse(invoice.l10n_ch_isr_needs_fixing)
|
||||
|
||||
def test_isr_ref_with_zeros(self):
|
||||
"""Enter ISR reference with ISR subscription account number
|
||||
|
||||
An ISR Reference can have lots of zeros on the left.
|
||||
|
||||
The vendor bill can be saved.
|
||||
"""
|
||||
self.env.company.country_id = self.env.ref('base.ch')
|
||||
self.env.company.account_fiscal_country_id = self.env.company.country_id
|
||||
form = Form(self.env["account.move"].with_context(
|
||||
default_move_type="in_invoice"), view="l10n_ch.isr_invoice_form")
|
||||
form.partner_id = self.supplier1
|
||||
form.partner_bank_id = self.bank_acc_isr
|
||||
|
||||
form.payment_reference = ISR_REFERENCE_ZEROS
|
||||
invoice = form.save()
|
||||
|
||||
self.assertFalse(invoice.l10n_ch_isr_needs_fixing)
|
||||
|
||||
def test_isr_ref_no_zeros(self):
|
||||
"""Enter ISR reference with ISR subscription account number
|
||||
|
||||
An ISR Reference full of zeros can be entered starting by the
|
||||
first non zero digit.
|
||||
|
||||
The vendor bill can be saved.
|
||||
"""
|
||||
self.env.company.country_id = self.env.ref('base.ch')
|
||||
self.env.company.account_fiscal_country_id = self.env.company.country_id
|
||||
form = Form(self.env["account.move"].with_context(
|
||||
default_move_type="in_invoice"), view="l10n_ch.isr_invoice_form")
|
||||
form.partner_id = self.supplier1
|
||||
form.partner_bank_id = self.bank_acc_isr
|
||||
|
||||
form.payment_reference = ISR_REFERENCE_NO_ZEROS
|
||||
invoice = form.save()
|
||||
|
||||
self.assertFalse(invoice.l10n_ch_isr_needs_fixing)
|
||||
|
||||
def test_isr_wrong_ref(self):
|
||||
"""Mistype ISR reference with ISR subscription account number
|
||||
Check it will show the warning
|
||||
"""
|
||||
self.env.company.country_id = self.env.ref('base.ch')
|
||||
self.env.company.account_fiscal_country_id = self.env.company.country_id
|
||||
form = Form(self.env["account.move"].with_context(
|
||||
default_move_type="in_invoice"), view="l10n_ch.isr_invoice_form")
|
||||
form.partner_id = self.supplier1
|
||||
form.partner_bank_id = self.bank_acc_isr
|
||||
|
||||
form.payment_reference = ISR_REFERENCE_BAD
|
||||
invoice = form.save()
|
||||
|
||||
self.assertTrue(invoice.l10n_ch_isr_needs_fixing)
|
||||
Loading…
Add table
Add a link
Reference in a new issue