Ein Wert, ein Ort: Startwerte und Raten read-only, Verteil-Dialoge als einziger Eingabeort
Deploy App / deploy (push) Successful in 1m13s
Deploy App / deploy (push) Successful in 1m13s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,7 +4,6 @@ import { useState } from "react";
|
||||
import { Trash2 } from "lucide-react";
|
||||
import { AlertTriangle } from "lucide-react";
|
||||
import { FieldLabel, InheritableField, MoneyField, NumberField, SelectField, TextField } from "@/components/FormField";
|
||||
import { InfoBubble } from "@/components/InfoBubble";
|
||||
import { formatChf } from "@/lib/format";
|
||||
import { api } from "@/lib/api-client";
|
||||
// Die reinen Uebergangs-Regeln liegen in lib/transitions.ts (auch serverseitig nutzbar) und
|
||||
@@ -73,6 +72,18 @@ export interface CellContext {
|
||||
// Betrag, der aus einem Kapitalbezug in DIESES Element umgeleitet wurde (Punkt C).
|
||||
capitalFromTransfer: number;
|
||||
capitalFromTransferSources: { name: string; amount: number }[];
|
||||
// Stammdaten des Elements. In der ERSTEN Phase ist der Startwert genau das -- er wird dort
|
||||
// nur noch ANGEZEIGT, denn sonst entstünde derselbe Betrag an zwei Orten (Kap. 3.14.3).
|
||||
baseData: PhaseData;
|
||||
// Einmalige Kapitalverwendungen, die am Übergang IN diese Phase beschlossen wurden. Sie
|
||||
// liegen technisch an der Vorphase, gehören aber sichtbar hierher -- zusammen mit der
|
||||
// Zusatzeinlage, die aus demselben Topf stammt.
|
||||
oneOffAmortization: number;
|
||||
oneOffRepayment: number;
|
||||
// Absprünge. Ein Wert entsteht an genau EINEM Ort; angezeigt wird er überall, wo er wirkt.
|
||||
onEditBase?: () => void;
|
||||
onDistributeRates?: () => void;
|
||||
onDistributeCapital?: () => void;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
@@ -118,6 +129,51 @@ function DerivedField({ label, value, help }: { label: string; value: number; he
|
||||
);
|
||||
}
|
||||
|
||||
// Read-only Anzeige mit Absprung an den Ort, an dem der Wert ENTSTEHT.
|
||||
//
|
||||
// Seit 0.40 hat jede Zahl genau einen Entstehungsort: Bestände in den Stammdaten, jährliche
|
||||
// Raten im Verteil-Dialog der Quote, einmalige Kapitalverwendungen im Kapital-Dialog. In der
|
||||
// Zelle stehen sie trotzdem -- nur eben unveränderlich. Zwei Eingabefelder für dieselbe Zahl
|
||||
// sind der Fehler, den dieser Umbau beseitigt: Man tippt in das eine und wundert sich, warum
|
||||
// das andere gewinnt.
|
||||
function LinkedField({
|
||||
label,
|
||||
value,
|
||||
help,
|
||||
actionLabel,
|
||||
onAction,
|
||||
suffix,
|
||||
}: {
|
||||
label: string;
|
||||
value: number;
|
||||
help?: string;
|
||||
actionLabel: string;
|
||||
onAction?: () => void;
|
||||
// Zusatz hinter dem Betrag, z. B. "/Jahr".
|
||||
suffix?: string;
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
<FieldLabel label={label} help={help} />
|
||||
<div className="flex w-full items-center justify-between gap-2 rounded-lg border border-dashed border-border bg-surface-2 px-2.5 py-1.5 text-sm text-muted">
|
||||
<span className="tabular-nums">
|
||||
{formatChf(value)}
|
||||
{suffix ? <span className="text-faint"> {suffix}</span> : null}
|
||||
</span>
|
||||
{onAction && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={onAction}
|
||||
className="shrink-0 whitespace-nowrap rounded border border-accent px-1.5 py-0.5 text-[11px] font-semibold text-accent transition-colors hover:bg-accent hover:text-accent-fg"
|
||||
>
|
||||
{actionLabel}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// PK/3a-Bezugs-Entscheid im normalen Übergang (Vorbezug): Kein Bezug / Bezug (+ Betrag +
|
||||
// Kapitalbezugssteuer). Der Bezugsbetrag wird brutto dem Kapital entnommen; ins Cash fliesst
|
||||
// der Betrag nach Abzug der Steuer.
|
||||
@@ -484,7 +540,48 @@ export function ElementPhaseFields({
|
||||
);
|
||||
};
|
||||
const asPct = (v: number) => `${v} %`;
|
||||
const asChf = (v: number) => formatChf(v);
|
||||
|
||||
// Der Startwert der ERSTEN Phase ist der Stammdatenwert -- hier nur angezeigt, geändert
|
||||
// wird er in der Spalte «Start». Bis 0.39 stand hier ein Eingabefeld, das
|
||||
// `phaseValues[phase1]` schrieb und die Stammdaten still überschattete (der Rechenkern
|
||||
// legt sie als `{...baseData, ...phaseValues}` übereinander): dieselbe Zahl an zwei Orten.
|
||||
const bd = context.baseData;
|
||||
const start = (key: "amount" | "currentValue" | "startValue" | "purchasePrice" | "mortgage", label: string, help?: string) => (
|
||||
<LinkedField
|
||||
label={label}
|
||||
help={help}
|
||||
value={Math.round(num(pd[key], num(bd[key])))}
|
||||
actionLabel="Startwert bearbeiten"
|
||||
onAction={context.onEditBase}
|
||||
/>
|
||||
);
|
||||
|
||||
// Jährliche Raten. Sie entstehen ausschliesslich im Verteil-Dialog der Spar- bzw.
|
||||
// Verzehrquote: Nur dort sieht man, wie viel überhaupt zu verteilen ist, und dass die
|
||||
// Summe aufgeht. Ein zweites Eingabefeld je Element hätte man auch über die Quote hinaus
|
||||
// füllen können, ohne dass es jemand merkt.
|
||||
const rate = (key: InheritableKey, label: string, help?: string) => (
|
||||
<LinkedField
|
||||
label={label}
|
||||
help={help}
|
||||
value={Math.round(num(pd[key], num(context.inheritedValues[key])))}
|
||||
suffix="/Jahr"
|
||||
actionLabel="Quote verteilen"
|
||||
onAction={context.onDistributeRates}
|
||||
/>
|
||||
);
|
||||
|
||||
// Einmalige Verwendung des in dieser Phase verfügbaren Kapitals -- alle aus demselben Topf,
|
||||
// deshalb auch alle im selben Dialog.
|
||||
const capital = (label: string, value: number, help?: string) => (
|
||||
<LinkedField
|
||||
label={label}
|
||||
help={help}
|
||||
value={Math.round(value)}
|
||||
actionLabel="Kapital verteilen"
|
||||
onAction={context.onDistributeCapital}
|
||||
/>
|
||||
);
|
||||
|
||||
switch (element.category) {
|
||||
case "INCOME":
|
||||
@@ -492,7 +589,8 @@ export function ElementPhaseFields({
|
||||
const isIncome = element.category === "INCOME";
|
||||
// Basiswert (erstes Jahr). Ab Phase 2 mit dem fortgeschriebenen Wert der Vorphase
|
||||
// vorbelegt, aber bewusst änderbar (Teilzeit, Beförderung, Jobwechsel …).
|
||||
const baseValue = typeof pd.amount === "number" ? pd.amount : carried ? context.derivedStart : 0;
|
||||
const baseValue =
|
||||
typeof pd.amount === "number" ? pd.amount : carried ? context.derivedStart : num(bd.amount);
|
||||
const d = context.deflatorStart || 1;
|
||||
// Info-Gegenwert im ersten Jahr: Einkommen -> real; Ausgaben -> nominal.
|
||||
const otherValue = isIncome ? Math.round(baseValue / d) : Math.round(baseValue * d);
|
||||
@@ -503,12 +601,22 @@ export function ElementPhaseFields({
|
||||
? "Bitte das NETTO-Einkommen erfassen: der Betrag, der nach allen Lohnabzügen (AHV/ALV, Pensionskasse, NBU) tatsächlich aufs Konto kommt – nicht der Bruttolohn. Erfasst wird NOMINAL; der reale Wert (heutige Kaufkraft) erscheint nur zur Info. Für die AHV-Rente rechnet das Tool intern auf den Bruttolohn zurück."
|
||||
: "Ausgaben werden REAL erfasst (in heutiger Kaufkraft). Die Inflation (plan-weit) rechnet daraus automatisch die nominalen Ausgaben – nur zur Info."}
|
||||
</p>
|
||||
<MoneyField
|
||||
label={isIncome ? "Jahreseinkommen NETTO, nominal (erstes Jahr)" : "Jahresausgaben REAL (erstes Jahr, heutige Kaufkraft)"}
|
||||
help={carried ? "Vorbelegt mit dem fortgeschriebenen Wert der Vorphase; hier bewusst änderbar." : undefined}
|
||||
value={baseValue}
|
||||
onChange={(v) => setP({ amount: v })}
|
||||
/>
|
||||
{carried ? (
|
||||
// Ab Phase 2 bewusst änderbar: Teilzeit, Beförderung, Jobwechsel, anderer
|
||||
// Lebensstandard -- das sind echte Entscheide dieser Phase.
|
||||
<MoneyField
|
||||
label={isIncome ? "Jahreseinkommen NETTO, nominal (erstes Jahr)" : "Jahresausgaben REAL (erstes Jahr, heutige Kaufkraft)"}
|
||||
help="Vorbelegt mit dem fortgeschriebenen Wert der Vorphase; hier bewusst änderbar."
|
||||
value={baseValue}
|
||||
onChange={(v) => setP({ amount: v })}
|
||||
/>
|
||||
) : (
|
||||
start(
|
||||
"amount",
|
||||
isIncome ? "Jahreseinkommen NETTO, nominal (erstes Jahr)" : "Jahresausgaben REAL (erstes Jahr, heutige Kaufkraft)",
|
||||
"In der ersten Lebensphase ist das der Wert aus der Bestandsaufnahme – geändert wird er in der Spalte «Start»."
|
||||
)
|
||||
)}
|
||||
<DerivedField
|
||||
label={isIncome ? "≈ real (heutige Kaufkraft)" : "≈ nominal (in diesem Jahr)"}
|
||||
value={otherValue}
|
||||
@@ -646,23 +754,19 @@ export function ElementPhaseFields({
|
||||
{carried ? (
|
||||
<>
|
||||
<DerivedField label="Startwert (fortgeschrieben)" value={context.derivedStart} help="Endwert der Vorphase, fortgeschrieben." />
|
||||
<MoneyField
|
||||
label="Zusatzeinlage aus Kapital (CHF)"
|
||||
help="Aufstockung aus dem verfügbaren Kapital dieser Phase."
|
||||
value={num(pd.additionalInvestment)}
|
||||
|
||||
onChange={(v) => setP({ additionalInvestment: v })}
|
||||
/>
|
||||
{capital(
|
||||
"Zusatzeinlage aus Kapital (CHF)",
|
||||
num(pd.additionalInvestment),
|
||||
"Aufstockung aus dem verfügbaren Kapital dieser Phase."
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<MoneyField label="Aktueller PK-Wert (CHF)" value={num(pd.currentValue)} onChange={(v) => setP({ currentValue: v })} />
|
||||
start("currentValue", "Aktueller PK-Wert (CHF)")
|
||||
)}
|
||||
{inh(
|
||||
{rate(
|
||||
"annualContribution",
|
||||
"Jährliche Einzahlung (CHF)",
|
||||
(v, set) => <MoneyField label="Jährliche Einzahlung (CHF)" value={v} onChange={set} />,
|
||||
asChf,
|
||||
"Arbeitnehmer- und Arbeitgeberbeiträge. Fliesst NICHT in die Sparquote ein (bereits in den Ausgaben berücksichtigt)."
|
||||
"Arbeitnehmer- und Arbeitgeberbeiträge. Stammen aus dem BRUTTOLOHN und schmälern die Sparquote nicht – deshalb stehen sie im Verteil-Dialog in einem eigenen Block."
|
||||
)}
|
||||
{inh(
|
||||
"expectedReturn",
|
||||
@@ -677,40 +781,27 @@ export function ElementPhaseFields({
|
||||
return <p className="col-span-2 text-sm text-muted">Die Säule 3a wird beim Pensions-Übergang vollständig bezogen.</p>;
|
||||
}
|
||||
// «Grosse Säule 3a» für Selbstständige ohne PK: höhere Obergrenze (Roadmap-Feedback C7c).
|
||||
// Der Schalter steht seit 0.40 im Verteil-Dialog, weil er dort die Obergrenze der
|
||||
// Einzahlung bestimmt -- getrennt von ihr wäre er eine Einstellung ohne sichtbare Wirkung.
|
||||
const max3a = pd.selfEmployed3a ? PILLAR_3A_MAX_SELF_EMPLOYED : PILLAR_3A_MAX_ANNUAL;
|
||||
return (
|
||||
<>
|
||||
{carried ? (
|
||||
<>
|
||||
<DerivedField label="Startwert (fortgeschrieben)" value={context.derivedStart} help="Endwert der Vorphase, fortgeschrieben." />
|
||||
<MoneyField
|
||||
label="Zusatzeinlage aus Kapital (CHF)"
|
||||
help="Aufstockung aus dem verfügbaren Kapital dieser Phase."
|
||||
value={num(pd.additionalInvestment)}
|
||||
|
||||
onChange={(v) => setP({ additionalInvestment: v })}
|
||||
/>
|
||||
{capital(
|
||||
"Zusatzeinlage aus Kapital (CHF)",
|
||||
num(pd.additionalInvestment),
|
||||
"Aufstockung aus dem verfügbaren Kapital dieser Phase."
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<MoneyField label="Aktueller 3a-Wert (CHF)" value={num(pd.currentValue)} onChange={(v) => setP({ currentValue: v })} />
|
||||
start("currentValue", "Aktueller 3a-Wert (CHF)")
|
||||
)}
|
||||
<label className="col-span-2 flex cursor-pointer items-center gap-2 text-xs text-muted">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={!!pd.selfEmployed3a}
|
||||
onChange={(e) => setP({ selfEmployed3a: e.target.checked })}
|
||||
/>
|
||||
Selbstständig ohne Pensionskasse («grosse Säule 3a»)
|
||||
<InfoBubble text={`Selbstständigerwerbende ohne PK dürfen bis 20 % des Nettoerwerbseinkommens einzahlen, gedeckelt auf ca. ${PILLAR_3A_MAX_SELF_EMPLOYED.toLocaleString("de-CH")} CHF – statt der ${PILLAR_3A_MAX_ANNUAL.toLocaleString("de-CH")} CHF mit PK.`} />
|
||||
</label>
|
||||
{inh(
|
||||
{rate(
|
||||
"annualContribution",
|
||||
"Jährliche Einzahlung (CHF)",
|
||||
(v, set) => (
|
||||
<MoneyField label="Jährliche Einzahlung (CHF)" value={v} max={max3a} onChange={set} />
|
||||
),
|
||||
asChf,
|
||||
`Maximal CHF ${max3a.toLocaleString("de-CH")} (2026, ${pd.selfEmployed3a ? "Selbstständig ohne PK" : "mit PK"}) und höchstens die Sparquote. Wird von der Sparquote abgezogen.`
|
||||
`Maximal CHF ${max3a.toLocaleString("de-CH")} (2026, ${pd.selfEmployed3a ? "Selbstständig ohne PK" : "mit PK"}) und höchstens die Sparquote.`
|
||||
)}
|
||||
{inh(
|
||||
"expectedReturn",
|
||||
@@ -724,8 +815,9 @@ export function ElementPhaseFields({
|
||||
case "REAL_ESTATE": {
|
||||
// Zinsbetrag zu Phasenbeginn und -ende: die Restschuld sinkt mit der Amortisation,
|
||||
// der Zinsbetrag also mit. Am Nullpunkt gekappt (analog zur Berechnung).
|
||||
const hypStart = carried ? context.derivedMortgage : num(pd.mortgage);
|
||||
const hypEnde = Math.max(0, hypStart - num(pd.amortization) * context.durationYears);
|
||||
const hypStart = carried ? context.derivedMortgage : num(pd.mortgage, num(bd.mortgage));
|
||||
const amortEff = num(pd.amortization, num(context.inheritedValues.amortization));
|
||||
const hypEnde = Math.max(0, hypStart - amortEff * context.durationYears);
|
||||
const zinsStart = Math.round((hypStart * num(pd.interestRate)) / 100);
|
||||
const zinsEnde = Math.round((hypEnde * num(pd.interestRate)) / 100);
|
||||
const handling = pd.interestHandling ?? "INCLUDED";
|
||||
@@ -742,17 +834,21 @@ export function ElementPhaseFields({
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<MoneyField label="Kaufpreis (CHF)" value={num(pd.purchasePrice)} onChange={(v) => setP({ purchasePrice: v })} />
|
||||
<MoneyField label="Hypothek (CHF)" value={num(pd.mortgage)} onChange={(v) => setP({ mortgage: v })} />
|
||||
{start("purchasePrice", "Kaufpreis (CHF)")}
|
||||
{start("mortgage", "Hypothek (CHF)")}
|
||||
</>
|
||||
)}
|
||||
{inh(
|
||||
{rate(
|
||||
"amortization",
|
||||
"Amortisation (CHF/Jahr)",
|
||||
(v, set) => <MoneyField label="Amortisation (CHF/Jahr)" value={v} onChange={set} />,
|
||||
asChf,
|
||||
"Jährliche Reduktion der Hypothek. Zählt gegen die Sparquote und endet, sobald die Hypothek abbezahlt ist."
|
||||
)}
|
||||
{context.oneOffAmortization > 0 &&
|
||||
capital(
|
||||
"Sonderamortisation aus Kapital (CHF)",
|
||||
context.oneOffAmortization,
|
||||
"Einmaltilgung am Übergang in diese Phase, aus dem verfügbaren Kapital."
|
||||
)}
|
||||
{inh(
|
||||
"interestRate",
|
||||
"Hypothekarzins (%/Jahr)",
|
||||
@@ -797,12 +893,11 @@ export function ElementPhaseFields({
|
||||
{carried ? (
|
||||
<>
|
||||
<DerivedField label="Startwert (fortgeschrieben)" value={context.derivedStart} help="Endwert der Vorphase, fortgeschrieben." />
|
||||
<MoneyField
|
||||
label="Zusatzinvestition aus Kapital (CHF)"
|
||||
help="Neuinvestition aus dem verfügbaren Kapital dieser Phase."
|
||||
value={num(pd.additionalInvestment)}
|
||||
onChange={(v) => setP({ additionalInvestment: v })}
|
||||
/>
|
||||
{capital(
|
||||
"Zusatzinvestition aus Kapital (CHF)",
|
||||
num(pd.additionalInvestment),
|
||||
"Neuinvestition aus dem verfügbaren Kapital dieser Phase."
|
||||
)}
|
||||
{/* Aus einem Kapitalbezug (PK/3a) am letzten Übergang umgeleitet -- nicht hier
|
||||
erfasst, sondern dort als Quote entschieden (Punkt C). Kommt der Betrag aus
|
||||
mehreren Bezügen (PK und 3a, ggf. beider Personen), wird er einzeln
|
||||
@@ -831,7 +926,7 @@ export function ElementPhaseFields({
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<MoneyField label="Startwert (CHF)" value={num(pd.startValue)} onChange={(v) => setP({ startValue: v })} />
|
||||
start("startValue", "Startwert (CHF)")
|
||||
)}
|
||||
{inh(
|
||||
"expectedReturn",
|
||||
@@ -839,18 +934,14 @@ export function ElementPhaseFields({
|
||||
(v, set) => <NumberField label="Erwartete Rendite (%/Jahr)" step={0.1} value={v} onChange={set} />,
|
||||
asPct
|
||||
)}
|
||||
{inh(
|
||||
{rate(
|
||||
"annualContribution",
|
||||
"Jährlicher Sparbeitrag (CHF)",
|
||||
(v, set) => <MoneyField label="Jährlicher Sparbeitrag (CHF)" value={v} onChange={set} />,
|
||||
asChf,
|
||||
"Flacher Jahresbetrag, der ins Vermögen fliesst und vom Cash abgezogen wird (geplante Sparrate)."
|
||||
)}
|
||||
{inh(
|
||||
{rate(
|
||||
"annualWithdrawal",
|
||||
"Jährliche Bezugsrate (CHF)",
|
||||
(v, set) => <MoneyField label="Jährliche Bezugsrate (CHF)" value={v} onChange={set} />,
|
||||
asChf,
|
||||
"Entnahme aus dem Vermögen (z. B. laufende Renten-Entnahme im Alter). Mindert das Vermögen und fliesst jährlich ins Cash (geplante Verzehrrate)."
|
||||
)}
|
||||
</>
|
||||
@@ -861,15 +952,15 @@ export function ElementPhaseFields({
|
||||
{carried ? (
|
||||
<DerivedField label="Restschuld (fortgeschrieben)" value={Math.abs(context.derivedStart)} help="Fortgeschriebene Restschuld aus der Vorphase." />
|
||||
) : (
|
||||
<MoneyField label="Restschuld (CHF)" value={num(pd.startValue)} onChange={(v) => setP({ startValue: v })} />
|
||||
)}
|
||||
{inh(
|
||||
"annualRepayment",
|
||||
"Jährliche Tilgung (CHF)",
|
||||
(v, set) => <MoneyField label="Jährliche Tilgung (CHF)" value={v} onChange={set} />,
|
||||
asChf,
|
||||
"Zählt gegen die Sparquote (max. die Sparquote)."
|
||||
start("startValue", "Restschuld (CHF)")
|
||||
)}
|
||||
{rate("annualRepayment", "Jährliche Tilgung (CHF)", "Zählt gegen die Sparquote (max. die Sparquote).")}
|
||||
{context.oneOffRepayment > 0 &&
|
||||
capital(
|
||||
"Sofort-Tilgung aus Kapital (CHF)",
|
||||
context.oneOffRepayment,
|
||||
"Einmalige Tilgung am Übergang in diese Phase, aus dem verfügbaren Kapital."
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -988,13 +1079,15 @@ export function ElementTransitionFields({
|
||||
<NumberField label="Grundstückgewinnsteuer (%)" step={1} value={num(td.saleTaxRate, DEFAULT_PROPERTY_GAINS_TAX_RATE)} onChange={(v) => setT({ saleTaxRate: v })} />
|
||||
</>
|
||||
)}
|
||||
{decision !== "SELL" && context.mortgageEnd > 0 && (
|
||||
<MoneyField
|
||||
label="Sonderamortisation (CHF)"
|
||||
help={`Einmaltilgung der Hypothek aus dem Cash der nächsten Phase (z. B. aus einem 3a-Bezug). Senkt Restschuld und künftige Zinsen. Maximal ${formatChf(context.mortgageEnd)} (Resthypothek am Phasenende).`}
|
||||
{/* Die Sonderamortisation stand bis 0.39 hier. Sie stammt aber aus dem Kapital, das
|
||||
in der FOLGEphase verfügbar ist, und wird dort im Kapital-Dialog zusammen mit
|
||||
allen anderen Verwendungen desselben Topfs entschieden. Zwei Eingaben für
|
||||
denselben Franken -- hier und dort -- gab es damit nicht mehr. */}
|
||||
{decision !== "SELL" && context.mortgageEnd > 0 && num(td.extraAmortization) > 0 && (
|
||||
<DerivedField
|
||||
label="Sonderamortisation aus Kapital (CHF)"
|
||||
value={num(td.extraAmortization)}
|
||||
max={context.mortgageEnd}
|
||||
onChange={(v) => setT({ extraAmortization: v })}
|
||||
help="Einmaltilgung aus dem Kapital der nächsten Phase. Geändert wird sie dort unter «Kapital verteilen»."
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
@@ -1027,13 +1120,18 @@ export function ElementTransitionFields({
|
||||
);
|
||||
}
|
||||
case "OTHER_DEBT":
|
||||
return (
|
||||
<MoneyField
|
||||
label="Sofortige Tilgung (CHF)"
|
||||
help="Wird sofort getilgt und vom verfügbaren Kapital der nächsten Phase abgezogen."
|
||||
// Dito: Die Sofort-Tilgung zehrt vom Kapital der Folgephase und wird dort entschieden.
|
||||
return num(td.immediateRepayment) > 0 ? (
|
||||
<DerivedField
|
||||
label="Sofort-Tilgung aus Kapital (CHF)"
|
||||
value={num(td.immediateRepayment)}
|
||||
onChange={(v) => setT({ immediateRepayment: v })}
|
||||
help="Wird am Übergang getilgt, aus dem Kapital der nächsten Phase. Geändert wird sie dort unter «Kapital verteilen»."
|
||||
/>
|
||||
) : (
|
||||
<p className="col-span-2 text-sm text-muted">
|
||||
Am Übergang ist hier nichts zu entscheiden. Eine einmalige Tilgung aus dem verfügbaren Kapital
|
||||
nimmst du in der nächsten Lebensphase unter «Kapital verteilen» vor.
|
||||
</p>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user