diff --git a/l10n_nl_partner_name/README.rst b/l10n_nl_partner_name/README.rst new file mode 100644 index 000000000..350b2aa50 --- /dev/null +++ b/l10n_nl_partner_name/README.rst @@ -0,0 +1,38 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License: AGPL-3 + +Module Dutch Partner Name +========================= + + Use Dutch conventions for partner names: + - have infixes + - have initials + - split first and last name (provided by partner_firstname) + +Roadmap +------- + +- allow to turn on/off initials and infix separately +- add nickname (roepnaam) field to also turn on and off separately + +Contributors +------------ + +* Holger Brunn +* Ronald Portier +* George Daramouskas + +Maintainer +---------- + +.. image:: http://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: http://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit http://odoo-community.org. diff --git a/l10n_nl_partner_name/__init__.py b/l10n_nl_partner_name/__init__.py new file mode 100644 index 000000000..068613b2a --- /dev/null +++ b/l10n_nl_partner_name/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import model diff --git a/l10n_nl_partner_name/__manifest__.py b/l10n_nl_partner_name/__manifest__.py new file mode 100644 index 000000000..0e2a4e81b --- /dev/null +++ b/l10n_nl_partner_name/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2017 Therp BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +{ + 'name': 'Dutch partner names', + 'version': '12.0.1.0.0', + 'author': 'Therp BV, Odoo Community Association (OCA)', + 'category': 'Contact management', + 'depends': [ + 'partner_firstname', + ], + 'data': [ + "views/res_partner.xml", + "data/ir.config_parameter.xml", + ], + 'installable': True, + 'license': 'AGPL-3', +} diff --git a/l10n_nl_partner_name/data/ir.config_parameter.xml b/l10n_nl_partner_name/data/ir.config_parameter.xml new file mode 100644 index 000000000..d93903bf1 --- /dev/null +++ b/l10n_nl_partner_name/data/ir.config_parameter.xml @@ -0,0 +1,7 @@ + + + + partner_names_order + first_last + + diff --git a/l10n_nl_partner_name/i18n/l10n_nl_partner_name.pot b/l10n_nl_partner_name/i18n/l10n_nl_partner_name.pot new file mode 100644 index 000000000..2e5884ef4 --- /dev/null +++ b/l10n_nl_partner_name/i18n/l10n_nl_partner_name.pot @@ -0,0 +1,48 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_nl_partner_name +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: l10n_nl_partner_name +#: model:ir.model,name:l10n_nl_partner_name.model_res_partner +msgid "Contact" +msgstr "" + +#. module: l10n_nl_partner_name +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_form_firstname +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_simple_form_firstname +msgid "First name" +msgstr "" + +#. module: l10n_nl_partner_name +#: model:ir.model.fields,field_description:l10n_nl_partner_name.field_res_partner_infix +#: model:ir.model.fields,field_description:l10n_nl_partner_name.field_res_users_infix +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_form_firstname +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_simple_form_firstname +msgid "Infix" +msgstr "" + +#. module: l10n_nl_partner_name +#: model:ir.model.fields,field_description:l10n_nl_partner_name.field_res_partner_initials +#: model:ir.model.fields,field_description:l10n_nl_partner_name.field_res_users_initials +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_form_firstname +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_simple_form_firstname +msgid "Initials" +msgstr "" + +#. module: l10n_nl_partner_name +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_form_firstname +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_simple_form_firstname +msgid "Last name" +msgstr "" + diff --git a/l10n_nl_partner_name/i18n/nl.po b/l10n_nl_partner_name/i18n/nl.po new file mode 100644 index 000000000..846cd69dd --- /dev/null +++ b/l10n_nl_partner_name/i18n/nl.po @@ -0,0 +1,53 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_nl_partner_name +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2013-10-02 14:42+0000\n" +"PO-Revision-Date: 2013-10-02 14:42+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: l10n_nl_partner_name +#: model:ir.model,name:l10n_nl_partner_name.model_res_partner +msgid "Contact" +msgstr "" + +#. module: l10n_nl_partner_name +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_form_firstname +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_simple_form_firstname +msgid "First name" +msgstr "" + +#. module: l10n_nl_partner_name +#: model:ir.model.fields,field_description:l10n_nl_partner_name.field_res_partner_infix +#: model:ir.model.fields,field_description:l10n_nl_partner_name.field_res_users_infix +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_form_firstname +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_simple_form_firstname +msgid "Infix" +msgstr "Tussenvoegsel" + +#. module: l10n_nl_partner_name +#: model:ir.model.fields,field_description:l10n_nl_partner_name.field_res_partner_initials +#: model:ir.model.fields,field_description:l10n_nl_partner_name.field_res_users_initials +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_form_firstname +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_simple_form_firstname +msgid "Initials" +msgstr "Voorletters" + +#. module: l10n_nl_partner_name +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_form_firstname +#: model:ir.ui.view,arch_db:l10n_nl_partner_name.view_partner_simple_form_firstname +msgid "Last name" +msgstr "" + +#~ msgid "Partner" +#~ msgstr "Relatie" diff --git a/l10n_nl_partner_name/model/__init__.py b/l10n_nl_partner_name/model/__init__.py new file mode 100644 index 000000000..73a41f174 --- /dev/null +++ b/l10n_nl_partner_name/model/__init__.py @@ -0,0 +1,2 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from . import res_partner diff --git a/l10n_nl_partner_name/model/res_partner.py b/l10n_nl_partner_name/model/res_partner.py new file mode 100644 index 000000000..f781ac43f --- /dev/null +++ b/l10n_nl_partner_name/model/res_partner.py @@ -0,0 +1,41 @@ +# Copyright 2017 Therp BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo import models, fields, api +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.multi + @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.onchange("firstname", "lastname", "initials", "infix") + def _onchange_subnames(self): + return super(ResPartner, self)._onchange_subnames() + + @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/scripts/guess_names.py b/l10n_nl_partner_name/scripts/guess_names.py new file mode 100644 index 000000000..d921fdd6d --- /dev/null +++ b/l10n_nl_partner_name/scripts/guess_names.py @@ -0,0 +1,82 @@ +#!/usr/bin/python +# Copyright 2017 Therp BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +import argparse +import xmlrpclib +import re +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() + +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): + return odoo_socket.execute( + args.odoo_db, odoo_uid, + args.odoo_passwd, model, method, *pargs, **kwargs) + + +infixes = ['van', 'der', 'ter', 'de', 'v/d'] +initial = re.compile(r'^([A-Z]{1,3}\.{0,1}){1,4}$') + +limit = 100000 +offset = 0 + + +def add_token(values, key, token, delimiter=' '): + values[key] = (values[key] + ' ' if values[key] else '') + token + + +while True: + ids = odoo_execute( + 'res.partner', 'search', + [ + ('lastname', '!=', False), + ('lastname', '!=', ''), + ('firstname', '=', False), + ('initials', '=', False), + ('infix', '=', False), + ('is_company', '=', False), + ] + + eval(args.additional_search or '[]'), + offset, + limit) + if not ids: + break + + for partner in odoo_execute( + 'res.partner', 'read', ids, + ['lastname', 'firstname', 'initials', 'infix']): + print(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) + partner['lastname'] = ' '.join(tokens) + + print(partner) + odoo_execute('res.partner', 'write', partner['id'], partner) + + offset += limit diff --git a/l10n_nl_partner_name/static/description/icon.png b/l10n_nl_partner_name/static/description/icon.png new file mode 100644 index 000000000..48485f76e Binary files /dev/null and b/l10n_nl_partner_name/static/description/icon.png differ diff --git a/l10n_nl_partner_name/static/src/img/icon.png b/l10n_nl_partner_name/static/src/img/icon.png new file mode 100644 index 000000000..48485f76e Binary files /dev/null and b/l10n_nl_partner_name/static/src/img/icon.png differ diff --git a/l10n_nl_partner_name/tests/__init__.py b/l10n_nl_partner_name/tests/__init__.py new file mode 100644 index 000000000..ddf925ff7 --- /dev/null +++ b/l10n_nl_partner_name/tests/__init__.py @@ -0,0 +1 @@ +from . import test_l10n_nl_partner_name 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 new file mode 100644 index 000000000..fe1809751 --- /dev/null +++ b/l10n_nl_partner_name/tests/test_l10n_nl_partner_name.py @@ -0,0 +1,29 @@ +# Copyright 2016 Therp BV +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from odoo.tests.common import TransactionCase + + +class TestL10nNlPartnerName(TransactionCase): + + def test_l10n_nl_partner_name(self): + partner = self.env['res.partner'].create({ + 'name': 'Mark Rutte', + }) + self.assertEqual(partner.firstname, 'Mark') + self.assertEqual(partner.lastname, 'Rutte') + partner.firstname = 'Willem-Alexander' + partner.lastname = 'van Oranje-Nassau' + self.assertEqual( + partner.name, + 'Willem-Alexander van Oranje-Nassau' + ) + partner.write({ + 'name': partner.name, + }) + self.assertEqual(partner.firstname, 'Willem-Alexander') + self.assertEqual(partner.lastname, 'van Oranje-Nassau') + partner._onchange_subnames() + self.assertEqual( + partner.name, + 'Willem-Alexander van Oranje-Nassau' + ) diff --git a/l10n_nl_partner_name/views/res_partner.xml b/l10n_nl_partner_name/views/res_partner.xml new file mode 100644 index 000000000..4f3256a0c --- /dev/null +++ b/l10n_nl_partner_name/views/res_partner.xml @@ -0,0 +1,76 @@ + + + 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 + + + + + + + + + + + +
+
+
diff --git a/oca_dependencies.txt b/oca_dependencies.txt index a9935f91c..bde2ce356 100644 --- a/oca_dependencies.txt +++ b/oca_dependencies.txt @@ -1,3 +1,4 @@ account-financial-reporting +partner-contact server-ux partner-contact