added a new penal charge endpoint #63
@@ -60,6 +60,9 @@ class Config:
|
||||
OVERDUE_LOAN_BATCH_DELAY_SECONDS = int(
|
||||
os.getenv("OVERDUE_LOAN_BATCH_DELAY_SECONDS", 5)
|
||||
)
|
||||
OVERDUE_GRACE_PERIOD_DAYS = int(os.getenv("OVERDUE_GRACE_PERIOD_DAYS", 30))
|
||||
|
||||
|
||||
BANK_CALL_API_TIME_OUT = os.getenv("BANK_CALL_API_TIME_OUT", 100)
|
||||
BANK_CALL_BASE_URL = os.getenv("BANK_CALL_BASE_URL", "https://bank-emulator.dev.simbrellang.net/api")
|
||||
BANK_CALL_SMS_BASE_URL= os.getenv("BANK_CALL_SMS_BASE_URL","https://first-advance-middleware-develop.fbn-devops-dev-asenv.appserviceenvironment.net/SMS")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from app.extensions import db
|
||||
from app.utils.logger import logger
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
@@ -115,6 +115,21 @@ class LoanRepaymentSchedule(db.Model):
|
||||
logger.error(f"Error fetching active overdue repayment schedules: {e}")
|
||||
return []
|
||||
@classmethod
|
||||
def get_overdue_repayment_schedule_with_grace_period(cls, grace_period_days):
|
||||
"""
|
||||
Get all overdue repayment schedules that are not repaid and beyond the grace period.
|
||||
"""
|
||||
try:
|
||||
grace_period_date = datetime.now(timezone.utc) - timedelta(days=grace_period_days)
|
||||
return cls.query.filter(
|
||||
cls.due_date < grace_period_date,
|
||||
cls.paid == False
|
||||
).order_by(cls.due_date.asc()).all()
|
||||
except Exception as e:
|
||||
logger.error(f"Error fetching overdue repayment schedules with grace period: {e}")
|
||||
return []
|
||||
|
||||
@classmethod
|
||||
def get_partially_paid_overdue_repayment_schedule(cls):
|
||||
"""
|
||||
Get all overdue repayment schedules that are partially paid.
|
||||
|
||||
+40
-1
@@ -440,7 +440,46 @@ def report():
|
||||
except Exception as e:
|
||||
logger.error(f"Error generating or sending report: {e}")
|
||||
return ResponseHelper.error("Failed to send report", status_code=500, error=str(e))
|
||||
|
||||
|
||||
@autocall_bp.route("/process-penal-charges", methods=["GET"])
|
||||
def process_penal_charges():
|
||||
try:
|
||||
OVERDUE_GRACE_PERIOD_DAYS = settings.OVERDUE_GRACE_PERIOD_DAYS
|
||||
|
||||
overdue_loans = (
|
||||
LoanRepaymentScheduleService
|
||||
.get_overdue_repayment_schedule_with_grace_period(OVERDUE_GRACE_PERIOD_DAYS)
|
||||
)
|
||||
|
||||
logger.info(f"Found {len(overdue_loans)} overdue loans.")
|
||||
|
||||
if not overdue_loans:
|
||||
return ResponseHelper.success(
|
||||
message="No overdue loans found",
|
||||
status_code=200
|
||||
)
|
||||
|
||||
processed_loans = []
|
||||
|
||||
for loan in overdue_loans:
|
||||
# TODO: apply penal charge logic here
|
||||
# PenalChargeService.apply_penal_charge(loan)
|
||||
|
||||
processed_loans.append(loan.to_dict())
|
||||
|
||||
return ResponseHelper.success(
|
||||
message="Penal Charges Processed Successfully",
|
||||
status_code=200,
|
||||
data=processed_loans
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
logger.exception(f"Error processing penal charges: {e}")
|
||||
return ResponseHelper.error(
|
||||
"Failed to process penal charges",
|
||||
status_code=500,
|
||||
error=str(e)
|
||||
)
|
||||
|
||||
@autocall_bp.route("/overdue-loans", methods=["GET"])
|
||||
def overdue_loans():
|
||||
|
||||
@@ -47,7 +47,9 @@ class LoanRepaymentScheduleService:
|
||||
"""
|
||||
return LoanRepaymentSchedule.update_repayment_schedule_description(schedule_id, description)
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_overdue_repayment_schedule_with_grace_period(cls, grace_period_days):
|
||||
return LoanRepaymentSchedule.get_overdue_repayment_schedule_with_grace_period(grace_period_days)
|
||||
@staticmethod
|
||||
def handle_schedule_updates(updated_loan, data, amount_collected, message, loan_data):
|
||||
"""
|
||||
|
||||
@@ -216,6 +216,12 @@ paths:
|
||||
responses:
|
||||
200:
|
||||
description: A successful response
|
||||
/autocall/process-penal-charges:
|
||||
get:
|
||||
summary: Get all overdue loans with grace period
|
||||
responses:
|
||||
200:
|
||||
description: A successful response
|
||||
/autocall/direct/loan:
|
||||
post:
|
||||
summary: Direct call for loan disbursement
|
||||
|
||||
Reference in New Issue
Block a user