diff --git a/app/modules/vacation/db.py b/app/modules/vacation/db.py index b2c92b8..cdd7eca 100644 --- a/app/modules/vacation/db.py +++ b/app/modules/vacation/db.py @@ -351,6 +351,23 @@ class VacationDBStore: ).fetchone() return self._req_serialize(row) + def hard_delete(self, *, request_id: str, user_email: str, is_admin: bool) -> None: + """완전 삭제. 승인 전(작성중/제출/반려)만 허용. owner 또는 admin.""" + user_email = user_email.lower().strip() + current = self.get_request(request_id=request_id) + if not current: + raise KeyError(request_id) + if not is_admin and current["owner"] != user_email: + raise PermissionError("본인 신청만 삭제할 수 있습니다.") + if current["status"] == "승인": + raise ValueError("승인된 휴가는 삭제할 수 없습니다. 취소 처리하세요.") + with self._pool.connection() as conn: + cur = conn.execute( + "DELETE FROM vacation_requests WHERE id = %s", (request_id,) + ) + if cur.rowcount == 0: + raise KeyError(request_id) + def list_pending(self) -> list[dict[str, Any]]: with self._pool.connection() as conn: rows = conn.execute( diff --git a/app/modules/vacation/router.py b/app/modules/vacation/router.py index a4601a3..c20fda1 100644 --- a/app/modules/vacation/router.py +++ b/app/modules/vacation/router.py @@ -800,3 +800,28 @@ async def cancel( except PermissionError as exc: raise HTTPException(status_code=403, detail=str(exc)) return RedirectResponse(url=f"/vacation/{request_id}", status_code=303) + + +@router.post("/{request_id}/delete") +async def delete( + request: Request, + request_id: str, + user: dict[str, Any] = Depends(_require_user), +) -> RedirectResponse: + """완전 삭제 — 승인 전(작성중/제출/반려)만. 달력으로 복귀.""" + from app.store import is_admin # noqa: WPS433 + + store = _store(request) + if store is None: + raise HTTPException(status_code=503, detail="vacation_db 미설정") + try: + store.hard_delete( + request_id=request_id, user_email=user["email"], is_admin=is_admin(user) + ) + except KeyError: + raise HTTPException(status_code=404, detail="휴가 신청을 찾을 수 없습니다.") + except PermissionError as exc: + raise HTTPException(status_code=403, detail=str(exc)) + except ValueError as exc: + raise HTTPException(status_code=409, detail=str(exc)) + return RedirectResponse(url="/vacation/", status_code=303) diff --git a/app/modules/vacation/templates/vacation/detail.html b/app/modules/vacation/templates/vacation/detail.html index 0c826c6..89c0b40 100644 --- a/app/modules/vacation/templates/vacation/detail.html +++ b/app/modules/vacation/templates/vacation/detail.html @@ -1,6 +1,6 @@ {% extends "erp_base.html" %} -{% block head_extra %}{% endblock %} +{% block head_extra %}{% endblock %} {% block content %}
@@ -65,11 +65,18 @@ {% endif %} - {% if req.status != '취소' and (is_owner or is_admin) %} -
- -
+ {% if (is_owner or is_admin) %} + {% if req.status == '승인' %} +
+ +
+ {% elif req.status in ('작성중', '제출', '반려') %} +
+ +
+ {% endif %} {% endif %} {% if can_edit %}