import os from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form from fastapi.responses import JSONResponse from sqlalchemy.orm import Session from typing import Optional from database import get_db import models from auth import require_admin, get_current_user from utils import generate_qr router = APIRouter(prefix="/api/chargers", tags=["chargers"]) # ── 충전기 종류 ────────────────────────────────────── @router.get("/types") def list_types(db: Session = Depends(get_db)): types = db.query(models.ChargerType).order_by(models.ChargerType.id).all() return [{"id": t.id, "name": t.name, "description": t.description, "charger_count": len(t.chargers)} for t in types] @router.post("/types") def create_type(name: str = Form(...), description: str = Form(""), db: Session = Depends(get_db), _=Depends(require_admin)): t = models.ChargerType(name=name, description=description) db.add(t); db.commit(); db.refresh(t) return {"id": t.id, "name": t.name} @router.put("/types/{type_id}") def update_type(type_id: int, name: str = Form(...), description: str = Form(""), db: Session = Depends(get_db), _=Depends(require_admin)): t = db.query(models.ChargerType).filter_by(id=type_id).first() if not t: raise HTTPException(404, "종류를 찾을 수 없습니다.") t.name = name; t.description = description db.commit() return {"id": t.id, "name": t.name} @router.delete("/types/{type_id}") def delete_type(type_id: int, db: Session = Depends(get_db), _=Depends(require_admin)): t = db.query(models.ChargerType).filter_by(id=type_id).first() if not t: raise HTTPException(404) if t.chargers: raise HTTPException(400, "해당 종류로 등록된 충전기가 있어 삭제할 수 없습니다.") db.delete(t); db.commit() return {"ok": True} # ── 충전기 ────────────────────────────────────────── @router.get("") def list_chargers(db: Session = Depends(get_db)): chargers = db.query(models.Charger).order_by(models.Charger.id).all() result = [] for c in chargers: pending = db.query(models.Report).filter( models.Report.charger_id == c.id, models.Report.status.in_(["pending", "in_progress"]) ).count() result.append({ "id": c.id, "name": c.name, "station_name": c.station_name, "cpo_name": c.cpo_name, "location_detail": c.location_detail, "installed_at": str(c.installed_at) if c.installed_at else None, "gps_lat": c.gps_lat, "gps_lng": c.gps_lng, "is_active": c.is_active, "charger_type": c.charger_type.name if c.charger_type else None, "charger_type_id": c.charger_type_id, "pending_reports": pending, }) return result @router.get("/{charger_id}") def get_charger(charger_id: str, db: Session = Depends(get_db)): c = db.query(models.Charger).filter_by(id=charger_id).first() if not c: raise HTTPException(404, "충전기를 찾을 수 없습니다.") return { "id": c.id, "name": c.name, "station_name": c.station_name, "cpo_name": c.cpo_name, "location_detail": c.location_detail, "installed_at": str(c.installed_at) if c.installed_at else None, "gps_lat": c.gps_lat, "gps_lng": c.gps_lng, "is_active": c.is_active, "charger_type": c.charger_type.name if c.charger_type else None, "charger_type_id": c.charger_type_id, } @router.post("") def create_charger( id: str = Form(...), charger_type_id: int = Form(...), name: str = Form(...), station_name: str = Form(...), location_detail: str = Form(""), cpo_name: str = Form(""), installed_at: Optional[str] = Form(None), gps_lat: Optional[float] = Form(None), gps_lng: Optional[float] = Form(None), db: Session = Depends(get_db), _=Depends(require_admin) ): if db.query(models.Charger).filter_by(id=id).first(): raise HTTPException(400, "이미 존재하는 충전기 ID입니다.") c = models.Charger( id=id, charger_type_id=charger_type_id, name=name, station_name=station_name, location_detail=location_detail, cpo_name=cpo_name, installed_at=installed_at or None, gps_lat=gps_lat, gps_lng=gps_lng ) db.add(c); db.commit() domain = os.getenv("DOMAIN", "localhost") qr_path = generate_qr(id, domain) return {"id": c.id, "qr_path": qr_path} @router.put("/{charger_id}") def update_charger( charger_id: str, charger_type_id: int = Form(...), name: str = Form(...), station_name: str = Form(...), location_detail: str = Form(""), cpo_name: str = Form(""), installed_at: Optional[str] = Form(None), gps_lat: Optional[float] = Form(None), gps_lng: Optional[float] = Form(None), db: Session = Depends(get_db), _=Depends(require_admin) ): c = db.query(models.Charger).filter_by(id=charger_id).first() if not c: raise HTTPException(404) c.charger_type_id = charger_type_id; c.name = name c.station_name = station_name; c.location_detail = location_detail c.cpo_name = cpo_name; c.installed_at = installed_at or None c.gps_lat = gps_lat; c.gps_lng = gps_lng db.commit() domain = os.getenv("DOMAIN", "localhost") qr_path = generate_qr(charger_id, domain) return {"id": c.id, "qr_path": qr_path} @router.post("/{charger_id}/qr") def regenerate_qr(charger_id: str, db: Session = Depends(get_db), _=Depends(require_admin)): c = db.query(models.Charger).filter_by(id=charger_id).first() if not c: raise HTTPException(404) domain = os.getenv("DOMAIN", "localhost") qr_path = generate_qr(charger_id, domain) return {"qr_path": qr_path}