ability to globally set a callable for isSaleable

This commit is contained in:
Herbert Maschke 2020-09-01 07:43:51 +02:00
parent 63cced9d69
commit cb32fe31bf
6 changed files with 83 additions and 46 deletions

View File

@ -1,14 +1,23 @@
<?php
use Webkul\Product\Models\Product;
return [
// use the 'code' of the 'attributes' table here to be able to control which attributes
// should be skipped when doing a copy (admin->catalog->products->copy product).
// you can also add every relation that should not be copied here to skip them.
// defaults to none (which means everything is copied).
'skipAttributesOnCopy' => [
],
// Make the original and source product 'related' via the 'product_relations' table
'linkProductsOnCopy' => false,
];
// Ability to set a global callable that defines if a product is saleable.
// Return neither true nor false but null by default to not interrupt the default chain that
// defines if a product is saleable. It depends on the isSaleable() method of the product
// type if this callable is obeyed.
'isSaleable' => function (Product $product): ?bool {
return null;
},
];

View File

@ -5,24 +5,25 @@ namespace Webkul\Core\Helpers;
// here you can define custom actions
// all public methods declared in helper class will be available in $I
use StdClass;
use Faker\Factory;
use Codeception\Module\Laravel5;
use Webkul\Attribute\Models\Attribute;
use Webkul\Attribute\Models\AttributeOption;
use Webkul\BookingProduct\Models\BookingProduct;
use Webkul\BookingProduct\Models\BookingProductEventTicket;
use Webkul\Checkout\Models\Cart;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Product\Models\Product;
use Illuminate\Support\Facades\DB;
use Webkul\Checkout\Models\CartItem;
use Webkul\Customer\Models\Customer;
use Illuminate\Support\Facades\Event;
use Webkul\Attribute\Models\Attribute;
use Webkul\Checkout\Models\CartAddress;
use Webkul\Customer\Models\CustomerAddress;
use Webkul\Product\Models\Product;
use Webkul\Product\Models\ProductInventory;
use Webkul\Attribute\Models\AttributeOption;
use Webkul\BookingProduct\Models\BookingProduct;
use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Models\ProductDownloadableLink;
use Webkul\BookingProduct\Models\BookingProductEventTicket;
use Webkul\Product\Models\ProductDownloadableLinkTranslation;
use Webkul\Product\Models\ProductInventory;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
/**
* Class Laravel5Helper
@ -54,6 +55,7 @@ class Laravel5Helper extends Laravel5
'textarea' => 'text_value',
'price' => 'float_value',
'date' => 'date_value',
'checkbox' => 'text_value',
];
return $possibleTypes[$type];
@ -127,7 +129,7 @@ class Laravel5Helper extends Laravel5
// actually set the cart to the user's session
// when in an functional test:
$stub = new \StdClass();
$stub = new StdClass();
$stub->id = $cart->id;
$I->setSession(['cart' => $stub]);

View File

@ -177,9 +177,10 @@ abstract class AbstractType
}
/**
* @param array $data
* @param int $id
* @param string $attribute
* @param array $data
* @param int $id
* @param string $attribute
*
* @return \Webkul\Product\Contracts\Product
*/
public function update(array $data, $id, $attribute = "id")
@ -199,20 +200,20 @@ abstract class AbstractType
continue;
}
if ($attribute->type == 'price' && isset($data[$attribute->code]) && $data[$attribute->code] == '') {
if ($attribute->type === 'price' && isset($data[$attribute->code]) && $data[$attribute->code] === '') {
$data[$attribute->code] = null;
}
if ($attribute->type == 'date' && $data[$attribute->code] == '' && $route != 'admin.catalog.products.massupdate') {
if ($attribute->type === 'date' && $data[$attribute->code] === '' && $route !== 'admin.catalog.products.massupdate') {
$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'
if ($attribute->type === 'image' || $attribute->type === 'file') {
$data[$attribute->code] = gettype($data[$attribute->code]) === 'object'
? request()->file($attribute->code)->store('product/' . $product->id)
: null;
}
@ -315,6 +316,11 @@ abstract class AbstractType
return false;
}
if (is_callable(config('products.isSaleable')) &&
call_user_func(config('products.isSaleable'), $this->product) === false) {
return false;
}
return true;
}
@ -533,8 +539,8 @@ abstract class AbstractType
$rulePrice = app('Webkul\CatalogRule\Helpers\CatalogRuleProductPrice')->getRulePrice($this->product);
if ((is_null($this->product->special_price) || !(float)$this->product->special_price)
&& !$rulePrice
if ((is_null($this->product->special_price) || ! (float)$this->product->special_price)
&& ! $rulePrice
&& $customerGroupPrice == $this->product->price
) {
return false;
@ -542,7 +548,7 @@ abstract class AbstractType
$haveSpecialPrice = false;
if (!(float)$this->product->special_price) {
if (! (float)$this->product->special_price) {
if ($rulePrice && $rulePrice->price < $this->product->price) {
$this->product->special_price = $rulePrice->price;

View File

@ -4,14 +4,13 @@ namespace Webkul\Product\Type;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Datatypes\CartItemValidationResult;
use Webkul\Product\Helpers\ProductImage;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Product\Repositories\ProductImageRepository;
use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Repositories\ProductDownloadableLinkRepository;
use Webkul\Product\Repositories\ProductDownloadableSampleRepository;
use Webkul\Product\Helpers\ProductImage;
use Webkul\Checkout\Models\CartItem;
class Downloadable extends AbstractType
{
@ -19,14 +18,14 @@ class Downloadable extends AbstractType
* ProductDownloadableLinkRepository instance
*
* @var \Webkul\Product\Repositories\ProductDownloadableLinkRepository
*/
*/
protected $productDownloadableLinkRepository;
/**
* ProductDownloadableSampleRepository instance
*
* @var \Webkul\Product\Repositories\ProductDownloadableSampleRepository
*/
*/
protected $productDownloadableSampleRepository;
/**
@ -46,7 +45,7 @@ class Downloadable extends AbstractType
'admin::catalog.products.accordians.categories',
'admin::catalog.products.accordians.downloadable',
'admin::catalog.products.accordians.channels',
'admin::catalog.products.accordians.product-links'
'admin::catalog.products.accordians.product-links',
];
/**
@ -64,14 +63,15 @@ class Downloadable extends AbstractType
/**
* Create a new product type instance.
*
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
* @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository
* @param \Webkul\Product\Repositories\ProductDownloadableLinkRepository $productDownloadableLinkRepository
* @param \Webkul\Product\Repositories\ProductDownloadableSampleRepository $productDownloadableSampleRepository
* @param \Webkul\Product\Helpers\ProductImage $productImageHelper
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
* @param \Webkul\Product\Repositories\ProductRepository $productRepository
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
* @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository
* @param \Webkul\Product\Repositories\ProductDownloadableLinkRepository $productDownloadableLinkRepository
* @param \Webkul\Product\Repositories\ProductDownloadableSampleRepository $productDownloadableSampleRepository
* @param \Webkul\Product\Helpers\ProductImage $productImageHelper
*
* @return void
*/
public function __construct(
@ -100,9 +100,10 @@ class Downloadable extends AbstractType
}
/**
* @param array $data
* @param int $id
* @param string $attribute
* @param array $data
* @param int $id
* @param string $attribute
*
* @return \Webkul\Product\Contracts\Product
*/
public function update(array $data, $id, $attribute = "id")
@ -129,6 +130,11 @@ class Downloadable extends AbstractType
return false;
}
if (is_callable(config('products.isSaleable')) &&
call_user_func(config('products.isSaleable'), $this->product) === false) {
return false;
}
if ($this->product->downloadable_links()->count()) {
return true;
}
@ -157,7 +163,8 @@ class Downloadable extends AbstractType
/**
* Add product. Returns error message if can't prepare product.
*
* @param array $data
* @param array $data
*
* @return array
*/
public function prepareForCart($data)
@ -184,8 +191,9 @@ class Downloadable extends AbstractType
/**
*
* @param array $options1
* @param array $options2
* @param array $options1
* @param array $options2
*
* @return bool
*/
public function compareOptions($options1, $options2)
@ -206,7 +214,8 @@ class Downloadable extends AbstractType
/**
* Returns additional information for items
*
* @param array $data
* @param array $data
*
* @return array
*/
public function getAdditionalOptions($data)

View File

@ -42,6 +42,11 @@ class Simple extends AbstractType
return false;
}
if (is_callable(config('products.isSaleable')) &&
call_user_func(config('products.isSaleable'), $this->product) === false) {
return false;
}
if ($this->haveSufficientQuantity(1)) {
return true;
}

View File

@ -49,6 +49,11 @@ class Virtual extends AbstractType
return false;
}
if (is_callable(config('products.isSaleable')) &&
call_user_func(config('products.isSaleable'), $this->product) === false) {
return false;
}
if ($this->haveSufficientQuantity(1)) {
return true;
}
@ -57,7 +62,8 @@ class Virtual extends AbstractType
}
/**
* @param int $qty
* @param int $qty
*
* @return bool
*/
public function haveSufficientQuantity(int $qty): bool