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.

132 lines
4.3 KiB

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