Coverage for bc/kwai-bc-training/src/kwai_bc_training/trainings/training.py: 98%
40 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.period import Period
9from kwai_core.domain.value_objects.text import LocaleText
11from kwai_bc_training.teams.team import TeamEntity
12from kwai_bc_training.trainings.training_schedule import (
13 TrainingScheduleEntity,
14)
15from kwai_bc_training.trainings.value_objects import TrainingCoach
18class TrainingIdentifier(IntIdentifier):
19 """Identifier for a training."""
22@dataclass(kw_only=True, eq=False, slots=True, frozen=True)
23class TrainingEntity(DataclassEntity):
24 """A training entity.
26 Attributes:
27 texts: A tuple with text content
28 schedule: The related training schedule, when the training was created from a schedule.
29 coaches: A frozenset of assigned coaches.
30 teams: A frozenset of assigned teams.
31 period: The period of the training.
32 season: The season that the training belongs to (not supported yet).
33 active: Is this training active?
34 cancelled: Is this training cancelled?
35 location: The location of this training
36 remark: A remark about this training
37 """
39 ID: ClassVar[Type] = TrainingIdentifier
41 texts: tuple[LocaleText, ...] = field(default_factory=tuple)
42 schedule: TrainingScheduleEntity | None = None
43 coaches: frozenset[TrainingCoach] = field(default_factory=frozenset)
44 teams: frozenset[TeamEntity] = field(default_factory=frozenset)
45 season: None = None
46 period: Period
47 active: bool = True
48 cancelled: bool = False
49 location: str = ""
50 remark: str = ""
52 def add_team(self, team: TeamEntity) -> Self:
53 """Add a team to this training."""
54 teams = self.teams | {team}
55 return replace(self, teams=teams)
57 def delete_team(self, team: TeamEntity) -> Self:
58 """Remove a team from this training."""
59 return replace(self, teams=self.teams - {team})
61 def add_coach(self, coach: TrainingCoach) -> Self:
62 """Add a coach to this training."""
63 coaches = self.coaches | {coach}
64 return replace(self, coaches=coaches)
66 def delete_coach(self, coach: TrainingCoach) -> Self:
67 """Remove a coach from this training."""
68 if coach.present:
69 raise ValueError(
70 "It's not allowed to remove a coach who was present on a training."
71 )
72 return replace(self, coaches=self.coaches - {coach})
74 def mark_coach_as_present(self, coach_id: str) -> Self:
75 """Mark a coach as present for this training."""
76 training_coaches = list(filter(lambda c: c.coach.id == coach_id, self.coaches))
77 if len(training_coaches) == 0:
78 raise ValueError(f"Coach with {coach_id} is not attached to this training.")
79 training_coach = replace(training_coaches[0], present=True)
80 return replace(
81 self, coaches=(self.coaches - {training_coaches[0]} | {training_coach})
82 )