154 lines
5.7 KiB
Python
154 lines
5.7 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_person": "",
|
|
"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_person": preset.owner_person 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_person: 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_person=owner_person.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_person: 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_person = owner_person.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)
|