From 1b973322c9e5c12fb3de070cc3401c1dff269ca8 Mon Sep 17 00:00:00 2001 From: VivianDee <115420678+VivianDee@users.noreply.github.com> Date: Thu, 10 Apr 2025 12:20:57 +0100 Subject: [PATCH] [add]: Loan details and repayment fix --- .vscode/settings.json | 48 ++++++++++++++++---------------- app/api/services/provide_loan.py | 17 ++++++++++- app/api/services/repayment.py | 6 ++-- app/api/services/select_offer.py | 2 +- app/models/customer.py | 6 ++-- app/models/loan.py | 34 ++++++++++++++++++++-- 6 files changed, 80 insertions(+), 33 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index b79483b..bc7c726 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,24 +1,24 @@ -{ - "editor.lineNumbers": "off", - "editor.padding.top": 3, - "editor.padding.bottom": 3, - "editor.formatOnSave": true, - "editor.formatOnPaste": true, - "editor.fontSize": 14, - "editor.lineHeight": 4.5, - "editor.suggestFontSize": 15, - // "editor.suggestLineHeight": 4, - "breadcrumbs.enabled": false, - "workbench.tips.enabled": false, - "workbench.statusBar.visible": false, - // "workbench.editor.showTabs": "single", - "git.enableSmartCommit": true, - "workbench.editor.editorActionsLocation": "hidden", - // "workbench.activityBar.location": "hidden", - "workbench.editor.enablePreviewFromQuickOpen": false, - "editor.lightbulb.enabled": "off", - "editor.selectionHighlight": false, - "editor.overviewRulerBorder": false, - "editor.renderLineHighlight": "none", - "editor.occurrencesHighlight": "off" -} +// { +// "editor.lineNumbers": "off", +// "editor.padding.top": 3, +// "editor.padding.bottom": 3, +// "editor.formatOnSave": true, +// "editor.formatOnPaste": true, +// "editor.fontSize": 14, +// "editor.lineHeight": 4.5, +// "editor.suggestFontSize": 15, +// // "editor.suggestLineHeight": 4, +// "breadcrumbs.enabled": false, +// "workbench.tips.enabled": false, +// "workbench.statusBar.visible": false, +// // "workbench.editor.showTabs": "single", +// "git.enableSmartCommit": true, +// "workbench.editor.editorActionsLocation": "hidden", +// // "workbench.activityBar.location": "hidden", +// "workbench.editor.enablePreviewFromQuickOpen": false, +// "editor.lightbulb.enabled": "off", +// "editor.selectionHighlight": false, +// "editor.overviewRulerBorder": false, +// "editor.renderLineHighlight": "none", +// "editor.occurrencesHighlight": "off" +// } diff --git a/app/api/services/provide_loan.py b/app/api/services/provide_loan.py index dfc5a96..9833661 100644 --- a/app/api/services/provide_loan.py +++ b/app/api/services/provide_loan.py @@ -7,6 +7,7 @@ from app.utils.logger import logger from app.api.schemas.provide_loan import ProvideLoanSchema from app.api.integrations import KafkaIntegration from threading import Thread +from app.models.loan import Loan class ProvideLoanService(BaseService): @@ -32,8 +33,23 @@ class ProvideLoanService(BaseService): transaction_id = validated_data.get('transactionId') if (ProvideLoanService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): + + # Save the loan details here + loan_id = f"loan_{transaction.id}" + + loan = Loan.create_loan( + id=loan_id, + customer_id=customer_id, + account_id=account_id, + product_id=validated_data.get('productId'), + principal_amount=validated_data.get('requestedAmount'), + status="active" + ) + transaction = ProvideLoanService.log_transaction(validated_data = validated_data) + + if not transaction: logger.error(f"Failed to log transaction") return jsonify({ @@ -89,4 +105,3 @@ class ProvideLoanService(BaseService): KafkaIntegration.send_loan_request(loan_data = loan_data, request_id = request_id) KafkaIntegration.flush() - diff --git a/app/api/services/repayment.py b/app/api/services/repayment.py index 7a53452..737e22f 100644 --- a/app/api/services/repayment.py +++ b/app/api/services/repayment.py @@ -21,10 +21,12 @@ class RepaymentService(BaseService): """ try: validated_data = RepaymentService.validate_data(data, RepaymentSchema()) - account_id = validated_data.get('accountId') customer_id = validated_data.get('customerId') + customer = RepaymentService.get_or_create_customer(validated_data) + account = customer.accounts[0] - if (RepaymentService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): + + if (RepaymentService.validate_account_ownership(account_id = account.id, customer_id = customer_id)): transaction = RepaymentService.log_transaction(validated_data = validated_data) if not transaction: diff --git a/app/api/services/select_offer.py b/app/api/services/select_offer.py index 151b635..1f07cd5 100644 --- a/app/api/services/select_offer.py +++ b/app/api/services/select_offer.py @@ -3,7 +3,7 @@ from marshmallow import ValidationError from app.api.services.base_service import BaseService from app.api.enums import TransactionType from app.utils.logger import logger -from app.api.schemas.select_offer import SelectOfferSchema +from app.api.schemas.select_offer import SelectOfferSchema class SelectOfferService(BaseService): TRANSACTION_TYPE = TransactionType.SELECT_OFFER diff --git a/app/models/customer.py b/app/models/customer.py index 2cb9c5d..e6418c1 100644 --- a/app/models/customer.py +++ b/app/models/customer.py @@ -20,11 +20,11 @@ class Customer(db.Model): ) @classmethod - def is_eligible(cls, customer_id): + def is_valid_customer(cls, customer_id): customer = cls.query.filter_by(id=customer_id).first() if not customer: - return False, "Customer not found" - return True, "Customer is eligible" + return False + return True @classmethod def create_customer(cls, id, msisdn, country_code, account_id, account_type='savings'): diff --git a/app/models/loan.py b/app/models/loan.py index 6fa73a1..edec13f 100644 --- a/app/models/loan.py +++ b/app/models/loan.py @@ -1,5 +1,7 @@ from datetime import datetime, timezone from app.extensions import db +from app.models.customer import Customer +from app.models.account import Account class Loan(db.Model): @@ -15,6 +17,34 @@ class Loan(db.Model): updated_at = db.Column(db.DateTime, default=datetime.now(timezone.utc), onupdate=datetime.now(timezone.utc)) + @classmethod + def create_loan(cls, id, customer_id, account_id, product_id, principal_amount, status='pending'): + + # Check if customer exists + is_valid = Customer.is_valid_customer(customer_id) + if not is_valid: + raise ValueError("Customer does not exist") + + # # Check for active loans + # has_active_loans = cls.has_active_loans(customer_id) + # if has_active_loans: + # raise ValueError("Customer has active loans") + + # Create and save the loan + loan = cls( + id=id, + customer_id=customer_id, + account_id=account_id, + product_id=product_id, + principal_amount=principal_amount, + status=status + ) + + db.session.add(loan) + db.session.commit() + return loan + + @classmethod def has_active_loans(cls, customer_id): active_loans = cls.query.filter_by( @@ -23,8 +53,8 @@ class Loan(db.Model): ).count() if active_loans > 0: - return False, "Customer has active loans" - return True, "No active loans" + return False + return True def __repr__(self):