Compare commits

..

9 Commits

Author SHA1 Message Date
VivianDee f1e9e39fe5 Update loan_repayment_schedule.py 2025-08-26 14:01:23 +01:00
VivianDee b412313fc5 [add]: Repayment status, balance and description 2025-08-26 13:58:49 +01:00
ameye cba6eac501 Merge branch 'process_date_and_count_on_repayment_schedules' of DigiFi/digifi-BankToProductCore into master 2025-08-22 10:48:18 +00:00
VivianDee 443c6262b7 [add]: process date and count 2025-08-21 14:31:05 +01:00
CHIEFSOFT\ameye 2ba97cee4a sql full added to env sample 2025-08-14 07:15:32 -04:00
CHIEFSOFT\ameye 8c714cb45c SQL switch 2025-08-13 19:57:53 -04:00
ameye c93e1a8bdd Merge branch 'mail_implementation' of DigiFi/digifi-BankToProductCore into master 2025-07-17 10:48:35 +00:00
VivianDee 6d8fe24718 [add]: send email in base service 2025-07-16 14:24:17 +01:00
VivianDee deaddd8132 [add]: mail 2025-07-16 14:19:10 +01:00
12 changed files with 175 additions and 10 deletions
+1
View File
@@ -12,6 +12,7 @@ DATABASE_PASSWORD=FirstAdvance!
DATABASE_HOST=dev-data.simbrellang.net
DATABASE_PORT=10532
DATABASE_NAME=firstadvancedev
#SQLALCHEMY_DATABASE_URI_FULL="oracle+oracledb://FIRSTADVSTG:Pchanged_56789@10.2.110.30:1521/?service_name=firstadv"
# DATABASE_HOST=10.20.30.60
# DATABASE_USER=firstadvance
+15
View File
@@ -0,0 +1,15 @@
from flask import Flask
from app.extensions import mail
from app.utils.mail import send_report_email, get_report_data
from app.config import settings
app = Flask(__name__)
app.config.from_object(settings)
mail.init_app(app)
with app.app_context():
report_data = get_report_data()
recipients = ["vdagbue@gmail.com"]
result = send_report_email(report_data, recipients)
print(result)
+5 -1
View File
@@ -1,4 +1,5 @@
from flask import Flask
from flask_mail import Mail
import os
from flask_swagger_ui import get_swaggerui_blueprint
from flask_cors import CORS
@@ -7,7 +8,7 @@ from app.api.routes import api
from app.errors import register_error_handlers
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from app.extensions import db, migrate
from app.extensions import db, migrate, mail
from flask_jwt_extended import (
JWTManager,
jwt_required,
@@ -47,6 +48,9 @@ def create_app():
from . import models
# Initialize Flask-Mail
mail.init_app(app)
# Database and Migrations
db.init_app(app)
+4
View File
@@ -4,6 +4,7 @@ from flask import jsonify
from marshmallow import ValidationError
import logging
from app.api.integrations import KafkaIntegration
from app.utils.mail import send_report_email, get_report_data
logger = logging.getLogger(__name__)
@@ -173,3 +174,6 @@ class BaseService:
# return {"rate": 0, "fee": 0, "due_days": 0}
@classmethod
def send_mail(cls, report_data, recipients):
send_report_email(report_data, recipients)
+4 -7
View File
@@ -87,13 +87,10 @@ class OfferAnalysis:
if failed_true_rules or failed_false_rules or not salaries:
if failed_true_rules:
logger.warning(f"RAC analysis failed: TRUE rules failed: {failed_true_rules}")
if failed_false_rules:
logger.warning(f"RAC analysis failed: FALSE rules failed: {failed_false_rules}")
if not salaries:
logger.warning("RAC analysis failed: No salary records found in RAC response.")
raise ValueError("RAC analysis failed")
logger.warning(f"Failed TRUE rules: {failed_true_rules}")
logger.warning(f"Failed FALSE rules: {failed_false_rules}")
logger.warning("No salary records found in RAC response.")
raise ValueError(f"RAC analysis failed")
+13 -2
View File
@@ -24,7 +24,10 @@ class Config:
# Database Connection
# SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://{DATABASE_USER}:{DATABASE_PASSWORD}@{DATABASE_HOST}:{DATABASE_PORT}/{DATABASE_NAME}"
SQLALCHEMY_DATABASE_URI = (f"oracle+oracledb://{DATABASE_USER}:{DATABASE_PASSWORD}@{DNS}")
SQLALCHEMY_DATABASE_URI_INTERNAL = (f"oracle+oracledb://{DATABASE_USER}:{DATABASE_PASSWORD}@{DNS}")
SQLALCHEMY_DATABASE_URI = os.getenv("SQLALCHEMY_DATABASE_URI_FULL", SQLALCHEMY_DATABASE_URI_INTERNAL)
#SQLALCHEMY_DATABASE_URI_FULL = 'oracle+oracledb://FIRSTADVSTG:Pchanged_56789@10.2.110.30:1521/?service_name=firstadv'
SQLALCHEMY_TRACK_MODIFICATIONS = False
@@ -85,7 +88,15 @@ class Config:
"salarypaymenT_6"
]
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', 'vdagbue@gmail.com')
settings = Config()
+2
View File
@@ -1,5 +1,7 @@
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_mail import Mail
mail = Mail()
db = SQLAlchemy()
migrate = Migrate()
+5
View File
@@ -17,6 +17,11 @@ class LoanRepaymentSchedule(db.Model):
total_repayment_amount = db.Column(db.Float, default=0.0)
paid = db.Column(db.Boolean, default=False)
paid_at = db.Column(db.DateTime, nullable=True)
due_process_date = db.Column(db.DateTime, nullable=True)
due_process_count = db.Column(db.Integer, default=0)
paid_status = db.Column(db.String(20), nullable=True)
repay_description = db.Column(db.String(255), nullable=True)
partial_balance = db.Column(db.Float, default=0.0)
created_at = db.Column(db.DateTime(timezone=True), server_default=func.now())
updated_at = db.Column(db.DateTime(timezone=True), server_default=func.now(), onupdate=func.now())
+40
View File
@@ -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"
+45
View File
@@ -0,0 +1,45 @@
"""empty message
Revision ID: 30b45df851fa
Revises: d59bfb9ead82
Create Date: 2025-08-26 13:48:27.458593
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '30b45df851fa'
down_revision = 'd59bfb9ead82'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
'loan_repayment_schedules',
sa.Column('paid_status', sa.String(length=20), nullable=True),
)
op.add_column(
'loan_repayment_schedules',
sa.Column('repay_description', sa.String(length=255), nullable=True),
)
op.add_column(
'loan_repayment_schedules',
sa.Column('partial_balance', sa.Float(), nullable=True),
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('loan_repayment_schedules', 'partial_balance')
op.drop_column('loan_repayment_schedules', 'repay_description')
op.drop_column('loan_repayment_schedules', 'paid_status')
# ### end Alembic commands ###
+38
View File
@@ -0,0 +1,38 @@
"""empty message
Revision ID: d59bfb9ead82
Revises: 05b5494ad406
Create Date: 2025-08-21 14:22:19.220158
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'd59bfb9ead82'
down_revision = '05b5494ad406'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
'loan_repayment_schedules',
sa.Column('due_process_date', sa.DateTime(), nullable=True)
)
# Add due_process_count column
op.add_column(
'loan_repayment_schedules',
sa.Column('due_process_count', sa.Integer(), nullable=True)
)
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('loan_repayment_schedules', 'due_process_date')
op.drop_column('loan_repayment_schedules', 'due_process_count')
# ### end Alembic commands ###
+3
View File
@@ -40,3 +40,6 @@ confluent-kafka==1.9.2
python-dateutil
Flask-Mail==0.10.0
pandas==2.1.3
openpyxl==3.1.5