""" 资产分配相关CRUD操作 """ from typing import List, Optional, Tuple from sqlalchemy.orm import Session from sqlalchemy import and_, or_ from app.models.allocation import AssetAllocationOrder, AssetAllocationItem from app.models.asset import Asset from app.schemas.allocation import AllocationOrderCreate, AllocationOrderUpdate class AllocationOrderCRUD: """分配单CRUD操作""" def get(self, db: Session, id: int) -> Optional[AssetAllocationOrder]: """根据ID获取分配单""" return db.query(AssetAllocationOrder).filter( AssetAllocationOrder.id == id ).first() def get_by_code(self, db: Session, order_code: str) -> Optional[AssetAllocationOrder]: """根据单号获取分配单""" return db.query(AssetAllocationOrder).filter( AssetAllocationOrder.order_code == order_code ).first() def get_multi( self, db: Session, skip: int = 0, limit: int = 20, order_type: Optional[str] = None, approval_status: Optional[str] = None, execute_status: Optional[str] = None, applicant_id: Optional[int] = None, target_organization_id: Optional[int] = None, keyword: Optional[str] = None ) -> Tuple[List[AssetAllocationOrder], int]: """获取分配单列表""" query = db.query(AssetAllocationOrder) # 筛选条件 if order_type: query = query.filter(AssetAllocationOrder.order_type == order_type) if approval_status: query = query.filter(AssetAllocationOrder.approval_status == approval_status) if execute_status: query = query.filter(AssetAllocationOrder.execute_status == execute_status) if applicant_id: query = query.filter(AssetAllocationOrder.applicant_id == applicant_id) if target_organization_id: query = query.filter(AssetAllocationOrder.target_organization_id == target_organization_id) if keyword: query = query.filter( or_( AssetAllocationOrder.order_code.like(f"%{keyword}%"), AssetAllocationOrder.title.like(f"%{keyword}%") ) ) # 排序 query = query.order_by(AssetAllocationOrder.created_at.desc()) # 总数 total = query.count() # 分页 items = query.offset(skip).limit(limit).all() return items, total def create( self, db: Session, obj_in: AllocationOrderCreate, order_code: str, applicant_id: int ) -> AssetAllocationOrder: """创建分配单""" # 创建分配单 db_obj = AssetAllocationOrder( order_code=order_code, order_type=obj_in.order_type, title=obj_in.title, source_organization_id=obj_in.source_organization_id, target_organization_id=obj_in.target_organization_id, applicant_id=applicant_id, expect_execute_date=obj_in.expect_execute_date, remark=obj_in.remark, created_by=applicant_id, approval_status="pending", execute_status="pending" ) db.add(db_obj) db.commit() db.refresh(db_obj) # 创建分配单明细 self._create_items( db=db, order_id=db_obj.id, asset_ids=obj_in.asset_ids, target_org_id=obj_in.target_organization_id ) return db_obj def update( self, db: Session, db_obj: AssetAllocationOrder, obj_in: AllocationOrderUpdate, updater_id: int ) -> AssetAllocationOrder: """更新分配单""" update_data = obj_in.model_dump(exclude_unset=True) for field, value in update_data.items(): setattr(db_obj, field, value) db_obj.updated_by = updater_id db.add(db_obj) db.commit() db.refresh(db_obj) return db_obj def approve( self, db: Session, db_obj: AssetAllocationOrder, approval_status: str, approver_id: int, approval_remark: Optional[str] = None ) -> AssetAllocationOrder: """审批分配单""" from datetime import datetime db_obj.approval_status = approval_status db_obj.approver_id = approver_id db_obj.approval_time = datetime.utcnow() db_obj.approval_remark = approval_remark # 如果审批通过,自动设置为可执行状态 if approval_status == "approved": db_obj.execute_status = "pending" elif approval_status == "rejected": db_obj.execute_status = "cancelled" db.add(db_obj) db.commit() db.refresh(db_obj) return db_obj def execute( self, db: Session, db_obj: AssetAllocationOrder, executor_id: int ) -> AssetAllocationOrder: """执行分配单""" from datetime import datetime, date db_obj.execute_status = "completed" db_obj.actual_execute_date = date.today() db_obj.executor_id = executor_id db.add(db_obj) db.commit() db.refresh(db_obj) return db_obj def cancel(self, db: Session, db_obj: AssetAllocationOrder) -> AssetAllocationOrder: """取消分配单""" db_obj.approval_status = "cancelled" db_obj.execute_status = "cancelled" db.add(db_obj) db.commit() db.refresh(db_obj) return db_obj def delete(self, db: Session, id: int) -> bool: """删除分配单""" obj = self.get(db, id) if obj: db.delete(obj) db.commit() return True return False def get_statistics( self, db: Session, applicant_id: Optional[int] = None ) -> dict: """获取分配单统计信息""" query = db.query(AssetAllocationOrder) if applicant_id: query = query.filter(AssetAllocationOrder.applicant_id == applicant_id) total = query.count() pending = query.filter(AssetAllocationOrder.approval_status == "pending").count() approved = query.filter(AssetAllocationOrder.approval_status == "approved").count() rejected = query.filter(AssetAllocationOrder.approval_status == "rejected").count() executing = query.filter(AssetAllocationOrder.execute_status == "executing").count() completed = query.filter(AssetAllocationOrder.execute_status == "completed").count() return { "total": total, "pending": pending, "approved": approved, "rejected": rejected, "executing": executing, "completed": completed } def _create_items( self, db: Session, order_id: int, asset_ids: List[int], target_org_id: int ): """创建分配单明细""" # 查询资产信息 assets = db.query(Asset).filter(Asset.id.in_(asset_ids)).all() for asset in assets: item = AssetAllocationItem( order_id=order_id, asset_id=asset.id, asset_code=asset.asset_code, asset_name=asset.asset_name, from_organization_id=asset.organization_id, to_organization_id=target_org_id, from_status=asset.status, to_status=self._get_target_status(asset.status), execute_status="pending" ) db.add(item) db.commit() def _get_target_status(self, current_status: str) -> str: """根据当前状态获取目标状态""" status_map = { "in_stock": "transferring", "in_use": "transferring", "maintenance": "in_stock" } return status_map.get(current_status, "transferring") class AllocationItemCRUD: """分配单明细CRUD操作""" def get_by_order(self, db: Session, order_id: int) -> List[AssetAllocationItem]: """根据分配单ID获取明细列表""" return db.query(AssetAllocationItem).filter( AssetAllocationItem.order_id == order_id ).order_by(AssetAllocationItem.id).all() def get_multi( self, db: Session, skip: int = 0, limit: int = 20, order_id: Optional[int] = None, execute_status: Optional[str] = None ) -> Tuple[List[AssetAllocationItem], int]: """获取明细列表""" query = db.query(AssetAllocationItem) if order_id: query = query.filter(AssetAllocationItem.order_id == order_id) if execute_status: query = query.filter(AssetAllocationItem.execute_status == execute_status) total = query.count() items = query.offset(skip).limit(limit).all() return items, total def update_execute_status( self, db: Session, item_id: int, execute_status: str, failure_reason: Optional[str] = None ) -> AssetAllocationItem: """更新明细执行状态""" from datetime import datetime item = db.query(AssetAllocationItem).filter( AssetAllocationItem.id == item_id ).first() if item: item.execute_status = execute_status item.execute_time = datetime.utcnow() item.failure_reason = failure_reason db.add(item) db.commit() db.refresh(item) return item def batch_update_execute_status( self, db: Session, order_id: int, execute_status: str ): """批量更新明细执行状态""" from datetime import datetime items = db.query(AssetAllocationItem).filter( and_( AssetAllocationItem.order_id == order_id, AssetAllocationItem.execute_status == "pending" ) ).all() for item in items: item.execute_status = execute_status item.execute_time = datetime.utcnow() db.add(item) db.commit() # 创建全局实例 allocation_order = AllocationOrderCRUD() allocation_item = AllocationItemCRUD()