share ticket and ticket message
This commit is contained in:
1 parent
39e64854b8
commit
79fe1cddbb
35 files changed
+1742
-95
No files matched your search
@@ -0,0 +1,83 @@
|
||||
"""Staff conversation access; message grants never become ticket grants."""
|
||||
import hashlib
|
||||
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.db.models import Q
|
||||
from django.http import JsonResponse
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from .models import MessageShare, TicketAccessGrant
|
||||
from .policies import TicketPolicy
|
||||
from .sharing import staff_message_context
|
||||
|
||||
|
||||
def received_messages(user, ticket=None):
|
||||
grants = MessageShare.objects.filter(user=user, revoked_at__isnull=True, message__deleted_at__isnull=True)
|
||||
return grants.filter(message__ticket=ticket) if ticket is not None else grants
|
||||
|
||||
|
||||
def unread_shares(user):
|
||||
profile = getattr(user, "staff_profile", None)
|
||||
if not user.is_authenticated or not user.is_active or user.account_type != "STAFF" or not profile or not profile.is_active:
|
||||
return 0
|
||||
return (received_messages(user).filter(first_viewed_at__isnull=True).count()
|
||||
+ TicketAccessGrant.objects.filter(user=user, revoked_at__isnull=True, first_viewed_at__isnull=True).count())
|
||||
|
||||
|
||||
def visible_messages(ticket, user):
|
||||
profile = getattr(user, "staff_profile", None)
|
||||
if not user.is_active or (profile is not None and not profile.is_active):
|
||||
raise PermissionDenied
|
||||
query = ticket.ticket_messages.all()
|
||||
if TicketPolicy.can_view(user, ticket):
|
||||
return query
|
||||
grants = received_messages(user, ticket)
|
||||
if not grants.exists():
|
||||
raise PermissionDenied
|
||||
return query.filter(pk__in=grants.values("message_id"))
|
||||
|
||||
|
||||
def message_context(ticket, user, conversation):
|
||||
context = staff_message_context(ticket, user, conversation)
|
||||
grants = {g.message_id: g for g in received_messages(user, ticket).select_related("granted_by__staff_profile")}
|
||||
for item in conversation:
|
||||
item.received_share = grants.get(item.pk)
|
||||
context["limited_share"] = not TicketPolicy.can_view(user, ticket)
|
||||
return context
|
||||
|
||||
|
||||
def shared_ticket_rows(user, params):
|
||||
"""All received shares use ordinary ticket metadata and filters."""
|
||||
from .models import Ticket
|
||||
from .selectors import filter_staff_tickets, staff_ticket_rows
|
||||
full = staff_ticket_rows(user)
|
||||
query = Ticket.objects.select_related("customer__customer_profile", "category", "owner__staff_profile", "selected_expert__staff_profile", "owning_unit", "assigned_unit", "group_dispatch").filter(
|
||||
Q(pk__in=full.values("pk")) | Q(pk__in=received_messages(user).values("message__ticket_id")))
|
||||
rows = list(filter_staff_tickets(query, user, params)[:100])
|
||||
full_ids = set(full.filter(pk__in=[ticket.pk for ticket in rows]).values_list("pk", flat=True))
|
||||
for ticket in rows:
|
||||
ticket.limited_share = ticket.pk not in full_ids
|
||||
return rows
|
||||
|
||||
|
||||
def limited_poll(request, ticket):
|
||||
"""Version depends exclusively on authorized messages and their active grants."""
|
||||
from .views import conversation_page
|
||||
query = visible_messages(ticket, request.user)
|
||||
grants = list(received_messages(request.user, ticket).values_list("pk", "note"))
|
||||
source = repr((list(query.order_by("pk").values_list("pk", "updated_at")), grants,
|
||||
ticket.status, ticket.priority, ticket.subject, ticket.province, ticket.city))
|
||||
version = hashlib.sha256(source.encode()).hexdigest()[:20]
|
||||
latest = query.order_by("-created_at", "-pk").first()
|
||||
cursor = str(latest.public_id) if latest else ""
|
||||
data = {"changed": False, "version": version, "cursor": cursor}
|
||||
if request.GET.get("version") != version or request.GET.get("cursor", "") != cursor:
|
||||
conversation, has_older, older_cursor = conversation_page(query.select_related("author").prefetch_related("attachments"))
|
||||
context = {"ticket": ticket, "viewer_user": request.user, "conversation": conversation,
|
||||
"has_older": has_older, "older_cursor": older_cursor,
|
||||
**message_context(ticket, request.user, conversation)}
|
||||
data.update(changed=True, replace=True, staff_limited=True, count=query.count(), status=ticket.get_status_display(),
|
||||
html=render_to_string("tickets/_staff_older_messages.html", context, request=request))
|
||||
response = JsonResponse(data)
|
||||
response["Cache-Control"] = "private, no-store"
|
||||
return response
|
||||
Reference in new issue
Block a user