""" Email and notification utilities for appointments app. """ from django.core.mail import send_mail, EmailMultiAlternatives from django.template.loader import render_to_string from django.conf import settings from django.utils import timezone from core.utils import AuditLogger class AppointmentNotifications: """ Handle email notifications for appointment-related events. """ @staticmethod def send_appointment_confirmation(appointment): """ Send confirmation email when appointment request is created. """ try: subject = f'Appointment Request Confirmation - {appointment.request_id}' # Render HTML email html_content = render_to_string('appointments/emails/appointment_confirmation.html', { 'appointment': appointment, 'patient': appointment.patient, 'provider': appointment.provider, }) # Render plain text email text_content = render_to_string('appointments/emails/appointment_confirmation.txt', { 'appointment': appointment, 'patient': appointment.patient, 'provider': appointment.provider, }) # Send email email = EmailMultiAlternatives( subject=subject, body=text_content, from_email=settings.DEFAULT_FROM_EMAIL, to=[appointment.patient.user.email], ) email.attach_alternative(html_content, "text/html") email.send() # Log notification AuditLogger.log_event( tenant=appointment.tenant, event_type='NOTIFICATION', event_category='APPOINTMENT_MANAGEMENT', action='Send Appointment Confirmation Email', description=f'Sent confirmation email to {appointment.patient.user.email}', user=None, content_object=appointment, request=None ) return True except Exception as e: print(f"Error sending appointment confirmation email: {e}") return False @staticmethod def send_appointment_reminder(appointment, hours_before=24): """ Send reminder email before appointment. """ try: subject = f'Appointment Reminder - {appointment.scheduled_datetime.strftime("%B %d, %Y")}' html_content = render_to_string('appointments/emails/appointment_reminder.html', { 'appointment': appointment, 'patient': appointment.patient, 'provider': appointment.provider, 'hours_before': hours_before, }) text_content = render_to_string('appointments/emails/appointment_reminder.txt', { 'appointment': appointment, 'patient': appointment.patient, 'provider': appointment.provider, 'hours_before': hours_before, }) email = EmailMultiAlternatives( subject=subject, body=text_content, from_email=settings.DEFAULT_FROM_EMAIL, to=[appointment.patient.user.email], ) email.attach_alternative(html_content, "text/html") email.send() # Log notification AuditLogger.log_event( tenant=appointment.tenant, event_type='NOTIFICATION', event_category='APPOINTMENT_MANAGEMENT', action='Send Appointment Reminder Email', description=f'Sent {hours_before}h reminder to {appointment.patient.user.email}', user=None, content_object=appointment, request=None ) return True except Exception as e: print(f"Error sending appointment reminder email: {e}") return False @staticmethod def send_appointment_cancelled(appointment): """ Send notification when appointment is cancelled. """ try: subject = f'Appointment Cancelled - {appointment.request_id}' html_content = render_to_string('appointments/emails/appointment_cancelled.html', { 'appointment': appointment, 'patient': appointment.patient, 'provider': appointment.provider, }) text_content = render_to_string('appointments/emails/appointment_cancelled.txt', { 'appointment': appointment, 'patient': appointment.patient, 'provider': appointment.provider, }) email = EmailMultiAlternatives( subject=subject, body=text_content, from_email=settings.DEFAULT_FROM_EMAIL, to=[appointment.patient.user.email], ) email.attach_alternative(html_content, "text/html") email.send() # Log notification AuditLogger.log_event( tenant=appointment.tenant, event_type='NOTIFICATION', event_category='APPOINTMENT_MANAGEMENT', action='Send Appointment Cancellation Email', description=f'Sent cancellation email to {appointment.patient.user.email}', user=None, content_object=appointment, request=None ) return True except Exception as e: print(f"Error sending appointment cancellation email: {e}") return False @staticmethod def send_appointment_rescheduled(appointment): """ Send notification when appointment is rescheduled. """ try: subject = f'Appointment Rescheduled - {appointment.request_id}' html_content = render_to_string('appointments/emails/appointment_rescheduled.html', { 'appointment': appointment, 'patient': appointment.patient, 'provider': appointment.provider, }) text_content = render_to_string('appointments/emails/appointment_rescheduled.txt', { 'appointment': appointment, 'patient': appointment.patient, 'provider': appointment.provider, }) email = EmailMultiAlternatives( subject=subject, body=text_content, from_email=settings.DEFAULT_FROM_EMAIL, to=[appointment.patient.user.email], ) email.attach_alternative(html_content, "text/html") email.send() # Log notification AuditLogger.log_event( tenant=appointment.tenant, event_type='NOTIFICATION', event_category='APPOINTMENT_MANAGEMENT', action='Send Appointment Rescheduled Email', description=f'Sent rescheduled email to {appointment.patient.user.email}', user=None, content_object=appointment, request=None ) return True except Exception as e: print(f"Error sending appointment rescheduled email: {e}") return False @staticmethod def send_queue_position_update(queue_entry): """ Send notification when patient's queue position changes significantly. """ try: subject = f'Queue Update - You are #{queue_entry.queue_position}' html_content = render_to_string('appointments/emails/queue_position_update.html', { 'queue_entry': queue_entry, 'patient': queue_entry.patient, 'queue': queue_entry.queue, }) text_content = render_to_string('appointments/emails/queue_position_update.txt', { 'queue_entry': queue_entry, 'patient': queue_entry.patient, 'queue': queue_entry.queue, }) email = EmailMultiAlternatives( subject=subject, body=text_content, from_email=settings.DEFAULT_FROM_EMAIL, to=[queue_entry.patient.user.email], ) email.attach_alternative(html_content, "text/html") email.send() return True except Exception as e: print(f"Error sending queue position update email: {e}") return False @staticmethod def send_patient_called(queue_entry): """ Send notification when patient is called from queue. """ try: subject = f'You are being called - {queue_entry.queue.name}' html_content = render_to_string('appointments/emails/patient_called.html', { 'queue_entry': queue_entry, 'patient': queue_entry.patient, 'queue': queue_entry.queue, }) text_content = render_to_string('appointments/emails/patient_called.txt', { 'queue_entry': queue_entry, 'patient': queue_entry.patient, 'queue': queue_entry.queue, }) email = EmailMultiAlternatives( subject=subject, body=text_content, from_email=settings.DEFAULT_FROM_EMAIL, to=[queue_entry.patient.user.email], ) email.attach_alternative(html_content, "text/html") email.send() return True except Exception as e: print(f"Error sending patient called email: {e}") return False class QueueAudioNotifications: """ Handle audio notifications for queue management. """ @staticmethod def get_notification_sound(notification_type='default'): """ Get the appropriate notification sound file. """ sounds = { 'default': 'sounds/notification.mp3', 'patient_called': 'sounds/patient_called.mp3', 'urgent': 'sounds/urgent.mp3', 'emergency': 'sounds/emergency.mp3', } return sounds.get(notification_type, sounds['default']) @staticmethod def should_play_sound(queue_entry): """ Determine if sound should be played based on priority. """ priority_sounds = { 'EMERGENCY': 'emergency', 'STAT': 'emergency', 'URGENT': 'urgent', 'ROUTINE': 'patient_called', } return priority_sounds.get(queue_entry.priority, 'default')