Merge pull request #3853 from Haendlerbund/global-callable-for-saleable

ability to globally set a callable for isSaleable
This commit is contained in:
Jitendra Singh 2020-10-01 16:36:55 +05:30 committed by GitHub
commit a7fe0f78a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 90 additions and 51 deletions

View File

@ -1,14 +1,23 @@
<?php <?php
use Webkul\Product\Models\Product;
return [ return [
// use the 'code' of the 'attributes' table here to be able to control which attributes // 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). // 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. // you can also add every relation that should not be copied here to skip them.
// defaults to none (which means everything is copied). // defaults to none (which means everything is copied).
'skipAttributesOnCopy' => [ 'skipAttributesOnCopy' => [
], ],
// Make the original and source product 'related' via the 'product_relations' table // Make the original and source product 'related' via the 'product_relations' table
'linkProductsOnCopy' => false, '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 // here you can define custom actions
// all public methods declared in helper class will be available in $I // all public methods declared in helper class will be available in $I
use StdClass;
use Faker\Factory; use Faker\Factory;
use Codeception\Module\Laravel5; 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\Cart;
use Webkul\Checkout\Models\CartAddress; use Webkul\Product\Models\Product;
use Illuminate\Support\Facades\DB;
use Webkul\Checkout\Models\CartItem; use Webkul\Checkout\Models\CartItem;
use Webkul\Customer\Models\Customer; 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\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\ProductAttributeValue;
use Webkul\Product\Models\ProductDownloadableLink; use Webkul\Product\Models\ProductDownloadableLink;
use Webkul\BookingProduct\Models\BookingProductEventTicket;
use Webkul\Product\Models\ProductDownloadableLinkTranslation; use Webkul\Product\Models\ProductDownloadableLinkTranslation;
use Webkul\Product\Models\ProductInventory;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
/** /**
* Class Laravel5Helper * Class Laravel5Helper
@ -54,6 +55,7 @@ class Laravel5Helper extends Laravel5
'textarea' => 'text_value', 'textarea' => 'text_value',
'price' => 'float_value', 'price' => 'float_value',
'date' => 'date_value', 'date' => 'date_value',
'checkbox' => 'text_value',
]; ];
return $possibleTypes[$type]; return $possibleTypes[$type];
@ -127,7 +129,7 @@ class Laravel5Helper extends Laravel5
// actually set the cart to the user's session // actually set the cart to the user's session
// when in an functional test: // when in an functional test:
$stub = new \StdClass(); $stub = new StdClass();
$stub->id = $cart->id; $stub->id = $cart->id;
$I->setSession(['cart' => $stub]); $I->setSession(['cart' => $stub]);

View File

@ -2,13 +2,14 @@
namespace Webkul\Product\Type; namespace Webkul\Product\Type;
use Illuminate\Support\Facades\Storage;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Checkout\Facades\Cart; use Webkul\Checkout\Facades\Cart;
use Webkul\Product\Datatypes\CartItemValidationResult; use Webkul\Checkout\Models\CartItem;
use Illuminate\Support\Facades\Storage;
use Webkul\Product\Helpers\ProductImage; use Webkul\Product\Helpers\ProductImage;
use Webkul\Product\Models\ProductAttributeValue; use Webkul\Product\Models\ProductAttributeValue;
use Webkul\Product\Repositories\ProductRepository; use Webkul\Product\Repositories\ProductRepository;
use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Datatypes\CartItemValidationResult;
use Webkul\Product\Repositories\ProductImageRepository; use Webkul\Product\Repositories\ProductImageRepository;
use Webkul\Product\Repositories\ProductInventoryRepository; use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository; use Webkul\Product\Repositories\ProductAttributeValueRepository;
@ -183,9 +184,10 @@ abstract class AbstractType
} }
/** /**
* @param array $data * @param array $data
* @param int $id * @param int $id
* @param string $attribute * @param string $attribute
*
* @return \Webkul\Product\Contracts\Product * @return \Webkul\Product\Contracts\Product
*/ */
public function update(array $data, $id, $attribute = "id") public function update(array $data, $id, $attribute = "id")
@ -205,20 +207,20 @@ abstract class AbstractType
continue; 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; $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; $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]); $data[$attribute->code] = implode(",", $data[$attribute->code]);
} }
if ($attribute->type == 'image' || $attribute->type == 'file') { if ($attribute->type === 'image' || $attribute->type === 'file') {
$data[$attribute->code] = gettype($data[$attribute->code]) == 'object' $data[$attribute->code] = gettype($data[$attribute->code]) === 'object'
? request()->file($attribute->code)->store('product/' . $product->id) ? request()->file($attribute->code)->store('product/' . $product->id)
: null; : null;
} }
@ -321,6 +323,11 @@ abstract class AbstractType
return false; return false;
} }
if (is_callable(config('products.isSaleable')) &&
call_user_func(config('products.isSaleable'), $this->product) === false) {
return false;
}
return true; return true;
} }
@ -549,8 +556,8 @@ abstract class AbstractType
$rulePrice = app('Webkul\CatalogRule\Helpers\CatalogRuleProductPrice')->getRulePrice($this->product); $rulePrice = app('Webkul\CatalogRule\Helpers\CatalogRuleProductPrice')->getRulePrice($this->product);
if ((is_null($this->product->special_price) || !(float)$this->product->special_price) if ((is_null($this->product->special_price) || ! (float)$this->product->special_price)
&& !$rulePrice && ! $rulePrice
&& $customerGroupPrice == $this->product->price && $customerGroupPrice == $this->product->price
) { ) {
return false; return false;
@ -558,7 +565,7 @@ abstract class AbstractType
$haveSpecialPrice = false; $haveSpecialPrice = false;
if (!(float)$this->product->special_price) { if (! (float)$this->product->special_price) {
if ($rulePrice && $rulePrice->price < $this->product->price) { if ($rulePrice && $rulePrice->price < $this->product->price) {
$this->product->special_price = $rulePrice->price; $this->product->special_price = $rulePrice->price;
@ -832,7 +839,7 @@ abstract class AbstractType
* *
* @return \Webkul\Product\Datatypes\CartItemValidationResult * @return \Webkul\Product\Datatypes\CartItemValidationResult
*/ */
public function validateCartItem(\Webkul\Checkout\Models\CartItem $item): CartItemValidationResult public function validateCartItem(CartItem $item): CartItemValidationResult
{ {
$result = new CartItemValidationResult(); $result = new CartItemValidationResult();

View File

@ -2,16 +2,16 @@
namespace Webkul\Product\Type; namespace Webkul\Product\Type;
use Webkul\Checkout\Models\CartItem;
use Webkul\Product\Helpers\ProductImage;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Attribute\Repositories\AttributeRepository; use Webkul\Attribute\Repositories\AttributeRepository;
use Webkul\Product\Datatypes\CartItemValidationResult; use Webkul\Product\Datatypes\CartItemValidationResult;
use Webkul\Product\Repositories\ProductRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Product\Repositories\ProductImageRepository; use Webkul\Product\Repositories\ProductImageRepository;
use Webkul\Product\Repositories\ProductInventoryRepository;
use Webkul\Product\Repositories\ProductAttributeValueRepository;
use Webkul\Product\Repositories\ProductDownloadableLinkRepository; use Webkul\Product\Repositories\ProductDownloadableLinkRepository;
use Webkul\Product\Repositories\ProductDownloadableSampleRepository; use Webkul\Product\Repositories\ProductDownloadableSampleRepository;
use Webkul\Product\Helpers\ProductImage;
use Webkul\Checkout\Models\CartItem;
class Downloadable extends AbstractType class Downloadable extends AbstractType
{ {
@ -19,14 +19,14 @@ class Downloadable extends AbstractType
* ProductDownloadableLinkRepository instance * ProductDownloadableLinkRepository instance
* *
* @var \Webkul\Product\Repositories\ProductDownloadableLinkRepository * @var \Webkul\Product\Repositories\ProductDownloadableLinkRepository
*/ */
protected $productDownloadableLinkRepository; protected $productDownloadableLinkRepository;
/** /**
* ProductDownloadableSampleRepository instance * ProductDownloadableSampleRepository instance
* *
* @var \Webkul\Product\Repositories\ProductDownloadableSampleRepository * @var \Webkul\Product\Repositories\ProductDownloadableSampleRepository
*/ */
protected $productDownloadableSampleRepository; protected $productDownloadableSampleRepository;
/** /**
@ -46,7 +46,7 @@ class Downloadable extends AbstractType
'admin::catalog.products.accordians.categories', 'admin::catalog.products.accordians.categories',
'admin::catalog.products.accordians.downloadable', 'admin::catalog.products.accordians.downloadable',
'admin::catalog.products.accordians.channels', 'admin::catalog.products.accordians.channels',
'admin::catalog.products.accordians.product-links' 'admin::catalog.products.accordians.product-links',
]; ];
/** /**
@ -71,14 +71,15 @@ class Downloadable extends AbstractType
/** /**
* Create a new product type instance. * Create a new product type instance.
* *
* @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository * @param \Webkul\Attribute\Repositories\AttributeRepository $attributeRepository
* @param \Webkul\Product\Repositories\ProductRepository $productRepository * @param \Webkul\Product\Repositories\ProductRepository $productRepository
* @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository * @param \Webkul\Product\Repositories\ProductAttributeValueRepository $attributeValueRepository
* @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository * @param \Webkul\Product\Repositories\ProductInventoryRepository $productInventoryRepository
* @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository * @param \Webkul\Product\Repositories\ProductImageRepository $productImageRepository
* @param \Webkul\Product\Repositories\ProductDownloadableLinkRepository $productDownloadableLinkRepository * @param \Webkul\Product\Repositories\ProductDownloadableLinkRepository $productDownloadableLinkRepository
* @param \Webkul\Product\Repositories\ProductDownloadableSampleRepository $productDownloadableSampleRepository * @param \Webkul\Product\Repositories\ProductDownloadableSampleRepository $productDownloadableSampleRepository
* @param \Webkul\Product\Helpers\ProductImage $productImageHelper * @param \Webkul\Product\Helpers\ProductImage $productImageHelper
*
* @return void * @return void
*/ */
public function __construct( public function __construct(
@ -107,9 +108,10 @@ class Downloadable extends AbstractType
} }
/** /**
* @param array $data * @param array $data
* @param int $id * @param int $id
* @param string $attribute * @param string $attribute
*
* @return \Webkul\Product\Contracts\Product * @return \Webkul\Product\Contracts\Product
*/ */
public function update(array $data, $id, $attribute = "id") public function update(array $data, $id, $attribute = "id")
@ -136,6 +138,11 @@ class Downloadable extends AbstractType
return false; 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()) { if ($this->product->downloadable_links()->count()) {
return true; return true;
} }
@ -164,7 +171,8 @@ class Downloadable extends AbstractType
/** /**
* Add product. Returns error message if can't prepare product. * Add product. Returns error message if can't prepare product.
* *
* @param array $data * @param array $data
*
* @return array * @return array
*/ */
public function prepareForCart($data) public function prepareForCart($data)
@ -191,8 +199,9 @@ class Downloadable extends AbstractType
/** /**
* *
* @param array $options1 * @param array $options1
* @param array $options2 * @param array $options2
*
* @return bool * @return bool
*/ */
public function compareOptions($options1, $options2) public function compareOptions($options1, $options2)
@ -213,7 +222,8 @@ class Downloadable extends AbstractType
/** /**
* Returns additional information for items * Returns additional information for items
* *
* @param array $data * @param array $data
*
* @return array * @return array
*/ */
public function getAdditionalOptions($data) public function getAdditionalOptions($data)

View File

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

View File

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