Neues Feld Plan.initialCash (additiv, Default 0). computePlan startet die erste Phase
mit diesem Cash-Bestand statt 0. In der Matrix ist die Cash-Zelle der ersten Phase
klickbar und oeffnet ein Popup zum Setzen des Anfangswerts (PATCH /api/plans/{id}).
Szenario-Kopie uebernimmt den Wert. Golden-Test ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,7 @@ function plan(opts: {
|
||||
age: number;
|
||||
retirementAge: number;
|
||||
inflation?: number;
|
||||
initialCash?: number;
|
||||
phases: { id: string; durationYears: number }[];
|
||||
elements: ReturnType<typeof el>[];
|
||||
household?: "SINGLE" | "COUPLE";
|
||||
@@ -29,6 +30,7 @@ function plan(opts: {
|
||||
name: "T",
|
||||
householdType: opts.household ?? "SINGLE",
|
||||
inflationRateDefault: opts.inflation ?? 2,
|
||||
initialCash: opts.initialCash ?? 0,
|
||||
persons: [{ id: "A", role: "PERSON_A", name: null, age: opts.age, retirementAge: opts.retirementAge }],
|
||||
phases: opts.phases.map((p, i) => ({ id: p.id, sequenceNumber: i + 1, name: p.id, durationYears: p.durationYears, inflationRate: null })),
|
||||
elements: opts.elements,
|
||||
@@ -103,6 +105,22 @@ describe("V4 Golden Tests", () => {
|
||||
expect(ph.cashNegative).toBe(true);
|
||||
});
|
||||
|
||||
it("Cash-Anfangswert fliesst in die erste Phase ein", () => {
|
||||
const p = plan({
|
||||
age: 40,
|
||||
retirementAge: 60,
|
||||
initialCash: 50000,
|
||||
phases: [{ id: "p1", durationYears: 3 }],
|
||||
elements: [
|
||||
el("INCOME", "PERSON_A", { p1: { amount: 100000, teuerungsausgleich: 0 } }),
|
||||
el("EXPENSE", "HOUSEHOLD", { p1: { amount: 100000, teuerungsausgleich: 0 } }),
|
||||
],
|
||||
});
|
||||
const ph = computePlan(p).phases[0];
|
||||
expect(ph.cashStart).toBe(50000);
|
||||
expect(ph.cashEnd).toBe(50000); // Quote 0, keine Raten -> Cash unveraendert
|
||||
});
|
||||
|
||||
it("indexRate 0 -> Einkommen bleibt nominal flach", () => {
|
||||
const p = plan({
|
||||
age: 40,
|
||||
|
||||
@@ -124,7 +124,7 @@ export function computePlan(plan: PlanInput): PlanComputed {
|
||||
const result: PhaseComputed[] = [];
|
||||
let yearsBefore = 0;
|
||||
let cumulativeInflation = 1;
|
||||
let cashCarryIn = 0;
|
||||
let cashCarryIn = Math.round(plan.initialCash || 0);
|
||||
let ruinAge: number | null = null;
|
||||
|
||||
for (let i = 0; i < phases.length; i++) {
|
||||
|
||||
@@ -31,6 +31,7 @@ export function toPlanInput(plan: PlanWithRelations): PlanInput {
|
||||
name: plan.name,
|
||||
householdType: plan.householdType,
|
||||
inflationRateDefault: plan.inflationRateDefault,
|
||||
initialCash: plan.initialCash,
|
||||
persons: plan.persons.map((p) => ({
|
||||
id: p.id,
|
||||
role: p.role,
|
||||
|
||||
@@ -42,6 +42,7 @@ export interface PlanInput {
|
||||
name: string;
|
||||
householdType: HouseholdType;
|
||||
inflationRateDefault: number;
|
||||
initialCash: number; // Anfangswert des Cash-Kontos in der ersten Lebensphase
|
||||
persons: PersonInput[];
|
||||
phases: PhaseInput[];
|
||||
elements: ElementInput[];
|
||||
|
||||
Reference in New Issue
Block a user