### Install Tickets for Laravel with Composer and Artisan Source: https://github.com/roundly-consulting/tickets-for-laravel/blob/main/README.md Run these commands to install the package, publish its configuration and migrations, and run the migrations. Requires PHP 8.4, Laravel 12 or 13, and MySQL or PostgreSQL. ```bash composer require roundly-consulting/tickets-for-laravel php artisan tickets:install php artisan migrate ``` -------------------------------- ### Use the Tickets facade to manage tickets Source: https://github.com/roundly-consulting/tickets-for-laravel/blob/main/README.md This example shows how to define an agent gate, create a category with defaults, open a ticket, claim and reply to it, add an internal note, and resolve it. It also demonstrates retrieving the status and thread. The $customer and $agent variables represent your user models. ```php use Illuminate\Support\Facades\Gate; use RoundlyConsulting\Tickets\Facades\Tickets; // Who is an agent is your call: is_support stands for your own agent flag. An undefined ability denies. Gate::define('tickets.agent', fn ($user) => $user->is_support); // A category, once: its defaults apply to every ticket filed under it. $hardware = Tickets::categories()->make(['en' => 'Hardware', 'sk' => 'Hardvér']) ->defaults(priority: 'high', dueIn: 'P1D') ->create(); // The customer opens a ticket — numbered TCK-1, high priority, due in a day. $ticket = Tickets::make() ->subject('Printer on floor 3 is jammed') ->description('Paper jam error E-102 since this morning.') ->requester($customer) ->category($hardware) ->create(); // An agent takes it, answers the customer and leaves a note only agents see. Tickets::for($ticket)->by($agent)->claim()->start(); Tickets::for($ticket)->by($agent)->reply('A technician is on the way.', transition: 'wait'); Tickets::for($ticket)->by($agent)->note('Roller worn out, order a spare.'); // The customer's reply puts it back in the queue; the agent resolves it. Tickets::for($ticket)->by($customer)->reply('Works again, thanks!'); Tickets::for('TCK-1')->by($agent)->resolve('Roller replaced.'); Tickets::for('TCK-1')->status(); // TicketStatus::Resolved Tickets::for('TCK-1')->thread(); // the two public replies — never the note ``` -------------------------------- ### Schedule tickets:sweep and lifecycle:sweep commands Source: https://github.com/roundly-consulting/tickets-for-laravel/blob/main/README.md Add these scheduled commands to routes/console.php. The tickets:sweep command runs every five minutes to update overdue and due-soon flags, while lifecycle:sweep runs every minute to close resolved tickets after 7 days. ```php // routes/console.php use Illuminate\Support\Facades\Schedule; Schedule::command('tickets:sweep')->everyFiveMinutes(); // overdue and due-soon flags Schedule::command('lifecycle:sweep')->everyMinute(); // closes resolved tickets after 7 days ```