2 Commits

Author SHA1 Message Date
Chinenye Nmoh 93d2659462 added extra query 2026-03-17 09:42:18 +01:00
Chinenye Nmoh 569d4c45d7 added extra query 2026-03-17 09:37:08 +01:00
49 changed files with 4517 additions and 4505 deletions
+20 -8
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,17 +123,24 @@ 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 []
@@ -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):