Custom templates fix
This commit is contained in:
+261
-261
@@ -1,261 +1,261 @@
|
||||
from datetime import datetime, timezone, timedelta
|
||||
from itertools import product
|
||||
from app.extensions import db
|
||||
from app.models.customer import Customer
|
||||
from app.models.account import Account
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
from sqlalchemy.orm import relationship
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from sqlalchemy import and_, or_, not_
|
||||
from sqlalchemy.sql import func
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Loan(db.Model):
|
||||
__tablename__ = 'loans'
|
||||
|
||||
id = db.Column(
|
||||
db.Integer,
|
||||
primary_key=True,
|
||||
autoincrement=True,
|
||||
)
|
||||
customer_id = db.Column(db.String(50), nullable=False)
|
||||
transaction_id = db.Column(db.String(50), nullable=True)
|
||||
original_transaction = db.Column(db.String(50), nullable=True)
|
||||
account_id = db.Column(db.String(50), nullable=False)
|
||||
offer_id = db.Column(db.String(20), nullable=False)
|
||||
product_id = db.Column(db.String(20), nullable=True)
|
||||
collection_type = db.Column(db.String(20), nullable=True)
|
||||
current_loan_amount = db.Column(db.Float, nullable=True)
|
||||
initial_loan_amount = db.Column(db.Float, nullable=False)
|
||||
default_penalty_fee = db.Column(db.Float, default=0)
|
||||
continuous_fee = db.Column(db.Float, default=0)
|
||||
upfront_fee = db.Column(db.Float, nullable=True, default=0.0)
|
||||
repayment_amount = db.Column(db.Float, nullable=True, default=0.0)
|
||||
installment_amount = db.Column(db.Float, nullable=True, default=0.0)
|
||||
status = db.Column(db.String(20), default='pending')
|
||||
tenor = db.Column(db.Integer, nullable=True)
|
||||
due_date = db.Column(db.DateTime, nullable=True)
|
||||
created_at = db.Column(db.DateTime(timezone=True), server_default=func.now())
|
||||
updated_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
eligible_amount = db.Column(db.Float, nullable=True, default=0.0)
|
||||
disburse_date = db.Column(db.DateTime, nullable=True)
|
||||
disburse_verify = db.Column(db.DateTime, nullable=True)
|
||||
reference = db.Column(db.String(50), nullable=True)
|
||||
disburse_result = db.Column(db.String(10), nullable=True)
|
||||
disburse_description = db.Column(db.String(100), nullable=True)
|
||||
verify_result = db.Column(db.String(10), nullable=True)
|
||||
verify_description = db.Column(db.String(100), nullable=True)
|
||||
|
||||
# customer = relationship(
|
||||
# "Customer",
|
||||
# primaryjoin="Customer.id == Loan.customer_id",
|
||||
# foreign_keys=[customer_id],
|
||||
# back_populates="loans",
|
||||
# )
|
||||
|
||||
loan_charges = relationship(
|
||||
"LoanCharge",
|
||||
primaryjoin="LoanCharge.loan_id == Loan.id",
|
||||
foreign_keys="LoanCharge.loan_id",
|
||||
back_populates="loan",
|
||||
)
|
||||
|
||||
loan_repayment_schedules = relationship(
|
||||
"LoanRepaymentSchedule",
|
||||
primaryjoin="LoanRepaymentSchedule.loan_id == Loan.id",
|
||||
foreign_keys="LoanRepaymentSchedule.loan_id",
|
||||
back_populates="loan",
|
||||
)
|
||||
|
||||
|
||||
@classmethod
|
||||
def create_loan(
|
||||
cls,
|
||||
customer_id,
|
||||
account_id,
|
||||
offer_id,
|
||||
product_id,
|
||||
initial_loan_amount,
|
||||
collection_type,
|
||||
transaction_id,
|
||||
original_transaction,
|
||||
upfront_fee,
|
||||
repayment_amount,
|
||||
installment_amount,
|
||||
tenor,
|
||||
eligible_amount,
|
||||
reference,
|
||||
status = "pending",
|
||||
):
|
||||
# Check if customer exists
|
||||
customer = Customer.is_valid_customer(customer_id)
|
||||
if not customer:
|
||||
raise ValueError("Customer does not exist")
|
||||
|
||||
now = datetime.now(timezone.utc)
|
||||
due_date = now + timedelta(days=tenor)
|
||||
|
||||
# Create and save the loan
|
||||
loan = cls(
|
||||
customer_id = customer_id,
|
||||
account_id = account_id,
|
||||
offer_id = offer_id,
|
||||
product_id = product_id,
|
||||
collection_type = collection_type,
|
||||
transaction_id = transaction_id,
|
||||
original_transaction = original_transaction,
|
||||
initial_loan_amount = initial_loan_amount,
|
||||
current_loan_amount = initial_loan_amount,
|
||||
upfront_fee = upfront_fee,
|
||||
repayment_amount = repayment_amount,
|
||||
installment_amount = installment_amount,
|
||||
due_date=due_date,
|
||||
tenor = tenor,
|
||||
status = status,
|
||||
eligible_amount =eligible_amount,
|
||||
reference = reference,
|
||||
created_at=datetime.now(timezone.utc),
|
||||
updated_at=datetime.now(timezone.utc)
|
||||
)
|
||||
|
||||
try:
|
||||
db.session.add(loan)
|
||||
except IntegrityError as err:
|
||||
raise ValueError(f"Database integrity error: {err}")
|
||||
return loan
|
||||
|
||||
@classmethod
|
||||
def has_active_loans(cls, customer_id):
|
||||
active_loans = cls.query.filter_by(
|
||||
customer_id=customer_id,
|
||||
status='active'
|
||||
).count()
|
||||
|
||||
if active_loans > 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_customer_loan(cls, loan_id, customer_id):
|
||||
"""
|
||||
Get customer's active loans by loan_id.
|
||||
"""
|
||||
loan = cls.query.filter_by(id = loan_id, customer_id = customer_id).first()
|
||||
if not loan:
|
||||
raise ValueError(f"Loan with ID {loan_id} does not exist or does not belong to customer {customer_id}.")
|
||||
return loan
|
||||
|
||||
@classmethod
|
||||
def get_customer_original_loan(cls, customer_id, original_transaction):
|
||||
"""
|
||||
Get customer's original loan offer.
|
||||
"""
|
||||
original_loan = cls.query.filter(and_( cls.customer_id ==customer_id, cls.original_transaction==original_transaction, cls.transaction_id==original_transaction )).first()
|
||||
if not original_loan:
|
||||
return None
|
||||
|
||||
logger.info(f" get_customer_original_loan ==>>>> {original_loan}")
|
||||
return original_loan
|
||||
|
||||
@classmethod
|
||||
def get_customer_last_loan(cls, customer_id):
|
||||
"""
|
||||
Get customer's active loans.
|
||||
"""
|
||||
logger.info(f"get_customer_last_loan [customer_id] ==>>>> {customer_id}")
|
||||
# loan = cls.query.filter_by( cls.customer_id == customer_id).first()
|
||||
loan = cls.query.filter(and_( cls.customer_id ==customer_id, cls.status=='active')).first()
|
||||
|
||||
if not loan:
|
||||
return None
|
||||
# loan = {
|
||||
# "original_transaction":"",
|
||||
# "eligible_amount": 0,
|
||||
# "loan_amount": 0,
|
||||
# "customer_id": customer_id,
|
||||
# "transaction_id": "",
|
||||
# "resultDescription": "No Active Loan"
|
||||
# }
|
||||
logger.info(f" get_customer_last_loan ==>>>> {loan}")
|
||||
return loan
|
||||
|
||||
@classmethod
|
||||
def get_active_loans_by_original_transaction(cls, original_transaction_id):
|
||||
"""
|
||||
Get all active loans with the same original_transaction ID.
|
||||
"""
|
||||
|
||||
active_loans = cls.query.filter_by(
|
||||
original_transaction=original_transaction_id,
|
||||
# status='active'
|
||||
).all()
|
||||
|
||||
return active_loans
|
||||
|
||||
|
||||
@classmethod
|
||||
def update_status(cls, loan_id, status):
|
||||
"""
|
||||
Update the status of the loan with the given loan_id.
|
||||
"""
|
||||
# Retrieve loan
|
||||
loan = cls.query.get(loan_id)
|
||||
|
||||
if not loan:
|
||||
raise ValueError(f"Loan with ID {loan_id} does not exist.")
|
||||
|
||||
if loan.status == status:
|
||||
return
|
||||
|
||||
# Update loan status and the updated_at timestamp
|
||||
loan.status = status
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_daily_loan_count(cls, customer_id, product_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,
|
||||
product_id=product_id,
|
||||
).filter(
|
||||
cls.created_at >= start_of_day,
|
||||
cls.created_at < end_of_day
|
||||
).count()
|
||||
|
||||
|
||||
def to_dict(self):
|
||||
"""
|
||||
Convert the Loan object to a dictionary format for JSON serialization.
|
||||
"""
|
||||
return {
|
||||
'debtId': self.id,
|
||||
'transactionId': self.transaction_id,
|
||||
'loanRef': self.reference,
|
||||
'productId': self.product_id,
|
||||
'initialLoanAmount': self.initial_loan_amount,
|
||||
'currentLoanAmount': self.current_loan_amount,
|
||||
'defaultPenaltyFee': self.default_penalty_fee,
|
||||
'continuousFee': self.continuous_fee,
|
||||
'collectionType': self.collection_type,
|
||||
'upfrontFee': self.upfront_fee,
|
||||
'repaymentAmount': self.repayment_amount,
|
||||
'installmentAmount': self.installment_amount,
|
||||
'status': self.status,
|
||||
'tenor': self.tenor,
|
||||
'dueDate': self.due_date.isoformat() if self.due_date else None,
|
||||
'loanDate': self.created_at.isoformat() if self.created_at else None,
|
||||
}
|
||||
|
||||
def __repr__(self):
|
||||
return f'<Loan {self.id}>'
|
||||
# from datetime import datetime, timezone, timedelta
|
||||
# from itertools import product
|
||||
# from app.extensions import db
|
||||
# from app.models.customer import Customer
|
||||
# from app.models.account import Account
|
||||
# from sqlalchemy.exc import IntegrityError
|
||||
# from sqlalchemy.orm import relationship
|
||||
# from dateutil.relativedelta import relativedelta
|
||||
# from datetime import timedelta
|
||||
# import logging
|
||||
# from sqlalchemy import and_, or_, not_
|
||||
# from sqlalchemy.sql import func
|
||||
#
|
||||
# logger = logging.getLogger(__name__)
|
||||
#
|
||||
#
|
||||
# class Loan(db.Model):
|
||||
# __tablename__ = 'loans'
|
||||
#
|
||||
# id = db.Column(
|
||||
# db.Integer,
|
||||
# primary_key=True,
|
||||
# autoincrement=True,
|
||||
# )
|
||||
# customer_id = db.Column(db.String(50), nullable=False)
|
||||
# transaction_id = db.Column(db.String(50), nullable=True)
|
||||
# original_transaction = db.Column(db.String(50), nullable=True)
|
||||
# account_id = db.Column(db.String(50), nullable=False)
|
||||
# offer_id = db.Column(db.String(20), nullable=False)
|
||||
# product_id = db.Column(db.String(20), nullable=True)
|
||||
# collection_type = db.Column(db.String(20), nullable=True)
|
||||
# current_loan_amount = db.Column(db.Float, nullable=True)
|
||||
# initial_loan_amount = db.Column(db.Float, nullable=False)
|
||||
# default_penalty_fee = db.Column(db.Float, default=0)
|
||||
# continuous_fee = db.Column(db.Float, default=0)
|
||||
# upfront_fee = db.Column(db.Float, nullable=True, default=0.0)
|
||||
# repayment_amount = db.Column(db.Float, nullable=True, default=0.0)
|
||||
# installment_amount = db.Column(db.Float, nullable=True, default=0.0)
|
||||
# status = db.Column(db.String(20), default='pending')
|
||||
# tenor = db.Column(db.Integer, nullable=True)
|
||||
# due_date = db.Column(db.DateTime, nullable=True)
|
||||
# created_at = db.Column(db.DateTime(timezone=True), server_default=func.now())
|
||||
# updated_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
|
||||
# eligible_amount = db.Column(db.Float, nullable=True, default=0.0)
|
||||
# disburse_date = db.Column(db.DateTime, nullable=True)
|
||||
# disburse_verify = db.Column(db.DateTime, nullable=True)
|
||||
# reference = db.Column(db.String(50), nullable=True)
|
||||
# disburse_result = db.Column(db.String(10), nullable=True)
|
||||
# disburse_description = db.Column(db.String(100), nullable=True)
|
||||
# verify_result = db.Column(db.String(10), nullable=True)
|
||||
# verify_description = db.Column(db.String(100), nullable=True)
|
||||
#
|
||||
# # customer = relationship(
|
||||
# # "Customer",
|
||||
# # primaryjoin="Customer.id == Loan.customer_id",
|
||||
# # foreign_keys=[customer_id],
|
||||
# # back_populates="loans",
|
||||
# # )
|
||||
#
|
||||
# loan_charges = relationship(
|
||||
# "LoanCharge",
|
||||
# primaryjoin="LoanCharge.loan_id == Loan.id",
|
||||
# foreign_keys="LoanCharge.loan_id",
|
||||
# back_populates="loan",
|
||||
# )
|
||||
#
|
||||
# loan_repayment_schedules = relationship(
|
||||
# "LoanRepaymentSchedule",
|
||||
# primaryjoin="LoanRepaymentSchedule.loan_id == Loan.id",
|
||||
# foreign_keys="LoanRepaymentSchedule.loan_id",
|
||||
# back_populates="loan",
|
||||
# )
|
||||
#
|
||||
#
|
||||
# @classmethod
|
||||
# def create_loan(
|
||||
# cls,
|
||||
# customer_id,
|
||||
# account_id,
|
||||
# offer_id,
|
||||
# product_id,
|
||||
# initial_loan_amount,
|
||||
# collection_type,
|
||||
# transaction_id,
|
||||
# original_transaction,
|
||||
# upfront_fee,
|
||||
# repayment_amount,
|
||||
# installment_amount,
|
||||
# tenor,
|
||||
# eligible_amount,
|
||||
# reference,
|
||||
# status = "pending",
|
||||
# ):
|
||||
# # Check if customer exists
|
||||
# customer = Customer.is_valid_customer(customer_id)
|
||||
# if not customer:
|
||||
# raise ValueError("Customer does not exist")
|
||||
#
|
||||
# now = datetime.now(timezone.utc)
|
||||
# due_date = now + timedelta(days=tenor)
|
||||
#
|
||||
# # Create and save the loan
|
||||
# loan = cls(
|
||||
# customer_id = customer_id,
|
||||
# account_id = account_id,
|
||||
# offer_id = offer_id,
|
||||
# product_id = product_id,
|
||||
# collection_type = collection_type,
|
||||
# transaction_id = transaction_id,
|
||||
# original_transaction = original_transaction,
|
||||
# initial_loan_amount = initial_loan_amount,
|
||||
# current_loan_amount = initial_loan_amount,
|
||||
# upfront_fee = upfront_fee,
|
||||
# repayment_amount = repayment_amount,
|
||||
# installment_amount = installment_amount,
|
||||
# due_date=due_date,
|
||||
# tenor = tenor,
|
||||
# status = status,
|
||||
# eligible_amount =eligible_amount,
|
||||
# reference = reference,
|
||||
# created_at=datetime.now(timezone.utc),
|
||||
# updated_at=datetime.now(timezone.utc)
|
||||
# )
|
||||
#
|
||||
# try:
|
||||
# db.session.add(loan)
|
||||
# except IntegrityError as err:
|
||||
# raise ValueError(f"Database integrity error: {err}")
|
||||
# return loan
|
||||
#
|
||||
# @classmethod
|
||||
# def has_active_loans(cls, customer_id):
|
||||
# active_loans = cls.query.filter_by(
|
||||
# customer_id=customer_id,
|
||||
# status='active'
|
||||
# ).count()
|
||||
#
|
||||
# if active_loans > 0:
|
||||
# return False
|
||||
# return True
|
||||
#
|
||||
#
|
||||
# @classmethod
|
||||
# def get_customer_loan(cls, loan_id, customer_id):
|
||||
# """
|
||||
# Get customer's active loans by loan_id.
|
||||
# """
|
||||
# loan = cls.query.filter_by(id = loan_id, customer_id = customer_id).first()
|
||||
# if not loan:
|
||||
# raise ValueError(f"Loan with ID {loan_id} does not exist or does not belong to customer {customer_id}.")
|
||||
# return loan
|
||||
#
|
||||
# @classmethod
|
||||
# def get_customer_original_loan(cls, customer_id, original_transaction):
|
||||
# """
|
||||
# Get customer's original loan offer.
|
||||
# """
|
||||
# original_loan = cls.query.filter(and_( cls.customer_id ==customer_id, cls.original_transaction==original_transaction, cls.transaction_id==original_transaction )).first()
|
||||
# if not original_loan:
|
||||
# return None
|
||||
#
|
||||
# logger.info(f" get_customer_original_loan ==>>>> {original_loan}")
|
||||
# return original_loan
|
||||
#
|
||||
# @classmethod
|
||||
# def get_customer_last_loan(cls, customer_id):
|
||||
# """
|
||||
# Get customer's active loans.
|
||||
# """
|
||||
# logger.info(f"get_customer_last_loan [customer_id] ==>>>> {customer_id}")
|
||||
# # loan = cls.query.filter_by( cls.customer_id == customer_id).first()
|
||||
# loan = cls.query.filter(and_( cls.customer_id ==customer_id, cls.status=='active')).first()
|
||||
#
|
||||
# if not loan:
|
||||
# return None
|
||||
# # loan = {
|
||||
# # "original_transaction":"",
|
||||
# # "eligible_amount": 0,
|
||||
# # "loan_amount": 0,
|
||||
# # "customer_id": customer_id,
|
||||
# # "transaction_id": "",
|
||||
# # "resultDescription": "No Active Loan"
|
||||
# # }
|
||||
# logger.info(f" get_customer_last_loan ==>>>> {loan}")
|
||||
# return loan
|
||||
#
|
||||
# @classmethod
|
||||
# def get_active_loans_by_original_transaction(cls, original_transaction_id):
|
||||
# """
|
||||
# Get all active loans with the same original_transaction ID.
|
||||
# """
|
||||
#
|
||||
# active_loans = cls.query.filter_by(
|
||||
# original_transaction=original_transaction_id,
|
||||
# # status='active'
|
||||
# ).all()
|
||||
#
|
||||
# return active_loans
|
||||
#
|
||||
#
|
||||
# @classmethod
|
||||
# def update_status(cls, loan_id, status):
|
||||
# """
|
||||
# Update the status of the loan with the given loan_id.
|
||||
# """
|
||||
# # Retrieve loan
|
||||
# loan = cls.query.get(loan_id)
|
||||
#
|
||||
# if not loan:
|
||||
# raise ValueError(f"Loan with ID {loan_id} does not exist.")
|
||||
#
|
||||
# if loan.status == status:
|
||||
# return
|
||||
#
|
||||
# # Update loan status and the updated_at timestamp
|
||||
# loan.status = status
|
||||
#
|
||||
#
|
||||
# @classmethod
|
||||
# def get_daily_loan_count(cls, customer_id, product_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,
|
||||
# product_id=product_id,
|
||||
# ).filter(
|
||||
# cls.created_at >= start_of_day,
|
||||
# cls.created_at < end_of_day
|
||||
# ).count()
|
||||
#
|
||||
#
|
||||
# def to_dict(self):
|
||||
# """
|
||||
# Convert the Loan object to a dictionary format for JSON serialization.
|
||||
# """
|
||||
# return {
|
||||
# 'debtId': self.id,
|
||||
# 'transactionId': self.transaction_id,
|
||||
# 'loanRef': self.reference,
|
||||
# 'productId': self.product_id,
|
||||
# 'initialLoanAmount': self.initial_loan_amount,
|
||||
# 'currentLoanAmount': self.current_loan_amount,
|
||||
# 'defaultPenaltyFee': self.default_penalty_fee,
|
||||
# 'continuousFee': self.continuous_fee,
|
||||
# 'collectionType': self.collection_type,
|
||||
# 'upfrontFee': self.upfront_fee,
|
||||
# 'repaymentAmount': self.repayment_amount,
|
||||
# 'installmentAmount': self.installment_amount,
|
||||
# 'status': self.status,
|
||||
# 'tenor': self.tenor,
|
||||
# 'dueDate': self.due_date.isoformat() if self.due_date else None,
|
||||
# 'loanDate': self.created_at.isoformat() if self.created_at else None,
|
||||
# }
|
||||
#
|
||||
# def __repr__(self):
|
||||
# return f'<Loan {self.id}>'
|
||||
Reference in New Issue
Block a user