Merge branch 'penal_check' of DigiFi/digifi-EventManager into master

This commit is contained in:
2026-03-17 11:21:21 +00:00
committed by Gogs
+21 -9
View File
@@ -2,6 +2,7 @@ from datetime import datetime, timedelta, timezone
from app.extensions import db from app.extensions import db
from app.utils.logger import logger from app.utils.logger import logger
from sqlalchemy.exc import SQLAlchemyError from sqlalchemy.exc import SQLAlchemyError
from sqlalchemy import or_
from app.enums.repayment_schedule_status import RepaymentScheduleStatus from app.enums.repayment_schedule_status import RepaymentScheduleStatus
from app.config import settings from app.config import settings
@@ -122,21 +123,28 @@ class LoanRepaymentSchedule(db.Model):
except Exception as e: except Exception as e:
logger.error(f"Error fetching active overdue repayment schedules: {e}") logger.error(f"Error fetching active overdue repayment schedules: {e}")
return [] return []
@classmethod @classmethod
def get_overdue_repayment_schedule_with_grace_period(cls, grace_period_days, limit=None): def get_overdue_repayment_schedule_with_grace_period(cls, grace_period_days, limit=None):
"""
Get all overdue repayment schedules that are not repaid and beyond the grace period.
"""
try: try:
grace_period_date = datetime.now(timezone.utc) - timedelta(days=grace_period_days) now = datetime.now(timezone.utc)
grace_period_date = now - timedelta(days=grace_period_days)
penal_interval = timedelta(days=settings.PENAL_CHARGE_INTERVAL_DAYS)
return cls.query.filter( return cls.query.filter(
cls.due_date < grace_period_date, cls.due_date < grace_period_date,
cls.paid == False cls.paid == False,
or_(
cls.last_penal_date == None, # never penalized before
cls.last_penal_date < now - penal_interval
)
).order_by(cls.due_date.asc()).limit(limit).all() ).order_by(cls.due_date.asc()).limit(limit).all()
except Exception as e: except Exception as e:
logger.error(f"Error fetching overdue repayment schedules with grace period: {e}") logger.error(f"Error fetching overdue repayment schedules with grace period: {e}")
return [] return []
@classmethod @classmethod
def get_partially_paid_overdue_repayment_schedule(cls): def get_partially_paid_overdue_repayment_schedule(cls):
""" """
@@ -300,22 +308,26 @@ class LoanRepaymentSchedule(db.Model):
db.session.rollback() db.session.rollback()
logger.error(f"Error applying repayment for schedule {schedule_id}: {e}") logger.error(f"Error applying repayment for schedule {schedule_id}: {e}")
raise raise
from decimal import Decimal
@classmethod @classmethod
def apply_penal_to_schedule(cls, schedule_id, penal_amount): def apply_penal_to_schedule(cls, schedule_id, penal_amount):
schedule = cls.query.get(schedule_id) schedule = cls.query.get(schedule_id)
now = datetime.now(timezone.utc) now = datetime.now(timezone.utc)
penal_amount = Decimal(str(penal_amount))
current_penal = Decimal(str(schedule.penal_charge)) if schedule.penal_charge else Decimal("0")
schedule.penal_count = (schedule.penal_count or 0) + 1 schedule.penal_count = (schedule.penal_count or 0) + 1
schedule.penal_charge = (schedule.penal_charge or 0) + penal_amount schedule.penal_charge = current_penal + penal_amount
schedule.last_penal_date = now schedule.last_penal_date = now
schedule.due_process_date = now schedule.due_process_date = now
schedule.updated_at = now schedule.updated_at = now
db.session.commit() db.session.commit()
# Calculate penal charge
@classmethod @classmethod
def calculate_penal_charge(cls, schedule): def calculate_penal_charge(cls, schedule):