d2d.emegrendeles.hu/app/Livewire/SupplierPortal/ProductGroupTree.php

132 lines
4.1 KiB
PHP

<?php
namespace App\Livewire\SupplierPortal;
use App\Models\Product;
use App\Models\ProductGroup;
use Illuminate\Contracts\View\View;
use Livewire\Component;
class ProductGroupTree extends Component
{
public ?int $selectedGroupId = null;
public function mount(): void
{
$this->selectedGroupId = null;
}
public function selectGroup(?int $groupId): void
{
$this->selectedGroupId = $groupId;
$this->dispatch('product-group-selected', groupId: $groupId);
}
/**
* Visszaadja a supplier termékeinek csoportjait fa struktúrában.
*
* @return array<int, array<string, mixed>>
*/
protected function buildTree(): array
{
$supplierId = auth()->user()->supplier_id;
// A supplier összes termékének product_group_id értékei
$groupIds = Product::query()
->where('supplier_id', $supplierId)
->whereNotNull('product_group_id')
->pluck('product_group_id')
->unique()
->values()
->toArray();
if (empty($groupIds)) {
return [];
}
// Termékszámok csoportonként
$productCountsByGroup = Product::query()
->where('supplier_id', $supplierId)
->whereNotNull('product_group_id')
->groupBy('product_group_id')
->selectRaw('product_group_id, COUNT(*) as products_count')
->pluck('products_count', 'product_group_id')
->toArray();
// Minden érintett csoport + felmenői szükségesek a fa felépítéséhez
$allRequiredIds = [];
foreach ($groupIds as $groupId) {
$ancestors = ProductGroup::ancestorsOf($groupId)->pluck('id')->toArray();
$allRequiredIds = array_unique(array_merge($allRequiredIds, $ancestors, [$groupId]));
}
// Csoportok lekérdezése mélységgel, gyökértől
$groups = ProductGroup::withDepth()
->whereIn('id', $allRequiredIds)
->orderBy('_lft')
->get();
// Termékszám hozzárendelése (beleértve a gyerek csoportok összesítését)
foreach ($groups as $group) {
$group->products_count = $productCountsByGroup[$group->id] ?? 0;
}
// Fa struktúra felépítése
return $this->buildTreeFromCollection($groups);
}
/**
* @param \Illuminate\Support\Collection $groups
* @return array<int, array<string, mixed>>
*/
protected function buildTreeFromCollection($groups): array
{
$tree = [];
$indexed = [];
foreach ($groups as $group) {
// A depth=0 gyökércsomópontot (pl. "Termékek" placeholder) csak referenciaként
// tartjuk nyilván, de nem jelenítjük meg közvetlenül a fában.
if ($group->depth === 0) {
$indexed[$group->id] = [
'id' => $group->id,
'name' => $group->name,
'depth' => $group->depth,
'products_count' => 0,
'children' => [],
];
continue;
}
$item = [
'id' => $group->id,
'name' => $group->name,
'depth' => $group->depth,
'products_count' => $group->products_count,
'children' => [],
];
$indexed[$group->id] = &$item;
if (! isset($indexed[$group->parent_id]) || $indexed[$group->parent_id]['depth'] < 0) {
$tree[] = &$item;
} elseif ($indexed[$group->parent_id]['depth'] === 0) {
// Közvetlen gyerek a root placeholder-nek → top-level elem a fában
$tree[] = &$item;
} else {
$indexed[$group->parent_id]['children'][] = &$item;
}
unset($item);
}
return $tree;
}
public function render(): View
{
return view('livewire.supplier-portal.product-group-tree', [
'tree' => $this->buildTree(),
]);
}
}