This commit is contained in:
VivianDee
2025-10-27 19:24:41 +01:00
6 changed files with 92 additions and 25 deletions
+55 -22
View File
@@ -3,15 +3,15 @@ from marshmallow import ValidationError
from app.api.enums.loan_status import LoanStatus from app.api.enums.loan_status import LoanStatus
from app.models import Customer from app.models import Customer
from app.utils.logger import logger from app.utils.logger import logger
from app.api.schemas.loan_status import LoanStatusSchema from app.api.schemas.loan_status import LoanStatusSchema
from app.api.services.base_service import BaseService from app.api.services.base_service import BaseService
from app.api.enums import TransactionType from app.api.enums import TransactionType
from app.extensions import db from app.extensions import db
from app.api.helpers.response_helper import ResponseHelper from app.api.helpers.response_helper import ResponseHelper
class LoanStatusService(BaseService): class LoanStatusService(BaseService):
TRANSACTION_TYPE = TransactionType.LOAN_STATUS TRANSACTION_TYPE = TransactionType.LOAN_STATUS
@staticmethod @staticmethod
def process_request(data): def process_request(data):
@@ -27,31 +27,57 @@ class LoanStatusService(BaseService):
try: try:
with db.session.begin(): with db.session.begin():
# Validate data # Validate data
validated_data = LoanStatusService.validate_data(data, LoanStatusSchema()) validated_data = LoanStatusService.validate_data(
data, LoanStatusSchema()
)
customer_id = validated_data.get('customerId') customer_id = validated_data.get("customerId")
logger.info(f"Looking for customer *** {customer_id}") logger.info(f"Looking for customer *** {customer_id}")
customer = Customer.get_customer_with_loan_list(customer_id) customer = Customer.get_customer_with_loan_list(customer_id)
transactionId = validated_data.get('transactionId')
account_id = validated_data.get('accountId')
if(LoanStatusService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): transactionId = validated_data.get("transactionId")
account_id = validated_data.get("accountId")
if LoanStatusService.validate_account_ownership(
account_id=account_id, customer_id=customer_id
):
# Get loans # Get loans
loans = [loan.to_dict() for loan in customer.loans if loan.status == LoanStatus.ACTIVE] customer_loans = customer.loans
transaction = LoanStatusService.log_transaction(validated_data = validated_data) loans = [
loan.to_dict()
for loan in customer_loans
if loan.status in [LoanStatus.ACTIVE, LoanStatus.START_REPAY, LoanStatus.ACTIVE_PARTIAL]
]
transaction = LoanStatusService.log_transaction(
validated_data=validated_data
)
if not transaction: if not transaction:
logger.error(f"Failed to log transaction") logger.error(f"Failed to log transaction")
return ResponseHelper.error(result_description="Failed to log transaction.") return ResponseHelper.error(
else: result_description="Failed to log transaction."
return ResponseHelper.error(result_description="Invalid Customer or Account") )
else:
total_debt_amount = sum( return ResponseHelper.error(
loan.get("currentLoanAmount") or 0 result_description="Invalid Customer or Account"
for loan in loans
) )
# CONFIRM IF THE TOTAL DEBT IF FOR ONLY ACTIVE LOANS OR ALL LOANS
total_debt_amount = sum(
loan.get("currentLoanAmount") or 0 for loan in loans
)
total_outstanding_amount = sum(
loan.get("currentLoanAmount") or 0 for loan in loans
)
total_active_loan_amount = sum(
loan.get("repaymentAmount") or 0 for loan in loans
)
total_settled_amount = total_active_loan_amount - total_outstanding_amount
# Simulated processing logic # Simulated processing logic
response_data = { response_data = {
"customerId": customer_id, "customerId": customer_id,
@@ -59,6 +85,11 @@ class LoanStatusService(BaseService):
"transactionId": transactionId, "transactionId": transactionId,
"loans": loans, "loans": loans,
"totalDebtAmount": total_debt_amount, "totalDebtAmount": total_debt_amount,
"summary": {
"totalSettledAmount": total_settled_amount,
"totalOutstandingAmount": total_outstanding_amount,
"totalActiveLoanAmount": total_active_loan_amount,
}
} }
db.session.commit() db.session.commit()
@@ -68,9 +99,11 @@ class LoanStatusService(BaseService):
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
db.session.rollback() db.session.rollback()
return ResponseHelper.unprocessable_entity(result_description="Validation exception") return ResponseHelper.unprocessable_entity(
result_description="Validation exception"
except ValueError as err: )
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}") logger.error(f"{getattr(err, 'messages', str(err))}")
db.session.rollback() db.session.rollback()
return ResponseHelper.error(result_description=str(err)) return ResponseHelper.error(result_description=str(err))
@@ -78,4 +111,4 @@ class LoanStatusService(BaseService):
except Exception as e: except Exception as e:
logger.error(f"An error occurred: {str(e)}", exc_info=True) logger.error(f"An error occurred: {str(e)}", exc_info=True)
db.session.rollback() db.session.rollback()
return ResponseHelper.internal_server_error() return ResponseHelper.internal_server_error()
+1
View File
@@ -38,6 +38,7 @@ class SelectOfferService(BaseService):
transaction_id = validated_data.get("transactionId") transaction_id = validated_data.get("transactionId")
request_id = validated_data.get("requestId") request_id = validated_data.get("requestId")
offer_id = int(transaction_offer_id[5:]) # The last part is int offer_id = int(transaction_offer_id[5:]) # The last part is int
#"offerId": "SAL30001129", #"offerId": "SAL30001129",
+1 -1
View File
@@ -246,7 +246,7 @@ class Loan(db.Model):
'loanRef': self.reference, 'loanRef': self.reference,
'productId': self.product_id, 'productId': self.product_id,
'initialLoanAmount': self.initial_loan_amount, 'initialLoanAmount': self.initial_loan_amount,
'currentLoanAmount': self.current_loan_amount, 'currentLoanAmount': self.balance,
'defaultPenaltyFee': self.default_penalty_fee, 'defaultPenaltyFee': self.default_penalty_fee,
'continuousFee': self.continuous_fee, 'continuousFee': self.continuous_fee,
'collectionType': self.collection_type, 'collectionType': self.collection_type,
+6
View File
@@ -56,6 +56,12 @@ class Repayment(db.Model):
raise ValueError(f"Database integrity error: {err}") raise ValueError(f"Database integrity error: {err}")
return repayment return repayment
# Get loan repayments
@classmethod
def get_repayments_by_id(cls, loan_id):
return cls.query.filter_by(loan_id=loan_id).all()
def to_dict(self): def to_dict(self):
return { return {
+6 -2
View File
@@ -103,7 +103,9 @@
"example": { "example": {
"status": "ok", "status": "ok",
"db_status": "Connection Successful", "db_status": "Connection Successful",
"events_service_status": "healthy", "events_service_status":"Connection Successful",
"emulator_status":"Connection Successful",
"db_uri": "postgresql://user:****@localhost:5432/digifi_db",
"error": [] "error": []
} }
} }
@@ -116,7 +118,9 @@
"example": { "example": {
"status": "failed", "status": "failed",
"db_status": "Connection Failed", "db_status": "Connection Failed",
"events_service_status": "unhealthy", "events_service_status":"Connection Failed",
"emulator_status":"Connection Failed",
"db_uri": "Unavailable",
"error":["could not connect to server: Connection refused"] "error":["could not connect to server: Connection refused"]
} }
} }
@@ -102,6 +102,29 @@
"type": "number", "type": "number",
"format": "float", "format": "float",
"example": 30000.0 "example": 30000.0
},
"summary": {
"type": "object",
"properties": {
"totalOutstandingAmount": {
"type": "number",
"format": "float",
"example": 114450.0,
"description": "Total amount still owed across all unpaid loans."
},
"totalActiveLoanAmount": {
"type": "number",
"format": "float",
"example": 40000.0,
"description": "Total principal amount of currently active loans."
},
"totalSettledAmount": {
"type": "number",
"format": "float",
"example": 80000.0,
"description": "Total amount that has been fully repaid."
}
}
} }
}, },
"xml": { "xml": {