Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit bccfe0b

Browse files
committed
[API][Cart] change order item quantity
1 parent a9f6ec2 commit bccfe0b

9 files changed

Lines changed: 266 additions & 4 deletions

File tree

features/cart/shopping_cart/changing_quantity_of_product_in_cart.feature

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ Feature: Changing quantity of a product in cart
99
And the store has a product "T-shirt banana" priced at "$12.54"
1010
And I add this product to the cart
1111

12-
@ui
12+
@ui @api
1313
Scenario: Increasing quantity of an item in cart
1414
Given I see the summary of my cart
15-
When I change "T-shirt banana" quantity to 2
15+
When I change product "T-shirt banana" quantity to 2 in my cart
1616
Then I should see "T-shirt banana" with quantity 2 in my cart
1717

18-
@ui
18+
@ui @api
1919
Scenario: Increasing quantity of an item in cart beyond the threshold
2020
Given I see the summary of my cart
21-
When I change "T-shirt banana" quantity to 20000
21+
When I change product "T-shirt banana" quantity to 20000 in my cart
2222
Then I should see "T-shirt banana" with quantity 9999 in my cart

src/Sylius/Behat/Context/Api/Shop/CartContext.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,24 @@ public function iAddOfThemToMyCart(int $quantity, ProductInterface $product, str
8383
$this->putProductToCart($product, $tokenValue, $quantity);
8484
}
8585

86+
/**
87+
* @When /^I change (product "[^"]+") quantity to (\d+) in my (cart)$/
88+
*/
89+
public function iChangeQuantityTo( ProductInterface $product, int $quantity, string $tokenValue): void
90+
{
91+
$items = $this->responseChecker->getValue($this->cartsClient->show($tokenValue), 'items');
92+
93+
foreach ($items as $item) {
94+
$pathElements = explode('/', $item['variant']['product']);
95+
96+
$productCode = $pathElements[array_key_last($pathElements)];
97+
98+
if ($product->getCode() === $productCode) {
99+
$this->changeQuantityOfOrderItem((string) $item['id'], $quantity, $tokenValue);
100+
}
101+
}
102+
}
103+
86104
/**
87105
* @When /^I remove (product "[^"]+") from the (cart)$/
88106
*/
@@ -244,4 +262,13 @@ private function getProductForItem(array $item): Response
244262

245263
return $this->productsClient->show(StringInflector::nameToSlug($productCode));
246264
}
265+
266+
private function changeQuantityOfOrderItem(string $orderItemId, int $quantity, string $tokenValue): void
267+
{
268+
$request = Request::customItemAction('orders', $tokenValue, HttpRequest::METHOD_PATCH, 'change-quantity');
269+
270+
$request->updateContent(['orderItemId' => $orderItemId, 'newQuantity' => $quantity]);
271+
272+
$this->cartsClient->executeCustomRequest($request);
273+
}
247274
}

src/Sylius/Behat/Context/Ui/Shop/CartContext.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ public function iRemoveProductFromTheCart(string $productName): void
9090

