production-evyos-systems-an.../ServicesBank/Finder/Payment/interest_calculate.py

138 lines
5.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import arrow
from decimal import Decimal
from typing import Literal
from datetime import date
from dataclasses import dataclass
@dataclass
class GecikmeFaizSonucu:
faiz_turu: str
gecikme_gunu: int
gunluk_oran: float
faiz: float
bsmv: float
kkdf: float
toplam: float
# Faiz türüne göre aylık faiz oranı (%)
GLOBAL_FAIZ_ORANLARI = {"akdi": 5.0, "gecikme": 5.3}
# Vergi oranları (%)
GLOBAL_BSMV_ORANI = 15.0
GLOBAL_KKDF_ORANI = 15.0
def hesapla_komisyon(vade_tarihi: date, islem_tarihi: date, tutar: float, oran: float) -> float:
gecikme = (islem_tarihi - vade_tarihi).days
if gecikme <= 0:
return 0.0
komisyon = tutar * oran * gecikme
return round(komisyon, 2)
def hesapla_gunluk_oran(
faiz_orani: float, tip: Literal["MIR", "YIR"], gun: int = 0
) -> float:
"""
orijinal_oran: Yıllık ya da aylık faiz oranı (örneğin %12 için 0.12)
tip: 'MIR' (Monthly Interest Rate) ya da 'YIR' (Yearly Interest Rate)
"""
faiz_orani = faiz_orani / 100
if tip.upper() == "MIR":
if gun < 1:
gun = 30
return faiz_orani / gun # varsayılan aylık 30 gün
elif tip.upper() == "YIR":
if gun < 1:
gun = 360
return faiz_orani / gun # varsayılan yıl 365 gün
else:
raise ValueError("Faiz tipi yalnızca 'MIR' ya da 'YIR' olabilir.")
def hesapla_gecikme_faizi(
borc: float, vade_tarihi: date, islem_tarihi: date | None = None, faiz_orani: float = None, faiz_turu: str = "akdi", bsmv_orani: float = None, kkdf_orani: float = None,
) -> GecikmeFaizSonucu:
if islem_tarihi is None:
islem_tarihi = date.today()
gecikme_gun = (arrow.get(islem_tarihi) - arrow.get(vade_tarihi)).days
if gecikme_gun <= 0:
return GecikmeFaizSonucu(faiz_turu, 0, 0, 0, 0, 0, 0)
# Varsayılan oranları içerden bağla
if faiz_orani is None:
faiz_orani = GLOBAL_FAIZ_ORANLARI.get(faiz_turu, 5.0)
if bsmv_orani is None:
bsmv_orani = GLOBAL_BSMV_ORANI
if kkdf_orani is None:
kkdf_orani = GLOBAL_KKDF_ORANI
faiz_tipi = "MIR" if faiz_turu == "akdi" else "YIR"
gunluk_oran = hesapla_gunluk_oran(faiz_orani, faiz_tipi)
faiz_tutari = Decimal(borc) * Decimal(gunluk_oran) * Decimal(gecikme_gun)
bsmv = Decimal(faiz_tutari) * Decimal(bsmv_orani / 100)
kkdf = Decimal(faiz_tutari) * Decimal(kkdf_orani / 100)
toplam_faiz = Decimal(faiz_tutari) + Decimal(bsmv) + Decimal(kkdf)
return GecikmeFaizSonucu(
faiz_turu=faiz_turu, gecikme_gunu=gecikme_gun, gunluk_oran=round(gunluk_oran, 6), faiz=round(faiz_tutari, 2), bsmv=round(bsmv, 2), kkdf=round(kkdf, 2), toplam=round(toplam_faiz, 4),
)
"""
2025 Güncel Oranlar (TCMB verilerine göre)
tip: 'MIR' (Monthly Interest Rate) ya da 'YIR' (Yearly Interest Rate)
Faiz Türü Aylık Oran Günlük Yaklaşık Açıklama
Akdi Faiz %5,00 %0,1667 Asgari üzerindeki borca uygulanır
Gecikme Faizi %5,30 %0,1767 Asgari tutarın ödenmeyen kısmına uygulanır
CREATE TABLE public.account_delay_interest (
account_records_id int4 NOT NULL,
build_decision_book_payment_id int4 NOT NULL,
build_decision_book_payment_refid varchar(100) NOT NULL,
interest_turn varchar(10) NOT NULL,
interest_rate numeric(10, 2) NOT NULL,
delay_day int2 NOT NULL,
daily_rate numeric(20, 6) NOT NULL,
interest numeric(20, 6) NOT NULL,
bsmv numeric(20, 6) NOT NULL,
kkdf numeric(20, 6) NOT NULL,
total numeric(20, 6) NOT NULL,
new_build_decision_book_payment_id int4 NULL,
approved_record bool false NOT NULL,
approving_person int4 NOT NULL,
approving_at timestamptz NULL,
id serial4 NOT NULL,
uu_id uuid DEFAULT gen_random_uuid() NOT NULL,
expiry_starts timestamptz DEFAULT now() NOT NULL,
expiry_ends timestamptz DEFAULT now() NOT NULL,
created_at timestamptz DEFAULT now() NOT NULL,
updated_at timestamptz DEFAULT now() NOT NULL,
CONSTRAINT account_delay_interest_pkey PRIMARY KEY (id))
CREATE UNIQUE INDEX _account_delay_interest_ndx_01 ON public.account_delay_interest USING btree (account_records_id, build_decision_book_payment_id);
CREATE INDEX _account_delay_interest_ndx_02 ON public.account_delay_interest USING btree (build_decision_book_payment_id);
CREATE UNIQUE INDEX _account_delay_interest_ndx_03 ON public.account_delay_interest USING btree (build_decision_book_payment_refid);
CREATE UNIQUE INDEX _account_delay_interest_ndx_04 ON public.account_delay_interest USING btree (uu_id);
-- Column comments
COMMENT ON COLUMN public.account_delay_interest.build_decision_book_payment_refid IS 'ref id';
COMMENT ON COLUMN public.account_delay_interest.interest_turn IS 'faiz turu';
COMMENT ON COLUMN public.account_delay_interest.interest_rate IS 'uygulanan faiz';
COMMENT ON COLUMN public.account_delay_interest.delay_day IS 'gecikme_gunu';
COMMENT ON COLUMN public.account_delay_interest.daily_rate IS 'gunluk_oran';
COMMENT ON COLUMN public.account_delay_interest.interest IS 'faiz';
COMMENT ON COLUMN public.account_delay_interest.bsmv IS 'bsmv';
COMMENT ON COLUMN public.account_delay_interest.kkdf IS 'kkdf';
COMMENT ON COLUMN public.account_delay_interest.total IS 'toplam';
COMMENT ON COLUMN public.account_delay_interest.approved_record IS 'onaylandı';
COMMENT ON COLUMN public.account_delay_interest.approving_person IS 'onaylayan';
COMMENT ON COLUMN public.account_delay_interest.approving_at IS 'onay zamani';
"""