diff --git a/partner_firstname/models.py b/partner_firstname/models.py index 96c0876e0..c63d48cae 100644 --- a/partner_firstname/models.py +++ b/partner_firstname/models.py @@ -96,11 +96,28 @@ class ResPartner(models.Model): if not (self.firstname or self.lastname): raise exceptions.EmptyNamesError(self) + @api.one + @api.onchange("firstname", "lastname") + def _onchange_subnames(self): + """Avoid recursion when the user changes one of these fields. + + This forces to skip the :attr:`~.name` inversion when the user is + setting it in a not-inverted way. + """ + # Modify self's context without creating a new Environment. + # See https://github.com/odoo/odoo/issues/7472#issuecomment-119503916. + self.env.context = self.with_context(skip_onchange=True).env.context + @api.one @api.onchange("name") def _onchange_name(self): """Ensure :attr:`~.name` is inverted in the UI.""" - self._inverse_name_after_cleaning_whitespace() + if self.env.context.get("skip_onchange"): + # Do not skip next onchange + self.env.context = ( + self.with_context(skip_onchange=False).env.context) + else: + self._inverse_name_after_cleaning_whitespace() @api.model def _install_partner_firstname(self): diff --git a/partner_firstname/tests/test_onchange.py b/partner_firstname/tests/test_onchange.py index 209a97d56..657f9d1eb 100644 --- a/partner_firstname/tests/test_onchange.py +++ b/partner_firstname/tests/test_onchange.py @@ -19,7 +19,7 @@ class PartnerCompanyCase(TransactionCase): # User ensures it is a company partner.is_company = True - # User sets a name, that triggers ``_onchange_name()`` + # User sets a name, which triggers onchanges partner.name = name partner._onchange_name() @@ -39,8 +39,9 @@ class PartnerContactCase(TransactionCase): # User ensures it is not a company partner.is_company = False - # Changes firstname, which triggers _onchange_name() + # Changes firstname, which triggers onchanges partner.firstname = firstname + partner._onchange_subnames() partner._onchange_name() self.assertEqual(partner.lastname, False) @@ -57,8 +58,9 @@ class PartnerContactCase(TransactionCase): # User ensures it is not a company partner.is_company = False - # Changes lastname, which triggers _onchange_name() + # Changes lastname, which triggers onchanges partner.lastname = lastname + partner._onchange_subnames() partner._onchange_name() self.assertEqual(partner.firstname, False) @@ -76,14 +78,16 @@ class PartnerContactCase(TransactionCase): # User ensures it is not a company partner.is_company = False - # Changes firstname, which triggers _onchange_name() + # Changes firstname, which triggers onchanges partner.firstname = firstname + partner._onchange_subnames() partner._onchange_name() - # Changes lastname, which triggers _onchange_name() + # Changes lastname, which triggers onchanges partner.lastname = lastname + partner._onchange_subnames() partner._onchange_name() self.assertEqual(partner.lastname, lastname) self.assertEqual(partner.firstname, firstname) - self.assertEqual(partner.name, u" ".join(lastname, firstname)) + self.assertEqual(partner.name, u" ".join((lastname, firstname)))