fix(pitch-deck): engine uses dynamic row matching for renamed labels
Some checks failed
Build pitch-deck / build-push-deploy (push) Successful in 1m16s
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-consent (push) Successful in 33s
CI / test-bqas (push) Has been cancelled
CI / test-python-voice (push) Has been cancelled

- Engine no longer hardcodes financing row labels — matches by row_type
- Handles renamed WD rows (Wandeldarlehen Investor/L-Bank, Stammkapital)
- fp-patch: all pending WD fixes (labels, investments, materialaufwand, pos3)
- Bestandskunden annual column shows Dec value (point-in-time)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-04-21 19:39:00 +02:00
parent 898ad1785b
commit e4f2d49e96
3 changed files with 75 additions and 22 deletions

View File

@@ -412,13 +412,23 @@ export async function computeFinanzplan(pool: Pool, scenarioId: string): Promise
const kontostand = findLiq('Kontostand zu Beginn des Monats')
const liquiditaet = findLiq('LIQUIDITÄT')
// Operative Einzahlungen (OHNE Eigenkapital und Fremdkapital)
// Dynamically categorize rows by row_type instead of hardcoded labels
// Operative Einzahlungen (OHNE Eigenkapital, Fremdkapital, Stammkapital, Wandeldarlehen)
const einzahlungenOperativ = ['Umsatzerlöse', 'Sonst. betriebl. Erträge', 'Anzahlungen']
// Finanzierung (separat)
const finanzierung = ['Neuer Eigenkapitalzugang', 'Erhaltenes Fremdkapital']
// Operative Auszahlungen (OHNE Kreditrückzahlungen)
// Finanzierung: match any row with these keywords (handles renamed labels)
const finanzierungRows = liquid.filter(r =>
r.row_type === 'einzahlung' &&
!einzahlungenOperativ.includes(r.row_label) &&
!r.row_label.includes('Summe')
)
// Operative Auszahlungen
const auszahlungenOperativ = ['Materialaufwand', 'Personalkosten', 'Sonstige Kosten', 'Umsatzsteuer', 'Gewerbesteuer', 'Körperschaftsteuer']
const finanzAuszahlungen = ['Kreditrückzahlungen']
// Finanz-Auszahlungen: any auszahlung not in operativ list
const finanzAuszahlungRows = liquid.filter(r =>
r.row_type === 'auszahlung' &&
!auszahlungenOperativ.includes(r.row_label) &&
!r.row_label.includes('Summe')
)
// Summe EINZAHLUNGEN = nur operativ (für die Zeile "Summe Einzahlungen")
if (sumEin) {
@@ -472,13 +482,11 @@ export async function computeFinanzplan(pool: Pool, scenarioId: string): Promise
if (kontostand && liquiditaet && ueberschuss) {
// Berechne monatliche Finanzierungs-Cashflows
const finCF = emptyMonthly()
for (const label of finanzierung) {
const row = findLiq(label)
if (row) for (let m = 1; m <= MONTHS; m++) finCF[`m${m}`] += Math.round(row.values[`m${m}`] || 0)
for (const row of finanzierungRows) {
for (let m = 1; m <= MONTHS; m++) finCF[`m${m}`] += Math.round(row.values[`m${m}`] || 0)
}
for (const label of finanzAuszahlungen) {
const row = findLiq(label)
if (row) for (let m = 1; m <= MONTHS; m++) finCF[`m${m}`] -= Math.round(row.values[`m${m}`] || 0)
for (const row of finanzAuszahlungRows) {
for (let m = 1; m <= MONTHS; m++) finCF[`m${m}`] -= Math.round(row.values[`m${m}`] || 0)
}
const ks = emptyMonthly()