Skip to content

Commit 4e91067

Browse files
committed
PWA-1299: [Graphql] Unable to update the items of a bundle-product in a wishlist
* Code review changes
1 parent 73751a5 commit 4e91067

File tree

3 files changed

+130
-108
lines changed

3 files changed

+130
-108
lines changed

app/code/Magento/WishlistGraphQl/Model/Resolver/UpdateProductsInWishlist.php

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@
99

1010
use Magento\Framework\GraphQl\Config\Element\Field;
1111
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
12-
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
12+
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
1313
use Magento\Framework\GraphQl\Query\ResolverInterface;
1414
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
1515
use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel;
1616
use Magento\Wishlist\Model\Wishlist;
1717
use Magento\Wishlist\Model\Wishlist\Config as WishlistConfig;
18-
use Magento\Wishlist\Model\Wishlist\Data\Error;
1918
use Magento\Wishlist\Model\Wishlist\Data\WishlistItemFactory;
2019
use Magento\Wishlist\Model\WishlistFactory;
2120
use Magento\WishlistGraphQl\Mapper\WishlistDataMapper;
@@ -83,44 +82,39 @@ public function resolve(
8382
array $args = null
8483
) {
8584
if (!$this->wishlistConfig->isEnabled()) {
86-
throw new GraphQlInputException(__('The wishlist configuration is currently disabled.'));
85+
throw new GraphQlAuthorizationException(__('The wishlist configuration is currently disabled'));
8786
}
8887

8988
$customerId = $context->getUserId();
9089

91-
/* Guest checking */
9290
if (null === $customerId || $customerId === 0) {
9391
throw new GraphQlAuthorizationException(__('The current user cannot perform operations on wishlist'));
9492
}
9593

96-
$wishlistId = ((int) $args['wishlistId']) ?: null;
97-
$wishlist = $this->getWishlist($wishlistId, $customerId);
94+
$wishlist = $this->getWishlist((int) $args['wishlistId'], $customerId);
95+
9896
if (null === $wishlist->getId() || $customerId !== (int) $wishlist->getCustomerId()) {
99-
throw new GraphQlInputException(__('The wishlist was not found.'));
97+
throw new GraphQlNoSuchEntityException(__('Could not find the specified wishlist'));
10098
}
10199

102-
$wishlistItems = $args['wishlistItems'];
103-
$wishlistItems = $this->getWishlistItems($wishlistItems, $wishlist);
104-
$wishlistOutput = "";
100+
$wishlistItems = $this->getWishlistItems($args['wishlistItems'], $wishlist);
101+
$userErrors = [];
105102

106103
foreach ($wishlistItems as $wishlistItem) {
107104
$wishlistOutput = $this->updateWishlistItem->execute($wishlistItem, $wishlist);
108-
}
105+
$wishlist = $wishlistOutput->getWishlist();
109106

110-
if (count($wishlistOutput->getErrors()) !== count($wishlistItems)) {
111-
$this->wishlistResource->save($wishlist);
107+
foreach ($wishlistOutput->getErrors() as $error) {
108+
$userErrors[] = [
109+
'code' => $error->getCode(),
110+
'message' => $error->getMessage()
111+
];
112+
}
112113
}
113114

114115
return [
115-
'wishlist' => $this->wishlistDataMapper->map($wishlistOutput->getWishlist()),'user_errors' => \array_map(
116-
function (Error $error) {
117-
return [
118-
'code' => $error->getCode(),
119-
'message' => $error->getMessage(),
120-
];
121-
},
122-
$wishlistOutput->getErrors()
123-
)
116+
'wishlist' => $this->wishlistDataMapper->map($wishlist),
117+
'user_errors' => $userErrors
124118
];
125119
}
126120

app/code/Magento/WishlistGraphQl/Model/UpdateWishlistItem.php

Lines changed: 85 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,37 @@
77

88
namespace Magento\WishlistGraphQl\Model;
99

10-
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
10+
use Magento\Framework\Exception\AlreadyExistsException;
11+
use Magento\Framework\Exception\LocalizedException;
12+
use Magento\Wishlist\Model\Item;
1113
use Magento\Wishlist\Model\ResourceModel\Wishlist as WishlistResourceModel;
1214
use Magento\Wishlist\Model\Wishlist;
13-
use Magento\Wishlist\Model\Wishlist\Data\WishlistOutput;
1415
use Magento\Wishlist\Model\Wishlist\BuyRequest\BuyRequestBuilder;
15-
use Magento\Wishlist\Model\Wishlist\Data\Error;
16+
use Magento\Wishlist\Model\Wishlist\Data\Error as WishlistError;
17+
use Magento\Wishlist\Model\Wishlist\Data\WishlistItem as WishlistItemData;
18+
use Magento\Wishlist\Model\Wishlist\Data\WishlistOutput;
1619

