Skip to content

Commit d809522

Browse files
authored
LYNX-788 Enhance Gift Options handling during cart merge
1 parent 0350e3c commit d809522

File tree

2 files changed

+71
-108
lines changed

2 files changed

+71
-108
lines changed
Lines changed: 64 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,53 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2019 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

88
namespace Magento\QuoteGraphQl\Model\Resolver;
99

10-
use Magento\CatalogInventory\Api\StockRegistryInterface;
11-
use Magento\Framework\App\ObjectManager;
1210
use Magento\Framework\Exception\CouldNotSaveException;
13-
use Magento\Framework\Exception\NoSuchEntityException;
1411
use Magento\Framework\GraphQl\Config\Element\Field;
1512
use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException;
1613
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
1714
use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException;
1815
use Magento\Framework\GraphQl\Query\ResolverInterface;
1916
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
2017
use Magento\GraphQl\Model\Query\ContextInterface;
21-
use Magento\Quote\Api\CartItemRepositoryInterface;
2218
use Magento\Quote\Api\CartRepositoryInterface;
23-
use Magento\Quote\Api\Data\CartInterface;
24-
use Magento\Quote\Api\Data\CartItemInterface;
2519
use Magento\Quote\Model\Cart\CustomerCartResolver;
20+
use Magento\Quote\Model\Quote;
2621
use Magento\Quote\Model\QuoteIdToMaskedQuoteIdInterface;
2722
use Magento\QuoteGraphQl\Model\Cart\GetCartForUser;
2823
use Magento\QuoteGraphQl\Model\Cart\MergeCarts\CartQuantityValidatorInterface;
2924

