helpdesk_team_share_collaborator_wizard.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. import re
  4. from odoo import api, fields, models, _
  5. from odoo.exceptions import ValidationError
  6. class HelpdeskTeamShareCollaboratorWizard(models.TransientModel):
  7. _name = 'helpdesk.team.share.collaborator.wizard'
  8. _description = 'Helpdesk Team Sharing Collaborator Wizard'
  9. parent_wizard_id = fields.Many2one(
  10. 'helpdesk.team.share.wizard',
  11. export_string_translation=False,
  12. )
  13. partner_id = fields.Many2one(
  14. 'res.partner',
  15. string='Collaborator',
  16. required=True,
  17. )
  18. access_mode = fields.Selection(
  19. [
  20. ('admin', 'Administrator'),
  21. ('user_all', 'User - All Tickets'),
  22. ('user_own', 'User - Own Tickets'),
  23. ],
  24. string='Access Mode',
  25. required=True,
  26. default='user_own',
  27. help="Administrator: can view all tickets and manage other users.\n"
  28. "User - All Tickets: can view all tickets and create own tickets.\n"
  29. "User - Own Tickets: can only create and view own tickets."
  30. )
  31. send_invitation = fields.Boolean(
  32. string='Send Invitation',
  33. compute='_compute_send_invitation',
  34. store=True,
  35. readonly=False,
  36. default=True,
  37. )
  38. @api.depends('partner_id', 'access_mode')
  39. def _compute_send_invitation(self):
  40. team = self.parent_wizard_id.resource_ref
  41. for collaborator in self:
  42. if (
  43. collaborator.partner_id not in team.message_partner_ids
  44. or (collaborator.access_mode != 'user_own' and collaborator.partner_id not in team.collaborator_ids.partner_id)
  45. ):
  46. collaborator.send_invitation = True
  47. else:
  48. collaborator.send_invitation = False
  49. @api.constrains('partner_id')
  50. def _check_partner_share(self):
  51. """Validate that partner is a portal/external partner"""
  52. for collaborator in self:
  53. if collaborator.partner_id and not collaborator.partner_id.partner_share:
  54. raise ValidationError(_(
  55. "Partner '%s' is an internal user and cannot be added as a collaborator. "
  56. "Only external partners (portal users) can be collaborators."
  57. ) % collaborator.partner_id.display_name)
  58. @api.constrains('partner_id')
  59. def _check_partner_commercial_partner(self):
  60. """Validate that partner belongs to the same commercial_partner_id as admin"""
  61. for collaborator in self:
  62. if not collaborator.partner_id or not collaborator.parent_wizard_id:
  63. continue
  64. # Get admin's commercial_partner_id from context
  65. admin_commercial_partner_id = collaborator._context.get('default_admin_commercial_partner_id')
  66. if not admin_commercial_partner_id:
  67. # Try to get from parent wizard context
  68. admin_commercial_partner_id = collaborator.parent_wizard_id._context.get('default_admin_commercial_partner_id')
  69. if admin_commercial_partner_id:
  70. partner_commercial_id = collaborator.partner_id.commercial_partner_id.id
  71. if partner_commercial_id != admin_commercial_partner_id:
  72. raise ValidationError(_(
  73. "Partner '%s' does not belong to your contact network. "
  74. "You can only add contacts from your company network."
  75. ) % collaborator.partner_id.display_name)
  76. @api.constrains('partner_id')
  77. def _check_partner_email(self):
  78. """Validate that partner has a valid email if invitation will be sent"""
  79. for collaborator in self:
  80. if collaborator.partner_id and collaborator.send_invitation:
  81. email = collaborator.partner_id.email
  82. if not email:
  83. raise ValidationError(_(
  84. "Partner '%s' does not have an email address. "
  85. "An email is required to send an invitation."
  86. ) % collaborator.partner_id.display_name)
  87. # Basic email format validation
  88. email_pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'
  89. if not re.match(email_pattern, email):
  90. raise ValidationError(_(
  91. "Partner '%s' has an invalid email address format: %s"
  92. ) % (collaborator.partner_id.display_name, email))
  93. @api.constrains('access_mode')
  94. def _check_access_mode(self):
  95. """Validate access mode value"""
  96. valid_modes = ['admin', 'user_all', 'user_own']
  97. for collaborator in self:
  98. if collaborator.access_mode and collaborator.access_mode not in valid_modes:
  99. raise ValidationError(_(
  100. "Invalid access mode '%s'. Valid modes are: %s"
  101. ) % (collaborator.access_mode, ', '.join(valid_modes)))