added report mail #40
+5
-1
@@ -1,9 +1,10 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
|
from flask_mail import Mail
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
from app.config import Config
|
from app.config import Config
|
||||||
from app.routes import auth_bp, autocall_bp
|
from app.routes import auth_bp, autocall_bp
|
||||||
from app.response import (method_not_allowed, unsupported_media_type, not_found, bad_request)
|
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():
|
def create_app():
|
||||||
@@ -15,6 +16,9 @@ def create_app():
|
|||||||
|
|
||||||
# Setup CORS
|
# Setup CORS
|
||||||
CORS(app)
|
CORS(app)
|
||||||
|
|
||||||
|
# Initialize Flask-Mail
|
||||||
|
mail.init_app(app)
|
||||||
|
|
||||||
# Register blueprints
|
# Register blueprints
|
||||||
app.register_blueprint(auth_bp)
|
app.register_blueprint(auth_bp)
|
||||||
|
|||||||
@@ -43,6 +43,15 @@ class Config:
|
|||||||
# SQLALCHEMY_ECHO = True
|
# 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_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_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")
|
BANK_CALL_DISBURSE_LOAN_ENDPOINT = os.getenv("BANK_CALL_DISBURSE_LOAN_ENDPOINT","/DisburseLoan")
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
from flask_sqlalchemy import SQLAlchemy
|
from flask_sqlalchemy import SQLAlchemy
|
||||||
|
from flask_mail import Mail
|
||||||
|
|
||||||
|
mail = Mail()
|
||||||
db = SQLAlchemy()
|
db = SQLAlchemy()
|
||||||
@@ -10,6 +10,8 @@ from app.services.loan import LoanService
|
|||||||
from app.services.repayment import RepaymentService
|
from app.services.repayment import RepaymentService
|
||||||
from app.services.salary import SalaryService
|
from app.services.salary import SalaryService
|
||||||
from app.enums.loan_status import LoanStatus
|
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__)
|
autocall_bp = Blueprint("autocall", __name__)
|
||||||
|
|
||||||
@@ -238,3 +240,19 @@ def process_salary_list():
|
|||||||
logger.info(f"Finished processing salary ID: {pending_salary.id}")
|
logger.info(f"Finished processing salary ID: {pending_salary.id}")
|
||||||
|
|
||||||
return ResponseHelper.success([], "Processed all pending salaries")
|
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))
|
||||||
|
|||||||
@@ -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"<h3>Loan Report Summary</h3>{html_table}",
|
||||||
|
)
|
||||||
|
msg.attach(
|
||||||
|
"loan_report.xlsx",
|
||||||
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||||
|
output.read()
|
||||||
|
)
|
||||||
|
|
||||||
|
with current_app.app_context():
|
||||||
|
mail.send(msg)
|
||||||
|
|
||||||
|
return "Report email sent"
|
||||||
+9
-1
@@ -200,4 +200,12 @@ paths:
|
|||||||
example: "2025-01-01"
|
example: "2025-01-01"
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: A successful response
|
description: A successful response
|
||||||
|
|
||||||
|
/autocall/report:
|
||||||
|
get:
|
||||||
|
summary: Generate and send a report
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
description: A successful response
|
||||||
|
|
||||||
@@ -11,3 +11,6 @@ psycopg2-binary
|
|||||||
alembic
|
alembic
|
||||||
python-dateutil
|
python-dateutil
|
||||||
oracledb
|
oracledb
|
||||||
|
Flask-Mail==0.10.0
|
||||||
|
pandas==2.1.3
|
||||||
|
openpyxl==3.1.5
|
||||||
|
|||||||
Reference in New Issue
Block a user