diff --git a/backend/apps/core/state_machine/callbacks/notifications.py b/backend/apps/core/state_machine/callbacks/notifications.py index 39509520..da689ec8 100644 --- a/backend/apps/core/state_machine/callbacks/notifications.py +++ b/backend/apps/core/state_machine/callbacks/notifications.py @@ -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 []