Skip to content

Commit

Permalink
refactor #488 [Cart] Simplify cart recalculation after customer cart …
Browse files Browse the repository at this point in the history
…assignment (lchrusciel)

This PR was merged into the 1.0-dev branch.

Discussion
----------

Closing #401, #259 and #406

Commits
-------

f80d609 [Customer] Refactor customer assignment to command
bf72278 [Cart] Simplify cart recalculation after customer cart assignment
e97cd65 [Cart] Auto assign customer to cart during cart pick up
  • Loading branch information
GSadee authored Jul 25, 2019
2 parents f937ffd + e97cd65 commit 94d3ceb
Show file tree
Hide file tree
Showing 14 changed files with 219 additions and 120 deletions.
20 changes: 20 additions & 0 deletions spec/Event/CartPickedUpSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\ShopApiPlugin\Event;

use PhpSpec\ObjectBehavior;

final class CartPickedUpSpec extends ObjectBehavior
{
function let(): void
{
$this->beConstructedWith('ORDERTOKEN');
}

function it_has_order_token(): void
{
$this->orderToken()->shouldReturn('ORDERTOKEN');
}
}
53 changes: 53 additions & 0 deletions spec/EventListener/Messenger/CartPickedUpListenerSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

declare(strict_types=1);

namespace spec\Sylius\ShopApiPlugin\EventListener\Messenger;

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\ShopApiPlugin\Command\Cart\AssignCustomerToCart;
use Sylius\ShopApiPlugin\Event\CartPickedUp;
use Sylius\ShopApiPlugin\Provider\LoggedInShopUserProviderInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;

final class CartPickedUpListenerSpec extends ObjectBehavior
{
function let(LoggedInShopUserProviderInterface $loggedInShopUserProvider, MessageBusInterface $bus): void
{
$this->beConstructedWith($loggedInShopUserProvider, $bus);
}

function it_assigns_customer_to_cart_when_user_is_logged_in(
LoggedInShopUserProviderInterface $loggedInShopUserProvider,
MessageBusInterface $bus,
ShopUserInterface $shopUser,
CustomerInterface $customer
): void {
$loggedInShopUserProvider->isUserLoggedIn()->willReturn(true);

$loggedInShopUserProvider->provide()->willReturn($shopUser);
$shopUser->getCustomer()->willReturn($customer);
$customer->getEmail()->willReturn('peter@parker.com');

$assignCustomerToCart = new AssignCustomerToCart('ORDERTOKEN', 'peter@parker.com');

$bus->dispatch($assignCustomerToCart)->willReturn(new Envelope($assignCustomerToCart))->shouldBeCalled();

$this(new CartPickedUp('ORDERTOKEN'));
}

function it_does_nothing_if_user_is_not_logged_in(
LoggedInShopUserProviderInterface $loggedInShopUserProvider,
MessageBusInterface $bus
): void {
$loggedInShopUserProvider->isUserLoggedIn()->willReturn(false);

$bus->dispatch(Argument::any())->shouldNotBeCalled();

$this(new CartPickedUp('ORDERTOKEN'));
}
}
27 changes: 17 additions & 10 deletions spec/Handler/Cart/AssignCustomerToCartHandlerSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,42 @@
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Order\Processor\OrderProcessorInterface;
use Sylius\ShopApiPlugin\Command\Cart\AssignCustomerToCart;
use Sylius\ShopApiPlugin\Provider\CustomerProviderInterface;

