From 353c84ecd356fd28e3bcc5a925c922b6de16d4b8 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Fri, 15 May 2015 13:59:59 +0200 Subject: [PATCH 01/20] Prepare partner_firstname for partner_second_lastname --- partner_firstname/__openerp__.py | 3 ++- partner_firstname/exceptions.py | 3 +-- partner_firstname/models.py | 7 ++++--- partner_firstname/tests/test_empty.py | 3 +-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/partner_firstname/__openerp__.py b/partner_firstname/__openerp__.py index 57ad3366f..4b8d9ce9e 100644 --- a/partner_firstname/__openerp__.py +++ b/partner_firstname/__openerp__.py @@ -22,7 +22,8 @@ 'name': 'Partner first name and last name', 'summary': "Split first name and last name for non company partners", 'version': '8.0.2.0.0', - 'author': "Camptocamp,Odoo Community Association (OCA)", + 'author': "Camptocamp, Odoo Community Association (OCA)", + "license": "AGPL-3", 'maintainer': 'Camptocamp, Acsone', 'category': 'Extra Tools', 'website': 'http://www.camptocamp.com, http://www.acsone.eu', diff --git a/partner_firstname/exceptions.py b/partner_firstname/exceptions.py index 99d5b630e..a75429514 100644 --- a/partner_firstname/exceptions.py +++ b/partner_firstname/exceptions.py @@ -1,5 +1,4 @@ -# -*- encoding: utf-8 -*- - +# -*- coding: utf-8 -*- # Odoo, Open Source Management Solution # Copyright (C) 2014-2015 Grupo ESOC # diff --git a/partner_firstname/models.py b/partner_firstname/models.py index 47f6f7e0f..346c7032e 100644 --- a/partner_firstname/models.py +++ b/partner_firstname/models.py @@ -73,7 +73,7 @@ class ResPartner(models.Model): @api.model def _get_inverse_name(self, name, is_company=False): - """Try to revert the effect of :meth:`._compute_name`. + """Compute the inverted name. - If the partner is a company, save it in the lastname. - Otherwise, make a guess. @@ -93,12 +93,13 @@ class ResPartner(models.Model): parts = name.split(" ", 1) while len(parts) < 2: parts.append(False) - return parts + return {"lastname": parts[0], "firstname": parts[1]} @api.one def _inverse_name(self): + """Try to revert the effect of :meth:`._compute_name`.""" parts = self._get_inverse_name(self.name, self.is_company) - self.lastname, self.firstname = parts + self.lastname, self.firstname = parts["lastname"], parts["firstname"] @api.one @api.constrains("firstname", "lastname") diff --git a/partner_firstname/tests/test_empty.py b/partner_firstname/tests/test_empty.py index 280ed9e92..168d987a5 100644 --- a/partner_firstname/tests/test_empty.py +++ b/partner_firstname/tests/test_empty.py @@ -1,5 +1,4 @@ -# -*- encoding: utf-8 -*- - +# -*- coding: utf-8 -*- # Odoo, Open Source Management Solution # Copyright (C) 2014-2015 Grupo ESOC # From eae67168f2ab8599c271801bc84e0b25c38ae8b6 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Fri, 30 Oct 2015 12:11:06 +0100 Subject: [PATCH 02/20] Fix #78. Test it too. --- partner_firstname/models.py | 15 ++++++ partner_firstname/tests/__init__.py | 2 +- partner_firstname/tests/test_defaults.py | 65 ++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 partner_firstname/tests/test_defaults.py diff --git a/partner_firstname/models.py b/partner_firstname/models.py index 346c7032e..39836e712 100644 --- a/partner_firstname/models.py +++ b/partner_firstname/models.py @@ -38,6 +38,21 @@ class ResPartner(models.Model): required=False, store=True) + @api.model + def default_get(self, fields_list): + """Invert name when getting default values.""" + result = super(ResPartner, self).default_get(fields_list) + + inverted = self._get_inverse_name( + result.get("name", ""), + result.get("is_company", False)) + + for field in inverted.keys(): + if field in fields_list: + result[field] = inverted.get(field) + + return result + @api.model def _get_computed_name(self, lastname, firstname): """Compute the 'name' field according to splitted data. diff --git a/partner_firstname/tests/__init__.py b/partner_firstname/tests/__init__.py index 7dfc1f9cc..239670f65 100644 --- a/partner_firstname/tests/__init__.py +++ b/partner_firstname/tests/__init__.py @@ -28,4 +28,4 @@ # ############################################################################## -from . import test_empty, test_name, test_onchange +from . import test_defaults, test_empty, test_name, test_onchange diff --git a/partner_firstname/tests/test_defaults.py b/partner_firstname/tests/test_defaults.py new file mode 100644 index 000000000..ab6c3a969 --- /dev/null +++ b/partner_firstname/tests/test_defaults.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# © 2015 Grupo ESOC Ingeniería de Servicios, S.L. - Jairo Llopis. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +"""Test default values for models.""" + +from openerp.tests.common import TransactionCase +from .base import MailInstalled + + +class PersonCase(TransactionCase): + """Test ``res.partner`` when it is a person.""" + context = {"default_is_company": False} + model = "res.partner" + + def setUp(self): + super(PersonCase, self).setUp() + self.values = { + "firstname": u"Núñez", + "lastname": u"Fernán", + } + self.values["name"] = "%s %s" % (self.values["lastname"], + self.values["firstname"]) + if "default_is_company" in self.context: + self.values["is_company"] = self.context["default_is_company"] + + def tearDown(self): + for key, value in self.values.iteritems(): + self.assertEqual( + self.defaults.get(key), + value, + "Checking key %s" % key) + + return super(PersonCase, self).tearDown() + + def test_default_get(self): + """Getting default values for fields includes new fields.""" + self.defaults = (self.env[self.model] + .with_context(self.context, + default_name=self.values["name"]) + .default_get(self.values.keys())) + + +class CompanyCase(PersonCase): + """Test ``res.partner`` when it is a company.""" + context = {"default_is_company": True} + + def tearDown(self): + self.values.update(lastname=self.values["name"], firstname=False) + return super(CompanyCase, self).tearDown() + + +class UserCase(PersonCase, MailInstalled): + """Test ``res.users``.""" + model = "res.users" + context = {"default_login": "user@example.com"} + + def tearDown(self): + # Cannot create users if ``mail`` is installed + if self.mail_installed(): + # Skip tests + super(PersonCase, self).tearDown() + else: + # Run tests + super(UserCase, self).tearDown() From 3b6ff052d55959e0c4d69bd7088753befa8a557f Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Fri, 30 Oct 2015 12:53:16 +0100 Subject: [PATCH 03/20] Inverse values of name if required at creation. --- partner_firstname/models.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/partner_firstname/models.py b/partner_firstname/models.py index 39836e712..48342b20d 100644 --- a/partner_firstname/models.py +++ b/partner_firstname/models.py @@ -38,6 +38,21 @@ class ResPartner(models.Model): required=False, store=True) + @api.model + def create(self, vals): + """Add inverted names at creation if unavailable.""" + if "name" in vals: + inverted = self._get_inverse_name( + vals.get("name"), + vals.get("is_company", + self.default_get(["is_company"])["is_company"])) + + for key, value in inverted.iteritems(): + if not vals.get(key): + vals[key] = value + + return super(ResPartner, self).create(vals) + @api.model def default_get(self, fields_list): """Invert name when getting default values.""" From 6b194f31817b24ce15a640aa37cbf010d5dd9434 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Mon, 2 Nov 2015 11:36:49 +0100 Subject: [PATCH 04/20] Allow creation of partners from *Create and Edit*. This fixes #78 and adds new tests for it. --- partner_firstname/__openerp__.py | 4 +- partner_firstname/models.py | 42 ++++++++++--- partner_firstname/tests/__init__.py | 3 +- partner_firstname/tests/base.py | 2 +- partner_firstname/tests/test_create.py | 81 ++++++++++++++++++++++++++ 5 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 partner_firstname/tests/test_create.py diff --git a/partner_firstname/__openerp__.py b/partner_firstname/__openerp__.py index 4b8d9ce9e..463b01c97 100644 --- a/partner_firstname/__openerp__.py +++ b/partner_firstname/__openerp__.py @@ -21,8 +21,8 @@ { 'name': 'Partner first name and last name', 'summary': "Split first name and last name for non company partners", - 'version': '8.0.2.0.0', - 'author': "Camptocamp, Odoo Community Association (OCA)", + 'version': '8.0.2.0.1', + 'author': "Camptocamp, Grupo ESOC, Odoo Community Association (OCA)", "license": "AGPL-3", 'maintainer': 'Camptocamp, Acsone', 'category': 'Extra Tools', diff --git a/partner_firstname/models.py b/partner_firstname/models.py index 48342b20d..4500e478d 100644 --- a/partner_firstname/models.py +++ b/partner_firstname/models.py @@ -41,17 +41,37 @@ class ResPartner(models.Model): @api.model def create(self, vals): """Add inverted names at creation if unavailable.""" - if "name" in vals: + context = dict(self.env.context) + name = vals.get("name", context.get("default_name")) + + if name is not None: + # Calculate the splitted fields inverted = self._get_inverse_name( - vals.get("name"), + self._get_whitespace_cleaned_name(name), vals.get("is_company", self.default_get(["is_company"])["is_company"])) for key, value in inverted.iteritems(): - if not vals.get(key): + if not vals.get(key) or context.get("copy"): vals[key] = value - return super(ResPartner, self).create(vals) + # Remove the combined fields + if "name" in vals: + del vals["name"] + if "default_name" in context: + del context["default_name"] + + return super(ResPartner, self.with_context(context)).create(vals) + + @api.multi + def copy(self, default=None): + """Ensure partners are copied right. + + Odoo adds ``(copy)`` to the end of :attr:`~.name`, but that would get + ignored in :meth:`~.create` because it also copies explicitly firstname + and lastname fields. + """ + return super(ResPartner, self.with_context(copy=True)).copy(default) @api.model def default_get(self, fields_list): @@ -59,7 +79,7 @@ class ResPartner(models.Model): result = super(ResPartner, self).default_get(fields_list) inverted = self._get_inverse_name( - result.get("name", ""), + self._get_whitespace_cleaned_name(result.get("name", "")), result.get("is_company", False)) for field in inverted.keys(): @@ -85,13 +105,11 @@ class ResPartner(models.Model): def _inverse_name_after_cleaning_whitespace(self): """Clean whitespace in :attr:`~.name` and split it. - Removes leading, trailing and duplicated whitespace. - The splitting logic is stored separately in :meth:`~._inverse_name`, so submodules can extend that method and get whitespace cleaning for free. """ # Remove unneeded whitespace - clean = u" ".join(self.name.split(None)) if self.name else self.name + clean = self._get_whitespace_cleaned_name(self.name) # Clean name avoiding infinite recursion if self.name != clean: @@ -101,6 +119,14 @@ class ResPartner(models.Model): else: self._inverse_name() + @api.model + def _get_whitespace_cleaned_name(self, name): + """Remove redundant whitespace from :param:`name`. + + Removes leading, trailing and duplicated whitespace. + """ + return u" ".join(name.split(None)) if name else name + @api.model def _get_inverse_name(self, name, is_company=False): """Compute the inverted name. diff --git a/partner_firstname/tests/__init__.py b/partner_firstname/tests/__init__.py index 239670f65..2bdf39b05 100644 --- a/partner_firstname/tests/__init__.py +++ b/partner_firstname/tests/__init__.py @@ -3,6 +3,7 @@ # # Authors: Nemry Jonathan # Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) +# 2015: Grupo ESOC # All Rights Reserved # # WARNING: This program as such is intended to be used by professional @@ -28,4 +29,4 @@ # ############################################################################## -from . import test_defaults, test_empty, test_name, test_onchange +from . import test_create, test_defaults, test_empty, test_name, test_onchange diff --git a/partner_firstname/tests/base.py b/partner_firstname/tests/base.py index 85e204435..68020d3bf 100644 --- a/partner_firstname/tests/base.py +++ b/partner_firstname/tests/base.py @@ -71,7 +71,7 @@ class BaseCase(TransactionCase, MailInstalled): def test_copy(self): """Copy the partner and compare the result.""" self.expect(self.lastname, u"%s (copy)" % self.firstname) - self.changed = self.original.with_context(lang="en_US").copy() + self.changed = self.original.with_context(copy=True, lang="en_US").copy() def test_one_name(self): """Test what happens when only one name is given.""" diff --git a/partner_firstname/tests/test_create.py b/partner_firstname/tests/test_create.py new file mode 100644 index 000000000..6ffe373ac --- /dev/null +++ b/partner_firstname/tests/test_create.py @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +# © 2015 Grupo ESOC Ingeniería de Servicios, S.L. - Jairo Llopis. +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +"""Test default values for models.""" + +from openerp.tests.common import TransactionCase +from .base import MailInstalled + + +class PersonCase(TransactionCase): + """Test ``res.partner`` when it is a person.""" + context = {"default_is_company": False} + model = "res.partner" + + def setUp(self): + super(PersonCase, self).setUp() + self.good_values = { + "firstname": u"Núñez", + "lastname": u"Fernán", + } + self.good_values["name"] = "%s %s" % (self.good_values["lastname"], + self.good_values["firstname"]) + if "default_is_company" in self.context: + self.good_values["is_company"] = self.context["default_is_company"] + self.values = self.good_values.copy() + + def tearDown(self): + self.record = (self.env[self.model] + .with_context(self.context) + .create(self.values)) + + for key, value in self.good_values.iteritems(): + self.assertEqual( + self.record[key], + value, + "Checking key %s" % key) + + super(PersonCase, self).tearDown() + + def test_no_name(self): + """Name is calculated.""" + del self.values["name"] + + def test_wrong_name_value(self): + """Wrong name value is ignored, name is calculated.""" + self.values["name"] = u"BÄD" + + def test_wrong_name_context(self): + """Wrong name context is ignored, name is calculated.""" + del self.values["name"] + self.context["default_name"] = u"BÄD" + + def test_wrong_name_value_and_context(self): + """Wrong name value and context is ignored, name is calculated.""" + self.values["name"] = u"BÄD1" + self.context["default_name"] = u"BÄD2" + + +class CompanyCase(PersonCase): + """Test ``res.partner`` when it is a company.""" + context = {"default_is_company": True} + + def setUp(self): + return super(CompanyCase, self).setUp() + self.values.update(lastname=self.values["name"], firstname=False) + + +class UserCase(PersonCase, MailInstalled): + """Test ``res.users``.""" + model = "res.users" + context = {"default_login": "user@example.com"} + + def tearDown(self): + # Cannot create users if ``mail`` is installed + if self.mail_installed(): + # Skip tests + super(PersonCase, self).tearDown() + else: + # Run tests + super(UserCase, self).tearDown() From e7fe07072fc0d25c99e907f56fe6b541053f82a0 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Mon, 7 Sep 2015 13:56:10 +0200 Subject: [PATCH 05/20] Fix bug #154. Conflicts: partner_firstname/__openerp__.py partner_firstname/tests/__init__.py --- partner_firstname/__openerp__.py | 4 +-- partner_firstname/models.py | 3 +- partner_firstname/tests/__init__.py | 9 +++++- partner_firstname/tests/test_delete.py | 39 ++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 partner_firstname/tests/test_delete.py diff --git a/partner_firstname/__openerp__.py b/partner_firstname/__openerp__.py index 463b01c97..61c0ac2b4 100644 --- a/partner_firstname/__openerp__.py +++ b/partner_firstname/__openerp__.py @@ -21,8 +21,8 @@ { 'name': 'Partner first name and last name', 'summary': "Split first name and last name for non company partners", - 'version': '8.0.2.0.1', - 'author': "Camptocamp, Grupo ESOC, Odoo Community Association (OCA)", + 'version': '8.0.2.1.0', + 'author': "Camptocamp,Odoo Community Association (OCA)", "license": "AGPL-3", 'maintainer': 'Camptocamp, Acsone', 'category': 'Extra Tools', diff --git a/partner_firstname/models.py b/partner_firstname/models.py index 4500e478d..eab2b1352 100644 --- a/partner_firstname/models.py +++ b/partner_firstname/models.py @@ -99,7 +99,8 @@ class ResPartner(models.Model): @api.depends("firstname", "lastname") def _compute_name(self): """Write the 'name' field according to splitted data.""" - self.name = self._get_computed_name(self.lastname, self.firstname) + if self.exists(): + self.name = self._get_computed_name(self.lastname, self.firstname) @api.one def _inverse_name_after_cleaning_whitespace(self): diff --git a/partner_firstname/tests/__init__.py b/partner_firstname/tests/__init__.py index 2bdf39b05..69104a4e4 100644 --- a/partner_firstname/tests/__init__.py +++ b/partner_firstname/tests/__init__.py @@ -29,4 +29,11 @@ # ############################################################################## -from . import test_create, test_defaults, test_empty, test_name, test_onchange +from . import ( + test_create, + test_defaults, + test_delete, + test_empty, + test_name, + test_onchange +) diff --git a/partner_firstname/tests/test_delete.py b/partner_firstname/tests/test_delete.py new file mode 100644 index 000000000..e31a3f44f --- /dev/null +++ b/partner_firstname/tests/test_delete.py @@ -0,0 +1,39 @@ +# -*- coding: utf-8 -*- +# © 2015 Grupo ESOC +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from openerp.tests.common import TransactionCase +from .base import MailInstalled +from .. import exceptions as ex + + +class CompanyCase(TransactionCase): + model = "res.partner" + context = {"default_is_company": True} + + def test_computing_after_unlink(self): + """Test what happens if recomputed after unlinking. + + This test might seem useless, but really this happens when module + ``partner_relations`` is installed. + + See https://github.com/OCA/partner-contact/issues/154. + """ + data = {"name": u"Söme name"} + record = self.env[self.model].with_context(**self.context).create(data) + record.unlink() + record.recompute() + + +class PersonCase(CompanyCase): + context = {"default_is_company": False} + + +class UserCase(CompanyCase, MailInstalled): + model = "res.users" + context = {"default_login": "user@example.com"} + + def test_computing_after_unlink(self): + # Cannot create users if ``mail`` is installed + if not self.mail_installed(): + super(UserCase, self).test_computing_after_unlink() From 2d8bf9b5b3a1223bde28386caf3c47e6f8a1c03a Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Tue, 8 Sep 2015 13:22:14 +0200 Subject: [PATCH 06/20] Fix flake8 error --- partner_firstname/__openerp__.py | 7 ++++--- partner_firstname/tests/test_delete.py | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/partner_firstname/__openerp__.py b/partner_firstname/__openerp__.py index 61c0ac2b4..f3b6e51c3 100644 --- a/partner_firstname/__openerp__.py +++ b/partner_firstname/__openerp__.py @@ -21,12 +21,13 @@ { 'name': 'Partner first name and last name', 'summary': "Split first name and last name for non company partners", - 'version': '8.0.2.1.0', - 'author': "Camptocamp,Odoo Community Association (OCA)", + 'version': '8.0.2.1.1', + 'author': "Camptocamp, Grupo ESOC, Odoo Community Association (OCA)", "license": "AGPL-3", 'maintainer': 'Camptocamp, Acsone', 'category': 'Extra Tools', - 'website': 'http://www.camptocamp.com, http://www.acsone.eu', + 'website': + 'http://www.camptocamp.com, http://www.acsone.eu, http://grupoesoc.es', 'depends': ['base'], 'data': [ 'views/res_partner.xml', diff --git a/partner_firstname/tests/test_delete.py b/partner_firstname/tests/test_delete.py index e31a3f44f..0729502f1 100644 --- a/partner_firstname/tests/test_delete.py +++ b/partner_firstname/tests/test_delete.py @@ -4,7 +4,6 @@ from openerp.tests.common import TransactionCase from .base import MailInstalled -from .. import exceptions as ex class CompanyCase(TransactionCase): From 21c63b426134d283fcb05ad4f39f4b2650fc392f Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Wed, 9 Sep 2015 10:24:18 +0200 Subject: [PATCH 07/20] After all, this was just a workaround. Remove it. The real fix was in #171. I leave the tests. --- partner_firstname/__openerp__.py | 2 +- partner_firstname/models.py | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/partner_firstname/__openerp__.py b/partner_firstname/__openerp__.py index f3b6e51c3..d8c109ae6 100644 --- a/partner_firstname/__openerp__.py +++ b/partner_firstname/__openerp__.py @@ -21,7 +21,7 @@ { 'name': 'Partner first name and last name', 'summary': "Split first name and last name for non company partners", - 'version': '8.0.2.1.1', + 'version': '8.0.2.1.0', 'author': "Camptocamp, Grupo ESOC, Odoo Community Association (OCA)", "license": "AGPL-3", 'maintainer': 'Camptocamp, Acsone', diff --git a/partner_firstname/models.py b/partner_firstname/models.py index eab2b1352..4500e478d 100644 --- a/partner_firstname/models.py +++ b/partner_firstname/models.py @@ -99,8 +99,7 @@ class ResPartner(models.Model): @api.depends("firstname", "lastname") def _compute_name(self): """Write the 'name' field according to splitted data.""" - if self.exists(): - self.name = self._get_computed_name(self.lastname, self.firstname) + self.name = self._get_computed_name(self.lastname, self.firstname) @api.one def _inverse_name_after_cleaning_whitespace(self): From 24f15fa8c2fb1b9683fb9340079ef05602924d09 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Tue, 3 Nov 2015 09:12:40 +0100 Subject: [PATCH 08/20] Fix test that was having sentences after return. --- partner_firstname/tests/test_create.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/partner_firstname/tests/test_create.py b/partner_firstname/tests/test_create.py index 6ffe373ac..8f3e06a7f 100644 --- a/partner_firstname/tests/test_create.py +++ b/partner_firstname/tests/test_create.py @@ -62,8 +62,9 @@ class CompanyCase(PersonCase): context = {"default_is_company": True} def setUp(self): - return super(CompanyCase, self).setUp() - self.values.update(lastname=self.values["name"], firstname=False) + super(CompanyCase, self).setUp() + self.good_values.update(lastname=self.values["name"], firstname=False) + self.values = self.good_values.copy() class UserCase(PersonCase, MailInstalled): From df754ec2a173207b5c7f87169e25e4086c4865b9 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Tue, 3 Nov 2015 09:13:50 +0100 Subject: [PATCH 09/20] PEP8 fix. --- partner_firstname/tests/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/partner_firstname/tests/base.py b/partner_firstname/tests/base.py index 68020d3bf..2ca475620 100644 --- a/partner_firstname/tests/base.py +++ b/partner_firstname/tests/base.py @@ -71,7 +71,8 @@ class BaseCase(TransactionCase, MailInstalled): def test_copy(self): """Copy the partner and compare the result.""" self.expect(self.lastname, u"%s (copy)" % self.firstname) - self.changed = self.original.with_context(copy=True, lang="en_US").copy() + self.changed = (self.original.with_context(copy=True, lang="en_US") + .copy()) def test_one_name(self): """Test what happens when only one name is given.""" From 50498ce5efddf46ba15c1d8c81fa09808b468f07 Mon Sep 17 00:00:00 2001 From: David Beal Date: Thu, 20 Aug 2015 15:51:01 +0200 Subject: [PATCH 10/20] [FIX] _get_inverse_name in case of space in name --- partner_firstname/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/partner_firstname/models.py b/partner_firstname/models.py index 4500e478d..fe2b5aa09 100644 --- a/partner_firstname/models.py +++ b/partner_firstname/models.py @@ -146,7 +146,7 @@ class ResPartner(models.Model): parts = [name or False, False] # Guess name splitting else: - parts = name.split(" ", 1) + parts = name.strip().split(" ", 1) while len(parts) < 2: parts.append(False) return {"lastname": parts[0], "firstname": parts[1]} From 9477c44e7ec24317c6a20df3e65ab106d4e579e4 Mon Sep 17 00:00:00 2001 From: Jairo Llopis Date: Tue, 5 Jan 2016 10:29:25 +0100 Subject: [PATCH 11/20] Credit creators, using same name across modules to avoid split statistics. Conflicts: partner_contact_gender/__openerp__.py --- partner_firstname/__openerp__.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/partner_firstname/__openerp__.py b/partner_firstname/__openerp__.py index d8c109ae6..6d8517cee 100644 --- a/partner_firstname/__openerp__.py +++ b/partner_firstname/__openerp__.py @@ -22,7 +22,9 @@ 'name': 'Partner first name and last name', 'summary': "Split first name and last name for non company partners", 'version': '8.0.2.1.0', - 'author': "Camptocamp, Grupo ESOC, Odoo Community Association (OCA)", + "author": "Camptocamp, " + "Grupo ESOC Ingeniería de Servicios, " + "Odoo Community Association (OCA)", "license": "AGPL-3", 'maintainer': 'Camptocamp, Acsone', 'category': 'Extra Tools', From efb51adf4d1f3799f76672e763d5ca8d14251a79 Mon Sep 17 00:00:00 2001 From: Yannick Vaucher Date: Tue, 12 Jan 2016 16:35:28 +0100 Subject: [PATCH 12/20] [PORT] partner_firstname to 9.0 - add missing authors - use reduced license header - move models in models directory - adapt views - show firstname, lastname only in edit mode - use company_type in views instead of is_company - adapt constraint on contacts --- partner_firstname/README.rst | 17 +++++ partner_firstname/__init__.py | 21 +----- partner_firstname/__openerp__.py | 28 ++------ partner_firstname/exceptions.py | 18 +----- partner_firstname/models/__init__.py | 4 ++ .../{models.py => models/partner.py} | 34 ++++------ partner_firstname/views/res_partner.xml | 64 ++++++++----------- partner_firstname/views/res_user.xml | 2 +- 8 files changed, 73 insertions(+), 115 deletions(-) create mode 100644 partner_firstname/models/__init__.py rename partner_firstname/{models.py => models/partner.py} (87%) diff --git a/partner_firstname/README.rst b/partner_firstname/README.rst index 5602d35ee..7c9bf10e9 100644 --- a/partner_firstname/README.rst +++ b/partner_firstname/README.rst @@ -39,11 +39,28 @@ Contributors ------------ * Nicolas Bessi +* Yannick Vaucher +* Vincent Renaville +* Guewen Baconnier +* Holger Brunn * Jonathan Nemry * Olivier Laurent +* Sandy Carter +* Alexis de Lattre +* Lorenzo Battistini * Hans Henrik Gabelgaard * Jairo Llopis * Adrien Peiffer +* Ronald Portier +* Sylvain Van Hoof +* Pedro Baeza + +Translations +------------ + +* Danish: Hans Henrik Gabelgaard +* Italian: Leonardo Donelli +* Spanish: Antonio Espinosa Maintainer ---------- diff --git a/partner_firstname/__init__.py b/partner_firstname/__init__.py index 4cdd79b3f..8a9bba4af 100644 --- a/partner_firstname/__init__.py +++ b/partner_firstname/__init__.py @@ -1,21 +1,4 @@ # -*- coding: utf-8 -*- - -# Author: Nicolas Bessi. Copyright Camptocamp SA -# Copyright (C) -# 2014: Agile Business Group () -# 2015: Grupo ESOC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - +# © 2013 Nicolas Bessi (Camptocamp SA) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from . import models diff --git a/partner_firstname/__openerp__.py b/partner_firstname/__openerp__.py index 6d8517cee..a308f30ac 100644 --- a/partner_firstname/__openerp__.py +++ b/partner_firstname/__openerp__.py @@ -1,28 +1,14 @@ # -*- coding: utf-8 -*- - -# Author: Nicolas Bessi. Copyright Camptocamp SA -# Copyright (C) -# 2014: Agile Business Group () -# 2015: Grupo ESOC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . +# © 2013 Nicolas Bessi (Camptocamp SA) +# © 2014 Agile Business Group () +# © 2015 Grupo ESOC () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { 'name': 'Partner first name and last name', 'summary': "Split first name and last name for non company partners", - 'version': '8.0.2.1.0', - "author": "Camptocamp, " + 'version': '9.0.1.0.0', + 'author': "Camptocamp, " "Grupo ESOC Ingeniería de Servicios, " "Odoo Community Association (OCA)", "license": "AGPL-3", @@ -39,6 +25,6 @@ 'demo': [], 'test': [], 'auto_install': False, - 'installable': False, + 'installable': True, 'images': [] } diff --git a/partner_firstname/exceptions.py b/partner_firstname/exceptions.py index a75429514..d2fdea566 100644 --- a/partner_firstname/exceptions.py +++ b/partner_firstname/exceptions.py @@ -1,20 +1,6 @@ # -*- coding: utf-8 -*- -# Odoo, Open Source Management Solution -# Copyright (C) 2014-2015 Grupo ESOC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - +# © 2014-2015 Grupo ESOC () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from openerp import _, exceptions diff --git a/partner_firstname/models/__init__.py b/partner_firstname/models/__init__.py new file mode 100644 index 000000000..4e1de1d72 --- /dev/null +++ b/partner_firstname/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# © 2013 Nicolas Bessi (Camptocamp SA) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from . import partner diff --git a/partner_firstname/models.py b/partner_firstname/models/partner.py similarity index 87% rename from partner_firstname/models.py rename to partner_firstname/models/partner.py index fe2b5aa09..3c8c87645 100644 --- a/partner_firstname/models.py +++ b/partner_firstname/models/partner.py @@ -1,26 +1,11 @@ # -*- coding: utf-8 -*- - -# Author: Nicolas Bessi. Copyright Camptocamp SA -# Copyright (C) -# 2014: Agile Business Group () -# 2015: Grupo ESOC -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . - +# © 2013 Nicolas Bessi (Camptocamp SA) +# © 2014 Agile Business Group () +# © 2015 Grupo ESOC () +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). import logging from openerp import api, fields, models -from . import exceptions +from .. import exceptions _logger = logging.getLogger(__name__) @@ -202,3 +187,12 @@ class ResPartner(models.Model): # Force calculations there records._inverse_name() _logger.info("%d partners updated installing module.", len(records)) + + # As name is computed after sql_constraint check, we modify it to accept + # to write when at least one name field is filled + _sql_constraints = [ + ('check_name', + "CHECK( (type='contact' AND (name IS NOT NULL OR" + " firstname IS NOT NULL OR lastname IS NOT NULL)) or" + " (type!='contact') )", 'Contacts require a name.'), + ] diff --git a/partner_firstname/views/res_partner.xml b/partner_firstname/views/res_partner.xml index 0838628eb..85c269613 100644 --- a/partner_firstname/views/res_partner.xml +++ b/partner_firstname/views/res_partner.xml @@ -15,7 +15,7 @@ } - + - - - - - - - - +
- -