diff --git a/app/config.py b/app/config.py index 2b604d7..65159ec 100644 --- a/app/config.py +++ b/app/config.py @@ -37,8 +37,9 @@ class Config: SQLALCHEMY_TRACK_MODIFICATIONS = False BANK_CALL_BASE_URL = os.getenv("BANK_CALL_BASE_URL", "https://bank-emulator.dev.simbrellang.net") - BANK_CALL_DISBURSE_LOAN_ENDPOINT = os.getenv("BANK_CALL_DISBURSE_LOAN_ENDPOINT","api/DisburseLoan") - BANK_CALL_COLLECT_LOAN_ENDPOINT = os.getenv("BANK_CALL_COLLECT_LOAN_ENDPOINT","api/CollectLoan") - BANK_CALL_TRANSACTION_VERIFY = os.getenv("BANK_CALL_TRANSACTION_VERIFY", "api/TransactionVerify") + BANK_CALL_SMS_BASE_URL= os.getenv("BANK_CALL_SMS_BASE_URL","https://first-advance-middleware-develop.fbn-devops-dev-asenv.appserviceenvironment.net/SMS") + BANK_CALL_DISBURSE_LOAN_ENDPOINT = os.getenv("BANK_CALL_DISBURSE_LOAN_ENDPOINT","/DisburseLoan") + BANK_CALL_COLLECT_LOAN_ENDPOINT = os.getenv("BANK_CALL_COLLECT_LOAN_ENDPOINT","/CollectLoan") + BANK_CALL_TRANSACTION_VERIFY = os.getenv("BANK_CALL_TRANSACTION_VERIFY", "/TransactionVerify") settings = Config() diff --git a/app/integrations/simbrella.py b/app/integrations/simbrella.py index 1bc92aa..228d628 100644 --- a/app/integrations/simbrella.py +++ b/app/integrations/simbrella.py @@ -14,6 +14,7 @@ from app.extensions import db class SimbrellaClient: BANK_CALL_BASE_URL = settings.BANK_CALL_BASE_URL + BANK_CALL_SMS_BASE_URL = settings.BANK_CALL_SMS_BASE_URL BANK_CALL_DISBURSE_LOAN_ENDPOINT = settings.BANK_CALL_DISBURSE_LOAN_ENDPOINT BANK_CALL_COLLECT_LOAN_ENDPOINT = settings.BANK_CALL_COLLECT_LOAN_ENDPOINT BANK_CALL_TRANSACTION_VERIFY = settings.BANK_CALL_TRANSACTION_VERIFY @@ -97,7 +98,8 @@ class SimbrellaClient: @staticmethod def verify_transaction(data): - api_url = f"{SimbrellaClient.BANK_CALL_BASE_URL}/{SimbrellaClient.BANK_CALL_DISBURSE_LOAN_ENDPOINT}" + api_url = f"{SimbrellaClient.BANK_CALL_BASE_URL}/{SimbrellaClient.BANK_CALL_TRANSACTION_VERIFY}" + sms_url = f"{SimbrellaClient.BANK_CALL_SMS_BASE_URL}/singleSMS" logger.info(f"Calling TransactionVerify api_url==> : {api_url}") # Check if the transaction exists @@ -124,6 +126,9 @@ class SimbrellaClient: logger.info(f"Here is your loan data: {loan_data}") if loan_data['disburseDate'] is not None and loan_data['disburseVerify'] is None : + LoanService.set_disburse_verify_date(loan_data['debtId'],loan_data['customerId']) + loan_data = loan.to_dict() + logger.info(f"Here is your loan data after setting verify date: {loan_data}") logger.info(f"Good to Verify transaction id: {data['transactionId']}") else: logger.info( @@ -132,11 +137,10 @@ class SimbrellaClient: verify_data = { - "channel": "USSD", "customerId": loan_data.get('customerId'), "accountId": loan_data.get('accountId'), "transactionId": loan_data.get('transactionId'), - "transactionType": "LOAN", + "transactionType": "provide", "countryId": "NG", "requestId": loan_data.get('transactionId') } @@ -144,9 +148,27 @@ class SimbrellaClient: try: logger.info(f"Here is your TransactionVerify Request data ****** : {verify_data}") response = requests.post(api_url, json=verify_data, timeout=10, headers=get_headers()) - logger.info(f"TransactionVerify Response: {response.json()}") - return ResponseHelper.success(response, "Successful") - + result = response.json() + LoanService.set_disburse_verify_result(loan_data['debtId'],result.get('responseCode', ''), result.get('responseMessage', '')) + sms_data = { + "dest": "2347038224367", + "text": "test", + "unicode": True + } + try: + sms_response = requests.post(sms_url, json=sms_data, timeout=10, headers=get_headers()) + sms_response.raise_for_status() # Raise an exception for 4xx or 5xx status codes + result = sms_response.json() + logger.info(f"SMS Response JSON: {result}") + if result.get('isSuccess'): + logger.info(f"sms sent successfully") + return ResponseHelper.success(response, "Successful") + logger.info(f"sms failed!") + return 1 + except requests.RequestException as e: + # Handle the exception + logger.error(f"Failed to send SMS: {e}") + return 0 except Exception as e: logger.info(f"Failed to call TransactionVerify endpoint: {e}") return 0 diff --git a/app/models/loan.py b/app/models/loan.py index 39e28f8..a247ad0 100644 --- a/app/models/loan.py +++ b/app/models/loan.py @@ -4,7 +4,7 @@ from sqlalchemy.orm import relationship from dateutil.relativedelta import relativedelta from datetime import timedelta import logging -from sqlalchemy import and_, or_, not_ +from sqlalchemy import and_, or_, not_ from sqlalchemy.sql import func from app.utils.logger import logger from app.extensions import db @@ -41,6 +41,8 @@ class Loan(db.Model): disburse_verify = db.Column(db.DateTime, nullable=True) disburse_result = db.Column(db.String(10), nullable=True) disburse_description = db.Column(db.String(100), nullable=True) + verify_result = db.Column(db.String(10), nullable=True) + verify_description = db.Column(db.String(100), nullable=True) reference = db.Column(db.String(50), nullable=True) customer = relationship( @@ -76,12 +78,14 @@ class Loan(db.Model): 'productId': self.product_id, 'disburseResult': self.disburse_result, 'disburseDescription': self.disburse_description, + 'verifyResult': self.verify_result, + 'verifyDescription': self.verify_description, 'transactionId': self.transaction_id, 'accountId':self.account_id, 'dueDate': self.due_date.isoformat() if self.due_date else None, 'loanDate': self.created_at.isoformat() if self.created_at else None, 'disburseDate': self.disburse_date.isoformat() if self.disburse_date else None, - 'disburseVerify': self.disburse_verify.isoformat if self.disburse_verify else None, + 'disburseVerify': self.disburse_verify.isoformat() if self.disburse_verify else None, 'reference': self.reference } @@ -117,6 +121,35 @@ class Loan(db.Model): db.session.rollback() logger.error(f"Failed to update disburse date: {e}") raise + @classmethod + def set_disburse_verify_date(cls, loan_id, customer_id): + """ + Update the disburse verify date 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.") + + # Check if customer_id matches + if loan.customer_id != customer_id: + raise ValueError(f"Customer ID {customer_id} does not match the loan's customer ID.") + + current_time = datetime.now() + logger.info(f"What is now ======= ==== ==> : {current_time}") + # Update loan verify_date + loan.disburse_verify = current_time + + # Commit changes to database + try: + logger.info(f"Updating disburse verify date for loan ID {loan_id} to {current_time}") + db.session.commit() + except Exception as e: + db.session.rollback() + logger.error(f"Failed to update disburse verify date: {e}") + raise + @classmethod def set_disbursement_result(cls, loan_id, result, description): @@ -141,7 +174,29 @@ class Loan(db.Model): db.session.rollback() logger.error(f"Failed to update disbursement result: {e}") raise + @classmethod + def set_disburse_verify_result(cls, loan_id, result, description): + """ + Update the verify result and description 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.") + + # Update disburse result and description + loan.verify_result = result + loan.verify_description = description + + # Commit changes to database + try: + logger.info(f"Updating verify result for loan ID {loan_id} to {result} with description {description}") + db.session.commit() + except Exception as e: + db.session.rollback() + logger.error(f"Failed to update verify result: {e}") + raise @classmethod def get_latest_loan_without_disburse_date(cls): """ @@ -154,8 +209,9 @@ class Loan(db.Model): @classmethod def get_latest_loan_with_disburse_date(cls): """ - Get the latest loan without a disbursement date. + Get the latest loan with a disbursement date and no verification date. """ return cls.query.filter( - cls.disburse_date.is_(None) + cls.disburse_date.isnot(None), + cls.disburse_verify.is_(None) ).order_by(cls.created_at.desc()).first() \ No newline at end of file diff --git a/app/services/loan.py b/app/services/loan.py index 1687529..51b3fe2 100644 --- a/app/services/loan.py +++ b/app/services/loan.py @@ -30,6 +30,12 @@ class LoanService: Update the disbursement status of the loan with the given loan_id. """ return Loan.set_disbursement_date(loan_id, customer_id) + @classmethod + def set_disburse_verify_date(cls, loan_id, customer_id): + """ + Update the disburse verify date of the loan with the given loan_id. + """ + return Loan.set_disburse_verify_date(loan_id, customer_id) @classmethod def set_disbursement_result(cls, loan_id, result, description): @@ -37,6 +43,12 @@ class LoanService: Update the disbursement result of the loan with the given loan_id. """ return Loan.set_disbursement_result(loan_id, result, description) + @classmethod + def set_disburse_verify_result(cls, loan_id, result, description): + """ + Update the disburse verify result of the loan with the given loan_id. + """ + return Loan.set_disburse_verify_result(loan_id, result, description) @classmethod def get_latest_loan_without_disburse_date(cls):