diff --git a/l10n_nl_bsn/__manifest__.py b/l10n_nl_bsn/__manifest__.py index 8e6ccce74..58e9e9ea3 100644 --- a/l10n_nl_bsn/__manifest__.py +++ b/l10n_nl_bsn/__manifest__.py @@ -1,9 +1,9 @@ -# Copyright 2016-2018 Onestein () +# Copyright 2016-2019 Onestein () # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { 'name': 'Burgerservicenummer (BSN) for Partners', - 'version': '12.0.1.0.0', + 'version': '12.0.1.0.1', 'development_status': 'Production/Stable', 'category': 'Localization', 'author': 'Onestein, Odoo Community Association (OCA)', diff --git a/l10n_nl_bsn/models/res_partner.py b/l10n_nl_bsn/models/res_partner.py index 8109c7a1b..3274c13e2 100644 --- a/l10n_nl_bsn/models/res_partner.py +++ b/l10n_nl_bsn/models/res_partner.py @@ -1,9 +1,10 @@ -# Copyright 2016-2018 Onestein () +# Copyright 2016-2019 Onestein () # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). import logging from odoo import api, fields, models, _ +from odoo.osv import expression _logger = logging.getLogger(__name__) try: @@ -17,33 +18,31 @@ class ResPartner(models.Model): bsn_number = fields.Char( string='BSN', - groups='hr.group_hr_user' + groups='hr.group_hr_user', ) - @api.multi @api.onchange('bsn_number') def onchange_bsn_number(self): warning = {} - for partner in self: - if partner.bsn_number: - # properly format the entered BSN - partner.bsn_number = bsn.format(partner.bsn_number) + if self.bsn_number: + # properly format the entered BSN + self.bsn_number = bsn.format(self.bsn_number) - # check is valid, otherwise display a warning - warning = partner._warn_bsn_invalid() + # check is valid, otherwise display a warning + warning = self._warn_bsn_invalid() - # search for another partner with the same BSN - args = [('bsn_number', '=', partner.bsn_number), - ('name', '!=', partner.name)] + # search for another partner with the same BSN + args = [('bsn_number', '=', self.bsn_number), + ('name', '!=', self.name)] - # refine search in case of multicompany setting - if partner.company_id: - args += [('company_id', '=', partner.company_id.id)] - other_partner = self.search(args, limit=1) + # refine search in case of multicompany setting + if self.company_id: + args += [('company_id', '=', self.company_id.id)] + other_partner = self.search(args, limit=1) - # if another partner exists, display a warning - if other_partner: - warning = other_partner._warn_bsn_existing() + # if another partner exists, display a warning + if other_partner: + warning = other_partner._warn_bsn_existing() return {'warning': warning, } @api.multi @@ -66,3 +65,34 @@ def _warn_bsn_existing(self): 'message': msg % (self.name, self.bsn_number) } return warning + + @api.model + def search(self, args, offset=0, limit=None, order=None, count=False): + res_domain = [] + for domain in args: + if ( + len(domain) > 2 + and domain[0] == "bsn_number" + and isinstance(domain[2], str) + and domain[2] + and domain[1] not in expression.NEGATIVE_TERM_OPERATORS + and not self.env.context.get("skip_formatted_bsn_number_search") + ): + operator = domain[1] + bsn_number = domain[2] + bsn_compact = bsn.compact(bsn_number) + bsn_domain = expression.OR([ + [('bsn_number', operator, bsn_number)], + [('bsn_number', operator, bsn_compact)], + ]) + if bsn.is_valid(bsn_number): + bsn_format = bsn.format(bsn_number) + bsn_domain = expression.OR([ + bsn_domain, + [('bsn_number', operator, bsn_format)], + ]) + res_domain += bsn_domain + else: + res_domain.append(domain) + return super().search( + res_domain, offset=offset, limit=limit, order=order, count=count) diff --git a/l10n_nl_bsn/readme/ROADMAP.rst b/l10n_nl_bsn/readme/ROADMAP.rst new file mode 100644 index 000000000..d3aaf81b0 --- /dev/null +++ b/l10n_nl_bsn/readme/ROADMAP.rst @@ -0,0 +1,3 @@ +* The 'ilike' search of a substring of a BSN number could not work properly in case the + entered BSN number does not contain dots while the corresponding BSN number stored in the + database contains dots. diff --git a/l10n_nl_bsn/tests/test_l10n_nl_bsn.py b/l10n_nl_bsn/tests/test_l10n_nl_bsn.py index 184a88ee9..52c2d0586 100644 --- a/l10n_nl_bsn/tests/test_l10n_nl_bsn.py +++ b/l10n_nl_bsn/tests/test_l10n_nl_bsn.py @@ -1,4 +1,4 @@ -# Copyright 2017-2018 Onestein () +# Copyright 2017-2019 Onestein () # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). from odoo.tests.common import TransactionCase @@ -7,10 +7,11 @@ class TestBsn(TransactionCase): def setUp(self): - super(TestBsn, self).setUp() + super().setUp() self.partner_bsn = self.env['res.partner'].create({ 'name': 'Partner with BSN', + 'company_id': self.env.user.company_id.id, }) def test_01_bsn_not_valid(self): @@ -36,15 +37,55 @@ def test_02_bsn_valid(self): def test_03_bsn_another_partner(self): new_partner_bsn = self.env['res.partner'].create({ - 'name': 'Partner with BSN', + 'name': 'Partner with BSN - NEW', 'bsn_number': '1000.00.009' }) + self.partner_bsn.bsn_number = '100000009' + res = self.partner_bsn.onchange_bsn_number() + self.assertTrue(res.get('warning')) warning = new_partner_bsn._warn_bsn_existing() message = warning.get('message') self.assertTrue(message) - msg_txt = 'Another person (Partner with BSN) ' \ + msg_txt = 'Another person (Partner with BSN - NEW) ' \ 'has the same BSN (1000.00.009).' self.assertEqual(message, msg_txt) + self.assertEqual(message, res['warning']['message']) title = warning.get('title') self.assertTrue(title) self.assertEqual(title, 'Warning!') + self.assertEqual(title, res['warning']['title']) + + def test_04_search_bsn_number(self): + self.partner_bsn.bsn_number = '100000009' + self.partner_bsn.onchange_bsn_number() + self.partner_bsn.write({}) + self.assertEqual(self.partner_bsn.bsn_number, '1000.00.009') + + res = self.env['res.partner'].search([ + ('bsn_number', '=', '100000009'), + ]) + self.assertEqual(len(res), 1) + res = self.env['res.partner'].search([ + ('bsn_number', '=', '1000.00.009'), + ]) + self.assertEqual(len(res), 1) + res = self.env['res.partner'].search([ + ('bsn_number', 'ilike', '1000.00.00'), + ]) + self.assertEqual(len(res), 1) + res = self.env['res.partner'].search([ + ('bsn_number', 'ilike', '00.00.009'), + ]) + self.assertEqual(len(res), 1) + res = self.env['res.partner'].search([ + ('bsn_number', 'ilike', '00.00.00'), + ]) + self.assertEqual(len(res), 1) + res = self.env['res.partner'].search([ + ('bsn_number', '=', '10000000'), + ]) + self.assertFalse(res) + res = self.env['res.partner'].search([ + ('bsn_number', '=', '1000.00.00'), + ]) + self.assertFalse(res)