198 lines
5.2 KiB
Python
198 lines
5.2 KiB
Python
from datetime import datetime
|
|
from typing import Optional, List, Any, Dict, Union
|
|
from uuid import UUID
|
|
|
|
from pydantic import BaseModel, Field, field_validator, model_validator
|
|
|
|
from app.models.gift import GiftStatus, GiftPriority
|
|
|
|
|
|
# Base Gift Schema
|
|
class GiftItemBase(BaseModel):
|
|
name: str
|
|
description: Optional[str] = None
|
|
price: Optional[float] = None
|
|
currency: Optional[str] = "USD"
|
|
quantity_requested: Optional[int] = 1
|
|
quantity_received: Optional[int] = 0
|
|
status: Optional[GiftStatus] = GiftStatus.AVAILABLE
|
|
priority: Optional[GiftPriority] = GiftPriority.MEDIUM
|
|
purchase_url: Optional[str] = None
|
|
store_name: Optional[str] = None
|
|
brand: Optional[str] = None
|
|
model: Optional[str] = None
|
|
image_url: Optional[str] = None
|
|
display_order: Optional[int] = None
|
|
is_visible: Optional[bool] = True
|
|
notes: Optional[str] = None
|
|
custom_fields: Optional[Dict[str, Any]] = None
|
|
|
|
|
|
# Schema for creating a gift
|
|
class GiftItemCreate(GiftItemBase):
|
|
event_id: UUID
|
|
added_by: UUID
|
|
category_id: Optional[UUID] = None
|
|
|
|
@field_validator('price')
|
|
@classmethod
|
|
def validate_price(cls, v: Optional[float]) -> Optional[float]:
|
|
if v is not None and v < 0:
|
|
raise ValueError("Price cannot be negative")
|
|
return v
|
|
|
|
@field_validator('quantity_requested')
|
|
@classmethod
|
|
def validate_quantity(cls, v: Optional[int]) -> Optional[int]:
|
|
if v is not None and v < 1:
|
|
raise ValueError("Quantity requested must be at least 1")
|
|
return v
|
|
|
|
|
|
# Schema for updating a gift
|
|
class GiftItemUpdate(BaseModel):
|
|
name: Optional[str] = None
|
|
description: Optional[str] = None
|
|
price: Optional[float] = None
|
|
currency: Optional[str] = None
|
|
quantity_requested: Optional[int] = None
|
|
quantity_received: Optional[int] = None
|
|
status: Optional[GiftStatus] = None
|
|
priority: Optional[GiftPriority] = None
|
|
purchase_url: Optional[str] = None
|
|
store_name: Optional[str] = None
|
|
brand: Optional[str] = None
|
|
model: Optional[str] = None
|
|
image_url: Optional[str] = None
|
|
display_order: Optional[int] = None
|
|
is_visible: Optional[bool] = None
|
|
notes: Optional[str] = None
|
|
custom_fields: Optional[Dict[str, Any]] = None
|
|
category_id: Optional[UUID] = None
|
|
|
|
@field_validator('price')
|
|
@classmethod
|
|
def validate_price(cls, v: Optional[float]) -> Optional[float]:
|
|
if v is not None and v < 0:
|
|
raise ValueError("Price cannot be negative")
|
|
return v
|
|
|
|
@field_validator('quantity_requested')
|
|
@classmethod
|
|
def validate_quantity(cls, v: Optional[int]) -> Optional[int]:
|
|
if v is not None and v < 1:
|
|
raise ValueError("Quantity requested must be at least 1")
|
|
return v
|
|
|
|
|
|
# Schema for reading a gift
|
|
class GiftItemInDB(GiftItemBase):
|
|
id: UUID
|
|
event_id: UUID
|
|
added_by: UUID
|
|
category_id: Optional[UUID] = None
|
|
last_status_change: Optional[datetime] = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# Public gift item response
|
|
class GiftItem(GiftItemInDB):
|
|
remaining_quantity: int
|
|
is_fully_received: bool
|
|
formatted_price: str
|
|
reserved: bool = False
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# Gift Category Schemas
|
|
class GiftCategoryBase(BaseModel):
|
|
name: str
|
|
description: Optional[str] = None
|
|
icon: Optional[str] = None
|
|
color: Optional[str] = None
|
|
display_order: Optional[int] = 0
|
|
is_visible: Optional[bool] = True
|
|
custom_fields: Optional[Dict[str, Any]] = None
|
|
|
|
|
|
# Schema for creating a category
|
|
class GiftCategoryCreate(GiftCategoryBase):
|
|
event_id: UUID
|
|
created_by: UUID
|
|
|
|
|
|
# Schema for updating a category
|
|
class GiftCategoryUpdate(BaseModel):
|
|
name: Optional[str] = None
|
|
description: Optional[str] = None
|
|
icon: Optional[str] = None
|
|
color: Optional[str] = None
|
|
display_order: Optional[int] = None
|
|
is_visible: Optional[bool] = None
|
|
custom_fields: Optional[Dict[str, Any]] = None
|
|
|
|
|
|
# Schema for reading a category
|
|
class GiftCategoryInDB(GiftCategoryBase):
|
|
id: UUID
|
|
event_id: UUID
|
|
created_by: UUID
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# Public category response with statistics
|
|
class GiftCategory(GiftCategoryInDB):
|
|
total_gifts: int
|
|
available_gifts: int
|
|
gifts: Optional[List[GiftItem]] = None
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# Gift Purchase Schemas
|
|
class GiftPurchaseBase(BaseModel):
|
|
gift_id: UUID
|
|
guest_id: UUID
|
|
quantity: int = 1
|
|
purchase_price: Optional[float] = None
|
|
purchase_currency: Optional[str] = None
|
|
notes: Optional[str] = None
|
|
|
|
|
|
# Schema for creating a purchase
|
|
class GiftPurchaseCreate(GiftPurchaseBase):
|
|
pass
|
|
|
|
|
|
# Schema for updating a purchase
|
|
class GiftPurchaseUpdate(BaseModel):
|
|
quantity: Optional[int] = None
|
|
purchase_price: Optional[float] = None
|
|
purchase_currency: Optional[str] = None
|
|
notes: Optional[str] = None
|
|
|
|
|
|
# Schema for reading a purchase
|
|
class GiftPurchaseInDB(GiftPurchaseBase):
|
|
id: UUID
|
|
purchased_at: datetime
|
|
|
|
class Config:
|
|
from_attributes = True
|
|
|
|
|
|
# Public gift purchase response
|
|
class GiftPurchase(GiftPurchaseInDB):
|
|
class Config:
|
|
from_attributes = True |