Files
fibdash/src/routes/admin.js
sebseb7 da435d2e66 u
2025-08-02 08:26:08 +02:00

274 lines
9.5 KiB
JavaScript

const express = require('express');
const { authenticateToken } = require('../middleware/auth');
const { checkAuthorizedEmail } = require('../middleware/emailAuth');
const { executeQuery, sql } = require('../config/database');
const fs = require('fs');
const path = require('path');
const router = express.Router();
// Removed admin access check - all authenticated users can access these routes
// Get system info
router.get('/system-info', authenticateToken, (req, res) => {
res.json({
currentUser: req.user.email,
environment: process.env.NODE_ENV || 'development'
});
});
// ==================== KREDITOR ROUTES ====================
// Get all kreditoren
router.get('/kreditoren', authenticateToken, async (req, res) => {
try {
const result = await executeQuery('SELECT id, iban, name, kreditorId, is_banking FROM fibdash.Kreditor ORDER BY name, iban');
res.json({ kreditoren: result.recordset });
} catch (error) {
console.error('Error fetching kreditoren:', error);
res.status(500).json({ error: 'Fehler beim Laden der Kreditoren' });
}
});
// Create new kreditor
router.post('/kreditoren', authenticateToken, async (req, res) => {
const { iban, name, kreditorId, is_banking } = req.body;
// IBAN is optional for banking accounts or manual kreditor assignments
const isBanking = is_banking || false;
if (!name || !kreditorId) {
return res.status(400).json({ error: 'Name und Kreditor ID sind erforderlich' });
}
// IBAN validation - required for non-banking accounts
if (!isBanking && (!iban || iban.trim() === '')) {
return res.status(400).json({ error: 'IBAN ist erforderlich (außer für Banking-Konten)' });
}
try {
await executeQuery(
'INSERT INTO fibdash.Kreditor (iban, name, kreditorId, is_banking) VALUES (@iban, @name, @kreditorId, @is_banking)',
{ iban: iban || null, name, kreditorId, is_banking: isBanking }
);
res.json({ message: 'Kreditor erfolgreich erstellt' });
} catch (error) {
console.error('Error creating kreditor:', error);
if (error.number === 2627) { // Unique constraint violation
res.status(400).json({ error: 'IBAN oder Kreditor ID bereits vorhanden' });
} else {
res.status(500).json({ error: 'Fehler beim Erstellen des Kreditors' });
}
}
});
// Update kreditor
router.put('/kreditoren/:id', authenticateToken, async (req, res) => {
const { id } = req.params;
const { iban, name, kreditorId, is_banking } = req.body;
// IBAN is optional for banking accounts or manual kreditor assignments
const isBanking = is_banking || false;
if (!name || !kreditorId) {
return res.status(400).json({ error: 'Name und Kreditor ID sind erforderlich' });
}
// IBAN validation - required for non-banking accounts
if (!isBanking && (!iban || iban.trim() === '')) {
return res.status(400).json({ error: 'IBAN ist erforderlich (außer für Banking-Konten)' });
}
try {
await executeQuery(
'UPDATE fibdash.Kreditor SET iban = @iban, name = @name, kreditorId = @kreditorId, is_banking = @is_banking WHERE id = @id',
{ iban: iban || null, name, kreditorId, is_banking: isBanking, id }
);
res.json({ message: 'Kreditor erfolgreich aktualisiert' });
} catch (error) {
console.error('Error updating kreditor:', error);
if (error.number === 2627) { // Unique constraint violation
res.status(400).json({ error: 'IBAN oder Kreditor ID bereits vorhanden' });
} else {
res.status(500).json({ error: 'Fehler beim Aktualisieren des Kreditors' });
}
}
});
// Delete kreditor
router.delete('/kreditoren/:id', authenticateToken, async (req, res) => {
const { id } = req.params;
try {
await executeQuery('DELETE FROM fibdash.Kreditor WHERE id = @id', { id });
res.json({ message: 'Kreditor erfolgreich gelöscht' });
} catch (error) {
console.error('Error deleting kreditor:', error);
if (error.number === 547) { // Foreign key constraint violation
res.status(400).json({ error: 'Kreditor kann nicht gelöscht werden, da er in Buchungen verwendet wird' });
} else {
res.status(500).json({ error: 'Fehler beim Löschen des Kreditors' });
}
}
});
// ==================== KONTO ROUTES ====================
// Get all konten
router.get('/konten', authenticateToken, async (req, res) => {
try {
const result = await executeQuery('SELECT * FROM fibdash.Konto ORDER BY konto');
res.json({ konten: result.recordset });
} catch (error) {
console.error('Error fetching konten:', error);
res.status(500).json({ error: 'Fehler beim Laden der Konten' });
}
});
// Create new konto
router.post('/konten', authenticateToken, async (req, res) => {
const { konto, name } = req.body;
if (!konto || !name) {
return res.status(400).json({ error: 'Konto und Name sind erforderlich' });
}
try {
await executeQuery(
'INSERT INTO fibdash.Konto (konto, name) VALUES (@konto, @name)',
{ konto, name }
);
res.json({ message: 'Konto erfolgreich erstellt' });
} catch (error) {
console.error('Error creating konto:', error);
if (error.number === 2627) { // Unique constraint violation
res.status(400).json({ error: 'Konto bereits vorhanden' });
} else {
res.status(500).json({ error: 'Fehler beim Erstellen des Kontos' });
}
}
});
// Update konto
router.put('/konten/:id', authenticateToken, async (req, res) => {
const { id } = req.params;
const { konto, name } = req.body;
if (!konto || !name) {
return res.status(400).json({ error: 'Konto und Name sind erforderlich' });
}
try {
await executeQuery(
'UPDATE fibdash.Konto SET konto = @konto, name = @name WHERE id = @id',
{ konto, name, id }
);
res.json({ message: 'Konto erfolgreich aktualisiert' });
} catch (error) {
console.error('Error updating konto:', error);
if (error.number === 2627) { // Unique constraint violation
res.status(400).json({ error: 'Konto bereits vorhanden' });
} else {
res.status(500).json({ error: 'Fehler beim Aktualisieren des Kontos' });
}
}
});
// Delete konto
router.delete('/konten/:id', authenticateToken, async (req, res) => {
const { id } = req.params;
try {
await executeQuery('DELETE FROM fibdash.Konto WHERE id = @id', { id });
res.json({ message: 'Konto erfolgreich gelöscht' });
} catch (error) {
console.error('Error deleting konto:', error);
if (error.number === 547) { // Foreign key constraint violation
res.status(400).json({ error: 'Konto kann nicht gelöscht werden, da es in Buchungen verwendet wird' });
} else {
res.status(500).json({ error: 'Fehler beim Löschen des Kontos' });
}
}
});
// ==================== BU (BUCHUNGSSCHLÜSSEL) ROUTES ====================
// Get all buchungsschluessel
router.get('/buchungsschluessel', authenticateToken, async (req, res) => {
try {
const result = await executeQuery('SELECT * FROM fibdash.BU ORDER BY bu');
res.json({ buchungsschluessel: result.recordset });
} catch (error) {
console.error('Error fetching buchungsschluessel:', error);
res.status(500).json({ error: 'Fehler beim Laden der Buchungsschlüssel' });
}
});
// Create new buchungsschluessel
router.post('/buchungsschluessel', authenticateToken, async (req, res) => {
const { bu, name, vst } = req.body;
if (!bu || !name) {
return res.status(400).json({ error: 'BU und Name sind erforderlich' });
}
try {
await executeQuery(
'INSERT INTO fibdash.BU (bu, name, vst) VALUES (@bu, @name, @vst)',
{ bu, name, vst: vst !== undefined && vst !== '' ? vst : null }
);
res.json({ message: 'Buchungsschlüssel erfolgreich erstellt' });
} catch (error) {
console.error('Error creating BU:', error);
if (error.number === 2627) { // Unique constraint violation
res.status(400).json({ error: 'Buchungsschlüssel bereits vorhanden' });
} else {
res.status(500).json({ error: 'Fehler beim Erstellen des Buchungsschlüssels' });
}
}
});
// Update buchungsschluessel
router.put('/buchungsschluessel/:id', authenticateToken, async (req, res) => {
const { id } = req.params;
const { bu, name, vst } = req.body;
if (!bu || !name) {
return res.status(400).json({ error: 'BU und Name sind erforderlich' });
}
try {
await executeQuery(
'UPDATE fibdash.BU SET bu = @bu, name = @name, vst = @vst WHERE id = @id',
{ bu, name, vst: vst !== undefined && vst !== '' ? vst : null, id }
);
res.json({ message: 'Buchungsschlüssel erfolgreich aktualisiert' });
} catch (error) {
console.error('Error updating BU:', error);
if (error.number === 2627) { // Unique constraint violation
res.status(400).json({ error: 'Buchungsschlüssel bereits vorhanden' });
} else {
res.status(500).json({ error: 'Fehler beim Aktualisieren des Buchungsschlüssels' });
}
}
});
// Delete buchungsschluessel
router.delete('/buchungsschluessel/:id', authenticateToken, async (req, res) => {
const { id } = req.params;
try {
await executeQuery('DELETE FROM fibdash.BU WHERE id = @id', { id });
res.json({ message: 'Buchungsschlüssel erfolgreich gelöscht' });
} catch (error) {
console.error('Error deleting BU:', error);
if (error.number === 547) { // Foreign key constraint violation
res.status(400).json({ error: 'Buchungsschlüssel kann nicht gelöscht werden, da er in Buchungen verwendet wird' });
} else {
res.status(500).json({ error: 'Fehler beim Löschen des Buchungsschlüssels' });
}
}
});
module.exports = router;