[update]: transaction logging and account ownership

This commit is contained in:
VivianDee
2025-03-31 14:50:22 +01:00
parent 6185c2df08
commit d9c99627ae
10 changed files with 203 additions and 79 deletions
+1 -1
View File
@@ -1 +1 @@
from .transaction_type import transaction_type from .transaction_type import TransactionType
+6 -2
View File
@@ -1,6 +1,10 @@
from enum import Enum from enum import Enum
class transaction_type(str, Enum): class TransactionType(str, Enum):
ELIGIBILITY_CHECK = "eligibility_check" ELIGIBILITY_CHECK = "eligibility_check"
PAYMENT = "payment" CUSTOMER_CONSENT = "customer_consent"
LOAN_STATUS = "loan_status"
NOTIFICATION_CALLBACK = "notification_callback"
PROVIDE_LOAN = "provide_loan"
REPAYMENT = "repayment" REPAYMENT = "repayment"
SELECT_OFFER = "select_offer"
+4 -6
View File
@@ -1,5 +1,5 @@
from app.models import Customer, Account, Transaction from app.models import Customer, Account, Transaction
from app.api.enums import transaction_type from app.api.enums import TransactionType
from flask import jsonify from flask import jsonify
from marshmallow import ValidationError from marshmallow import ValidationError
import logging import logging
@@ -40,18 +40,16 @@ class BaseService:
Check if the provided account belongs to the customer. Check if the provided account belongs to the customer.
""" """
is_valid = Account.is_valid_account(account_id, customer_id) is_valid = Account.is_valid_account(account_id, customer_id)
return is_valid
if not is_valid:
raise ValueError("Account does not belong to customer")
@classmethod @classmethod
def create_transaction(cls, validated_data): def log_transaction(cls, validated_data):
""" """
Create a new transaction. Create a new transaction.
""" """
return Transaction.create_transaction( return Transaction.create_transaction(
id=validated_data.get("transactionId"), id=validated_data.get("transactionId"),
account_id=validated_data.get("accountId"), account_id=validated_data.get("accountId"),
type=BaseService.TRANSACTION_TYPE, type=cls.TRANSACTION_TYPE,
channel=validated_data.get("channel"), channel=validated_data.get("channel"),
) )
+31 -11
View File
@@ -3,9 +3,13 @@ from app.api.services.base_service import BaseService
from marshmallow import ValidationError from marshmallow import ValidationError
from app.utils.logger import logger from app.utils.logger import logger
from app.api.schemas.customer_consent import CustomerConsentSchema from app.api.schemas.customer_consent import CustomerConsentSchema
from app.api.services.base_service import BaseService
from app.api.enums import TransactionType
class CustomerConsentService(BaseService): class CustomerConsentService(BaseService):
TRANSACTION_TYPE = TransactionType.CUSTOMER_CONSENT
@staticmethod @staticmethod
def process_request(data): def process_request(data):
""" """
@@ -18,11 +22,24 @@ class CustomerConsentService(BaseService):
dict: A standardized response. dict: A standardized response.
""" """
try: try:
logger.info("Processing CustomerConsent request")
# Validate input data using the CustomerConsent schema validated_data = CustomerConsentService.validate_data(data, CustomerConsentSchema())
schema = CustomerConsentSchema() account_id = validated_data.get('accountId')
validated_data = schema.load(data) customer_id = validated_data.get('customerId')
if(CustomerConsentService.validate_account_ownership(account_id = account_id, customer_id = customer_id)):
transaction = CustomerConsentService.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
# Simulated processing logic # Simulated processing logic
response_data = { response_data = {
@@ -30,20 +47,23 @@ class CustomerConsentService(BaseService):
"resultDescription": "Request is received" "resultDescription": "Request is received"
} }
# return ResponseHelper.success(
# data=response_data,
# message="Customer consent processed successfully"
# )
return response_data return response_data
except ValidationError as err: except ValidationError as err:
logger.error(f"Validation Error: {err.messages}")
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
return jsonify({ return jsonify({
"message": "Validation exception" "message": "Validation exception"
}) , 422 }) , 422
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
return jsonify({
"message": str(err)
}) , 400
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)
return jsonify({ return jsonify({
+14 -10
View File
@@ -3,10 +3,10 @@ from app.utils.logger import logger
from app.api.services.base_service import BaseService from app.api.services.base_service import BaseService
from app.api.schemas.eligibility_check import EligibilityCheckSchema from app.api.schemas.eligibility_check import EligibilityCheckSchema
from marshmallow import ValidationError from marshmallow import ValidationError
from app.api.enums import transaction_type from app.api.enums import TransactionType
class EligibilityCheckService(BaseService): class EligibilityCheckService(BaseService):
TRANSACTION_TYPE = transaction_type.ELIGIBILITY_CHECK TRANSACTION_TYPE = TransactionType.ELIGIBILITY_CHECK
@staticmethod @staticmethod
def process_request(data): def process_request(data):
@@ -27,20 +27,17 @@ class EligibilityCheckService(BaseService):
customer = EligibilityCheckService.get_or_create_customer(validated_data = validated_data) customer = EligibilityCheckService.get_or_create_customer(validated_data = validated_data)
logger.error(account_id)
logger.error(customer_id)
if (EligibilityCheckService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): if (EligibilityCheckService.validate_account_ownership(account_id = account_id, customer_id = customer_id)):
transaction = EligibilityCheckService.create_transaction(validated_data = validated_data) transaction = EligibilityCheckService.log_transaction(validated_data = validated_data)
if not transaction: if not transaction:
logger.error(f"Transaction creation failed") logger.error(f"Failed to log transaction")
return jsonify({ return jsonify({
"message": "Transaction creation failed." "message": "Failed to log transaction."
}), 400 }), 400
else: else:
return jsonify({ return jsonify({
"message": "Invalid account" "message": "Invalid Customer or Account"
}), 400 }), 400
@@ -74,7 +71,7 @@ class EligibilityCheckService(BaseService):
} }
return response_data return response_data
except (ValidationError, ValueError) as err: except ValidationError as err:
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}") logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
@@ -82,6 +79,13 @@ class EligibilityCheckService(BaseService):
"message": "Validation exception" "message": "Validation exception"
}) , 422 }) , 422
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
return jsonify({
"message": str(err)
}) , 400
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)
return jsonify({ return jsonify({
+32 -11
View File
@@ -2,8 +2,13 @@ from flask import request, jsonify
from marshmallow import ValidationError from marshmallow import ValidationError
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.enums import TransactionType
class LoanStatusService(BaseService):
TRANSACTION_TYPE = TransactionType.LOAN_STATUS
class LoanStatusService:
@staticmethod @staticmethod
def process_request(data): def process_request(data):
""" """
@@ -16,11 +21,23 @@ class LoanStatusService:
dict: A standardized response. dict: A standardized response.
""" """
try: try:
logger.info("Processing LoanStatus request") validated_data = LoanStatusService.validate_data(data, LoanStatusSchema())
account_id = validated_data.get('accountId')
customer_id = validated_data.get('customerId')
if (LoanStatusService.validate_account_ownership(account_id = account_id, customer_id = customer_id)):
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"
}), 400
# Validate input data using the imported schema
schema = LoanStatusSchema()
validated_data = schema.load(data) # Raises ValidationError if invalid
loans = [ loans = [
{ {
@@ -46,19 +63,23 @@ class LoanStatusService:
} }
# return ResponseHelper.success(
# data=response_data,
# message="Loan information retrieved successfully"
# )
return response_data return response_data
except ValidationError as err: except ValidationError as err:
logger.error(f"Validation Error: {err.messages}")
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
return jsonify({ return jsonify({
"message": "Validation exception" "message": "Validation exception"
}) , 422 }) , 422
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
return jsonify({
"message": str(err)
}) , 400
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)
return jsonify({ return jsonify({
+15 -2
View File
@@ -1,9 +1,13 @@
from flask import request, jsonify from flask import request, jsonify
from marshmallow import ValidationError 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.utils.logger import logger
from app.api.schemas.notification_callback import NotificationCallbackSchema from app.api.schemas.notification_callback import NotificationCallbackSchema
class NotificationCallbackService: class NotificationCallbackService(BaseService):
TRANSACTION_TYPE = TransactionType.NOTIFICATION_CALLBACK
@staticmethod @staticmethod
def process_request(data): def process_request(data):
""" """
@@ -37,11 +41,20 @@ class NotificationCallbackService:
return response_data return response_data
except ValidationError as err: except ValidationError as err:
logger.error(f"Validation Error: {err.messages}")
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
return jsonify({ return jsonify({
"message": "Validation exception" "message": "Validation exception"
}) , 422 }) , 422
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
return jsonify({
"message": str(err)
}) , 400
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)
return jsonify({ return jsonify({
+32 -11
View File
@@ -1,9 +1,14 @@
from flask import request, jsonify from flask import request, jsonify
from marshmallow import ValidationError 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.utils.logger import logger
from app.api.schemas.provide_loan import ProvideLoanSchema from app.api.schemas.provide_loan import ProvideLoanSchema
class ProvideLoanService: class ProvideLoanService(BaseService):
TRANSACTION_TYPE = TransactionType.PROVIDE_LOAN
@staticmethod @staticmethod
def process_request(data): def process_request(data):
""" """
@@ -16,13 +21,24 @@ class ProvideLoanService:
dict: A standardized response. dict: A standardized response.
""" """
try: try:
logger.info("Processing ProvideLoan request") validated_data = ProvideLoanService.validate_data(data, ProvideLoanSchema())
account_id = validated_data.get('accountId')
customer_id = validated_data.get('customerId')
if (ProvideLoanService.validate_account_ownership(account_id = account_id, customer_id = customer_id)):
transaction = ProvideLoanService.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
# Validate input data using the imported schema
schema = ProvideLoanSchema()
validated_data = schema.load(data) # Raises ValidationError if invalid
# Business logic - providing a loan
response_data = { response_data = {
"requestId": "202111170001371256908", "requestId": "202111170001371256908",
"transactionId": "Tr201712RK9232P115", "transactionId": "Tr201712RK9232P115",
@@ -34,19 +50,24 @@ class ProvideLoanService:
} }
# return ResponseHelper.success(
# data=response_data,
# message="Loan successfully provided"
# )
return response_data return response_data
except ValidationError as err: except ValidationError as err:
logger.error(f"Validation Error: {err.messages}")
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
return jsonify({ return jsonify({
"message": "Validation exception" "message": "Validation exception"
}) , 422 }) , 422
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
return jsonify({
"message": str(err)
}) , 400
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)
return jsonify({ return jsonify({
+30 -6
View File
@@ -2,8 +2,12 @@ from flask import request, jsonify
from marshmallow import ValidationError from marshmallow import ValidationError
from app.utils.logger import logger from app.utils.logger import logger
from app.api.schemas.repayment import RepaymentSchema from app.api.schemas.repayment import RepaymentSchema
from app.api.services.base_service import BaseService
from app.api.enums import TransactionType
class RepaymentService(BaseService):
TRANSACTION_TYPE = TransactionType.REPAYMENT
class RepaymentService:
@staticmethod @staticmethod
def process_request(data): def process_request(data):
""" """
@@ -16,11 +20,22 @@ class RepaymentService:
dict: A standardized response. dict: A standardized response.
""" """
try: try:
logger.info("Processing Repayment request") validated_data = RepaymentService.validate_data(data, RepaymentSchema())
account_id = validated_data.get('accountId')
customer_id = validated_data.get('customerId')
# Validate input data using the Repayment schema if (RepaymentService.validate_account_ownership(account_id = account_id, customer_id = customer_id)):
schema = RepaymentSchema() transaction = RepaymentService.log_transaction(validated_data = validated_data)
validated_data = schema.load(data) # Raises ValidationError if invalid
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
# Simulated processing logic # Simulated processing logic
response_data = { response_data = {
@@ -39,11 +54,20 @@ class RepaymentService:
return response_data return response_data
except ValidationError as err: except ValidationError as err:
logger.error(f"Validation Error: {err.messages}")
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
return jsonify({ return jsonify({
"message": "Validation exception" "message": "Validation exception"
}) , 422 }) , 422
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
return jsonify({
"message": str(err)
}) , 400
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)
return jsonify({ return jsonify({
+30 -11
View File
@@ -1,9 +1,13 @@
from flask import request, jsonify from flask import request, jsonify
from marshmallow import ValidationError 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.utils.logger import logger
from app.api.schemas.select_offer import SelectOfferSchema from app.api.schemas.select_offer import SelectOfferSchema
class SelectOfferService: class SelectOfferService(BaseService):
TRANSACTION_TYPE = TransactionType.SELECT_OFFER
@staticmethod @staticmethod
def process_request(data): def process_request(data):
""" """
@@ -16,11 +20,22 @@ class SelectOfferService:
dict: A standardized response. dict: A standardized response.
""" """
try: try:
logger.info("Processing SelectOffer request") validated_data = SelectOfferService.validate_data(data, SelectOfferSchema())
account_id = validated_data.get('accountId')
customer_id = validated_data.get('customerId')
# Validate input data using the imported schema if (SelectOfferService.validate_account_ownership(account_id = account_id, customer_id = customer_id)):
schema = SelectOfferSchema() transaction = SelectOfferService.log_transaction(validated_data = validated_data)
validated_data = schema.load(data) # Raises ValidationError if invalid
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 = [ offers = [
{ {
@@ -54,19 +69,23 @@ class SelectOfferService:
} }
# return ResponseHelper.success(
# data=response_data,
# message="Offer selection completed successfully"
# )
return response_data return response_data
except ValidationError as err: except ValidationError as err:
logger.error(f"Validation Error: {err.messages}")
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
return jsonify({ return jsonify({
"message": "Validation exception" "message": "Validation exception"
}) , 422 }) , 422
except ValueError as err:
logger.error(f"{getattr(err, 'messages', str(err))}")
return jsonify({
"message": str(err)
}) , 400
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)
return jsonify({ return jsonify({