bemade-addons/bemade_sports_clinic/models/sports_team.py
2025-05-29 21:35:47 -04:00

244 lines
8.2 KiB
Python

from odoo import models, fields, api, _, Command
from odoo.exceptions import ValidationError
class SportsTeam(models.Model):
_name = "sports.team"
_description = "Sports Team"
_inherit = ["mail.thread", "mail.activity.mixin"]
name = fields.Char()
patient_ids = fields.Many2many(
comodel_name="sports.patient",
relation="sports_team_patient_rel",
column1="team_id",
column2="patient_id",
string="Players",
tracking=True,
)
player_count = fields.Integer(compute="_compute_player_counts")
injured_count = fields.Integer(compute="_compute_player_counts")
healthy_count = fields.Integer(compute="_compute_player_counts")
parent_id = fields.Many2one(
comodel_name="res.partner",
string="Parent Organization",
ondelete="restrict",
tracking=True,
)
staff_ids = fields.One2many(
comodel_name="sports.team.staff",
inverse_name="team_id",
tracking=True,
)
head_coach_id = fields.Many2one(
comodel_name="res.partner",
compute="_compute_head_coach",
store=True,
)
head_coach_name = fields.Char(
related="head_coach_id.name",
string="Head Coach Name",
)
head_therapist_id = fields.Many2one(
comodel_name="res.partner",
compute="_compute_head_therapist",
store=True,
string="Head Therapist",
)
head_therapist_name = fields.Char(
related="head_therapist_id.name",
string="Head Therapist Name",
)
website = fields.Char()
allowed_user_ids = fields.Many2many(
comodel_name="res.users",
compute="_compute_allowed_user_ids",
inverse="_inverse_allowed_user_ids",
)
def write(self, vals):
previous_patient_ids = self.sudo().patient_ids
res = super().write(vals)
if "staff_ids" in vals or "patient_ids" in vals:
(self.sudo().patient_ids | previous_patient_ids).recompute_followers()
return res
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
for index, rec in enumerate(res):
if "staff_ids" in vals_list[index]:
rec.sudo().patient_ids.recompute_followers()
return res
def unlink(self):
to_recompute = self.patient_ids
res = super().unlink()
to_recompute.recompute_followers()
return res
@api.depends("patient_ids.is_injured")
def _compute_player_counts(self):
for rec in self:
rec.player_count = len(rec.patient_ids)
rec.injured_count = len(rec.patient_ids.filtered(lambda p: p.is_injured))
rec.healthy_count = rec.player_count - rec.injured_count
@api.depends("staff_ids.role")
def _compute_head_coach(self):
for rec in self:
staff = rec.staff_ids.filtered(lambda r: r.role == "head_coach")
rec.head_coach_id = staff.partner_id if staff else False
@api.depends("staff_ids.role")
def _compute_head_therapist(self):
for rec in self:
staff = rec.staff_ids.filtered(lambda r: r.role == "head_therapist")
rec.head_therapist_id = staff.partner_id if staff else False
def _compute_allowed_user_ids(self):
for rec in self:
rec.allowed_user_ids = rec.staff_ids.user_ids
def _inverse_allowed_user_ids(self):
for rec in self:
removed_staff = rec.staff_ids.filtered(
lambda staff: staff.user_ids not in rec.allowed_user_ids
)
added_users = rec.allowed_user_ids - rec.staff_ids.user_ids
removed_staff.unlink()
self.env["sports.team.staff"].create(
[
{
"team_id": rec.id,
"partner_id": user.partner_id.id,
"role": "other",
}
for user in added_users
]
)
def remove_access(self, user):
self.staff_ids.filtered(lambda staff: user in staff.user_ids).unlink()
class TeamStaff(models.Model):
_name = "sports.team.staff"
_description = "Sports Team Staff"
sequence = fields.Integer()
team_id = fields.Many2one(
comodel_name="sports.team",
string="Team",
required=True,
ondelete="cascade",
)
partner_id = fields.Many2one(
comodel_name="res.partner",
string="Staff Member",
required=True,
domain=[("is_company", "=", False)],
ondelete="cascade",
)
active = fields.Boolean(related="partner_id.active")
role = fields.Selection(
selection=[
("head_coach", "Head Coach"),
("head_therapist", "Head Therapist"),
("coach", "Coach"),
("therapist", "Therapist"),
("doctor", "Doctor"),
("other", "Other"),
],
required=True,
)
mobile = fields.Char(related="partner_id.mobile", readonly=False)
name = fields.Char(related="partner_id.name", readonly=False)
parent_id = fields.Many2one(
related="partner_id.parent_id",
readonly=False,
string="Organization",
domain=[("is_company", "=", True)],
)
email = fields.Char(related="partner_id.email", readonly=False)
user_ids = fields.One2many(related="partner_id.user_ids", readonly=True)
has_portal_access = fields.Boolean(
compute="_compute_has_portal_access", compute_sudo=True
)
_sql_constraints = [
(
"team_staff_unique",
"unique(team_id, partner_id)",
"Each partner can only be related to a given team once.",
)
]
@api.constrains("role")
def _constrain_role(self):
teams = self.mapped("team_id")
for team in teams:
if len(team.staff_ids.filtered(lambda r: r.role == "head_coach")) > 1:
raise ValidationError(_("A team can have only one head coach."))
if len(team.staff_ids.filtered(lambda r: r.role == "head_therapist")) > 1:
raise ValidationError(_("A team can have only one head therapist."))
@api.onchange("mobile")
def _onchange_mobile_validation(self):
if self.mobile:
self.mobile = self.partner_id._phone_format(
self.mobile, force_format="INTERNATIONAL"
)
@api.depends("user_ids", "user_ids.groups_id")
def _compute_has_portal_access(self):
for rec in self:
rec.has_portal_access = (
bool(rec.user_ids.filtered(lambda r: r.has_group("base.group_portal")))
or bool(rec.user_ids.filtered(lambda r: r.has_group("base.group_user")))
or bool(rec.partner_id.signup_token)
)
def action_revoke_portal_access(self):
group_portal = self.env.ref("base.group_portal")
group_public = self.env.ref("base.group_public")
self.user_ids.write(
{
"groups_id": [
Command.unlink(group_portal.id),
Command.link(group_public.id),
],
"active": False,
}
)
# Remove the signup token, so it cannot be used
self.partner_id.sudo().signup_token = False
def action_grant_portal_access(self):
wiz = self.env["portal.wizard"].create(
{"partner_ids": [(4, self.partner_id.id)]}
)
return wiz._action_open_modal()
@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
res.team_id.mapped("patient_ids").recompute_followers()
return res
def unlink(self):
patients = self.team_id.mapped("patient_ids")
res = super().unlink()
patients.recompute_followers()
return res
def write(self, values):
if "team_id" in values:
to_recompute = self.env["sports.patient"]
for rec in self:
if rec.team_id.id != values["team_id"]:
to_recompute |= rec.team_id.patient_ids
res = super().write(values)
to_recompute.recompute_followers()
return res
return super().write(values)