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.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 (record.date_start and record.date_end and
  53. record.date_start > record.date_end):
  54. raise ValidationError(
  55. _('The starting date cannot be after the ending date.')
  56. )
  57. @api.constrains('left_partner_id', 'type_id')
  58. def _check_partner_left(self):
  59. """Check left partner for required company or person
  60. :raises ValidationError: When constraint is violated
  61. """
  62. self._check_partner("left")
  63. @api.constrains('right_partner_id', 'type_id')
  64. def _check_partner_right(self):
  65. """Check right partner for required company or person
  66. :raises ValidationError: When constraint is violated
  67. """
  68. self._check_partner("right")
  69. @api.multi
  70. def _check_partner(self, side):
  71. """Check partner for required company or person, and for category
  72. :param str side: left or right
  73. :raises ValidationError: When constraint is violated
  74. """
  75. for record in self:
  76. assert side in ['left', 'right']
  77. ptype = getattr(record.type_id, "contact_type_%s" % side)
  78. partner = getattr(record, '%s_partner_id' % side)
  79. if ((ptype == 'c' and not partner.is_company) or
  80. (ptype == 'p' and partner.is_company)):
  81. raise ValidationError(
  82. _('The %s partner is not applicable for this '
  83. 'relation type.') % side
  84. )
  85. category = getattr(record.type_id, "partner_category_%s" % side)
  86. if category and category.id not in partner.category_id.ids:
  87. raise ValidationError(
  88. _('The %s partner does not have category %s.') %
  89. (side, category.name)
  90. )
  91. @api.constrains('left_partner_id', 'right_partner_id')
  92. def _check_not_with_self(self):
  93. """Not allowed to link partner to same partner
  94. :raises ValidationError: When constraint is violated
  95. """
  96. for record in self:
  97. if record.left_partner_id == record.right_partner_id:
  98. if not (record.type_id and record.type_id.allow_self):
  99. raise ValidationError(
  100. _('Partners cannot have a relation with themselves.')
  101. )
  102. @api.constrains(
  103. 'left_partner_id',
  104. 'type_id',
  105. 'right_partner_id',
  106. 'date_start',
  107. 'date_end',
  108. )
  109. def _check_relation_uniqueness(self):
  110. """Forbid multiple active relations of the same type between the same
  111. partners
  112. :raises ValidationError: When constraint is violated
  113. """
  114. # pylint: disable=no-member
  115. # pylint: disable=no-value-for-parameter
  116. for record in self:
  117. domain = [
  118. ('type_id', '=', record.type_id.id),
  119. ('id', '!=', record.id),
  120. ('left_partner_id', '=', record.left_partner_id.id),
  121. ('right_partner_id', '=', record.right_partner_id.id),
  122. ]
  123. if record.date_start:
  124. domain += [
  125. '|',
  126. ('date_end', '=', False),
  127. ('date_end', '>=', record.date_start),
  128. ]
  129. if record.date_end:
  130. domain += [
  131. '|',
  132. ('date_start', '=', False),
  133. ('date_start', '<=', record.date_end),
  134. ]
  135. if record.search(domain):
  136. raise ValidationError(
  137. _('There is already a similar relation with '
  138. 'overlapping dates')
  139. )