Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
- H/F/I/O SS304/GRAPHITE/CS/CS 패턴에서 4개 구성요소 모두 표시 - 기존 SS304 + GRAPHITE → SS304/GRAPHITE/CS/CS로 완전한 구성 표시 - 외부링/필러/내부링/추가구성 모든 정보 포함 - 구매수량 계산 모달에서 정확한 재질 정보 확인 가능
182 lines
6.3 KiB
Python
182 lines
6.3 KiB
Python
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)}")
|