*/ public function forTenant(Tenant $tenant): Collection { return FeaturedGroup::query() ->where('tenant_code', $tenant->codigo) ->where('source_type', FeaturedGroupSource::Category) ->whereHas('category', fn ($query) => $query->where('tenant_code', $tenant->codigo)) ->with('category') ->orderBy('group_order') ->orderBy('id') ->get(); } /** @param array{category_name: string, is_featured: bool} $data */ public function create(Tenant $tenant, array $data): FeaturedGroup { return DB::transaction(function () use ($tenant, $data): FeaturedGroup { $category = $tenant->categories()->create([ 'nombre' => $data['category_name'], ]); $featuredGroup = FeaturedGroup::query()->create([ 'tenant_code' => $tenant->codigo, 'source_type' => FeaturedGroupSource::Category, 'category_id' => $category->id, 'product_layout' => $this->productLayout($data['is_featured']), 'group_layout' => GroupLayout::Paginated, 'group_name' => $data['category_name'], 'group_order' => $this->nextOrder($tenant), ]); return $featuredGroup->setRelation('category', $category); }); } /** @param array{category_name: string, is_featured: bool} $data */ public function update( Tenant $tenant, FeaturedGroup $featuredGroup, array $data, ): FeaturedGroup { return DB::transaction(function () use ($tenant, $featuredGroup, $data): FeaturedGroup { $featuredGroup = FeaturedGroup::query() ->whereKey($featuredGroup->getKey()) ->where('tenant_code', $tenant->codigo) ->where('source_type', FeaturedGroupSource::Category) ->lockForUpdate() ->firstOrFail(); $category = Category::query() ->whereKey($featuredGroup->category_id) ->where('tenant_code', $tenant->codigo) ->lockForUpdate() ->firstOrFail(); $category->update(['nombre' => $data['category_name']]); $featuredGroup->update([ 'group_name' => $data['category_name'], 'product_layout' => $this->productLayout($data['is_featured']), 'group_layout' => GroupLayout::Paginated, ]); return $featuredGroup->setRelation('category', $category); }); } private function productLayout(bool $isFeatured): ProductLayout { return $isFeatured ? ProductLayout::Row : ProductLayout::ColumnWithCart; } private function nextOrder(Tenant $tenant): int { $maximumOrder = FeaturedGroup::query() ->where('tenant_code', $tenant->codigo) ->max('group_order'); return $maximumOrder === null ? 0 : ((int) $maximumOrder) + 1; } }