diff --git a/backend/src/tools/statistik/routes.js b/backend/src/tools/statistik/routes.js index 0ad8e80..d5203f7 100644 --- a/backend/src/tools/statistik/routes.js +++ b/backend/src/tools/statistik/routes.js @@ -132,14 +132,18 @@ router.get('/overview', authenticate, (req, res) => { function getBucketKey(dateStr) { if (!dateStr) return null; - const d = dateStr.slice(0, 10); + const d = dateStr.slice(0, 10); // YYYY-MM-DD, immer lokal if (granularity === 'day') return d; if (granularity === 'week') { - // ISO-Woche: Montag der Woche - const dt = new Date(d); - const day = dt.getDay() || 7; + // Montag der Woche – rein mit String-Arithmetik (kein UTC-Bug) + const [y, m, dd] = d.split('-').map(Number); + const dt = new Date(y, m - 1, dd); // lokaler Konstruktor + const day = dt.getDay() || 7; // 1=Mo … 7=So dt.setDate(dt.getDate() - day + 1); - return dt.toISOString().slice(0,10); + const py = dt.getFullYear(); + const pm = String(dt.getMonth() + 1).padStart(2, '0'); + const pd = String(dt.getDate()).padStart(2, '0'); + return `${py}-${pm}-${pd}`; } return d.slice(0, 7); // YYYY-MM } @@ -171,6 +175,26 @@ router.get('/overview', authenticate, (req, res) => { buckets[key].expenses += e.amount; } + // Leere Buckets auffüllen – lokaler Date-Konstruktor um UTC-Bug zu vermeiden + if (from || to) { + const parseLocal = s => { const [y,m,d] = s.split('-').map(Number); return new Date(y, m-1, d); }; + const fmtLocal = dt => { + const y = dt.getFullYear(), m = String(dt.getMonth()+1).padStart(2,'0'), d = String(dt.getDate()).padStart(2,'0'); + return `${y}-${m}-${d}`; + }; + const firstBucket = Object.keys(buckets).sort()[0]; + const startD = parseLocal(from || firstBucket || to); + const endD = parseLocal(to || fmtLocal(new Date())); + const cur = new Date(startD); + while (cur <= endD) { + const key = getBucketKey(fmtLocal(cur)); + if (key && !buckets[key]) buckets[key] = { month:key, revenue:0, base_cost:0, expenses:0, orders:0 }; + if (granularity === 'day') cur.setDate(cur.getDate() + 1); + else if (granularity === 'week') cur.setDate(cur.getDate() + 7); + else cur.setMonth(cur.getMonth() + 1); + } + } + // Sortiert + ohne Filter auf letzte 12 Monate begrenzen let monthlyData = Object.values(buckets) .sort((a,b) => a.month.localeCompare(b.month))