Wer nach dem Gehaltseingang plant, stellt unter Einstellungen den Tag ein, ab dem ein neuer Monat zählt. Der Zeitraum läuft dann vom Gehaltstag bis zum Vortag des nächsten und trägt den Namen des Monats, in dem er beginnt: Mit dem 25. umfasst „September 2026“ den 25.09. bis zum 24.10. Ein Starttag jenseits der Monatslänge rutscht auf den Monatsletzten, sodass 31 verlässlich den letzten Tag des Monats meint. Dashboard, Cashflow-Kalender, Budgets, Zwölf-Monats-Vorschau, die Kategorienauswertung, der Monatsexport und die Benachrichtigung über überschrittene Budgets rechnen mit diesem Zeitraum. Budgets bleiben je Monat gepflegt; der Bezeichner ist weiterhin der Monatserste, nur der Schnitt verschiebt sich. Bestandsinstallationen bleiben beim Ersten. Die Einstellung liegt in einer einzeiligen Tabelle hinter GET/PUT /api/settings; die Monatsauswertungen liefern zusätzlich period_start und period_end. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fj7mB1PGA1aDHyfdSGHgzD
38 lines
1.3 KiB
Python
38 lines
1.3 KiB
Python
"""Anwendungsweite Einstellungen.
|
||
|
||
Die Tabelle enthält genau eine Zeile. Fehlt sie – etwa direkt nach der
|
||
Migration –, liefert `load_settings` die Vorgaben, ohne sie zu schreiben.
|
||
Erst ein Speichern legt die Zeile an.
|
||
"""
|
||
|
||
from sqlalchemy.ext.asyncio import AsyncSession
|
||
|
||
from app.core.clock import DEFAULT_MONTH_START_DAY
|
||
from app.models import AppSetting
|
||
|
||
SETTING_ID = 1
|
||
|
||
|
||
async def load_settings(session: AsyncSession) -> AppSetting:
|
||
"""Die Einstellungen; ohne gespeicherte Zeile ein Objekt mit den Vorgaben."""
|
||
vorhanden = await session.get(AppSetting, SETTING_ID)
|
||
if vorhanden is not None:
|
||
return vorhanden
|
||
return AppSetting(id=SETTING_ID, month_start_day=DEFAULT_MONTH_START_DAY)
|
||
|
||
|
||
async def month_start_day(session: AsyncSession) -> int:
|
||
"""Der eingestellte Gehaltstag – ab ihm beginnt der Abrechnungsmonat."""
|
||
return (await load_settings(session)).month_start_day
|
||
|
||
|
||
async def save_settings(session: AsyncSession, *, month_start_day: int) -> AppSetting:
|
||
"""Schreibt die Einstellungen und legt die Zeile bei Bedarf an."""
|
||
eintrag = await session.get(AppSetting, SETTING_ID)
|
||
if eintrag is None:
|
||
eintrag = AppSetting(id=SETTING_ID)
|
||
session.add(eintrag)
|
||
eintrag.month_start_day = month_start_day
|
||
await session.flush()
|
||
return eintrag
|