You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

112 lines
4.0 KiB

  1. # -*- coding: utf-8 -*-
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  3. # Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis
  4. # Copyright 2015 Antiun Ingenieria S.L. - Antonio Espinosa
  5. # Copyright 2017 Tecnativa - Pedro M. Baeza
  6. from odoo import api, fields, models
  7. from odoo.addons.partner_firstname import exceptions
  8. class ResPartner(models.Model):
  9. """Adds a second last name."""
  10. _inherit = "res.partner"
  11. lastname2 = fields.Char("Second last name", oldname="lastname_second")
  12. @api.model
  13. def _get_computed_name(self, lastname, firstname, lastname2=None):
  14. """Compute the name combined with the second lastname too.
  15. We have 2 lastnames, so lastnames and firstname will be separated by a
  16. comma.
  17. """
  18. order = self._get_names_order()
  19. names = list()
  20. if order == 'first_last':
  21. if firstname:
  22. names.append(firstname)
  23. if lastname:
  24. names.append(lastname)
  25. if lastname2:
  26. names.append(lastname2)
  27. else:
  28. if lastname:
  29. names.append(lastname)
  30. if lastname2:
  31. names.append(lastname2)
  32. if names and firstname and order == 'last_first_comma':
  33. names[-1] = names[-1] + ","
  34. if firstname:
  35. names.append(firstname)
  36. return " ".join(names)
  37. @api.depends("firstname", "lastname", "lastname2")
  38. def _compute_name(self):
  39. """Write :attr:`~.name` according to splitted data."""
  40. for partner in self:
  41. partner.name = self._get_computed_name(
  42. partner.lastname, partner.firstname, partner.lastname2,
  43. )
  44. @api.one
  45. def _inverse_name(self):
  46. """Try to revert the effect of :meth:`._compute_name`."""
  47. parts = self._get_inverse_name(self.name, self.is_company)
  48. # Avoid to hit :meth:`~._check_name` with all 3 fields being ``False``
  49. before, after = {}, {}
  50. for key, value in parts.items():
  51. (before if value else after)[key] = value
  52. if any([before[k] != self[k] for k in list(before.keys())]):
  53. self.update(before)
  54. if any([after[k] != self[k] for k in list(after.keys())]):
  55. self.update(after)
  56. @api.model
  57. def _get_inverse_name(self, name, is_company=False):
  58. """Compute the inverted name.
  59. - If the partner is a company, save it in the lastname.
  60. - Otherwise, make a guess.
  61. """
  62. # Company name goes to the lastname
  63. result = {
  64. 'firstname': False,
  65. 'lastname': name or False,
  66. 'lastname2': False,
  67. }
  68. if not is_company and name:
  69. order = self._get_names_order()
  70. result = super(ResPartner, self)._get_inverse_name(
  71. name, is_company)
  72. parts = []
  73. if order == 'last_first':
  74. if result['firstname']:
  75. parts = result['firstname'].split(" ", 1)
  76. while len(parts) < 2:
  77. parts.append(False)
  78. result['lastname2'] = parts[0]
  79. result['firstname'] = parts[1]
  80. else:
  81. if result['lastname']:
  82. parts = result['lastname'].split(" ", 1)
  83. while len(parts) < 2:
  84. parts.append(False)
  85. result['lastname'] = parts[0]
  86. result['lastname2'] = parts[1]
  87. return result
  88. @api.constrains("firstname", "lastname", "lastname2")
  89. def _check_name(self):
  90. """Ensure at least one name is set."""
  91. try:
  92. super(ResPartner, self)._check_name()
  93. except exceptions.EmptyNamesError:
  94. for partner in self:
  95. if not partner.lastname2:
  96. raise
  97. @api.onchange("firstname", "lastname", "lastname2")
  98. def _onchange_subnames(self):
  99. """Trigger onchange with :attr:`~.lastname2` too."""
  100. super(ResPartner, self)._onchange_subnames()