Custom templates fix

This commit is contained in:
CHIEFSOFT\ameye
2025-09-20 20:00:24 -04:00
parent ff8513292b
commit 4d894d8214
12 changed files with 762 additions and 732 deletions
+2 -1
View File
@@ -1,4 +1,5 @@
from .transaction_type import TransactionType
from .loan_status import LoanStatus
from .settings_items_data import SettingsItemsData
from .generatives_list import GenerativesList
from .generatives_list import GenerativesList
from .kafka_messages import KafkaMessage
+5
View File
@@ -0,0 +1,5 @@
from enum import Enum
class KafkaMessage(str, Enum):
REFRESH_PRODUCT_SETTINGS = "REFRESH_PRODUCT_SETTINGS"
FLUTTER_PAYMENT_RECEIVED = "FLUTTER_PAYMENT_RECEIVED"
+110 -144
View File
@@ -306,45 +306,45 @@ class BaseService:
logger.info(f"Processing {cls.TRANSACTION_TYPE} request")
return schema.load(data)
@classmethod
def get_or_create_customer(cls, validated_data):
"""
Check if a customer exists; if not, create one.
"""
# @classmethod
# def get_or_create_customer(cls, validated_data):
#
# """
# Check if a customer exists; if not, create one.
# """
#
# customer = Customer.query.filter_by(id=validated_data.get("customerId")).first()
# if not customer:
# customer = Customer.create_customer(
# id=validated_data.get("customerId"),
# msisdn=validated_data.get("msisdn"),
# country_code=validated_data.get("countryCode"),
# account_id=validated_data.get("accountId"),
# )
# return customer
customer = Customer.query.filter_by(id=validated_data.get("customerId")).first()
if not customer:
customer = Customer.create_customer(
id=validated_data.get("customerId"),
msisdn=validated_data.get("msisdn"),
country_code=validated_data.get("countryCode"),
account_id=validated_data.get("accountId"),
)
return customer
# @classmethod
# def validate_account_ownership(cls, account_id, customer_id):
# """
# Check if the provided account belongs to the customer.
# """
# is_valid = Account.is_valid_account(account_id, customer_id)
# return is_valid
@classmethod
def validate_account_ownership(cls, account_id, customer_id):
"""
Check if the provided account belongs to the customer.
"""
is_valid = Account.is_valid_account(account_id, customer_id)
return is_valid
@classmethod
def log_transaction(cls, validated_data):
"""
Create a new transaction.
"""
channel = "USSD" if validated_data.get("channel") is None else validated_data.get("channel")
return Transaction.create_transaction(
transaction_id = validated_data.get("transactionId"),
customer_id = validated_data.get('customerId', None),
account_id = validated_data.get("accountId", None),
type = cls.TRANSACTION_TYPE,
channel = channel,
)
# @classmethod
# def log_transaction(cls, validated_data):
# """
# Create a new transaction.
# """
# channel = "USSD" if validated_data.get("channel") is None else validated_data.get("channel")
#
# return Transaction.create_transaction(
# transaction_id = validated_data.get("transactionId"),
# customer_id = validated_data.get('customerId', None),
# account_id = validated_data.get("accountId", None),
# type = cls.TRANSACTION_TYPE,
# channel = channel,
# )
@classmethod
def async_send_settings_refresh_to_kafka(cls, settings_data, subscription_uid, topic):
@@ -357,113 +357,79 @@ class BaseService:
KafkaIntegration.send_loan_request(loan_data = loan_data, request_id = request_id, topic = topic)
KafkaIntegration.flush()
@classmethod
def calculate_charges(cls, offer, amount):
"""
Calculates and returns the charges for the given offer and amount.
Args:
offer (Offer): The offer object that contains the charges.
amount (float): The requested loan amount.
Returns:
dict: A dictionary containing the calculated charges.
"""
if not offer or not offer.charges:
logger.error(f"No charges found for offer ID {offer.id}")
return {"error": "No charges found for the offer"}
loan_charges = offer.charges
tenor = offer.schedule # offer.tenor // 30 # Convert to months
interest = cls.get_charge_detail(rates = offer.interest_rate, charges = loan_charges, code = "INTEREST", amount = amount)
management = cls.get_charge_detail(rates = offer.management_rate, charges = loan_charges, code = "MGTFEE", amount = amount)
insurance = cls.get_charge_detail(rates = offer.insurance_rate, charges = loan_charges, code = "INSURANCE", amount = amount)
vat = cls.get_charge_detail(rates = offer.vat_rate, charges = loan_charges, code = "VAT", amount = amount, management_fee = management["fee"])
# Separate fees into upfront and postpaid
upfront_fees = [
fee["fee"]
for fee in [interest, management, insurance, vat]
if fee["due_days"] == 0
]
postpaid_fees = [
fee["fee"]
for fee in [interest, management, insurance, vat]
if fee["due_days"] != 0
]
vat_test = vat["fee"]
logger.info(f"VAT fee == *************** : {vat_test}")
# Up-front payment: (only those fees due immediately i.e due_days == 0)
# upfront_payment = sum(upfront_fees)
if offer.schedule == 1:
upfront_payment = vat["fee"] + management["fee"] + insurance["fee"] + interest["fee"]
interest_amount = interest["fee"]
repayment_amount = amount
else:
upfront_payment = vat["fee"] + insurance["fee"]+management["fee"]
interest_amount = interest["fee"]*offer.schedule
repayment_amount = amount + interest_amount
#
# @classmethod
# def calculate_charges(cls, offer, amount):
# """
# Calculates and returns the charges for the given offer and amount.
#
# Args:
# offer (Offer): The offer object that contains the charges.
# amount (float): The requested loan amount.
#
# Returns:
# dict: A dictionary containing the calculated charges.
# """
# if not offer or not offer.charges:
# logger.error(f"No charges found for offer ID {offer.id}")
# return {"error": "No charges found for the offer"}
#
# loan_charges = offer.charges
# tenor = offer.schedule # offer.tenor // 30 # Convert to months
# interest = cls.get_charge_detail(rates = offer.interest_rate, charges = loan_charges, code = "INTEREST", amount = amount)
# management = cls.get_charge_detail(rates = offer.management_rate, charges = loan_charges, code = "MGTFEE", amount = amount)
# insurance = cls.get_charge_detail(rates = offer.insurance_rate, charges = loan_charges, code = "INSURANCE", amount = amount)
# vat = cls.get_charge_detail(rates = offer.vat_rate, charges = loan_charges, code = "VAT", amount = amount, management_fee = management["fee"])
#
# # Separate fees into upfront and postpaid
# upfront_fees = [
# fee["fee"]
# for fee in [interest, management, insurance, vat]
# if fee["due_days"] == 0
# ]
#
# postpaid_fees = [
# fee["fee"]
# for fee in [interest, management, insurance, vat]
# if fee["due_days"] != 0
# ]
# vat_test = vat["fee"]
# logger.info(f"VAT fee == *************** : {vat_test}")
#
# # Up-front payment: (only those fees due immediately i.e due_days == 0)
# # upfront_payment = sum(upfront_fees)
# if offer.schedule == 1:
# upfront_payment = vat["fee"] + management["fee"] + insurance["fee"] + interest["fee"]
# interest_amount = interest["fee"]
# repayment_amount = amount
# else:
# upfront_payment = vat["fee"] + insurance["fee"]+management["fee"]
# interest_amount = interest["fee"]*offer.schedule
# repayment_amount = amount + interest_amount
#
#
# # Repayment amount: (principal + only those fees not due immediately i.e due_days != 0)
# # repayment_amount = amount + (sum(postpaid_fees) * tenor)
#
# # Total amount: (upfront_payment + repayment_amount)
# total_amount = upfront_payment + repayment_amount
#
# # Calculate the installment amount
# installment_amount = repayment_amount / offer.schedule
#
# return {
# "interest": interest,
# "interest_amount": interest_amount,
# "management": management,
# "insurance": insurance,
# "vat": vat,
# "upfront_payment": round(upfront_payment, 2),
# "repayment_amount": round(repayment_amount, 2),
# "installment_amount": round(installment_amount, 2),
# "total_amount": round(total_amount, 2)
# }
#
#
# Repayment amount: (principal + only those fees not due immediately i.e due_days != 0)
# repayment_amount = amount + (sum(postpaid_fees) * tenor)
# Total amount: (upfront_payment + repayment_amount)
total_amount = upfront_payment + repayment_amount
# Calculate the installment amount
installment_amount = repayment_amount / offer.schedule
return {
"interest": interest,
"interest_amount": interest_amount,
"management": management,
"insurance": insurance,
"vat": vat,
"upfront_payment": round(upfront_payment, 2),
"repayment_amount": round(repayment_amount, 2),
"installment_amount": round(installment_amount, 2),
"total_amount": round(total_amount, 2)
}
@classmethod
def get_charge_detail(cls, rates, charges, code, amount, management_fee= 0.0):
"""
Get details for a specific charge code from a list of loan charges.
Returns default values if not found.
"""
fee = 0.0
if code == "VAT" and management_fee > 0:
fee = management_fee * rates / 100
else:
fee = amount * rates / 100
return {
"rate": rates,
"fee": round(fee, 2),
"due_days": 30,
"code": code,
"description" : "have no idea how to get this yet"
}
# if charge.code == code:
# if code == "VAT" and management_fee > 0:
# fee = management_fee * rates / 100
# else:
# fee = amount * rates / 100
#
# return {
# "rate": rates,
# "fee": round(fee, 2),
# "due_days": charge.due
# }
# return {"rate": 0, "fee": 0, "due_days": 0}
+59 -59
View File
@@ -1,60 +1,60 @@
from flask import request, jsonify
from app.api.helpers.response_helper import ResponseHelper
# from flask import request, jsonify
# from app.api.helpers.response_helper import ResponseHelper
# # from app.api.services.base_service import BaseService
# from marshmallow import ValidationError
# from app.utils.logger import logger
# # from app.api.schemas.customer_consent import CustomerConsentSchema
# from app.api.services.base_service import BaseService
from marshmallow import ValidationError
from app.utils.logger import logger
# from app.api.schemas.customer_consent import CustomerConsentSchema
from app.api.services.base_service import BaseService
from app.api.enums import TransactionType
from app.extensions import db
class CustomerConsentService(BaseService):
TRANSACTION_TYPE = TransactionType.CUSTOMER_CONSENT
@staticmethod
def process_request(data):
"""
Process the CustomerConsent request.
Args:
data (dict): The request data.
Returns:
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')
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 ResponseHelper.error(result_description="Failed to log transaction.")
else:
return ResponseHelper.error(result_description="Invalid Customer or Account")
db.session.commit()
return ResponseHelper.success(result_description="Request is received")
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()
# from app.api.enums import TransactionType
# from app.extensions import db
#
#
# class CustomerConsentService(BaseService):
# TRANSACTION_TYPE = TransactionType.CUSTOMER_CONSENT
#
# @staticmethod
# def process_request(data):
# """
# Process the CustomerConsent request.
#
# Args:
# data (dict): The request data.
#
# Returns:
# 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')
#
# 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 ResponseHelper.error(result_description="Failed to log transaction.")
# else:
# return ResponseHelper.error(result_description="Invalid Customer or Account")
#
#
# db.session.commit()
# return ResponseHelper.success(result_description="Request is received")
#
# 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()
+2 -10
View File
@@ -2,7 +2,7 @@ from urllib import request
from flask import session, jsonify
from app.api.enums import SettingsItemsData
from app.api.enums import SettingsItemsData,KafkaMessage
from app.api.schemas.myproduct_set_template import MyProductSetTemplateSchema
from app.utils.logger import logger
from app.api.services.base_service import BaseService
@@ -279,15 +279,7 @@ class MyProductsService(BaseService):
# logger.info(f"Incoming MyProduct data ==>>>> {memberSubscription}")
productDataStatus = memberSubscription.status
product_subscription_uid = memberSubscription.uid
# product_subscription_external_url = memberSubscription.external_url
# product_subscription_internal_url = memberSubscription.internal_url
# result_data = {
# "myproudct": {
# "result": "Reveived under development ",
# "message": "to be fixed"
# }
# }
for key in settings.keys():
setting_value = settings[key]
@@ -303,7 +295,7 @@ class MyProductsService(BaseService):
}
logger.error(f"Going for Thread ******************** ")
thread = Thread(target=MyProductsService.async_send_settings_refresh_to_kafka,
args=(response_data, subscription_uid, "REFRESH_PRODUCT_SETTINGS"))
args=(response_data, subscription_uid, KafkaMessage.REFRESH_PRODUCT_SETTINGS))
thread.start()
logger.error(f"After the Thread ******************** ")