Files
shanxia2.0/backend/app/schemas/crm/quote.py
T

269 lines
7.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""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 QuoteColumnFilterMixin(BaseModel):
"""列头漏斗参数:前端 camelCase ↔ 后端 snake_case,供 build_quote_column_filters。"""
model_config = ConfigDict(populate_by_name=True)
quote_no: Optional[str] = Field(default=None, alias="quoteNo", description="报价单号")
customer_name: Optional[str] = Field(default=None, alias="customerName", description="客户名称")
quote_no_in: Optional[str] = Field(default=None, alias="quoteNoIn", description="报价单号多选(逗号)")
customer_name_in: Optional[str] = Field(
default=None, alias="customerNameIn", description="客户名称多选(逗号)"
)
class QuoteListBody(QuoteColumnFilterMixin):
"""列表/导出查询;extra=allow 接收列头漏斗动态参数(*In / *From|To / *Op|Min|Max 等)。"""
model_config = ConfigDict(populate_by_name=True, extra="allow")
page: int = Field(default=1, ge=1)
pageSize: int = Field(default=10, ge=1, le=500)
keyword: Optional[str] = None
quoteTitle: 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
sortField: Optional[str] = None
sortOrder: Optional[str] = None
ids: Optional[List[str]] = Field(default=None, description="导出指定ID列表")
columns: Optional[List[str]] = Field(default=None, description="导出列(前端 visibleColumns)")
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)
barrelDeposit: 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
products: Optional[List[QuoteProductItem]] = None
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
invalidReason: Optional[str] = None
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
class QuoteColumnFacetBody(QuoteColumnFilterMixin):
"""报价列表列头可选值(去重;可附带列表上下文)"""
model_config = ConfigDict(populate_by_name=True, extra="allow")
field: str = Field(..., description="quoteNo | customerName")
keyword: Optional[str] = Field(default=None, description="列表搜索关键词")
limit: Optional[int] = Field(default=500, ge=1, le=500, description="返回条数上限")