from pydantic import model_validator, EmailStr, Field, computed_field, field_serializer from typing import Self, Literal from datetime import date from fiber_package.base import FiberBaseModel from .enums import Membership, LanguageOption from .submodels import Address class PersonModel(FiberBaseModel): collection_name: Literal["entity"] = "entity" membership: dict[str, Membership] = Field(default_factory=dict) first_name: str infix: str | None = None # mostly in Dutch names last_name: str full_name: str | None = None # first_name + infix + last_name email: EmailStr language: LanguageOption # TODO: phone number address: Address | None = None date_of_birth: date | None = None @computed_field @property def underage(self) -> bool: if self.date_of_birth is None: return False today = date.today() age = ( today.year - self.date_of_birth.year - ( (today.month, today.day) < (self.date_of_birth.month, self.date_of_birth.day) ) ) return age < 18 @model_validator(mode="after") def generate_full_name(self) -> Self: full_name = self.first_name if self.infix: full_name += " " + self.infix full_name += " " + self.last_name self.full_name = full_name return self # Needed for dates, as pymongo cannot handle them @field_serializer("date_of_birth", when_used="always") def serialize_date(self, value: date | None): return value.isoformat() if value else None