feat(buchhaltung): add transfers, bank statements, Haushaltsplan, and PDF export

This commit is contained in:
Matthias Hochmeister
2026-03-30 17:05:18 +02:00
parent 2eb59e9ff1
commit 5acfd7cc4f
14 changed files with 1911 additions and 10 deletions

View File

@@ -8,6 +8,7 @@ import fs from 'fs';
import notificationService from './notification.service';
import { permissionService } from './permission.service';
import ausruestungsanfrageService from './ausruestungsanfrage.service';
import buchhaltungService from './buchhaltung.service';
// ---------------------------------------------------------------------------
// Catalog (shared ausruestung_artikel via ausruestungsanfrageService)
@@ -381,6 +382,17 @@ async function updateOrderStatus(id: number, status: string, userId: string, for
}
}
// Block transition to abgeschlossen if positions have missing prices
if (status === 'abgeschlossen') {
const posCheck = await pool.query(
`SELECT COUNT(*) FROM bestellpositionen WHERE bestellung_id = $1 AND (einzelpreis IS NULL OR einzelpreis = 0)`,
[id]
);
if (parseInt(posCheck.rows[0].count) > 0) {
throw new Error('Alle Positionen müssen einen Einzelpreis haben, bevor die Bestellung abgeschlossen werden kann.');
}
}
const updates: string[] = ['status = $1', 'aktualisiert_am = NOW()'];
const params: unknown[] = [status];
let paramIndex = 2;
@@ -452,6 +464,13 @@ async function updateOrderStatus(id: number, status: string, userId: string, for
});
}
// Create pending buchhaltung transaction when order is completed
if (status === 'abgeschlossen') {
buchhaltungService.createPendingFromBestellung(id, userId).catch(err =>
logger.error('createPendingFromBestellung failed (non-fatal)', { err, orderId: id })
);
}
return result.rows[0];
} catch (error) {
logger.error('BestellungService.updateOrderStatus failed', { error, id });