mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-22 01:31:08 -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"
|
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__(
|
super().__init__(
|
||||||
notification_type="submission_approved",
|
notification_type="submission_approved",
|
||||||
recipient_field="submitted_by",
|
recipient_field="submitted_by",
|
||||||
**kwargs,
|
**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:
|
def execute(self, context: TransitionContext) -> bool:
|
||||||
"""Execute the approval notification."""
|
"""Execute the approval notification."""
|
||||||
@@ -177,12 +193,16 @@ class SubmissionApprovedNotification(NotificationCallback):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
submission_type = self._get_submission_type(context)
|
||||||
|
additional_message = context.extra_data.get('comment', '')
|
||||||
|
|
||||||
# Use the specific method if available
|
# Use the specific method if available
|
||||||
if hasattr(notification_service, 'create_submission_approved_notification'):
|
if hasattr(notification_service, 'create_submission_approved_notification'):
|
||||||
notification_service.create_submission_approved_notification(
|
notification_service.create_submission_approved_notification(
|
||||||
user=recipient,
|
user=recipient,
|
||||||
submission=context.instance,
|
submission_object=context.instance,
|
||||||
approved_by=context.user,
|
submission_type=submission_type,
|
||||||
|
additional_message=additional_message,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
# Fall back to generic notification
|
# Fall back to generic notification
|
||||||
@@ -190,6 +210,8 @@ class SubmissionApprovedNotification(NotificationCallback):
|
|||||||
notification_service.create_notification(
|
notification_service.create_notification(
|
||||||
user=recipient,
|
user=recipient,
|
||||||
notification_type=self.notification_type,
|
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,
|
related_object=context.instance,
|
||||||
extra_data=extra_data,
|
extra_data=extra_data,
|
||||||
)
|
)
|
||||||
@@ -211,12 +233,28 @@ class SubmissionRejectedNotification(NotificationCallback):
|
|||||||
|
|
||||||
name: str = "SubmissionRejectedNotification"
|
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__(
|
super().__init__(
|
||||||
notification_type="submission_rejected",
|
notification_type="submission_rejected",
|
||||||
recipient_field="submitted_by",
|
recipient_field="submitted_by",
|
||||||
**kwargs,
|
**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:
|
def execute(self, context: TransitionContext) -> bool:
|
||||||
"""Execute the rejection notification."""
|
"""Execute the rejection notification."""
|
||||||
@@ -229,21 +267,27 @@ class SubmissionRejectedNotification(NotificationCallback):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
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
|
# Use the specific method if available
|
||||||
if hasattr(notification_service, 'create_submission_rejected_notification'):
|
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(
|
notification_service.create_submission_rejected_notification(
|
||||||
user=recipient,
|
user=recipient,
|
||||||
submission=context.instance,
|
submission_object=context.instance,
|
||||||
rejected_by=context.user,
|
submission_type=submission_type,
|
||||||
reason=reason,
|
rejection_reason=rejection_reason,
|
||||||
|
additional_message=additional_message,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
extra_data = self._build_extra_data(context)
|
extra_data = self._build_extra_data(context)
|
||||||
notification_service.create_notification(
|
notification_service.create_notification(
|
||||||
user=recipient,
|
user=recipient,
|
||||||
notification_type=self.notification_type,
|
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,
|
related_object=context.instance,
|
||||||
extra_data=extra_data,
|
extra_data=extra_data,
|
||||||
)
|
)
|
||||||
@@ -283,8 +327,8 @@ class SubmissionEscalatedNotification(NotificationCallback):
|
|||||||
"""Get admin users to notify."""
|
"""Get admin users to notify."""
|
||||||
try:
|
try:
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
User = get_user_model()
|
user_model = get_user_model()
|
||||||
return User.objects.filter(is_staff=True, is_active=True)
|
return user_model.objects.filter(is_staff=True, is_active=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f"Failed to get admin users: {e}")
|
logger.exception(f"Failed to get admin users: {e}")
|
||||||
return []
|
return []
|
||||||
@@ -297,9 +341,14 @@ class SubmissionEscalatedNotification(NotificationCallback):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
extra_data = self._build_extra_data(context)
|
extra_data = self._build_extra_data(context)
|
||||||
# Add escalation reason if available
|
escalation_reason = context.extra_data.get('reason', '')
|
||||||
if 'reason' in context.extra_data:
|
if escalation_reason:
|
||||||
extra_data['escalation_reason'] = context.extra_data['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:
|
if self.admin_recipient:
|
||||||
# Notify admin users
|
# Notify admin users
|
||||||
@@ -308,6 +357,8 @@ class SubmissionEscalatedNotification(NotificationCallback):
|
|||||||
notification_service.create_notification(
|
notification_service.create_notification(
|
||||||
user=admin,
|
user=admin,
|
||||||
notification_type=self.notification_type,
|
notification_type=self.notification_type,
|
||||||
|
title=title,
|
||||||
|
message=message,
|
||||||
related_object=context.instance,
|
related_object=context.instance,
|
||||||
extra_data=extra_data,
|
extra_data=extra_data,
|
||||||
)
|
)
|
||||||
@@ -321,6 +372,8 @@ class SubmissionEscalatedNotification(NotificationCallback):
|
|||||||
notification_service.create_notification(
|
notification_service.create_notification(
|
||||||
user=recipient,
|
user=recipient,
|
||||||
notification_type=self.notification_type,
|
notification_type=self.notification_type,
|
||||||
|
title=title,
|
||||||
|
message=message,
|
||||||
related_object=context.instance,
|
related_object=context.instance,
|
||||||
extra_data=extra_data,
|
extra_data=extra_data,
|
||||||
)
|
)
|
||||||
@@ -395,12 +448,22 @@ class StatusChangeNotification(NotificationCallback):
|
|||||||
extra_data['entity_type'] = context.model_name
|
extra_data['entity_type'] = context.model_name
|
||||||
extra_data['entity_id'] = context.instance.pk
|
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
|
# Notify admin users
|
||||||
admins = self._get_admin_users()
|
admins = self._get_admin_users()
|
||||||
for admin in admins:
|
for admin in admins:
|
||||||
notification_service.create_notification(
|
notification_service.create_notification(
|
||||||
user=admin,
|
user=admin,
|
||||||
notification_type=self.notification_type,
|
notification_type=self.notification_type,
|
||||||
|
title=title,
|
||||||
|
message=message,
|
||||||
related_object=context.instance,
|
related_object=context.instance,
|
||||||
extra_data=extra_data,
|
extra_data=extra_data,
|
||||||
)
|
)
|
||||||
@@ -421,8 +484,8 @@ class StatusChangeNotification(NotificationCallback):
|
|||||||
"""Get admin users to notify."""
|
"""Get admin users to notify."""
|
||||||
try:
|
try:
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
User = get_user_model()
|
user_model = get_user_model()
|
||||||
return User.objects.filter(is_staff=True, is_active=True)
|
return user_model.objects.filter(is_staff=True, is_active=True)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(f"Failed to get admin users: {e}")
|
logger.exception(f"Failed to get admin users: {e}")
|
||||||
return []
|
return []
|
||||||
|
|||||||
Reference in New Issue
Block a user