diff --git a/app/__init__.py b/app/__init__.py index e5e7e35..ed6ddc3 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,9 +1,10 @@ from flask import Flask +from flask_mail import Mail from flask_cors import CORS from app.config import Config from app.routes import auth_bp, autocall_bp from app.response import (method_not_allowed, unsupported_media_type, not_found, bad_request) -from app.extensions import db +from app.extensions import db, mail def create_app(): @@ -15,6 +16,9 @@ def create_app(): # Setup CORS CORS(app) + + # Initialize Flask-Mail + mail.init_app(app) # Register blueprints app.register_blueprint(auth_bp) diff --git a/app/config.py b/app/config.py index 04cc785..948a00a 100644 --- a/app/config.py +++ b/app/config.py @@ -43,6 +43,15 @@ class Config: # SQLALCHEMY_ECHO = True + MAIL_SERVER = os.getenv('MAIL_SERVER','smtp.zoho.com') + MAIL_PORT = 587 + MAIL_USERNAME = os.getenv('MAIL_USERNAME', 'firstadvance@dynamikservices.tech') + MAIL_PASSWORD = os.getenv('MAIL_PASSWORD') + MAIL_USE_TLS = True + MAIL_USE_SSL = False + MAIL_DEFAULT_SENDER = ('FirstAdvance', 'firstadvance@dynamikservices.tech') + MAIL_RECEIVER= os.getenv('MAIL_RECEIVER', 'chinenyeumeaku@gmail.com,umeakuchinenye@gmail.com') + BANK_CALL_BASE_URL = os.getenv("BANK_CALL_BASE_URL", "https://bank-emulator.dev.simbrellang.net/api") BANK_CALL_SMS_BASE_URL= os.getenv("BANK_CALL_SMS_BASE_URL","https://first-advance-middleware-develop.fbn-devops-dev-asenv.appserviceenvironment.net/SMS") BANK_CALL_DISBURSE_LOAN_ENDPOINT = os.getenv("BANK_CALL_DISBURSE_LOAN_ENDPOINT","/DisburseLoan") diff --git a/app/extensions.py b/app/extensions.py index 2e1eeb6..1afa3d6 100644 --- a/app/extensions.py +++ b/app/extensions.py @@ -1,3 +1,5 @@ from flask_sqlalchemy import SQLAlchemy +from flask_mail import Mail +mail = Mail() db = SQLAlchemy() \ No newline at end of file diff --git a/app/routes/autocall.py b/app/routes/autocall.py index 679608f..7a291b6 100644 --- a/app/routes/autocall.py +++ b/app/routes/autocall.py @@ -10,6 +10,8 @@ from app.services.loan import LoanService from app.services.repayment import RepaymentService from app.services.salary import SalaryService from app.enums.loan_status import LoanStatus +from app.utils.mail import send_report_email, get_report_data +from app.config import settings autocall_bp = Blueprint("autocall", __name__) @@ -238,3 +240,19 @@ def process_salary_list(): logger.info(f"Finished processing salary ID: {pending_salary.id}") return ResponseHelper.success([], "Processed all pending salaries") + + + +@autocall_bp.route("/report", methods=["GET"]) +def report(): + try: + report_data = get_report_data() + logger.info(f"Generated report data: {report_data}") + send_report_email( + report_data, + recipients = [email.strip() for email in settings.MAIL_RECEIVER.split(",")]) + + return ResponseHelper.success(message="Report sent successfully",status_code=200) + except Exception as e: + logger.error(f"Error generating or sending report: {e}") + return ResponseHelper.error("Failed to send report", status_code=500, error=str(e)) diff --git a/app/utils/mail.py b/app/utils/mail.py new file mode 100644 index 0000000..3e39255 --- /dev/null +++ b/app/utils/mail.py @@ -0,0 +1,40 @@ +from flask_mail import Message +from flask import current_app +from app.extensions import mail +import pandas as pd +from io import BytesIO + +def get_report_data(): + """ + Fetch and return loan summary data. + """ + return [ + {"Type": "Disbursement", "Count": 45}, + {"Type": "Repayment", "Count": 32}, + ] +def send_report_email(report_data: list, recipients: list): + """ + Sends an HTML + Excel report to the given email recipients. + """ + df = pd.DataFrame(report_data) + output = BytesIO() + df.to_excel(output, index=False) + output.seek(0) + + html_table = df.to_html(index=False, border=1) + + msg = Message( + subject="Loan Report Summary", + recipients=recipients, + html=f"