- | {{ $item->type == 'configurable' ? $item->child->sku : $item->sku }} |
+ {{ Webkul\Product\Helpers\ProductType::hasVariants($item->type) ? $item->child->sku : $item->sku }} |
{{ $item->name }}
@if (isset($item->additional['attributes']))
-
+
@foreach ($item->additional['attributes'] as $attribute)
{{ $attribute['attribute_name'] }} : {{ $attribute['option_label'] }}
@endforeach
@@ -417,7 +417,7 @@
if (! response.data) {
window.flashMessages = [{
'type': 'alert-error',
- 'message': "{{ __('admin::app.sales.refunds.invalid-qty') }}"
+ 'message': "{{ __('admin::app.sales.refunds.invalid-qty') }}"
}];
this_this.$root.addFlashMessages()
diff --git a/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php b/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php
index 962d65389..95c8f22e0 100644
--- a/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php
+++ b/packages/Webkul/Discount/src/Helpers/Catalog/Apply.php
@@ -6,6 +6,7 @@ use Webkul\Discount\Repositories\CatalogRuleRepository as CatalogRule;
use Webkul\Discount\Repositories\CatalogRuleProductsRepository as CatalogRuleProducts;
use Webkul\Discount\Repositories\CatalogRuleProductsPriceRepository as CatalogRuleProductsPrice;
use Webkul\Discount\Helpers\Catalog\ConvertXToProductId as ConvertX;
+use Webkul\Product\Helpers\ProductType;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Discount\Helpers\Catalog\Sale;
@@ -451,7 +452,7 @@ class Apply extends Sale
foreach ($productIDs as $productID) {
$product = $products->find($productID);
- if ($product->type == 'configurable') {
+ if (ProductType::hasVariants($product->type)) {
$variants = $product->variants;
foreach($variants as $variant) {
diff --git a/packages/Webkul/Discount/src/Helpers/Catalog/ConvertXToProductId.php b/packages/Webkul/Discount/src/Helpers/Catalog/ConvertXToProductId.php
index c71d6c4e4..b44eaea8b 100644
--- a/packages/Webkul/Discount/src/Helpers/Catalog/ConvertXToProductId.php
+++ b/packages/Webkul/Discount/src/Helpers/Catalog/ConvertXToProductId.php
@@ -6,6 +6,7 @@ use Webkul\Discount\Repositories\CatalogRuleRepository as CatalogRule;
use Webkul\Attribute\Repositories\AttributeRepository as Attribute;
use Webkul\Attribute\Repositories\AttributeOptionRepository as AttributeOption;
use Webkul\Category\Repositories\CategoryRepository as Category;
+use Webkul\Product\Helpers\ProductType;
use Webkul\Product\Repositories\ProductRepository as Product;
use Webkul\Product\Models\ProductAttributeValue as ProductAttributeValue;
@@ -110,7 +111,7 @@ class ConvertXToProductId
$products = collect();
foreach ($attributeOptions as $attributeOption) {
- if (isset($attributeOption->type) && $attributeOption->name != null && $attributeOption->condition != null && $attributeOption->value != [] && $attributeOption->type != null) {
+ if (isset($attributeOption->type) && $attributeOption->attribute != null && $attributeOption->condition != null && $attributeOption->value != [] && $attributeOption->type != null) {
$selectedOptions = $attributeOption->value;
if ($attributeOption->type == 'select' || $attributeOption->type == 'multiselect') {
@@ -154,17 +155,17 @@ class ConvertXToProductId
if ($testCondition == '{}') {
$foundProducts = $this->product->findWhere([
['sku', 'like', '%' . $testValue . '%'],
- ['type', '!=', 'configurable']
- ])->flatten()->all();
+ ['type', 'NOT IN', ProductType::getAllTypesHavingVariants()]
+ ])->flatten()->all();
} else if ($testCondition == '!{}') {
$foundProducts = $this->product->findWhere([
['sku', 'not like', '%' . $testValue . '%'],
- ['type', '!=', 'configurable']
+ ['type', 'NOT IN', ProductType::getAllTypesHavingVariants()]
])->flatten()->all();
} else if ($testCondition == '=') {
$foundProducts = $this->product->findWhere([
['sku', '=', $testValue],
- ['type', '!=', 'configurable']
+ ['type', 'NOT IN', ProductType::getAllTypesHavingVariants()]
])->flatten()->all();
}
}
diff --git a/packages/Webkul/Product/src/Helpers/ProductType.php b/packages/Webkul/Product/src/Helpers/ProductType.php
new file mode 100644
index 000000000..103b1ed58
--- /dev/null
+++ b/packages/Webkul/Product/src/Helpers/ProductType.php
@@ -0,0 +1,39 @@
+hasVariants();
+ }
+
+ /**
+ * Get all ProductTypes that are allowed to have variants
+ *
+ * @return array of product_types->keys
+ */
+ public static function getAllTypesHavingVariants(): array
+ {
+ foreach (config('product_types') as $type) {
+ if (self::hasVariants($type['key'])) {
+ array_push($havingVariants, $type['key']);
+ }
+ }
+
+ return $havingVariants;
+ }
+}
\ No newline at end of file
diff --git a/packages/Webkul/Product/src/Http/Controllers/ProductController.php b/packages/Webkul/Product/src/Http/Controllers/ProductController.php
index 0a4d0da0c..9134991d4 100755
--- a/packages/Webkul/Product/src/Http/Controllers/ProductController.php
+++ b/packages/Webkul/Product/src/Http/Controllers/ProductController.php
@@ -4,6 +4,7 @@ namespace Webkul\Product\Http\Controllers;
use Illuminate\Support\Facades\Event;
use Webkul\Product\Http\Requests\ProductForm;
+use Webkul\Product\Helpers\ProductType;
use Webkul\Category\Repositories\CategoryRepository;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductDownloadableLinkRepository;
@@ -140,13 +141,13 @@ class ProductController extends Controller
public function store()
{
if (! request()->get('family')
- && request()->input('type') == 'configurable'
+ && ProductType::hasVariants(request()->input('type'))
&& request()->input('sku') != '') {
return redirect(url()->current() . '?type=' . request()->input('type') . '&family=' . request()->input('attribute_family_id') . '&sku=' . request()->input('sku'));
}
- if (request()->input('type') == 'configurable'
+ if (ProductType::hasVariants(request()->input('type'))
&& (! request()->has('super_attributes')
|| ! count(request()->get('super_attributes')))) {
diff --git a/packages/Webkul/Product/src/Listeners/ProductFlat.php b/packages/Webkul/Product/src/Listeners/ProductFlat.php
index a993a58ae..ecb8ffe9a 100644
--- a/packages/Webkul/Product/src/Listeners/ProductFlat.php
+++ b/packages/Webkul/Product/src/Listeners/ProductFlat.php
@@ -6,6 +6,7 @@ use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Attribute\Repositories\AttributeOptionRepository;
+use Webkul\Product\Helpers\ProductType;
use Webkul\Product\Repositories\ProductFlatRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Models\ProductAttributeValue;
@@ -148,7 +149,7 @@ class ProductFlat
{
$this->createFlat($product);
- if ($product->type == 'configurable') {
+ if (ProductType::hasVariants($product->type)) {
foreach ($product->variants()->get() as $variant) {
$this->createFlat($variant, $product);
}
diff --git a/packages/Webkul/Product/src/Type/AbstractType.php b/packages/Webkul/Product/src/Type/AbstractType.php
index 75abbba1e..39568653d 100644
--- a/packages/Webkul/Product/src/Type/AbstractType.php
+++ b/packages/Webkul/Product/src/Type/AbstractType.php
@@ -3,6 +3,7 @@
namespace Webkul\Product\Type;
use Illuminate\Support\Facades\Storage;
+use phpDocumentor\Reflection\Types\Boolean;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
@@ -57,7 +58,7 @@ abstract class AbstractType
/**
* Product Image helper instance
- *
+ *
* @var ProductImage
*/
protected $productImageHelper;
@@ -104,6 +105,13 @@ abstract class AbstractType
*/
protected $canBeMovedFromWishlistToCart = true;
+ /**
+ * Has child products aka variants
+ *
+ * @var boolean
+ */
+ protected $hasVariants = false;
+
/**
* Create a new product type instance.
*
@@ -159,17 +167,21 @@ abstract class AbstractType
$product->update($data);
foreach ($product->attribute_family->custom_attributes as $attribute) {
- if ($attribute->type == 'boolean')
+ if ($attribute->type == 'boolean') {
$data[$attribute->code] = isset($data[$attribute->code]) && $data[$attribute->code] ? 1 : 0;
+ }
- if (! isset($data[$attribute->code]))
+ if (! isset($data[$attribute->code])) {
continue;
+ }
- if ($attribute->type == 'date' && $data[$attribute->code] == '')
+ if ($attribute->type == 'date' && $data[$attribute->code] == '') {
$data[$attribute->code] = null;
+ }
- if ($attribute->type == 'multiselect' || $attribute->type == 'checkbox')
+ if ($attribute->type == 'multiselect' || $attribute->type == 'checkbox') {
$data[$attribute->code] = implode(",", $data[$attribute->code]);
+ }
if ($attribute->type == 'image' || $attribute->type == 'file') {
$data[$attribute->code] = gettype($data[$attribute->code]) == 'object'
@@ -198,16 +210,18 @@ abstract class AbstractType
], $attributeValue->id
);
- if ($attribute->type == 'image' || $attribute->type == 'file')
+ if ($attribute->type == 'image' || $attribute->type == 'file') {
Storage::delete($attributeValue->text_value);
+ }
}
}
- $route = request()->route() ? request()->route()->getName() : "";
+ $route = request()->route() ? request()->route()->getName() : "";
if ($route != 'admin.catalog.products.massupdate') {
- if (isset($data['categories']))
+ if (isset($data['categories'])) {
$product->categories()->sync($data['categories']);
+ }
$product->up_sells()->sync($data['up_sell'] ?? []);
@@ -243,9 +257,10 @@ abstract class AbstractType
*/
public function isSaleable()
{
- if (! $this->product->status)
+ if (! $this->product->status) {
return false;
-
+ }
+
return true;
}
@@ -260,7 +275,7 @@ abstract class AbstractType
}
/**
- * Return true if this product can have inventory
+ * Return true if this product can be composite
*
* @return boolean
*/
@@ -269,6 +284,16 @@ abstract class AbstractType
return $this->isComposite;
}
+ /**
+ * Return true if this product can have variants
+ *
+ * @return bool
+ */
+ public function hasVariants(): bool
+ {
+ return $this->hasVariants;
+ }
+
/**
* @param integer $qty
* @return bool
@@ -277,7 +302,7 @@ abstract class AbstractType
{
return $this->haveSufficientQuantity;
}
-
+
/**
* Return true if this product can have inventory
*
@@ -310,8 +335,9 @@ abstract class AbstractType
->pluck('id');
foreach ($this->product->inventories as $inventory) {
- if (is_numeric($index = $channelInventorySourceIds->search($inventory->inventory_source_id)))
+ if (is_numeric($index = $channelInventorySourceIds->search($inventory->inventory_source_id))) {
$total += $inventory->qty;
+ }
}
$orderedInventory = $this->product->ordered_inventories()
@@ -344,11 +370,13 @@ abstract class AbstractType
*/
public function getEditableAttributes($group = null, $skipSuperAttribute = true)
{
- if ($skipSuperAttribute)
+ if ($skipSuperAttribute) {
$this->skipAttributes = array_merge($this->product->super_attributes->pluck('code')->toArray(), $this->skipAttributes);
+ }
- if (! $group)
+ if (! $group) {
return $this->product->attribute_family->custom_attributes()->whereNotIn('attributes.code', $this->skipAttributes)->get();
+ }
return $group->custom_attributes()->whereNotIn('code', $this->skipAttributes)->get();
}
@@ -380,8 +408,9 @@ abstract class AbstractType
*/
public function getMinimalPrice()
{
- if ($this->haveSpecialPrice())
+ if ($this->haveSpecialPrice()) {
return $this->product->special_price;
+ }
return $this->product->price;
}
@@ -421,11 +450,13 @@ abstract class AbstractType
*/
public function haveSpecialPrice()
{
- if (is_null($this->product->special_price) || ! (float) $this->product->special_price)
+ if (is_null($this->product->special_price) || ! (float) $this->product->special_price) {
return false;
+ }
- if (core()->isChannelDateInInterval($this->product->special_price_from, $this->product->special_price_to))
+ if (core()->isChannelDateInInterval($this->product->special_price_from, $this->product->special_price_to)) {
return true;
+ }
return false;
}
@@ -479,8 +510,9 @@ abstract class AbstractType
$data = $this->getQtyRequest($data);
- if (! $this->haveSufficientQuantity($data['quantity']))
+ if (! $this->haveSufficientQuantity($data['quantity'])) {
return trans('shop::app.checkout.cart.quantity.inventory_warning');
+ }
$price = $this->getFinalPrice();
@@ -514,12 +546,13 @@ abstract class AbstractType
*/
public function getQtyRequest($data)
{
- if ($item = Cart::getItemByProduct(['additional' => $data]))
+ if ($item = Cart::getItemByProduct(['additional' => $data])) {
$data['quantity'] += $item->quantity;
+ }
return $data;
}
-
+
/**
*
* @param array $options1
@@ -546,7 +579,7 @@ abstract class AbstractType
return true;
}
-
+
/**
* Returns additional information for items
*
@@ -590,8 +623,9 @@ abstract class AbstractType
{
$price = $item->product->getTypeInstance()->getFinalPrice();
- if ($price == $item->base_price)
+ if ($price == $item->base_price) {
return;
+ }
$item->base_price = $price;
$item->price = core()->convertPrice($price);
diff --git a/packages/Webkul/Product/src/Type/Configurable.php b/packages/Webkul/Product/src/Type/Configurable.php
index 79cb4c081..6977bf5de 100644
--- a/packages/Webkul/Product/src/Type/Configurable.php
+++ b/packages/Webkul/Product/src/Type/Configurable.php
@@ -22,7 +22,7 @@ class Configurable extends AbstractType
/**
* These blade files will be included in product edit page
- *
+ *
* @var array
*/
protected $additionalViews = [
@@ -47,6 +47,13 @@ class Configurable extends AbstractType
*/
protected $showQuantityBox = true;
+ /**
+ * Has child products aka variants
+ *
+ * @var boolean
+ */
+ protected $hasVariants = true;
+
/**
* @param array $data
* @return Product
@@ -416,7 +423,7 @@ class Configurable extends AbstractType
return $products;
}
-
+
/**
*
* @param array $options1
@@ -451,7 +458,7 @@ class Configurable extends AbstractType
];
}
- return $data;
+ return $data;
}
/**
diff --git a/packages/Webkul/Shop/src/Resources/views/products/view/configurable-options.blade.php b/packages/Webkul/Shop/src/Resources/views/products/view/configurable-options.blade.php
index 154bc0815..3e4b74eca 100755
--- a/packages/Webkul/Shop/src/Resources/views/products/view/configurable-options.blade.php
+++ b/packages/Webkul/Shop/src/Resources/views/products/view/configurable-options.blade.php
@@ -1,4 +1,4 @@
-@if ($product->type == 'configurable')
+@if (Webkul\Product\Helpers\ProductType::hasVariants($product->type))
@inject ('configurableOptionHelper', 'Webkul\Product\Helpers\ConfigurableOption')
|