policy->view($request->user()), 403); $nodes = TaxonomyNode::query() ->with('type:id,key,name') ->where('organization_id', $this->tenant->id()) ->when($request->string('taxonomyTypeId')->isNotEmpty(), fn ($query) => $query->where('taxonomy_type_id', $request->string('taxonomyTypeId'))) ->when($request->string('status')->isNotEmpty(), fn ($query) => $query->where('status', $request->string('status'))) ->when($request->string('search')->isNotEmpty(), function ($query) use ($request) { $search = '%'.str_replace(['%', '_'], ['\\%', '\\_'], $request->string('search')).'%'; $query->where(fn ($nested) => $nested->where('name', 'like', $search)->orWhere('code', 'like', $search)); }) ->orderBy('name') ->limit(500) ->get() ->map(fn (TaxonomyNode $node) => $this->payload($node)); return response()->json(['data' => $nodes]); } public function store(StoreTaxonomyNodeRequest $request): JsonResponse { abort_unless($this->policy->manage($request->user()), 403); $data = $request->validated(); $type = TaxonomyType::query()->where('organization_id', $this->tenant->id())->findOrFail($data['taxonomyTypeId']); $this->hierarchy->assertValidParent($this->tenant->id(), $type->getKey(), $data['parentId'] ?? null); $node = TaxonomyNode::query()->create([ 'organization_id' => $this->tenant->id(), 'taxonomy_type_id' => $type->getKey(), 'parent_id' => $data['parentId'] ?? null, 'name' => $data['name'], 'description' => $data['description'] ?? null, 'code' => $data['code'] ?? null, 'metadata' => $data['metadata'] ?? null, 'status' => TaxonomyStatus::Active, 'created_by' => $request->user()->getKey(), ]); return response()->json(['data' => $this->payload($node->load('type:id,key,name'))], 201); } public function update(UpdateTaxonomyNodeRequest $request, string $node): JsonResponse { abort_unless($this->policy->manage($request->user()), 403); $taxonomyNode = TaxonomyNode::query()->where('organization_id', $this->tenant->id())->findOrFail($node); $data = $request->validated(); if (array_key_exists('parentId', $data)) { $this->hierarchy->assertValidParent($this->tenant->id(), $taxonomyNode->taxonomy_type_id, $data['parentId'], $taxonomyNode->getKey()); $taxonomyNode->parent_id = $data['parentId']; } foreach (['name', 'description', 'code', 'status', 'metadata'] as $attribute) { if (array_key_exists($attribute, $data)) { $taxonomyNode->{$attribute} = $data[$attribute]; } } $taxonomyNode->save(); return response()->json(['data' => $this->payload($taxonomyNode->load('type:id,key,name'))]); } private function payload(TaxonomyNode $node): array { return [ 'id' => $node->getKey(), 'taxonomyType' => $node->type ? ['id' => $node->type->getKey(), 'key' => $node->type->key, 'name' => $node->type->name] : null, 'parentId' => $node->parent_id, 'name' => $node->name, 'description' => $node->description, 'code' => $node->code, 'status' => $node->status->value, 'metadata' => $node->metadata, ]; } }