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

[IMP] partner_firstname: compatible with standard sql constraint #1889

Closed
wants to merge 2 commits into from
Closed
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
69 changes: 41 additions & 28 deletions partner_firstname/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,38 +44,46 @@ def create(self, vals_list):
it's not appropriate, we must call `create` for each partner individually with
the correct context.
"""
created_partners = self.browse()

for vals in vals_list:
partner_context = dict(self.env.context)
if (
not vals.get("is_company")
and self.name_fields_in_vals(vals)
and "name" in vals
):
del vals["name"]
partner_context.pop("default_name", None)
is_company = vals.get(
"is_company", self.default_get(["is_company"])["is_company"]
)

compute_name = False
if self.name_fields_in_vals(vals):
compute_name = self._get_computed_name_create(vals)

if is_company:
if "name" in vals:
# name is leading
vals["name"] = self._get_whitespace_cleaned_name(vals["name"])
vals["lastname"] = vals["name"]

vals["firstname"] = False
elif compute_name:
# fallback to lastname when name missing
vals["name"] = compute_name
vals["lastname"] = compute_name
vals["firstname"] = False
else:
name = vals.get("name", partner_context.get("default_name"))
if name is not None:
name = vals.get("name", self.env.context.get("default_name"))
if compute_name:
vals["name"] = compute_name
# overwrite firstname/lastname with name
elif name is not None:
# Calculate the split fields
inverted = self._get_inverse_name(
self._get_whitespace_cleaned_name(name),
vals.get(
"is_company", self.default_get(["is_company"])["is_company"]
),
is_company,
)
for key, value in inverted.items():
if not vals.get(key) or partner_context.get("copy"):
if not vals.get(key):
vals[key] = value

# Remove the combined fields
vals.pop("name", None)
partner_context.pop("default_name", None)
# pylint: disable=W8121
created_partners |= super(
ResPartner, self.with_context(partner_context)
).create([vals])
return created_partners
return super(ResPartner, self.with_context(no_inverse_name=True)).create(
vals_list
)

def get_extra_default_copy_values(self, order):
"""Method to add '(copy)' suffix to lastname or firstname, depending on name
Expand Down Expand Up @@ -105,7 +113,7 @@ def copy(self, default=None):
order = self._get_names_order()
extra_default_values = self.get_extra_default_copy_values(order)
default.update(extra_default_values)
return super(ResPartner, self.with_context(copy=True)).copy(default)
return super().copy(default)

@api.model
def default_get(self, fields_list):
Expand Down Expand Up @@ -142,6 +150,13 @@ def _get_names_order(self):
.get_param("partner_names_order", self._names_order_default())
)

@api.model
def _get_computed_name_create(self, vals):
return self._get_computed_name(
self._get_whitespace_cleaned_name(vals.get("lastname")),
self._get_whitespace_cleaned_name(vals.get("firstname")),
)

@api.model
def _get_computed_name(self, lastname, firstname):
"""Compute the 'name' field according to splitted data.
Expand All @@ -167,6 +182,8 @@ def _inverse_name_after_cleaning_whitespace(self):
The splitting logic is stored separately in :meth:`~._inverse_name`, so
submodules can extend that method and get whitespace cleaning for free.
"""
if self.env.context.get("no_inverse_name"):
return
for record in self:
# Remove unneeded whitespace
clean = record._get_whitespace_cleaned_name(record.name)
Expand Down Expand Up @@ -268,7 +285,3 @@ def _install_partner_firstname(self):
# Force calculations there
records._inverse_name()
_logger.info("%d partners updated installing module.", len(records))

# Disabling SQL constraint givint a more explicit error using a Python
# contstraint
_sql_constraints = [("check_name", "CHECK( 1=1 )", "Contacts require a name.")]
2 changes: 1 addition & 1 deletion partner_firstname/tests/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def tearDown(self):
def test_copy(self):
"""Copy the partner and compare the result."""
self.expect("%s (copy)" % self.lastname, self.firstname)
self.changed = self.original.with_context(copy=True, lang="en_US").copy()
self.changed = self.original.with_context(lang="en_US").copy()

def test_one_name(self):
"""Test what happens when only one name is given."""
Expand Down
6 changes: 6 additions & 0 deletions partner_firstname/tests/test_create.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ def setUp(self):
self.good_values.update(lastname=self.values["name"], firstname=False)
self.values = self.good_values.copy()

def test_wrong_name_value(self):
"""Name for company is taken."""

def test_wrong_name_value_and_context(self):
"""Name for company is taken, defaults are ignored"""


class UserCase(PersonCase, MailInstalled):
"""Test ``res.users``."""
Expand Down
7 changes: 4 additions & 3 deletions partner_firstname/tests/test_empty.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@

To have more accurate results, remove the ``mail`` module before testing.
"""
import psycopg2

from odoo.tests.common import TransactionCase

from .. import exceptions as ex
from .base import MailInstalled


Expand All @@ -19,9 +20,9 @@ class CompanyCase(TransactionCase):

def tearDown(self):
try:
data = {"name": self.name}
data = {"name": False}
model = self.env[self.model].with_context(**self.context)
with self.assertRaises(ex.EmptyNamesError):
with self.assertRaises(psycopg2.errors.CheckViolation):
model.create(data)
finally:
super().tearDown()
Expand Down
8 changes: 8 additions & 0 deletions partner_second_lastname/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ def get_extra_default_copy_values(self, order):
}
return super().get_extra_default_copy_values(order)

@api.model
def _get_computed_name_create(self, vals):
return self._get_computed_name(
self._get_whitespace_cleaned_name(vals.get("lastname")),
self._get_whitespace_cleaned_name(vals.get("firstname")),
self._get_whitespace_cleaned_name(vals.get("lastname2")),
)

@api.model
def _get_computed_name(self, lastname, firstname, lastname2=None):
"""Compute the name combined with the second lastname too.
Expand Down
Loading