from dataclasses import dataclass from django.contrib.contenttypes.models import ContentType from django.db import transaction from django.db.models import Q from django.utils import timezone from notifications.cache import invalidate_unread_summary from notifications.models import Notification from notifications.realtime import send_notifications_read_all_event from requests_app.models import Request as EmployeeRequest @dataclass(frozen=True) class RequestNotificationReadResult: notification_ids: list[int] count: int class RequestNotificationReadService: """Отмечает прочитанными уведомления только выбранного заявления.""" def mark_request_notifications_as_read( self, *, user, employee_request: EmployeeRequest, ) -> RequestNotificationReadResult: request_content_type = ContentType.objects.get_for_model(EmployeeRequest) request_id = employee_request.id request_id_text = str(request_id) queryset = ( Notification.objects.filter( recipient_id=user.id, unread=True, deleted=False, verb__startswith="request_", ) .filter( Q(data__request_id=request_id) | Q(data__request_id=request_id_text) | Q( target_content_type=request_content_type, target_object_id=request_id_text, ) | Q( action_object_content_type=request_content_type, action_object_object_id=request_id_text, ) ) .distinct() ) notification_ids = list(queryset.values_list("id", flat=True)) if not notification_ids: return RequestNotificationReadResult(notification_ids=[], count=0) count = Notification.objects.filter(id__in=notification_ids).update( unread=False, timestamp_read=timezone.now(), ) invalidate_unread_summary(user.id) def notify_after_commit(): invalidate_unread_summary(user.id) send_notifications_read_all_event(user.id, notification_ids) transaction.on_commit(notify_after_commit) return RequestNotificationReadResult( notification_ids=notification_ids, count=count, )