232 lines
11 KiB
Python
232 lines
11 KiB
Python
"""运输计划管理 - 运费结算 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")
|
|
freight_remark: Optional[str] = Field(default=None, alias="freightRemark")
|
|
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")
|
|
freight_remark: Optional[str] = Field(default=None, alias="freightRemark")
|
|
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=500, 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}
|