mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-22 17:11:13 -05:00
feat(notifications): enhance submission approval and rejection notifications with dynamic titles and messages
This commit is contained in:
@@ -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 []
|
||||
|
||||
Reference in New Issue
Block a user