183 lines
6.6 KiB
Python
183 lines
6.6 KiB
Python
"""
|
|
Complaint signals - Automatic SMS notifications on status changes
|
|
|
|
This module handles automatic SMS notifications to complainants when:
|
|
1. Complaint is created (confirmation)
|
|
2. Complaint status changes to resolved or closed
|
|
"""
|
|
import logging
|
|
|
|
from django.db.models.signals import post_save
|
|
from django.dispatch import receiver
|
|
from django.contrib.sites.shortcuts import get_current_site
|
|
|
|
from .models import Complaint, ComplaintUpdate
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
@receiver(post_save, sender=Complaint)
|
|
def send_complaint_creation_sms(sender, instance, created, **kwargs):
|
|
"""
|
|
Send SMS notification when complaint is created.
|
|
|
|
Only sends for public complaints (those with contact_phone).
|
|
"""
|
|
if not created:
|
|
return
|
|
|
|
# Only send SMS if phone number is provided
|
|
if not instance.contact_phone:
|
|
logger.info(f"Complaint #{instance.id} created but no phone number provided. Skipping SMS.")
|
|
return
|
|
|
|
# Send SMS notification
|
|
try:
|
|
from apps.notifications.services import NotificationService
|
|
|
|
# Get tracking URL
|
|
tracking_url = instance.get_tracking_url()
|
|
|
|
# Bilingual SMS messages
|
|
messages = {
|
|
'en': f"PX360: Your complaint #{instance.reference_number} has been received. Track: {tracking_url}",
|
|
'ar': f"PX360: تم استلام شكوتك #{instance.reference_number}. تتبع الشكوى: {tracking_url}"
|
|
}
|
|
|
|
# Default to English (can be enhanced to detect language)
|
|
sms_message = messages['en']
|
|
|
|
# Send SMS
|
|
notification_log = NotificationService.send_sms(
|
|
phone=instance.contact_phone,
|
|
message=sms_message,
|
|
related_object=instance,
|
|
metadata={
|
|
'notification_type': 'complaint_created',
|
|
'reference_number': instance.reference_number,
|
|
'tracking_url': tracking_url,
|
|
'language': 'en' # Default to English
|
|
}
|
|
)
|
|
|
|
logger.info(f"Creation SMS sent to {instance.contact_phone} for complaint #{instance.id}")
|
|
|
|
# Create complaint update to track SMS
|
|
ComplaintUpdate.objects.create(
|
|
complaint=instance,
|
|
update_type='communication',
|
|
message=f"SMS notification sent to complainant: Your complaint has been received",
|
|
metadata={
|
|
'notification_type': 'complaint_created',
|
|
'notification_log_id': str(notification_log.id) if notification_log else None
|
|
}
|
|
)
|
|
|
|
except Exception as e:
|
|
# Log error but don't fail the complaint save
|
|
logger.error(f"Failed to send creation SMS for complaint #{instance.id}: {str(e)}")
|
|
|
|
|
|
@receiver(post_save, sender=Complaint)
|
|
def send_complaint_status_change_sms(sender, instance, created, **kwargs):
|
|
"""
|
|
Send SMS notification when complaint status changes to resolved or closed.
|
|
|
|
Uses update_fields to detect actual status changes (not just re-saves).
|
|
"""
|
|
# Skip on creation (handled by creation signal)
|
|
if created:
|
|
return
|
|
|
|
# Check if this is a status change to resolved or closed
|
|
# Use update_fields to detect actual status changes
|
|
if not hasattr(instance, '_status_was'):
|
|
return
|
|
|
|
old_status = instance._status_was
|
|
new_status = instance.status
|
|
|
|
# Only send SMS for resolved or closed status changes
|
|
if new_status not in ['resolved', 'closed']:
|
|
return
|
|
|
|
# Only send if status actually changed
|
|
if old_status == new_status:
|
|
return
|
|
|
|
# Only send SMS if phone number is provided
|
|
if not instance.contact_phone:
|
|
logger.info(f"Complaint #{instance.id} status changed to {new_status} but no phone number. Skipping SMS.")
|
|
return
|
|
|
|
# Send SMS notification
|
|
try:
|
|
from apps.notifications.services import NotificationService
|
|
|
|
# Bilingual SMS messages
|
|
messages_en = {
|
|
'resolved': f"PX360: Your complaint #{instance.reference_number} has been resolved. Thank you for your feedback.",
|
|
'closed': f"PX360: Your complaint #{instance.reference_number} has been closed. Thank you for your feedback."
|
|
}
|
|
|
|
messages_ar = {
|
|
'resolved': f"PX360: تم حل شكوتك #{instance.reference_number}. شكراً لتعاونكم.",
|
|
'closed': f"PX360: تم إغلاق شكوتك #{instance.reference_number}. شكراً لتعاونكم."
|
|
}
|
|
|
|
# Default to English (can be enhanced to detect language)
|
|
sms_message = messages_en.get(new_status, '')
|
|
|
|
# Send SMS
|
|
notification_log = NotificationService.send_sms(
|
|
phone=instance.contact_phone,
|
|
message=sms_message,
|
|
related_object=instance,
|
|
metadata={
|
|
'notification_type': 'complaint_status_change',
|
|
'reference_number': instance.reference_number,
|
|
'old_status': old_status,
|
|
'new_status': new_status,
|
|
'language': 'en' # Default to English
|
|
}
|
|
)
|
|
|
|
logger.info(f"Status change SMS sent to {instance.contact_phone} for complaint #{instance.id}: {old_status} -> {new_status}")
|
|
|
|
# Create complaint update to track SMS
|
|
ComplaintUpdate.objects.create(
|
|
complaint=instance,
|
|
update_type='communication',
|
|
message=f"SMS notification sent to complainant: Status changed to {new_status}",
|
|
metadata={
|
|
'notification_type': 'complaint_status_change',
|
|
'old_status': old_status,
|
|
'new_status': new_status,
|
|
'notification_log_id': str(notification_log.id) if notification_log else None
|
|
}
|
|
)
|
|
|
|
except Exception as e:
|
|
# Log error but don't fail the complaint save
|
|
logger.error(f"Failed to send status change SMS for complaint #{instance.id}: {str(e)}")
|
|
|
|
|
|
# Hook into ComplaintUpdate to track SMS sent manually via API
|
|
@receiver(post_save, sender=ComplaintUpdate)
|
|
def track_manual_sms(sender, instance, created, **kwargs):
|
|
"""
|
|
Track manually sent SMS notifications.
|
|
|
|
This ensures that SMS sent via API endpoints (like send_resolution_notification)
|
|
are also properly tracked.
|
|
"""
|
|
if not created:
|
|
return
|
|
|
|
# Check if this update was for a communication/notification
|
|
if instance.update_type == 'communication':
|
|
# Log tracking info
|
|
logger.info(
|
|
f"Manual communication update created for complaint #{instance.complaint.id}: "
|
|
f"{instance.message[:50]}..."
|
|
) |