[update]: Select Offer
This commit is contained in:
@@ -5,6 +5,7 @@ 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
|
||||
from app.models import Offer
|
||||
|
||||
|
||||
class SelectOfferService(BaseService):
|
||||
@@ -28,6 +29,8 @@ class SelectOfferService(BaseService):
|
||||
)
|
||||
account_id = validated_data.get("accountId")
|
||||
customer_id = validated_data.get("customerId")
|
||||
amount = validated_data.get("amount")
|
||||
product_id = validated_data.get("productId")
|
||||
|
||||
if SelectOfferService.validate_account_ownership(
|
||||
account_id=account_id, customer_id=customer_id
|
||||
@@ -42,22 +45,67 @@ class SelectOfferService(BaseService):
|
||||
else:
|
||||
return jsonify({"message": "Invalid Customer or Account"}), 400
|
||||
|
||||
# Get the offer by product ID
|
||||
offer = Offer.get_offer_by_product_id(product_id)
|
||||
|
||||
if not offer:
|
||||
logger.error(f"Offer with product ID {product_id} not found")
|
||||
return jsonify({"message": "Offer not found"}), 404
|
||||
|
||||
# Get the loan charges for the offer
|
||||
loan_charges = offer.charges
|
||||
if not loan_charges:
|
||||
logger.error(f"No charges found for offer ID {offer.id}")
|
||||
return jsonify({"message": "No charges found for the offer"}), 404
|
||||
|
||||
# logger.error(f"{loan_charges}")
|
||||
|
||||
fees_and_dues = {
|
||||
charge.code: {
|
||||
"rate": charge.percent,
|
||||
"fee": amount * charge.percent / 100,
|
||||
"due_days": charge.due,
|
||||
}
|
||||
for charge in loan_charges
|
||||
}
|
||||
|
||||
|
||||
# Total amount (principal + all fees)
|
||||
total_amount = amount + sum(item["fee"] for item in fees_and_dues.values())
|
||||
|
||||
# Up-front payment: only those fees due immediately (due_days == 0)
|
||||
upfront_payment = sum(
|
||||
item["fee"]
|
||||
for item in fees_and_dues.values()
|
||||
if item["due_days"] == 0
|
||||
)
|
||||
|
||||
# Calculate the repayment dates
|
||||
tenor = offer.tenor
|
||||
start_date = date.today()
|
||||
|
||||
recommended_repayment_dates = [
|
||||
(start_date + relativedelta(months=i + 1)).isoformat()
|
||||
for i in range(tenor)
|
||||
]
|
||||
|
||||
|
||||
offers = [
|
||||
{
|
||||
"offerId": "SAL90",
|
||||
"productId": "2030",
|
||||
"amount": 10000.0,
|
||||
"upfrontPayment": 1000.0,
|
||||
"offerId": Offer.id,
|
||||
"productId": product_id,
|
||||
"amount": amount,
|
||||
"upfrontPayment": upfront_payment,
|
||||
"interestRate": 3.0,
|
||||
"managementRate": 1.0,
|
||||
"managementFee": 1.0,
|
||||
"insuranceRate": 1.0,
|
||||
"insuranceFee": 100.0,
|
||||
"VATRate": 7.5,
|
||||
"VATAmount": 100.0,
|
||||
"managementRate": fees_and_dues["management"]["rate"],
|
||||
"managementFee": fees_and_dues["management"]["fee"],
|
||||
"insuranceRate": fees_and_dues["insurance"]["rate"],
|
||||
"insuranceFee": fees_and_dues["insurance"]["fee"],
|
||||
"VATRate": fees_and_dues["VAT"]["rate"],
|
||||
"VATAmount": fees_and_dues["VAT"]["fee"],
|
||||
"recommendedRepaymentDates": ["2022-11-30"],
|
||||
"installmentAmount": 11000.0,
|
||||
"totalRepaymentAmount": 11000.0,
|
||||
"installmentAmount": recommended_repayment_dates,
|
||||
"totalRepaymentAmount": total_amount,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -40,6 +40,28 @@ class Offer(db.Model):
|
||||
if not offer:
|
||||
return False
|
||||
return offer
|
||||
|
||||
@classmethod
|
||||
def get_offer_by_id(cls, offer_id):
|
||||
"""
|
||||
Return an offer by its ID.
|
||||
"""
|
||||
offer = cls.query.filter_by(id=str(offer_id)).first()
|
||||
|
||||
if not offer:
|
||||
raise ValueError(f"Offer with ID {offer_id} not found")
|
||||
return offer
|
||||
|
||||
@classmethod
|
||||
def get_offer_by_product_id(cls, product_id):
|
||||
"""
|
||||
Return an offer by its product ID.
|
||||
"""
|
||||
offer = cls.query.filter_by(product_id=str(product_id)).first()
|
||||
|
||||
if not offer:
|
||||
raise ValueError(f"Offer with Product ID {product_id} not found")
|
||||
return offer
|
||||
|
||||
def to_dict(self):
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user