from django.contrib import messages from django.db.models import Count, Q from django.shortcuts import get_object_or_404, redirect, render from .forms import ReplyForm, TicketForm, TicketTriageForm from .models import Ticket def _ticket_stats(): return { "total": Ticket.objects.count(), "open": Ticket.objects.exclude(status=Ticket.Status.RESOLVED).count(), "triage": Ticket.objects.filter(status=Ticket.Status.TRIAGE).count(), "resolved": Ticket.objects.filter(status=Ticket.Status.RESOLVED).count(), } def home(request): """Render the branded support center landing page and quick ticket intake.""" if request.method == "POST": ticket_form = TicketForm(request.POST) if ticket_form.is_valid(): ticket = ticket_form.save() messages.success(request, "Ticket submitted. Your support thread is ready.") return redirect("ticket_success", public_id=ticket.public_id) else: ticket_form = TicketForm() status_counts = dict( Ticket.objects.values_list("status").annotate(total=Count("id")) ) recent_tickets = Ticket.objects.select_related("assigned_to")[:5] context = { "project_name": "RelayDesk", "page_description": "A lightweight support center for ticket submission, triage, threaded replies, and status tracking.", "ticket_form": ticket_form, "stats": _ticket_stats(), "status_choices": Ticket.Status.choices, "status_counts": status_counts, "recent_tickets": recent_tickets, } return render(request, "core/index.html", context) def ticket_create(request): if request.method == "POST": form = TicketForm(request.POST) if form.is_valid(): ticket = form.save() messages.success(request, "Ticket submitted. We created a trackable support thread for you.") return redirect("ticket_success", public_id=ticket.public_id) else: form = TicketForm() return render( request, "core/ticket_form.html", { "form": form, "project_name": "RelayDesk", "page_description": "Submit a support ticket with category, priority, and details.", }, ) def ticket_success(request, public_id): ticket = get_object_or_404(Ticket.objects.select_related("assigned_to"), public_id=public_id) return render( request, "core/ticket_success.html", { "ticket": ticket, "project_name": "RelayDesk", "page_description": f"Confirmation for support ticket {ticket.ticket_number}.", }, ) def ticket_list(request): tickets = Ticket.objects.select_related("assigned_to").annotate(reply_count=Count("replies")) query = request.GET.get("q", "").strip() status = request.GET.get("status", "").strip() priority = request.GET.get("priority", "").strip() category = request.GET.get("category", "").strip() if query: tickets = tickets.filter( Q(subject__icontains=query) | Q(description__icontains=query) | Q(requester_name__icontains=query) | Q(requester_email__icontains=query) ) if status in Ticket.Status.values: tickets = tickets.filter(status=status) if priority in Ticket.Priority.values: tickets = tickets.filter(priority=priority) if category in Ticket.Category.values: tickets = tickets.filter(category=category) context = { "project_name": "RelayDesk", "page_description": "Search, filter, and triage support tickets.", "tickets": tickets, "stats": _ticket_stats(), "query": query, "selected_status": status, "selected_priority": priority, "selected_category": category, "status_choices": Ticket.Status.choices, "priority_choices": Ticket.Priority.choices, "category_choices": Ticket.Category.choices, } return render(request, "core/ticket_list.html", context) def ticket_detail(request, public_id): ticket = get_object_or_404( Ticket.objects.select_related("assigned_to").prefetch_related("replies"), public_id=public_id, ) reply_form = ReplyForm( initial={ "author_name": request.user.get_full_name() or request.user.get_username() if request.user.is_authenticated else "", "author_email": request.user.email if request.user.is_authenticated else "", } ) triage_form = TicketTriageForm(instance=ticket) if request.method == "POST" and "reply_submit" in request.POST: reply_form = ReplyForm(request.POST) if reply_form.is_valid(): reply = reply_form.save(commit=False) reply.ticket = ticket if request.user.is_authenticated: reply.author_user = request.user reply.is_staff_reply = request.user.is_staff if not reply.author_name: reply.author_name = request.user.get_full_name() or request.user.get_username() if not reply.author_email: reply.author_email = request.user.email reply.save() messages.success(request, "Reply added to the ticket thread.") return redirect("ticket_detail", public_id=ticket.public_id) if request.method == "POST" and "triage_submit" in request.POST and request.user.is_staff: triage_form = TicketTriageForm(request.POST, instance=ticket) if triage_form.is_valid(): triage_form.save() messages.success(request, "Ticket triage fields updated.") return redirect("ticket_detail", public_id=ticket.public_id) context = { "project_name": "RelayDesk", "page_description": f"Ticket thread and status for {ticket.ticket_number}.", "ticket": ticket, "reply_form": reply_form, "triage_form": triage_form, } return render(request, "core/ticket_detail.html", context)