Coverage for bc/kwai-bc-training/src/kwai_bc_training/trainings/training.py: 89%
56 statements
« prev ^ index » next coverage.py v7.11.0, created at 2024-01-01 00:00 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2024-01-01 00:00 +0000
1"""Module for defining a training entity."""
3from dataclasses import dataclass, field, replace
4from typing import ClassVar, Self, Type
6from kwai_core.domain.entity import DataclassEntity
7from kwai_core.domain.value_objects.identifier import IntIdentifier
8from kwai_core.domain.value_objects.owner import Owner
9from kwai_core.domain.value_objects.period import Period
10from kwai_core.domain.value_objects.text import LocaleText
11from kwai_core.domain.value_objects.unique_id import UniqueId
13from kwai_bc_training.coaches.coach import CoachEntity
14from kwai_bc_training.teams.team import TeamEntity
15from kwai_bc_training.trainings.training_schedule import (
16 TrainingScheduleEntity,
17)
20class TrainingCoachIdentifier(IntIdentifier):
21 """Identifier for a coach appointed to a training."""
24@dataclass(kw_only=True, frozen=True, slots=True)
25class TrainingCoachEntity(DataclassEntity):
26 """A coach attached to a training."""
28 ID: ClassVar[Type] = TrainingCoachIdentifier
30 coach: CoachEntity
31 owner: Owner
32 present: bool = False
33 type: int = 0
34 payed: bool = False
35 remark: str = ""
38class TrainingIdentifier(IntIdentifier):
39 """Identifier for a training."""
42@dataclass(kw_only=True, eq=False, slots=True, frozen=True)
43class TrainingEntity(DataclassEntity):
44 """A training entity.
46 Attributes:
47 texts: A tuple with text content
48 schedule: The related training schedule, when the training was created from a schedule.
49 coaches: A frozenset of assigned coaches.
50 teams: A frozenset of assigned teams.
51 period: The period of the training.
52 season: The season that the training belongs to (not supported yet).
53 active: Is this training active?
54 cancelled: Is this training cancelled?
55 location: The location of this training
56 remark: A remark about this training
57 """
59 ID: ClassVar[Type] = TrainingIdentifier
61 texts: tuple[LocaleText, ...] = field(default_factory=tuple)
62 schedule: TrainingScheduleEntity | None = None
63 coaches: frozenset[TrainingCoachEntity] = field(default_factory=frozenset)
64 teams: frozenset[TeamEntity] = field(default_factory=frozenset)
65 season: None = None
66 period: Period
67 active: bool = True
68 cancelled: bool = False
69 location: str = ""
70 remark: str = ""
72 def add_team(self, team: TeamEntity) -> Self:
73 """Add a team to this training."""
74 teams = self.teams | {team}
75 return replace(self, teams=teams)
77 def delete_team(self, team: TeamEntity) -> Self:
78 """Remove a team from this training."""
79 return replace(self, teams=self.teams - {team})
81 def add_coach(self, coach: TrainingCoachEntity) -> Self:
82 """Add a coach to this training."""
83 coaches = self.coaches | {coach}
84 return replace(self, coaches=coaches)
86 def delete_coach(self, coach: TrainingCoachEntity) -> Self:
87 """Remove a coach from this training."""
88 if coach.present:
89 raise ValueError(
90 "It's not allowed to remove a coach who was present on a training."
91 )
92 return replace(self, coaches=self.coaches - {coach})
94 def mark_coach_as_present(self, coach_uuid: UniqueId, present: bool = True) -> Self:
95 """Mark a coach as present or not for this training.
97 Args:
98 coach_uuid: The uuid of the coach to mark as present or not
99 present: Whether the coach was present or not
100 """
101 training_coaches = list(
102 filter(lambda c: c.coach.uuid == coach_uuid, self.coaches)
103 )
104 if len(training_coaches) == 0:
105 raise ValueError(
106 f"Coach with {coach_uuid} is not attached to this training."
107 )
108 training_coach = replace(training_coaches[0], present=present)
109 return replace(
110 self, coaches=(self.coaches - {training_coaches[0]} | {training_coach})
111 )
113 def appoint_head_coach(self, coach_uuid: UniqueId, appoint: bool = True) -> Self:
114 """Appoint a coach as head of this training.
116 Args:
117 coach_uuid: The uuid of the coach to appoint or not
118 appoint: Whether the coach is appointed or not
119 """
120 training_coaches = list(
121 filter(lambda c: c.coach.uuid == coach_uuid, self.coaches)
122 )
123 if len(training_coaches) == 0:
124 raise ValueError(
125 f"Coach with {coach_uuid} is not attached to this training."
126 )
127 training_coach = replace(training_coaches[0], type=1 if appoint else 0)
128 return replace(
129 self, coaches=(self.coaches - {training_coaches[0]} | {training_coach})
130 )