import typing from datetime import datetime from xmlrpc.client import DateTime from sqlmodel import Field, Relationship, SQLModel, String WorkTypes = typing.Literal["cooking", "dishes", "tables"] class Event(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) title: str = Field(nullable=False) event_time: datetime = Field(nullable=False) registration_deadline: datetime = Field(nullable=False) description: str recipe_link: str # Min and max number of people needed for cooking, doing the dishes and preparing the tables team_cooking_min: int = 3 team_cooking_max: int = 5 team_dishes_min: int = 3 team_dishes_max: int = 5 # Todo: Rename to "table" team_prep_min: int = 1 team_prep_max: int = 1 registrations: list["Registration"] = Relationship() team: list["TeamRegistration"] = Relationship() def team_min_reached(self, work_type: WorkTypes): threshold = { "cooking": self.team_cooking_min, "dishes": self.team_dishes_min, "tables": self.team_prep_min, }[work_type] return sum(1 for t in self.team if t.work_type == work_type) >= threshold def team_max_reached(self, work_type: WorkTypes): threshold = { "cooking": self.team_cooking_max, "dishes": self.team_dishes_max, "tables": self.team_prep_max, }[work_type] return sum(1 for t in self.team if t.work_type == work_type) >= threshold def all_teams_min(self): return all( self.team_min_reached(work_type) for work_type in typing.get_args(WorkTypes) ) def all_teams_max(self): return all( self.team_max_reached(work_type) for work_type in typing.get_args(WorkTypes) ) class TeamRegistration(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) event_id: int | None = Field(default=None, foreign_key="event.id") person_name: str = Field(nullable=False) work_type: WorkTypes = Field(nullable=False, sa_type=String) comment: str | None class Household(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str = Field(nullable=False) class Registration(SQLModel, table=True): event_id: int | None = Field(default=None, foreign_key="event.id", primary_key=True) household_id: int | None = Field( default=None, foreign_key="household.id", primary_key=True ) num_adult_meals: int num_children_meals: int num_small_children_meals: int comment: str | None household: Household = Relationship() class Subscription(SQLModel, table=True): household_id: int | None = Field( default=None, foreign_key="household.id", primary_key=True ) num_adult_meals: int num_children_meals: int num_small_children_meals: int comment: str | None last_modified: datetime = Field(default_factory=datetime.now, nullable=False) monday: bool = True tuesday: bool = True wednesday: bool = True thursday: bool = True friday: bool = True saturday: bool = True sunday: bool = True household: Household = Relationship() def day_string_de(self) -> str: """ Generates a string representation of selected days in German short form. """ result = [] if self.monday: result.append("Mo") if self.tuesday: result.append("Di") if self.wednesday: result.append("Mi") if self.thursday: result.append("Do") if self.friday: result.append("Fr") if self.saturday: result.append("Sa") if self.sunday: result.append("So") if len(result) < 7: return ", ".join(result) else: return "Alle"