diff --git a/app/api/services/select_offer.py b/app/api/services/select_offer.py index 6f70aeb..46ab444 100644 --- a/app/api/services/select_offer.py +++ b/app/api/services/select_offer.py @@ -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, } ] diff --git a/app/models/offer.py b/app/models/offer.py index b51dc25..a2009e7 100644 --- a/app/models/offer.py +++ b/app/models/offer.py @@ -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 {