Deploy Ladill Queue / deploy (push) Successful in 56s
Phases 1–6: tickets, counters, displays, appointments, workflows, rules, analytics, reports, feedback, admin, device API, and Gitea deploy workflow for queue.ladill.com. Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
2.9 KiB
PHP
100 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Qms;
|
|
|
|
use App\Models\ServiceQueue;
|
|
use App\Models\Ticket;
|
|
use App\Models\Workflow;
|
|
use App\Models\WorkflowStep;
|
|
|
|
class WorkflowService
|
|
{
|
|
public function __construct(
|
|
protected QueueEngine $engine,
|
|
) {}
|
|
|
|
/**
|
|
* @param array<string, mixed> $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<int, array{name: string, queue_id: int|null, sort_order: int}>
|
|
*/
|
|
public function industryTemplate(string $template): array
|
|
{
|
|
return config("qms.workflow_templates.{$template}", config('qms.workflow_templates.custom', []));
|
|
}
|
|
}
|