From 016869daeb5dc1696fe5c3c775943c892a90789b Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Mon, 22 Jul 2024 17:45:28 +0200 Subject: [PATCH] [MIG] l10n_nl_partner_name: Migration to 16.0 --- l10n_nl_partner_name/__init__.py | 2 +- l10n_nl_partner_name/__manifest__.py | 2 +- l10n_nl_partner_name/model/res_partner.py | 41 ------- .../{model => models}/__init__.py | 0 l10n_nl_partner_name/models/res_partner.py | 60 ++++++++++ l10n_nl_partner_name/scripts/guess_names.py | 108 ------------------ .../tests/test_l10n_nl_partner_name.py | 20 +++- l10n_nl_partner_name/views/res_partner.xml | 94 +++------------ 8 files changed, 94 insertions(+), 233 deletions(-) delete mode 100644 l10n_nl_partner_name/model/res_partner.py rename l10n_nl_partner_name/{model => models}/__init__.py (100%) create mode 100644 l10n_nl_partner_name/models/res_partner.py delete mode 100755 l10n_nl_partner_name/scripts/guess_names.py diff --git a/l10n_nl_partner_name/__init__.py b/l10n_nl_partner_name/__init__.py index 068613b2a..c32fd62b7 100644 --- a/l10n_nl_partner_name/__init__.py +++ b/l10n_nl_partner_name/__init__.py @@ -1,2 +1,2 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from . import model +from . import models diff --git a/l10n_nl_partner_name/__manifest__.py b/l10n_nl_partner_name/__manifest__.py index a7d12715c..16dc58ceb 100644 --- a/l10n_nl_partner_name/__manifest__.py +++ b/l10n_nl_partner_name/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). { "name": "Dutch partner names", - "version": "13.0.1.0.0", + "version": "16.0.1.0.0", "summary": "Adapt parter names to Dutch conventions (support infix)", "author": "Therp BV, Odoo Community Association (OCA)", "website": "https://github.com/OCA/l10n-netherlands", diff --git a/l10n_nl_partner_name/model/res_partner.py b/l10n_nl_partner_name/model/res_partner.py deleted file mode 100644 index 3017b7924..000000000 --- a/l10n_nl_partner_name/model/res_partner.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright 2017-2022 Therp BV . -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from odoo import api, fields, models - -from odoo.addons.mail.models.mail_template import mako_safe_template_env - - -class ResPartner(models.Model): - """Extend res.partner with extra fields for Dutch names.""" - - _inherit = "res.partner" - - initials = fields.Char() - infix = fields.Char() - - @api.depends("firstname", "lastname", "initials", "infix") - def _compute_name(self): - for record in self: - record.name = record._get_computed_name( - record.lastname, record.firstname, record.initials, record.infix - ) - - @api.model - def _get_computed_name(self, lastname, firstname, initials=None, infix=None): - name_template = mako_safe_template_env.from_string( - self.env.context.get( - "name_format", - "${firstname or initials or ''}" - "${(firstname or initials) and ' ' or ''}" - "${infix or ''}${infix and ' ' or ''}${lastname or ''}", - ) - ) - name = name_template.render( - { - "firstname": firstname, - "lastname": lastname, - "initials": initials, - "infix": infix, - } - ) - return name if name else "" diff --git a/l10n_nl_partner_name/model/__init__.py b/l10n_nl_partner_name/models/__init__.py similarity index 100% rename from l10n_nl_partner_name/model/__init__.py rename to l10n_nl_partner_name/models/__init__.py diff --git a/l10n_nl_partner_name/models/res_partner.py b/l10n_nl_partner_name/models/res_partner.py new file mode 100644 index 000000000..2c9efb180 --- /dev/null +++ b/l10n_nl_partner_name/models/res_partner.py @@ -0,0 +1,60 @@ +# Copyright 2017-2022 Therp BV . +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo import api, fields, models + + +class ResPartner(models.Model): + """Extend res.partner with extra fields for Dutch names.""" + + _inherit = "res.partner" + _l10n_nl_partner_name_infixes = ("van", "der", "den", "op", "ter", "de", "v/d") + + initials = fields.Char() + infix = fields.Char() + + @api.depends("firstname", "lastname", "initials", "infix") + def _compute_name(self): + for record in self: + record.name = record._get_computed_name( + record.lastname, record.firstname, record.initials, record.infix + ) + + def _inverse_name(self): + for record in self: + parts = record._get_inverse_name(record.name, record.is_company) + record.update(parts) + + @api.model + def _get_computed_name(self, lastname, firstname, initials=None, infix=None): + return " ".join( + filter( + None, + (firstname, ("(%s)" % initials) if initials else None, infix, lastname), + ) + ) + + @api.model + def _get_inverse_name(self, name, is_company=False): + if is_company: + return super()._get_inverse_name(name, is_company=is_company) + + def add_token(key, value): + result[key] += (result[key] and " " or "") + value + + result = dict.fromkeys(("firstname", "lastname", "initials", "infix"), "") + tokens = (name or "").split() + while len(tokens) > 1: + token = tokens.pop(0) + if all((c.isupper() or c == ".") for c in token): + add_token("initials", token) + elif token[:1] == "(" and token[-1:] == ")": + add_token("initials", token[1:-1]) + elif token.lower() in self._l10n_nl_partner_name_infixes: + add_token("infix", token) + elif result["infix"]: + tokens.insert(0, token) + break + else: + add_token("firstname", token) + result["lastname"] = " ".join(tokens) + return result diff --git a/l10n_nl_partner_name/scripts/guess_names.py b/l10n_nl_partner_name/scripts/guess_names.py deleted file mode 100755 index a09546146..000000000 --- a/l10n_nl_partner_name/scripts/guess_names.py +++ /dev/null @@ -1,108 +0,0 @@ -#!/usr/bin/python -# Copyright 2017-2022 Therp BV -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -"""Script to convert names using a Dutch specific guessing strategy.""" -# pylint: disable=invalid-name,eval-used - -import argparse -import ast -import logging -import re -import xmlrpc.client as xmlrpclib - -logging.basicConfig(level=logging.DEBUG) -logger = logging.getLogger(__name__) - -parser = argparse.ArgumentParser() -parser.add_argument("odoo_host") -parser.add_argument("odoo_db") -parser.add_argument("odoo_user") -parser.add_argument("odoo_passwd") -parser.add_argument("additional_search", nargs="?") -args = parser.parse_args() - -extra_domain = ( - ast.literal_eval(args.additional_search) if args.additional_search else [] -) - -odoo_socket = xmlrpclib.ServerProxy("http://%s/xmlrpc/common" % args.odoo_host) -odoo_uid = odoo_socket.login(args.odoo_db, args.odoo_user, args.odoo_passwd) -odoo_socket = xmlrpclib.ServerProxy( - "http://%s/xmlrpc/object" % args.odoo_host, allow_none=True -) - - -def odoo_execute(model, method, *pargs, **kwargs): - """Execute a model method on Odoo through xmlrpc.""" - return odoo_socket.execute( - args.odoo_db, odoo_uid, args.odoo_passwd, model, method, *pargs, **kwargs - ) - - -field_names = ["lastname", "firstname", "initials", "infix"] -infixes = ["van", "der", "ter", "de", "v/d"] -initial = re.compile(r"^([A-Z]{1,3}\.{0,1}){1,4}$") - -limit = 10000 -offset = 0 - - -def add_token(values, key, token): - """Add a name part to the correct field value of the partner names.""" - values[key] = (values[key] + " " if values[key] else "") + token - - -def update_partner(partner): - """Update a single partner, reading old fields, adjusting names.""" - saved_lastname = partner["lastname"] - have_infix = False - tokens = partner["lastname"].split() - while len(tokens) > 1: - token = tokens.pop(0) - if initial.match(token): - add_token(partner, "initials", token) - elif any(map(lambda infix: re.match(infix, token, re.I), infixes)): - add_token(partner, "infix", token.lower()) - have_infix = True - else: - if have_infix: - tokens.insert(0, token) - break - add_token(partner, "firstname", token) - new_lastname = " ".join(tokens) - logger.info("Lastname was %s, lastname = %s", saved_lastname, new_lastname) - partner["lastname"] = new_lastname - odoo_execute("res.partner", "write", partner["id"], partner) - - -def get_partner_ids(): - """Search next batch of partners to process.""" - return odoo_execute( - "res.partner", - "search", - [ - ("lastname", "!=", False), - ("lastname", "!=", ""), - ("firstname", "=", False), - ("initials", "=", False), - ("infix", "=", False), - ("is_company", "=", False), - ] - + extra_domain, - offset, - limit, - ) - - -def process_partners(): - """Read and process partners.""" - for partner in odoo_execute("res.partner", "read", ids, field_names): - update_partner(partner) - - -while True: - ids = get_partner_ids() - if not ids: - break - process_partners() - offset += limit diff --git a/l10n_nl_partner_name/tests/test_l10n_nl_partner_name.py b/l10n_nl_partner_name/tests/test_l10n_nl_partner_name.py index c521895ef..1430afffa 100644 --- a/l10n_nl_partner_name/tests/test_l10n_nl_partner_name.py +++ b/l10n_nl_partner_name/tests/test_l10n_nl_partner_name.py @@ -11,7 +11,23 @@ def test_l10n_nl_partner_name(self): partner.firstname = "Willem-Alexander" partner.lastname = "van Oranje-Nassau" self.assertEqual(partner.name, "Willem-Alexander van Oranje-Nassau") - partner.write({"name": partner.name}) + partner.name = partner.name self.assertEqual(partner.firstname, "Willem-Alexander") - self.assertEqual(partner.lastname, "van Oranje-Nassau") + self.assertEqual(partner.infix, "van") + self.assertEqual(partner.lastname, "Oranje-Nassau") self.assertEqual(partner.name, "Willem-Alexander van Oranje-Nassau") + partner.name = "Willem Frederik (W.F.) Hermans" + self.assertEqual(partner.firstname, "Willem Frederik") + self.assertEqual(partner.infix, "") + self.assertEqual(partner.initials, "W.F.") + self.assertEqual(partner.lastname, "Hermans") + self.assertEqual(partner.name, "Willem Frederik (W.F.) Hermans") + partner.name = "Alfred J. Kwack" + self.assertEqual(partner.firstname, "Alfred") + self.assertEqual(partner.infix, "") + self.assertEqual(partner.initials, "J.") + self.assertEqual(partner.lastname, "Kwack") + partner.write({"initials": "A.J."}) + self.assertEqual(partner.name, "Alfred (A.J.) Kwack") + partner.name = "Willem-Alexander van Oranje Nassau" + self.assertEqual(partner.lastname, "Oranje Nassau") diff --git a/l10n_nl_partner_name/views/res_partner.xml b/l10n_nl_partner_name/views/res_partner.xml index dcd8bbc4d..58cef7211 100644 --- a/l10n_nl_partner_name/views/res_partner.xml +++ b/l10n_nl_partner_name/views/res_partner.xml @@ -1,102 +1,36 @@ - - res.partner.simplified.form.firstname + res.partner - + - -
-
-
- - - - - - Last name - max-width: calc(50% - 2.1em) - - - First name - max-width: calc(50% - 2.1em) - 1 - - + - +
- - res.partner.form.firstname + res.partner - + - -
-
-
- - - - - - Last name - max-width: calc(50% - 2.1em) - oe_inline - 1 - - - First name - max-width: calc(50% - 2.1em) - 1 - oe_inline - 1 - - + - + + +