- Add docstrings to ``_compute_user_id``, ``create`` and ``_define_user_id`` and clarify the inline comments describing the team-leader fallback rules. - Convert ``README.rst`` to ``README.md``, documenting usage, the graceful handling of partners without a linked user, and how to run the test suite.
97 lines
3.9 KiB
Python
97 lines
3.9 KiB
Python
from odoo import api, models
|
|
|
|
|
|
class HelpdeskTicket(models.Model):
|
|
_inherit = "helpdesk.ticket"
|
|
|
|
@api.depends("team_id")
|
|
def _compute_user_id(self):
|
|
"""Recompute the assigned user whenever the team changes.
|
|
|
|
Delegates to :meth:`_define_user_id` so that, when a team is set or
|
|
changed, the assigned user is realigned with that team (replaced by
|
|
the team leader if the current user does not belong to the team).
|
|
"""
|
|
for ticket in self:
|
|
ticket.user_id = self._define_user_id(
|
|
ticket.team_id,
|
|
ticket.user_id,
|
|
)
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
"""Auto-assign team, project and user for portal-created tickets.
|
|
|
|
When a ticket is created without an explicit team but with a partner,
|
|
the partner's linked user is looked up and, if that user has a default
|
|
helpdesk team configured, the ticket is routed accordingly:
|
|
|
|
* ``team_id`` is set to the user's default helpdesk team.
|
|
* ``project_id`` is set to the team's default project, if any.
|
|
* ``user_id`` is set to the team leader (via :meth:`_define_user_id`).
|
|
|
|
Tickets that already have a team, that have no partner, or whose
|
|
partner has no linked user / no default team are left untouched.
|
|
"""
|
|
for vals in vals_list:
|
|
if not vals.get("team_id") and vals.get("partner_id"):
|
|
# Find the user who creates the ticket
|
|
partner = self.env["res.partner"].browse(vals.get("partner_id"))
|
|
if not partner:
|
|
continue
|
|
# A partner may have no linked user (e.g. a plain contact)
|
|
user = partner.user_ids[:1]
|
|
if not user:
|
|
continue
|
|
|
|
# Get its default team_id
|
|
team = user.default_helpdesk_ticket_team_id
|
|
if not team:
|
|
continue
|
|
|
|
vals["team_id"] = team.id
|
|
|
|
# Set the linked project
|
|
if team.default_project_id:
|
|
vals["project_id"] = team.default_project_id.id
|
|
|
|
# Set the user_id to which the ticket is assigned
|
|
user_id = self._define_user_id(team, None)
|
|
if user_id:
|
|
vals["user_id"] = user_id.id
|
|
return super().create(vals_list)
|
|
|
|
def _define_user_id(self, team_id=None, ticket_user_id=None):
|
|
"""Determine which user should be assigned to a ticket for a team.
|
|
|
|
Decides whether the current ticket user must be kept or replaced by
|
|
the helpdesk team leader (``team_id.user_id``), according to the
|
|
following rules:
|
|
|
|
* No team -> keep ``ticket_user_id`` unchanged.
|
|
* No current user -> use the team leader.
|
|
* User not in team -> replace with the team leader.
|
|
* User is a team member-> keep ``ticket_user_id`` unchanged.
|
|
|
|
:param team_id: the ``helpdesk.ticket.team`` record (or falsy).
|
|
:param ticket_user_id: the currently assigned ``res.users`` (or falsy).
|
|
:return: the ``res.users`` record that should be assigned (possibly an
|
|
empty recordset when the team has no leader and the current user
|
|
is not a member of the team).
|
|
"""
|
|
if not team_id:
|
|
# If no team, return the current ticket_user_id
|
|
return ticket_user_id
|
|
|
|
if not ticket_user_id:
|
|
# If no current user, fall back to the team leader (may be empty).
|
|
return team_id.user_id
|
|
|
|
if ticket_user_id not in team_id.user_ids:
|
|
# If the current user is not a team member, replace it with the
|
|
# team leader (may be empty).
|
|
return team_id.user_id
|
|
|
|
# Otherwise the current user is a valid team member: keep it unchanged.
|
|
return ticket_user_id
|