[update]: Offers

This commit was merged in pull request #34.
This commit is contained in:
VivianDee
2025-05-19 14:37:19 +01:00
parent 89760f81ed
commit 31b0367e6a
12 changed files with 116 additions and 14 deletions
+38 -2
View File
@@ -1,4 +1,5 @@
from flask import session, jsonify
from app.models.loan import Loan
from app.models.transaction_offers import TransactionOffer
from app.utils.logger import logger
from app.api.services.base_service import BaseService
@@ -50,6 +51,12 @@ class EligibilityCheckService(BaseService):
return ResponseHelper.error(result_description="Invalid Customer or Account")
db.session.flush()
# Determine Loan count
is_eligible = EligibilityCheckService.check_loan_limits(customer_id)
if not is_eligible:
return ResponseHelper.error(result_description="Max loan count reached")
# Call RACCheck
response = SimbrellaIntegration.rac_check(
@@ -58,7 +65,7 @@ class EligibilityCheckService(BaseService):
transaction_id = transaction.transaction_id,
)
# this chck for error is not valid
# this chek for error is not valid
if response.status_code != 200:
return ResponseHelper.error(result_description="RACCheck failed")
@@ -146,4 +153,33 @@ class EligibilityCheckService(BaseService):
except Exception as e:
logger.error(f"An error occurred: {str(e)}", exc_info=True)
db.session.rollback()
return ResponseHelper.internal_server_error()
return ResponseHelper.internal_server_error()
@staticmethod
def check_loan_limits(customer_id):
"""
Checks if a customer has exceeded the loan limits for given offer.
"""
loan = Loan.get_customer_last_loan(customer_id)
if not loan:
return True
offer_id = loan.offer_id[:5]
offer = Offer.get_offer_by_id(offer_id)
if not offer:
logger.error(f"Offer not found for offer_id: {offer_id} (customer_id: {customer_id})")
return False
daily_count = TransactionOffer.get_daily_loan_count(customer_id, offer_id)
logger.error(f"daily_count: {daily_count}, Max: {offer.max_daily_loans}")
if offer.max_daily_loans is not None and daily_count >= offer.max_daily_loans:
return False
return True
+3 -1
View File
@@ -27,7 +27,9 @@ class Account(db.Model):
account = cls(
id=id,
customer_id=customer_id,
account_type=account_type
account_type=account_type,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
try:
+3 -1
View File
@@ -57,7 +57,9 @@ class Charge(db.Model):
code = code,
percent = percent,
description = description,
due = due_days
due = due_days,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
db.session.add(charge_obj)
+7 -1
View File
@@ -47,7 +47,13 @@ class Customer(db.Model):
raise ValueError("Customer already exists")
# Create the customer
customer = cls(id=id, msisdn=msisdn, country_code=country_code)
customer = cls(
id=id,
msisdn=msisdn,
country_code=country_code,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
try:
db.session.add(customer)
+3 -1
View File
@@ -109,7 +109,9 @@ class Loan(db.Model):
due_date=due_date,
tenor = tenor,
status = status,
eligible_amount =eligible_amount
eligible_amount =eligible_amount,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
try:
+3 -1
View File
@@ -63,7 +63,9 @@ class LoanCharge(db.Model):
percent = percent,
description = description,
due = due_days,
due_date = now + timedelta(days=due_days)
due_date = now + timedelta(days=due_days),
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
db.session.add(charge_obj)
+3 -1
View File
@@ -45,7 +45,9 @@ class LoanRepaymentSchedule(db.Model):
total_repayment_amount = round(loan.repayment_amount, 2),
installment_amount=round(loan.installment_amount, 2),
product_id = loan.product_id,
transaction_id = transaction_id
transaction_id = transaction_id,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
db.session.add(schedule)
+5 -1
View File
@@ -83,7 +83,11 @@ class Offer(db.Model):
"interest_rate": self.interest_rate,
"management_rate": self.management_rate,
"insurance_rate": self.insurance_rate,
"vat_rate": self.vat_rate
"vat_rate": self.vat_rate,
"maxDailyLoans": self.max_daily_loans,
"maxActiveLoans": self.max_active_loans,
"maxLifeLoans": self.max_life_loans
}
def __repr__(self):
+3 -1
View File
@@ -25,7 +25,9 @@ class RACCheck(db.Model):
customer_id = customer_id,
account_id = account_id,
transaction_id = transaction_id,
rac_response = data
rac_response = data,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
try:
+3 -1
View File
@@ -42,7 +42,9 @@ class Repayment(db.Model):
customer_id=customer_id,
loan_id=loan_id,
product_id=product_id,
transaction_id = transaction_id
transaction_id = transaction_id,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
try:
+3 -1
View File
@@ -38,7 +38,9 @@ class Transaction(db.Model):
customer_id = customer_id,
account_id = account_id,
type = type,
channel = channel
channel = channel,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
try:
+42 -2
View File
@@ -1,4 +1,5 @@
from datetime import datetime, timezone
from datetime import datetime, timezone, timedelta
from app.api.enums.loan_status import LoanStatus
from app.extensions import db
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
@@ -58,7 +59,9 @@ class TransactionOffer(db.Model):
max_amount=max_amount,
eligible_amount=eligible_amount,
product_id=product_id,
tenor=tenor
tenor=tenor,
created_at=datetime.now(timezone.utc),
updated_at=datetime.now(timezone.utc)
)
db.session.add(transaction_offer)
@@ -66,6 +69,43 @@ class TransactionOffer(db.Model):
return transaction_offer
@classmethod
def get_lifetime_loan_count(cls, customer_id):
"""
Returns the total number of loans ever created for a customer.
"""
return cls.query.filter_by(customer_id=customer_id).count()
@classmethod
def get_daily_loan_count(cls, customer_id, offer_id):
"""
Returns the count of loans created today for a customer.
"""
start_of_day = datetime.now(timezone.utc).replace(hour=0, minute=0, second=0, microsecond=0)
end_of_day = start_of_day + timedelta(days=1)
return cls.query.filter_by(
customer_id=customer_id,
offer_id=offer_id
).filter(
cls.created_at >= start_of_day,
cls.created_at < end_of_day
).count()
@classmethod
def get_latest_transaction_offer(cls, customer_id):
"""
Returns the most recent transaction offer for the given customer based on creation time.
"""
return cls.query.filter_by(customer_id=customer_id) \
.order_by(cls.created_at.desc()) \
.first()
def to_dict(self):
return {
'id': self.id,