link view ticket for staff

This commit is contained in:
javad committed 2026-10-13 16:09:45 +03:30
1 parent 6b546aad76
commit 089db0afa4
13 files changed
+412 -3

No files matched your search

@@ -0,0 +1,30 @@
# Generated by Django 5.1.1 on 2026-10-13 12:22
import apps.tickets.models
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('tickets', '0018_dispatch_response_opening'),
]
operations = [
migrations.CreateModel(
name='StaffTicketShortLink',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('token', models.CharField(default=apps.tickets.models.staff_ticket_link_token, editable=False, max_length=10, unique=True)),
('expires_at', models.DateTimeField(default=apps.tickets.models.staff_ticket_link_expiry)),
('ticket', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='staff_short_link', to='tickets.ticket')),
],
options={
'verbose_name': 'لینک کوتاه تیکت کارشناسان',
'verbose_name_plural': 'لینک\u200cهای کوتاه تیکت کارشناسان',
},
),
]
+25
View File
@@ -1,10 +1,35 @@
import uuid
import secrets
import string
from datetime import timedelta
from django.conf import settings
from django.core.validators import MinLengthValidator
from django.db import models
from django.db.models import Q
from django.utils import timezone
from apps.core.models import PersianTextNormalizationMixin, PublicIdModel, TimeStampedModel
def staff_ticket_link_token():
return "".join(secrets.choice(string.ascii_letters + string.digits) for _ in range(10))
def staff_ticket_link_expiry():
return timezone.now() + timedelta(days=7)
class StaffTicketShortLink(TimeStampedModel):
"""A short navigation URL; it never authenticates or grants ticket access."""
ticket = models.OneToOneField("Ticket", on_delete=models.CASCADE, related_name="staff_short_link")
token = models.CharField(max_length=10, unique=True, default=staff_ticket_link_token, editable=False)
expires_at = models.DateTimeField(default=staff_ticket_link_expiry)
class Meta:
verbose_name = "لینک کوتاه تیکت کارشناسان"
verbose_name_plural = "لینک‌های کوتاه تیکت کارشناسان"
class TicketCategory(PersianTextNormalizationMixin, TimeStampedModel):
persian_text_fields = {"title": False, "description": True, "search_keywords": True}
unit=models.ForeignKey("staff.OrganizationalUnit",on_delete=models.PROTECT,null=True,blank=True,related_name="ticket_categories",verbose_name="واحد سازمانی",help_text="برای دسته‌های قدیمی عمومی می‌تواند خالی باشد؛ دسته‌های جدید باید واحد داشته باشند.")
+38
View File
@@ -0,0 +1,38 @@
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils import timezone
from django.views.decorators.cache import never_cache
from django.views.decorators.http import require_GET
from apps.accounts.models import User
from .models import StaffTicketShortLink
from .policies import TicketPolicy
def append_supervisor_ticket_link(ticket, message):
unit = ticket.owning_unit
if not unit or not unit.supervisor_sms_ticket_link_enabled:
return message
link, _ = StaffTicketShortLink.objects.get_or_create(ticket=ticket)
if link.expires_at <= timezone.now():
return message
url = settings.PUBLIC_BASE_URL.rstrip("/") + reverse("staff_ticket_short_link", args=[link.token])
return f"{message}\nمشاهده و پاسخ: {url}"
@never_cache
@require_GET
@login_required(login_url="/staff/login/")
def open_staff_ticket_link(request, token):
if not request.user.is_active or request.user.account_type != User.AccountType.STAFF:
raise PermissionDenied
link = get_object_or_404(
StaffTicketShortLink.objects.select_related("ticket"),
token=token, expires_at__gt=timezone.now(),
)
if not TicketPolicy.can_view(request.user, link.ticket):
raise PermissionDenied
return redirect("staff_tickets:detail", public_id=link.ticket.public_id)