Add SQLite passive income dashboard with Excel import and deployment tools

This commit is contained in:
kai
2026-09-09 08:46:27 +02:00
parent 729a13bfca
commit afc6f74f36
27 changed files with 1109 additions and 67 deletions
+35
View File
@@ -0,0 +1,35 @@
import csv
import io
from decimal import Decimal
from fastapi import APIRouter
from fastapi.responses import StreamingResponse
from database import connect
from models import CATEGORIES
router = APIRouter()
def safe_cell(value):
text = str(value or '')
return "'" + text if text.lstrip().startswith(('=', '+', '-', '@')) or text.startswith(('\t', '\r', '\n')) else text
def csv_rows():
stream = io.StringIO(newline='')
writer = csv.writer(stream, delimiter=';', lineterminator='\r\n')
yield '\ufeff'
writer.writerow(['Datum', 'Position', 'Kategorie', 'Betrag', 'Notiz', 'Erwartet', 'Erhalten'])
yield stream.getvalue()
stream.seek(0); stream.truncate(0)
with connect() as db:
for row in db.execute('SELECT i.*, a.name FROM income_entries i JOIN assets a ON a.id=i.asset_id ORDER BY date DESC, i.id DESC'):
writer.writerow([row['date'], safe_cell(row['name']), CATEGORIES[row['category']],
f"{Decimal(row['amount'])/100:.2f}".replace('.', ','), safe_cell(row['note']),
'Ja' if row['expected'] else 'Nein', 'Ja' if row['received'] else 'Nein'])
yield stream.getvalue()
stream.seek(0); stream.truncate(0)
@router.get('/export/income.csv')
def export():
return StreamingResponse(csv_rows(), media_type='text/csv; charset=utf-8', headers={'Content-Disposition': 'attachment; filename="income.csv"'})