56 lines
2.2 KiB
Python
56 lines
2.2 KiB
Python
"""内部额度命令。sources/on_date/executed 必须由调用方从权限校验后的业务记录提取,禁止直接暴露为 HTTP 请求体。"""
|
|
from datetime import date
|
|
from decimal import Decimal
|
|
from typing import Dict, List, Literal, Optional
|
|
from pydantic import BaseModel, ConfigDict, Field, condecimal
|
|
|
|
class InternalModel(BaseModel):
|
|
model_config = ConfigDict(extra='forbid')
|
|
|
|
class UsageSource(InternalModel):
|
|
source_stop_type: Literal['load', 'delivery']
|
|
source_stop_id: str
|
|
source_stop_product_id: str
|
|
plan_product_id: str
|
|
contract_id: str
|
|
contract_product_id: str
|
|
product_id: str
|
|
quantity: Decimal = Field(ge=0, max_digits=18, decimal_places=6)
|
|
unit: str
|
|
related_stop_products: List[str] = Field(default_factory=list)
|
|
fingerprint: str
|
|
snapshot: dict = Field(default_factory=dict)
|
|
|
|
@property
|
|
def source_id(self):
|
|
return self.source_stop_type + ':' + self.source_stop_product_id
|
|
|
|
class UsageManual(InternalModel):
|
|
permit_kind: Literal['purchase', 'transport']
|
|
source_id: str
|
|
permit_id: str
|
|
source_quantity: Decimal = Field(ge=0, max_digits=18, decimal_places=6)
|
|
permit_quantity: Decimal = Field(ge=0, max_digits=18, decimal_places=6)
|
|
note: str = Field(min_length=1)
|
|
|
|
class UsageRequest(InternalModel):
|
|
operation_id: str = Field(min_length=1, max_length=64)
|
|
action: Literal['reserve','resize','release','settle','actual_adjust','total_adjust']
|
|
plan_id: Optional[str] = None
|
|
sources: List[UsageSource] = Field(default_factory=list)
|
|
purchase_cert_ids: List[str] = Field(default_factory=list)
|
|
transport_cert_ids: List[str] = Field(default_factory=list)
|
|
vehicle_no: str = ''
|
|
on_date: date = Field(default_factory=date.today)
|
|
executed: bool = False
|
|
allow_supplement: bool = False
|
|
manual_allocations: List[UsageManual] = Field(default_factory=list)
|
|
actual_by_source: Dict[str, Decimal] = Field(default_factory=dict)
|
|
manual_actuals: List[UsageManual] = Field(default_factory=list)
|
|
reason: str = ''
|
|
evidence_urls: str = ''
|
|
source_note: str = ''
|
|
cert_type: Optional[Literal['purchase','transport']] = None
|
|
cert_id: Optional[str] = None
|
|
total_qty: Optional[condecimal(ge=0, max_digits=18, decimal_places=6)] = None
|