from fastapi import APIRouter, Depends, HTTPException, Query from sqlalchemy.orm import Session from sqlalchemy import text from typing import Optional from datetime import datetime, date from pydantic import BaseModel from ..database import get_db router = APIRouter() # Pydantic 모델들 class JobCreate(BaseModel): job_no: str job_name: str client_name: str end_user: Optional[str] = None epc_company: Optional[str] = None project_site: Optional[str] = None contract_date: Optional[date] = None delivery_date: Optional[date] = None delivery_terms: Optional[str] = None project_type: Optional[str] = "냉동기" description: Optional[str] = None @router.get("/") async def get_jobs( skip: int = Query(0, ge=0), limit: int = Query(100, ge=1, le=1000), search: Optional[str] = Query(None), db: Session = Depends(get_db) ): """Job 목록 조회 (job_name을 프로젝트명으로 사용)""" try: query = """ SELECT job_no, job_name, client_name, end_user, epc_company, project_site, contract_date, delivery_date, delivery_terms, project_type, status, description, created_by, created_at, updated_at, is_active FROM jobs WHERE is_active = true """ params = {} if search: query += " AND (job_no ILIKE :search OR job_name ILIKE :search OR client_name ILIKE :search)" params["search"] = f"%{search}%" query += " ORDER BY created_at DESC LIMIT :limit OFFSET :skip" params["limit"] = limit params["skip"] = skip result = db.execute(text(query), params) jobs = result.fetchall() return { "success": True, "total_count": len(jobs), "jobs": [ { "job_no": job.job_no, "job_name": job.job_name, "client_name": job.client_name, "end_user": job.end_user, "epc_company": job.epc_company, "project_site": job.project_site, "contract_date": job.contract_date, "delivery_date": job.delivery_date, "delivery_terms": job.delivery_terms, "project_type": job.project_type, "status": job.status, "description": job.description, "created_at": job.created_at, "project_name": job.job_name # job_name을 프로젝트명으로 사용 } for job in jobs ] } except Exception as e: raise HTTPException(status_code=500, detail=f"Job 목록 조회 실패: {str(e)}") @router.get("/{job_no}") async def get_job(job_no: str, db: Session = Depends(get_db)): """Job 상세 정보 조회""" try: query = text(""" SELECT job_no, job_name, client_name, end_user, epc_company, project_site, contract_date, delivery_date, delivery_terms, project_type, status, description, created_by, created_at, updated_at, is_active FROM jobs WHERE job_no = :job_no AND is_active = true """) result = db.execute(query, {"job_no": job_no}) job = result.fetchone() if not job: raise HTTPException(status_code=404, detail="Job을 찾을 수 없습니다") return { "success": True, "job": { "job_no": job.job_no, "job_name": job.job_name, "client_name": job.client_name, "end_user": job.end_user, "epc_company": job.epc_company, "project_site": job.project_site, "contract_date": job.contract_date, "delivery_date": job.delivery_date, "delivery_terms": job.delivery_terms, "project_type": job.project_type, "status": job.status, "description": job.description, "created_by": job.created_by, "created_at": job.created_at } } except HTTPException: raise except Exception as e: raise HTTPException(status_code=500, detail=f"Job 조회 실패: {str(e)}") @router.post("/") async def create_job(job: JobCreate, db: Session = Depends(get_db)): """새 Job 생성""" try: # Job No. 중복 확인 check_query = text("SELECT job_no FROM jobs WHERE job_no = :job_no") existing = db.execute(check_query, {"job_no": job.job_no}).fetchone() if existing: raise HTTPException( status_code=400, detail=f"Job No. '{job.job_no}'가 이미 존재합니다" ) # 새 Job 생성 insert_query = text(""" INSERT INTO jobs ( job_no, job_name, client_name, end_user, epc_company, project_site, contract_date, delivery_date, delivery_terms, project_type, description, created_by, status, is_active ) VALUES ( :job_no, :job_name, :client_name, :end_user, :epc_company, :project_site, :contract_date, :delivery_date, :delivery_terms, :project_type, :description, :created_by, :status, :is_active ) RETURNING job_no, job_name, client_name, project_type """) result = db.execute(insert_query, { **job.dict(), "created_by": "admin", "status": "진행중", "is_active": True }) new_job = result.fetchone() db.commit() return { "success": True, "message": "Job이 성공적으로 생성되었습니다", "job": { "job_no": new_job.job_no, "job_name": new_job.job_name, "client_name": new_job.client_name, "project_type": new_job.project_type } } except HTTPException: db.rollback() raise except Exception as e: db.rollback() raise HTTPException(status_code=500, detail=f"Job 생성 실패: {str(e)}")