diff --git a/spec/CommandHandler/Wishlist/AddSelectedProductsToCartHandlerSpec.php b/spec/CommandHandler/Wishlist/AddSelectedProductsToCartHandlerSpec.php index adb47989..d2562f28 100644 --- a/spec/CommandHandler/Wishlist/AddSelectedProductsToCartHandlerSpec.php +++ b/spec/CommandHandler/Wishlist/AddSelectedProductsToCartHandlerSpec.php @@ -15,6 +15,7 @@ use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItem; use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItemInterface; use BitBag\SyliusWishlistPlugin\CommandHandler\Wishlist\AddSelectedProductsToCartHandler; +use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantityException; use Doctrine\Common\Collections\ArrayCollection; use PhpSpec\ObjectBehavior; use Sylius\Bundle\OrderBundle\Controller\AddToCartCommandInterface; @@ -34,16 +35,12 @@ final class AddSelectedProductsToCartHandlerSpec extends ObjectBehavior { public function let( - RequestStack $requestStack, - Translator $translator, OrderItemQuantityModifierInterface $itemQuantityModifier, OrderModifierInterface $orderModifier, OrderRepositoryInterface $orderRepository, AvailabilityCheckerInterface $availabilityChecker, ): void { $this->beConstructedWith( - $requestStack, - $translator, $itemQuantityModifier, $orderModifier, $orderRepository, @@ -60,14 +57,9 @@ public function it_adds_selected_products_to_cart( WishlistItem $wishlistProduct, OrderModifierInterface $orderModifier, OrderRepositoryInterface $orderRepository, - OrderItemQuantityModifierInterface $itemQuantityModifier, OrderInterface $order, OrderItemInterface $orderItem, AddToCartCommandInterface $addToCartCommand, - RequestStack $requestStack, - Session $session, - FlashBagInterface $flashBag, - TranslatorInterface $translator, AvailabilityCheckerInterface $availabilityChecker, ProductVariantInterface $productVariant, ): void { @@ -86,27 +78,16 @@ public function it_adds_selected_products_to_cart( $availabilityChecker->isStockSufficient($productVariant, 1)->willReturn(true); - $requestStack->getSession()->willReturn($session); - $session->getFlashBag()->willReturn($flashBag); - $flashBag->has('success')->willReturn(false); - - $translator->trans('bitbag_sylius_wishlist_plugin.ui.added_to_cart')->willReturn('Test translation'); - $flashBag->add('success', 'Test translation')->shouldBeCalled(); - - $this->__invoke($addSelectedProductsToCart); + $this->shouldNotThrow()->during('__invoke', [$addSelectedProductsToCart]); } - public function it_doesnt_add_selected_products_to_cart_if_product_cannot_be_processed( + public function it_doesnt_add_selected_products_to_cart_if_product_cannot_be_processed_but_throws_exception( WishlistItemInterface $wishlistProduct, OrderModifierInterface $orderModifier, OrderRepositoryInterface $orderRepository, OrderInterface $order, OrderItemInterface $orderItem, AddToCartCommandInterface $addToCartCommand, - RequestStack $requestStack, - Session $session, - FlashBagInterface $flashBag, - TranslatorInterface $translator, AvailabilityCheckerInterface $availabilityChecker, ProductVariantInterface $productVariant, ): void { @@ -123,12 +104,6 @@ public function it_doesnt_add_selected_products_to_cart_if_product_cannot_be_pro $orderModifier->addToOrder($order, $orderItem)->shouldNotBeCalled(); $orderRepository->add($order)->shouldNotBeCalled(); - $requestStack->getSession()->willReturn($session); - $session->getFlashBag()->willReturn($flashBag); - - $translator->trans('bitbag_sylius_wishlist_plugin.ui.increase_quantity')->willReturn('Increase the quantity of at least one item.'); - $flashBag->add('error', 'Increase the quantity of at least one item.')->shouldBeCalled(); - - $this->__invoke($addSelectedProductsToCart); + $this->shouldThrow(InvalidProductQuantityException::class)->during('__invoke', [$addSelectedProductsToCart]); } } diff --git a/src/CommandHandler/Wishlist/AddSelectedProductsToCartHandler.php b/src/CommandHandler/Wishlist/AddSelectedProductsToCartHandler.php index 182b49c7..7450943f 100644 --- a/src/CommandHandler/Wishlist/AddSelectedProductsToCartHandler.php +++ b/src/CommandHandler/Wishlist/AddSelectedProductsToCartHandler.php @@ -13,6 +13,8 @@ use BitBag\SyliusWishlistPlugin\Command\Wishlist\AddSelectedProductsToCart; use BitBag\SyliusWishlistPlugin\Command\Wishlist\WishlistItemInterface; +use BitBag\SyliusWishlistPlugin\Exception\InsufficientProductStockException; +use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantityException; use Doctrine\Common\Collections\Collection; use Sylius\Bundle\OrderBundle\Controller\AddToCartCommandInterface; use Sylius\Component\Core\Model\OrderItemInterface; @@ -21,18 +23,13 @@ use Sylius\Component\Inventory\Checker\AvailabilityCheckerInterface; use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface; use Sylius\Component\Order\Modifier\OrderModifierInterface; -use Symfony\Component\HttpFoundation\RequestStack; -use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\Messenger\Attribute\AsMessageHandler; use Symfony\Component\Routing\Exception\ResourceNotFoundException; -use Symfony\Contracts\Translation\TranslatorInterface; #[AsMessageHandler] final class AddSelectedProductsToCartHandler { public function __construct( - private RequestStack $requestStack, - private TranslatorInterface $translator, private OrderItemQuantityModifierInterface $itemQuantityModifier, private OrderModifierInterface $orderModifier, private OrderRepositoryInterface $orderRepository, @@ -87,13 +84,7 @@ private function productIsStockSufficient(OrderItemInterface $product): bool return true; } - $message = sprintf('%s does not have sufficient stock.', $product->getProductName()); - - /** @var Session $session */ - $session = $this->requestStack->getSession(); - $session->getFlashBag()->add('error', $this->translator->trans($message)); - - return false; + throw new InsufficientProductStockException((string) $product->getProductName()); } private function productHasPositiveQuantity(OrderItemInterface $product): bool @@ -101,11 +92,8 @@ private function productHasPositiveQuantity(OrderItemInterface $product): bool if (0 < $product->getQuantity()) { return true; } - /** @var Session $session */ - $session = $this->requestStack->getSession(); - $session->getFlashBag()->add('error', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.increase_quantity')); - return false; + throw new InvalidProductQuantityException(); } private function addProductToWishlist(WishlistItemInterface $wishlistProduct): void @@ -126,13 +114,5 @@ private function addProductToWishlist(WishlistItemInterface $wishlistProduct): v $this->orderModifier->addToOrder($cart, $cartItem); $this->orderRepository->add($cart); - - /** @var Session $session */ - $session = $this->requestStack->getSession(); - $flashBag = $session->getFlashBag(); - - if (false === $flashBag->has('success')) { - $flashBag->add('success', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.added_to_cart')); - } } } diff --git a/src/Controller/Action/AddSelectedProductsToCartAction.php b/src/Controller/Action/AddSelectedProductsToCartAction.php index 84602675..be592805 100644 --- a/src/Controller/Action/AddSelectedProductsToCartAction.php +++ b/src/Controller/Action/AddSelectedProductsToCartAction.php @@ -12,12 +12,17 @@ namespace BitBag\SyliusWishlistPlugin\Controller\Action; use BitBag\SyliusWishlistPlugin\Command\Wishlist\AddSelectedProductsToCart; +use BitBag\SyliusWishlistPlugin\Exception\InsufficientProductStockException; +use BitBag\SyliusWishlistPlugin\Exception\InvalidProductQuantityException; use BitBag\SyliusWishlistPlugin\Processor\WishlistCommandProcessorInterface; use BitBag\SyliusWishlistPlugin\Repository\WishlistRepositoryInterface; use Sylius\Component\Order\Context\CartContextInterface; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\RequestStack; +use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface; +use Symfony\Component\HttpFoundation\Session\Session; +use Symfony\Component\Messenger\Exception\HandlerFailedException; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Contracts\Translation\TranslatorInterface; @@ -48,7 +53,35 @@ public function __construct( protected function handleCommand(FormInterface $form): void { - $command = new AddSelectedProductsToCart($form->getData()); - $this->messageBus->dispatch($command); + try { + $command = new AddSelectedProductsToCart($form->getData()); + $this->messageBus->dispatch($command); + if (false === $this->getFlashBag()->has('success')) { + $this->getFlashBag()->add('success', $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.added_to_cart')); + } + } catch (HandlerFailedException $exception) { + $this->getFlashBag()->add('error', $this->getExceptionMessage($exception)); + } + } + + private function getExceptionMessage(HandlerFailedException $exception): string + { + $previous = $exception->getPrevious(); + if ($previous instanceof InsufficientProductStockException) { + return $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.insufficient_stock', ['%productName%' => $previous->getProductName()]); + } + if ($previous instanceof InvalidProductQuantityException) { + return $this->translator->trans('bitbag_sylius_wishlist_plugin.ui.increase_quantity'); + } + + return $exception->getMessage(); + } + + private function getFlashBag(): FlashBagInterface + { + /** @var Session $session */ + $session = $this->requestStack->getSession(); + + return $session->getFlashBag(); } } diff --git a/src/Exception/InsufficientProductStockException.php b/src/Exception/InsufficientProductStockException.php new file mode 100644 index 00000000..609870dd --- /dev/null +++ b/src/Exception/InsufficientProductStockException.php @@ -0,0 +1,25 @@ +productName; + } +} diff --git a/src/Exception/InvalidProductQuantityException.php b/src/Exception/InvalidProductQuantityException.php new file mode 100644 index 00000000..0ba2d523 --- /dev/null +++ b/src/Exception/InvalidProductQuantityException.php @@ -0,0 +1,16 @@ + - - diff --git a/src/Resources/translations/messages.en.yml b/src/Resources/translations/messages.en.yml index bcdb5563..e1cf837a 100644 --- a/src/Resources/translations/messages.en.yml +++ b/src/Resources/translations/messages.en.yml @@ -14,6 +14,7 @@ bitbag_sylius_wishlist_plugin: added_to_cart: Wishlist items have been added to your cart. save_wishlist: Save wishlist variant_not_unique: You already have this variant on your wishlist + insufficient_stock: '%productName% does not have sufficient stock.' increase_quantity: Increase the quantity of at least one item. select_products: Select at least one item. added_selected_wishlist_items_to_cart: Selected wishlist items have been added to your cart. diff --git a/src/Resources/translations/messages.pl.yml b/src/Resources/translations/messages.pl.yml index 4fda0000..55556167 100644 --- a/src/Resources/translations/messages.pl.yml +++ b/src/Resources/translations/messages.pl.yml @@ -12,6 +12,7 @@ bitbag_sylius_wishlist_plugin: added_to_cart: Produkty z listy życzeń zostały dodane do koszyka. save_wishlist: Zapisz listę życzeń variant_not_unique: Ten wariant jest już na Twojej liście życzeń + insufficient_stock: '%productName% nie ma wystarczającego stanu magazynowego.' increase_quantity: Zwiększ ilość przynajmniej jednego z produktów. select_products: Wybierz przynajmniej jeden produkt. added_selected_wishlist_items_to_cart: Wybrane produkty zostały dodane do koszyka.