132 lines
4.1 KiB
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(),
|
|
]);
|
|
}
|
|
}
|