# models/schema/vendor.py import re from datetime import datetime from typing import Dict, List, Optional from pydantic import BaseModel, ConfigDict, Field, field_validator class VendorCreate(BaseModel): """Schema for creating a new vendor.""" vendor_code: str = Field(..., description="Unique vendor identifier (e.g., TECHSTORE)") subdomain: str = Field(..., description="Unique subdomain for the vendor") name: str = Field(..., description="Display name of the vendor") description: Optional[str] = None # Owner information - REQUIRED for admin creation owner_email: str = Field(..., description="Email for the vendor owner account") # Contact information contact_phone: Optional[str] = None website: Optional[str] = None # Business information business_address: Optional[str] = None tax_number: Optional[str] = None # Letzshop CSV URLs (multi-language support) letzshop_csv_url_fr: Optional[str] = None letzshop_csv_url_en: Optional[str] = None letzshop_csv_url_de: Optional[str] = None # Theme configuration theme_config: Optional[Dict] = Field(default_factory=dict) @field_validator("owner_email") @classmethod def validate_owner_email(cls, v): if not v or "@" not in v or "." not in v: raise ValueError("Valid email address required for vendor owner") return v.lower() @field_validator("subdomain") @classmethod def validate_subdomain(cls, v): # Basic subdomain validation: lowercase alphanumeric with hyphens if v and not re.match(r'^[a-z0-9][a-z0-9-]*[a-z0-9]$', v): raise ValueError("Subdomain must contain only lowercase letters, numbers, and hyphens") return v.lower() if v else v @field_validator("vendor_code") @classmethod def validate_vendor_code(cls, v): # Ensure vendor code is uppercase for consistency return v.upper() if v else v class VendorUpdate(BaseModel): """Schema for updating vendor information.""" name: Optional[str] = None description: Optional[str] = None contact_email: Optional[str] = None contact_phone: Optional[str] = None website: Optional[str] = None business_address: Optional[str] = None tax_number: Optional[str] = None letzshop_csv_url_fr: Optional[str] = None letzshop_csv_url_en: Optional[str] = None letzshop_csv_url_de: Optional[str] = None theme_config: Optional[Dict] = None is_active: Optional[bool] = None @field_validator("contact_email") @classmethod def validate_contact_email(cls, v): if v and ("@" not in v or "." not in v): raise ValueError("Invalid email format") return v.lower() if v else v class VendorResponse(BaseModel): """Schema for vendor response data.""" model_config = ConfigDict(from_attributes=True) id: int vendor_code: str subdomain: str name: str description: Optional[str] owner_user_id: int # Contact information contact_email: Optional[str] contact_phone: Optional[str] website: Optional[str] # Business information business_address: Optional[str] tax_number: Optional[str] # Letzshop URLs letzshop_csv_url_fr: Optional[str] letzshop_csv_url_en: Optional[str] letzshop_csv_url_de: Optional[str] # Theme configuration theme_config: Dict # Status flags is_active: bool is_verified: bool # Timestamps created_at: datetime updated_at: datetime class VendorListResponse(BaseModel): """Schema for paginated vendor list.""" vendors: List[VendorResponse] total: int skip: int limit: int class VendorSummary(BaseModel): """Lightweight vendor summary for dropdowns and quick references.""" model_config = ConfigDict(from_attributes=True) id: int vendor_code: str subdomain: str name: str is_active: bool class VendorCreateResponse(VendorResponse): """Extended response for vendor creation with owner credentials.""" owner_email: str owner_username: str temporary_password: str login_url: Optional[str] = None