From d397c834f4fbaf1aa02717ec3cb445889aa4ed23 Mon Sep 17 00:00:00 2001 From: VivianDee <115420678+VivianDee@users.noreply.github.com> Date: Thu, 10 Apr 2025 23:45:40 +0100 Subject: [PATCH] [add]: db sessions --- app/api/services/customer_consent.py | 40 +++++----- app/api/services/eligibility_check.py | 107 ++++++++++++------------- app/api/services/loan_status.py | 76 +++++++++--------- app/api/services/provide_loan.py | 62 ++++++++------- app/api/services/repayment.py | 53 +++++++------ app/api/services/select_offer.py | 108 +++++++++++++------------- app/models/repayment.py | 2 +- 7 files changed, 231 insertions(+), 217 deletions(-) diff --git a/app/api/services/customer_consent.py b/app/api/services/customer_consent.py index da50864..a6b4f07 100644 --- a/app/api/services/customer_consent.py +++ b/app/api/services/customer_consent.py @@ -23,13 +23,13 @@ class CustomerConsentService(BaseService): dict: A standardized response. """ try: + with db.session.begin(): + validated_data = CustomerConsentService.validate_data(data, CustomerConsentSchema()) + account_id = validated_data.get('accountId') + customer_id = validated_data.get('customerId') - validated_data = CustomerConsentService.validate_data(data, CustomerConsentSchema()) - account_id = validated_data.get('accountId') - customer_id = validated_data.get('customerId') - - if(CustomerConsentService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): - with db.session.begin(): + if(CustomerConsentService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): + transaction = CustomerConsentService.log_transaction(validated_data = validated_data) if not transaction: @@ -37,23 +37,25 @@ class CustomerConsentService(BaseService): return jsonify({ "message": "Failed to log transaction." }), 400 - else: - return jsonify({ - "message": "Invalid Customer or Account" - }), 400 + else: + return jsonify({ + "message": "Invalid Customer or Account" + }), 400 - - # Simulated processing logic - response_data = { - "resultCode": "00", - "resultDescription": "Request is received" - } + + # Simulated processing logic + response_data = { + "resultCode": "00", + "resultDescription": "Request is received" + } - return response_data - + db.session.commit() + return response_data + except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") + db.session.rollback() return jsonify({ "message": "Validation exception" @@ -61,6 +63,7 @@ class CustomerConsentService(BaseService): except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") + db.session.rollback() return jsonify({ "message": str(err) @@ -68,6 +71,7 @@ class CustomerConsentService(BaseService): except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) + db.session.rollback() return jsonify({ "message": "Internal Server Error" }) , 500 \ No newline at end of file diff --git a/app/api/services/eligibility_check.py b/app/api/services/eligibility_check.py index 840424b..256ddf3 100644 --- a/app/api/services/eligibility_check.py +++ b/app/api/services/eligibility_check.py @@ -22,17 +22,18 @@ class EligibilityCheckService(BaseService): dict: A standardized response. """ try: + with db.session.begin(): - validated_data = EligibilityCheckService.validate_data(data, EligibilityCheckSchema()) - account_id = validated_data.get('accountId') - customer_id = validated_data.get('customerId') - transactionId = validated_data.get('transactionId') - msisdn = validated_data.get('msisdn') + validated_data = EligibilityCheckService.validate_data(data, EligibilityCheckSchema()) + account_id = validated_data.get('accountId') + customer_id = validated_data.get('customerId') + transactionId = validated_data.get('transactionId') + msisdn = validated_data.get('msisdn') - customer = EligibilityCheckService.get_or_create_customer(validated_data = validated_data) + customer = EligibilityCheckService.get_or_create_customer(validated_data = validated_data) - if (EligibilityCheckService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): - with db.session.begin(): + if (EligibilityCheckService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): + transaction = EligibilityCheckService.log_transaction(validated_data = validated_data) if not transaction: @@ -40,54 +41,56 @@ class EligibilityCheckService(BaseService): return jsonify({ "message": "Failed to log transaction." }), 400 - else: - return jsonify({ - "message": "Invalid Customer or Account" - }), 400 - - # Call RACCheck - response = SimbrellaIntegration.rac_check( - customer_id = customer_id, - account_id = account_id, - transaction_id = transaction.id, - ) - logger.error(f"This is Response Returned ****** : {str(response)}") + + else: + return jsonify({ + "message": "Invalid Customer or Account" + }), 400 + + # Call RACCheck + response = SimbrellaIntegration.rac_check( + customer_id = customer_id, + account_id = account_id, + transaction_id = transaction.id, + ) + logger.error(f"This is Response Returned ****** : {str(response)}") - # this chck for error is not valid - logger.error(f"Check for ERROR is not valid ****** FIX THIS !!!!!") - #if "error" in response or response.get("status") != 200: - # return jsonify({"message": "RACCheck failed"}), 400 + # this chck for error is not valid + logger.error(f"Check for ERROR is not valid ****** FIX THIS !!!!!") + #if "error" in response or response.get("status") != 200: + # return jsonify({"message": "RACCheck failed"}), 400 - offers = [ - { - "offerId": "SAL90", - "productId": "2030", - "minAmount": 5000, - "maxAmount": 100000, - "tenor": 30 - }, - { - "offerId": "SAL30", - "productId": "2090", - "minAmount": 3000, - "maxAmount": 500000, - "tenor": 90 - } - ] + offers = [ + { + "offerId": "SAL90", + "productId": "2030", + "minAmount": 5000, + "maxAmount": 100000, + "tenor": 30 + }, + { + "offerId": "SAL30", + "productId": "2090", + "minAmount": 3000, + "maxAmount": 500000, + "tenor": 90 + } + ] - # Simulate processing - response_data = { - "customerId": customer_id, - "transactionId": transactionId, - "countryCode": "NG", - "msisdn": msisdn, - "eligibleOffers": offers, - "resultDescription": "Successful", - "resultCode": "00", - "accountId": account_id - } + # Simulate processing + response_data = { + "customerId": customer_id, + "transactionId": transactionId, + "countryCode": "NG", + "msisdn": msisdn, + "eligibleOffers": offers, + "resultDescription": "Successful", + "resultCode": "00", + "accountId": account_id + } - return response_data + return response_data + except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") diff --git a/app/api/services/loan_status.py b/app/api/services/loan_status.py index 2e03b29..bfe8b68 100644 --- a/app/api/services/loan_status.py +++ b/app/api/services/loan_status.py @@ -22,55 +22,49 @@ class LoanStatusService(BaseService): dict: A standardized response. """ try: - validated_data = LoanStatusService.validate_data(data, LoanStatusSchema()) - customer_id = validated_data.get('customerId') - customer = LoanStatusService.get_or_create_customer(validated_data) - account = customer.accounts[0] + with db.session.begin(): + validated_data = LoanStatusService.validate_data(data, LoanStatusSchema()) + customer_id = validated_data.get('customerId') + + transaction = LoanStatusService.log_transaction(validated_data = validated_data) - if (LoanStatusService.validate_account_ownership(account_id = account.id, customer_id = customer_id)): - with db.session.begin(): - transaction = LoanStatusService.log_transaction(validated_data = validated_data) - - if not transaction: - logger.error(f"Failed to log transaction") - return jsonify({ - "message": "Failed to log transaction." - }), 400 - else: - return jsonify({ - "message": "Invalid Customer or Account" + if not transaction: + logger.error(f"Failed to log transaction") + return jsonify({ + "message": "Failed to log transaction." }), 400 - + - loans = [ - { - "debtId": "123456789", - "loanDate": "2019-10-18 14:26:21.063", - "dueDate": "2019-11-20 14:26:21.063", - "currentLoanAmount": 8500, - "initialLoanAmount": 10000, - "defaultPenaltyFee": 0, - "continuousFee": 0, - "productId": "101" + loans = [ + { + "debtId": "123456789", + "loanDate": "2019-10-18 14:26:21.063", + "dueDate": "2019-11-20 14:26:21.063", + "currentLoanAmount": 8500, + "initialLoanAmount": 10000, + "defaultPenaltyFee": 0, + "continuousFee": 0, + "productId": "101" + } + ] + + # Simulated processing logic + response_data = { + "customerId": "CN621868", + "transactionId": "Tr201712RK9232P115", + "loans": loans, + "totalDebtAmount": 8500, + "resultCode": "00", + "resultDescription": "Successful" } - ] - # Simulated processing logic - response_data = { - "customerId": "CN621868", - "transactionId": "Tr201712RK9232P115", - "loans": loans, - "totalDebtAmount": 8500, - "resultCode": "00", - "resultDescription": "Successful" - } - - - return response_data + db.session.commit() + return response_data except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") + db.session.rollback() return jsonify({ "message": "Validation exception" @@ -78,6 +72,7 @@ class LoanStatusService(BaseService): except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") + db.session.rollback() return jsonify({ "message": str(err) @@ -85,6 +80,7 @@ class LoanStatusService(BaseService): except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) + db.session.rollback() return jsonify({ "message": "Internal Server Error" }) , 500 \ No newline at end of file diff --git a/app/api/services/provide_loan.py b/app/api/services/provide_loan.py index e62fa04..b496265 100644 --- a/app/api/services/provide_loan.py +++ b/app/api/services/provide_loan.py @@ -26,15 +26,16 @@ class ProvideLoanService(BaseService): dict: A standardized response. """ try: - validated_data = ProvideLoanService.validate_data(data, ProvideLoanSchema()) - account_id = validated_data.get('accountId') - customer_id = validated_data.get('customerId') - request_id = validated_data.get('requestId') - transaction_id = validated_data.get('transactionId') + with db.session.begin(): + validated_data = ProvideLoanService.validate_data(data, ProvideLoanSchema()) + account_id = validated_data.get('accountId') + customer_id = validated_data.get('customerId') + request_id = validated_data.get('requestId') + transaction_id = validated_data.get('transactionId') - if (ProvideLoanService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): + if (ProvideLoanService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): - with db.session.begin(): + # Save the loan details loan = Loan.create_loan( customer_id=customer_id, @@ -50,6 +51,7 @@ class ProvideLoanService(BaseService): "message": "Failed to save loan details." }), 400 + db.session.flush() validated_data['refId'] = loan.id validated_data['refModel'] = "loan" @@ -63,34 +65,36 @@ class ProvideLoanService(BaseService): }), 400 - - else: - return jsonify({ - "message": "Invalid Customer or Account" - }), 400 - - - response_data = { - "requestId": request_id, - "transactionId": transaction_id, - "customerId": customer_id, - "accountId": account_id, - "msisdn": "3451342", - "resultCode": "00", - "resultDescription": "Successful" - } + + else: + return jsonify({ + "message": "Invalid Customer or Account" + }), 400 + + + response_data = { + "requestId": request_id, + "transactionId": transaction_id, + "customerId": customer_id, + "accountId": account_id, + "msisdn": "3451342", + "resultCode": "00", + "resultDescription": "Successful" + } - # KafkaIntegration.send_loan_request(loan_data = response_data, request_id = request_id) - # Call Kafka in a background thread - thread = Thread(target=ProvideLoanService.async_send_to_kafka, args=(response_data, request_id, "PROCESS_PAYMENT")) - thread.start() + # KafkaIntegration.send_loan_request(loan_data = response_data, request_id = request_id) + # Call Kafka in a background thread + thread = Thread(target=ProvideLoanService.async_send_to_kafka, args=(response_data, request_id, "PROCESS_PAYMENT")) + thread.start() - return response_data + db.session.commit() + return response_data except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") + db.session.rollback() return jsonify({ "message": "Validation exception" @@ -98,6 +102,7 @@ class ProvideLoanService(BaseService): except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") + db.session.rollback() return jsonify({ "message": str(err) @@ -105,6 +110,7 @@ class ProvideLoanService(BaseService): except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) + db.session.rollback() return jsonify({ "message": "Internal Server Error" }) , 500 diff --git a/app/api/services/repayment.py b/app/api/services/repayment.py index f914310..33be586 100644 --- a/app/api/services/repayment.py +++ b/app/api/services/repayment.py @@ -25,14 +25,15 @@ class RepaymentService(BaseService): dict: A standardized response. """ try: - validated_data = RepaymentService.validate_data(data, RepaymentSchema()) - customer_id = validated_data.get('customerId') - request_id = validated_data.get('requestId') - loan_id = validated_data.get('debtId') - product_id = validated_data.get('productId') - - with db.session.begin(): + validated_data = RepaymentService.validate_data(data, RepaymentSchema()) + customer_id = validated_data.get('customerId') + request_id = validated_data.get('requestId') + loan_id = validated_data.get('debtId') + product_id = validated_data.get('productId') + + + # Save the repayment details repayment = Repayment.create_repayment( customer_id = customer_id, @@ -47,6 +48,8 @@ class RepaymentService(BaseService): "message": "Failed to save repayment details." }), 400 + db.session.flush() + validated_data['refId'] = repayment.id validated_data['refModel'] = "repayment" @@ -62,29 +65,31 @@ class RepaymentService(BaseService): }), 400 - # Simulated processing logic - response_data = { - "customerId": customer_id, - "productId": product_id, - "debtId": loan_id, - "resultCode": "00", - "resultDescription": "Successful" - } + # Simulated processing logic + response_data = { + "customerId": customer_id, + "productId": product_id, + "debtId": loan_id, + "resultCode": "00", + "resultDescription": "Successful" + } - # return ResponseHelper.success( - # data=response_data, - # message="Repayment processed successfully" - # ) + # return ResponseHelper.success( + # data=response_data, + # message="Repayment processed successfully" + # ) - # Call Kafka in a background thread - thread = Thread(target=RepaymentService.async_send_to_kafka, args=(response_data, request_id, "LOAN_REPAYMENT")) - thread.start() + # Call Kafka in a background thread + thread = Thread(target=RepaymentService.async_send_to_kafka, args=(response_data, request_id, "LOAN_REPAYMENT")) + thread.start() - return response_data + db.session.commit() + return response_data except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") + db.session.rollback() return jsonify({ "message": "Validation exception" @@ -92,6 +97,7 @@ class RepaymentService(BaseService): except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") + db.session.rollback() return jsonify({ "message": str(err) @@ -99,6 +105,7 @@ class RepaymentService(BaseService): except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) + db.session.rollback() return jsonify({ "message": "Internal Server Error" }) , 500 diff --git a/app/api/services/select_offer.py b/app/api/services/select_offer.py index 4b4c4bb..6a0a914 100644 --- a/app/api/services/select_offer.py +++ b/app/api/services/select_offer.py @@ -1,13 +1,14 @@ from flask import request, jsonify from marshmallow import ValidationError from app.api.services.base_service import BaseService -from app.api.enums import TransactionType +from app.api.enums import TransactionType from app.utils.logger import logger from app.api.schemas.select_offer import SelectOfferSchema from app.extensions import db + class SelectOfferService(BaseService): - TRANSACTION_TYPE = TransactionType.SELECT_OFFER + TRANSACTION_TYPE = TransactionType.SELECT_OFFER @staticmethod def process_request(data): @@ -21,75 +22,72 @@ class SelectOfferService(BaseService): dict: A standardized response. """ try: - validated_data = SelectOfferService.validate_data(data, SelectOfferSchema()) - account_id = validated_data.get('accountId') - customer_id = validated_data.get('customerId') + with db.session.begin(): + validated_data = SelectOfferService.validate_data( + data, SelectOfferSchema() + ) + account_id = validated_data.get("accountId") + customer_id = validated_data.get("customerId") - if (SelectOfferService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): - with db.session.begin(): - transaction = SelectOfferService.log_transaction(validated_data = validated_data) + if SelectOfferService.validate_account_ownership( + account_id=account_id, customer_id=customer_id + ): + transaction = SelectOfferService.log_transaction( + validated_data=validated_data + ) if not transaction: logger.error(f"Failed to log transaction") - return jsonify({ - "message": "Failed to log transaction." - }), 400 - else: - return jsonify({ - "message": "Invalid Customer or Account" - }), 400 - - offers = [ + return jsonify({"message": "Failed to log transaction."}), 400 + else: + return jsonify({"message": "Invalid Customer or Account"}), 400 + + offers = [ { - "offerId": "14451", - "productId": "2030", - "amount": 10000.0, - "upfrontPayment": 1000.0, - "interestRate": 3.0, - "managementRate": 1.0, - "managementFee": 1.0, - "insuranceRate": 1.0, - "insuranceFee": 100.0, - "VATRate": 7.5, - "VATAmount": 100.0, - "recommendedRepaymentDates": ["2022-11-30"], - "installmentAmount": 11000.0, - "totalRepaymentAmount": 11000.0 + "offerId": "14451", + "productId": "2030", + "amount": 10000.0, + "upfrontPayment": 1000.0, + "interestRate": 3.0, + "managementRate": 1.0, + "managementFee": 1.0, + "insuranceRate": 1.0, + "insuranceFee": 100.0, + "VATRate": 7.5, + "VATAmount": 100.0, + "recommendedRepaymentDates": ["2022-11-30"], + "installmentAmount": 11000.0, + "totalRepaymentAmount": 11000.0, } ] - # Business logic - selecting an offer - response_data = { - "outstandingDebtAmount": 0, - "requestId": "202111170001371256908", - "transactionId": transaction.id, - "customerId": customer_id, - "accountId": account_id, - "loan": offers, - "resultCode": "00", - "resultDescription": "Successful" + # Business logic - selecting an offer + response_data = { + "outstandingDebtAmount": 0, + "requestId": "202111170001371256908", + "transactionId": transaction.id, + "customerId": customer_id, + "accountId": account_id, + "loan": offers, + "resultCode": "00", + "resultDescription": "Successful", } - - return response_data + db.session.commit() + return response_data except ValidationError as err: logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") + db.session.rollback() + return jsonify({"message": "Validation exception"}), 422 - return jsonify({ - "message": "Validation exception" - }) , 422 - - except ValueError as err: + except ValueError as err: logger.error(f"{getattr(err, 'messages', str(err))}") - - return jsonify({ - "message": str(err) - }) , 400 + db.session.rollback() + return jsonify({"message": str(err)}), 400 except Exception as e: logger.error(f"An error occurred: {str(e)}", exc_info=True) - return jsonify({ - "message": "Internal Server Error" - }) , 500 \ No newline at end of file + db.session.rollback() + return jsonify({"message": "Internal Server Error"}), 500 diff --git a/app/models/repayment.py b/app/models/repayment.py index f58e1a8..c313131 100644 --- a/app/models/repayment.py +++ b/app/models/repayment.py @@ -38,7 +38,7 @@ class Repayment(db.Model): repayment = cls( customer_id=customer_id, - loan_id=loan.id, + loan_id=loan_id, product_id=product_id, )