authorizeAbility($request, 'queues.view'); $owner = $this->ownerRef($request); $organization = $this->organization($request); $departments = Department::owned($owner) ->whereHas('branch', fn ($q) => $q->where('organization_id', $organization->id)) ->with('branch') ->orderBy('name') ->get() ->map(fn (Department $d) => $this->serialize($d)); return response()->json(['data' => $departments]); } public function store(Request $request): JsonResponse { $this->authorizeAbility($request, 'queues.manage'); $owner = $this->ownerRef($request); $organization = $this->organization($request); $validated = $request->validate([ 'name' => ['required', 'string', 'max:255'], 'type' => ['nullable', 'string', 'max:50'], 'branch_id' => ['nullable', 'integer'], 'branch_name' => ['nullable', 'string', 'max:255'], 'external_key' => ['nullable', 'string', 'max:191'], 'is_active' => ['nullable', 'boolean'], ]); $branch = $this->resolveBranch($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 = Department::owned($owner) ->where('external_key', $externalKey) ->first(); if ($existing) { $existing->update([ 'name' => $validated['name'], 'type' => $validated['type'] ?? $existing->type, 'branch_id' => $branch->id, 'is_active' => array_key_exists('is_active', $validated) ? (bool) $validated['is_active'] : true, ]); AuditLogger::record($owner, 'department.updated', $organization->id, $owner, Department::class, $existing->id); return response()->json(['data' => $this->serialize($existing->fresh('branch'))]); } } $byName = Department::owned($owner) ->where('branch_id', $branch->id) ->whereRaw('LOWER(name) = ?', [strtolower($validated['name'])]) ->first(); if ($byName) { $byName->update([ 'type' => $validated['type'] ?? $byName->type, 'external_key' => $externalKey !== '' ? $externalKey : $byName->external_key, 'is_active' => array_key_exists('is_active', $validated) ? (bool) $validated['is_active'] : true, ]); AuditLogger::record($owner, 'department.updated', $organization->id, $owner, Department::class, $byName->id); return response()->json(['data' => $this->serialize($byName->fresh('branch'))]); } $department = Department::create([ 'owner_ref' => $owner, 'branch_id' => $branch->id, 'name' => $validated['name'], 'type' => $validated['type'] ?? 'general', 'external_key' => $externalKey !== '' ? $externalKey : null, 'is_active' => array_key_exists('is_active', $validated) ? (bool) $validated['is_active'] : true, ]); AuditLogger::record($owner, 'department.created', $organization->id, $owner, Department::class, $department->id); return response()->json(['data' => $this->serialize($department->fresh('branch'))], 201); } /** * @param array $validated */ protected function resolveBranch(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(); } /** * @return array */ protected function serialize(Department $d): array { return [ 'id' => $d->id, 'name' => $d->name, 'type' => $d->type, 'external_key' => $d->external_key, 'is_active' => $d->is_active, 'branch' => $d->branch?->name, 'branch_id' => $d->branch_id, ]; } }