Merge pull request #1782 from Haendlerbund/introduce-product-type-helper
introduce ProductType Helper
This commit is contained in:
commit
840290f0bb
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -241,14 +241,14 @@
|
|||
<tbody>
|
||||
@foreach ($order->items as $item)
|
||||
<tr>
|
||||
<td>{{ $item->type == 'configurable' ? $item->child->sku : $item->sku }}</td>
|
||||
<td>{{ Webkul\Product\Helpers\ProductType::hasVariants($item->type) ? $item->child->sku : $item->sku }}</td>
|
||||
|
||||
<td>
|
||||
{{ $item->name }}
|
||||
|
||||
@if (isset($item->additional['attributes']))
|
||||
<div class="item-options">
|
||||
|
||||
|
||||
@foreach ($item->additional['attributes'] as $attribute)
|
||||
<b>{{ $attribute['attribute_name'] }} : </b>{{ $attribute['option_label'] }}</br>
|
||||
@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()
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
|
||||
namespace Webkul\Product\Helpers;
|
||||
|
||||
use Webkul\Product\Type\AbstractType;
|
||||
|
||||
class ProductType extends AbstractProduct
|
||||
{
|
||||
/**
|
||||
* Checks if a ProductType may have variants
|
||||
*
|
||||
* @param string $typeKey as defined in config('product_types)
|
||||
*
|
||||
* @return bool whether ProductType is able to have variants
|
||||
*/
|
||||
public static function hasVariants(string $typeKey): bool
|
||||
{
|
||||
/** @var AbstractType $type */
|
||||
$type = app(config('product_types.' . $typeKey . '.class'));
|
||||
|
||||
return $type->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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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')))) {
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
@if ($product->type == 'configurable')
|
||||
@if (Webkul\Product\Helpers\ProductType::hasVariants($product->type))
|
||||
|
||||
@inject ('configurableOptionHelper', 'Webkul\Product\Helpers\ConfigurableOption')
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue