Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 93d2659462 | |||
| 569d4c45d7 |
@@ -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):
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user