feat: add Buchhaltung dashboard widget, CSV export, Bestellungen linking, recurring bookings, and approval workflow
This commit is contained in:
@@ -335,6 +335,109 @@ class BuchhaltungController {
|
||||
res.status(500).json({ success: false, message: 'Einstellungen konnten nicht gespeichert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// ── Wiederkehrend ────────────────────────────────────────────────────────────
|
||||
|
||||
async listWiederkehrend(_req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const data = await buchhaltungService.getAllWiederkehrend();
|
||||
res.json({ success: true, data });
|
||||
} catch (error) {
|
||||
logger.error('BuchhaltungController.listWiederkehrend', { error });
|
||||
res.status(500).json({ success: false, message: 'Wiederkehrende Buchungen konnten nicht geladen werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async createWiederkehrend(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
const data = await buchhaltungService.createWiederkehrend(req.body, req.user!.id);
|
||||
res.status(201).json({ success: true, data });
|
||||
} catch (error) {
|
||||
logger.error('BuchhaltungController.createWiederkehrend', { error });
|
||||
res.status(500).json({ success: false, message: 'Wiederkehrende Buchung konnte nicht erstellt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async updateWiederkehrend(req: Request, res: Response): Promise<void> {
|
||||
const id = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
|
||||
try {
|
||||
const data = await buchhaltungService.updateWiederkehrend(id, req.body);
|
||||
if (!data) { res.status(404).json({ success: false, message: 'Wiederkehrende Buchung nicht gefunden' }); return; }
|
||||
res.json({ success: true, data });
|
||||
} catch (error) {
|
||||
logger.error('BuchhaltungController.updateWiederkehrend', { error });
|
||||
res.status(500).json({ success: false, message: 'Wiederkehrende Buchung konnte nicht aktualisiert werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async deleteWiederkehrend(req: Request, res: Response): Promise<void> {
|
||||
const id = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
|
||||
try {
|
||||
await buchhaltungService.deleteWiederkehrend(id);
|
||||
res.json({ success: true });
|
||||
} catch (error) {
|
||||
logger.error('BuchhaltungController.deleteWiederkehrend', { error });
|
||||
res.status(500).json({ success: false, message: 'Wiederkehrende Buchung konnte nicht gelöscht werden' });
|
||||
}
|
||||
}
|
||||
|
||||
// ── CSV Export ───────────────────────────────────────────────────────────────
|
||||
|
||||
async exportCsv(req: Request, res: Response): Promise<void> {
|
||||
const haushaltsjahrId = parseInt(req.query.haushaltsjahr_id as string, 10);
|
||||
if (isNaN(haushaltsjahrId)) { res.status(400).json({ success: false, message: 'haushaltsjahr_id erforderlich' }); return; }
|
||||
try {
|
||||
const csv = await buchhaltungService.exportTransaktionenCsv(haushaltsjahrId);
|
||||
res.setHeader('Content-Type', 'text/csv; charset=utf-8');
|
||||
res.setHeader('Content-Disposition', `attachment; filename="transaktionen_${haushaltsjahrId}.csv"`);
|
||||
res.send(csv);
|
||||
} catch (error) {
|
||||
logger.error('BuchhaltungController.exportCsv', { error });
|
||||
res.status(500).json({ success: false, message: 'CSV-Export fehlgeschlagen' });
|
||||
}
|
||||
}
|
||||
|
||||
// ── Freigaben ────────────────────────────────────────────────────────────────
|
||||
|
||||
async requestFreigabe(req: Request, res: Response): Promise<void> {
|
||||
const id = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
|
||||
try {
|
||||
const data = await buchhaltungService.createFreigabe(id, req.user!.id);
|
||||
res.status(201).json({ success: true, data });
|
||||
} catch (error) {
|
||||
logger.error('BuchhaltungController.requestFreigabe', { error });
|
||||
res.status(500).json({ success: false, message: 'Freigabe konnte nicht angefragt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async approveFreigabe(req: Request, res: Response): Promise<void> {
|
||||
const id = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
|
||||
try {
|
||||
const data = await buchhaltungService.approveFreigabe(id, req.body.kommentar, req.user!.id);
|
||||
if (!data) { res.status(404).json({ success: false, message: 'Freigabe nicht gefunden' }); return; }
|
||||
res.json({ success: true, data });
|
||||
} catch (error) {
|
||||
logger.error('BuchhaltungController.approveFreigabe', { error });
|
||||
res.status(500).json({ success: false, message: 'Freigabe konnte nicht genehmigt werden' });
|
||||
}
|
||||
}
|
||||
|
||||
async rejectFreigabe(req: Request, res: Response): Promise<void> {
|
||||
const id = parseInt(param(req, 'id'), 10);
|
||||
if (isNaN(id)) { res.status(400).json({ success: false, message: 'Ungültige ID' }); return; }
|
||||
try {
|
||||
const data = await buchhaltungService.rejectFreigabe(id, req.body.kommentar, req.user!.id);
|
||||
if (!data) { res.status(404).json({ success: false, message: 'Freigabe nicht gefunden' }); return; }
|
||||
res.json({ success: true, data });
|
||||
} catch (error) {
|
||||
logger.error('BuchhaltungController.rejectFreigabe', { error });
|
||||
res.status(500).json({ success: false, message: 'Freigabe konnte nicht abgelehnt werden' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default new BuchhaltungController();
|
||||
|
||||
Reference in New Issue
Block a user