""" Notification service for Plutus payment processing application. Handles email notifications for payment failures and success reports. Integrates with existing emailclass.py for SMTP functionality. """ from datetime import datetime from typing import List, Dict, Any, Optional from emailclass import SendEmail import json import logging logger = logging.getLogger(__name__) class NotificationService: def __init__(self): self.email_client = SendEmail() def send_payment_failure_notification( self, payment_data: Dict[str, Any], recipient_email: str = "alan.woodman@interphone.com.au" ) -> bool: """ Send email notification for a failed payment. Args: payment_data: Dictionary containing payment information recipient_email: Email address to send notification to Returns: bool: True if email sent successfully """ try: # Extract payment information splynx_id = payment_data.get('splynx_id', 'Unknown') payment_id = payment_data.get('payment_id', 'Unknown') amount = payment_data.get('amount', 0.0) error = payment_data.get('error', 'Unknown error') payment_method = payment_data.get('payment_method', 'Unknown') customer_name = payment_data.get('customer_name', 'Unknown Customer') # Configure email self.email_client.receiver = recipient_email self.email_client.subject = f"Payment Failure - Customer {splynx_id} - ${amount:.2f}" self.email_client.message_type = "html" # Create HTML email content html_content = self._create_failure_email_html( payment_data, splynx_id, payment_id, amount, error, payment_method, customer_name ) self.email_client.message_body_html = html_content # Send email result = self.email_client.send() if result: logger.info(f"Payment failure email sent successfully for payment {payment_id}") else: logger.error(f"Failed to send payment failure email for payment {payment_id}") return result except Exception as e: logger.error(f"Error sending payment failure notification: {e}") return False def send_batch_summary_email( self, batch_summary: Dict[str, Any], recipient_email: str = "alan.woodman@interphone.com.au" ) -> bool: """ Send email summary for batch payment processing. Args: batch_summary: Dictionary containing batch processing summary recipient_email: Email address to send summary to Returns: bool: True if email sent successfully """ try: batch_id = batch_summary.get('batch_id', 'Unknown') total_processed = batch_summary.get('total_processed', 0) successful_count = batch_summary.get('successful_count', 0) failed_count = batch_summary.get('failed_count', 0) total_amount = batch_summary.get('total_amount', 0.0) # Configure email self.email_client.receiver = recipient_email self.email_client.subject = f"Batch Payment Summary - Batch #{batch_id} - {successful_count}/{total_processed} Successful" self.email_client.message_type = "html" # Create HTML email content html_content = self._create_batch_summary_html(batch_summary) self.email_client.message_body_html = html_content # Send email result = self.email_client.send() if result: logger.info(f"Batch summary email sent successfully for batch {batch_id}") else: logger.error(f"Failed to send batch summary email for batch {batch_id}") return result except Exception as e: logger.error(f"Error sending batch summary email: {e}") return False def _create_failure_email_html( self, payment_data: Dict[str, Any], splynx_id: str, payment_id: str, amount: float, error: str, payment_method: str, customer_name: str ) -> str: """Create HTML content for payment failure email.""" timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') return f"""

🚨 Payment Processing Failure

Plutus Payment System Alert

Payment Failed: A payment processing attempt has failed and requires attention.

Payment Details

Payment ID{payment_id}
Splynx Customer ID{splynx_id}
Customer Name{customer_name}
Payment Amount${amount:.2f} AUD
Payment Method{payment_method}
Timestamp{timestamp}

Error Information

Error Details:

{error}

Recommended Actions

System Links:

""" def _create_batch_summary_html(self, batch_summary: Dict[str, Any]) -> str: """Create HTML content for batch summary email.""" batch_id = batch_summary.get('batch_id', 'Unknown') total_processed = batch_summary.get('total_processed', 0) successful_count = batch_summary.get('successful_count', 0) failed_count = batch_summary.get('failed_count', 0) total_amount = batch_summary.get('total_amount', 0.0) success_amount = batch_summary.get('success_amount', 0.0) failed_payments = batch_summary.get('failed_payments', []) timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') # Determine status color if failed_count == 0: status_color = "#28a745" # Green status_text = "✅ All Successful" elif successful_count == 0: status_color = "#dc3545" # Red status_text = "❌ All Failed" else: status_color = "#ffc107" # Yellow status_text = "⚠️ Partial Success" # Build failed payments table failed_payments_html = "" if failed_payments: failed_payments_html = """

Failed Payments

""" for payment in failed_payments[:10]: # Limit to first 10 failures failed_payments_html += f""" """ failed_payments_html += "
Payment IDCustomer IDAmountError
{payment.get('id', 'N/A')} {payment.get('splynx_id', 'N/A')} ${payment.get('amount', 0.0):.2f} {payment.get('error', 'Unknown error')[:100]}...
" if len(failed_payments) > 10: failed_payments_html += f"

... and {len(failed_payments) - 10} more failed payments

" return f"""

📊 Batch Payment Summary

Batch #{batch_id}

{status_text}

Processing Summary

{total_processed}

Total Processed

{successful_count}

Successful

{failed_count}

Failed

MetricValue
Batch ID#{batch_id}
Total Amount Processed${total_amount:.2f} AUD
Successful Amount${success_amount:.2f} AUD
Success Rate{(successful_count/total_processed*100):.1f}%
Processing Time{timestamp}
{failed_payments_html}

Actions Required

"""