""" Schemas Pydantic pour Student et StudentEnrollment. """ from datetime import date, datetime from typing import Optional, List from pydantic import Field, EmailStr from schemas.common import BaseSchema class StudentBase(BaseSchema): """Schema de base pour Student.""" last_name: str first_name: str email: Optional[str] = None class StudentRead(StudentBase): """Schema pour la lecture d'un Student.""" id: int full_name: str = "" @property def computed_full_name(self) -> str: return f"{self.first_name} {self.last_name}" class StudentWithClass(StudentRead): """Schema avec la classe actuelle.""" current_class_id: Optional[int] = None current_class_name: Optional[str] = None class StudentDetail(StudentWithClass): """Schema détaillé avec historique d'inscriptions.""" enrollments: List["EnrollmentRead"] = [] class StudentList(BaseSchema): """Schema pour la liste des étudiants.""" students: List[StudentWithClass] total: int # Schemas pour les inscriptions temporelles class EnrollmentBase(BaseSchema): """Schema de base pour StudentEnrollment.""" enrollment_date: date departure_date: Optional[date] = None enrollment_reason: Optional[str] = None departure_reason: Optional[str] = None class EnrollmentRead(EnrollmentBase): """Schema pour la lecture d'une inscription.""" id: int student_id: int class_group_id: int class_name: Optional[str] = None is_active: bool = True created_at: datetime updated_at: datetime class EnrollmentCreate(EnrollmentBase): """Schema pour créer une inscription.""" student_id: int class_group_id: int # Schemas pour les opérations d'écriture (CRUD) class StudentCreate(StudentBase): """Schema pour créer un étudiant.""" class_group_id: Optional[int] = None enrollment_date: Optional[date] = None enrollment_reason: Optional[str] = None class StudentUpdate(BaseSchema): """Schema pour modifier un étudiant.""" last_name: Optional[str] = None first_name: Optional[str] = None email: Optional[str] = None class EnrollRequest(BaseSchema): """Schema pour inscrire un élève dans une classe.""" # Pour élève existant student_id: Optional[int] = None # Pour nouvel élève (si student_id est None) first_name: Optional[str] = None last_name: Optional[str] = None email: Optional[str] = None # Informations d'inscription class_group_id: int enrollment_date: date enrollment_reason: Optional[str] = None class TransferRequest(BaseSchema): """Schema pour transférer un élève vers une autre classe.""" student_id: int new_class_group_id: int transfer_date: date transfer_reason: Optional[str] = None class DepartureRequest(BaseSchema): """Schema pour enregistrer le départ d'un élève.""" student_id: int departure_date: date departure_reason: Optional[str] = None class EnrollmentResponse(BaseSchema): """Schema de réponse pour les opérations d'inscription.""" enrollment_id: int student_id: int student_name: str class_name: str message: str = "" is_new_student: bool = False class TransferResponse(BaseSchema): """Schema de réponse pour les transferts.""" old_enrollment_id: int new_enrollment_id: int student_name: str old_class_name: str new_class_name: str message: str = "" class DepartureResponse(BaseSchema): """Schema de réponse pour les départs.""" enrollment_id: int student_name: str class_name: str message: str = "" # Pour éviter les références circulaires StudentDetail.model_rebuild()