feat(notifications): enhance submission approval and rejection notifications with dynamic titles and messages

This commit is contained in:
pacnpal
2025-12-21 19:22:15 -05:00
parent b860e332cb
commit 8f6acbdc23

View File

@@ -159,12 +159,28 @@ class SubmissionApprovedNotification(NotificationCallback):
name: str = "SubmissionApprovedNotification"
def __init__(self, **kwargs):
def __init__(self, submission_type: str = "submission", **kwargs):
"""
Initialize the approval notification callback.
Args:
submission_type: Type of submission (e.g., "park photo", "ride review")
**kwargs: Additional arguments passed to parent class.
"""
super().__init__(
notification_type="submission_approved",
recipient_field="submitted_by",
**kwargs,
)
self.submission_type = submission_type
def _get_submission_type(self, context: TransitionContext) -> str:
"""Get the submission type from context or instance."""
# Try to get from extra_data first
if 'submission_type' in context.extra_data:
return context.extra_data['submission_type']
# Fall back to model name
return self.submission_type or context.model_name.lower()
def execute(self, context: TransitionContext) -> bool:
"""Execute the approval notification."""
@@ -177,12 +193,16 @@ class SubmissionApprovedNotification(NotificationCallback):
return False
try:
submission_type = self._get_submission_type(context)
additional_message = context.extra_data.get('comment', '')
# Use the specific method if available
if hasattr(notification_service, 'create_submission_approved_notification'):
notification_service.create_submission_approved_notification(
user=recipient,
submission=context.instance,
approved_by=context.user,
submission_object=context.instance,
submission_type=submission_type,
additional_message=additional_message,
)
else:
# Fall back to generic notification
@@ -190,6 +210,8 @@ class SubmissionApprovedNotification(NotificationCallback):
notification_service.create_notification(
user=recipient,
notification_type=self.notification_type,
title=f"Your {submission_type} has been approved!",
message=f"Your {submission_type} submission has been approved.",
related_object=context.instance,
extra_data=extra_data,
)
@@ -211,12 +233,28 @@ class SubmissionRejectedNotification(NotificationCallback):
name: str = "SubmissionRejectedNotification"
def __init__(self, **kwargs):
def __init__(self, submission_type: str = "submission", **kwargs):
"""
Initialize the rejection notification callback.
Args:
submission_type: Type of submission (e.g., "park photo", "ride review")
**kwargs: Additional arguments passed to parent class.
"""
super().__init__(
notification_type="submission_rejected",
recipient_field="submitted_by",
**kwargs,
)
self.submission_type = submission_type
def _get_submission_type(self, context: TransitionContext) -> str:
"""Get the submission type from context or instance."""
# Try to get from extra_data first
if 'submission_type' in context.extra_data:
return context.extra_data['submission_type']
# Fall back to model name
return self.submission_type or context.model_name.lower()
def execute(self, context: TransitionContext) -> bool:
"""Execute the rejection notification."""
@@ -229,21 +267,27 @@ class SubmissionRejectedNotification(NotificationCallback):
return False
try:
submission_type = self._get_submission_type(context)
# Extract rejection reason from extra_data
rejection_reason = context.extra_data.get('reason', 'No reason provided')
additional_message = context.extra_data.get('comment', '')
# Use the specific method if available
if hasattr(notification_service, 'create_submission_rejected_notification'):
# Extract rejection reason from extra_data
reason = context.extra_data.get('reason', '')
notification_service.create_submission_rejected_notification(
user=recipient,
submission=context.instance,
rejected_by=context.user,
reason=reason,
submission_object=context.instance,
submission_type=submission_type,
rejection_reason=rejection_reason,
additional_message=additional_message,
)
else:
extra_data = self._build_extra_data(context)
notification_service.create_notification(
user=recipient,
notification_type=self.notification_type,
title=f"Your {submission_type} needs attention",
message=f"Your {submission_type} submission was rejected. Reason: {rejection_reason}",
related_object=context.instance,
extra_data=extra_data,
)
@@ -283,8 +327,8 @@ class SubmissionEscalatedNotification(NotificationCallback):
"""Get admin users to notify."""
try:
from django.contrib.auth import get_user_model
User = get_user_model()
return User.objects.filter(is_staff=True, is_active=True)
user_model = get_user_model()
return user_model.objects.filter(is_staff=True, is_active=True)
except Exception as e:
logger.exception(f"Failed to get admin users: {e}")
return []
@@ -297,9 +341,14 @@ class SubmissionEscalatedNotification(NotificationCallback):
try:
extra_data = self._build_extra_data(context)
# Add escalation reason if available
if 'reason' in context.extra_data:
extra_data['escalation_reason'] = context.extra_data['reason']
escalation_reason = context.extra_data.get('reason', '')
if escalation_reason:
extra_data['escalation_reason'] = escalation_reason
title = f"{context.model_name} escalated for review"
message = f"A {context.model_name} has been escalated and requires attention."
if escalation_reason:
message += f" Reason: {escalation_reason}"
if self.admin_recipient:
# Notify admin users
@@ -308,6 +357,8 @@ class SubmissionEscalatedNotification(NotificationCallback):
notification_service.create_notification(
user=admin,
notification_type=self.notification_type,
title=title,
message=message,
related_object=context.instance,
extra_data=extra_data,
)
@@ -321,6 +372,8 @@ class SubmissionEscalatedNotification(NotificationCallback):
notification_service.create_notification(
user=recipient,
notification_type=self.notification_type,
title=title,
message=message,
related_object=context.instance,
extra_data=extra_data,
)
@@ -395,12 +448,22 @@ class StatusChangeNotification(NotificationCallback):
extra_data['entity_type'] = context.model_name
extra_data['entity_id'] = context.instance.pk
# Build title and message
entity_name = getattr(context.instance, 'name', str(context.instance))
title = f"{context.model_name} status changed to {context.target_state}"
message = (
f"{entity_name} has changed status from {context.source_state} "
f"to {context.target_state}."
)
# Notify admin users
admins = self._get_admin_users()
for admin in admins:
notification_service.create_notification(
user=admin,
notification_type=self.notification_type,
title=title,
message=message,
related_object=context.instance,
extra_data=extra_data,
)
@@ -421,8 +484,8 @@ class StatusChangeNotification(NotificationCallback):
"""Get admin users to notify."""
try:
from django.contrib.auth import get_user_model
User = get_user_model()
return User.objects.filter(is_staff=True, is_active=True)
user_model = get_user_model()
return user_model.objects.filter(is_staff=True, is_active=True)
except Exception as e:
logger.exception(f"Failed to get admin users: {e}")
return []