Files
shanxia2.0/backend/app/schemas/bx/reimburse.py
T

217 lines
6.1 KiB
Python

from typing import List, Optional
from pydantic import BaseModel, ConfigDict, Field, field_validator
from pydantic.alias_generators import to_camel
from app.schemas.bx.common import DatetimeToStr, OptDateToStr, OptDatetimeToStr
def _coerce_id(value):
if value is None:
return None
return str(value).strip()
class ReimburseDetailCreate(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
expense_item_id: str
amount: float
remark: Optional[str] = None
@field_validator("expense_item_id", mode="before")
@classmethod
def validate_expense_item_id(cls, value):
s = _coerce_id(value)
if not s:
raise ValueError("费用项目不能为空")
return s
class ReimburseDetailOut(BaseModel):
model_config = ConfigDict(from_attributes=True, populate_by_name=True, alias_generator=to_camel)
id: str
expense_id: str
expense_name: str
amount: float
remark: Optional[str] = None
class ReimburseInvoiceBriefOut(BaseModel):
model_config = ConfigDict(from_attributes=True, populate_by_name=True, alias_generator=to_camel)
id: str
amount: float
owner_user_name: Optional[str] = None
class ReimburseApplyCreate(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
title: Optional[str] = None
reimburse_date: Optional[str] = None
details: List[ReimburseDetailCreate] = Field(..., min_length=1)
remark: Optional[str] = None
invoice_ids: Optional[List[str]] = None
@field_validator("details")
@classmethod
def details_must_not_be_empty(cls, value):
if not value or len(value) < 1:
raise ValueError("至少需要一条报销明细")
return value
class ReimburseApplyUpdate(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
details: Optional[List[ReimburseDetailCreate]] = None
title: Optional[str] = None
reimburse_date: Optional[str] = None
remark: Optional[str] = None
invoice_ids: Optional[List[str]] = None
class ReimburseSubmitBody(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
invoice_ids: Optional[List[str]] = None
class ReimburseApplyOut(BaseModel):
model_config = ConfigDict(from_attributes=True, populate_by_name=True, alias_generator=to_camel)
id: str
apply_code: str
applicant_id: str
applicant_name: str
title: str
reimburse_date: OptDateToStr = None
expense_id: Optional[str] = None
expense_name: str
amount: float
current_node: Optional[str] = None
apply_time: DatetimeToStr = Field(validation_alias="create_time")
create_by: Optional[str] = Field(default=None, validation_alias="create_by")
status: Optional[str] = None
remark: Optional[str] = None
invoice_count: int = 0
attach_count: int = 0
pay_status: Optional[str] = None
pay_time: OptDatetimeToStr = None
pay_user_name: Optional[str] = None
actual_amount: Optional[float] = None
offset_advance_id: Optional[str] = None
offset_amount: Optional[float] = None
details: Optional[List[ReimburseDetailOut]] = None
invoice_ids: Optional[List[str]] = None
invoices: Optional[List[ReimburseInvoiceBriefOut]] = None
class ReimburseApprovalCreate(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
approval_status: Optional[str] = None
approval_opinion: Optional[str] = None
class ReimburseApprovalOut(BaseModel):
model_config = ConfigDict(from_attributes=True, populate_by_name=True, alias_generator=to_camel)
id: str
reimburse_id: str
node_name: str
node_order: int
approval_status: str
approval_opinion: Optional[str] = None
approver_name: str
approval_time: OptDatetimeToStr = None
class ReimburseMyStatsOut(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
total_count: int
pending_count: int
approved_count: int
rejected_count: int
approved_amount: float
month_apply_amount: float
month_apply_count: int
class ReimburseApproverPendingStatsOut(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
pending_total: int
month_pending_amount: float
class PayRequest(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
pay_remark: Optional[str] = None
actual_amount: Optional[float] = None
class OffsetRequest(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
advance_id: str
offset_amount: float
remark: Optional[str] = None
@field_validator("advance_id", mode="before")
@classmethod
def validate_advance_id(cls, value):
s = _coerce_id(value)
if not s:
raise ValueError("备用金单不能为空")
return s
class OffsetItem(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
advance_id: str
offset_amount: float
@field_validator("advance_id", mode="before")
@classmethod
def validate_advance_id(cls, value):
s = _coerce_id(value)
if not s:
raise ValueError("备用金单不能为空")
return s
class BatchOffsetRequest(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
items: List[OffsetItem]
pay_amount: float = 0
remark: Optional[str] = None
class ReimburseOffsetRecordOut(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
advance_id: str
advance_apply_code: str
advance_applicant_name: Optional[str] = None
advance_reason: Optional[str] = None
offset_amount: float
remark: Optional[str] = None
operator: Optional[str] = None
create_time: OptDatetimeToStr = None
class PaymentFinanceStatsOut(BaseModel):
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
pending_count: int
paid_count: int
offset_count: int
month_processed_amount: float