Files
shanxia2.0/backend/app/schemas/crm/quote.py
T
zlwuandCursor 10c3c5470c chore: sync local PL/CRM/BX and migration work to new Gogs host
Bundle pending backend/web-admin feature updates, data-migration scripts,
and related docs so the V1.5 branch on the Tencent Cloud Gogs matches the
current workspace (excluding local secrets).

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-01 09:19:21 +08:00

238 lines
6.0 KiB
Python

"""CRM 报价单 Pydantic Schemas"""
from typing import List, Optional
from pydantic import BaseModel, ConfigDict, Field
class QuoteProductItem(BaseModel):
model_config = ConfigDict(populate_by_name=True)
id: Optional[str] = None
productId: Optional[str] = None
productName: Optional[str] = None
productNo: Optional[str] = None
categoryId: Optional[str] = None
categoryName: Optional[str] = None
model: Optional[str] = None
unit: Optional[str] = None
quantity: float = Field(default=1, gt=0)
price: float = Field(default=0, ge=0)
discount: Optional[float] = Field(default=0)
taxRate: Optional[float] = Field(default=13.0)
taxAmount: Optional[float] = Field(default=0)
subtotal: Optional[float] = None
packageSpec: Optional[str] = None
deliveryMethod: Optional[str] = None
description: Optional[str] = None
sort: Optional[int] = None
remark: Optional[str] = None
brandMode: Optional[str] = None
brandId: Optional[str] = None
brandName: Optional[str] = None
class QuoteListBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
page: int = Field(default=1, ge=1)
pageSize: int = Field(default=10, ge=1, le=100)
keyword: Optional[str] = None
quoteNo: Optional[str] = None
quoteTitle: Optional[str] = None
customerName: Optional[str] = None
customerId: Optional[str] = None
opportunityId: Optional[str] = None
status: Optional[str] = None
excludeStatus: Optional[str] = None
quoteType: Optional[str] = None
ownerUserId: Optional[str] = None
isLatest: Optional[int] = None
minAmount: Optional[float] = None
maxAmount: Optional[float] = None
quoteDateBegin: Optional[str] = None
quoteDateEnd: Optional[str] = None
beginTime: Optional[str] = None
endTime: Optional[str] = None
approvedByUserId: Optional[str] = None
pendingApprovalUserId: Optional[str] = None
class QuoteDetailBody(BaseModel):
id: str
class QuoteDeleteBody(BaseModel):
ids: List[str]
class QuoteCreateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
quoteNo: Optional[str] = None
quoteTitle: Optional[str] = None
quoteType: Optional[str] = Field(default="sales")
customerId: str
customerName: Optional[str] = None
opportunityId: Optional[str] = None
contactId: Optional[str] = None
version: Optional[str] = None
parentId: Optional[str] = None
isLatest: Optional[int] = None
totalAmount: Optional[float] = None
discountRate: Optional[float] = Field(default=0)
discountAmount: Optional[float] = None
finalAmount: Optional[float] = None
validityDays: Optional[int] = Field(default=30)
quoteDate: Optional[str] = None
expireDate: Optional[str] = None
status: Optional[str] = Field(default="draft")
ownerUserId: Optional[str] = None
supplierId: Optional[str] = None
supplierName: Optional[str] = None
paymentTerms: Optional[str] = None
deliveryTerms: Optional[str] = None
freight: Optional[float] = Field(default=0)
attachments: Optional[str] = None
templateContent: Optional[str] = None
remark: Optional[str] = None
products: List[QuoteProductItem] = Field(default_factory=list)
class QuoteUpdateBody(QuoteCreateBody):
id: str
class QuoteSubmitBody(BaseModel):
id: str
approverIds: List[str] = Field(default_factory=list)
remark: Optional[str] = None
class QuoteTemplateSaveBody(BaseModel):
id: str
templateContent: str
class QuoteTemplateGetBody(BaseModel):
id: str
class QuotePdfBody(BaseModel):
id: str
class QuoteShareGenerateBody(BaseModel):
id: str
validityDays: Optional[int] = None
password: Optional[str] = None
class QuoteAcceptBody(BaseModel):
id: str
remark: Optional[str] = None
class QuoteRejectBody(BaseModel):
id: str
rejectReason: Optional[str] = None
remark: Optional[str] = None
class QuoteToContractBody(BaseModel):
id: str
contractNo: Optional[str] = None
contractTitle: Optional[str] = None
signDate: Optional[str] = None
startDate: Optional[str] = None
endDate: Optional[str] = None
class QuoteNewVersionBody(BaseModel):
id: str
version: str
remark: Optional[str] = None
class QuoteVersionsBody(BaseModel):
quoteNo: str
class QuoteInvalidBody(BaseModel):
id: str
remark: Optional[str] = None
class QuoteStatisticsOverviewBody(BaseModel):
ownerUserId: Optional[str] = None
beginTime: Optional[str] = None
endTime: Optional[str] = None
class QuoteStatisticsTrendBody(BaseModel):
type: Optional[str] = Field(default="month")
beginTime: Optional[str] = None
endTime: Optional[str] = None
class QuoteProductListBody(BaseModel):
quoteId: str
class QuoteProductCreateBody(BaseModel):
model_config = ConfigDict(populate_by_name=True)
quoteId: str
productId: Optional[str] = None
productName: Optional[str] = None
quantity: float = Field(default=1, gt=0)
price: float = Field(default=0, ge=0)
discount: Optional[float] = 0
taxRate: Optional[float] = 13.0
model: Optional[str] = None
unit: Optional[str] = None
categoryId: Optional[str] = None
categoryName: Optional[str] = None
description: Optional[str] = None
sort: Optional[int] = None
remark: Optional[str] = None
brandMode: Optional[str] = None
brandId: Optional[str] = None
brandName: Optional[str] = None
class QuoteProductUpdateBody(QuoteProductCreateBody):
id: str
class QuoteProductDeleteBody(BaseModel):
ids: List[str]
class QuoteApprovalListBody(BaseModel):
quoteId: str
class QuoteApprovalApproveBody(BaseModel):
id: str
approvalResult: str
approvalOpinion: Optional[str] = None
remark: Optional[str] = None
class QuoteApprovalWithdrawBody(BaseModel):
quoteId: str
remark: Optional[str] = None
class QuoteApprovalRefreshNamesBody(BaseModel):
quoteId: Optional[str] = None
class QuoteShareLogListBody(BaseModel):
quoteId: str
class QuoteShareLogStatisticsBody(BaseModel):
quoteId: str