103 lines
2.5 KiB
Python
103 lines
2.5 KiB
Python
from pydantic import BaseModel, Field, EmailStr, field_validator
|
|
from typing import List, Optional
|
|
from datetime import datetime
|
|
from bson import ObjectId
|
|
from pydantic import ConfigDict
|
|
from typing import Any, ClassVar
|
|
|
|
|
|
class PyObjectId(ObjectId):
|
|
@classmethod
|
|
def __get_pydantic_core_schema__(
|
|
cls, _source_type: Any, _handler: Any
|
|
) -> Any:
|
|
from pydantic_core import core_schema
|
|
return core_schema.json_or_python_schema(
|
|
python_schema=core_schema.is_instance_schema(ObjectId),
|
|
json_schema=core_schema.StringSchema(),
|
|
serialization=core_schema.to_string_ser_schema(),
|
|
)
|
|
|
|
|
|
class MongoBaseModel(BaseModel):
|
|
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
|
|
|
|
model_config = ConfigDict(
|
|
populate_by_name=True,
|
|
arbitrary_types_allowed=True,
|
|
json_encoders={ObjectId: str}
|
|
)
|
|
|
|
|
|
class Item(MongoBaseModel):
|
|
name: str
|
|
price: float
|
|
quantity: int
|
|
unit: str
|
|
related_items: List[str] = []
|
|
|
|
|
|
class OrderItem(BaseModel):
|
|
item_id: PyObjectId
|
|
quantity: int
|
|
price_at_order: float
|
|
|
|
|
|
class Order(MongoBaseModel):
|
|
user_id: PyObjectId
|
|
items: List[OrderItem]
|
|
total_amount: float
|
|
payment_method: Optional[str] = None
|
|
payment_status: str = "pending"
|
|
order_status: str = "created"
|
|
created_at: datetime = Field(default_factory=datetime.now(datetime.UTC))
|
|
updated_at: Optional[datetime] = None
|
|
discount_applied: Optional[float] = None
|
|
notes: Optional[str] = None
|
|
|
|
@field_validator('order_status')
|
|
def valid_order_status(cls, v):
|
|
allowed_statuses = ["created", "processing",
|
|
"shipped", "delivered", "cancelled"]
|
|
if v not in allowed_statuses:
|
|
raise ValueError(f"Invalid order status. Must be one of: {
|
|
', '.join(allowed_statuses)}")
|
|
return v
|
|
|
|
@field_validator('payment_status')
|
|
def valid_payment_status(cls, v):
|
|
allowed_statuses = ["pending", "paid", "refunded", "failed"]
|
|
if v not in allowed_statuses:
|
|
raise ValueError(f"Invalid payment status. Must be one of: {
|
|
', '.join(allowed_statuses)}")
|
|
return v
|
|
|
|
|
|
class UserBase(BaseModel):
|
|
username: str
|
|
email: EmailStr
|
|
full_name: str
|
|
is_active: bool = True
|
|
is_superuser: bool = False
|
|
|
|
|
|
class UserCreate(UserBase):
|
|
password: str
|
|
|
|
|
|
class UserInDB(UserBase, MongoBaseModel):
|
|
hashed_password: str
|
|
|
|
|
|
class User(UserBase, MongoBaseModel):
|
|
pass
|
|
|
|
|
|
class Token(BaseModel):
|
|
access_token: str
|
|
token_type: str
|
|
|
|
|
|
class TokenData(BaseModel):
|
|
username: Optional[str] = None
|