Initial Ladill Queue release — enterprise QMS standalone app.
Deploy Ladill Queue / deploy (push) Successful in 56s
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>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
<?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', []));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user