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.

155 lines
5.6 KiB

  1. # Copyright 2013-2017 Therp BV <http://therp.nl>
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  3. # pylint: disable=api-one-deprecated
  4. """Store relations (connections) between partners."""
  5. from odoo import _, api, fields, models
  6. from odoo.exceptions import ValidationError
  7. class ResPartnerRelation(models.Model):
  8. """Model res.partner.relation is used to describe all links or relations
  9. between partners in the database.
  10. This model is actually only used to store the data. The model
  11. res.partner.relation.all, based on a view that contains each record
  12. two times, once for the normal relation, once for the inverse relation,
  13. will be used to maintain the data.
  14. """
  15. _name = "res.partner.relation"
  16. _description = "Partner relation"
  17. left_partner_id = fields.Many2one(
  18. comodel_name="res.partner",
  19. string="Source Partner",
  20. required=True,
  21. auto_join=True,
  22. ondelete="cascade",
  23. )
  24. right_partner_id = fields.Many2one(
  25. comodel_name="res.partner",
  26. string="Destination Partner",
  27. required=True,
  28. auto_join=True,
  29. ondelete="cascade",
  30. )
  31. type_id = fields.Many2one(
  32. comodel_name="res.partner.relation.type",
  33. string="Type",
  34. required=True,
  35. auto_join=True,
  36. )
  37. date_start = fields.Date("Starting date")
  38. date_end = fields.Date("Ending date")
  39. @api.model
  40. def create(self, vals):
  41. """Override create to correct values, before being stored."""
  42. context = self.env.context
  43. if "left_partner_id" not in vals and context.get("active_id"):
  44. vals["left_partner_id"] = context.get("active_id")
  45. return super(ResPartnerRelation, self).create(vals)
  46. @api.constrains("date_start", "date_end")
  47. def _check_dates(self):
  48. """End date should not be before start date, if not filled
  49. :raises ValidationError: When constraint is violated
  50. """
  51. for record in self:
  52. if (
  53. record.date_start
  54. and record.date_end
  55. and record.date_start > record.date_end
  56. ):
  57. raise ValidationError(
  58. _("The starting date cannot be after the ending date.")
  59. )
  60. @api.constrains("left_partner_id", "type_id")
  61. def _check_partner_left(self):
  62. """Check left partner for required company or person
  63. :raises ValidationError: When constraint is violated
  64. """
  65. self._check_partner("left")
  66. @api.constrains("right_partner_id", "type_id")
  67. def _check_partner_right(self):
  68. """Check right partner for required company or person
  69. :raises ValidationError: When constraint is violated
  70. """
  71. self._check_partner("right")
  72. def _check_partner(self, side):
  73. """Check partner for required company or person, and for category
  74. :param str side: left or right
  75. :raises ValidationError: When constraint is violated
  76. """
  77. for record in self:
  78. assert side in ["left", "right"]
  79. ptype = getattr(record.type_id, "contact_type_%s" % side)
  80. partner = getattr(record, "%s_partner_id" % side)
  81. if (ptype == "c" and not partner.is_company) or (
  82. ptype == "p" and partner.is_company
  83. ):
  84. raise ValidationError(
  85. _("The %s partner is not applicable for this " "relation type.")
  86. % side
  87. )
  88. category = getattr(record.type_id, "partner_category_%s" % side)
  89. if category and category.id not in partner.category_id.ids:
  90. raise ValidationError(
  91. _("The %s partner does not have category %s.")
  92. % (side, category.name)
  93. )
  94. @api.constrains("left_partner_id", "right_partner_id")
  95. def _check_not_with_self(self):
  96. """Not allowed to link partner to same partner
  97. :raises ValidationError: When constraint is violated
  98. """
  99. for record in self:
  100. if record.left_partner_id == record.right_partner_id:
  101. if not (record.type_id and record.type_id.allow_self):
  102. raise ValidationError(
  103. _("Partners cannot have a relation with themselves.")
  104. )
  105. @api.constrains(
  106. "left_partner_id", "type_id", "right_partner_id", "date_start", "date_end"
  107. )
  108. def _check_relation_uniqueness(self):
  109. """Forbid multiple active relations of the same type between the same
  110. partners
  111. :raises ValidationError: When constraint is violated
  112. """
  113. # pylint: disable=no-member
  114. # pylint: disable=no-value-for-parameter
  115. for record in self:
  116. domain = [
  117. ("type_id", "=", record.type_id.id),
  118. ("id", "!=", record.id),
  119. ("left_partner_id", "=", record.left_partner_id.id),
  120. ("right_partner_id", "=", record.right_partner_id.id),
  121. ]
  122. if record.date_start:
  123. domain += [
  124. "|",
  125. ("date_end", "=", False),
  126. ("date_end", ">=", record.date_start),
  127. ]
  128. if record.date_end:
  129. domain += [
  130. "|",
  131. ("date_start", "=", False),
  132. ("date_start", "<=", record.date_end),
  133. ]
  134. if record.search(domain):
  135. raise ValidationError(
  136. _("There is already a similar relation with " "overlapping dates")
  137. )