added direct calls for loans and repayment #46
+1
-1
@@ -100,7 +100,7 @@ class Loan(db.Model):
|
||||
@classmethod
|
||||
def get_loan_by_loan_id(cls, loan_id):
|
||||
return cls.query.filter_by(id=loan_id).first()
|
||||
|
||||
|
||||
@classmethod
|
||||
def set_disbursement_date(cls, loan_id, customer_id):
|
||||
"""
|
||||
|
||||
+137
-1
@@ -64,6 +64,136 @@ def disbursement():
|
||||
return response
|
||||
|
||||
|
||||
|
||||
@autocall_bp.route("/direct/loan", methods=["POST"])
|
||||
def direct_loan():
|
||||
data = request.get_json()
|
||||
logger.info(f"Data received: {data}")
|
||||
|
||||
REQUIRED_KEYS = [
|
||||
"transactionId"
|
||||
]
|
||||
|
||||
# Check for missing keys
|
||||
missing_keys = [key for key in REQUIRED_KEYS if key not in data or data[key] is None]
|
||||
if missing_keys:
|
||||
logger.warning(f"Missing required keys: {missing_keys}")
|
||||
return jsonify({
|
||||
"status": "error",
|
||||
"message": f"Missing required fields: {', '.join(missing_keys)}"
|
||||
}), 400
|
||||
|
||||
# Check if the loan exists
|
||||
loan = LoanService.get_loan_by_transaction_id(transaction_id=data['transactionId'])
|
||||
if not loan:
|
||||
return jsonify({
|
||||
"status": "error",
|
||||
"message": f"Loan with transaction id {data['transactionId']} does not exist"
|
||||
}), 400
|
||||
|
||||
loan_data = loan.to_dict()
|
||||
|
||||
# Prevent double disbursement
|
||||
if loan_data.get('disburseDate') is not None:
|
||||
return jsonify({
|
||||
"status": "error",
|
||||
"message": f"Loan with transaction id {data['transactionId']} has already been processed"
|
||||
}), 400
|
||||
|
||||
data_to_process = {
|
||||
"transactionId": loan_data.get('transactionId'),
|
||||
"FbnTransactionId": loan_data.get('transactionId'),
|
||||
"debtId": str(loan_data.get('debtId')),
|
||||
"customerId": loan_data.get('customerId'),
|
||||
"accountId": loan_data.get('accountId'),
|
||||
"productId": str(loan_data.get('productId', "")),
|
||||
"provideAmount": loan_data.get('currentLoanAmount'),
|
||||
}
|
||||
response = SimbrellaClient.disburse_loan(data_to_process)
|
||||
return response
|
||||
|
||||
@autocall_bp.route("/direct/repayment", methods=["POST"])
|
||||
def direct_repayment():
|
||||
data = request.get_json()
|
||||
logger.info(f"Data received: {data}")
|
||||
|
||||
REQUIRED_KEYS = ["transactionId"]
|
||||
|
||||
# Check for missing keys
|
||||
missing_keys = [key for key in REQUIRED_KEYS if key not in data or data[key] is None]
|
||||
if missing_keys:
|
||||
logger.warning(f"Missing required keys: {missing_keys}")
|
||||
return jsonify({
|
||||
"status": "error",
|
||||
"message": f"Missing required fields: {', '.join(missing_keys)}"
|
||||
}), 400
|
||||
|
||||
# Check if the loan exists
|
||||
loan = LoanService.get_loan_by_transaction_id(transaction_id=data['transactionId'])
|
||||
if not loan:
|
||||
return jsonify({
|
||||
"status": "error",
|
||||
"message": f"Loan with transaction id {data['transactionId']} does not exist"
|
||||
}), 400
|
||||
|
||||
loan_data = loan.to_dict()
|
||||
|
||||
# check if loan has been repaid
|
||||
if loan_data.get("status") == LoanStatus.REPAID and loan_data.get("balance") <= 0:
|
||||
return jsonify({
|
||||
"status": "error",
|
||||
"message": f"loan with Id {loan_data.get('debtId')} has been repaid"
|
||||
}), 400
|
||||
|
||||
|
||||
repayment_data = {
|
||||
"customerId": loan_data.get("customerId"),
|
||||
"loanId": loan_data.get("debtId"),
|
||||
"productId": loan_data.get("productId"),
|
||||
"transactionId": loan_data.get("transactionId"),
|
||||
"initiatedBy": "USER INITIATED",
|
||||
"salaryAmount": 0,
|
||||
"LoanStatus": loan_data.get("status"),
|
||||
}
|
||||
|
||||
logger.info(f"Creating repayment with data: {repayment_data}")
|
||||
|
||||
try:
|
||||
repayment = RepaymentService.create_repayment(repayment_data)
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
logger.error(f"Repayment creation raised exception: {e}")
|
||||
return jsonify({
|
||||
"status": "error",
|
||||
"message": "Failed to create repayment"
|
||||
}), 500
|
||||
|
||||
if not repayment or (isinstance(repayment, dict) and "error" in repayment):
|
||||
db.session.rollback()
|
||||
logger.error(f"Repayment creation failed for loan ID {loan_data.get('debtId')}: {repayment}")
|
||||
|
||||
try:
|
||||
if loan_data.get('status') == LoanStatus.ACTIVE:
|
||||
LoanService.update_status(loan_id=loan_data.get('debtId'), status=LoanStatus.START_REPAY)
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
logger.error(f"Failed to update loan status for loan ID {loan_data.get('debtId')}: {e}")
|
||||
repayment_data_dict = repayment.to_dict()
|
||||
|
||||
data_to_process = {
|
||||
"transactionId": repayment_data_dict['transactionId'],
|
||||
"debtId": repayment_data_dict['loanId'],
|
||||
"customerId": repayment_data_dict['customerId'],
|
||||
"productId": repayment_data_dict['productId'],
|
||||
"Id":repayment_data_dict['Id']
|
||||
}
|
||||
|
||||
response = SimbrellaClient.collect_loan_user_initiated(data_to_process)
|
||||
return response
|
||||
|
||||
|
||||
|
||||
|
||||
@autocall_bp.route("/refresh-verify-collection", methods=["GET"])
|
||||
def refresh_verify_collection():
|
||||
data = request.get_json()
|
||||
@@ -190,6 +320,11 @@ def process_salary_list():
|
||||
# Step 4: Create repayments for each loan
|
||||
for loan in loans:
|
||||
logger.info(f"Processing Loan ID: {loan.id}")
|
||||
#check if the loan has been repaid
|
||||
if loan.status in [LoanStatus.REPAID] and loan.balance <= 0:
|
||||
logger.info(f"Skipping loan ID {loan.id} because it is already repaid/closed")
|
||||
continue
|
||||
|
||||
try:
|
||||
repayment_data = {
|
||||
"customerId": loan.customer_id,
|
||||
@@ -210,7 +345,8 @@ def process_salary_list():
|
||||
continue
|
||||
|
||||
try:
|
||||
LoanService.update_status(loan_id=loan.id, status=LoanStatus.START_REPAY)
|
||||
if loan.status == LoanStatus.ACTIVE:
|
||||
LoanService.update_status(loan_id=loan.id, status=LoanStatus.START_REPAY)
|
||||
except Exception as e:
|
||||
db.session.rollback()
|
||||
logger.error(f"Failed to update loan status for loan ID {loan.id}: {e}")
|
||||
|
||||
+36
-1
@@ -213,4 +213,39 @@ paths:
|
||||
summary: Get all overdue loans
|
||||
responses:
|
||||
200:
|
||||
description: A successful response
|
||||
description: A successful response
|
||||
/autocall/direct/loan:
|
||||
post:
|
||||
summary: Direct call for loan disbursement
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
transactionId:
|
||||
type: string
|
||||
example: "TXN123456"
|
||||
responses:
|
||||
200:
|
||||
description: A successful response
|
||||
/autocall/direct/repayment:
|
||||
post:
|
||||
summary: Direct call for loan repayment
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
transactionId:
|
||||
type: string
|
||||
example: "TXN123456"
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: A successful response
|
||||
|
||||
|
||||
Reference in New Issue
Block a user