feat(T06): Verkaufsmodul + Rechtsdokumente + DATEV-Export + Sales UI
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
"""Pydantic schemas for sale-related request and response bodies."""
|
||||
|
||||
import uuid
|
||||
from datetime import date, datetime
|
||||
from decimal import Decimal
|
||||
from typing import Literal, Optional
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
|
||||
SALE_STATUSES = Literal["draft", "completed", "cancelled"]
|
||||
|
||||
|
||||
class SaleCreate(BaseModel):
|
||||
"""POST /api/v1/sales request body."""
|
||||
|
||||
vehicle_id: uuid.UUID
|
||||
buyer_contact_id: uuid.UUID
|
||||
seller_contact_id: Optional[uuid.UUID] = None
|
||||
sale_price: Decimal = Field(..., ge=0)
|
||||
sale_date: Optional[date] = None
|
||||
status: SALE_STATUSES = "draft"
|
||||
is_gwg: bool = False
|
||||
|
||||
|
||||
class SaleUpdate(BaseModel):
|
||||
"""PUT /api/v1/sales/:id request body (all fields optional)."""
|
||||
|
||||
sale_price: Optional[Decimal] = Field(None, ge=0)
|
||||
sale_date: Optional[date] = None
|
||||
status: Optional[SALE_STATUSES] = None
|
||||
is_gwg: Optional[bool] = None
|
||||
seller_contact_id: Optional[uuid.UUID] = None
|
||||
|
||||
|
||||
class VehicleNested(BaseModel):
|
||||
"""Nested vehicle info in sale response."""
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: uuid.UUID
|
||||
make: str
|
||||
model: str
|
||||
fin: str
|
||||
vehicle_type: str
|
||||
availability: str
|
||||
price: Decimal
|
||||
|
||||
|
||||
class ContactNested(BaseModel):
|
||||
"""Nested contact info in sale response."""
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: uuid.UUID
|
||||
company_name: str
|
||||
address_city: Optional[str] = None
|
||||
address_country: str
|
||||
vat_id: Optional[str] = None
|
||||
email: Optional[str] = None
|
||||
phone: Optional[str] = None
|
||||
|
||||
|
||||
class SaleResponse(BaseModel):
|
||||
"""Sale response schema with nested vehicle and contacts."""
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: uuid.UUID
|
||||
vehicle_id: uuid.UUID
|
||||
buyer_contact_id: uuid.UUID
|
||||
seller_contact_id: Optional[uuid.UUID] = None
|
||||
sale_price: Decimal
|
||||
sale_date: date
|
||||
status: str
|
||||
is_gwg: bool
|
||||
contract_pdf_path: Optional[str] = None
|
||||
created_at: Optional[datetime] = None
|
||||
updated_at: Optional[datetime] = None
|
||||
vehicle: Optional[VehicleNested] = None
|
||||
buyer: Optional[ContactNested] = None
|
||||
seller: Optional[ContactNested] = None
|
||||
|
||||
|
||||
class SaleListResponse(BaseModel):
|
||||
"""Paginated sale list response."""
|
||||
|
||||
items: list[SaleResponse]
|
||||
total: int
|
||||
page: int
|
||||
page_size: int
|
||||
|
||||
|
||||
class ContractResponse(BaseModel):
|
||||
"""Response for contract PDF generation/download."""
|
||||
|
||||
sale_id: uuid.UUID
|
||||
contract_pdf_path: str
|
||||
message: str = "Contract generated"
|
||||
|
||||
|
||||
class UstIdVerifyResponse(BaseModel):
|
||||
"""Response for USt-IdNr. verification."""
|
||||
|
||||
verified: bool
|
||||
message: str
|
||||
vat_id: Optional[str] = None
|
||||
Reference in New Issue
Block a user