from typing import List, Optional from pydantic import BaseModel, EmailStr, constr from datetime import date # Contact Person schemas class ContactPersonBase(BaseModel): firstname: str lastname: str phone_number: str email: EmailStr class ContactPersonCreate(ContactPersonBase): pass class ContactPerson(ContactPersonBase): id: int class Config: from_attributes = True # Address schemas class AddressCreate(BaseModel): street: str city: str zipcode: str country: str class Address(AddressCreate): id: int class Config: from_attributes = True # Sample schemas class Sample(BaseModel): id: int sample_name: str class Config: from_attributes = True # Puck schemas class PuckBase(BaseModel): puck_name: str puck_type: str puck_location_in_dewar: int class PuckCreate(PuckBase): positions: List[int] = [] class PuckUpdate(BaseModel): puck_name: Optional[str] = None puck_type: Optional[str] = None puck_location_in_dewar: Optional[int] = None dewar_id: Optional[int] = None positions: Optional[List[int]] = None class Puck(PuckBase): id: int positions: List[Sample] = [] class Config: from_attributes = True # Dewar schemas class DewarBase(BaseModel): dewar_name: str tracking_number: str number_of_pucks: int number_of_samples: int status: str ready_date: Optional[date] shipping_date: Optional[date] arrival_date: Optional[date] returning_date: Optional[date] qrcode: str contact_person_id: Optional[int] return_address_id: Optional[int] class DewarCreate(DewarBase): pass class Dewar(DewarBase): id: str shipment_id: Optional[str] contact_person: Optional[ContactPerson] return_address: Optional[Address] pucks: Optional[List[Puck]] = [] class Config: from_attributes = True class DewarUpdate(BaseModel): dewar_name: Optional[str] = None tracking_number: Optional[str] = None status: Optional[str] = None ready_date: Optional[date] = None shipping_date: Optional[date] = None arrival_date: Optional[date] = None returning_date: Optional[date] = None qrcode: Optional[str] = None contact_person_id: Optional[int] = None address_id: Optional[int] = None # Proposal schemas class Proposal(BaseModel): id: int number: str class Config: from_attributes = True # Shipment schemas class Shipment(BaseModel): shipment_id: str shipment_name: str shipment_date: date shipment_status: str comments: Optional[str] contact_person: Optional[ContactPerson] return_address: Optional[Address] proposal: Optional[Proposal] dewars: Optional[List[Dewar]] = [] class Config: from_attributes = True class ShipmentCreate(BaseModel): shipment_name: str shipment_date: date shipment_status: str comments: Optional[constr(max_length=500)] contact_person_id: int return_address_id: int proposal_id: int dewars: Optional[List[DewarUpdate]] = [] class Config: from_attributes = True class UpdateShipmentComments(BaseModel): comments: str