final class AssignCustomerToCartHandlerSpec extends ObjectBehavior
{
function let(OrderRepositoryInterface $orderRepository, CustomerProviderInterface $customerProvider): void
{
$this->beConstructedWith($orderRepository, $customerProvider);
function let(
OrderRepositoryInterface $cartRepository,
OrderProcessorInterface $orderProcessor,
CustomerProviderInterface $customerProvider
): void {
$this->beConstructedWith($cartRepository, $orderProcessor, $customerProvider);
}

function it_handles_assigning_customer_to_cart(
CustomerInterface $customer,
OrderRepositoryInterface $cartRepository,
OrderProcessorInterface $orderProcessor,
CustomerProviderInterface $customerProvider,
OrderInterface $order,
OrderRepositoryInterface $orderRepository
CustomerInterface $customer,
OrderInterface $cart
): void {
$orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($order);
$cartRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn($cart);

$customerProvider->provide('example@customer.com')->willReturn($customer);

$order->setCustomer($customer)->shouldBeCalled();
$cart->setCustomer($customer)->shouldBeCalled();

$orderProcessor->process($cart);

$this(new AssignCustomerToCart('ORDERTOKEN', 'example@customer.com'));
}

function it_throws_an_exception_if_order_does_not_exist(
OrderRepositoryInterface $orderRepository
OrderRepositoryInterface $cartRepository
): void {
$orderRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn(null);
$cartRepository->findOneBy(['tokenValue' => 'ORDERTOKEN'])->willReturn(null);

$this
->shouldThrow(\InvalidArgumentException::class)
Expand Down
16 changes: 13 additions & 3 deletions spec/Handler/Cart/PickupCartHandlerSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,24 @@
use Sylius\Component\Locale\Model\LocaleInterface;
use Sylius\Component\Resource\Factory\FactoryInterface;
use Sylius\ShopApiPlugin\Command\Cart\PickupCart;
use Sylius\ShopApiPlugin\Event\CartPickedUp;
use Sylius\ShopApiPlugin\Handler\Cart\PickupCartHandler;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;

final class PickupCartHandlerSpec extends ObjectBehavior
{
function let(
FactoryInterface $cartFactory,
OrderRepositoryInterface $cartRepository,
ChannelRepositoryInterface $channelRepository
ChannelRepositoryInterface $channelRepository,
MessageBusInterface $eventBus
): void {
$this->beConstructedWith(
$cartFactory,
$cartRepository,
$channelRepository
$channelRepository,
$eventBus
);
}

Expand All @@ -41,7 +46,8 @@ function it_handles_cart_pickup_for_not_logged_in_user(
FactoryInterface $cartFactory,
LocaleInterface $locale,
OrderInterface $cart,
OrderRepositoryInterface $cartRepository
OrderRepositoryInterface $cartRepository,
MessageBusInterface $eventBus
): void {
$channelRepository->findOneByCode('CHANNEL_CODE')->willReturn($channel);
$channel->getBaseCurrency()->willReturn($currency);
Expand All @@ -58,6 +64,10 @@ function it_handles_cart_pickup_for_not_logged_in_user(

$cartRepository->add($cart)->shouldBeCalledOnce();

$cartPickedUp = new CartPickedUp('ORDERTOKEN');

$eventBus->dispatch($cartPickedUp)->willReturn(new Envelope($cartPickedUp))->shouldBeCalled();

$this(new PickupCart('ORDERTOKEN', 'CHANNEL_CODE'));
}

Expand Down
21 changes: 21 additions & 0 deletions src/Event/CartPickedUp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Sylius\ShopApiPlugin\Event;

class CartPickedUp
{
/** @var string */
protected $orderToken;

public function __construct(string $orderToken)
{
$this->orderToken = $orderToken;
}

public function orderToken(): string
{
return $this->orderToken;
}
}
48 changes: 11 additions & 37 deletions src/EventListener/CartBlamerListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,32 @@

namespace Sylius\ShopApiPlugin\EventListener;

use Doctrine\Common\Persistence\ObjectManager;
use Lexik\Bundle\JWTAuthenticationBundle\Event\JWTCreatedEvent;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\ShopUserInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Order\Context\CartNotFoundException;
use Sylius\ShopApiPlugin\Command\Cart\AssignCustomerToCart;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Messenger\MessageBusInterface;
use Webmozart\Assert\Assert;

final class CartBlamerListener
{
/** @var ObjectManager */
private $cartManager;

/** @var CartContextInterface */
private $cartContext;

/** @var OrderRepositoryInterface */
private $cartRepository;

/** @var MessageBusInterface */
private $bus;

/** @var RequestStack */
private $requestStack;

public function __construct(
ObjectManager $cartManager,
CartContextInterface $cartContext,
OrderRepositoryInterface $cartRepository,
MessageBusInterface $bus,
RequestStack $requestStack
) {
$this->cartManager = $cartManager;
$this->cartContext = $cartContext;
$this->cartRepository = $cartRepository;
$this->bus = $bus;
$this->requestStack = $requestStack;
}

Expand All @@ -51,33 +44,14 @@ public function onJwtLogin(JWTCreatedEvent $interactiveLoginEvent): void
return;
}

$cart = $this->getCart($request->request->get('token'));
$token = $request->request->get('token');

$cart = $this->cartRepository->findOneBy(['tokenValue' => $token]);

if (null === $cart) {
return;
}

$cart->setCustomer($user->getCustomer());
$this->cartManager->persist($cart);
$this->cartManager->flush();
}

private function getCart(?string $token): ?OrderInterface
{
if (null !== $token) {
/** @var OrderInterface $cart */
$cart = $this->cartRepository->findOneBy(['tokenValue' => $token]);

return $cart;
}

try {
/** @var OrderInterface $cart */
$cart = $this->cartContext->getCart();

return $cart;
} catch (CartNotFoundException $exception) {
return null;
}
$this->bus->dispatch(new AssignCustomerToCart($token, $user->getCustomer()->getEmail()));
}
}
37 changes: 37 additions & 0 deletions src/EventListener/Messenger/CartPickedUpListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Sylius\ShopApiPlugin\EventListener\Messenger;

use Sylius\ShopApiPlugin\Command\Cart\AssignCustomerToCart;
use Sylius\ShopApiPlugin\Event\CartPickedUp;
use Sylius\ShopApiPlugin\Provider\LoggedInShopUserProviderInterface;
use Symfony\Component\Messenger\MessageBusInterface;

final class CartPickedUpListener
{
/** @var LoggedInShopUserProviderInterface */
private $loggedInShopUserProvider;

/** @var MessageBusInterface */
private $bus;

public function __construct(LoggedInShopUserProviderInterface $loggedInShopUserProvider, MessageBusInterface $bus)
{
$this->loggedInShopUserProvider = $loggedInShopUserProvider;
$this->bus = $bus;
}

public function __invoke(CartPickedUp $cartPickedUp): void
{
if (!$this->loggedInShopUserProvider->isUserLoggedIn()) {
return;
}

$shopUser = $this->loggedInShopUserProvider->provide();
$email = $shopUser->getCustomer()->getEmail();

$this->bus->dispatch(new AssignCustomerToCart($cartPickedUp->orderToken(), $email));
}
}
49 changes: 0 additions & 49 deletions src/EventListener/UserCartRecalculationListener.php

This file was deleted.

Loading

0 comments on commit 94d3ceb

Please sign in to comment.