""" 리비전 자재 처리 API 엔드포인트 """ from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from typing import List, Dict, Any from pydantic import BaseModel from ..database import get_db from ..auth.middleware import get_current_user from ..services.revision_material_service import RevisionMaterialService from ..auth.models import User from ..utils.logger import get_logger logger = get_logger(__name__) router = APIRouter(prefix="/revision-material", tags=["Revision Material"]) class ProcessingResultRequest(BaseModel): processing_results: List[Dict[str, Any]] class MaterialProcessRequest(BaseModel): action: str additional_data: Dict[str, Any] = {} @router.get("/category/{file_id}/{category}") async def get_category_materials( file_id: int, category: str, include_processing_info: bool = True, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """ 리비전 페이지용 카테고리별 자재 조회 """ if category == 'PIPE': raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="PIPE 카테고리는 별도 처리가 필요합니다." ) try: material_service = RevisionMaterialService(db) materials = material_service.get_category_materials_for_revision( file_id=file_id, category=category, include_processing_info=include_processing_info ) # 처리 정보 요약 processing_info = { "total_materials": len(materials), "by_status": {}, "by_priority": {"high": 0, "medium": 0, "low": 0} } for material in materials: proc_info = material.get('processing_info', {}) status = proc_info.get('display_status', 'UNKNOWN') priority = proc_info.get('priority', 'medium') processing_info["by_status"][status] = processing_info["by_status"].get(status, 0) + 1 processing_info["by_priority"][priority] += 1 logger.info(f"Retrieved {len(materials)} materials for category {category} in file {file_id}") return { "success": True, "data": { "materials": materials, "processing_info": processing_info }, "message": f"{category} 카테고리 자재 조회 완료" } except Exception as e: logger.error(f"Failed to get category materials: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"카테고리 자재 조회 중 오류가 발생했습니다: {str(e)}" ) @router.post("/process/{material_id}") async def process_material( material_id: int, request: MaterialProcessRequest, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """ 개별 자재 처리 """ try: material_service = RevisionMaterialService(db) # 자재 정보 조회 material_query = """ SELECT * FROM materials WHERE id = :material_id """ result = material_service.db_service.execute_query( material_query, {"material_id": material_id} ) material = result.fetchone() if not material: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="자재를 찾을 수 없습니다." ) material_dict = dict(material._mapping) # 액션에 따른 처리 if request.action == "new_material": processing_result = material_service.process_new_material( material_dict, material_dict.get('classified_category', 'UNKNOWN') ) elif request.action == "remove_material": processing_result = material_service.process_removed_material( material_dict, material_dict.get('classified_category', 'UNKNOWN') ) else: # 기본 처리 (구매 상태별) # 이전 자재 정보가 필요한 경우 additional_data에서 가져옴 prev_material = request.additional_data.get('previous_material', material_dict) processing_result = material_service.process_material_by_purchase_status( prev_material, material_dict, material_dict.get('classified_category', 'UNKNOWN') ) # 처리 결과 적용 apply_result = material_service.apply_material_processing_results([processing_result]) logger.info(f"Processed material {material_id} with action {request.action}") return { "success": True, "data": { "processing_result": processing_result, "apply_result": apply_result }, "message": "자재 처리 완료" } except HTTPException: raise except Exception as e: logger.error(f"Failed to process material {material_id}: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"자재 처리 중 오류가 발생했습니다: {str(e)}" ) @router.post("/apply-results") async def apply_processing_results( request: ProcessingResultRequest, db: Session = Depends(get_db), current_user: User = Depends(get_current_user) ): """ 자재 처리 결과를 일괄 적용 """ try: material_service = RevisionMaterialService(db) apply_result = material_service.apply_material_processing_results( request.processing_results ) logger.info(f"Applied {len(request.processing_results)} processing results") return { "success": True, "data": apply_result, "message": "처리 결과 적용 완료" } except Exception as e: logger.error(f"Failed to apply processing results: {e}") raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"처리 결과 적용 중 오류가 발생했습니다: {str(e)}" )