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.

156 lines
5.3 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2013-2016 Therp BV <http://therp.nl>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. """Store relations (connections) between partners."""
  5. from openerp import _, api, fields, models
  6. from openerp.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.one
  47. @api.constrains('date_start', 'date_end')
  48. def _check_dates(self):
  49. """End date should not be before start date, if not filled
  50. :raises ValidationError: When constraint is violated
  51. """
  52. if (self.date_start and self.date_end and
  53. self.date_start > self.date_end):
  54. raise ValidationError(
  55. _('The starting date cannot be after the ending date.')
  56. )
  57. @api.one
  58. @api.constrains('left_partner_id', 'type_id')
  59. def _check_partner_left(self):
  60. """Check left partner for required company or person
  61. :raises ValidationError: When constraint is violated
  62. """
  63. self._check_partner("left")
  64. @api.one
  65. @api.constrains('right_partner_id', 'type_id')
  66. def _check_partner_right(self):
  67. """Check right partner for required company or person
  68. :raises ValidationError: When constraint is violated
  69. """
  70. self._check_partner("right")
  71. @api.one
  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. assert side in ['left', 'right']
  78. ptype = getattr(self.type_id, "contact_type_%s" % side)
  79. partner = getattr(self, '%s_partner_id' % side)
  80. if ((ptype == 'c' and not partner.is_company) or
  81. (ptype == 'p' and partner.is_company)):
  82. raise ValidationError(
  83. _('The %s partner is not applicable for this relation type.') %
  84. side
  85. )
  86. category = getattr(self.type_id, "partner_category_%s" % side)
  87. if category and category.id not in partner.category_id.ids:
  88. raise ValidationError(
  89. _('The %s partner does not have category %s.') %
  90. (side, category.name)
  91. )
  92. @api.one
  93. @api.constrains('left_partner_id', 'right_partner_id')
  94. def _check_not_with_self(self):
  95. """Not allowed to link partner to same partner
  96. :raises ValidationError: When constraint is violated
  97. """
  98. if self.left_partner_id == self.right_partner_id:
  99. if not (self.type_id and self.type_id.allow_self):
  100. raise ValidationError(
  101. _('Partners cannot have a relation with themselves.')
  102. )
  103. @api.one
  104. @api.constrains(
  105. 'left_partner_id',
  106. 'type_id',
  107. 'right_partner_id',
  108. 'date_start',
  109. 'date_end',
  110. )
  111. def _check_relation_uniqueness(self):
  112. """Forbid multiple active relations of the same type between the same
  113. partners
  114. :raises ValidationError: When constraint is violated
  115. """
  116. # pylint: disable=no-member
  117. # pylint: disable=no-value-for-parameter
  118. domain = [
  119. ('type_id', '=', self.type_id.id),
  120. ('id', '!=', self.id),
  121. ('left_partner_id', '=', self.left_partner_id.id),
  122. ('right_partner_id', '=', self.right_partner_id.id),
  123. ]
  124. if self.date_start:
  125. domain += [
  126. '|',
  127. ('date_end', '=', False),
  128. ('date_end', '>=', self.date_start),
  129. ]
  130. if self.date_end:
  131. domain += [
  132. '|',
  133. ('date_start', '=', False),
  134. ('date_start', '<=', self.date_end),
  135. ]
  136. if self.search(domain):
  137. raise ValidationError(
  138. _('There is already a similar relation with overlapping dates')
  139. )