diff --git a/app/api/routes/routes.py b/app/api/routes/routes.py index 2bf06c5..a18a62a 100644 --- a/app/api/routes/routes.py +++ b/app/api/routes/routes.py @@ -42,10 +42,10 @@ def swagger_json(): return send_from_directory(swagger_dir, "digifi_swagger.json") -# @api.route("/swagger/") -# def serve_paths(filename): -# swagger_dir = os.path.join("swagger") -# return send_from_directory(swagger_dir, filename) +@api.route("/swagger/") +def serve_paths(filename): + swagger_dir = os.path.join("swagger") + return send_from_directory(swagger_dir, filename) # EligibilityCheck Endpoint diff --git a/app/api/services/provide_loan.py b/app/api/services/provide_loan.py index 86c0fe7..2a4615f 100644 --- a/app/api/services/provide_loan.py +++ b/app/api/services/provide_loan.py @@ -17,6 +17,7 @@ from app.api.integrations import EventServiceIntegration from app.models import LoanRepaymentSchedule from app.api.services.offer_analysis import OfferAnalysis from app.api.helpers.response_helper import ResponseHelper +from datetime import datetime, timezone, timedelta class ProvideLoanService(BaseService): TRANSACTION_TYPE = TransactionType.PROVIDE_LOAN @@ -162,16 +163,14 @@ class ProvideLoanService(BaseService): else: return ResponseHelper.error(result_description="Invalid Customer or Account") - charge_schedule_items = [] - for idx, charge in enumerate(loan_charges, start=len(charge_schedule_items) + 1): - charge_schedule_items.append({ - "id": idx, - "dueDate": charge.due_date.isoformat(), - "amountDue": float(charge.amount), - "componentName": charge.code.upper(), # e.g. INTEREST, MGMT_FEE, VAT_FEE - "startDate": charge.created_at.isoformat(), - }) - + + charge_schedule_items = ProvideLoanService.get_charge_schedule_items( + loan_charges=loan_charges, + offer=offer, + loan_ref=loan_ref, + amount=amount + ) + response_data = { "requestId": request_id, "transactionId": transaction_id, @@ -215,4 +214,35 @@ class ProvideLoanService(BaseService): response = EventServiceIntegration.direct_loan(transaction_id=transaction_id) return response - + @classmethod + def get_charge_schedule_items(cls, loan_charges, offer, loan_ref, amount): + now = datetime.now(timezone.utc) + due_date = now + timedelta(days=offer.tenor) + + charge_schedule_items = [] + + charge_schedule_items.append({ + "id": 1, + "dueDate": due_date.isoformat(), + "amountDue": amount, + "componentName": "PRINCIPAL", + "startDate": now.isoformat(), + }) + + for idx, charge in enumerate(loan_charges, start=len(charge_schedule_items) + 1): + item = { + "id": idx, + "dueDate": charge.due_date.isoformat(), + "amountDue": float(charge.amount), + "componentName": charge.code.upper(), # e.g. INTEREST, MGMT_FEE, VAT_FEE + "startDate": charge.created_at.isoformat(), + } + + if charge.code.upper() == "INTEREST": + item["loanRef"] = loan_ref + + charge_schedule_items.append(item) + + return charge_schedule_items + + diff --git a/app/swagger/schemas/ProvideLoanResponse.json b/app/swagger/schemas/ProvideLoanResponse.json index c4c688e..c9891fe 100644 --- a/app/swagger/schemas/ProvideLoanResponse.json +++ b/app/swagger/schemas/ProvideLoanResponse.json @@ -25,6 +25,41 @@ "type": "string", "example": "98016510058" }, + "schedule": { + "type": "array", + "description": "List of loan repayment components with due dates and amounts.", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "example": 1 + }, + "amountDue": { + "type": "number", + "example": 2000.0 + }, + "componentName": { + "type": "string", + "example": "INTEREST" + }, + "dueDate": { + "type": "string", + "format": "date-time", + "example": "2026-01-13T11:36:39.890747+00:00" + }, + "startDate": { + "type": "string", + "format": "date-time", + "example": "2025-10-15T11:36:39.890747+00:00" + }, + "loanRef": { + "type": "string", + "example": "TRX1760528156816285USSD3MPC" + } + } + } + }, "resultCode": { "type": "string", "example": "00"