Merge branch 'loan_repayment_event' of DigiFi/digifi-BankToProductCore into master

This commit is contained in:
2025-04-14 20:05:16 +00:00
committed by Gogs
9 changed files with 90 additions and 30 deletions
+1
View File
@@ -3,6 +3,7 @@ from marshmallow import Schema, fields
# Loan Information Schema # Loan Information Schema
class LoanStatusSchema(Schema): class LoanStatusSchema(Schema):
transactionId = fields.Str(required=True) transactionId = fields.Str(required=True)
accountId = fields.Str(required=True)
customerId = fields.Str(required=True) customerId = fields.Str(required=True)
msisdn = fields.Str(required=False) msisdn = fields.Str(required=False)
channel = fields.Str(required=True) channel = fields.Str(required=True)
+1
View File
@@ -7,5 +7,6 @@ class RepaymentSchema(Schema):
debtId = fields.Str(required=True) debtId = fields.Str(required=True)
productId = fields.Str(required=True) productId = fields.Str(required=True)
transactionId = fields.Str(required=True) transactionId = fields.Str(required=True)
accountId = fields.Str(required=True)
customerId = fields.Str(required=True) customerId = fields.Str(required=True)
channel = fields.Str(required=True) channel = fields.Str(required=True)
+1
View File
@@ -50,6 +50,7 @@ class BaseService:
""" """
return Transaction.create_transaction( return Transaction.create_transaction(
transaction_id = validated_data.get("transactionId"), transaction_id = validated_data.get("transactionId"),
customer_id = validated_data.get('customerId', None),
account_id = validated_data.get("accountId", None), account_id = validated_data.get("accountId", None),
type = cls.TRANSACTION_TYPE, type = cls.TRANSACTION_TYPE,
channel = validated_data.get("channel"), channel = validated_data.get("channel"),
+14 -7
View File
@@ -32,17 +32,24 @@ class LoanStatusService(BaseService):
customer_id = validated_data.get('customerId') customer_id = validated_data.get('customerId')
customer = Customer.get_customer(customer_id) customer = Customer.get_customer(customer_id)
transactionId = validated_data.get('transactionId') transactionId = validated_data.get('transactionId')
account_id = validated_data.get('accountId')
# Get loans if(LoanStatusService.validate_account_ownership(account_id = account_id, customer_id = customer_id)):
loans = [loan.to_dict() for loan in customer.loans if loan.status == LoanStatus.ACTIVE]
transaction = LoanStatusService.log_transaction(validated_data = validated_data) # Get loans
loans = [loan.to_dict() for loan in customer.loans if loan.status == LoanStatus.ACTIVE]
if not transaction: transaction = LoanStatusService.log_transaction(validated_data = validated_data)
logger.error(f"Failed to log transaction")
if not transaction:
logger.error(f"Failed to log transaction")
return jsonify({
"message": "Failed to log transaction."
}), 400
else:
return jsonify({ return jsonify({
"message": "Failed to log transaction." "message": "Invalid Customer or Account"
}), 400 }), 400
# loans = [ # loans = [
+30 -22
View File
@@ -2,6 +2,7 @@ from flask import request, jsonify
from marshmallow import ValidationError from marshmallow import ValidationError
from app.api.enums.loan_status import LoanStatus from app.api.enums.loan_status import LoanStatus
from app.models import Repayment from app.models import Repayment
from app.models.customer import Customer
from app.models.loan import Loan from app.models.loan import Loan
from app.utils.logger import logger from app.utils.logger import logger
from app.api.schemas.repayment import RepaymentSchema from app.api.schemas.repayment import RepaymentSchema
@@ -31,35 +32,42 @@ class RepaymentService(BaseService):
request_id = validated_data.get('requestId') request_id = validated_data.get('requestId')
loan_id = validated_data.get('debtId') loan_id = validated_data.get('debtId')
product_id = validated_data.get('productId') product_id = validated_data.get('productId')
account_id = validated_data.get('accountId')
customer = Customer.get_customer(customer_id)
if(RepaymentService.validate_account_ownership(account_id = account_id, customer_id = customer_id)):
# Save the repayment details
repayment = Repayment.create_repayment(
customer_id = customer_id,
loan_id = loan_id,
product_id = product_id
)
if not repayment:
logger.error(f"Failed to save repayment details")
return jsonify({
"message": "Failed to save repayment details."
}), 400
#Update Loan status
Loan.update_status(loan_id = loan_id, status = LoanStatus.REPAID)
# Save the repayment details transaction = RepaymentService.log_transaction(validated_data = validated_data)
repayment = Repayment.create_repayment(
customer_id = customer_id,
loan_id = loan_id,
product_id = product_id
) if not transaction:
logger.error(f"Failed to log transaction")
if not repayment: return jsonify({
logger.error(f"Failed to save repayment details") "message": "Failed to log transaction."
}), 400
else:
return jsonify({ return jsonify({
"message": "Failed to save repayment details." "message": "Invalid Customer or Account"
}), 400 }), 400
#Update Loan status
Loan.update_status(loan_id = loan_id, status = LoanStatus.REPAID)
transaction = RepaymentService.log_transaction(validated_data = validated_data)
if not transaction:
logger.error(f"Failed to log transaction")
return jsonify({
"message": "Failed to log transaction."
}), 400
# Simulated processing logic # Simulated processing logic
response_data = { response_data = {
+3 -1
View File
@@ -13,6 +13,7 @@ class Transaction(db.Model):
) )
transaction_id = db.Column(db.String(50), nullable=False) transaction_id = db.Column(db.String(50), nullable=False)
account_id = db.Column(db.String(50), nullable=True) account_id = db.Column(db.String(50), nullable=True)
customer_id = db.Column(db.String(50), nullable=True)
type = db.Column(db.String(50), nullable=False) type = db.Column(db.String(50), nullable=False)
channel = db.Column(db.String(50), nullable=False) channel = db.Column(db.String(50), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.now(timezone.utc)) created_at = db.Column(db.DateTime, default=datetime.now(timezone.utc))
@@ -22,7 +23,7 @@ class Transaction(db.Model):
return f'<Transaction {self.id}>' return f'<Transaction {self.id}>'
@classmethod @classmethod
def create_transaction(cls, transaction_id, account_id, type, channel): def create_transaction(cls, transaction_id, account_id, customer_id, type, channel):
# if cls.query.filter_by(transaction_id=transaction_id).first(): # if cls.query.filter_by(transaction_id=transaction_id).first():
# raise ValueError("Duplicate Transaction") # raise ValueError("Duplicate Transaction")
@@ -34,6 +35,7 @@ class Transaction(db.Model):
transaction = cls( transaction = cls(
transaction_id = transaction_id, transaction_id = transaction_id,
customer_id = customer_id,
account_id = account_id, account_id = account_id,
type = type, type = type,
channel = channel channel = channel
@@ -16,6 +16,10 @@
"channel": { "channel": {
"type": "string", "type": "string",
"example": "USSD" "example": "USSD"
},
"accountId": {
"type": "string",
"example": "ACN8263457"
} }
}, },
"xml": { "xml": {
@@ -24,6 +24,10 @@
"channel": { "channel": {
"type": "string", "type": "string",
"example": "USSD" "example": "USSD"
},
"accountId": {
"type": "string",
"example": "ACN8263457"
} }
}, },
"xml": { "xml": {
@@ -0,0 +1,32 @@
"""Migration on Mon Apr 14 15:15:05 UTC 2025
Revision ID: 783a023a477f
Revises: f6cd1bfc8832
Create Date: 2025-04-14 15:15:36.991148
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '783a023a477f'
down_revision = 'f6cd1bfc8832'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('transactions', schema=None) as batch_op:
batch_op.add_column(sa.Column('customer_id', sa.String(length=50), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('transactions', schema=None) as batch_op:
batch_op.drop_column('customer_id')
# ### end Alembic commands ###