const express = require('express'); const router = express.Router(); const db = require('../../db'); const { authenticate } = require('../../middleware/auth'); const uid = req => req.user.id; // ── Ausgaben CRUD ────────────────────────────────────────────────────────── router.get('/expenses', authenticate, (req, res) => { const { from, to } = req.query; let q = 'SELECT * FROM expenses WHERE user_id=?'; const p = [uid(req)]; if (from) { q += ' AND date>=?'; p.push(from); } if (to) { q += ' AND date<=?'; p.push(to); } q += ' ORDER BY date DESC, id DESC'; res.json(db.prepare(q).all(...p)); }); router.post('/expenses', authenticate, (req, res) => { const { date, category, description, amount } = req.body; if (!date || !description || !amount) return res.status(400).json({ error: 'Fehlende Felder' }); const r = db.prepare('INSERT INTO expenses (user_id,date,category,description,amount) VALUES (?,?,?,?,?)') .run(uid(req), date, category||'Sonstiges', description, parseFloat(amount)); res.json(db.prepare('SELECT * FROM expenses WHERE id=?').get(r.lastInsertRowid)); }); router.delete('/expenses/:id', authenticate, (req, res) => { const e = db.prepare('SELECT id FROM expenses WHERE id=? AND user_id=?').get(req.params.id, uid(req)); if (!e) return res.status(404).json({ error: 'Nicht gefunden' }); db.prepare('DELETE FROM expenses WHERE id=?').run(e.id); res.json({ ok: true }); }); // ── Statistik-Daten ──────────────────────────────────────────────────────── router.get('/overview', authenticate, (req, res) => { const { from, to } = req.query; const u = uid(req); let oq = `SELECT o.*, COALESCE(o.custom_price, (SELECT SUM(oi.custom_price * oi.stueckzahl) FROM order_items oi WHERE oi.order_id=o.id AND oi.custom_price IS NOT NULL) ) as revenue, (SELECT COALESCE(SUM(COALESCE(c.preis_freundschaft, oi.preis_freundschaft, 0) * oi.stueckzahl),0) FROM order_items oi LEFT JOIN calculations c ON c.id=oi.calculation_id WHERE oi.order_id=o.id) as base_cost FROM orders o WHERE o.user_id=?`; const op = [u]; if (from) { oq += ' AND DATE(o.created_at)>=?'; op.push(from); } if (to) { oq += ' AND DATE(o.created_at)<=?'; op.push(to); } oq += ' ORDER BY o.created_at DESC'; const orders = db.prepare(oq).all(...op); const paidOrders = orders.filter(o => !!o.bezahlt); const openOrders = orders.filter(o => !o.bezahlt && o.status !== 'warteliste'); const totalRevenue = paidOrders.reduce((s,o) => s + (o.revenue || 0), 0); const openRevenue = openOrders.reduce((s,o) => s + (o.revenue || 0), 0); const totalBaseCost = paidOrders.reduce((s,o) => s + (o.base_cost || 0), 0); const totalProfit = totalRevenue - totalBaseCost; let eq = 'SELECT * FROM expenses WHERE user_id=?'; const ep = [u]; if (from) { eq += ' AND date>=?'; ep.push(from); } if (to) { eq += ' AND date<=?'; ep.push(to); } const expenses = db.prepare(eq + ' ORDER BY date DESC').all(...ep); const totalExpenses = expenses.reduce((s,e) => s + e.amount, 0); const netProfit = totalProfit - totalExpenses; const byStatus = { warteliste:0, in_arbeit:0, fertig:0, bezahlt:0, abgeschlossen:0 }; for (const o of orders) { if (!!o.bezahlt && !!o.abgeholt) byStatus.abgeschlossen++; else if (!!o.bezahlt) byStatus.bezahlt++; else if (o.status in byStatus) byStatus[o.status]++; } const byCategory = {}; for (const e of expenses) { byCategory[e.category] = (byCategory[e.category] || 0) + e.amount; } // Monatliche Daten const monthlyRev = db.prepare(` SELECT strftime('%Y-%m', created_at) as month, SUM(CASE WHEN bezahlt=1 THEN COALESCE(custom_price,0) ELSE 0 END) as revenue, COUNT(*) as orders FROM orders WHERE user_id=? GROUP BY month ORDER BY month `).all(u); const monthlyExp = db.prepare(` SELECT strftime('%Y-%m', date) as month, SUM(amount) as expenses FROM expenses WHERE user_id=? GROUP BY month ORDER BY month `).all(u); const monthlyMap = {}; for (const m of monthlyRev) monthlyMap[m.month] = { month:m.month, revenue:m.revenue||0, orders:m.orders||0, expenses:0 }; for (const m of monthlyExp) { if (monthlyMap[m.month]) monthlyMap[m.month].expenses = m.expenses||0; else monthlyMap[m.month] = { month:m.month, revenue:0, orders:0, expenses:m.expenses||0 }; } const monthlyData = Object.values(monthlyMap).sort((a,b)=>a.month.localeCompare(b.month)).slice(-12); let cum = 0; const cumulativeData = monthlyData.map(m => { cum += (m.revenue||0) - (m.expenses||0); return { month: m.month, value: Math.round(cum*100)/100 }; }); res.json({ totalRevenue, openRevenue, totalBaseCost, totalProfit, totalExpenses, netProfit, totalOrders: orders.length, byStatus, byCategory, monthlyData, cumulativeData, expenses: expenses.slice(0,100), recentOrders: orders.slice(0,30), }); }); module.exports = router;