from pydantic import BaseModel, Field,field_validator from typing import List, Optional, Literal from ..common.datetime import datetime_date,get_current_date from fastapi import HTTPException from ..common.validators import DateStr from ..common.base import BaseResponseWithID class ContractResponse(BaseResponseWithID): """ 合同返回信息 """ id : str = Field(..., description="合同ID") project_id: str = Field("", description="所属项目ID") name: str = Field("", description="合同名称") short_name: str = Field("", description="合同简称") code: str = Field("", description="合同编码") contract_type: str = Field("", description="合同类型") currency: str = Field("CNY", description="币种") manager_name: str = Field("", description="负责人姓名") manager_phone: str = Field("", description="负责人电话") sign_company: str = Field("", description="签订公司") company_id: str = Field("", description="签订公司id") sign_date: DateStr = Field("", description="签订日期", examples=["2023-10-01"]) credit_code: Optional[str] = Field("", description="签订公司信用代码") total_price: float = Field(0.0, description="合同金额") sub_name: Optional[str] = Field(None, description="合同子标题") class ContractCreate(BaseModel): """ 创建合同 CONTRACT = "contract" """ name: str|None = Field(None, description="合同名称") sub_name:str|None= Field(None, description="合同子标题") code: str = Field("", description="合同编码") contract_type: str = Field("", description="合同类型") project_id: str = Field("", description="所属项目ID") currency: str = Field("CNY", description="币种") manager_name: str = Field("", description="负责人姓名") manager_phone: str = Field("", description="负责人电话") sign_company: str = Field("", description="签订公司") company_id: Optional[str] = Field(None, description="签订公司id") sign_date: DateStr = Field("", description="签订日期", examples=["2023-10-01"]) credit_code: Optional[str] = Field(None, description="签订公司信用代码") total_price: float = Field(0.0, description="合同金额") @field_validator("total_price") def validate_price(cls, v): """验证金额必须为非负数""" if v < 0: raise HTTPException(status_code=400, detail='合同金额不能小于0') return v @field_validator('sign_date') def validate_actual_date_not_future(cls, v: str) -> str: if v == "": return "" try: actual = datetime_date(v) except ValueError: raise HTTPException(status_code=400, detail='日期格式为(YYYY-MM-DD)') today = datetime_date(get_current_date()) if actual > today: raise HTTPException(status_code=400, detail='签约日期不能晚于今天') return v class ContractUpdate(BaseModel): """ 更新合同 CONTRACT = "contract" """ id : str = Field(..., description="合同ID") sub_name:str|None= Field(None, description="合同子标题") currency: str|None = Field(None, description="币种") manager_name: str|None= Field(None, description="负责人姓名") manager_phone: str|None= Field(None, description="负责人电话") sign_company: str|None= Field(None, description="签订公司") company_id: Optional[str] = Field(None, description="签订公司id") sign_date: str|None = Field(None, description="签订日期", examples=["2023-10-01"]) credit_code: Optional[str] = Field(None, description="签订公司信用代码") total_price: float|None= Field(None, description="合同金额") @field_validator("total_price") def validate_price(cls, v): """验证金额必须为非负数""" if v is None: return None if v < 0: raise HTTPException(status_code=400, detail='合同金额不能小于0') return v @field_validator('sign_date') def validate_actual_date_not_future(cls, v: str): if v is None: return None if v == "": return "" try: actual = datetime_date(v) except ValueError: raise HTTPException(status_code=400, detail='日期格式为(YYYY-MM-DD)') today = datetime_date(get_current_date()) if actual > today: raise HTTPException(status_code=400, detail='签约日期不能晚于今天') return v