From e5320c075e0cfe60c265f68a00fd161f5c7467d6 Mon Sep 17 00:00:00 2001 From: VivianDee <115420678+VivianDee@users.noreply.github.com> Date: Thu, 10 Apr 2025 18:35:26 +0100 Subject: [PATCH] [add]: Update loan status after repayment --- app/api/enums/__init__.py | 3 ++- app/api/enums/loan_status.py | 6 ++++++ app/api/services/provide_loan.py | 4 ++-- app/api/services/repayment.py | 8 +++++++- app/models/loan.py | 25 ++++++++++++++++++++++--- app/models/repayment.py | 8 ++++++-- 6 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 app/api/enums/loan_status.py diff --git a/app/api/enums/__init__.py b/app/api/enums/__init__.py index 2e3a1d8..deb3f94 100644 --- a/app/api/enums/__init__.py +++ b/app/api/enums/__init__.py @@ -1 +1,2 @@ -from .transaction_type import TransactionType \ No newline at end of file +from .transaction_type import TransactionType +from .loan_status import LoanStatus \ No newline at end of file diff --git a/app/api/enums/loan_status.py b/app/api/enums/loan_status.py new file mode 100644 index 0000000..dace234 --- /dev/null +++ b/app/api/enums/loan_status.py @@ -0,0 +1,6 @@ +from enum import Enum + +class LoanStatus(str, Enum): + PENDING = "pending" + ACTIVE = "active" + REPAID = "repaid" \ No newline at end of file diff --git a/app/api/services/provide_loan.py b/app/api/services/provide_loan.py index 495c07b..e268a92 100644 --- a/app/api/services/provide_loan.py +++ b/app/api/services/provide_loan.py @@ -7,7 +7,7 @@ from app.utils.logger import logger from app.api.schemas.provide_loan import ProvideLoanSchema from threading import Thread from app.models.loan import Loan - +from app.api.enums import LoanStatus class ProvideLoanService(BaseService): TRANSACTION_TYPE = TransactionType.PROVIDE_LOAN @@ -39,7 +39,7 @@ class ProvideLoanService(BaseService): account_id=account_id, offer_id=validated_data.get('offerId'), principal_amount=validated_data.get('requestedAmount'), - status="active" + status=LoanStatus.ACTIVE ) if not loan: diff --git a/app/api/services/repayment.py b/app/api/services/repayment.py index 3129392..d92f8b8 100644 --- a/app/api/services/repayment.py +++ b/app/api/services/repayment.py @@ -1,6 +1,8 @@ from flask import request, jsonify from marshmallow import ValidationError +from app.api.enums.loan_status import LoanStatus from app.models import Repayment +from app.models.loan import Loan from app.utils.logger import logger from app.api.schemas.repayment import RepaymentSchema from app.api.services.base_service import BaseService @@ -28,6 +30,7 @@ class RepaymentService(BaseService): account = customer.accounts[0] validated_data['accountId'] = account.id request_id = validated_data.get('requestId') + loan_id = validated_data.get('debtId') if (RepaymentService.validate_account_ownership(account_id = account.id, customer_id = customer_id)): @@ -35,7 +38,7 @@ class RepaymentService(BaseService): # Save the repayment details repayment = Repayment.create_repayment( customer_id = customer_id, - loan_id = validated_data.get('debtId'), + loan_id = loan_id, product_id = validated_data.get('productId') ) @@ -46,6 +49,9 @@ class RepaymentService(BaseService): "message": "Failed to save repayment details." }), 400 + #Update Loan status + Loan.update_status(loan_id = loan_id, status = LoanStatus.REPAID) + transaction = RepaymentService.log_transaction(validated_data = validated_data) if not transaction: diff --git a/app/models/loan.py b/app/models/loan.py index 2d68a64..0fec3d2 100644 --- a/app/models/loan.py +++ b/app/models/loan.py @@ -65,16 +65,35 @@ class Loan(db.Model): return False return True + @classmethod def get_customer_loan(cls, loan_id, customer_id): """ - Check if a loan with the given ID exists and if the loan belongs to the specified customer_id. + Get customer's active loans. """ - loan = cls.query.filter_by(id=loan_id, customer_id=customer_id).first() + loan = cls.query.filter_by(id = loan_id, customer_id = customer_id).first() if not loan: - raise ValueError(f"Loan with ID {loan_id} does not exist or does not belong to customer {customer_id}.") + raise ValueError(f"Loan with ID {loan_id} does not exist or does not belong to customer {customer_id}.") return loan + @classmethod + def update_status(cls, loan_id, status): + """ + Update the status of the loan with the given loan_id. + """ + # Retrieve loan + loan = cls.query.get(loan_id) + + if not loan: + raise ValueError(f"Loan with ID {loan_id} does not exist.") + + if loan.status == status: + return + + # Update loan status and the updated_at timestamp + loan.status = status + + db.session.commit() def __repr__(self): return f'' \ No newline at end of file diff --git a/app/models/repayment.py b/app/models/repayment.py index 538eda3..06b872c 100644 --- a/app/models/repayment.py +++ b/app/models/repayment.py @@ -1,4 +1,5 @@ from datetime import datetime, timezone +from app.api.enums.loan_status import LoanStatus from app.extensions import db from app.models.customer import Customer from app.models.loan import Loan @@ -29,8 +30,11 @@ class Repayment(db.Model): # Check loan exists loan = Loan.get_customer_loan(loan_id = loan_id, customer_id = customer_id) - if not loan: - raise ValueError("Loan not found for customer") + + # Check that the loan is active + if loan.status != LoanStatus.ACTIVE: + raise ValueError(f"Repayment cannot be processed. Loan status: ({loan.status})") + repayment = cls( customer_id=customer_id, -- 2.34.1