mercore starter
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
from flask import request, jsonify
|
||||
from marshmallow import ValidationError
|
||||
from app.api.helpers.response_helper import ResponseHelper
|
||||
from app.api.services.base_service import BaseService
|
||||
from app.api.enums import TransactionType
|
||||
from app.models.transaction_offers import TransactionOffer
|
||||
from app.utils.logger import logger
|
||||
from app.api.schemas.select_offer import SelectOfferSchema
|
||||
from app.extensions import db
|
||||
from app.models import Offer
|
||||
from datetime import date
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
class SelectOfferService(BaseService):
|
||||
TRANSACTION_TYPE = TransactionType.SELECT_OFFER
|
||||
|
||||
@staticmethod
|
||||
def process_request(data):
|
||||
"""
|
||||
Process the SelectOffer request.
|
||||
|
||||
Args:
|
||||
data (dict): The request data.
|
||||
|
||||
Returns:
|
||||
dict: A standardized response.
|
||||
"""
|
||||
try:
|
||||
with db.session.begin():
|
||||
validated_data = SelectOfferService.validate_data(
|
||||
data, SelectOfferSchema()
|
||||
)
|
||||
account_id = validated_data.get("accountId")
|
||||
customer_id = validated_data.get("customerId")
|
||||
amount = validated_data.get("requestedAmount")
|
||||
product_id = validated_data.get("productId")
|
||||
transaction_offer_id = validated_data.get("offerId")
|
||||
transaction_id = validated_data.get("transactionId")
|
||||
request_id = validated_data.get("requestId")
|
||||
|
||||
offer_id = int(transaction_offer_id[5:]) # The last part is int
|
||||
|
||||
#"offerId": "SAL30001129",
|
||||
|
||||
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 ResponseHelper.error(result_description="Failed to log transaction.")
|
||||
else:
|
||||
return ResponseHelper.error(result_description="Invalid Customer or Account")
|
||||
|
||||
# Get the offer by product ID
|
||||
offer = Offer.get_offer_by_product_id(product_id)
|
||||
|
||||
transaction_offer = TransactionOffer.get_transaction_offer(transaction_offer_id=offer_id)
|
||||
|
||||
if not transaction_offer:
|
||||
logger.error(f"offer {offer_id} not found for customer {customer_id} and transaction {transaction_id}.")
|
||||
return ResponseHelper.error(result_description="Offer not found.")
|
||||
|
||||
db.session.flush()
|
||||
|
||||
if amount < transaction_offer.min_amount:
|
||||
logger.error(f"The amount {amount} is less than the minimum allowed offer amount {transaction_offer.min_amount}.")
|
||||
return ResponseHelper.error(result_description="The amount is less than the minimum allowed offer amount.")
|
||||
elif amount > transaction_offer.eligible_amount:
|
||||
logger.error(f"The amount {amount} is greater than the eligible offer amount {transaction_offer.eligible_amount}.")
|
||||
return ResponseHelper.error(result_description="The amount is greater than the eligible offer amount.")
|
||||
|
||||
|
||||
|
||||
charges = SelectOfferService.calculate_charges(offer, amount)
|
||||
upfront_payment = charges["upfront_payment"]
|
||||
total_amount = charges["total_amount"]
|
||||
installment_amount = charges["installment_amount"]
|
||||
interest = charges["interest"]
|
||||
management = charges["management"]
|
||||
insurance = charges["insurance"]
|
||||
vat = charges["vat"]
|
||||
repayment_amount = charges["repayment_amount"]
|
||||
interest_amount = charges["interest_amount"]
|
||||
|
||||
|
||||
# Calculate the repayment dates
|
||||
tenor = offer.tenor
|
||||
start_date = date.today()
|
||||
|
||||
# Convert tenor to months
|
||||
months = offer.schedule # tenor // 30
|
||||
|
||||
recommended_repayment_dates = [
|
||||
(start_date + relativedelta(months=i + 1)).isoformat()
|
||||
for i in range(months)
|
||||
]
|
||||
|
||||
|
||||
|
||||
offers = [
|
||||
{
|
||||
"offerId": transaction_offer_id,
|
||||
"productId": product_id,
|
||||
"amount": amount,
|
||||
"upfrontPayment": upfront_payment,
|
||||
"interestRate": offer.interest_rate,
|
||||
"interestFee": interest_amount,
|
||||
"managementRate": offer.management_rate,
|
||||
"managementFee": management["fee"],
|
||||
"insuranceRate": offer.insurance_rate,
|
||||
"insuranceFee": insurance["fee"],
|
||||
"VATRate": offer.vat_rate,
|
||||
"VATAmount": vat["fee"],
|
||||
"recommendedRepaymentDates": recommended_repayment_dates,
|
||||
"repaymentAmount": repayment_amount,
|
||||
"installmentAmount": installment_amount,
|
||||
"totalRepaymentAmount": total_amount,
|
||||
}
|
||||
]
|
||||
|
||||
# "offerId": offer.id,
|
||||
# "productId": product_id,
|
||||
# "amount": amount,
|
||||
# "upfrontPayment": upfront_payment,
|
||||
# "interestRate": interest["rate"],
|
||||
# "managementRate": management["rate"],
|
||||
# "managementFee": management["fee"],
|
||||
# "insuranceRate": insurance["rate"],
|
||||
# "insuranceFee": insurance["fee"],
|
||||
# "VATRate": vat["rate"],
|
||||
# "VATAmount": vat["fee"],
|
||||
# "recommendedRepaymentDates": recommended_repayment_dates,
|
||||
# "installmentAmount": installment_amount,
|
||||
# "totalRepaymentAmount": total_amount,
|
||||
#
|
||||
# Business logic - selecting an offer
|
||||
response_data = {
|
||||
"outstandingDebtAmount": 0,
|
||||
"requestId": request_id,
|
||||
"transactionId": transaction_id,
|
||||
"customerId": customer_id,
|
||||
"accountId": account_id,
|
||||
"loan": offers,
|
||||
}
|
||||
|
||||
db.session.commit()
|
||||
return ResponseHelper.success(data=response_data)
|
||||
|
||||
except ValidationError as err:
|
||||
|
||||
logger.error(f"Validation Error: {getattr(err, 'messages', str(err))}")
|
||||
db.session.rollback()
|
||||
return ResponseHelper.unprocessable_entity(result_description="Validation exception")
|
||||
|
||||
except ValueError as err:
|
||||
logger.error(f"{getattr(err, 'messages', str(err))}")
|
||||
db.session.rollback()
|
||||
return ResponseHelper.error(result_description=str(err))
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"An error occurred: {str(e)}", exc_info=True)
|
||||
db.session.rollback()
|
||||
return ResponseHelper.internal_server_error()
|
||||
|
||||
Reference in New Issue
Block a user