Expose Care service-token APIs to create queues and counters.
Deploy Ladill Queue / deploy (push) Successful in 1m0s
Deploy Ladill Queue / deploy (push) Successful in 1m0s
Specialty module activation needs idempotent queue/counter upserts (by external_key or name+branch) plus soft deactivate, without opening Queue admin for each Care specialty. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,6 +4,7 @@ namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Api\Concerns\ScopesApiToAccount;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Branch;
|
||||
use App\Models\Counter;
|
||||
use App\Models\ServiceQueue;
|
||||
use App\Services\Qms\AuditLogger;
|
||||
@@ -22,16 +23,10 @@ class CounterController extends Controller
|
||||
|
||||
$counters = Counter::owned($owner)
|
||||
->where('organization_id', $organization->id)
|
||||
->with('serviceQueues')
|
||||
->with(['serviceQueues', 'branch'])
|
||||
->orderBy('name')
|
||||
->get()
|
||||
->map(fn (Counter $c) => [
|
||||
'uuid' => $c->uuid,
|
||||
'name' => $c->name,
|
||||
'code' => $c->code,
|
||||
'status' => $c->status,
|
||||
'queues' => $c->serviceQueues->pluck('name'),
|
||||
]);
|
||||
->map(fn (Counter $c) => $this->serializeCounter($c));
|
||||
|
||||
return response()->json(['data' => $counters]);
|
||||
}
|
||||
@@ -45,30 +40,156 @@ class CounterController extends Controller
|
||||
$validated = $request->validate([
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'code' => ['nullable', 'string', 'max:50'],
|
||||
'branch_id' => ['required', 'integer'],
|
||||
'branch_id' => ['nullable', 'integer'],
|
||||
'branch_name' => ['nullable', 'string', 'max:255'],
|
||||
'department_id' => ['nullable', 'integer'],
|
||||
'queue_ids' => ['nullable', 'array'],
|
||||
'queue_ids.*' => ['uuid'],
|
||||
'queue_uuids' => ['nullable', 'array'],
|
||||
'queue_uuids.*' => ['uuid'],
|
||||
'external_key' => ['nullable', 'string', 'max:191'],
|
||||
'is_active' => ['nullable', 'boolean'],
|
||||
]);
|
||||
|
||||
$branch = $this->resolveBranch($request, $organization->id, $owner, $validated);
|
||||
abort_unless($branch, 422, 'A valid branch_id or branch_name is required.');
|
||||
|
||||
$externalKey = isset($validated['external_key']) ? trim((string) $validated['external_key']) : '';
|
||||
if ($externalKey !== '') {
|
||||
$existing = Counter::owned($owner)
|
||||
->where('organization_id', $organization->id)
|
||||
->where('settings->external_key', $externalKey)
|
||||
->first();
|
||||
|
||||
if ($existing) {
|
||||
$existing->update([
|
||||
'name' => $validated['name'],
|
||||
'code' => $validated['code'] ?? $existing->code,
|
||||
'branch_id' => $branch->id,
|
||||
'department_id' => $validated['department_id'] ?? $existing->department_id,
|
||||
'is_active' => array_key_exists('is_active', $validated)
|
||||
? (bool) $validated['is_active']
|
||||
: true,
|
||||
'settings' => array_merge($existing->settings ?? [], ['external_key' => $externalKey]),
|
||||
]);
|
||||
$this->syncQueues($existing, $owner, $validated);
|
||||
AuditLogger::record($owner, 'counter.updated', $organization->id, $owner, Counter::class, $existing->id);
|
||||
|
||||
return response()->json(['data' => $this->serializeCounter($existing->fresh(['serviceQueues', 'branch']))]);
|
||||
}
|
||||
}
|
||||
|
||||
$counter = Counter::create([
|
||||
'owner_ref' => $owner,
|
||||
'organization_id' => $organization->id,
|
||||
'branch_id' => $validated['branch_id'],
|
||||
'branch_id' => $branch->id,
|
||||
'department_id' => $validated['department_id'] ?? null,
|
||||
'name' => $validated['name'],
|
||||
'code' => $validated['code'] ?? null,
|
||||
'status' => 'offline',
|
||||
'is_active' => true,
|
||||
'is_active' => array_key_exists('is_active', $validated) ? (bool) $validated['is_active'] : true,
|
||||
'settings' => $externalKey !== '' ? ['external_key' => $externalKey] : null,
|
||||
]);
|
||||
|
||||
if (! empty($validated['queue_ids'])) {
|
||||
$queueIds = ServiceQueue::owned($owner)->whereIn('uuid', $validated['queue_ids'])->pluck('id');
|
||||
$counter->serviceQueues()->sync($queueIds);
|
||||
}
|
||||
$this->syncQueues($counter, $owner, $validated);
|
||||
|
||||
AuditLogger::record($owner, 'counter.created', $organization->id, $owner, Counter::class, $counter->id);
|
||||
|
||||
return response()->json(['data' => ['uuid' => $counter->uuid, 'name' => $counter->name]], 201);
|
||||
return response()->json(['data' => $this->serializeCounter($counter->fresh(['serviceQueues', 'branch']))], 201);
|
||||
}
|
||||
|
||||
public function update(Request $request, Counter $counter): JsonResponse
|
||||
{
|
||||
$this->authorizeAbility($request, 'counters.manage');
|
||||
$this->authorizeOwner($request, $counter);
|
||||
|
||||
$validated = $request->validate([
|
||||
'name' => ['sometimes', 'string', 'max:255'],
|
||||
'code' => ['nullable', 'string', 'max:50'],
|
||||
'is_active' => ['sometimes', 'boolean'],
|
||||
'queue_ids' => ['nullable', 'array'],
|
||||
'queue_ids.*' => ['uuid'],
|
||||
'queue_uuids' => ['nullable', 'array'],
|
||||
'queue_uuids.*' => ['uuid'],
|
||||
]);
|
||||
|
||||
$counter->update(array_filter([
|
||||
'name' => $validated['name'] ?? null,
|
||||
'code' => array_key_exists('code', $validated) ? $validated['code'] : null,
|
||||
'is_active' => array_key_exists('is_active', $validated) ? (bool) $validated['is_active'] : null,
|
||||
], fn ($v) => $v !== null));
|
||||
|
||||
if (array_key_exists('queue_ids', $validated) || array_key_exists('queue_uuids', $validated)) {
|
||||
$this->syncQueues($counter, $this->ownerRef($request), $validated);
|
||||
}
|
||||
|
||||
AuditLogger::record(
|
||||
$this->ownerRef($request),
|
||||
'counter.updated',
|
||||
$counter->organization_id,
|
||||
$this->ownerRef($request),
|
||||
Counter::class,
|
||||
$counter->id,
|
||||
);
|
||||
|
||||
return response()->json(['data' => $this->serializeCounter($counter->fresh(['serviceQueues', 'branch']))]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $validated
|
||||
*/
|
||||
protected function resolveBranch(Request $request, int $organizationId, string $owner, array $validated): ?Branch
|
||||
{
|
||||
if (! empty($validated['branch_id'])) {
|
||||
return Branch::owned($owner)
|
||||
->where('organization_id', $organizationId)
|
||||
->where('id', (int) $validated['branch_id'])
|
||||
->first();
|
||||
}
|
||||
|
||||
$branchName = trim((string) ($validated['branch_name'] ?? ''));
|
||||
if ($branchName === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Branch::owned($owner)
|
||||
->where('organization_id', $organizationId)
|
||||
->whereRaw('LOWER(name) = ?', [strtolower($branchName)])
|
||||
->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $validated
|
||||
*/
|
||||
protected function syncQueues(Counter $counter, string $owner, array $validated): void
|
||||
{
|
||||
$uuids = $validated['queue_uuids'] ?? $validated['queue_ids'] ?? null;
|
||||
if ($uuids === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$queueIds = ServiceQueue::owned($owner)->whereIn('uuid', $uuids)->pluck('id');
|
||||
$counter->serviceQueues()->sync($queueIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
protected function serializeCounter(Counter $c): array
|
||||
{
|
||||
return [
|
||||
'uuid' => $c->uuid,
|
||||
'name' => $c->name,
|
||||
'code' => $c->code,
|
||||
'status' => $c->status,
|
||||
'is_active' => $c->is_active,
|
||||
'branch' => $c->branch?->name,
|
||||
'external_key' => data_get($c->settings, 'external_key'),
|
||||
'queues' => $c->serviceQueues->map(fn (ServiceQueue $q) => [
|
||||
'uuid' => $q->uuid,
|
||||
'name' => $q->name,
|
||||
'prefix' => $q->prefix,
|
||||
])->values()->all(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user