from flask import Blueprint, request, jsonify, send_from_directory from flask import Blueprint, request, jsonify from app.api.services import LoanRepaymentScheduleService from app.api.services.repayment_service import RepaymentService from app.api.services.loan_charge_service import LoanChargeService from app.api.services.loan_service import LoanService from app.api.services.transaction_service import TransactionService from app.api.services.transaction_offers_service import TransactionOfferService from app.api.services.auth_service import AuthService from app.api.services.dashboard_service import DashboardService from app.api.services.offer_service import OfferService from app.api.services.charge_service import ChargeService from functools import wraps from app.utils.logger import logger from app.api.middlewares import enforce_json, require_auth import os from flask_jwt_extended import ( JWTManager, jwt_required, create_access_token, get_jwt_identity, create_refresh_token, ) api = Blueprint('api', __name__) @api.before_request def cors_middleware(): """Middleware applied globally to all API routes in this blueprint""" return enforce_json() # Swagger JSON file @api.route("/swagger.json", methods=["GET"]) def swagger_json(): swagger_dir = os.path.join("swagger") 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) # JWT Authentication decorator def token_required(f): @wraps(f) def decorated(*args, **kwargs): token = None # Get token from header auth_header = request.headers.get('Authorization') if auth_header: if auth_header.startswith('Bearer '): token = auth_header.split(' ')[1] if not token: return jsonify({'message': 'Token is missing!'}), 401 # Verify token payload = AuthService.verify_token(token) if not payload: return jsonify({'message': 'Token is invalid or expired!'}), 401 # Add user info to request request.user = payload return f(*args, **kwargs) return decorated @api.route('/login', methods=['POST']) def login(): data = request.get_json() # Check if username and password are provided if not data or 'username' not in data or 'password' not in data: return jsonify({ 'error': 'Missing credentials', 'message': 'Username and password are required' }), 400 username = data.get('username', '') password = data.get('password', '') # Call the login method from AuthService result = AuthService.login(username, password) # Check if result is a tuple (error response) if isinstance(result, tuple): return jsonify(result[0]), result[1] return jsonify(result) @api.route('/dashboard', methods=['GET']) # @token_required def get_dashboard(): # Call the dashboard service result = DashboardService.get_dashboard_data() return jsonify(result) @api.route('/loans', methods=['GET']) # @token_required def get_loans(): # Extract query parameters for filtering filters = { 'id': request.args.get('id'), 'customer_id': request.args.get('customer_id'), 'account_id': request.args.get('account_id'), 'status': request.args.get('status'), 'tenor': request.args.get('tenor'), 'offer_id': request.args.get('offer_id'), 'product_id': request.args.get('product_id'), 'transaction_id': request.args.get('transaction_id'), 'original_transaction': request.args.get('original_transaction'), 'start_date': request.args.get('start_date'), 'end_date': request.args.get('end_date'), 'due_before': request.args.get('due_before'), 'due_after': request.args.get('due_after'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } # logger.info(f"Get loans request received with filters: {filters}") response = LoanService.process_request(filters) return response @api.route('/transactions', methods=['GET']) # @token_required def get_transactions(): # Extract query parameters for filtering filters = { 'account_id': request.args.get('account_id'), 'transaction_id': request.args.get('transaction_id'), 'type': request.args.get('type'), 'channel': request.args.get('channel'), 'start_date': request.args.get('start_date'), 'end_date': request.args.get('end_date'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } # logger.info(f"Get transactions request received with filters: {filters}") response = TransactionService.process_request(filters) return response @api.route('/transaction-offers', methods=['GET']) # @token_required def get_transaction_offers(): # Extract query parameters for filtering filters = { 'customer_id': request.args.get('customer_id'), 'transaction_id': request.args.get('transaction_id'), 'offer_id': request.args.get('offer_id'), 'product_id': request.args.get('product_id'), 'original_transaction': request.args.get('original_transaction'), 'start_date': request.args.get('start_date'), 'end_date': request.args.get('end_date'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } response = TransactionOfferService.process_request(filters) return response @api.route('/repayments', methods=['GET']) # @token_required def get_all_repayments(): # Extract query parameters for filtering filters = { 'loan_id': request.args.get('loan_id'), 'customer_id': request.args.get('customer_id'), 'product_id': request.args.get('product_id'), 'start_date': request.args.get('start_date'), 'end_date': request.args.get('end_date'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } # logger.info(f"Get repayments request received with filters: {filters}") response = RepaymentService.get_all_repayments(filters) return response @api.route('/loan-charges', methods=['GET']) # @token_required def get_all_loan_charges(): # Extract query parameters for filtering filters = { 'loan_id': request.args.get('loan_id'), 'transaction_id': request.args.get('transaction_id'), 'code': request.args.get('code'), 'start_date': request.args.get('start_date'), 'end_date': request.args.get('end_date'), 'due_before': request.args.get('due_before'), 'due_after': request.args.get('due_after'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } # logger.info(f"Get loan charges request received with filters: {filters}") response = LoanChargeService.get_all_loan_charges(filters) return response @api.route('/repayment-schedules', methods=['GET']) # @token_required def get_all_repayment_schedules(): # Extract query parameters for filtering filters = { 'loan_id': request.args.get('loan_id'), 'product_id': request.args.get('product_id'), 'transaction_id': request.args.get('transaction_id'), 'paid': request.args.get('paid'), 'due_before': request.args.get('due_before'), 'due_after': request.args.get('due_after'), 'installment_number': request.args.get('installment_number'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } # logger.info(f"Get repayment schedules request received with filters: {filters}") response = LoanRepaymentScheduleService.get_all_repayment_schedules(filters) return response @api.route('/offers', methods=['GET']) # @token_required def get_all_offers(): # Extract query parameters for filtering filters = { 'id': request.args.get('id'), 'product_id': request.args.get('product_id'), 'start_date': request.args.get('start_date'), 'end_date': request.args.get('end_date'), 'page': request.args.get('page', 1), 'limit': request.args.get('limit', 20) } # logger.info(f"Get offers request received with filters: {filters}") response = OfferService.get_all_offers(filters) return jsonify(response) # @api.route('/charges', methods=['GET']) # # @token_required # def get_all_charges(): # # Extract query parameters for filtering # filters = { # 'offer_id': request.args.get('offer_id'), # 'code': request.args.get('code'), # 'start_date': request.args.get('start_date'), # 'end_date': request.args.get('end_date'), # 'page': request.args.get('page', 1), # 'limit': request.args.get('limit', 20) # } # # logger.info(f"Get charges request received with filters: {filters}") # response = ChargeService.get_all_charges(filters) # return jsonify(response)