74 lines
2.4 KiB
Python

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,
)