$attributes */ public function attachOnIssue(ServiceQueue $queue, array &$attributes): void { if (data_get($attributes, 'metadata.workflow_id')) { return; } $workflow = Workflow::query() ->where('owner_ref', $queue->owner_ref) ->where('organization_id', $queue->organization_id) ->where('is_active', true) ->when($queue->branch_id, fn ($q) => $q->where(fn ($inner) => $inner->whereNull('branch_id')->orWhere('branch_id', $queue->branch_id))) ->whereHas('steps', fn ($q) => $q->where('service_queue_id', $queue->id)) ->first(); if (! $workflow) { return; } $firstStep = $workflow->steps() ->where('service_queue_id', $queue->id) ->orderBy('sort_order') ->first(); if (! $firstStep) { return; } $metadata = $attributes['metadata'] ?? []; $metadata['workflow_id'] = $workflow->id; $metadata['workflow_step'] = $firstStep->sort_order; $attributes['metadata'] = $metadata; } /** Advance completed ticket to the next workflow step queue, if configured. */ public function advanceAfterCompletion(Ticket $ticket): ?Ticket { $workflowId = data_get($ticket->metadata, 'workflow_id'); $stepOrder = (int) data_get($ticket->metadata, 'workflow_step', 0); if (! $workflowId) { return null; } $workflow = Workflow::find($workflowId); if (! $workflow || ! $workflow->is_active) { return null; } $nextStep = WorkflowStep::where('workflow_id', $workflow->id) ->where('sort_order', '>', $stepOrder) ->orderBy('sort_order') ->first(); if (! $nextStep?->service_queue_id) { return null; } $toQueue = ServiceQueue::find($nextStep->service_queue_id); if (! $toQueue) { return null; } $transferred = $this->engine->transfer($ticket, $toQueue, null, 'Workflow advance', null); $transferred->update([ 'metadata' => array_merge($transferred->metadata ?? [], [ 'workflow_id' => $workflow->id, 'workflow_step' => $nextStep->sort_order, ]), ]); return $transferred; } /** * @return array */ public function industryTemplate(string $template): array { return config("qms.workflow_templates.{$template}", config('qms.workflow_templates.custom', [])); } }