Files
KanbanGit/app/Actions/Tickets/MoveProjectTicket.php

106 lines
3.1 KiB
PHP

<?php
namespace App\Actions\Tickets;
use App\Actions\Notifications\BuildTicketStatusChangedPayload;
use App\Actions\Notifications\TicketStatusChanged;
use App\Enums\TicketWorklogEntryType;
use App\Models\Project;
use App\Models\Ticket;
use App\Models\TicketStatus;
use App\Models\User;
use Carbon\CarbonImmutable;
use Illuminate\Support\Arr;
class MoveProjectTicket
{
public function __construct(
private readonly BuildTicketStatusChangedPayload $buildTicketStatusChangedPayload,
private readonly CreateTicketWorklogEntry $createTicketWorklogEntry,
) {}
/**
* @param array{ticket_status_id: int} $validated
* @return array{destination_label: string, moved: bool}
*/
public function handle(Project $project, Ticket $ticket, User $user, array $validated): array
{
$ticketStatusId = (int) Arr::get($validated, 'ticket_status_id');
$destinationStatus = $project->ticketStatuses()
->with('boardColumn')
->findOrFail($ticketStatusId);
$ticket->loadMissing('ticketStatus.boardColumn');
$originStatusId = $ticket->ticket_status_id;
$originLabel = $this->statusLabel($ticket->ticketStatus);
$destinationLabel = $this->statusLabel($destinationStatus);
if ($ticket->ticket_status_id === $ticketStatusId) {
return [
'destination_label' => $destinationLabel,
'moved' => false,
];
}
$ticket->update([
'ticket_status_id' => $destinationStatus->id,
]);
$occurredAt = CarbonImmutable::now();
$this->createTicketWorklogEntry->handle(
$ticket->fresh(),
$user,
TicketWorklogEntryType::StatusChanged,
"Moved from {$originLabel} to {$destinationLabel}.",
[
'from' => [
'label' => $originLabel,
'ticket_status_id' => $originStatusId,
],
'to' => [
'label' => $destinationLabel,
'ticket_status_id' => $destinationStatus->id,
],
],
);
TicketStatusChanged::dispatch(
$this->buildTicketStatusChangedPayload->handle(
$project,
$ticket,
$user,
$originStatusId,
$originLabel,
$destinationStatus,
$destinationLabel,
$occurredAt,
),
);
return [
'destination_label' => $destinationLabel,
'moved' => true,
];
}
private function statusLabel(?TicketStatus $ticketStatus): string
{
if ($ticketStatus === null) {
return 'Unknown status';
}
if ($ticketStatus->boardColumn === null) {
return $ticketStatus->name;
}
if ($ticketStatus->boardColumn->name === $ticketStatus->name) {
return $ticketStatus->name;
}
return "{$ticketStatus->boardColumn->name} / {$ticketStatus->name}";
}
}