Initial commit - Stand 26.04.2026
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
// 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 });
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user