Olympus/backend/hermes/app/schemas/customer.py
2026-07-02 23:37:46 +02:00

131 lines
3.7 KiB
Python

from datetime import datetime
from typing import Literal
from pydantic import BaseModel, ConfigDict, EmailStr, Field, HttpUrl, field_validator
CustomerStatus = Literal["lead", "active", "inactive", "blocked", "archived"]
CustomerType = Literal["company", "private", "public_sector", "partner", "supplier"]
AddressType = Literal["billing", "shipping", "primary", "other"]
def normalize_optional_text(value: object) -> str:
if value is None:
return ""
return str(value).strip()
class CustomerAddressBase(BaseModel):
type: AddressType = "primary"
street: str = Field(default="", max_length=255)
postal_code: str = Field(default="", max_length=30)
city: str = Field(default="", max_length=120)
state: str = Field(default="", max_length=120)
country: str = Field(default="Deutschland", max_length=120)
is_primary: bool = False
@field_validator("street", "postal_code", "city", "state", "country", mode="before")
@classmethod
def normalize_text(cls, value: object) -> str:
return normalize_optional_text(value)
class CustomerAddressCreate(CustomerAddressBase):
pass
class CustomerAddressUpdate(CustomerAddressBase):
pass
class CustomerAddressResponse(CustomerAddressBase):
id: int
customer_id: int
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class CustomerContactBase(BaseModel):
first_name: str = Field(default="", max_length=100)
last_name: str = Field(default="", max_length=100)
position: str = Field(default="", max_length=120)
email: EmailStr | None = None
phone: str = Field(default="", max_length=80)
mobile: str = Field(default="", max_length=80)
is_primary: bool = False
notes: str = ""
@field_validator("first_name", "last_name", "position", "phone", "mobile", "notes", mode="before")
@classmethod
def normalize_text(cls, value: object) -> str:
return normalize_optional_text(value)
class CustomerContactCreate(CustomerContactBase):
pass
class CustomerContactUpdate(CustomerContactBase):
pass
class CustomerContactResponse(CustomerContactBase):
id: int
customer_id: int
email: str
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)
class CustomerBase(BaseModel):
customer_number: str = Field(min_length=1, max_length=50)
company_name: str = Field(min_length=1, max_length=255)
legal_name: str = Field(default="", max_length=255)
customer_type: CustomerType
status: CustomerStatus
industry: str = Field(default="", max_length=120)
website: HttpUrl | None = None
email: EmailStr | None = None
phone: str = Field(default="", max_length=80)
tax_number: str = Field(default="", max_length=120)
vat_id: str = Field(default="", max_length=120)
notes: str = ""
@field_validator(
"customer_number",
"company_name",
"legal_name",
"industry",
"phone",
"tax_number",
"vat_id",
"notes",
mode="before",
)
@classmethod
def normalize_text(cls, value: object) -> str:
return normalize_optional_text(value)
class CustomerCreate(CustomerBase):
addresses: list[CustomerAddressCreate] = Field(default_factory=list)
contacts: list[CustomerContactCreate] = Field(default_factory=list)
class CustomerUpdate(CustomerBase):
addresses: list[CustomerAddressUpdate] = Field(default_factory=list)
class CustomerResponse(CustomerBase):
id: int
website: str
email: str
addresses: list[CustomerAddressResponse]
contacts: list[CustomerContactResponse]
created_at: datetime
updated_at: datetime
model_config = ConfigDict(from_attributes=True)