Files
KanbanGit/app/Actions/Tickets/CreateProjectTicket.php
T
Koda 5f74ddd964
linter / quality (pull_request) Successful in 1m25s
tests / ci (8.4) (pull_request) Successful in 1m42s
Add ticket create notification event support
2026-04-24 19:35:13 +00:00

92 lines
3.2 KiB
PHP

<?php
namespace App\Actions\Tickets;
use App\Actions\Notifications\BuildTicketCreatedPayload;
use App\Actions\Notifications\TicketCreated;
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;
use Illuminate\Support\Facades\DB;
class CreateProjectTicket
{
public function __construct(
private readonly BuildTicketCreatedPayload $buildTicketCreatedPayload,
private readonly CreateTicketWorklogEntry $createTicketWorklogEntry,
) {}
/**
* @param array{
* acceptance_criteria: string|null,
* assignee_user_id?: int|null,
* description: string|null,
* story_points?: int|null,
* ticket_priority_id: int,
* ticket_status_id: int,
* ticket_type_id: int,
* title: string
* } $attributes
*/
public function handle(Project $project, array $attributes, ?User $actor = null): Ticket
{
return DB::transaction(function () use ($actor, $attributes, $project): Ticket {
$nextSequenceNumber = (int) Ticket::query()
->where('project_id', $project->id)
->max('sequence_number') + 1;
$ticketStatus = TicketStatus::query()
->where('project_id', $project->id)
->findOrFail(Arr::get($attributes, 'ticket_status_id'));
$ticket = Ticket::query()->create([
'acceptance_criteria' => Arr::get($attributes, 'acceptance_criteria'),
'assignee_user_id' => Arr::get($attributes, 'assignee_user_id'),
'author_user_id' => $actor?->id,
'description' => Arr::get($attributes, 'description'),
'project_id' => $project->id,
'sequence_number' => $nextSequenceNumber,
'ticket_key' => "{$project->key}-{$nextSequenceNumber}",
'ticket_priority_id' => Arr::get($attributes, 'ticket_priority_id'),
'ticket_status_id' => $ticketStatus->id,
'ticket_type_id' => Arr::get($attributes, 'ticket_type_id'),
'title' => Arr::get($attributes, 'title'),
'story_points' => Arr::get($attributes, 'story_points'),
]);
$occurredAt = CarbonImmutable::now();
if ($actor !== null) {
$this->createTicketWorklogEntry->handle(
$ticket,
$actor,
TicketWorklogEntryType::Created,
"Ticket was created in {$ticketStatus->name}.",
[
'from' => null,
'to' => [
'label' => $ticketStatus->name,
'ticket_status_id' => $ticketStatus->id,
],
],
);
}
TicketCreated::dispatch(
$this->buildTicketCreatedPayload->handle(
$project,
$ticket,
$ticketStatus,
$actor,
$occurredAt,
),
);
return $ticket;
});
}
}