Feat: Cashflow auf paid_amount, Differenz-Badge, Kulanz-Abschreibung im Bezahlt-Modal (SW by-v984)

This commit is contained in:
rene 2026-05-15 16:06:08 +02:00
parent 0f6b5afd6a
commit e714580d77
5 changed files with 70 additions and 14 deletions

View file

@ -38,6 +38,7 @@ class InvoiceCreate(BaseModel):
class PayBody(BaseModel):
paid_at: str
paid_amount: float
notes: Optional[str] = None
class CancelBody(BaseModel):
@ -373,7 +374,9 @@ def get_cashflow(admin=Depends(require_admin)):
with db() as conn:
monthly = conn.execute("""
SELECT substr(created_at, 1, 7) AS month,
SUM(amount_gross) AS revenue,
SUM(CASE WHEN status='paid'
THEN COALESCE(paid_amount, amount_gross)
ELSE amount_gross END) AS revenue,
COUNT(*) AS count
FROM invoices
WHERE status IN ('sent', 'paid')
@ -383,7 +386,10 @@ def get_cashflow(admin=Depends(require_admin)):
year = datetime.now().year
total_year = conn.execute(
"SELECT COALESCE(SUM(amount_gross),0) FROM invoices WHERE status IN ('sent','paid') AND created_at LIKE ?",
"""SELECT COALESCE(SUM(CASE WHEN status='paid'
THEN COALESCE(paid_amount, amount_gross)
ELSE amount_gross END), 0)
FROM invoices WHERE status IN ('sent','paid') AND created_at LIKE ?""",
(f"{year}%",)
).fetchone()[0]
@ -705,10 +711,16 @@ def pay_invoice(invoice_id: int, data: PayBody, admin=Depends(require_admin)):
raise HTTPException(404, "Rechnung nicht gefunden.")
if row["status"] == "cancelled":
raise HTTPException(400, "Stornierte Rechnung kann nicht als bezahlt markiert werden.")
conn.execute(
"UPDATE invoices SET status='paid', paid_at=?, paid_amount=? WHERE id=?",
(data.paid_at, data.paid_amount, invoice_id)
)
if data.notes:
conn.execute(
"UPDATE invoices SET status='paid', paid_at=?, paid_amount=?, notes=? WHERE id=?",
(data.paid_at, data.paid_amount, data.notes, invoice_id)
)
else:
conn.execute(
"UPDATE invoices SET status='paid', paid_at=?, paid_amount=? WHERE id=?",
(data.paid_at, data.paid_amount, invoice_id)
)
row = conn.execute("SELECT * FROM invoices WHERE id=?", (invoice_id,)).fetchone()
return _row_to_dict(row)