"""Chore schemas.""" from pydantic import BaseModel, ConfigDict, field_validator from typing import Optional, Union, List from datetime import datetime, date from app.models.chore import ChoreFrequency, ChoreStatus, ChoreAssignmentType class ChoreBase(BaseModel): """Base chore schema.""" title: str description: Optional[str] = None room: str frequency: ChoreFrequency points: Optional[int] = 0 image_url: Optional[str] = None assignment_type: Optional[ChoreAssignmentType] = ChoreAssignmentType.ANY_ONE due_date: Optional[Union[datetime, date, str]] = None @field_validator('due_date', mode='before') @classmethod def parse_due_date(cls, v): """Parse due_date to handle various formats.""" if v is None or v == '' or isinstance(v, (datetime, date)): return None if v == '' else v if isinstance(v, str): # Try parsing as datetime first for fmt in ['%Y-%m-%dT%H:%M:%S', '%Y-%m-%d']: try: return datetime.strptime(v, fmt) except ValueError: continue # If no format matches, return None instead of the invalid string return None return None class ChoreCreate(ChoreBase): """Schema for creating a chore.""" assigned_user_ids: Optional[List[int]] = [] # Multiple users can be assigned class ChoreUpdate(BaseModel): """Schema for updating a chore.""" title: Optional[str] = None description: Optional[str] = None room: Optional[str] = None frequency: Optional[ChoreFrequency] = None points: Optional[int] = None status: Optional[ChoreStatus] = None assignment_type: Optional[ChoreAssignmentType] = None assigned_user_ids: Optional[List[int]] = None # Multiple users due_date: Optional[Union[datetime, date, str]] = None @field_validator('due_date', mode='before') @classmethod def parse_due_date(cls, v): """Parse due_date to handle various formats.""" if v is None or v == '' or isinstance(v, (datetime, date)): return None if v == '' else v if isinstance(v, str): # Try parsing as datetime first for fmt in ['%Y-%m-%dT%H:%M:%S', '%Y-%m-%d']: try: return datetime.strptime(v, fmt) except ValueError: continue # If no format matches, return None instead of the invalid string return None return None class AssignedUserDetail(BaseModel): """User info for chore assignment.""" model_config = ConfigDict(from_attributes=True) id: int username: str full_name: str avatar_url: Optional[str] = None birthday: Optional[date] = None completed_at: Optional[datetime] = None # When this user completed the chore class Chore(ChoreBase): """Schema for a chore response.""" model_config = ConfigDict(from_attributes=True) id: int status: ChoreStatus points: int assignment_type: ChoreAssignmentType assigned_users: List[AssignedUserDetail] = [] # Multiple users with completion status completed_at: Optional[datetime] = None created_at: datetime updated_at: datetime # Legacy field for backward compatibility assigned_user_id: Optional[int] = None