From 482a860bd2d50adb2cc6eb2cf076f6ec50d17fdd Mon Sep 17 00:00:00 2001 From: VivianDee <115420678+VivianDee@users.noreply.github.com> Date: Mon, 14 Apr 2025 15:26:46 +0100 Subject: [PATCH 1/2] [add]: account_id to loan status and repayment --- app/api/services/loan_status.py | 21 ++++++--- app/api/services/repayment.py | 52 +++++++++++++--------- app/swagger/schemas/LoanStatusRequest.json | 4 ++ app/swagger/schemas/RepaymentRequest.json | 4 ++ 4 files changed, 52 insertions(+), 29 deletions(-) diff --git a/app/api/services/loan_status.py b/app/api/services/loan_status.py index 6a2c01a..55de9b8 100644 --- a/app/api/services/loan_status.py +++ b/app/api/services/loan_status.py @@ -32,17 +32,24 @@ class LoanStatusService(BaseService): customer_id = validated_data.get('customerId') customer = Customer.get_customer(customer_id) transactionId = validated_data.get('transactionId') + account_id = validated_data.get('accountId') - # Get loans - loans = [loan.to_dict() for loan in customer.loans if loan.status == LoanStatus.ACTIVE] + if(LoanStatusService.validate_account_ownership(account_id = account_id, customer_id = customer_id)): - 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: - logger.error(f"Failed to log transaction") + transaction = LoanStatusService.log_transaction(validated_data = validated_data) + + if not transaction: + logger.error(f"Failed to log transaction") + return jsonify({ + "message": "Failed to log transaction." + }), 400 + else: return jsonify({ - "message": "Failed to log transaction." - }), 400 + "message": "Invalid Customer or Account" + }), 400 # loans = [ diff --git a/app/api/services/repayment.py b/app/api/services/repayment.py index 4d400db..dac4fb0 100644 --- a/app/api/services/repayment.py +++ b/app/api/services/repayment.py @@ -2,6 +2,7 @@ from flask import request, jsonify from marshmallow import ValidationError from app.api.enums.loan_status import LoanStatus from app.models import Repayment +from app.models.customer import Customer from app.models.loan import Loan from app.utils.logger import logger from app.api.schemas.repayment import RepaymentSchema @@ -31,34 +32,41 @@ class RepaymentService(BaseService): request_id = validated_data.get('requestId') loan_id = validated_data.get('debtId') product_id = validated_data.get('productId') - - + account_id = validated_data.get('accountId') + customer = Customer.get_customer(customer_id) - # Save the repayment details - repayment = Repayment.create_repayment( - customer_id = customer_id, - loan_id = loan_id, - product_id = product_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 - + ) + + 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) - - transaction = RepaymentService.log_transaction(validated_data = validated_data) + + #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") + if not transaction: + logger.error(f"Failed to log transaction") + return jsonify({ + "message": "Failed to log transaction." + }), 400 + else: return jsonify({ - "message": "Failed to log transaction." - }), 400 + "message": "Invalid Customer or Account" + }), 400 + # Simulated processing logic diff --git a/app/swagger/schemas/LoanStatusRequest.json b/app/swagger/schemas/LoanStatusRequest.json index 0252f26..43adf6b 100644 --- a/app/swagger/schemas/LoanStatusRequest.json +++ b/app/swagger/schemas/LoanStatusRequest.json @@ -16,6 +16,10 @@ "channel": { "type": "string", "example": "USSD" + }, + "accountId": { + "type": "string", + "example": "ACN8263457" } }, "xml": { diff --git a/app/swagger/schemas/RepaymentRequest.json b/app/swagger/schemas/RepaymentRequest.json index c31d585..9543f74 100644 --- a/app/swagger/schemas/RepaymentRequest.json +++ b/app/swagger/schemas/RepaymentRequest.json @@ -24,6 +24,10 @@ "channel": { "type": "string", "example": "USSD" + }, + "accountId": { + "type": "string", + "example": "ACN8263457" } }, "xml": { From a6e7eaac3cea7e1036deb9963fba586a17323609 Mon Sep 17 00:00:00 2001 From: VivianDee <115420678+VivianDee@users.noreply.github.com> Date: Mon, 14 Apr 2025 21:04:17 +0100 Subject: [PATCH 2/2] [add]: accountId on loan and repayment --- app/api/schemas/loan_status.py | 1 + app/api/schemas/repayment.py | 1 + app/api/services/base_service.py | 1 + app/models/transaction.py | 4 ++- ...f_migration_on_mon_apr_14_15_15_05_utc_.py | 32 +++++++++++++++++++ 5 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 migrations/versions/783a023a477f_migration_on_mon_apr_14_15_15_05_utc_.py diff --git a/app/api/schemas/loan_status.py b/app/api/schemas/loan_status.py index 7599d5f..3899223 100644 --- a/app/api/schemas/loan_status.py +++ b/app/api/schemas/loan_status.py @@ -3,6 +3,7 @@ from marshmallow import Schema, fields # Loan Information Schema class LoanStatusSchema(Schema): transactionId = fields.Str(required=True) + accountId = fields.Str(required=True) customerId = fields.Str(required=True) msisdn = fields.Str(required=False) channel = fields.Str(required=True) \ No newline at end of file diff --git a/app/api/schemas/repayment.py b/app/api/schemas/repayment.py index 2d05321..0a393b9 100644 --- a/app/api/schemas/repayment.py +++ b/app/api/schemas/repayment.py @@ -7,5 +7,6 @@ class RepaymentSchema(Schema): debtId = fields.Str(required=True) productId = fields.Str(required=True) transactionId = fields.Str(required=True) + accountId = fields.Str(required=True) customerId = fields.Str(required=True) channel = fields.Str(required=True) diff --git a/app/api/services/base_service.py b/app/api/services/base_service.py index 4382181..a9532af 100644 --- a/app/api/services/base_service.py +++ b/app/api/services/base_service.py @@ -50,6 +50,7 @@ class BaseService: """ return Transaction.create_transaction( transaction_id = validated_data.get("transactionId"), + customer_id = validated_data.get('customerId', None), account_id = validated_data.get("accountId", None), type = cls.TRANSACTION_TYPE, channel = validated_data.get("channel"), diff --git a/app/models/transaction.py b/app/models/transaction.py index 9b18479..27fa8ae 100644 --- a/app/models/transaction.py +++ b/app/models/transaction.py @@ -13,6 +13,7 @@ class Transaction(db.Model): ) transaction_id = db.Column(db.String(50), nullable=False) 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) channel = db.Column(db.String(50), nullable=False) created_at = db.Column(db.DateTime, default=datetime.now(timezone.utc)) @@ -22,7 +23,7 @@ class Transaction(db.Model): return f'' @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(): # raise ValueError("Duplicate Transaction") @@ -34,6 +35,7 @@ class Transaction(db.Model): transaction = cls( transaction_id = transaction_id, + customer_id = customer_id, account_id = account_id, type = type, channel = channel diff --git a/migrations/versions/783a023a477f_migration_on_mon_apr_14_15_15_05_utc_.py b/migrations/versions/783a023a477f_migration_on_mon_apr_14_15_15_05_utc_.py new file mode 100644 index 0000000..7308758 --- /dev/null +++ b/migrations/versions/783a023a477f_migration_on_mon_apr_14_15_15_05_utc_.py @@ -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 ###