link view ticket for staff
This commit is contained in:
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های کوتاه تیکت کارشناسان',
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -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="برای دستههای قدیمی عمومی میتواند خالی باشد؛ دستههای جدید باید واحد داشته باشند.")
|
||||
|
||||
@@ -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)
|
||||
Reference in new issue
Block a user