Adaugă solduri în notificările email

- EmailNotifier primește lista de conturi (nu doar count)
- _create_email_body afișează solduri per cont + total RON
- Format tabel HTML frumos cu styling
- send_notifications.py citește date din JSON
- Sincronizare cu TelegramNotifier (deja avea solduri)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-06 21:15:52 +02:00
parent 5aa4900b23
commit 2439d0b62a
2 changed files with 57 additions and 18 deletions

View File

@@ -23,13 +23,13 @@ class EmailNotifier:
self.config = config
self.enabled = config.EMAIL_ENABLED
def send(self, files: List[str], account_count: int) -> bool:
def send(self, files: List[str], accounts: list) -> bool:
"""
Send email with CSV attachments
Args:
files: List of file paths to attach
account_count: Number of accounts processed
accounts: List of account data with balances
Returns:
True if successful, False otherwise
@@ -51,7 +51,7 @@ class EmailNotifier:
msg['Subject'] = f'BTGO Scraper Results - {datetime.now().strftime("%Y-%m-%d %H:%M")}'
# Email body
body = self._create_email_body(files, account_count)
body = self._create_email_body(files, accounts)
msg.attach(MIMEText(body, 'html'))
# Attach files
@@ -67,7 +67,7 @@ class EmailNotifier:
# Check size limit (10MB typical SMTP limit)
if total_size > 10 * 1024 * 1024:
logging.warning(f"Email attachments exceed 10MB, creating ZIP archive")
return self._send_with_zip(files, account_count)
return self._send_with_zip(files, accounts)
with open(file_path, 'rb') as f:
part = MIMEBase('application', 'octet-stream')
@@ -94,7 +94,7 @@ class EmailNotifier:
logging.error(f"Failed to send email: {e}")
return False
def _send_with_zip(self, files: List[str], account_count: int) -> bool:
def _send_with_zip(self, files: List[str], accounts: list) -> bool:
"""Send email with files compressed as ZIP"""
try:
# Create ZIP archive
@@ -114,7 +114,7 @@ class EmailNotifier:
msg['To'] = self.config.EMAIL_TO
msg['Subject'] = f'BTGO Scraper Results (ZIP) - {datetime.now().strftime("%Y-%m-%d %H:%M")}'
body = self._create_email_body([str(zip_path)], account_count, is_zip=True)
body = self._create_email_body([str(zip_path)], accounts, is_zip=True)
msg.attach(MIMEText(body, 'html'))
with open(zip_path, 'rb') as f:
@@ -137,19 +137,39 @@ class EmailNotifier:
logging.error(f"Failed to send email with ZIP: {e}")
return False
def _create_email_body(self, files: List[str], account_count: int, is_zip: bool = False) -> str:
def _create_email_body(self, files: List[str], accounts: list, is_zip: bool = False) -> str:
"""Create HTML email body"""
file_list = '<br>'.join([f'{Path(f).name}' for f in files])
file_count = 1 if is_zip else len(files)
# Calculate total balance
total_ron = sum(acc['sold'] for acc in accounts if acc.get('moneda') == 'RON')
# Build account balance list
account_balances = ""
for acc in accounts:
nume = acc['nume_cont']
sold = acc['sold']
moneda = acc['moneda']
account_balances += f'<tr><td style="padding: 8px; border-bottom: 1px solid #ecf0f1;">{nume}</td><td style="padding: 8px; text-align: right; border-bottom: 1px solid #ecf0f1;"><strong>{sold:,.2f} {moneda}</strong></td></tr>'
return f"""
<html>
<body style="font-family: Arial, sans-serif;">
<h2 style="color: #2c3e50;">BTGO Scraper Results</h2>
<p><strong>Execution time:</strong> {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
<p><strong>Accounts processed:</strong> {account_count}</p>
<p><strong>Accounts processed:</strong> {len(accounts)}</p>
<p><strong>Files attached:</strong> {file_count}</p>
<hr>
<h3 style="color: #27ae60;">Solduri:</h3>
<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;">
{account_balances}
<tr style="background-color: #f8f9fa;">
<td style="padding: 12px; font-weight: bold;">TOTAL</td>
<td style="padding: 12px; text-align: right; font-weight: bold; color: #27ae60; font-size: 1.2em;">{total_ron:,.2f} RON</td>
</tr>
</table>
<hr>
<h3>{'Archive contents:' if is_zip else 'Attached files:'}</h3>
{file_list}
<hr>
@@ -479,7 +499,7 @@ class NotificationService:
# Send via email
if self.config.EMAIL_ENABLED:
results['email'] = self.email.send(files, account_count)
results['email'] = self.email.send(files, accounts)
# Send via Telegram
if self.config.TELEGRAM_ENABLED: