Files
data-entry-app/backend/app/api/mix_calculator.py
T

120 lines
5.0 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, Response, status
from sqlalchemy.orm import Session
from app.api.deps import AuthSession, require_client_module_access
from app.db.session import get_db
from app.schemas.mix_calculator import (
MixCalculatorOptionsRead,
MixCalculatorPreviewRead,
MixCalculatorSessionCreate,
MixCalculatorSessionRead,
MixCalculatorSessionSummaryRead,
MixCalculatorSessionUpdate,
)
from app.services.mix_calculator_service import (
build_mix_calculator_options,
can_view_all_mix_calculator_sessions,
calculate_mix_calculator_preview,
create_mix_calculator_session,
get_mix_calculator_session,
list_mix_calculator_sessions,
serialize_mix_calculator_session,
update_mix_calculator_session,
)
from app.services.mix_calculator_pdf import MixCalculatorPdfUnavailableError, build_mix_calculator_pdf
from app.services.mix_calculator_filenames import mix_calculator_pdf_filename
router = APIRouter(prefix="/api/mix-calculator", tags=["mix-calculator"])
@router.get("/options", response_model=MixCalculatorOptionsRead)
def mix_calculator_options(
session: AuthSession = Depends(require_client_module_access("mix_calculator")),
db: Session = Depends(get_db),
):
return build_mix_calculator_options(db, tenant_id=session.tenant_id or "")
@router.get("", response_model=list[MixCalculatorSessionSummaryRead])
def mix_calculator_sessions(
session: AuthSession = Depends(require_client_module_access("mix_calculator")),
db: Session = Depends(get_db),
):
return list_mix_calculator_sessions(db, auth_session=session)
@router.post("/preview", response_model=MixCalculatorPreviewRead)
def preview_mix_calculator_session(
payload: MixCalculatorSessionCreate,
session: AuthSession = Depends(require_client_module_access("mix_calculator", "edit")),
db: Session = Depends(get_db),
):
try:
return calculate_mix_calculator_preview(db, tenant_id=session.tenant_id or "", payload=payload)
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
@router.post("", response_model=MixCalculatorSessionRead, status_code=status.HTTP_201_CREATED)
def create_saved_mix_calculator_session(
payload: MixCalculatorSessionCreate,
session: AuthSession = Depends(require_client_module_access("mix_calculator", "edit")),
db: Session = Depends(get_db),
):
try:
return create_mix_calculator_session(db, auth_session=session, payload=payload)
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
@router.get("/{session_id}", response_model=MixCalculatorSessionRead)
def read_mix_calculator_session(
session_id: int,
session: AuthSession = Depends(require_client_module_access("mix_calculator")),
db: Session = Depends(get_db),
):
session_record = get_mix_calculator_session(db, auth_session=session, session_id=session_id)
if session_record is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Mix calculator session not found")
return serialize_mix_calculator_session(session_record, session)
@router.get("/{session_id}/pdf")
def download_mix_calculator_session_pdf(
session_id: int,
session: AuthSession = Depends(require_client_module_access("mix_calculator")),
db: Session = Depends(get_db),
):
session_record = get_mix_calculator_session(db, auth_session=session, session_id=session_id)
if session_record is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Mix calculator session not found")
try:
pdf_bytes = build_mix_calculator_pdf(session_record)
except MixCalculatorPdfUnavailableError as exc:
raise HTTPException(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail=str(exc)) from exc
filename = mix_calculator_pdf_filename(session_record)
return Response(
content=pdf_bytes,
media_type="application/pdf",
headers={"Content-Disposition": f'attachment; filename="{filename}"'},
)
@router.patch("/{session_id}", response_model=MixCalculatorSessionRead)
def patch_mix_calculator_session(
session_id: int,
payload: MixCalculatorSessionUpdate,
session: AuthSession = Depends(require_client_module_access("mix_calculator", "edit")),
db: Session = Depends(get_db),
):
session_record = get_mix_calculator_session(db, auth_session=session, session_id=session_id)
if session_record is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Mix calculator session not found")
if not can_view_all_mix_calculator_sessions(session) and session_record.prepared_by_user_id != session.user_id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="You can only edit your own mix calculator sessions")
try:
return update_mix_calculator_session(db, auth_session=session, session_record=session_record, payload=payload)
except ValueError as exc:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc