import decimal from decimal import Decimal from typing import Optional, List from pydantic import computed_field from sqlalchemy.orm import selectinload from sqlmodel import Field, Relationship, select from app.model.BasicModel import BasicModel from app.model.ProjectModel import ProjectModel from app.model.ReimburseOtherModel import ReimburseOtherModel from app.model.ReimburseTravelModel import ReimburseTravelModel from app.utils.create_module_service import create_model_service class ReimburseModel(BasicModel, table=True): __tablename__ = "pl_reimburse" title: str = Field(default=None, description="标题") remarks: str = Field(default=None, description="备注信息") # /*---------------------------------------project-------------------------------------------*/ proj_id: str = Field( default=None, description="所属项目id", foreign_key="pl_project.id", # 添加外键约束 nullable=True ) proj_rel: Optional["ProjectModel"] = Relationship( sa_relationship_kwargs={ "foreign_keys": "ReimburseModel.proj_id", "remote_side": "ProjectModel.id", "uselist": False } ) @computed_field @property def project(self) -> Optional[ProjectModel]: return self.proj_rel @project.setter def project(self, value: Optional[ProjectModel]) -> None: pass # /*---------------------------------------travel_list-------------------------------------------*/ # 新增:与ReimburseTravelModel的一对多关系 travel_list_rel: Optional[List["ReimburseTravelModel"]] = Relationship( sa_relationship_kwargs={ "foreign_keys": "ReimburseTravelModel.reimburse_id", "primaryjoin": "ReimburseModel.id == ReimburseTravelModel.reimburse_id", } ) @computed_field @property def travel_list(self) -> Optional[List["ReimburseTravelModel"]]: return self.travel_list_rel @travel_list.setter def travel_list(self, value: Optional[List["ReimburseTravelModel"]]) -> None: pass # /*---------------------------------------other_list-------------------------------------------*/ other_list_rel: Optional[List["ReimburseOtherModel"]] = Relationship( sa_relationship_kwargs={ "foreign_keys": "ReimburseOtherModel.reimburse_id", "primaryjoin": "ReimburseModel.id == ReimburseOtherModel.reimburse_id", } ) @computed_field @property def other_list(self) -> Optional[List["ReimburseOtherModel"]]: return self.other_list_rel @other_list.setter def other_list(self, value: Optional[List["ReimburseOtherModel"]]) -> None: pass @computed_field @property def amount(self) -> Decimal: ret = Decimal(0) for other_item in (self.other_list or []): ret = ret + Decimal(other_item.amount) for travel_item in (self.travel_list or []): ret = ret + Decimal(travel_item.amount) return ret @amount.setter def amount(self, value: decimal) -> None: pass ReimburseService = create_model_service( Cls=ReimburseModel, custom_query=lambda: select(ReimburseModel) .options( selectinload(ReimburseModel.proj_rel). selectinload(ProjectModel.leader), selectinload(ReimburseModel.travel_list_rel), selectinload(ReimburseModel.other_list_rel), ) )