Published on 05 Oct, 2025
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Category;
use App\Models\Ticket;
use App\Models\TicketHistory;
use App\Models\User;
use Illuminate\Support\Str; // Reference ID เคฌเคจเคพเคจเฅ เคเฅ เคฒเคฟเค
class TicketController extends Controller
{
// ==========================================================
// 1. TICKET CREATION & LISTING
// ==========================================================
/**
* Show the ticket creation form with active categories.
*/
public function getCategories()
{
$categories = Category::where('status', 1)->get();
return view('users.createTicket', compact('categories'));
}
/**
* Store a new ticket in the database.
*/
public function storeTicket(Request $request)
{
// 1. Validation
$request->validate([
'category_id' => 'required|exists:categories,id',
'title' => 'required|string|max:255',
'description' => 'required|string',
'priority' => 'required|in:Low,Medium,High',
'attachment' => 'nullable|file|mimes:jpg,jpeg,png,pdf,doc,docx|max:2048',
]);
$filePath = null;
$userId = session('user_id');
// 2. Handle file upload
if ($request->hasFile('attachment')) {
$file = $request->file('attachment');
$fileName = time().'_'.Str::random(10).'.'.$file->getClientOriginalExtension(); // Added random string for uniqueness
$filePath = $file->storeAs('tickets', $fileName, 'public');
}
// 3. Generate a unique Reference ID (e.g., TK-A1B2C3D4)
$referenceId = 'TK-' . strtoupper(Str::random(8));
// 4. Create Ticket
Ticket::create([
'user_id' => $userId,
'category_id' => $request->category_id,
'title' => $request->title,
'description' => $request->description,
'priority' => $request->priority,
'attachment' => $filePath,
'reference_id' => $referenceId, // Added Reference ID
'status' => 'Open', // Explicitly setting the initial status
]);
return redirect()->route('users.create.ticket')
->with('success', "Ticket created successfully! Your Reference ID is: {$referenceId}");
}
/**
* List all tickets for the logged-in user.
*/
public function listTickets()
{
$userId = session('user_id');
$tickets = Ticket::where('user_id', $userId)
->with('category')
->orderBy('created_at', 'desc')
->paginate(10); // Added pagination for large lists
return view('users.ticketslist', compact('tickets'));
}
/**
* Show a specific ticket with its history.
*/
public function show($id) {
$ticket = Ticket::with(['category', 'history.user'])->findOrFail($id); // history เคเฅ เคธเคพเคฅ user data เคญเฅ เคฒเฅเคก เคเคฐเฅเค
return view('users.showTicket', compact('ticket'));
}
/**
* Show the form to edit a specific ticket.
*/
public function edit($id) {
$ticket = Ticket::findOrFail($id);
$categories = Category::all();
// Check if the ticket is editable (e.g., status is 'Open')
if ($ticket->status !== 'Open') {
return back()->with('error', 'Only open tickets can be edited.');
}
return view('users.editTicket', compact('ticket','categories'));
}
/**
* Add a remark (comment) to a ticket.
*/
public function addRemark(Request $request, $id)
{
$request->validate([
'remark' => 'required|string|max:1000',
]);
$ticket = Ticket::findOrFail($id);
// Prevent adding remarks to closed tickets
if ($ticket->status === 'Closed') {
return back()->with('error', 'Cannot add remarks to a closed ticket.');
}
TicketHistory::create([
'ticket_id' => $ticket->id,
'user_id' => session('user_id'),
'remark' => $request->remark,
'status' => $ticket->status,
'user_type' => 'user',
]);
return back()->with('success', 'Remark added successfully.');
}
/**
* Show the user dashboard with ticket status counts.
*/
public function dashboard()
{
$userId = session('user_id');
$ticketCounts = Ticket::where('user_id', $userId)
->selectRaw('status, COUNT(*) as count')
->groupBy('status')
->pluck('count', 'status');
$statuses = ['Open', 'In Progress', 'Closed'];
$counts = [];
foreach ($statuses as $status) {
$counts[$status] = $ticketCounts[$status] ?? 0; // Use null coalescing operator
}
return view('users.dashboard', compact('counts')); // compact('counts')
}
// ==========================================================
// 2. TICKET STATUS CHECK (Public Methods)
// ==========================================================
/**
* Show the form for users to check their ticket status by ID/Email.
*/
public function showStatusForm()
{
return view('ticket.status');
}
/**
* Handle the form submission from the status check page and display the ticket result.
*/
public function checkStatus(Request $request)
{
$request->validate([
'ticket_id' => 'required|string',
'email' => 'required|email',
]);
// Find ticket by ID OR the newly added reference_id
$ticket = Ticket::where('id', $request->ticket_id)
->orWhere('reference_id', $request->ticket_id)
->with(['user', 'category', 'history.user']) // Relationships load เคเคฐเฅเค
->first();
if ($ticket) {
// Check if the user's email matches the email provided in the form
// Note: $ticket->user relationship must be defined in the Ticket model
if ($ticket->user && strtolower($ticket->user->email) === strtolower($request->email)) {
// Return the detailed status view
return view('ticket.status_result', compact('ticket'));
}
}
// If ticket not found or email does not match
return back()->withErrors(['status' => 'Ticket not found or email address does not match the record. Please check the Ticket ID/Reference ID and Email.']);
}
}