Fix: Uebergangs-Defaults (Steuer/Umwandlung) wurden in der Berechnung als 0 gerechnet
Deploy App / deploy (push) Successful in 54s

Kapitalbezugssteuer, Grundstueckgewinnsteuer und PK-Umwandlungssatz wurden im UI nur
optisch vorbelegt (num(td.x, 8/20/6)), die Berechnung las aber num(td.x) mit Fallback 0.
Ein nicht angetupftes Feld fuehrte so zu 0% Steuer bzw. 0 Rente. Defaults sind jetzt
zentrale Konstanten (constants.ts) und werden in Berechnung UND UI als Fallback genutzt.
Betrifft: PK-Kapital/-Kombi/-Rente, 3a-Bezug, Immobilienverkauf.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 15:18:03 +02:00
parent b45af8f264
commit 9506f43b67
3 changed files with 27 additions and 13 deletions
+9 -6
View File
@@ -2,6 +2,9 @@ import {
AHV_COUPLE_CAP_FACTOR,
AHV_FULL_CONTRIBUTION_YEARS,
AHV_MAX_ANNUAL_SINGLE,
DEFAULT_CAPITAL_TAX_RATE,
DEFAULT_PK_CONVERSION_RATE,
DEFAULT_PROPERTY_GAINS_TAX_RATE,
} from "@/lib/constants";
import { num } from "@/lib/elements";
import type { ElementCategory } from "@/lib/elements";
@@ -459,18 +462,18 @@ export function computePlan(plan: PlanInput): PlanComputed {
const value = ec.endValue;
const mode = td.payoutMode ?? "PENSION";
if (mode === "CAPITAL") {
const net = Math.round(value * (1 - num(td.capitalTaxRate) / 100));
const net = Math.round(value * (1 - num(td.capitalTaxRate, DEFAULT_CAPITAL_TAX_RATE) / 100));
outgoing += net;
carry.value = 0;
carry.pkPensionAnnual = 0;
} else if (mode === "PENSION") {
carry.pkPensionAnnual = Math.round((value * num(td.conversionRate)) / 100);
carry.pkPensionAnnual = Math.round((value * num(td.conversionRate, DEFAULT_PK_CONVERSION_RATE)) / 100);
carry.value = 0;
} else {
const capital = Math.min(value, Math.round(num(td.capitalAmount)));
const net = Math.round(capital * (1 - num(td.capitalTaxRate) / 100));
const net = Math.round(capital * (1 - num(td.capitalTaxRate, DEFAULT_CAPITAL_TAX_RATE) / 100));
outgoing += net;
carry.pkPensionAnnual = Math.round(((value - capital) * num(td.conversionRate)) / 100);
carry.pkPensionAnnual = Math.round(((value - capital) * num(td.conversionRate, DEFAULT_PK_CONVERSION_RATE)) / 100);
carry.value = 0;
}
} else {
@@ -482,7 +485,7 @@ export function computePlan(plan: PlanInput): PlanComputed {
}
case "PILLAR_3A": {
if (ownerRetiresNext) {
const net = Math.round(ec.endValue * (1 - num(td.capitalTaxRate) / 100));
const net = Math.round(ec.endValue * (1 - num(td.capitalTaxRate, DEFAULT_CAPITAL_TAX_RATE) / 100));
outgoing += net;
carry.value = 0;
} else {
@@ -506,7 +509,7 @@ export function computePlan(plan: PlanInput): PlanComputed {
const purchase = Math.round(num(e.phaseValues[phase.id]?.purchasePrice));
const salePrice = Math.round(num(td.salePrice));
const gain = Math.max(0, salePrice - purchase);
const tax = gain * (num(td.saleTaxRate) / 100);
const tax = gain * (num(td.saleTaxRate, DEFAULT_PROPERTY_GAINS_TAX_RATE) / 100);
outgoing += Math.round(salePrice - carry.mortgage - tax);
carry.status = "SOLD";
}