From cf3a96ad983ec1ba8af5266a6bb531dad4c83063 Mon Sep 17 00:00:00 2001 From: Chinenye Nmoh Date: Wed, 11 Mar 2026 10:25:03 +0100 Subject: [PATCH] added penal charge log --- app/config.py | 1 + app/models/loan_repayment_schedule.py | 32 ++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/app/config.py b/app/config.py index a466d8c..8541323 100644 --- a/app/config.py +++ b/app/config.py @@ -62,6 +62,7 @@ class Config: ) OVERDUE_GRACE_PERIOD_DAYS = int(os.getenv("OVERDUE_GRACE_PERIOD_DAYS", 30)) OVERDUE_PROCESSING_LIST_LIMIT = int(os.getenv("OVERDUE_PROCESSING_LIST_LIMIT", 100)) + PENAL_CHARGE_PERCENTAGE = os.getenv("PENAL_CHARGE_PERCENTAGE", 1) BANK_CALL_API_TIME_OUT = os.getenv("BANK_CALL_API_TIME_OUT", 100) diff --git a/app/models/loan_repayment_schedule.py b/app/models/loan_repayment_schedule.py index 5592c8a..b9af20b 100644 --- a/app/models/loan_repayment_schedule.py +++ b/app/models/loan_repayment_schedule.py @@ -3,6 +3,7 @@ from app.extensions import db from app.utils.logger import logger from sqlalchemy.exc import SQLAlchemyError from app.enums.repayment_schedule_status import RepaymentScheduleStatus +from app.config import settings from decimal import Decimal, ROUND_HALF_UP # from dateutil.relativedelta import relativedelta @@ -299,14 +300,43 @@ class LoanRepaymentSchedule(db.Model): """ try: schedule = cls.query.get(schedule_id) + if not schedule: + raise ValueError(f"Schedule with ID {schedule_id} does not exist.") if schedule.due_process_count is None: schedule.due_process_count = 0 schedule.due_process_count += 1 schedule.due_process_date = datetime.now(timezone.utc) schedule.updated_at = datetime.now(timezone.utc) + now = datetime.now(timezone.utc) + # Calculate DPD + dpd = max((now.date() - schedule.due_date.date()).days, 0) + # Determine outstanding balance + if schedule.paid_status == RepaymentScheduleStatus.PARTIALLY_PAID and schedule.partial_balance: + outstanding_amount = Decimal(str(schedule.partial_balance)) + else: + outstanding_amount = Decimal(str(schedule.installment_amount)) + + # Calculate penal charge (1% default if settings not set) + try: + penalty_rate = getattr(settings, "PENAL_CHARGE_PERCENTAGE", 1)/100 + except: + penalty_rate = 0.01 + penal_charge = (outstanding_amount * Decimal(str(penalty_rate))).quantize( + Decimal("0.01"), rounding=ROUND_HALF_UP + ) + + #new balance + penal charge + new_balance = outstanding_amount + penal_charge db.session.commit() - logger.info(f"Updated due process date and count for schedule ID {schedule.id}") + logger.info(f"""Updated due process date and count for schedule ID {schedule.id}, + amount due: {schedule.installment_amount}, + outstanding amount: {outstanding_amount}, + due process count: {schedule.due_process_count}, + DPD: {dpd}, + penal charge(1%): {penal_charge}, + new balance(plus penal charge): {new_balance} + """) except Exception as e: db.session.rollback() -- 2.34.1