| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- """运输计划管理 - 运费结算 Schema"""
- from datetime import date, datetime
- from decimal import Decimal
- from typing import Any, Optional
- from pydantic import BaseModel, Field, model_validator
- # =============================================================================
- # 运费结算 Schema
- # =============================================================================
- class FreightSettlementBase(BaseModel):
- total_freight: Decimal = Field(default=Decimal("0.00"), alias="totalFreight", description="运费合计")
- invoice_amount: Optional[Decimal] = Field(default=None, alias="invoiceAmount", description="发票金额")
- invoice_no: Optional[str] = Field(default=None, max_length=50, alias="invoiceNo", description="发票号")
- invoice_date: Optional[date] = Field(default=None, alias="invoiceDate", description="开票日期")
- invoice_attachment_urls: Optional[str] = Field(
- default=None, alias="invoiceAttachmentUrls", description="发票附件URLs,逗号分隔"
- )
- settlement_status: str = Field(default="pending", alias="settlementStatus", description="结算状态")
- remark: Optional[str] = None
- class FreightSettlementCreate(BaseModel):
- transport_ids: Optional[list[str]] = Field(default=None, alias="transportIds", description="运输ID列表")
- plan_ids: Optional[list[str]] = Field(default=None, alias="planIds", description="计划ID列表")
- model_config = {"populate_by_name": True}
- @model_validator(mode="after")
- def check_ids(self):
- if not self.transport_ids and not self.plan_ids:
- raise ValueError("transportIds 或 planIds 至少提供一个")
- return self
- class FreightSettlementUpdate(BaseModel):
- invoice_amount: Optional[Decimal] = Field(default=None, alias="invoiceAmount")
- invoice_no: Optional[str] = Field(default=None, max_length=50, alias="invoiceNo")
- invoice_date: Optional[date] = Field(default=None, alias="invoiceDate")
- invoice_attachment_urls: Optional[str] = Field(default=None, alias="invoiceAttachmentUrls")
- remark: Optional[str] = None
- transport_ids: Optional[list[str]] = Field(
- default=None, alias="transportIds", description="关联运输ID全量列表,仅草稿可更新"
- )
- model_config = {"populate_by_name": True}
- class FreightSettlementRead(FreightSettlementBase):
- id: str
- settlement_no: str = Field(alias="settlementNo")
- tenant_no: str = Field(alias="tenantNo")
- order_num: Optional[int] = Field(default=None, alias="orderNum")
- create_by: Optional[str] = Field(default=None, alias="createBy")
- create_dept_id: Optional[str] = Field(default=None, alias="createDeptId")
- create_time: datetime = Field(alias="createTime")
- update_by: Optional[str] = Field(default=None, alias="updateBy")
- update_time: datetime = Field(alias="updateTime")
- del_flag: int = Field(default=0, alias="delFlag")
- model_config = {"from_attributes": True, "populate_by_name": True}
- class FreightSettlementListItem(FreightSettlementRead):
- plan_count: int = Field(default=0, alias="planCount")
- license_plate_summary: Optional[str] = Field(default=None, alias="licensePlateSummary")
- current_approver_name: Optional[str] = Field(default=None, alias="currentApproverName")
- can_approve: bool = Field(default=False, alias="canApprove")
- can_withdraw: bool = Field(default=False, alias="canWithdraw")
- current_approval_id: Optional[str] = Field(default=None, alias="currentApprovalId")
- approval_finished_time: Optional[datetime] = Field(default=None, alias="approvalFinishedTime")
- disburse_time: Optional[datetime] = Field(default=None, alias="disburseTime")
- disburse_amount: Optional[Decimal] = Field(default=None, alias="disburseAmount")
- submitter_name: Optional[str] = Field(default=None, alias="submitterName")
- model_config = {"from_attributes": True, "populate_by_name": True}
- class FreightSettlementTransportRead(BaseModel):
- id: str
- settlement_id: str = Field(alias="settlementId")
- transport_id: str = Field(alias="transportId")
- freight_amount: Decimal = Field(alias="freightAmount")
- tenant_no: str = Field(alias="tenantNo")
- create_time: datetime = Field(alias="createTime")
- model_config = {"from_attributes": True, "populate_by_name": True}
- class UnsettledPlanItem(BaseModel):
- id: str
- plan_no: str = Field(alias="planNo")
- plan_date: Optional[date] = Field(default=None, alias="planDate")
- plan_type: str = Field(alias="planType")
- customer_name: Optional[str] = Field(default=None, alias="customerName")
- supplier_name: Optional[str] = Field(default=None, alias="supplierName")
- license_plate: Optional[str] = Field(default=None, alias="licensePlate")
- transport_company: Optional[str] = Field(default=None, alias="transportCompany")
- freight_amount: Decimal = Field(default=Decimal("0"), alias="freightAmount")
- archive_time: Optional[datetime] = Field(default=None, alias="archiveTime")
- transport_id: str = Field(alias="transportId")
- transport_no: Optional[str] = Field(default=None, alias="transportNo")
- driver_name: Optional[str] = Field(default=None, alias="driverName")
- transport_medium: Optional[str] = Field(default=None, alias="transportMedium")
- start_point: Optional[str] = Field(default=None, alias="startPoint")
- end_point: Optional[str] = Field(default=None, alias="endPoint")
- model_config = {"populate_by_name": True}
- class UnsettledPlanListResponse(BaseModel):
- total: int
- list: list[UnsettledPlanItem]
- class SettlementPlanSummary(BaseModel):
- id: str
- plan_no: str = Field(alias="planNo")
- plan_date: Optional[date] = Field(default=None, alias="planDate")
- license_plate: Optional[str] = Field(default=None, alias="licensePlate")
- freight_amount: Optional[Decimal] = Field(default=None, alias="freightAmount")
- model_config = {"populate_by_name": True}
- class SettlementApprovalFlowItem(BaseModel):
- id: str
- step: int
- step_name: Optional[str] = Field(default=None, alias="stepName")
- approver_id: str = Field(alias="approverId")
- approver_name: Optional[str] = Field(default=None, alias="approverName")
- approval_type: Optional[str] = Field(default=None, alias="approvalType")
- approval_result: str = Field(alias="approvalResult")
- approval_opinion: Optional[str] = Field(default=None, alias="approvalOpinion")
- approval_time: Optional[datetime] = Field(default=None, alias="approvalTime")
- is_current: int = Field(default=0, alias="isCurrent")
- model_config = {"populate_by_name": True}
- class FreightSettlementWithTransports(FreightSettlementRead):
- transports: list = []
- plans: list[SettlementPlanSummary] = []
- approval_flow: list[SettlementApprovalFlowItem] = Field(default_factory=list, alias="approvalFlow")
- approval_history: list[SettlementApprovalFlowItem] = Field(default_factory=list, alias="approvalHistory")
- vouchers: list = []
- plan_count: int = Field(default=0, alias="planCount")
- license_plate_summary: Optional[str] = Field(default=None, alias="licensePlateSummary")
- current_approver_name: Optional[str] = Field(default=None, alias="currentApproverName")
- can_approve: bool = Field(default=False, alias="canApprove")
- can_withdraw: bool = Field(default=False, alias="canWithdraw")
- current_approval_id: Optional[str] = Field(default=None, alias="currentApprovalId")
- approval_finished_time: Optional[datetime] = Field(default=None, alias="approvalFinishedTime")
- disburse_time: Optional[datetime] = Field(default=None, alias="disburseTime")
- disburse_amount: Optional[Decimal] = Field(default=None, alias="disburseAmount")
- submitter_name: Optional[str] = Field(default=None, alias="submitterName")
- class FreightSettlementSubmitApprovalBody(BaseModel):
- approval_type: str = Field(default="sequential", alias="approvalType")
- approver_ids: list[str] = Field(..., alias="approverIds", min_length=1)
- remark: Optional[str] = None
- model_config = {"populate_by_name": True}
- class FreightSettlementApprovalActionBody(BaseModel):
- action: str = Field(..., description="approve|reject")
- comment: Optional[str] = None
- class FreightSettlementDisburseBody(BaseModel):
- remittance_date: date = Field(..., alias="remittanceDate")
- remittance_amount: Decimal = Field(..., alias="remittanceAmount", gt=0)
- voucher_urls: list[str] = Field(..., alias="voucherUrls", min_length=1)
- remark: Optional[str] = None
- model_config = {"populate_by_name": True}
- # =============================================================================
- # 汇款凭证 Schema
- # =============================================================================
- class RemittanceVoucherCreate(BaseModel):
- settlement_id: str = Field(..., alias="settlementId", description="结算单ID")
- remittance_date: Optional[date] = Field(default=None, alias="remittanceDate", description="汇款日期")
- remittance_amount: Optional[Decimal] = Field(default=None, alias="remittanceAmount", description="汇款金额")
- voucher_urls: Optional[list[str]] = Field(default=None, alias="voucherUrls", description="凭证文件URLs")
- remark: Optional[str] = None
- model_config = {"populate_by_name": True}
- class RemittanceVoucherRead(BaseModel):
- id: str
- settlement_id: str = Field(alias="settlementId")
- voucher_no: Optional[str] = Field(default=None, alias="voucherNo")
- remittance_date: Optional[date] = Field(default=None, alias="remittanceDate")
- remittance_amount: Optional[Decimal] = Field(default=None, alias="remittanceAmount")
- voucher_urls: Optional[str] = Field(default=None, alias="voucherUrls")
- remark: Optional[str] = None
- tenant_no: str = Field(alias="tenantNo")
- create_by: Optional[str] = Field(default=None, alias="createBy")
- create_time: datetime = Field(alias="createTime")
- model_config = {"from_attributes": True, "populate_by_name": True}
- # =============================================================================
- # 列表查询
- # =============================================================================
- class FreightSettlementListQuery(BaseModel):
- q: Optional[str] = Field(default=None, description="模糊搜索")
- settlement_status: Optional[str] = Field(default=None, alias="settlementStatus", description="结算状态")
- tab: Optional[str] = Field(default=None, description="bills|disburse|settled")
- page: int = Field(default=1, ge=1)
- page_size: int = Field(default=20, ge=1, le=100, alias="pageSize")
- model_config = {"populate_by_name": True}
- class FreightSettlementListResponse(BaseModel):
- total: int
- list: list[FreightSettlementListItem]
- class FreightSettlementByTransportRead(BaseModel):
- id: str
- settlement_no: str = Field(alias="settlementNo")
- invoice_amount: Optional[Decimal] = Field(default=None, alias="invoiceAmount")
- invoice_no: Optional[str] = Field(default=None, alias="invoiceNo")
- invoice_date: Optional[date] = Field(default=None, alias="invoiceDate")
- invoice_attachment_urls: Optional[str] = Field(default=None, alias="invoiceAttachmentUrls")
- settlement_status: str = Field(alias="settlementStatus")
- model_config = {"populate_by_name": True}
|