From 9a43776cc01ac3030d13c622b228aac1179338fa Mon Sep 17 00:00:00 2001 From: Annika Wolff Date: Thu, 21 Nov 2019 16:56:21 +0100 Subject: [PATCH] introduce ProductType Helper --- .../API/Http/Resources/Catalog/Product.php | 3 +- .../views/sales/refunds/create.blade.php | 6 +- .../Discount/src/Helpers/Catalog/Apply.php | 3 +- .../Helpers/Catalog/ConvertXToProductId.php | 11 +-- .../Product/src/Helpers/ProductType.php | 40 +++++++++++ .../Http/Controllers/ProductController.php | 5 +- .../Product/src/Listeners/ProductFlat.php | 3 +- .../Webkul/Product/src/Type/AbstractType.php | 67 ++++++++++++++++--- .../Webkul/Product/src/Type/Configurable.php | 13 +++- .../view/configurable-options.blade.php | 2 +- 10 files changed, 128 insertions(+), 25 deletions(-) create mode 100644 packages/Webkul/Product/src/Helpers/ProductType.php diff --git a/packages/Webkul/API/Http/Resources/Catalog/Product.php b/packages/Webkul/API/Http/Resources/Catalog/Product.php index 711ed1c42..c4a1ec895 100644 --- a/packages/Webkul/API/Http/Resources/Catalog/Product.php +++ b/packages/Webkul/API/Http/Resources/Catalog/Product.php @@ -3,6 +3,7 @@ namespace Webkul\API\Http\Resources\Catalog; use Illuminate\Http\Resources\Json\JsonResource; +use Webkul\Product\Helpers\ProductType; class Product extends JsonResource { @@ -44,7 +45,7 @@ class Product extends JsonResource 'base_image' => $this->productImageHelper->getProductBaseImage($product), 'variants' => Self::collection($this->variants), 'in_stock' => $product->haveSufficientQuantity(1), - $this->mergeWhen($product->type == 'configurable', [ + $this->mergeWhen($product->getTypeInstance()->isComposite(), [ 'super_attributes' => Attribute::collection($product->super_attributes), ]), 'special_price' => $this->when( diff --git a/packages/Webkul/Admin/src/Resources/views/sales/refunds/create.blade.php b/packages/Webkul/Admin/src/Resources/views/sales/refunds/create.blade.php index 8a273df8b..e0e0ac3d1 100755 --- a/packages/Webkul/Admin/src/Resources/views/sales/refunds/create.blade.php +++ b/packages/Webkul/Admin/src/Resources/views/sales/refunds/create.blade.php @@ -241,14 +241,14 @@ @foreach ($order->items as $item) - {{ $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 855d8d065..4a8ba4d8e 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; @@ -453,7 +454,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 c6e4cd79a..91df9871f 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; @@ -113,7 +114,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') { @@ -162,17 +163,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..9dcf87c32 --- /dev/null +++ b/packages/Webkul/Product/src/Helpers/ProductType.php @@ -0,0 +1,40 @@ +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..44e6a76a5 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. * @@ -160,16 +168,24 @@ abstract class AbstractType foreach ($product->attribute_family->custom_attributes as $attribute) { if ($attribute->type == 'boolean') + { $data[$attribute->code] = isset($data[$attribute->code]) && $data[$attribute->code] ? 1 : 0; + } if (! isset($data[$attribute->code])) + { continue; + } if ($attribute->type == 'date' && $data[$attribute->code] == '') + { $data[$attribute->code] = null; + } 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' @@ -199,15 +215,19 @@ abstract class AbstractType ); 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'])) + { $product->categories()->sync($data['categories']); + } $product->up_sells()->sync($data['up_sell'] ?? []); @@ -244,8 +264,10 @@ abstract class AbstractType public function isSaleable() { if (! $this->product->status) + { return false; - + } + return true; } @@ -260,7 +282,7 @@ abstract class AbstractType } /** - * Return true if this product can have inventory + * Return true if this product can be composite * * @return boolean */ @@ -269,6 +291,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 +309,7 @@ abstract class AbstractType { return $this->haveSufficientQuantity; } - + /** * Return true if this product can have inventory * @@ -311,14 +343,17 @@ abstract class AbstractType foreach ($this->product->inventories as $inventory) { if (is_numeric($index = $channelInventorySourceIds->search($inventory->inventory_source_id))) + { $total += $inventory->qty; + } } $orderedInventory = $this->product->ordered_inventories() ->where('channel_id', core()->getCurrentChannel()->id) ->first(); - if ($orderedInventory) { + if ($orderedInventory) + { $total -= $orderedInventory->qty; } @@ -345,10 +380,14 @@ abstract class AbstractType public function getEditableAttributes($group = null, $skipSuperAttribute = true) { if ($skipSuperAttribute) + { $this->skipAttributes = array_merge($this->product->super_attributes->pluck('code')->toArray(), $this->skipAttributes); + } if (! $group) + { return $this->product->attribute_family->custom_attributes()->whereNotIn('attributes.code', $this->skipAttributes)->get(); + } return $group->custom_attributes()->whereNotIn('code', $this->skipAttributes)->get(); } @@ -381,7 +420,9 @@ abstract class AbstractType public function getMinimalPrice() { if ($this->haveSpecialPrice()) + { return $this->product->special_price; + } return $this->product->price; } @@ -422,10 +463,14 @@ abstract class AbstractType public function haveSpecialPrice() { 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)) + { return true; + } return false; } @@ -480,7 +525,9 @@ abstract class AbstractType $data = $this->getQtyRequest($data); if (! $this->haveSufficientQuantity($data['quantity'])) + { return trans('shop::app.checkout.cart.quantity.inventory_warning'); + } $price = $this->getFinalPrice(); @@ -515,11 +562,13 @@ abstract class AbstractType public function getQtyRequest($data) { if ($item = Cart::getItemByProduct(['additional' => $data])) + { $data['quantity'] += $item->quantity; + } return $data; } - + /** * * @param array $options1 @@ -546,7 +595,7 @@ abstract class AbstractType return true; } - + /** * Returns additional information for items * @@ -591,7 +640,9 @@ abstract class AbstractType $price = $item->product->getTypeInstance()->getFinalPrice(); 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')