phase 6 added helpdesk
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Modules\Helpdesk\Models\KanbanBoard;
|
||||
use Modules\Helpdesk\Models\Status;
|
||||
use Modules\Helpdesk\Models\Ticket;
|
||||
use Modules\Helpdesk\Services\WorkflowNotificationService;
|
||||
|
||||
final class TicketBoardController extends Controller
|
||||
{
|
||||
public function __invoke(Request $request, Ticket $ticket, WorkflowNotificationService $workflow): RedirectResponse
|
||||
{
|
||||
Gate::authorize('update', $ticket);
|
||||
|
||||
$validated = $request->validate([
|
||||
'board_id' => ['required', 'integer', Rule::exists('helpdesk_kanban_boards', 'id')],
|
||||
'return_to_board_id' => ['nullable', 'integer', Rule::exists('helpdesk_kanban_boards', 'id')],
|
||||
]);
|
||||
|
||||
$targetBoardId = (int) $validated['board_id'];
|
||||
|
||||
$targetBoard = KanbanBoard::query()
|
||||
->with(['statuses' => fn ($query) => $query->orderBy('helpdesk_kanban_board_statuses.sort_order')->orderBy('helpdesk_statuses.sort_order')->orderBy('helpdesk_statuses.name')])
|
||||
->findOrFail($targetBoardId);
|
||||
|
||||
if ($targetBoard->statuses->isEmpty()) {
|
||||
$this->ensureBoardHasStatuses($targetBoardId);
|
||||
$targetBoard->load(['statuses' => fn ($query) => $query->orderBy('helpdesk_kanban_board_statuses.sort_order')->orderBy('helpdesk_statuses.sort_order')->orderBy('helpdesk_statuses.name')]);
|
||||
}
|
||||
|
||||
$fresh = DB::transaction(function () use ($ticket, $targetBoard): Ticket {
|
||||
$lockedTicket = Ticket::query()
|
||||
->visibleTo(Auth::user())
|
||||
->lockForUpdate()
|
||||
->findOrFail($ticket->id);
|
||||
|
||||
$targetStatus = $targetBoard->statuses->firstWhere('id', (int) $lockedTicket->status_id)
|
||||
?: $targetBoard->statuses->first();
|
||||
|
||||
if ($targetStatus === null) {
|
||||
$targetStatus = Status::query()->orderBy('sort_order')->orderBy('name')->firstOrFail();
|
||||
$this->addStatusToBoard($targetBoard->id, $targetStatus->id);
|
||||
}
|
||||
|
||||
$updates = [
|
||||
'board_id' => $targetBoard->id,
|
||||
'status_id' => $targetStatus->id,
|
||||
'completed_at' => $targetStatus->is_closed ? now() : null,
|
||||
'last_activity_at' => now(),
|
||||
];
|
||||
|
||||
if (DB::getSchemaBuilder()->hasColumn('helpdesk_tickets', 'updated_at')) {
|
||||
$updates['updated_at'] = now();
|
||||
}
|
||||
|
||||
$affected = DB::table('helpdesk_tickets')
|
||||
->where('id', $lockedTicket->id)
|
||||
->update($updates);
|
||||
|
||||
if ($affected < 1) {
|
||||
throw new \RuntimeException('Ticket board update did not persist.');
|
||||
}
|
||||
|
||||
return Ticket::query()
|
||||
->with(['status', 'priority', 'category', 'project', 'team', 'product', 'tags', 'checklistItems', 'board'])
|
||||
->findOrFail($lockedTicket->id);
|
||||
});
|
||||
|
||||
$workflow->dispatch($fresh, 'ticket.updated', Auth::user());
|
||||
|
||||
return redirect()
|
||||
->route('helpdesk.kanban', ['board_id' => $targetBoardId])
|
||||
->with('success', 'Ticket ' . $fresh->reference . ' moved to ' . $targetBoard->name . '.');
|
||||
}
|
||||
|
||||
private function ensureBoardHasStatuses(int $boardId): void
|
||||
{
|
||||
Status::query()
|
||||
->orderBy('sort_order')
|
||||
->orderBy('name')
|
||||
->get(['id'])
|
||||
->values()
|
||||
->each(function (Status $status, int $index) use ($boardId): void {
|
||||
$this->addStatusToBoard($boardId, (int) $status->id, ($index + 1) * 10);
|
||||
});
|
||||
}
|
||||
|
||||
private function addStatusToBoard(int $boardId, int $statusId, int $sortOrder = 999): void
|
||||
{
|
||||
DB::table('helpdesk_kanban_board_statuses')->updateOrInsert(
|
||||
['board_id' => $boardId, 'status_id' => $statusId],
|
||||
['sort_order' => $sortOrder, 'updated_at' => now(), 'created_at' => now()],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user