Bank Services tested and completed

This commit is contained in:
2025-04-21 14:33:25 +03:00
parent 2c5f00ab1d
commit 35aab0ba11
31 changed files with 1751 additions and 15 deletions

View File

@@ -0,0 +1,25 @@
FROM python:3.12-slim
WORKDIR /
# Install system dependencies and Poetry
RUN apt-get update && apt-get install -y --no-install-recommends gcc && rm -rf /var/lib/apt/lists/* && pip install --no-cache-dir poetry
# Copy Poetry configuration
COPY /BankServices/SenderService/pyproject.toml ./pyproject.toml
# Configure Poetry and install dependencies with optimizations
RUN poetry config virtualenvs.create false && poetry install --no-interaction --no-ansi --no-root --only main && pip cache purge && rm -rf ~/.cache/pypoetry
# Copy application code
COPY /BankServices/SenderService /
COPY /Schemas /Schemas
COPY /Controllers /Controllers
COPY /BankServices/ServiceDepends /
# Set Python path to include app directory
ENV PYTHONPATH=/ PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
# Run the application using the configured uvicorn server
CMD ["poetry", "run", "python", "app.py"]

View File

@@ -0,0 +1,172 @@
import time
import arrow
from typing import List, Any
from Schemas import AccountRecords
from jinja2 import Environment, FileSystemLoader
from Controllers.Email.send_email import EmailSendModel, EmailService
def render_email_template(
headers: List[str], rows: List[List[Any]], balance_error: bool, bank_balance: str
) -> str:
"""
Render the HTML email template with the provided data.
Args:
headers: List of column headers for the table
rows: List of data rows for the table
balance_error: Flag indicating if there's a balance discrepancy
bank_balance: Current bank balance formatted as string
Returns:
Rendered HTML template as string
"""
try:
# Look for template in ServiceDepends directory
env = Environment(loader=FileSystemLoader("/"))
template = env.get_template("template_accounts.html")
return template.render(
headers=headers,
rows=rows,
bank_balance=bank_balance,
balance_error=balance_error,
today=str(arrow.now().date()),
)
except Exception as e:
print(f'Template rendering failed: {e}')
raise
def send_email_to_given_address(send_to: str, html_template: str, count_of_records: int) -> bool:
"""
Send email with the rendered HTML template to the specified address.
Args:
send_to: Email address of the recipient
html_template: Rendered HTML template content
Returns:
Boolean indicating if the email was sent successfully
"""
today = arrow.now()
subject = f"{str(today.date())} Gunes Apt. Cari Durum Kayıt Giriş Raporu"
# Create email parameters using EmailSendModel
email_params = EmailSendModel(
subject=subject + f" ({count_of_records} kayıt)",
html=html_template,
receivers=[send_to],
text=f"Gunes Apt. Cari Durum Kayıt Giriş Raporu - {today.date()}"
)
try:
# Use the context manager to handle connection errors
with EmailService.new_session() as email_session:
# Send email through the service
EmailService.send_email(email_session, email_params)
print(f"Email successfully sent to: {send_to}")
return True
except Exception as e:
print(f'Failed to send email: {e}')
return False
def process_unsent_email_records() -> bool:
"""
Process account records that haven't been emailed yet.
Finds records with is_email_send=False, formats them into an email,
sends the email, and updates the records as sent if successful.
Returns:
bool: True if email was sent successfully, False otherwise
"""
try:
# Use the context manager to handle database connections
with AccountRecords.new_session() as db_session:
# Query un-sent mail rows - with limit for display only
account_records_query = AccountRecords.filter_all(
AccountRecords.is_email_send == False,
db=db_session,
).query.order_by(AccountRecords.bank_date.asc()).limit(20)
account_records: List[AccountRecords] = account_records_query.all()
if not account_records:
print("No unsent email records found")
return False
# Get the IDs of the records we're processing
record_ids = [record.id for record in account_records]
print(f"Found {len(account_records)} unsent email records")
# Format rows for the email template
list_of_rows = []
for record in account_records:
list_of_rows.append([
record.bank_date.strftime("%d/%m/%Y %H:%M"),
record.process_comment,
f"{record.currency_value:,.2f}",
f"{record.bank_balance:,.2f}"
])
# Reverse list by date
list_of_rows = list_of_rows[::-1]
# Get the most recent bank balance
last_bank_balance = sorted(account_records, key=lambda x: x.bank_date, reverse=True)[0].bank_balance
# Define headers for the table
headers = ["Ulaştığı Tarih", "Banka Transaksiyonu Ek Bilgi", "Aktarım Değeri", "Banka Bakiyesi"]
# Recipient email address
send_to = "karatay@mehmetkaratay.com.tr"
# Render email template
html_template = render_email_template(
headers=headers,
rows=list_of_rows,
balance_error=False,
bank_balance=f"{last_bank_balance:,.2f}",
)
# Send the email
if send_email_to_given_address(send_to=send_to, html_template=html_template, count_of_records=len(list_of_rows)):
# Create a new query without limit for updating
update_query = AccountRecords.filter_all(
AccountRecords.id.in_(record_ids),
db=db_session
).query
# Update records as sent
update_query.update({"is_email_send": True}, synchronize_session=False)
AccountRecords.save(db_session)
print(f"Successfully marked {len(account_records)} records as sent")
return True
print("Email sending failed, records not updated")
return False
except Exception as e:
print(f'Error processing unsent email records: {e}')
return False
if __name__ == "__main__":
print("Starting Email Sender Service")
while True:
try:
result = process_unsent_email_records()
if result:
print("Email processing completed successfully")
else:
print("No emails sent in this iteration")
except Exception as e:
print(f"Unexpected error in main loop: {e}")
# Sleep for 60 seconds before next check
print("Sleeping for 60 seconds")
time.sleep(60)

View File

@@ -0,0 +1,17 @@
[project]
name = "routineemailservice"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"arrow>=1.3.0",
"redbox>=0.2.1",
"redis>=5.2.1",
"pydantic-settings>=2.8.1",
"sqlalchemy-mixins>=2.0.5",
"fastapi>=0.115.11",
"jinja2>=3.1.6",
"psycopg2-binary>=2.9.10",
"redmail>=0.6.0",
]