Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[12.0][FIX] l10n_nl_bsn: searching on BSN without dots #232

Merged
merged 2 commits into from
Dec 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions l10n_nl_bsn/__manifest__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Copyright 2016-2018 Onestein (<https://www.onestein.eu>)
# Copyright 2016-2019 Onestein (<https://www.onestein.eu>)
# 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)',
Expand Down
68 changes: 49 additions & 19 deletions l10n_nl_bsn/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Copyright 2016-2018 Onestein (<https://www.onestein.eu>)
# Copyright 2016-2019 Onestein (<https://www.onestein.eu>)
# 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:
Expand All @@ -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
Expand All @@ -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]
astirpe marked this conversation as resolved.
Show resolved Hide resolved
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)
astirpe marked this conversation as resolved.
Show resolved Hide resolved
return super().search(
res_domain, offset=offset, limit=limit, order=order, count=count)
3 changes: 3 additions & 0 deletions l10n_nl_bsn/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -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.
hbrunn marked this conversation as resolved.
Show resolved Hide resolved
49 changes: 45 additions & 4 deletions l10n_nl_bsn/tests/test_l10n_nl_bsn.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2017-2018 Onestein (<https://www.onestein.eu>)
# Copyright 2017-2019 Onestein (<https://www.onestein.eu>)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo.tests.common import TransactionCase
Expand All @@ -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):
Expand All @@ -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'),
])
astirpe marked this conversation as resolved.
Show resolved Hide resolved
self.assertEqual(len(res), 1)
astirpe marked this conversation as resolved.
Show resolved Hide resolved
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)