fix: Liquidität — operativer Überschuss ohne Kapitaleinzahlungen

Überschuss = NUR operativer Cashflow:
  Einzahlungen: Umsatz + Sonst.Erträge + Anzahlungen (OHNE EK/FK)
  Auszahlungen: Material + Personal + Sonstige + Steuern (OHNE Kredit)
  = Operativer Überschuss

Kontostand = Vormonat + Operativer Überschuss + Finanzierung
  Finanzierung = EK + FK - Kreditrückzahlungen (separat)

So zeigt der Überschuss die echte operative Performance,
die Kapitaleinzahlung erscheint nur im Kontostand.

Marketing: 5.000€/Mo ab Jul 2027 (statt 20k)
Alle Werte Math.round() — ganzzahlig

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Benjamin Admin
2026-03-27 17:40:50 +01:00
parent f849fd729a
commit 11c0c1df38

View File

@@ -289,6 +289,7 @@ export async function computeFinanzplan(pool: Pool, scenarioId: string): Promise
}
// Compute sums and rolling balance
// WICHTIG: Überschuss = nur operativer Cashflow (ohne Kapitaleinzahlungen)
const sumEin = findLiq('Summe EINZAHLUNGEN')
const sumAus = findLiq('Summe AUSZAHLUNGEN')
const uebVorInv = findLiq('UEBERSCHUSS VOR INVESTITIONEN')
@@ -297,59 +298,81 @@ export async function computeFinanzplan(pool: Pool, scenarioId: string): Promise
const kontostand = findLiq('Kontostand zu Beginn des Monats')
const liquiditaet = findLiq('LIQUIDITAET')
const einzahlungen = ['Umsatzerloese', 'Sonst. betriebl. Ertraege', 'Anzahlungen', 'Neuer Eigenkapitalzugang', 'Erhaltenes Fremdkapital']
const auszahlungen = ['Materialaufwand', 'Personalkosten', 'Sonstige Kosten', 'Kreditrueckzahlungen', 'Umsatzsteuer', 'Gewerbesteuer', 'Koerperschaftsteuer']
// Operative Einzahlungen (OHNE Eigenkapital und Fremdkapital)
const einzahlungenOperativ = ['Umsatzerloese', 'Sonst. betriebl. Ertraege', 'Anzahlungen']
// Finanzierung (separat)
const finanzierung = ['Neuer Eigenkapitalzugang', 'Erhaltenes Fremdkapital']
// Operative Auszahlungen (OHNE Kreditrückzahlungen)
const auszahlungenOperativ = ['Materialaufwand', 'Personalkosten', 'Sonstige Kosten', 'Umsatzsteuer', 'Gewerbesteuer', 'Koerperschaftsteuer']
const finanzAuszahlungen = ['Kreditrueckzahlungen']
// Summe EINZAHLUNGEN = nur operativ (für die Zeile "Summe Einzahlungen")
if (sumEin) {
const s = emptyMonthly()
for (const label of einzahlungen) {
for (const label of einzahlungenOperativ) {
const row = findLiq(label)
if (row) for (let m = 1; m <= MONTHS; m++) s[`m${m}`] += row.values[`m${m}`] || 0
if (row) for (let m = 1; m <= MONTHS; m++) s[`m${m}`] += Math.round(row.values[`m${m}`] || 0)
}
await pool.query('UPDATE fp_liquiditaet SET values = $1 WHERE id = $2', [JSON.stringify(s), sumEin.id])
sumEin.values = s
}
// Summe AUSZAHLUNGEN = nur operativ
if (sumAus) {
const s = emptyMonthly()
for (const label of auszahlungen) {
for (const label of auszahlungenOperativ) {
const row = findLiq(label)
if (row) for (let m = 1; m <= MONTHS; m++) s[`m${m}`] += row.values[`m${m}`] || 0
if (row) for (let m = 1; m <= MONTHS; m++) s[`m${m}`] += Math.round(row.values[`m${m}`] || 0)
}
await pool.query('UPDATE fp_liquiditaet SET values = $1 WHERE id = $2', [JSON.stringify(s), sumAus.id])
sumAus.values = s
}
// Überschüsse und Kontostand
// OPERATIVER ÜBERSCHUSS VOR INVESTITIONEN = operative Einzahlungen - operative Auszahlungen
if (uebVorInv && sumEin && sumAus) {
const s = emptyMonthly()
for (let m = 1; m <= MONTHS; m++) s[`m${m}`] = (sumEin.values[`m${m}`] || 0) - (sumAus.values[`m${m}`] || 0)
for (let m = 1; m <= MONTHS; m++) s[`m${m}`] = Math.round((sumEin.values[`m${m}`] || 0) - (sumAus.values[`m${m}`] || 0))
await pool.query('UPDATE fp_liquiditaet SET values = $1 WHERE id = $2', [JSON.stringify(s), uebVorInv.id])
uebVorInv.values = s
}
// ÜBERSCHUSS VOR ENTNAHMEN = Operativer Überschuss - Investitionen
if (uebVorEnt && uebVorInv && liqInvest) {
const s = emptyMonthly()
for (let m = 1; m <= MONTHS; m++) s[`m${m}`] = (uebVorInv.values[`m${m}`] || 0) - (liqInvest.values[`m${m}`] || 0)
for (let m = 1; m <= MONTHS; m++) s[`m${m}`] = Math.round((uebVorInv.values[`m${m}`] || 0) - (liqInvest.values[`m${m}`] || 0))
await pool.query('UPDATE fp_liquiditaet SET values = $1 WHERE id = $2', [JSON.stringify(s), uebVorEnt.id])
uebVorEnt.values = s
}
// ÜBERSCHUSS = Überschuss vor Entnahmen - Entnahmen (immer noch rein operativ)
const entnahmen = findLiq('Kapitalentnahmen/Ausschuettungen')
if (ueberschuss && uebVorEnt && entnahmen) {
const s = emptyMonthly()
for (let m = 1; m <= MONTHS; m++) s[`m${m}`] = (uebVorEnt.values[`m${m}`] || 0) - (entnahmen.values[`m${m}`] || 0)
for (let m = 1; m <= MONTHS; m++) s[`m${m}`] = Math.round((uebVorEnt.values[`m${m}`] || 0) - (entnahmen.values[`m${m}`] || 0))
await pool.query('UPDATE fp_liquiditaet SET values = $1 WHERE id = $2', [JSON.stringify(s), ueberschuss.id])
ueberschuss.values = s
}
// Rolling Kontostand
// Rolling Kontostand: Vormonat + Operativer Überschuss + Finanzierung
// Finanzierung = Eigenkapital + Fremdkapital - Kreditrückzahlungen
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 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)
}
const ks = emptyMonthly()
const lq = emptyMonthly()
for (let m = 1; m <= MONTHS; m++) {
ks[`m${m}`] = m === 1 ? 0 : lq[`m${m - 1}`]
lq[`m${m}`] = ks[`m${m}`] + (ueberschuss.values[`m${m}`] || 0)
ks[`m${m}`] = m === 1 ? 0 : Math.round(lq[`m${m - 1}`])
// LIQUIDITÄT = Kontostand + Operativer Überschuss + Finanzierung
lq[`m${m}`] = Math.round(ks[`m${m}`] + (ueberschuss.values[`m${m}`] || 0) + (finCF[`m${m}`] || 0))
}
await pool.query('UPDATE fp_liquiditaet SET values = $1 WHERE id = $2', [JSON.stringify(ks), kontostand.id])
await pool.query('UPDATE fp_liquiditaet SET values = $1 WHERE id = $2', [JSON.stringify(lq), liquiditaet.id])