30-
/**
31-
* Merge Carts Resolver
32-
*
33-
* @SuppressWarnings(PHPMD.LongVariable)
34-
*/
3525
class MergeCarts implements ResolverInterface
3626
{
3727
/**
38-
* @var GetCartForUser
39-
*/
40-
private $getCartForUser;
41-
42-
/**
43-
* @var CartRepositoryInterface
44-
*/
45-
private $cartRepository;
46-
47-
/**
48-
* @var CustomerCartResolver
49-
*/
50-
private $customerCartResolver;
51-
52-
/**
53-
* @var QuoteIdToMaskedQuoteIdInterface
54-
*/
55-
private $quoteIdToMaskedQuoteId;
56-
57-
/**
58-
* @var CartItemRepositoryInterface
59-
*/
60-
private $cartItemRepository;
61-
62-
/**
63-
* @var StockRegistryInterface
64-
*/
65-
private $stockRegistry;
66-
67-
/**
68-
* @var CartQuantityValidatorInterface
28+
* @var array
6929
*/
70-
private $cartQuantityValidator;
30+
private array $fields;
7131

7232
/**
33+
* MergeCarts Constructor
34+
*
7335
* @param GetCartForUser $getCartForUser
7436
* @param CartRepositoryInterface $cartRepository
75-
* @param CustomerCartResolver|null $customerCartResolver
76-
* @param QuoteIdToMaskedQuoteIdInterface|null $quoteIdToMaskedQuoteId
77-
* @param CartItemRepositoryInterface|null $cartItemRepository
78-
* @param StockRegistryInterface|null $stockRegistry
37+
* @param CustomerCartResolver $customerCartResolver
38+
* @param QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedQuoteId
39+
* @param CartQuantityValidatorInterface $cartQuantityValidator
40+
* @param array $fields
7941
*/
8042
public function __construct(
81-
GetCartForUser $getCartForUser,
82-
CartRepositoryInterface $cartRepository,
83-
?CustomerCartResolver $customerCartResolver = null,
84-
?QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedQuoteId = null,
85-
?CartItemRepositoryInterface $cartItemRepository = null,
86-
?StockRegistryInterface $stockRegistry = null,
87-
?CartQuantityValidatorInterface $cartQuantityValidator = null
43+
private readonly GetCartForUser $getCartForUser,
44+
private readonly CartRepositoryInterface $cartRepository,
45+
private readonly CustomerCartResolver $customerCartResolver,
46+
private readonly QuoteIdToMaskedQuoteIdInterface $quoteIdToMaskedQuoteId,
47+
private readonly CartQuantityValidatorInterface $cartQuantityValidator,
48+
array $fields
8849
) {
89-
$this->getCartForUser = $getCartForUser;
90-
$this->cartRepository = $cartRepository;
91-
$this->customerCartResolver = $customerCartResolver
92-
?: ObjectManager::getInstance()->get(CustomerCartResolver::class);
93-
$this->quoteIdToMaskedQuoteId = $quoteIdToMaskedQuoteId
94-
?: ObjectManager::getInstance()->get(QuoteIdToMaskedQuoteIdInterface::class);
95-
$this->cartItemRepository = $cartItemRepository
96-
?: ObjectManager::getInstance()->get(CartItemRepositoryInterface::class);
97-
$this->stockRegistry = $stockRegistry
98-
?: ObjectManager::getInstance()->get(StockRegistryInterface::class);
99-
$this->cartQuantityValidator = $cartQuantityValidator
100-
?: ObjectManager::getInstance()->get(CartQuantityValidatorInterface::class);
50+
$this->fields = $fields;
10151
}
10252

10353
/**
@@ -109,69 +59,75 @@ public function resolve(
10959
ResolveInfo $info,
11060
?array $value = null,
11161
?array $args = null
112-
) {
62+
): array {
11363
if (empty($args['source_cart_id'])) {
114-
throw new GraphQlInputException(__(
115-
'Required parameter "source_cart_id" is missing'
116-
));
64+
throw new GraphQlInputException(__('Required parameter "source_cart_id" is missing'));
65+
}
66+
67+
if (isset($args['destination_cart_id']) && empty($args['destination_cart_id'])) {
68+
throw new GraphQlInputException(__('The parameter "destination_cart_id" cannot be empty'));
11769
}
11870

11971
/** @var ContextInterface $context */
120-
if (false === $context->getExtensionAttributes()->getIsCustomer()) {
121-
throw new GraphQlAuthorizationException(__(
122-
'The current customer isn\'t authorized.'
123-
));
72+
if (!$context->getExtensionAttributes()->getIsCustomer()) {
73+
throw new GraphQlAuthorizationException(__('The current customer isn\'t authorized.'));
12474
}
75+
12576
$currentUserId = $context->getUserId();
77+
$storeId = (int)$context->getExtensionAttributes()->getStore()->getId();
78+
$guestMaskedCartId = $args['source_cart_id'];
79+
80+
// Resolve destination cart ID
81+
$customerMaskedCartId = $args['destination_cart_id'] ?? null;
12682

127-
if (!isset($args['destination_cart_id'])) {
83+
if (!$customerMaskedCartId) {
12884
try {
12985
$cart = $this->customerCartResolver->resolve($currentUserId);
86+
$customerMaskedCartId = $this->quoteIdToMaskedQuoteId->execute((int) $cart->getId());
13087
} catch (CouldNotSaveException $exception) {
13188
throw new GraphQlNoSuchEntityException(
13289
__('Could not create empty cart for customer'),
13390
$exception
13491
);
13592
}
136-
$customerMaskedCartId = $this->quoteIdToMaskedQuoteId->execute(
137-
(int) $cart->getId()
138-
);
139-
} else {
140-
if (empty($args['destination_cart_id'])) {
141-
throw new GraphQlInputException(__(
142-
'The parameter "destination_cart_id" cannot be empty'
143-
));
144-
}
14593
}
14694

147-
$guestMaskedCartId = $args['source_cart_id'];
148-
$customerMaskedCartId = $customerMaskedCartId ?? $args['destination_cart_id'];
95+
// Fetch guest and customer carts
96+
$customerCart = $this->getCartForUser->execute($customerMaskedCartId, $currentUserId, $storeId);
97+
$guestCart = $this->getCartForUser->execute($guestMaskedCartId, null, $storeId);
14998

150-
$storeId = (int)$context->getExtensionAttributes()->getStore()->getId();
151-
// passing customerId as null enforces source cart should always be a guestcart
152-
$guestCart = $this->getCartForUser->execute(
153-
$guestMaskedCartId,
154-
null,
155-
$storeId
156-
);
157-
$customerCart = $this->getCartForUser->execute(
158-
$customerMaskedCartId,
159-
$currentUserId,
160-
$storeId
161-
);
99+
// Validate cart quantities before merging
162100
if ($this->cartQuantityValidator->validateFinalCartQuantities($customerCart, $guestCart)) {
163-
$guestCart = $this->getCartForUser->execute(
164-
$guestMaskedCartId,
165-
null,
166-
$storeId
167-
);
101+
$guestCart = $this->getCartForUser->execute($guestMaskedCartId, null, $storeId);
168102
}
103+
104+
// Merge carts and save
169105
$customerCart->merge($guestCart);
170106
$guestCart->setIsActive(false);
107+
// Check and update gift options from guest cart to customer cart
108+
$customerCart = $this->updateGiftOptions($guestCart, $customerCart);
109+
171110
$this->cartRepository->save($customerCart);
172111
$this->cartRepository->save($guestCart);
173-
return [
174-
'model' => $customerCart,
175-
];
112+
113+
return ['model' => $customerCart];
114+
}
115+
116+
/**
117+
* Check and update gift options in customer cart from guest cart
118+
*
119+
* @param Quote $guestCart
120+
* @param Quote $customerCart
121+
* @return Quote
122+
*/
123+
private function updateGiftOptions(Quote $guestCart, Quote $customerCart): Quote
124+
{
125+
foreach ($this->fields as $field) {
126+
if (!empty($guestCart->getData($field)) && empty($customerCart->getData($field))) {
127+
$customerCart->setData($field, $guestCart->getData($field));
128+
}
129+
}
130+
131+
return $customerCart;
176132
}
177133
}

app/code/Magento/QuoteGraphQl/etc/graphql/di.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,11 @@
9999
<type name="Magento\Payment\Model\MethodList">
100100
<plugin name="restrict_payment_methods_graphql" type="Magento\QuoteGraphQl\Plugin\Model\RestrictPaymentMethods"/>
101101
</type>
102+
<type name="Magento\QuoteGraphQl\Model\Resolver\MergeCarts">
103+
<arguments>
104+
<argument name="fields" xsi:type="array">
105+
<item name="gift_message_id" xsi:type="string">gift_message_id</item>
106+
</argument>
107+
</arguments>
108+
</type>
102109
</config>

0 commit comments

Comments
 (0)