115 lines
3.5 KiB
Python
115 lines
3.5 KiB
Python
from datetime import datetime
|
|
|
|
from pydantic import BaseModel, Field, validator
|
|
|
|
from app.models.product import ProductStatus
|
|
|
|
|
|
class ProductImageBase(BaseModel):
|
|
image_url: str
|
|
alt_text: str | None = None
|
|
is_primary: bool | None = False
|
|
display_order: int | None = 0
|
|
|
|
class ProductImageCreate(ProductImageBase):
|
|
pass
|
|
|
|
class ProductImageUpdate(ProductImageBase):
|
|
image_url: str | None = None
|
|
|
|
class ProductImage(ProductImageBase):
|
|
id: str
|
|
product_id: str
|
|
created_at: datetime
|
|
|
|
class Config:
|
|
orm_mode = True
|
|
|
|
class ProductBase(BaseModel):
|
|
name: str
|
|
description: str | None = None
|
|
price: float = Field(..., gt=0)
|
|
sku: str | None = None
|
|
barcode: str | None = None
|
|
stock_quantity: int = Field(0, ge=0)
|
|
weight: float | None = None
|
|
dimensions: str | None = None
|
|
status: ProductStatus = ProductStatus.DRAFT
|
|
is_featured: bool | None = False
|
|
is_digital: bool | None = False
|
|
digital_download_link: str | None = None
|
|
slug: str
|
|
tax_rate: float | None = 0.0
|
|
discount_price: float | None = None
|
|
discount_start_date: datetime | None = None
|
|
discount_end_date: datetime | None = None
|
|
category_id: str | None = None
|
|
|
|
@validator('discount_price')
|
|
def discount_price_must_be_less_than_price(cls, v, values):
|
|
if v is not None and 'price' in values and v >= values['price']:
|
|
raise ValueError('Discount price must be less than regular price')
|
|
return v
|
|
|
|
@validator('discount_end_date')
|
|
def end_date_must_be_after_start_date(cls, v, values):
|
|
if (v is not None and 'discount_start_date' in values
|
|
and values['discount_start_date'] is not None
|
|
and v <= values['discount_start_date']):
|
|
raise ValueError('Discount end date must be after start date')
|
|
return v
|
|
|
|
class ProductCreate(ProductBase):
|
|
images: list[ProductImageCreate] | None = None
|
|
tag_ids: list[str] | None = []
|
|
|
|
class ProductUpdate(BaseModel):
|
|
name: str | None = None
|
|
description: str | None = None
|
|
price: float | None = Field(None, gt=0)
|
|
sku: str | None = None
|
|
barcode: str | None = None
|
|
stock_quantity: int | None = Field(None, ge=0)
|
|
weight: float | None = None
|
|
dimensions: str | None = None
|
|
status: ProductStatus | None = None
|
|
is_featured: bool | None = None
|
|
is_digital: bool | None = None
|
|
digital_download_link: str | None = None
|
|
slug: str | None = None
|
|
tax_rate: float | None = None
|
|
discount_price: float | None = None
|
|
discount_start_date: datetime | None = None
|
|
discount_end_date: datetime | None = None
|
|
category_id: str | None = None
|
|
tag_ids: list[str] | None = None
|
|
|
|
@validator('discount_price')
|
|
def discount_price_validation(cls, v, values):
|
|
if v is not None and 'price' in values and values['price'] is not None and v >= values['price']:
|
|
raise ValueError('Discount price must be less than regular price')
|
|
return v
|
|
|
|
class ProductInDBBase(ProductBase):
|
|
id: str
|
|
seller_id: str | None
|
|
created_at: datetime
|
|
updated_at: datetime | None
|
|
|
|
class Config:
|
|
orm_mode = True
|
|
|
|
class Product(ProductInDBBase):
|
|
images: list[ProductImage] = []
|
|
average_rating: float | None = None
|
|
current_price: float
|
|
category_name: str | None = None
|
|
tags: list[str] = []
|
|
|
|
class ProductDetails(Product):
|
|
"""Extended product details including inventory and sales data"""
|
|
|
|
total_sales: int | None = None
|
|
total_revenue: float | None = None
|
|
in_stock: bool
|