From 177327a7d27fa832d62a052ecbed123b103c20e4 Mon Sep 17 00:00:00 2001 From: Steffen Mahler Date: Thu, 4 Jun 2020 13:09:00 +0200 Subject: [PATCH] rework removing of inactive products from cart, add error handling and messaging --- packages/Webkul/Checkout/src/Cart.php | 78 +++++++++---------- .../src/Listeners/CustomerEventsHandler.php | 14 ---- .../src/Repositories/CartItemRepository.php | 16 ++-- .../src/Http/Controllers/CartController.php | 22 ++++-- .../Webkul/Shop/src/Resources/lang/de/app.php | 2 + .../Webkul/Shop/src/Resources/lang/en/app.php | 4 +- tests/unit/Checkout/Cart/CartCest.php | 5 +- 7 files changed, 67 insertions(+), 74 deletions(-) diff --git a/packages/Webkul/Checkout/src/Cart.php b/packages/Webkul/Checkout/src/Cart.php index a7714f408..ed60b6a95 100755 --- a/packages/Webkul/Checkout/src/Cart.php +++ b/packages/Webkul/Checkout/src/Cart.php @@ -137,6 +137,9 @@ class Cart } $product = $this->productRepository->findOneByField('id', $productId); + if ($product->status === 0) { + return ['info' => __('shop::app.checkout.cart.item.inactive-add')]; + } $cartProducts = $product->getTypeInstance()->prepareForCart($data); @@ -243,6 +246,10 @@ class Cart continue; } + if ($item->product && $item->product->status === 0) { + throw new \Exception(trans('shop::app.checkout.cart.item.inactive')); + } + if ($quantity <= 0) { $this->removeItem($itemId); @@ -439,17 +446,20 @@ class Cart */ public function getCart(): ?\Webkul\Checkout\Contracts\Cart { + $cart = null; if ($this->getCurrentCustomer()->check()) { - return $this->cartRepository->findOneWhere([ + $cart = $this->cartRepository->findOneWhere([ 'customer_id' => $this->getCurrentCustomer()->user()->id, 'is_active' => 1, ]); } elseif (session()->has('cart')) { - return $this->cartRepository->find(session()->get('cart')->id); + $cart = $this->cartRepository->find(session()->get('cart')->id); } - return null; + $this->removeInactiveItems($cart); + + return $cart; } /** @@ -765,7 +775,7 @@ class Cart return true; } - if (! $this->checkCartItems()) { + if (! $this->isItemsHaveSufficientQuantity()) { return true; } @@ -773,19 +783,13 @@ class Cart } /** - * Checks all cart items for: - * - product is active (if not, cart item will be removed) - * - product has sufficient quantity + * Checks if all cart items have sufficient quantity. * * @return bool */ - public function checkCartItems(): bool + public function isItemsHaveSufficientQuantity(): bool { foreach ($this->getCart()->items as $item) { - if ($this->removeInactiveItem($item)) { - continue; - } - if (! $this->isItemHaveQuantity($item)) { return false; } @@ -797,17 +801,31 @@ class Cart /** * Remove cart items, whose product is inactive */ - public function removeInactiveItems() + public function removeInactiveItems(\Webkul\Checkout\Models\Cart $cart = null): ?\Webkul\Checkout\Models\Cart { - if (! $cart = $this->getCart()) { - return; + if (! $cart) { + return $cart; } foreach ($cart->items as $item) { - if ($this->removeInactiveItem($item)) { - continue; + if ($item->product && $item->product->status === 0) { + + $this->cartItemRepository->delete($item->id); + + if ($cart->items()->get()->count() == 0) { + $this->cartRepository->delete($cart->id); + + if (session()->has('cart')) { + session()->forget('cart'); + } + } + + session()->flash('info', trans('shop::app.checkout.cart.item.inactive')); } } + $cart->save(); + + return $cart; } /** @@ -1143,32 +1161,6 @@ class Cart return $attributes; } - /** - * Remove item from cart, whose product is inactive - * and returns true, if so. - * - * @param \Webkul\Checkout\Models\CartItem $item - * - * @return bool - */ - private function removeInactiveItem(\Webkul\Checkout\Models\CartItem $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 diff --git a/packages/Webkul/Checkout/src/Listeners/CustomerEventsHandler.php b/packages/Webkul/Checkout/src/Listeners/CustomerEventsHandler.php index ae0def7d6..a72116f26 100755 --- a/packages/Webkul/Checkout/src/Listeners/CustomerEventsHandler.php +++ b/packages/Webkul/Checkout/src/Listeners/CustomerEventsHandler.php @@ -19,14 +19,6 @@ class CustomerEventsHandler { Cart::mergeCart(); } - /** - * Handle cart changes - */ - public function onCartChanged() - { - Cart::removeInactiveItems(); - } - /** * Register the listeners for the subscriber. * @@ -36,11 +28,5 @@ 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'); } } \ No newline at end of file diff --git a/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php b/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php index 4141923c0..a5917c929 100755 --- a/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php +++ b/packages/Webkul/Checkout/src/Repositories/CartItemRepository.php @@ -3,6 +3,7 @@ namespace Webkul\Checkout\Repositories; use Webkul\Core\Eloquent\Repository; +use Webkul\Checkout\Contracts\CartItem; class CartItemRepository extends Repository { @@ -18,16 +19,19 @@ class CartItemRepository extends Repository } /** - * @param array $data - * @param int $id - * @param string $attribute - * @return \Webkul\Checkout\Contracts\CartItem + * @param array $data + * @param $id + * @param string $attribute + * + * @return \Webkul\Checkout\Contracts\CartItem|null */ - public function update(array $data, $id, $attribute = "id") + public function update(array $data, $id, $attribute = "id"): ?CartItem { $item = $this->find($id); - $item->update($data); + if ($item) { + $item->update($data); + } return $item; } diff --git a/packages/Webkul/Shop/src/Http/Controllers/CartController.php b/packages/Webkul/Shop/src/Http/Controllers/CartController.php index 74b3253b9..418a9d495 100755 --- a/packages/Webkul/Shop/src/Http/Controllers/CartController.php +++ b/packages/Webkul/Shop/src/Http/Controllers/CartController.php @@ -68,9 +68,7 @@ class CartController extends Controller try { $result = Cart::addProduct($id, request()->all()); - if ($this->onWarningAddingToCart($result)) { - session()->flash('warning', $result['warning']); - + if ($this->onFailureAddingToCart($result)) { return redirect()->back(); } @@ -205,13 +203,25 @@ class CartController extends Controller } /** - * Returns true, if result of adding product to cart is an array and contains a key "warning" + * Returns true, if result of adding product to cart + * is an array and contains a key "warning" or "info" * * @param array $result + * * @return boolean */ - private function onWarningAddingToCart($result): bool + private function onFailureAddingToCart($result): bool { - return is_array($result) && isset($result['warning']); + if (is_array($result) && isset($result['warning'])) { + session()->flash('warning', $result['warning']); + return true; + } + + if (is_array($result) && isset($result['info'])) { + session()->flash('info', $result['info']); + return true; + } + + return false; } } diff --git a/packages/Webkul/Shop/src/Resources/lang/de/app.php b/packages/Webkul/Shop/src/Resources/lang/de/app.php index dec432e80..e0abff994 100755 --- a/packages/Webkul/Shop/src/Resources/lang/de/app.php +++ b/packages/Webkul/Shop/src/Resources/lang/de/app.php @@ -458,6 +458,8 @@ return [ 'success' => 'Artikel wurde erfolgreich zum Warenkorb hinzugefügt', 'success-remove' => 'Artikel wurde erfolgreich aus dem Warenkorb entfernt', 'error-add' => 'Artikel kann nicht zum Warenkorb hinzugefügt werden. Bitte versuchen Sie es später erneut', + 'inactive' => 'Ein Artikel ist inaktiv und wurde aus dem Warenkorb entfernt.', + 'inactive-add' => 'Ein inactiver Artikel kann nicht zum Warenkorb hinzugefügt werde.', ], 'quantity-error' => 'Die angeforderte Menge ist nicht verfügbar', 'cart-subtotal' => 'Warenkorb Zwischensumme', diff --git a/packages/Webkul/Shop/src/Resources/lang/en/app.php b/packages/Webkul/Shop/src/Resources/lang/en/app.php index 30e5564a7..6f3eb67bd 100755 --- a/packages/Webkul/Shop/src/Resources/lang/en/app.php +++ b/packages/Webkul/Shop/src/Resources/lang/en/app.php @@ -461,6 +461,8 @@ return [ 'success' => 'Item was successfully added to cart.', 'success-remove' => 'Item was removed successfully from the cart.', 'error-add' => 'Item cannot be added to cart, please try again later.', + 'inactive' => 'An item is inactive and was removed from cart.', + 'inactive-add' => 'Inactive item cannot be added to cart.', ], 'quantity-error' => 'Requested quantity is not available.', 'cart-subtotal' => 'Cart Subtotal', @@ -576,7 +578,7 @@ return [ 'final-summary' => 'Thanks for showing your interest in our store we will send you tracking number once it shipped', 'help' => 'If you need any kind of help please contact us at :support_email', 'thanks' => 'Thanks!', - + 'comment' => [ 'subject' => 'New comment added to your order', 'dear' => 'Dear :customer_name', diff --git a/tests/unit/Checkout/Cart/CartCest.php b/tests/unit/Checkout/Cart/CartCest.php index e2ae38cdc..967188e36 100644 --- a/tests/unit/Checkout/Cart/CartCest.php +++ b/tests/unit/Checkout/Cart/CartCest.php @@ -85,8 +85,8 @@ class CartCest 'links' => $this->downloadableProduct2->downloadable_links->pluck('id')->all(), ]); - $I->assertFalse(cart()->hasError()); $I->assertEquals(4, count(cart()->getCart()->items)); + $I->assertFalse(cart()->hasError()); $I->comment('deactivate dP2'); DB::table('product_attribute_values') @@ -98,9 +98,6 @@ class CartCest 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'),