This commit is contained in:
Mateusz Gruszczyński
2026-06-03 13:02:07 +02:00
parent fdc946989f
commit 7cb2eddafe
8 changed files with 532 additions and 84 deletions
+30
View File
@@ -1,5 +1,6 @@
from __future__ import annotations
from datetime import date
from enum import Enum
from typing import Literal
from pydantic import BaseModel, Field
@@ -15,6 +16,12 @@ class OverpaymentEffect(str, Enum):
lower_payment = "lower_payment"
class GraceType(str, Enum):
none = "none"
interest_only = "interest_only"
full = "full"
class RateChange(BaseModel):
month: int = Field(ge=1, description="Miesiac od startu kredytu")
annual_rate: float = Field(ge=0, le=30, description="Roczne oprocentowanie procentowo")
@@ -25,6 +32,16 @@ class Overpayment(BaseModel):
amount: float = Field(gt=0)
repeat: Literal["once", "monthly", "yearly"] = "once"
until_month: int | None = Field(default=None, ge=1)
commission_percent: float = Field(default=0, ge=0, le=20, description="Prowizja od nadplaty w procentach")
class HistoricalMonth(BaseModel):
month: int = Field(ge=1)
annual_rate: float | None = Field(default=None, ge=0, le=30)
grace_type: GraceType = GraceType.none
overpayment: float = Field(default=0, ge=0)
overpayment_commission_percent: float = Field(default=0, ge=0, le=20)
note: str = ""
class SimulationRequest(BaseModel):
@@ -34,18 +51,29 @@ class SimulationRequest(BaseModel):
base_rate: float = Field(ge=0, le=30, default=5.75)
installment_type: InstallmentType = InstallmentType.equal
overpayment_effect: OverpaymentEffect = OverpaymentEffect.shorten
loan_start_date: date = Field(default_factory=date.today)
due_day: int = Field(default=5, ge=1, le=28, description="Dzien splaty raty")
move_due_date_to_business_day: bool = True
rate_changes: list[RateChange] = Field(default_factory=list)
overpayments: list[Overpayment] = Field(default_factory=list)
historical_months: list[HistoricalMonth] = Field(default_factory=list)
class ScheduleRow(BaseModel):
month: int
due_date: str
days: int
rate: float
payment: float
principal_part: float
interest_part: float
overpayment: float
overpayment_fee: float
remaining: float
grace_type: GraceType = GraceType.none
cumulative_interest: float
cumulative_cost: float
cumulative_overpayment: float
class Summary(BaseModel):
@@ -53,12 +81,14 @@ class Summary(BaseModel):
total_paid: float
total_interest: float
total_overpayment: float
total_overpayment_fees: float
interest_saved: float
months_saved: int
baseline_interest: float
baseline_months: int
average_payment: float
max_payment: float
payoff_date: str | None = None
class SimulationResponse(BaseModel):