Fundament: Element-Stammdaten, Fixpunkte, Horizont in Jahren, PK-Bezugsalter
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+21
-22
@@ -49,18 +49,24 @@ export function sortedPhases(plan: PlanInput) {
|
||||
|
||||
// --- Planungshorizont -----------------------------------------------------------------------
|
||||
//
|
||||
// Bis 0.33 ergab sich das Planende stillschweigend als Summe der Phasendauern. Zwei Szenarien
|
||||
// Bis 0.35 ergab sich das Planende stillschweigend als Summe der Phasendauern. Zwei Szenarien
|
||||
// konnten dadurch unbemerkt verschieden weit rechnen -- und waren dann nicht vergleichbar,
|
||||
// obwohl genau das ihr Zweck ist. Neu ist der Horizont eine erfasste Zahl, und die LETZTE
|
||||
// Phase folgt ihr (dieselbe Richtung wie beim Pensionsalter: Zahl stellen, Struktur folgt).
|
||||
// obwohl genau das ihr Zweck ist.
|
||||
//
|
||||
// Referenzperson ist die aelteste: Sie erreicht ihren Horizont zuerst, und der Plan muss so
|
||||
// lange laufen, bis die LETZTE Person ihren erreicht hat.
|
||||
// Seit 0.36 ist der Horizont eine Zahl in JAHREN am Szenario. Vorher stand er als Endalter je
|
||||
// PERSON -- bei einem Paar zwei Zahlen, die auseinanderlaufen konnten und aus denen sich das
|
||||
// Planende erst per Maximum ergab. Eine Laufzeit ist eine Eigenschaft der PLANUNG, nicht der
|
||||
// Person; die Endalter sind die Ableitung davon, nicht umgekehrt.
|
||||
export function planEndYear(plan: PlanInput): number | null {
|
||||
const years = plan.persons
|
||||
.filter((p) => typeof p.planningHorizonAge === "number")
|
||||
.map((p) => (p.planningHorizonAge as number) - p.age);
|
||||
return years.length > 0 ? Math.max(...years) : null;
|
||||
const y = plan.planningHorizonYears;
|
||||
return typeof y === "number" && y > 0 ? y : null;
|
||||
}
|
||||
|
||||
// Alter, das eine Person am Ende der Planung erreicht. Read-only-Anzeige neben dem Horizont.
|
||||
export function endAgeOf(plan: PlanInput, role: PersonRole): number | null {
|
||||
const years = planEndYear(plan);
|
||||
const person = plan.persons.find((p) => p.role === role);
|
||||
return years !== null && person ? person.age + years : null;
|
||||
}
|
||||
|
||||
export interface HorizonChange {
|
||||
@@ -70,23 +76,15 @@ export interface HorizonChange {
|
||||
blocked: string | null;
|
||||
}
|
||||
|
||||
// Was muesste an der letzten Phase geschehen, damit der Plan bis zum Horizont laeuft?
|
||||
export function planHorizonChange(plan: PlanInput, horizonAge: number, role: PersonRole): HorizonChange | null {
|
||||
// Was muesste an der letzten Phase geschehen, damit der Plan genau bis zum Horizont laeuft?
|
||||
// Dieselbe Richtung wie beim Pensionsalter: Zahl stellen, Struktur folgt.
|
||||
export function planHorizonChange(plan: PlanInput, horizonYears: number): HorizonChange | null {
|
||||
const phases = sortedPhases(plan);
|
||||
const last = phases[phases.length - 1];
|
||||
if (!last) return null;
|
||||
const person = plan.persons.find((p) => p.role === role);
|
||||
if (!person) return null;
|
||||
|
||||
// Zielgesamtdauer aus SICHT DIESER Person; die uebrigen Horizonte bleiben unberuehrt und
|
||||
// koennen laenger sein -- deshalb das Maximum ueber alle.
|
||||
const wish = Math.max(
|
||||
horizonAge - person.age,
|
||||
...plan.persons.filter((p) => p.role !== role && typeof p.planningHorizonAge === "number")
|
||||
.map((p) => (p.planningHorizonAge as number) - p.age)
|
||||
);
|
||||
const before = phases.slice(0, -1).reduce((s, p) => s + p.durationYears, 0);
|
||||
const newDuration = wish - before;
|
||||
const newDuration = horizonYears - before;
|
||||
const change: HorizonChange = {
|
||||
lastPhaseId: last.id,
|
||||
oldDuration: last.durationYears,
|
||||
@@ -94,7 +92,8 @@ export function planHorizonChange(plan: PlanInput, horizonAge: number, role: Per
|
||||
blocked: null,
|
||||
};
|
||||
if (newDuration < 1) {
|
||||
change.blocked = `Der Horizont liegt vor dem Ende der zweitletzten Lebensphase. Die letzte Phase muss mindestens ein Jahr dauern – kürze zuerst eine frühere Phase.`;
|
||||
change.blocked =
|
||||
"Der Horizont liegt vor dem Ende der zweitletzten Lebensphase. Die letzte Phase muss mindestens ein Jahr dauern – kürze zuerst eine frühere Phase oder verlängere den Horizont.";
|
||||
}
|
||||
return change;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user