9191
/**
9292
* @Given I change :productName quantity to :quantity
93+
* @Given I change product :productName quantity to :quantity in my cart
9394
*/
9495
public function iChangeQuantityTo($productName, $quantity)
9596
{
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Sylius package.
5+
*
6+
* (c) Paweł Jędrzejewski
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Sylius\Bundle\ApiBundle\Command\Cart;
15+
16+
use Sylius\Bundle\ApiBundle\Command\OrderTokenValueAwareInterface;
17+
18+
final class ChangeItemQuantityInCart implements OrderTokenValueAwareInterface
19+
{
20+
/** @var string|null */
21+
public $orderTokenValue;
22+
23+
/**
24+
* @var string
25+
* @psalm-immutable
26+
*/
27+
public $orderItemId;
28+
29+
/**
30+
* @var int
31+
* @psalm-immutable
32+
*/
33+
public $newQuantity;
34+
35+
public function __construct(string $orderItemId, int $newQuantity)
36+
{
37+
$this->orderItemId = $orderItemId;
38+
$this->newQuantity = $newQuantity;
39+
}
40+
41+
public static function createFromData(string $tokenValue, string $orderItemId, int $newQuantity): self
42+
{
43+
$command = new self($orderItemId, $newQuantity);
44+
45+
$command->orderTokenValue = $tokenValue;
46+
47+
return $command;
48+
}
49+
50+
public function getOrderTokenValue(): ?string
51+
{
52+
return $this->orderTokenValue;
53+
}
54+
55+
public function setOrderTokenValue(?string $orderTokenValue): void
56+
{
57+
$this->orderTokenValue = $orderTokenValue;
58+
}
59+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Sylius package.
5+
*
6+
* (c) Paweł Jędrzejewski
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Sylius\Bundle\ApiBundle\CommandHandler\Cart;
15+
16+
use Sylius\Bundle\ApiBundle\Command\Cart\ChangeItemQuantityInCart;
17+
use Sylius\Component\Core\Model\OrderInterface;
18+
use Sylius\Component\Core\Model\OrderItemInterface;
19+
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
20+
use Sylius\Component\Order\Processor\OrderProcessorInterface;
21+
use Sylius\Component\Order\Repository\OrderItemRepositoryInterface;
22+
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
23+
use Webmozart\Assert\Assert;
24+
25+
final class ChangeItemQuantityInCartHandler implements MessageHandlerInterface
26+
{
27+
/** @var OrderItemRepositoryInterface */
28+
private $orderItemRepository;
29+
30+
/** @var OrderItemQuantityModifierInterface */
31+
private $orderItemQuantityModifier;
32+
33+
/** @var OrderProcessorInterface */
34+
private $orderProcessor;
35+
36+
public function __construct(
37+
OrderItemRepositoryInterface $orderItemRepository,
38+
OrderItemQuantityModifierInterface $orderItemQuantityModifier,
39+
OrderProcessorInterface $orderProcessor
40+
) {
41+
$this->orderItemRepository = $orderItemRepository;
42+
$this->orderItemQuantityModifier = $orderItemQuantityModifier;
43+
$this->orderProcessor = $orderProcessor;
44+
}
45+
46+
public function __invoke(ChangeItemQuantityInCart $command): OrderInterface
47+
{
48+
/** @var OrderItemInterface|null $orderItem */
49+
$orderItem = $this->orderItemRepository->findOneByIdAndCartTokenValue(
50+
$command->orderItemId,
51+
$command->orderTokenValue
52+
);
53+
54+
Assert::notNull($orderItem);
55+
56+
/** @var OrderInterface $cart */
57+
$cart = $orderItem->getOrder();
58+
59+
Assert::same($cart->getTokenValue(), $command->orderTokenValue);
60+
61+
$this->orderItemQuantityModifier->modify($orderItem, $command->newQuantity);
62+
$this->orderProcessor->process($cart);
63+
64+
return $cart;
65+
}
66+
}

src/Sylius/Bundle/ApiBundle/Resources/config/api_resources/Order.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,20 @@
143143
<attribute name="groups">cart:remove_item</attribute>
144144
</attribute>
145145
</itemOperation>
146+
147+
<itemOperation name="change_quantity">
148+
<attribute name="security">is_granted('IS_AUTHENTICATED_ANONYMOUSLY')</attribute>
149+
<attribute name="openapi_context">
150+
<attribute name="summary">Change quantity of order item</attribute>
151+
</attribute>
152+
<attribute name="method">PATCH</attribute>
153+
<attribute name="path">/orders/{id}/change-quantity</attribute>
154+
<attribute name="messenger">input</attribute>
155+
<attribute name="input">Sylius\Bundle\ApiBundle\Command\Cart\ChangeItemQuantityInCart</attribute>
156+
<attribute name="denormalization_context">
157+
<attribute name="groups">cart:change_quantity</attribute>
158+
</attribute>
159+
</itemOperation>
146160
</itemOperations>
147161

148162
<property name="id" identifier="false" writable="false" />
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" ?>
2+
3+
<!--
4+
5+
This file is part of the Sylius package.
6+
7+
(c) Paweł Jędrzejewski
8+
9+
For the full copyright and license information, please view the LICENSE
10+
file that was distributed with this source code.
11+
12+
-->
13+
14+
<serializer xmlns="http://symfony.com/schema/dic/serializer-mapping"
15+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
16+
xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
17+
>
18+
<class name="Sylius\Bundle\ApiBundle\Command\Cart\ChangeItemQuantityInCart">
19+
<attribute name="orderItemId">
20+
<group>cart:change_quantity</group>
21+
</attribute>
22+
23+
<attribute name="newQuantity">
24+
<group>cart:change_quantity</group>
25+
</attribute>
26+
</class>
27+
</serializer>

src/Sylius/Bundle/ApiBundle/Resources/config/services/command_handlers.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,12 @@
7777
<argument type="service" id="sm.factory" />
7878
<tag name="messenger.message_handler" />
7979
</service>
80+
81+
<service id="Sylius\Bundle\ApiBundle\CommandHandler\Cart\ChangeItemQuantityInCartHandler">
82+
<argument type="service" id="sylius.repository.order_item" />
83+
<argument type="service" id="sylius.order_item_quantity_modifier" />
84+
<argument type="service" id="sylius.order_processing.order_processor" />
85+
<tag name="messenger.message_handler" />
86+
</service>
8087
</services>
8188
</container>
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Sylius package.
5+
*
6+
* (c) Paweł Jędrzejewski
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Sylius\Bundle\ApiBundle\spec\CommandHandler\Cart;
15+
16+
use PhpSpec\ObjectBehavior;
17+
use Sylius\Bundle\ApiBundle\Command\Cart\ChangeItemQuantityInCart;
18+
use Sylius\Bundle\OrderBundle\Doctrine\ORM\OrderItemRepository;
19+
use Sylius\Component\Core\Model\OrderInterface;
20+
use Sylius\Component\Core\Model\OrderItemInterface;
21+
use Sylius\Component\Order\Modifier\OrderItemQuantityModifierInterface;
22+
use Sylius\Component\Order\Processor\OrderProcessorInterface;
23+
use Sylius\Component\Order\Repository\OrderItemRepositoryInterface;
24+
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
25+
26+
final class ChangeItemQuantityInCartSpec extends ObjectBehavior
27+
{
28+
function let(
29+
OrderItemRepositoryInterface $orderItemRepository,
30+
OrderItemQuantityModifierInterface $orderItemQuantityModifier,
31+
OrderProcessorInterface $orderProcessor
32+
) {
33+
$this->beConstructedWith($orderItemRepository, $orderItemQuantityModifier, $orderProcessor);
34+
}
35+
36+
function it_is_a_message_handler(): void
37+
{
38+
$this->shouldImplement(MessageHandlerInterface::class);
39+
}
40+
41+
function it_changes_order_item_quantity(
42+
OrderItemRepository $orderItemRepository,
43+
OrderInterface $cart,
44+
OrderItemInterface $cartItem,
45+
OrderItemQuantityModifierInterface $orderItemQuantityModifier
46+
47+
): void {
48+
$orderItemRepository->findOneByIdAndCartTokenValue(
49+
'ORDER_ITEM_ID',
50+
'TOKEN_VALUE'
51+
)->willReturn($cartItem);
52+
53+
$cartItem->getOrder()->willReturn($cart);
54+
55+
$cart->getTokenValue()->willReturn('TOKEN_VALUE');
56+
57+
$orderItemQuantityModifier->modify($cartItem, 5)->shouldBeCalled();
58+
59+
$this(ChangeItemQuantityInCart::createFromData('ORDER_ITEM_ID', 'TOKEN_VALUE'));
60+
}
61+
}

0 commit comments

Comments
 (0)