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 DashboardService(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 } 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