152 lines
5.2 KiB
JavaScript
152 lines
5.2 KiB
JavaScript
// API Routes für Private Finanzen (Monatliche Ausgaben, etc.)
|
|
const { Pool } = require('pg');
|
|
|
|
const pool = new Pool({
|
|
host: process.env.DB_HOST || 'buchhaltung-db',
|
|
port: process.env.DB_PORT || 5432,
|
|
database: process.env.DB_NAME || 'buchhaltung',
|
|
user: process.env.DB_USER || 'postgres',
|
|
password: process.env.DB_PASSWORD || 'postgres',
|
|
});
|
|
|
|
module.exports = (app) => {
|
|
|
|
// ========== PRIVAT AUSGABEN ==========
|
|
|
|
// Tabelle erstellen falls nicht existiert
|
|
app.post('/api/privat/init', async (req, res) => {
|
|
try {
|
|
await pool.query(`
|
|
CREATE TABLE IF NOT EXISTS privat_ausgaben (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
kategorie VARCHAR(100) NOT NULL,
|
|
bezeichnung VARCHAR(255),
|
|
betrag DECIMAL(10,2) NOT NULL,
|
|
jahr INTEGER NOT NULL,
|
|
monat INTEGER NOT NULL, -- 0-11 für Jan-Dez
|
|
typ VARCHAR(20) DEFAULT 'einmalig', -- 'einmalig' oder 'wiederkehrend'
|
|
wiederkehrend_bis INTEGER, -- Monat bis zu dem es wiederkehrt (optional)
|
|
wiederkehrend_bis_jahr INTEGER,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
)
|
|
`);
|
|
res.json({ success: true, message: 'Tabelle privat_ausgaben erstellt' });
|
|
} catch (error) {
|
|
console.error('Init Error:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// Alle Ausgaben für Jahr/Monat laden
|
|
app.get('/api/privat/ausgaben', async (req, res) => {
|
|
try {
|
|
const { jahr, monat } = req.query;
|
|
|
|
let query = 'SELECT * FROM privat_ausgaben WHERE 1=1';
|
|
const params = [];
|
|
let paramCount = 0;
|
|
|
|
if (jahr) {
|
|
paramCount++;
|
|
query += ` AND (jahr = $${paramCount} OR (typ = 'wiederkehrend' AND jahr <= $${paramCount}))`;
|
|
params.push(parseInt(jahr));
|
|
}
|
|
|
|
if (monat !== undefined) {
|
|
paramCount++;
|
|
query += ` AND (monat = $${paramCount} OR typ = 'wiederkehrend')`;
|
|
params.push(parseInt(monat));
|
|
}
|
|
|
|
query += ' ORDER BY created_at DESC';
|
|
|
|
const result = await pool.query(query, params);
|
|
res.json(result.rows);
|
|
} catch (error) {
|
|
// Tabelle existiert nicht - leeres Array zurückgeben
|
|
if (error.message.includes('relation "privat_ausgaben" does not exist')) {
|
|
return res.json([]);
|
|
}
|
|
console.error('Load Error:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// Ausgabe erstellen
|
|
app.post('/api/privat/ausgaben', async (req, res) => {
|
|
try {
|
|
const { kategorie, bezeichnung, betrag, jahr, monat, typ, wiederkehrend_bis, wiederkehrend_bis_jahr } = req.body;
|
|
|
|
// Tabelle erstellen falls nicht existiert
|
|
await pool.query(`
|
|
CREATE TABLE IF NOT EXISTS privat_ausgaben (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
kategorie VARCHAR(100) NOT NULL,
|
|
bezeichnung VARCHAR(255),
|
|
betrag DECIMAL(10,2) NOT NULL,
|
|
jahr INTEGER NOT NULL,
|
|
monat INTEGER NOT NULL,
|
|
typ VARCHAR(20) DEFAULT 'einmalig',
|
|
wiederkehrend_bis INTEGER,
|
|
wiederkehrend_bis_jahr INTEGER,
|
|
created_at TIMESTAMP DEFAULT NOW(),
|
|
updated_at TIMESTAMP DEFAULT NOW()
|
|
)
|
|
`);
|
|
|
|
const result = await pool.query(
|
|
`INSERT INTO privat_ausgaben (kategorie, bezeichnung, betrag, jahr, monat, typ, wiederkehrend_bis, wiederkehrend_bis_jahr)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *`,
|
|
[kategorie, bezeichnung, betrag, jahr, monat, typ || 'einmalig', wiederkehrend_bis, wiederkehrend_bis_jahr]
|
|
);
|
|
|
|
res.json(result.rows[0]);
|
|
} catch (error) {
|
|
console.error('Create Error:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// Ausgabe aktualisieren
|
|
app.put('/api/privat/ausgaben/:id', async (req, res) => {
|
|
try {
|
|
const { kategorie, bezeichnung, betrag, jahr, monat, typ, wiederkehrend_bis, wiederkehrend_bis_jahr } = req.body;
|
|
|
|
const result = await pool.query(
|
|
`UPDATE privat_ausgaben
|
|
SET kategorie = $1, bezeichnung = $2, betrag = $3, jahr = $4, monat = $5,
|
|
typ = $6, wiederkehrend_bis = $7, wiederkehrend_bis_jahr = $8, updated_at = NOW()
|
|
WHERE id = $9 RETURNING *`,
|
|
[kategorie, bezeichnung, betrag, jahr, monat, typ, wiederkehrend_bis, wiederkehrend_bis_jahr, req.params.id]
|
|
);
|
|
|
|
if (result.rows.length === 0) {
|
|
return res.status(404).json({ error: 'Ausgabe nicht gefunden' });
|
|
}
|
|
|
|
res.json(result.rows[0]);
|
|
} catch (error) {
|
|
console.error('Update Error:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
// Ausgabe löschen
|
|
app.delete('/api/privat/ausgaben/:id', async (req, res) => {
|
|
try {
|
|
const result = await pool.query('DELETE FROM privat_ausgaben WHERE id = $1 RETURNING *', [req.params.id]);
|
|
|
|
if (result.rows.length === 0) {
|
|
return res.status(404).json({ error: 'Ausgabe nicht gefunden' });
|
|
}
|
|
|
|
res.json({ success: true, deleted: result.rows[0] });
|
|
} catch (error) {
|
|
console.error('Delete Error:', error);
|
|
res.status(500).json({ error: error.message });
|
|
}
|
|
});
|
|
|
|
};
|