add function to remove inactive products from cart
This commit is contained in:
parent
05a1e0eb13
commit
80bd331123
|
|
@ -499,7 +499,7 @@ class Cart
|
|||
$this->saveAddressesWhenRequested($data, $billingAddressData, $shippingAddressData);
|
||||
|
||||
$this->linkAddresses($cart, $billingAddressData, $shippingAddressData);
|
||||
|
||||
|
||||
$this->assignCustomerFields($cart);
|
||||
|
||||
$cart->save();
|
||||
|
|
@ -765,7 +765,7 @@ class Cart
|
|||
return true;
|
||||
}
|
||||
|
||||
if (! $this->isItemsHaveSufficientQuantity()) {
|
||||
if (! $this->checkCartItems()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -773,13 +773,19 @@ class Cart
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks if all cart items have sufficient quantity.
|
||||
* Checks all cart items for:
|
||||
* - product is active (if not, cart item will be removed)
|
||||
* - product has sufficient quantity
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isItemsHaveSufficientQuantity(): bool
|
||||
public function checkCartItems(): bool
|
||||
{
|
||||
foreach ($this->getCart()->items as $item) {
|
||||
if ($this->removeInactiveItem($item)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! $this->isItemHaveQuantity($item)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -788,6 +794,22 @@ class Cart
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove cart items, whose product is inactive
|
||||
*/
|
||||
public function removeInactiveItems()
|
||||
{
|
||||
if (! $cart = $this->getCart()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($cart->items as $item) {
|
||||
if ($this->removeInactiveItem($item)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if all cart items have sufficient quantity.
|
||||
*
|
||||
|
|
@ -1121,6 +1143,28 @@ class Cart
|
|||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove item from cart, whose product is inactive
|
||||
* and returns true, if so.
|
||||
*/
|
||||
private function removeInactiveItem($item): bool
|
||||
{
|
||||
if (! $item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->getCart()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($item->product && $item->product->status === 0) {
|
||||
$this->removeItem($item->id);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param array $billingAddress
|
||||
|
|
|
|||
|
|
@ -19,6 +19,14 @@ class CustomerEventsHandler {
|
|||
Cart::mergeCart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle cart changes
|
||||
*/
|
||||
public function onCartChanged()
|
||||
{
|
||||
Cart::removeInactiveItems();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the listeners for the subscriber.
|
||||
*
|
||||
|
|
@ -28,5 +36,11 @@ class CustomerEventsHandler {
|
|||
public function subscribe($events)
|
||||
{
|
||||
$events->listen('customer.after.login', 'Webkul\Checkout\Listeners\CustomerEventsHandler@onCustomerLogin');
|
||||
|
||||
$events->listen('checkout.cart.add.before', 'Webkul\Checkout\Listeners\CustomerEventsHandler@onCartChanged');
|
||||
$events->listen('checkout.cart.item.add.before', 'Webkul\Checkout\Listeners\CustomerEventsHandler@onCartChanged');
|
||||
|
||||
$events->listen('checkout.cart.update.before', 'Webkul\Checkout\Listeners\CustomerEventsHandler@onCartChanged');
|
||||
$events->listen('checkout.cart.item.update.before', 'Webkul\Checkout\Listeners\CustomerEventsHandler@onCartChanged');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
|
||||
namespace Tests\Unit\Checkout\Cart;
|
||||
|
||||
use Faker\Factory;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use UnitTester;
|
||||
use Webkul\Core\Helpers\Laravel5Helper;
|
||||
|
||||
class CartCest
|
||||
{
|
||||
private $faker;
|
||||
private $simpleProduct1;
|
||||
private $simpleProduct2;
|
||||
private $virtualProduct1;
|
||||
private $virtualProduct2;
|
||||
private $downloadableProduct1;
|
||||
private $downloadableProduct2;
|
||||
|
||||
public function _before(UnitTester $I)
|
||||
{
|
||||
$this->faker = Factory::create();
|
||||
|
||||
$this->sessionToken = $this->faker->uuid;
|
||||
session(['_token' => $this->sessionToken]);
|
||||
|
||||
$this->simpleProduct1 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT);
|
||||
cart()->addProduct($this->simpleProduct1->id, [
|
||||
'_token' => session('_token'),
|
||||
'product_id' => $this->simpleProduct1->id,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$this->simpleProduct2 = $I->haveProduct(Laravel5Helper::SIMPLE_PRODUCT);
|
||||
cart()->addProduct($this->simpleProduct2->id, [
|
||||
'_token' => session('_token'),
|
||||
'product_id' => $this->simpleProduct2->id,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$this->virtualProduct1 = $I->haveProduct(Laravel5Helper::VIRTUAL_PRODUCT);
|
||||
cart()->addProduct($this->virtualProduct1->id, [
|
||||
'_token' => session('_token'),
|
||||
'product_id' => $this->virtualProduct1->id,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$this->virtualProduct2 = $I->haveProduct(Laravel5Helper::VIRTUAL_PRODUCT);
|
||||
cart()->addProduct($this->virtualProduct2->id, [
|
||||
'_token' => session('_token'),
|
||||
'product_id' => $this->virtualProduct2->id,
|
||||
'quantity' => 1,
|
||||
]);
|
||||
|
||||
$this->downloadableProduct1 = $I->haveProduct(Laravel5Helper::DOWNLOADABLE_PRODUCT);
|
||||
|
||||
$this->downloadableProduct2 = $I->haveProduct(Laravel5Helper::DOWNLOADABLE_PRODUCT);
|
||||
}
|
||||
|
||||
public function testCartWithInactiveProducts(UnitTester $I)
|
||||
{
|
||||
$I->comment('sP1, sP2, vP1 and vP2 in cart');
|
||||
$I->assertEquals(4, count(cart()->getCart()->items));
|
||||
|
||||
$I->comment('deactivate sP2');
|
||||
DB::table('product_attribute_values')
|
||||
->where([
|
||||
'product_id' => $this->simpleProduct2->id,
|
||||
'attribute_id' => 8 // status
|
||||
])
|
||||
->update(['boolean_value' => 0]);
|
||||
|
||||
Event::dispatch('catalog.product.update.after', $this->simpleProduct2->refresh());
|
||||
|
||||
$I->assertFalse(cart()->hasError());
|
||||
$I->comment('sP2 is inactive');
|
||||
$I->assertEquals(3, count(cart()->getCart()->items));
|
||||
|
||||
$I->comment('add dP2 to cart');
|
||||
cart()->addProduct($this->downloadableProduct2->id, [
|
||||
'_token' => session('_token'),
|
||||
'product_id' => $this->downloadableProduct2->id,
|
||||
'quantity' => 1,
|
||||
'links' => $this->downloadableProduct2->downloadable_links->pluck('id')->all(),
|
||||
]);
|
||||
|
||||
$I->assertFalse(cart()->hasError());
|
||||
$I->assertEquals(4, count(cart()->getCart()->items));
|
||||
|
||||
$I->comment('deactivate dP2');
|
||||
DB::table('product_attribute_values')
|
||||
->where([
|
||||
'product_id' => $this->downloadableProduct2->id,
|
||||
'attribute_id' => 8 // status
|
||||
])
|
||||
->update(['boolean_value' => 0]);
|
||||
|
||||
Event::dispatch('catalog.product.update.after', $this->downloadableProduct2->refresh());
|
||||
|
||||
$I->comment('we still have 4 products in cart as we didn`t changed cart itself');
|
||||
$I->assertEquals(4, count(cart()->getCart()->items));
|
||||
|
||||
$I->comment('add dP1 to cart, dP2 should be removed now');
|
||||
cart()->addProduct($this->downloadableProduct1->id, [
|
||||
'_token' => session('_token'),
|
||||
'product_id' => $this->downloadableProduct1->id,
|
||||
'quantity' => 1,
|
||||
'links' => $this->downloadableProduct1->downloadable_links->pluck('id')->all(),
|
||||
]);
|
||||
|
||||
$I->assertEquals(4, count(cart()->getCart()->items));
|
||||
|
||||
$I->comment('deactivate vP2');
|
||||
DB::table('product_attribute_values')
|
||||
->where([
|
||||
'product_id' => $this->virtualProduct2->id,
|
||||
'attribute_id' => 8 // status
|
||||
])
|
||||
->update(['boolean_value' => 0]);
|
||||
|
||||
Event::dispatch('catalog.product.update.after', $this->virtualProduct2->refresh());
|
||||
|
||||
$I->comment('change quantity of vP1, vP2 should be removed now');
|
||||
$cartItemId = $this->getCartItemIdFromProduct($this->virtualProduct1->id);
|
||||
cart()->updateItems([
|
||||
'qty' => [
|
||||
$cartItemId => 5
|
||||
],
|
||||
]);
|
||||
$I->assertEquals(3, count(cart()->getCart()->items));
|
||||
|
||||
$I->assertEquals(5, cart()->getCart()->items()->find($cartItemId)->quantity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $productId
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
private function getCartItemIdFromProduct(int $productId): ?int
|
||||
{
|
||||
foreach(cart()->getCart()->items as $item) {
|
||||
if ($item->product_id === $productId) {
|
||||
return $item->id;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue