document-processor/app/routes/presets.py

160 lines
6.0 KiB
Python

from pathlib import Path
from fastapi import APIRouter, Depends, Form, Request
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from app.db.deps import get_db
from app.models.document_preset import DocumentPreset
router = APIRouter(prefix="/presets", tags=["presets"])
BASE_DIR = Path(__file__).resolve().parent.parent
templates = Jinja2Templates(directory=str(BASE_DIR / "templates"))
def _parse_people_list(value: str) -> list[str]:
return [part.strip() for part in value.split(",") if part.strip()]
def _format_people_list(value: list | None) -> str:
if not value:
return ""
return ", ".join(str(x).strip() for x in value if str(x).strip())
def _preset_form_values(preset: DocumentPreset | None = None) -> dict:
if preset is None:
return {
"name": "",
"owner_primary": "",
"owner_secondary": "",
"paid_by_person": "",
"covered_people": "",
"attendees": "",
"occasion_note": "",
"is_shared_expense": False,
"reimbursement_expected_from": "",
"reimbursement_paid_by": "",
"reimbursement_paid_to": "",
"reimbursement_note": "",
}
return {
"name": preset.name or "",
"owner_primary": preset.owner_primary or "",
"owner_secondary": preset.owner_secondary or "",
"paid_by_person": preset.paid_by_person or "",
"covered_people": _format_people_list(preset.covered_people),
"attendees": _format_people_list(preset.attendees),
"occasion_note": preset.occasion_note or "",
"is_shared_expense": bool(preset.is_shared_expense),
"reimbursement_expected_from": _format_people_list(preset.reimbursement_expected_from),
"reimbursement_paid_by": preset.reimbursement_paid_by or "",
"reimbursement_paid_to": preset.reimbursement_paid_to or "",
"reimbursement_note": preset.reimbursement_note or "",
}
@router.get("/", response_class=HTMLResponse)
def list_presets(request: Request, edit_id: int | None = None, db: Session = Depends(get_db)):
presets = db.query(DocumentPreset).order_by(DocumentPreset.name.asc()).all()
editing = None
if edit_id is not None:
editing = db.query(DocumentPreset).filter(DocumentPreset.id == edit_id).first()
return templates.TemplateResponse(
request=request,
name="presets/index.html",
context={
"request": request,
"presets": presets,
"editing": editing,
"form_values": _preset_form_values(editing),
"active_page": "presets",
},
)
@router.post("/create", response_class=RedirectResponse)
def create_preset(
name: str = Form(...),
owner_primary: str = Form(""),
owner_secondary: str = Form(""),
paid_by_person: str = Form(""),
covered_people: str = Form(""),
attendees: str = Form(""),
occasion_note: str = Form(""),
is_shared_expense: str | None = Form(None),
reimbursement_expected_from: str = Form(""),
reimbursement_paid_by: str = Form(""),
reimbursement_paid_to: str = Form(""),
reimbursement_note: str = Form(""),
db: Session = Depends(get_db),
):
preset = DocumentPreset(
name=name.strip(),
owner_primary=owner_primary.strip() or None,
owner_secondary=owner_secondary.strip() or None,
paid_by_person=paid_by_person.strip() or None,
covered_people=_parse_people_list(covered_people),
attendees=_parse_people_list(attendees),
occasion_note=occasion_note.strip() or None,
is_shared_expense=bool(is_shared_expense),
reimbursement_expected_from=_parse_people_list(reimbursement_expected_from),
reimbursement_paid_by=reimbursement_paid_by.strip() or None,
reimbursement_paid_to=reimbursement_paid_to.strip() or None,
reimbursement_note=reimbursement_note.strip() or None,
)
db.add(preset)
db.commit()
return RedirectResponse(url="/presets/", status_code=303)
@router.post("/{preset_id}/update", response_class=RedirectResponse)
def update_preset(
preset_id: int,
name: str = Form(...),
owner_primary: str = Form(""),
owner_secondary: str = Form(""),
paid_by_person: str = Form(""),
covered_people: str = Form(""),
attendees: str = Form(""),
occasion_note: str = Form(""),
is_shared_expense: str | None = Form(None),
reimbursement_expected_from: str = Form(""),
reimbursement_paid_by: str = Form(""),
reimbursement_paid_to: str = Form(""),
reimbursement_note: str = Form(""),
db: Session = Depends(get_db),
):
preset = db.query(DocumentPreset).filter(DocumentPreset.id == preset_id).first()
if preset is None:
return RedirectResponse(url="/presets/", status_code=303)
preset.name = name.strip()
preset.owner_primary = owner_primary.strip() or None
preset.owner_secondary = owner_secondary.strip() or None
preset.paid_by_person = paid_by_person.strip() or None
preset.covered_people = _parse_people_list(covered_people)
preset.attendees = _parse_people_list(attendees)
preset.occasion_note = occasion_note.strip() or None
preset.is_shared_expense = bool(is_shared_expense)
preset.reimbursement_expected_from = _parse_people_list(reimbursement_expected_from)
preset.reimbursement_paid_by = reimbursement_paid_by.strip() or None
preset.reimbursement_paid_to = reimbursement_paid_to.strip() or None
preset.reimbursement_note = reimbursement_note.strip() or None
db.commit()
return RedirectResponse(url="/presets/", status_code=303)
@router.post("/{preset_id}/delete", response_class=RedirectResponse)
def delete_preset(preset_id: int, db: Session = Depends(get_db)):
preset = db.query(DocumentPreset).filter(DocumentPreset.id == preset_id).first()
if preset is not None:
db.delete(preset)
db.commit()
return RedirectResponse(url="/presets/", status_code=303)