final all done 2nd last plan before goign live
This commit is contained in:
132
backend/igny8_core/business/notifications/views.py
Normal file
132
backend/igny8_core/business/notifications/views.py
Normal file
@@ -0,0 +1,132 @@
|
||||
"""
|
||||
Notification Views
|
||||
"""
|
||||
|
||||
from rest_framework import viewsets, status
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from django.utils import timezone
|
||||
|
||||
from igny8_core.api.pagination import CustomPageNumberPagination
|
||||
from igny8_core.api.base import AccountModelViewSet
|
||||
|
||||
from .models import Notification
|
||||
from .serializers import NotificationSerializer, NotificationListSerializer, MarkReadSerializer
|
||||
|
||||
|
||||
class NotificationViewSet(AccountModelViewSet):
|
||||
"""
|
||||
ViewSet for managing notifications
|
||||
|
||||
Endpoints:
|
||||
- GET /api/v1/notifications/ - List notifications
|
||||
- GET /api/v1/notifications/{id}/ - Get notification detail
|
||||
- DELETE /api/v1/notifications/{id}/ - Delete notification
|
||||
- POST /api/v1/notifications/{id}/read/ - Mark single notification as read
|
||||
- POST /api/v1/notifications/read-all/ - Mark all notifications as read
|
||||
- GET /api/v1/notifications/unread-count/ - Get unread notification count
|
||||
"""
|
||||
|
||||
serializer_class = NotificationSerializer
|
||||
pagination_class = CustomPageNumberPagination
|
||||
permission_classes = [IsAuthenticated]
|
||||
|
||||
def get_queryset(self):
|
||||
"""Filter notifications for current account and user"""
|
||||
from django.db.models import Q
|
||||
|
||||
user = self.request.user
|
||||
account = getattr(user, 'account', None)
|
||||
|
||||
if not account:
|
||||
return Notification.objects.none()
|
||||
|
||||
# Get notifications for this account that are either:
|
||||
# - For all users (user=None)
|
||||
# - For this specific user
|
||||
queryset = Notification.objects.filter(
|
||||
Q(account=account, user__isnull=True) |
|
||||
Q(account=account, user=user)
|
||||
).select_related('site').order_by('-created_at')
|
||||
|
||||
# Optional filters
|
||||
is_read = self.request.query_params.get('is_read')
|
||||
if is_read is not None:
|
||||
queryset = queryset.filter(is_read=is_read.lower() == 'true')
|
||||
|
||||
notification_type = self.request.query_params.get('type')
|
||||
if notification_type:
|
||||
queryset = queryset.filter(notification_type=notification_type)
|
||||
|
||||
severity = self.request.query_params.get('severity')
|
||||
if severity:
|
||||
queryset = queryset.filter(severity=severity)
|
||||
|
||||
return queryset
|
||||
|
||||
def get_serializer_class(self):
|
||||
"""Use list serializer for list action"""
|
||||
if self.action == 'list':
|
||||
return NotificationListSerializer
|
||||
return NotificationSerializer
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
"""List notifications with unread count"""
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
|
||||
# Get unread count
|
||||
unread_count = queryset.filter(is_read=False).count()
|
||||
|
||||
page = self.paginate_queryset(queryset)
|
||||
if page is not None:
|
||||
serializer = self.get_serializer(page, many=True)
|
||||
response = self.get_paginated_response(serializer.data)
|
||||
response.data['unread_count'] = unread_count
|
||||
return response
|
||||
|
||||
serializer = self.get_serializer(queryset, many=True)
|
||||
return Response({
|
||||
'results': serializer.data,
|
||||
'unread_count': unread_count
|
||||
})
|
||||
|
||||
@action(detail=True, methods=['post'])
|
||||
def read(self, request, pk=None):
|
||||
"""Mark a single notification as read"""
|
||||
notification = self.get_object()
|
||||
notification.mark_as_read()
|
||||
serializer = self.get_serializer(notification)
|
||||
return Response(serializer.data)
|
||||
|
||||
@action(detail=False, methods=['post'], url_path='read-all')
|
||||
def read_all(self, request):
|
||||
"""Mark all notifications as read"""
|
||||
serializer = MarkReadSerializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
notification_ids = serializer.validated_data.get('notification_ids', [])
|
||||
|
||||
queryset = self.get_queryset().filter(is_read=False)
|
||||
|
||||
if notification_ids:
|
||||
queryset = queryset.filter(id__in=notification_ids)
|
||||
|
||||
count = queryset.update(is_read=True, read_at=timezone.now())
|
||||
|
||||
return Response({
|
||||
'status': 'success',
|
||||
'marked_read': count
|
||||
})
|
||||
|
||||
@action(detail=False, methods=['get'], url_path='unread-count')
|
||||
def unread_count(self, request):
|
||||
"""Get count of unread notifications"""
|
||||
count = self.get_queryset().filter(is_read=False).count()
|
||||
return Response({'unread_count': count})
|
||||
|
||||
def destroy(self, request, *args, **kwargs):
|
||||
"""Delete a notification"""
|
||||
instance = self.get_object()
|
||||
self.perform_destroy(instance)
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
Reference in New Issue
Block a user