| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- import io
- import pandas as pd
- from docx import Document
- from fastapi import APIRouter, Depends, Form, HTTPException, Request, Response
- from fastapi.responses import HTMLResponse, RedirectResponse, StreamingResponse
- from fastapi.templating import Jinja2Templates
- from sqlalchemy.orm import Session
- from .auth import ldap_authenticate
- from .db import get_session
- from .models import Bemerkung, Forderung
- from .schemas import BemerkungIn
- router = APIRouter()
- templates = Jinja2Templates(directory="templates")
- @router.get("/", response_class=HTMLResponse)
- def index(request: Request):
- return RedirectResponse(url="/forderungen")
- @router.get("/login", response_class=HTMLResponse)
- def login_get(request: Request):
- return templates.TemplateResponse("login.html", {"request": request})
- @router.post("/login")
- def login_post(username: str = Form(...), password: str = Form(...)):
- user = ldap_authenticate(username, password)
- if not user:
- raise HTTPException(status_code=401, detail="Invalid credentials")
- # For a simple demo we set a cookie (not secure) -- replace with real session in production
- response = RedirectResponse(url="/forderungen", status_code=302)
- response.set_cookie("user", user["username"])
- return response
- @router.get("/forderungen", response_class=HTMLResponse)
- def forderungsliste(request: Request, db: Session = Depends(get_session), limit: int = 100):
- q = db.query(Forderung).order_by(Forderung.faelligkeit.asc()).limit(limit).all()
- return templates.TemplateResponse("list.html", {"request": request, "forderungen": q})
- @router.get("/export/csv")
- def export_csv(db: Session = Depends(get_session)):
- q = db.query(Forderung).all()
- rows = []
- for f in q:
- rows.append(
- {
- "id": f.id,
- "rechnungsnummer": f.rechnungsnummer,
- "kunde": f.kunde.name if f.kunde else "",
- "betrag": float(f.betrag),
- "faelligkeit": f.faelligkeit.isoformat() if f.faelligkeit else "",
- }
- )
- df = pd.DataFrame(rows)
- buf = io.StringIO()
- df.to_csv(buf, index=False)
- buf.seek(0)
- return Response(
- content=buf.getvalue(),
- media_type="text/csv",
- headers={"Content-Disposition": "attachment; filename=forderungen.csv"},
- )
- @router.get("/export/xlsx")
- def export_xlsx(db: Session = Depends(get_session)):
- q = db.query(Forderung).all()
- rows = []
- for f in q:
- rows.append(
- {
- "id": f.id,
- "rechnungsnummer": f.rechnungsnummer,
- "kunde": f.kunde.name if f.kunde else "",
- "betrag": float(f.betrag),
- "faelligkeit": f.faelligkeit.isoformat() if f.faelligkeit else "",
- }
- )
- df = pd.DataFrame(rows)
- buf = io.BytesIO()
- with pd.ExcelWriter(buf, engine="openpyxl") as writer:
- df.to_excel(writer, index=False, sheet_name="Forderungen")
- buf.seek(0)
- return StreamingResponse(
- buf,
- media_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
- headers={"Content-Disposition": "attachment; filename=forderungen.xlsx"},
- )
- @router.get("/detail/{id}", response_class=HTMLResponse)
- def detail(request: Request, id: int, db: Session = Depends(get_session)):
- f = db.query(Forderung).filter(Forderung.id == id).first()
- if not f:
- raise HTTPException(status_code=404)
- return templates.TemplateResponse("detail.html", {"request": request, "forderung": f})
- @router.post("/detail/{id}/bemerkung")
- def save_bemerkung(id: int, data: BemerkungIn, request: Request, db: Session = Depends(get_session)):
- user = request.cookies.get("user") or "anonymous"
- b = Bemerkung(
- forderung_id=id, benutzer=user, bemerkung=data.bemerkung, wiedervorlage_datum=data.wiedervorlage_datum
- )
- db.add(b)
- db.commit()
- return RedirectResponse(url=f"/detail/{id}", status_code=302)
- @router.get("/detail/{id}/export/docx")
- def export_docx(id: int, db: Session = Depends(get_session)):
- f = db.query(Forderung).filter(Forderung.id == id).first()
- if not f:
- raise HTTPException(status_code=404)
- doc = Document()
- doc.add_heading(f"Rechnung {f.rechnungsnummer}", level=1)
- doc.add_paragraph(f'Kunde: {f.kunde.name if f.kunde else ""}')
- doc.add_paragraph(f"Betrag: {float(f.betrag)}")
- doc.add_paragraph(f"Fälligkeit: {f.faelligkeit}")
- buf = io.BytesIO()
- doc.save(buf)
- buf.seek(0)
- return StreamingResponse(
- buf,
- media_type="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
- headers={"Content-Disposition": f"attachment; filename=rechnung_{f.rechnungsnummer}.docx"},
- )
|