diff --git a/app/api/routes/routes.py b/app/api/routes/routes.py index 0c6cc01..e0e15ad 100644 --- a/app/api/routes/routes.py +++ b/app/api/routes/routes.py @@ -14,7 +14,8 @@ from app.api.services import ( AuthorizationService, MyProductsService, ContactService, - OfficeAuthService + OfficeAuthService, + OfficeDashboardService ) from app.utils.logger import logger from app.api.middlewares import enforce_json, require_auth @@ -219,6 +220,13 @@ def login(): return jsonify(result[0]), result[1] return jsonify(result) + +@api.route('/office/dashboard', methods=['GET']) +# @token_required +def get_dashboard(): + # Call the dashboard service + result = OfficeDashboardService.get_dashboard_data() + return jsonify(result) #===================================================== # # EligibilityCheck Endpoint diff --git a/app/api/services/__init__.py b/app/api/services/__init__.py index e57341e..40753c5 100644 --- a/app/api/services/__init__.py +++ b/app/api/services/__init__.py @@ -14,3 +14,5 @@ from app.api.services.account import AccountService from app.api.services.myproduct import MyProductsService from app.api.services.contacts import ContactService from app.api.services.office_auth import OfficeAuthService +from app.api.services.office_dashboard import OfficeDashboardService + diff --git a/app/api/services/office_dashboard.py b/app/api/services/office_dashboard.py new file mode 100644 index 0000000..433f432 --- /dev/null +++ b/app/api/services/office_dashboard.py @@ -0,0 +1,275 @@ +from flask import jsonify +from app.utils.logger import logger +from app.api.services.base_service import BaseService +from app.models.transaction import Transaction +from app.models.loan import Loan +from sqlalchemy import func, desc +from datetime import datetime, timedelta, timezone +from app.extensions import db +from app.api.enums.transaction_type import TransactionType + + +class OfficeDashboardService(BaseService): + @staticmethod + def get_dashboard_data(): + try: + # now = datetime.now() + # start_of_week = now - timedelta(days=now.weekday()) + # start_of_week = start_of_week.replace(hour=0, minute=0, second=0, microsecond=0) + # + # # Calculate 24 hours ago + # last_24_hours = datetime.now(timezone.utc) - timedelta(hours=24) + # + # # Loans this week + # loans_this_week = db.session.query( + # func.sum(Loan.initial_loan_amount) + # ).filter( + # Loan.created_at >= start_of_week + # ).scalar() or 0 + # + # # Payments this week + # payments_this_week = db.session.query( + # func.count(Transaction.id) + # ).filter( + # Transaction.created_at >= start_of_week, + # Transaction.type == 'PAYMENT' + # ).scalar() or 0 + # + # # Request summary for the last 24 hours + # eligibility_check_count = db.session.query( + # func.count(Transaction.id) + # ).filter( + # Transaction.type == TransactionType.ELIGIBILITY_CHECK.value, + # Transaction.created_at >= last_24_hours + # ).scalar() or 0 + # + # select_offer_count = db.session.query( + # func.count(Transaction.id) + # ).filter( + # Transaction.type == TransactionType.SELECT_OFFER.value, + # Transaction.created_at >= last_24_hours + # ).scalar() or 0 + # + # provide_loan_count = db.session.query( + # func.count(Transaction.id) + # ).filter( + # Transaction.type == TransactionType.PROVIDE_LOAN.value, + # Transaction.created_at >= last_24_hours + # ).scalar() or 0 + # + # repayment_count = db.session.query( + # func.count(Transaction.id) + # ).filter( + # Transaction.type == TransactionType.REPAYMENT.value, + # Transaction.created_at >= last_24_hours + # ).scalar() or 0 + # + # # Recent transactions (not limited to 24 hrs, just latest 15) + # recent_transactions = Transaction.query.order_by( + # Transaction.id.desc() + # ).limit(15).all() + # + # recent_transactions_data = [{ + # 'id': t.id, + # 'transaction_id': t.transaction_id, + # 'account_id': t.account_id, + # 'type': t.type, + # 'channel': t.channel, + # 'created_at': t.created_at.isoformat() if t.created_at else None, + # 'updated_at': t.updated_at.isoformat() if t.updated_at else None + # } for t in recent_transactions] + # + # # Final response + # dashboard_data = { + # "loans": { + # "value": float(loans_this_week), + # "currency": "Naira", + # "currency_text": "₦", + # "text": "this week" + # }, + # "payments": { + # "value": payments_this_week, + # "currency": "Naira", + # "currency_text": "₦", + # "text": "this week" + # }, + # "request_summary": { + # "eligibility_check": {"Eligibility": eligibility_check_count}, + # "select_offer": {"Offers": select_offer_count}, + # "provide_loan": {"Loans": provide_loan_count}, + # "repayment": {"Repayments": repayment_count} + # }, + # "recent_transactions": recent_transactions_data + # } + + dashboard_data = { + "loans": { + "currency": "Naira", + "currency_text": "\u20a6", + "text": "this week", + "value": 15000.0 + }, + "payments": { + "currency": "Naira", + "currency_text": "\u20a6", + "text": "this week", + "value": 0 + }, + "recent_transactions": [ + { + "account_id": "361005323", + "channel": "USSD", + "created_at": "2025-07-21T10:03:42", + "id": 232, + "transaction_id": "TRCVIC36703401245", + "type": "select_offer", + "updated_at": "2025-07-21T10:03:42" + }, + { + "account_id": "361005323", + "channel": "USSD", + "created_at": "2025-07-21T10:03:29", + "id": 231, + "transaction_id": "TRCVIC36703401245", + "type": "eligibility_check", + "updated_at": "2025-07-21T10:03:29" + }, + { + "account_id": "ACC8118473344", + "channel": "USSD", + "created_at": "2025-07-21T10:03:18", + "id": 230, + "transaction_id": "TRCVIC12120647494", + "type": "eligibility_check", + "updated_at": "2025-07-21T10:03:18" + }, + { + "account_id": "ACC8113712034", + "channel": "USSD", + "created_at": "2025-07-21T10:03:05", + "id": 229, + "transaction_id": "TRCVIC40090254960", + "type": "eligibility_check", + "updated_at": "2025-07-21T10:03:05" + }, + { + "account_id": "ACC8115473093", + "channel": "USSD", + "created_at": "2025-07-21T10:02:48", + "id": 228, + "transaction_id": "TRCVIC27184433816", + "type": "eligibility_check", + "updated_at": "2025-07-21T10:02:48" + }, + { + "account_id": "101036327", + "channel": "USSD", + "created_at": "2025-07-21T08:59:57", + "id": 227, + "transaction_id": "TRCVIC27716634966", + "type": "provide_loan", + "updated_at": "2025-07-21T08:59:57" + }, + { + "account_id": "101036327", + "channel": "USSD", + "created_at": "2025-07-21T08:59:50", + "id": 226, + "transaction_id": "TRCVIC27716634966", + "type": "select_offer", + "updated_at": "2025-07-21T08:59:50" + }, + { + "account_id": "101036327", + "channel": "USSD", + "created_at": "2025-07-21T08:59:40", + "id": 225, + "transaction_id": "TRCVIC27716634966", + "type": "eligibility_check", + "updated_at": "2025-07-21T08:59:40" + }, + { + "account_id": "361005323", + "channel": "USSD", + "created_at": "2025-07-21T08:59:15", + "id": 224, + "transaction_id": "TRCVIC26225302171", + "type": "provide_loan", + "updated_at": "2025-07-21T08:59:15" + }, + { + "account_id": "361005323", + "channel": "USSD", + "created_at": "2025-07-21T08:59:02", + "id": 223, + "transaction_id": "TRCVIC26225302171", + "type": "select_offer", + "updated_at": "2025-07-21T08:59:02" + }, + { + "account_id": "361005323", + "channel": "USSD", + "created_at": "2025-07-21T08:58:52", + "id": 222, + "transaction_id": "TRCVIC26225302171", + "type": "eligibility_check", + "updated_at": "2025-07-21T08:58:52" + }, + { + "account_id": "IT51846105", + "channel": "USSD", + "created_at": "2025-07-18T14:42:58", + "id": 221, + "transaction_id": "FBN2507181418049D08B23", + "type": "repayment", + "updated_at": "2025-07-18T14:42:58" + }, + { + "account_id": "IT51846105", + "channel": "100", + "created_at": "2025-07-18T14:42:51", + "id": 220, + "transaction_id": "TRCVIC93468626395", + "type": "loan_status", + "updated_at": "2025-07-18T14:42:51" + }, + { + "account_id": "IT51846105", + "channel": "100", + "created_at": "2025-07-18T14:42:33", + "id": 219, + "transaction_id": "TRCVIC55986208679", + "type": "loan_status", + "updated_at": "2025-07-18T14:42:33" + }, + { + "account_id": "IT51846105", + "channel": "USSD", + "created_at": "2025-07-18T14:38:33", + "id": 218, + "transaction_id": "FBN250718143821FF5D323", + "type": "loan_status", + "updated_at": "2025-07-18T14:38:33" + } + ], + "request_summary": { + "eligibility_check": { + "Eligibility": 6 + }, + "provide_loan": { + "Loans": 2 + }, + "repayment": { + "Repayments": 0 + }, + "select_offer": { + "Offers": 3 + } + } + } + + return dashboard_data + + except Exception as e: + logger.error(f"An error occurred while getting dashboard data: {str(e)}", exc_info=True) + return jsonify({"message": "Internal Server Error"}), 500