feat: Phase 2 – Budget-Engine + Direktzugriff (http://IP:Port)
Budget: - Modelle + Migration 0003: budget_template_lines, planned_income_lines, budget_periods, budget_period_lines. - services/budget: Perioden-Grenzen (einstellbarer Starttag, Label nach Endmonat), Standard-Vorlage vs. Monats-Override (Snapshot-on-Customize), Soll/Ist inkl. budgetierter Sparen-Transfers, geplante Einnahmen (Soll/Ist). - routers/budgets: Vorlage, geplante Einnahmen (CRUD), Monats-Soll/Ist, Monats-Override, Zurücksetzen. pytest: Perioden, Soll/Ist, Override/Reset, Einnahmen. - Frontend: Budget-Seite (Monat + Standard-Budget), Fortschrittsbalken grün/rot, Monats-Navigation, editierbare Soll-Beträge; Sparen-Option im Transfer-Formular. Deployment-Fix (Nutzer-Anforderung: http://IP:Port muss funktionieren): - Dienst bindet an APP_BIND_HOST=0.0.0.0 (direkt im LAN erreichbar). - APP_COOKIE_SECURE=false als Standard (sonst kein Login über reines HTTP); für reinen HTTPS-Betrieb umstellbar. Doku + install.sh entsprechend angepasst. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -54,3 +54,14 @@ export function todayIso() {
|
||||
const z = (n) => String(n).padStart(2, "0");
|
||||
return `${d.getFullYear()}-${z(d.getMonth() + 1)}-${z(d.getDate())}`;
|
||||
}
|
||||
|
||||
/** Monats-Label "2026-09" -> "September 2026". */
|
||||
export function formatMonthLabel(label, locale = "de") {
|
||||
if (!label) return "";
|
||||
const [y, m] = label.split("-").map(Number);
|
||||
const d = new Date(y, (m || 1) - 1, 1);
|
||||
return new Intl.DateTimeFormat(locale === "en" ? "en-GB" : "de-DE", {
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
}).format(d);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user