- 사진 2장까지 업로드 지원 - 카메라 촬영 + 갤러리 선택 분리 - 이미지 압축 및 최적화 (ImageUtils) - iPhone .mpo 파일 JPEG 변환 지원 - 카테고리 변경: 치수불량 → 설계미스, 검사미스 추가 - KST 시간대 설정 - URL 해시 처리로 목록관리 페이지 이동 개선 - 로그인 OAuth2 form-data 형식 수정 - 업로드 속도 개선 및 프로그레스바 추가
164 lines
5.2 KiB
Python
164 lines
5.2 KiB
Python
from fastapi import APIRouter, Depends, HTTPException
|
|
from sqlalchemy.orm import Session
|
|
from typing import List, Optional
|
|
from datetime import datetime, date, timezone, timedelta
|
|
|
|
from database.database import get_db
|
|
from database.models import DailyWork, User, UserRole, KST
|
|
from database import schemas
|
|
from routers.auth import get_current_user
|
|
|
|
router = APIRouter(prefix="/api/daily-work", tags=["daily-work"])
|
|
|
|
@router.post("/", response_model=schemas.DailyWork)
|
|
async def create_daily_work(
|
|
work: schemas.DailyWorkCreate,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
# 중복 확인 (같은 날짜)
|
|
existing = db.query(DailyWork).filter(
|
|
DailyWork.date == work.date.date()
|
|
).first()
|
|
if existing:
|
|
raise HTTPException(status_code=400, detail="Daily work for this date already exists")
|
|
|
|
# 계산
|
|
regular_hours = work.worker_count * 8 # 정규 근무 8시간
|
|
overtime_total = work.overtime_workers * work.overtime_hours
|
|
total_hours = regular_hours + overtime_total
|
|
|
|
# 생성
|
|
db_work = DailyWork(
|
|
date=work.date,
|
|
worker_count=work.worker_count,
|
|
regular_hours=regular_hours,
|
|
overtime_workers=work.overtime_workers,
|
|
overtime_hours=work.overtime_hours,
|
|
overtime_total=overtime_total,
|
|
total_hours=total_hours,
|
|
created_by_id=current_user.id
|
|
)
|
|
db.add(db_work)
|
|
db.commit()
|
|
db.refresh(db_work)
|
|
return db_work
|
|
|
|
@router.get("/", response_model=List[schemas.DailyWork])
|
|
async def read_daily_works(
|
|
skip: int = 0,
|
|
limit: int = 100,
|
|
start_date: Optional[date] = None,
|
|
end_date: Optional[date] = None,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
query = db.query(DailyWork)
|
|
|
|
if start_date:
|
|
query = query.filter(DailyWork.date >= start_date)
|
|
if end_date:
|
|
query = query.filter(DailyWork.date <= end_date)
|
|
|
|
works = query.order_by(DailyWork.date.desc()).offset(skip).limit(limit).all()
|
|
return works
|
|
|
|
@router.get("/{work_id}", response_model=schemas.DailyWork)
|
|
async def read_daily_work(
|
|
work_id: int,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
work = db.query(DailyWork).filter(DailyWork.id == work_id).first()
|
|
if not work:
|
|
raise HTTPException(status_code=404, detail="Daily work not found")
|
|
return work
|
|
|
|
@router.put("/{work_id}", response_model=schemas.DailyWork)
|
|
async def update_daily_work(
|
|
work_id: int,
|
|
work_update: schemas.DailyWorkUpdate,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
work = db.query(DailyWork).filter(DailyWork.id == work_id).first()
|
|
if not work:
|
|
raise HTTPException(status_code=404, detail="Daily work not found")
|
|
|
|
# 업데이트
|
|
update_data = work_update.dict(exclude_unset=True)
|
|
|
|
# 재계산 필요한 경우
|
|
if any(key in update_data for key in ["worker_count", "overtime_workers", "overtime_hours"]):
|
|
worker_count = update_data.get("worker_count", work.worker_count)
|
|
overtime_workers = update_data.get("overtime_workers", work.overtime_workers)
|
|
overtime_hours = update_data.get("overtime_hours", work.overtime_hours)
|
|
|
|
regular_hours = worker_count * 8
|
|
overtime_total = overtime_workers * overtime_hours
|
|
total_hours = regular_hours + overtime_total
|
|
|
|
update_data["regular_hours"] = regular_hours
|
|
update_data["overtime_total"] = overtime_total
|
|
update_data["total_hours"] = total_hours
|
|
|
|
for field, value in update_data.items():
|
|
setattr(work, field, value)
|
|
|
|
db.commit()
|
|
db.refresh(work)
|
|
return work
|
|
|
|
@router.delete("/{work_id}")
|
|
async def delete_daily_work(
|
|
work_id: int,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
work = db.query(DailyWork).filter(DailyWork.id == work_id).first()
|
|
if not work:
|
|
raise HTTPException(status_code=404, detail="Daily work not found")
|
|
|
|
# 권한 확인 (관리자만 삭제 가능)
|
|
if current_user.role != UserRole.admin:
|
|
raise HTTPException(status_code=403, detail="Only admin can delete daily work")
|
|
|
|
db.delete(work)
|
|
db.commit()
|
|
return {"detail": "Daily work deleted successfully"}
|
|
|
|
@router.get("/stats/summary")
|
|
async def get_daily_work_stats(
|
|
start_date: Optional[date] = None,
|
|
end_date: Optional[date] = None,
|
|
current_user: User = Depends(get_current_user),
|
|
db: Session = Depends(get_db)
|
|
):
|
|
"""일일 공수 통계"""
|
|
query = db.query(DailyWork)
|
|
|
|
if start_date:
|
|
query = query.filter(DailyWork.date >= start_date)
|
|
if end_date:
|
|
query = query.filter(DailyWork.date <= end_date)
|
|
|
|
works = query.all()
|
|
|
|
if not works:
|
|
return {
|
|
"total_days": 0,
|
|
"total_hours": 0,
|
|
"total_overtime": 0,
|
|
"average_daily_hours": 0
|
|
}
|
|
|
|
total_hours = sum(w.total_hours for w in works)
|
|
total_overtime = sum(w.overtime_total for w in works)
|
|
|
|
return {
|
|
"total_days": len(works),
|
|
"total_hours": total_hours,
|
|
"total_overtime": total_overtime,
|
|
"average_daily_hours": total_hours / len(works)
|
|
}
|