"""?? CRUD ??""" from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from typing import Optional from app.database import get_db_pms from app.models import PmsWorkOrder, PmsProject, MaterialBase, WorkOrderStatus from app.schemas.work_order import ( WorkOrderCreate, WorkOrderUpdate, WorkOrderStatusUpdate, WorkOrderResponse, ) router = APIRouter(prefix="/api/pms/work_order", tags=["????"]) @router.get("", response_model=list[WorkOrderResponse]) async def list_work_orders( project_id: Optional[int] = Query(None, description="???ID??"), status: Optional[WorkOrderStatus] = Query(None, description="?????"), assignee_name: Optional[str] = Query(None, description="??????"), skip: int = Query(0, ge=0), limit: int = Query(100, gt=0, le=500), db: Session = Depends(get_db_pms) ): """??????""" query = db.query(PmsWorkOrder) if project_id is not None: query = query.filter(PmsWorkOrder.project_id == project_id) if status is not None: query = query.filter(PmsWorkOrder.status == status) if assignee_name is not None: query = query.filter(PmsWorkOrder.assignee_name == assignee_name) return query.order_by(PmsWorkOrder.created_at.desc()).offset(skip).limit(limit).all() @router.get("/{work_order_id}", response_model=WorkOrderResponse) async def get_work_order(work_order_id: int, db: Session = Depends(get_db_pms)): """????????""" work_order = db.query(PmsWorkOrder).filter(PmsWorkOrder.id == work_order_id).first() if not work_order: raise HTTPException(status_code=404, detail=f"?? ID={work_order_id} ???") return work_order @router.post("", response_model=WorkOrderResponse, status_code=201) async def create_work_order(data: WorkOrderCreate, db: Session = Depends(get_db_pms)): """?????""" project = db.query(PmsProject).filter(PmsProject.id == data.project_id).first() if not project: raise HTTPException(status_code=400, detail=f"?? ID={data.project_id} ???") material = db.query(MaterialBase).filter(MaterialBase.id == data.target_base_id).first() if not material: raise HTTPException(status_code=400, detail=f"???? ID={data.target_base_id} ???") existing = db.query(PmsWorkOrder).filter( PmsWorkOrder.work_order_no == data.work_order_no ).first() if existing: raise HTTPException(status_code=400, detail=f"??? {data.work_order_no} ???") work_order = PmsWorkOrder( work_order_no=data.work_order_no, project_id=data.project_id, target_base_id=data.target_base_id, target_quantity=data.target_quantity, assignee_name=data.assignee_name, status=WorkOrderStatus.PENDING, ) db.add(work_order) db.commit() db.refresh(work_order) return work_order @router.patch("/{work_order_id}", response_model=WorkOrderResponse) async def update_work_order( work_order_id: int, data: WorkOrderUpdate, db: Session = Depends(get_db_pms) ): """????""" work_order = db.query(PmsWorkOrder).filter(PmsWorkOrder.id == work_order_id).first() if not work_order: raise HTTPException(status_code=404, detail=f"?? ID={work_order_id} ???") if work_order.status == WorkOrderStatus.COMPLETED: raise HTTPException(status_code=400, detail="??????????") if data.target_quantity is not None: work_order.target_quantity = data.target_quantity if data.assignee_name is not None: work_order.assignee_name = data.assignee_name db.commit() db.refresh(work_order) return work_order @router.delete("/{work_order_id}", status_code=204) async def delete_work_order(work_order_id: int, db: Session = Depends(get_db_pms)): """????""" work_order = db.query(PmsWorkOrder).filter(PmsWorkOrder.id == work_order_id).first() if not work_order: raise HTTPException(status_code=404, detail=f"?? ID={work_order_id} ???") if work_order.status == WorkOrderStatus.IN_PROGRESS: raise HTTPException(status_code=400, detail="??????????") db.delete(work_order) db.commit() # ?????? @router.put("/{work_order_id}/status", response_model=WorkOrderResponse) async def update_work_order_status( work_order_id: int, data: WorkOrderStatusUpdate, db: Session = Depends(get_db_pms) ): """ ???????? ???????: - PENDING (???) -> IN_PROGRESS (???) - IN_PROGRESS (???) -> COMPLETED (???) - IN_PROGRESS (???) -> CANCELLED (???) - PENDING (???) -> CANCELLED (???) ????????????????????? ??????????????????? ??????????????? """ work_order = db.query(PmsWorkOrder).filter(PmsWorkOrder.id == work_order_id).first() if not work_order: raise HTTPException(status_code=404, detail=f"?? ID={work_order_id} ???") current_status = work_order.status new_status = data.status valid_transitions = { WorkOrderStatus.PENDING: {WorkOrderStatus.IN_PROGRESS, WorkOrderStatus.CANCELLED}, WorkOrderStatus.IN_PROGRESS: {WorkOrderStatus.COMPLETED, WorkOrderStatus.CANCELLED}, WorkOrderStatus.COMPLETED: set(), WorkOrderStatus.CANCELLED: set(), } if new_status not in valid_transitions.get(current_status, set()): raise HTTPException( status_code=400, detail=f"???????: {current_status.value} -> {new_status.value}" ) work_order.status = new_status db.commit() db.refresh(work_order) return work_order