Skip to content

Commit b63124a

Browse files
ENGCOM-8490: Allow customer to specify associated product qtys when adding grouped product to cart via RESTful API #27845
- Merge Pull Request #27845 from shawnabramson/magento2:26909-grouped-product-restapi - Merged commits: 1. dcc6381 2. de1f626 3. 8d2c280 4. e9fa0a8 5. d5160db 6. 8b141e1 7. bb9c1e2 8. 3bcdd48 9. 7f49335 10. 3626d9c 11. cc0c942 12. 74709d2 13. fa4c7b8 14. 24c27a4 15. be84eb1 16. c936161 17. 7af13d7 18. 4240a6b 19. 768b305 20. 4aa5527 21. 0ace0c3 22. bdfe7ec 23. 769653a
2 parents 78c411d + 769653a commit b63124a

File tree

6 files changed

+415
-14
lines changed

6 files changed

+415
-14
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GroupedProduct\Api\Data;
9+
10+
use Magento\Framework\Api\ExtensibleDataInterface;
11+
12+
/**
13+
* Represents `product item id with qty` of a grouped product.
14+
*/
15+
interface GroupedOptionsInterface extends ExtensibleDataInterface
16+
{
17+
/**
18+
* Get associated product id
19+
*
20+
* @return int|null
21+
*/
22+
public function getId(): ?int;
23+
24+
/**
25+
* Get associated product qty
26+
*
27+
* @return int|null
28+
*/
29+
public function getQty(): ?int;
30+
31+
/**
32+
* Set extension attributes
33+
*
34+
* @param \Magento\GroupedProduct\Api\Data\GroupedOptionsExtensionInterface $extensionAttributes
35+
* @return void
36+
*/
37+
public function setExtensionAttributes(GroupedOptionsExtensionInterface $extensionAttributes): void;
38+
39+
/**
40+
* Get extension attributes
41+
*
42+
* @return \Magento\GroupedProduct\Api\Data\GroupedOptionsExtensionInterface|null
43+
*/
44+
public function getExtensionAttributes(): ?GroupedOptionsExtensionInterface;
45+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GroupedProduct\Model\Quote\Item;
9+
10+
use Magento\Framework\DataObject;
11+
use Magento\Framework\DataObject\Factory as ObjectFactory;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\GroupedProduct\Api\Data\GroupedOptionsInterface;
14+
use Magento\GroupedProduct\Model\Product\Type\Grouped;
15+
use Magento\Quote\Api\Data as QuoteApi;
16+
use Magento\Quote\Api\Data\CartItemInterface;
17+
use Magento\Quote\Model\Quote\Item\CartItemProcessorInterface;
18+
19+
/**
20+
* Converts grouped_options to super_group for the grouped product.
21+
*/
22+
class CartItemProcessor implements CartItemProcessorInterface
23+
{
24+
private const SUPER_GROUP_CODE = 'super_group';
25+
26+
/**
27+
* @var ObjectFactory
28+
*/
29+
private $objectFactory;
30+
31+
/**
32+
* @var QuoteApi\ProductOptionExtensionFactory
33+
*/
34+
private $productOptionExtensionFactory;
35+
36+
/**
37+
* @var QuoteApi\ProductOptionInterfaceFactory
38+
*/
39+
private $productOptionFactory;
40+
41+
/**
42+
* @var array|null
43+
*/
44+
private $groupedOptions;
45+
46+
/**
47+
* @param ObjectFactory $objectFactory
48+
* @param QuoteApi\ProductOptionExtensionFactory $productOptionExtensionFactory
49+
* @param QuoteApi\ProductOptionInterfaceFactory $productOptionFactory
50+
*/
51+
public function __construct(
52+
ObjectFactory $objectFactory,
53+
QuoteApi\ProductOptionExtensionFactory $productOptionExtensionFactory,
54+
QuoteApi\ProductOptionInterfaceFactory $productOptionFactory
55+
) {
56+
$this->objectFactory = $objectFactory;
57+
$this->productOptionExtensionFactory = $productOptionExtensionFactory;
58+
$this->productOptionFactory = $productOptionFactory;
59+
}
60+
61+
/**
62+
* Converts the grouped_options request data into the same format as native frontend add-to-cart
63+
*
64+
* @param CartItemInterface $cartItem
65+
* @return DataObject|null
66+
*/
67+
public function convertToBuyRequest(CartItemInterface $cartItem): ?DataObject
68+
{
69+
if ($cartItem->getProductOption()
70+
&& $cartItem->getProductOption()->getExtensionAttributes()
71+
&& $cartItem->getProductOption()->getExtensionAttributes()->getGroupedOptions()
72+
) {
73+
$groupedOptions = $cartItem->getProductOption()->getExtensionAttributes()->getGroupedOptions();
74+
$this->groupedOptions = $groupedOptions;
75+
76+
return $this->objectFactory->create($this->getConvertedData($groupedOptions));
77+
}
78+
79+
return null;
80+
}
81+
82+
/**
83+
* Returns grouped_options converted to super_group data
84+
*
85+
* @param GroupedOptionsInterface[] $groupedOptions
86+
* @return array
87+
* @throws LocalizedException
88+
*/
89+
private function getConvertedData(array $groupedOptions): array
90+
{
91+
$requestData = [];
92+
foreach ($groupedOptions as $item) {
93+
/** @var GroupedOptionsInterface $item */
94+
if ($item->getQty() === null || $item->getId() === null) {
95+
throw new LocalizedException(__('Please specify id and qty for grouped options.'));
96+
}
97+
$requestData[self::SUPER_GROUP_CODE][$item->getId()] = $item->getQty();
98+
}
99+
100+
return $requestData;
101+
}
102+
103+
/**
104+
* Option processor
105+
*
106+
* @param CartItemInterface $cartItem
107+
* @return CartItemInterface
108+
*/
109+
public function processOptions(CartItemInterface $cartItem): CartItemInterface
110+
{
111+
if (empty($this->groupedOptions) || $cartItem->getProductType() !== Grouped::TYPE_CODE) {
112+
return $cartItem;
113+
}
114+
115+
$extension = $this->productOptionExtensionFactory->create()
116+
->setGroupedOptions($this->groupedOptions);
117+
if (!$cartItem->getProductOption()) {
118+
$cartItem->setProductOption($this->productOptionFactory->create());
119+
}
120+
$cartItem->getProductOption()->setExtensionAttributes($extension);
121+
122+
return $cartItem;
123+
}
124+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\GroupedProduct\Model\Quote\Item;
9+
10+
use Magento\GroupedProduct\Api\Data\GroupedOptionsInterface;
11+
use Magento\GroupedProduct\Api\Data\GroupedOptionsExtensionInterface;
12+
13+
/**
14+
* @inheritDoc
15+
*/
16+
class GroupedOptions implements GroupedOptionsInterface
17+
{
18+
/**
19+
* @var int|null
20+
*/
21+
private $qty;
22+
23+
/**
24+
* @var int|null
25+
*/
26+
private $id;
27+
28+
/**
29+
* @var GroupedOptionsExtensionInterface|null
30+
*/
31+
private $extensionAttributes;
32+
33+
/**
34+
* @param int|null $id
35+
* @param int|null $qty
36+
* @param GroupedOptionsExtensionInterface|null $extensionAttributes
37+
*/
38+
public function __construct(
39+
?int $id = null,
40+
?int $qty = null,
41+
?GroupedOptionsExtensionInterface $extensionAttributes = null
42+
) {
43+
$this->id = $id;
44+
$this->qty = $qty;
45+
$this->extensionAttributes = $extensionAttributes;
46+
}
47+
48+
/**
49+
* @inheritDoc
50+
*/
51+
public function getId(): ?int
52+
{
53+
return $this->id;
54+
}
55+
56+
/**
57+
* @inheritDoc
58+
*/
59+
public function getQty(): ?int
60+
{
61+
return $this->qty;
62+
}
63+
64+
/**
65+
* @inheritDoc
66+
*/
67+
public function setExtensionAttributes(GroupedOptionsExtensionInterface $extensionAttributes): void
68+
{
69+
$this->extensionAttributes = $extensionAttributes;
70+
}
71+
72+
/**
73+
* @inheritDoc
74+
*/
75+
public function getExtensionAttributes(): ?GroupedOptionsExtensionInterface
76+
{
77+
return $this->extensionAttributes;
78+
}
79+
}

app/code/Magento/GroupedProduct/etc/di.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
9+
<preference for="Magento\GroupedProduct\Api\Data\GroupedOptionsInterface" type="Magento\GroupedProduct\Model\Quote\Item\GroupedOptions" />
10+
911
<type name="Magento\Quote\Model\Quote\Item\RelatedProducts">
1012
<arguments>
1113
<argument name="relatedProductTypes" xsi:type="array">
@@ -105,6 +107,13 @@
105107
</argument>
106108
</arguments>
107109
</type>
110+
<type name="Magento\Quote\Model\Quote\Item\Repository">
111+
<arguments>
112+
<argument name="cartItemProcessors" xsi:type="array">
113+
<item name="grouped" xsi:type="object">Magento\GroupedProduct\Model\Quote\Item\CartItemProcessor\Proxy</item>
114+
</argument>
115+
</arguments>
116+
</type>
108117
<type name="Magento\CatalogInventory\Observer\SaveInventoryDataObserver">
109118
<arguments>
110119
<argument name="parentItemProcessorPool" xsi:type="array">

app/code/Magento/GroupedProduct/etc/extension_attributes.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,8 @@
99
<extension_attributes for="Magento\Catalog\Api\Data\ProductLinkInterface">
1010
<attribute code="qty" type="float" />
1111
</extension_attributes>
12+
13+
<extension_attributes for="Magento\Quote\Api\Data\ProductOptionInterface">
14+
<attribute code="grouped_options" type="Magento\GroupedProduct\Api\Data\GroupedOptionsInterface[]" />
15+
</extension_attributes>
1216
</config>

0 commit comments

Comments
 (0)