1720
/**
1821
* Update wishlist items helper
1922
*/
2023
class UpdateWishlistItem
2124
{
25+
private const ERROR_UNDEFINED = 'UNDEFINED';
26+
2227
/**
2328
* @var WishlistResourceModel
2429
*/
2530
private $wishlistResource;
2631

2732
/**
28-
* @var array
33+
* @var BuyRequestBuilder
2934
*/
30-
private $errors = [];
35+
private $buyRequestBuilder;
3136

3237
/**
33-
* BuyRequestBuilder
34-
* @var BuyRequestBuilder $buyRequestBuilder
38+
* @var array
3539
*/
36-
private $buyRequestBuilder;
37-
38-
private const ERROR_UNDEFINED = 'UNDEFINED';
40+
private $errors = [];
3941

4042
/**
4143
* @param WishlistResourceModel $wishlistResource
@@ -50,70 +52,92 @@ public function __construct(
5052
}
5153

5254
/**
53-
* Update wishlist Item and set data from request
55+
* Update wishlist item and set data from request
5456
*
55-
* @param object $options
57+
* @param WishlistItemData $wishlistItemData
5658
* @param Wishlist $wishlist
5759
*
5860
* @return WishlistOutput
59-
* @throws GraphQlInputException
60-
* @throws \Magento\Framework\Exception\LocalizedException
61+
* @throws LocalizedException
62+
* @throws AlreadyExistsException
6163
*/
62-
public function execute(object $options, Wishlist $wishlist)
64+
public function execute(WishlistItemData $wishlistItemData, Wishlist $wishlist)
6365
{
64-
$itemId = $options->getId();
65-
if ($wishlist->getItem($itemId) == null) {
66+
$wishlistItemId = (int) $wishlistItemData->getId();
67+
$wishlistItemToUpdate = $wishlist->getItem($wishlistItemId);
68+
69+
if (!$wishlistItemToUpdate) {
6670
$this->addError(
67-
__(
68-
'The wishlist item with ID "%id" does not belong to the wishlist',
69-
['id' => $itemId]
70-
)->render()
71+
__('Could not find the wishlist item with ID "%1"', $wishlistItemId)->render()
7172
);
7273
} else {
73-
$buyRequest = $this->buyRequestBuilder->build($options);
74-
$item = $wishlist->getItem((int)$itemId);
75-
$product = $item->getProduct();
76-
$productId = $product->getId();
77-
78-
if ($productId) {
79-
$buyRequest->setData('action', 'updateItem');
80-
$product->setWishlistStoreId($item->getStoreId());
81-
$cartCandidates = $product->getTypeInstance()->processConfiguration($buyRequest, clone $product);
82-
83-
/**
84-
* If the product with options existed or not
85-
*/
86-
if (is_string($cartCandidates)) {
87-
throw new GraphQlInputException(__('The product with options does not exist.'));
88-
}
89-
90-
/**
91-
* If prepare process return one object
92-
*/
93-
if (!is_array($cartCandidates)) {
94-
$cartCandidates = [$cartCandidates];
95-
}
96-
97-
foreach ($cartCandidates as $candidate) {
98-
if ($candidate->getParentProductId()) {
99-
continue;
100-
}
101-
$candidate->setWishlistStoreId($item->getStoreId());
102-
$qty = $buyRequest->getData('qty') ? $buyRequest->getData('qty') : 1;
103-
$item->setOptions($candidate->getCustomOptions());
104-
$item->setQty($qty);
105-
if($options->getDescription()) {
106-
$item->setDescription($options->getDescription());
107-
}
108-
}
109-
$this->wishlistResource->save($wishlist);
110-
} else {
111-
throw new GraphQlInputException(__('The product does not exist.'));
74+
$updatedOptions = $this->getUpdatedOptions($wishlistItemData, $wishlistItemToUpdate);
75+
76+
$wishlistItemToUpdate->setOptions($updatedOptions);
77+
$wishlistItemToUpdate->setQty($wishlistItemData->getQuantity());
78+
if ($wishlistItemData->getDescription()) {
79+
$wishlistItemToUpdate->setDescription($wishlistItemData->getDescription());
11280
}
81+
82+
$this->wishlistResource->save($wishlist);
11383
}
84+
11485
return $this->prepareOutput($wishlist);
11586
}
11687

88+
/**
89+
* Build the updated options for the specified wishlist item.
90+
*
91+
* @param WishlistItemData $wishlistItemData
92+
* @param Item $wishlistItemToUpdate
93+
* @return array
94+
* @throws LocalizedException
95+
*/
96+
private function getUpdatedOptions(WishlistItemData $wishlistItemData, Item $wishlistItemToUpdate)
97+
{
98+
$wishlistItemId = $wishlistItemToUpdate->getId();
99+
$wishlistItemProduct = $wishlistItemToUpdate->getProduct();
100+
101+
if (!$wishlistItemProduct->getId()) {
102+
throw new LocalizedException(
103+
__('Could not find product for the wishlist item with ID "%1"', $wishlistItemId)
104+
);
105+
}
106+
107+
// Create a buy request with the updated wishlist item data
108+
$updatedBuyRequest = $this->buyRequestBuilder
109+
->build($wishlistItemData)
110+
->setData('action', 'updateItem');
111+
112+
// Get potential products to add to the cart for the product type using the updated buy request
113+
$wishlistItemProduct->setWishlistStoreId($wishlistItemToUpdate->getStoreId());
114+
$cartCandidates = $wishlistItemProduct->getTypeInstance()->processConfiguration(
115+
$updatedBuyRequest,
116+
clone $wishlistItemProduct
117+
);
118+
119+
if (is_string($cartCandidates)) {
120+
throw new LocalizedException(
121+
__('Could not prepare product for the wishlist item with ID %1', $wishlistItemId)
122+
);
123+
}
124+
125+
// Of the cart candidates, find the parent product and get its options
126+
if (!is_array($cartCandidates)) {
127+
$cartCandidates = [$cartCandidates];
128+
}
129+
$updatedOptions = [];
130+
foreach ($cartCandidates as $candidate) {
131+
if ($candidate->getParentProductId() === null) {
132+
$candidate->setWishlistStoreId($wishlistItemToUpdate->getStoreId());
133+
$updatedOptions = $candidate->getCustomOptions();
134+
break;
135+
}
136+
}
137+
138+
return $updatedOptions;
139+
}
140+
117141
/**
118142
* Add wishlist line item error
119143
*
@@ -124,7 +148,7 @@ public function execute(object $options, Wishlist $wishlist)
124148
*/
125149
private function addError(string $message, string $code = null): void
126150
{
127-
$this->errors[] = new Error(
151+
$this->errors[] = new WishlistError(
128152
$message,
129153
$code ?? self::ERROR_UNDEFINED
130154
);

dev/tests/api-functional/testsuite/Magento/GraphQl/Wishlist/UpdateBundleProductsFromWishlistTest.php

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public function testUpdateBundleProductWithOptions(): void
7777
// Add product to wishlist
7878
$wishlist = $this->addProductToWishlist();
7979
$wishlistId = $wishlist['addProductsToWishlist']['wishlist']['id'];
80-
$wishlistItemId = $wishlist['addProductsToWishlist']['wishlist']['items_v2'][0]['id'];
80+
$wishlistItemId = $wishlist['addProductsToWishlist']['wishlist']['items_v2']['items'][0]['id'];
8181
$itemsCount = $wishlist['addProductsToWishlist']['wishlist']['items_count'];
8282

8383
$query = $this->getBundleQuery((int)$wishlistItemId, $qty, $bundleOptions, (int)$wishlistId);
@@ -87,9 +87,9 @@ public function testUpdateBundleProductWithOptions(): void
8787
$this->assertArrayHasKey('wishlist', $response['updateProductsInWishlist']);
8888
$response = $response['updateProductsInWishlist']['wishlist'];
8989
$this->assertEquals($itemsCount, $response['items_count']);
90-
$this->assertEquals($qty, $response['items_v2'][0]['quantity']);
91-
$this->assertNotEmpty($response['items_v2'][0]['bundle_options']);
92-
$bundleOptions = $response['items_v2'][0]['bundle_options'];
90+
$this->assertEquals($qty, $response['items_v2']['items'][0]['quantity']);
91+
$this->assertNotEmpty($response['items_v2']['items'][0]['bundle_options']);
92+
$bundleOptions = $response['items_v2']['items'][0]['bundle_options'];
9393
$this->assertEquals('Bundle Product Items', $bundleOptions[0]['label']);
9494
$this->assertEquals(Select::NAME, $bundleOptions[0]['type']);
9595
}
@@ -151,18 +151,20 @@ private function getBundleQuery(
151151
items_count
152152
updated_at
153153
items_v2 {
154-
id
155-
quantity
156-
... on BundleWishlistItem {
157-
bundle_options {
158-
id
159-
label
160-
type
161-
values {
154+
items{
155+
id
156+
quantity
157+
... on BundleWishlistItem {
158+
bundle_options {
162159
id
163160
label
164-
quantity
165-
price
161+
type
162+
values {
163+
id
164+
label
165+
quantity
166+
price
167+
}
166168
}
167169
}
168170
}
@@ -255,19 +257,21 @@ private function addQuery(
255257
items_count
256258
updated_at
257259
items_v2 {
258-
id
259-
quantity
260-
added_at
261-
... on BundleWishlistItem {
262-
bundle_options {
263-
id
264-
label
265-
type
266-
values {
260+
items{
261+
id
262+
quantity
263+
added_at
264+
... on BundleWishlistItem {
265+
bundle_options {
267266
id
268267
label
269-
quantity
270-
price
268+
type
269+
values {
270+
id
271+
label
272+
quantity
273+
price
274+
}
271275
}
272276
}
273277
}

0 commit comments

Comments
 (0)