815cbf9d8c
- 更新 .gitignore:全面覆盖环境变量、数据库、日志、缓存、上传文件 - 移除误跟踪的 server/venv/、crm_data.db、.env 文件 - 新增 server/.env.example 模板 - 新增合同管理、利润核算、AI教练等功能模块 - 新增 Playwright e2e 测试套件 - 前后端多项功能升级和 bug 修复
107 lines
3.5 KiB
Python
107 lines
3.5 KiB
Python
"""
|
|
合同域 Pydantic V2 Schemas
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from datetime import date, datetime
|
|
from typing import Any
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
|
|
# ── 合同明细行 ────────────────────────────────────────────
|
|
class ContractItemCreate(BaseModel):
|
|
sku_id: uuid.UUID
|
|
qty: float = Field(gt=0)
|
|
unit_price: float = Field(ge=0)
|
|
sub_total: float = Field(ge=0)
|
|
|
|
|
|
class ContractItemResponse(BaseModel):
|
|
id: uuid.UUID
|
|
sku_id: uuid.UUID
|
|
sku_code: str | None = None
|
|
sku_name: str | None = None
|
|
spec: str | None = None
|
|
unit: str | None = None
|
|
qty: float
|
|
unit_price: float
|
|
sub_total: float
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
# ── 合同创建 ──────────────────────────────────────────────
|
|
class ContractCreate(BaseModel):
|
|
buyer_customer_id: uuid.UUID
|
|
items: list[ContractItemCreate] = Field(min_length=1)
|
|
payment_terms: str = "货到付全款"
|
|
shipping_terms: str = "买方自提"
|
|
remark: str | None = None
|
|
delivery_terms: str | None = None
|
|
sign_date: date | None = None
|
|
|
|
|
|
# ── 合同更新 ──────────────────────────────────────────────
|
|
class ContractUpdate(BaseModel):
|
|
buyer_customer_id: uuid.UUID | None = None
|
|
items: list[ContractItemCreate] | None = None
|
|
payment_terms: str | None = None
|
|
shipping_terms: str | None = None
|
|
status: str | None = None
|
|
is_signed: bool | None = None
|
|
remark: str | None = None
|
|
delivery_terms: str | None = None
|
|
sign_date: date | None = None
|
|
|
|
|
|
# ── 执行进度 ──────────────────────────────────────────────
|
|
class ContractProgressResponse(BaseModel):
|
|
is_signed: bool = False
|
|
has_order: bool = False
|
|
order_id: uuid.UUID | None = None
|
|
has_shipped: bool = False
|
|
has_invoice: bool = False
|
|
is_paid: bool = False
|
|
|
|
|
|
# ── 合同响应 ──────────────────────────────────────────────
|
|
class ContractResponse(BaseModel):
|
|
id: uuid.UUID
|
|
contract_no: str
|
|
buyer_customer_id: uuid.UUID
|
|
buyer_customer_name: str | None = None
|
|
seller_company_id: uuid.UUID
|
|
seller_company_name: str | None = None
|
|
company_id: uuid.UUID
|
|
total_amount_excl_tax: float = 0
|
|
total_amount_incl_tax: float = 0
|
|
total_amount_cn: str | None = None
|
|
payment_terms: str
|
|
shipping_terms: str
|
|
status: str
|
|
is_signed: bool = False
|
|
signed_file_url: str | None = None
|
|
linked_order_id: uuid.UUID | None = None
|
|
salesperson_id: uuid.UUID | None = None
|
|
salesperson_name: str | None = None
|
|
sign_date: date | None = None
|
|
remark: str | None = None
|
|
delivery_terms: str | None = None
|
|
items: list[ContractItemResponse] = []
|
|
progress: ContractProgressResponse | None = None
|
|
created_at: datetime
|
|
updated_at: datetime
|
|
|
|
model_config = {"from_attributes": True}
|
|
|
|
|
|
# ── 分页列表 ──────────────────────────────────────────────
|
|
class ContractListResponse(BaseModel):
|
|
total: int
|
|
items: list[ContractResponse]
|
|
page: int
|
|
size: int
|