diff --git a/resources/js/components/Product/AddToCart.vue b/resources/js/components/Product/AddToCart.vue index df90beb5a..f9f83831b 100644 --- a/resources/js/components/Product/AddToCart.vue +++ b/resources/js/components/Product/AddToCart.vue @@ -65,7 +65,10 @@ }, async add() { - if (Object.values(this.product.children).length && window.location.pathname !== this.product.url && !config.show_swatches) { + if ('children' in this.product + && Object.values(this.product.children).length + && window.location.pathname !== this.product.url + && !config.show_swatches) { Turbolinks.visit(this.product.url) return; } diff --git a/resources/views/product/overview.blade.php b/resources/views/product/overview.blade.php index 014245251..9e6c55a43 100644 --- a/resources/views/product/overview.blade.php +++ b/resources/views/product/overview.blade.php @@ -19,7 +19,8 @@
{!! $product->description !!}
- @include('rapidez::product.partials.addtocart') + @includeWhen($product->type == 'grouped', 'rapidez::product.partials.grouped') + @includeWhen($product->type !== 'grouped', 'rapidez::product.partials.addtocart') diff --git a/resources/views/product/partials/grouped.blade.php b/resources/views/product/partials/grouped.blade.php new file mode 100644 index 000000000..665cec2a7 --- /dev/null +++ b/resources/views/product/partials/grouped.blade.php @@ -0,0 +1,42 @@ +
+
+ +
+
+ @{{ simpleProduct.name }} +
+
@{{ (simpleProduct.special_price || simpleProduct.price) | price }}
+
@{{ simpleProduct.price | price }}
+
+
+ + @if(!$product->in_stock) +

@lang('Sorry! This product is currently out of stock.')

+ @else + + + + + + + + + @lang('Add to cart') + @lang('Adding')... + @lang('Added') + + @endif +
+
+
+
diff --git a/src/Commands/ValidateCommand.php b/src/Commands/ValidateCommand.php index 6de237633..c1039065d 100644 --- a/src/Commands/ValidateCommand.php +++ b/src/Commands/ValidateCommand.php @@ -55,8 +55,8 @@ public function validateMagentoSettings() $superAttributesCount = count($attributeModel::getCachedWhere(fn ($attribute) => $attribute['super'])); $joinCount = ($superAttributesCount * 2) + (count($nonFlatAttributes) * 3) + 4; - if ($joinCount > 61) { - $this->error('Most likely the queries needed for Rapidez will exceed 61 joins when indexing or viewing products so you have to reduce them by adding more attributes to the flat tables'); + if ($joinCount > 58) { + $this->error('Most likely the queries needed for Rapidez will exceed 58 joins when indexing or viewing products so you have to reduce them by adding more attributes to the flat tables'); } $this->info('The validation finished, if there where any errors; fix them before you continue. See: https://rapidez.io/docs/0.x/installation#flat-tables'); diff --git a/src/Http/Controllers/ProductController.php b/src/Http/Controllers/ProductController.php index 3656788bb..349b29971 100644 --- a/src/Http/Controllers/ProductController.php +++ b/src/Http/Controllers/ProductController.php @@ -13,7 +13,7 @@ public function show(int $productId) ->withEventyGlobalScopes('productpage.scopes') ->findOrFail($productId); - $attributes = ['id', 'name', 'sku', 'super_attributes', 'children', 'price', 'special_price', 'images', 'url']; + $attributes = ['id', 'name', 'sku', 'super_attributes', 'children', 'grouped', 'price', 'special_price', 'images', 'url']; $attributes = Eventy::filter('productpage.frontend.attributes', $attributes); foreach ($product->super_attributes ?: [] as $superAttribute) { diff --git a/src/Models/Product.php b/src/Models/Product.php index da20a3462..c235d4240 100644 --- a/src/Models/Product.php +++ b/src/Models/Product.php @@ -11,6 +11,7 @@ use Rapidez\Core\Models\Scopes\Product\WithProductAttributesScope; use Rapidez\Core\Models\Scopes\Product\WithProductCategoryIdsScope; use Rapidez\Core\Models\Scopes\Product\WithProductChildrenScope; +use Rapidez\Core\Models\Scopes\Product\WithProductGroupedScope; use Rapidez\Core\Models\Scopes\Product\WithProductRelationIdsScope; use Rapidez\Core\Models\Scopes\Product\WithProductStockScope; use Rapidez\Core\Models\Scopes\Product\WithProductSuperAttributesScope; @@ -39,9 +40,10 @@ protected static function booting(): void static::addGlobalScope(new WithProductCategoryIdsScope()); static::addGlobalScope(new WithProductRelationIdsScope()); static::addGlobalScope(new WithProductChildrenScope()); + static::addGlobalScope(new WithProductGroupedScope()); static::addGlobalScope('defaults', function (Builder $builder) { $builder - ->whereNotIn($builder->getQuery()->from.'.type_id', ['grouped', 'bundle']) + ->whereNotIn($builder->getQuery()->from.'.type_id', ['bundle']) ->groupBy($builder->getQuery()->from.'.entity_id'); }); } @@ -62,6 +64,7 @@ public function getCasts(): array 'relation_ids' => CommaSeparatedToArray::class, 'upsell_ids' => CommaSeparatedToArray::class, 'children' => Children::class, + 'grouped' => Children::class, 'qty_increments' => 'int', ], $this->getSuperAttributeCasts(), @@ -91,16 +94,20 @@ public function scopeByIds(Builder $query, array $productIds): Builder public function getPriceAttribute($price) { - if (!(array) $this->children) { - return $price; + if ($this->type == 'configurable') { + return collect($this->children)->min->price; } - return collect($this->children)->min->price; + if ($this->type == 'grouped') { + return collect($this->grouped)->min->price; + } + + return $price; } public function getSpecialPriceAttribute($specialPrice) { - if (!(array) $this->children) { + if (!in_array($this->type, ['configurable', 'grouped'])) { if ($this->special_from_date && $this->special_from_date > now()->toDateString()) { return null; } @@ -112,7 +119,7 @@ public function getSpecialPriceAttribute($specialPrice) return $specialPrice !== $this->price ? $specialPrice : null; } - return collect($this->children)->filter(function ($child) { + return collect($this->type == 'configurable' ? $this->children : $this->grouped)->filter(function ($child) { if (!$child->special_price) { return false; } diff --git a/src/Models/Scopes/Product/WithProductAttributesScope.php b/src/Models/Scopes/Product/WithProductAttributesScope.php index b7ba76d3d..e8ff6af4f 100644 --- a/src/Models/Scopes/Product/WithProductAttributesScope.php +++ b/src/Models/Scopes/Product/WithProductAttributesScope.php @@ -24,7 +24,8 @@ public function apply(Builder $builder, Model $model) $builder ->addSelect($builder->getQuery()->from.'.entity_id AS id') - ->addSelect($builder->getQuery()->from.'.sku'); + ->addSelect($builder->getQuery()->from.'.sku') + ->addSelect($builder->getQuery()->from.'.type_id AS type'); foreach ($attributes as $attribute) { $attribute = (object) $attribute; diff --git a/src/Models/Scopes/Product/WithProductGroupedScope.php b/src/Models/Scopes/Product/WithProductGroupedScope.php new file mode 100644 index 000000000..84c605fc7 --- /dev/null +++ b/src/Models/Scopes/Product/WithProductGroupedScope.php @@ -0,0 +1,36 @@ +selectRaw('JSON_REMOVE(JSON_OBJECTAGG(IFNULL(grouped.entity_id, "null__"), JSON_OBJECT( + '.Eventy::filter('product.grouped.select', <<leftJoin('catalog_product_link', function ($join) use ($model) { + $join->on('catalog_product_link.product_id', '=', $model->getTable().'.entity_id') + ->where('link_type_id', 3); + }) + ->leftJoin($model->getTable().' as grouped', 'linked_product_id', '=', 'grouped.entity_id') + ->leftJoin('cataloginventory_stock_item AS grouped_stock', 'grouped.entity_id', '=', 'grouped_stock.product_id'); + } +}