1
1
<?php
2
2
/**
3
- * Copyright 2019 Adobe
4
- * All Rights Reserved .
3
+ * Copyright © Magento, Inc. All rights reserved.
4
+ * See COPYING.txt for license details .
5
5
*/
6
6
declare (strict_types=1 );
7
7
8
8
namespace Magento \QuoteGraphQl \Model \Cart \MergeCarts ;
9
9
10
- use Magento \Catalog \Api \Data \ProductInterface ;
11
- use Magento \Catalog \Api \ProductRepositoryInterface ;
10
+
12
11
use Magento \CatalogInventory \Api \StockRegistryInterface ;
13
- use Magento \Checkout \Model \Config ;
14
12
use Magento \Framework \Exception \CouldNotSaveException ;
15
13
use Magento \Framework \Exception \NoSuchEntityException ;
16
14
use Magento \Quote \Api \CartItemRepositoryInterface ;
17
15
use Magento \Quote \Api \Data \CartInterface ;
18
16
use Magento \Quote \Api \Data \CartItemInterface ;
19
- use Magento \Quote \Model \Quote \Item ;
20
- use Psr \Log \LoggerInterface ;
21
17
22
18
class CartQuantityValidator implements CartQuantityValidatorInterface
23
19
{
24
20
/**
25
- * @var array
21
+ * @var CartItemRepositoryInterface
26
22
*/
27
- private array $ cumulativeQty = [];
23
+ private $ cartItemRepository ;
24
+
25
+ /**
26
+ * @var StockRegistryInterface
27
+ */
28
+ private $ stockRegistry ;
28
29
29
30
/**
30
- * CartQuantityValidator Constructor
31
- *
32
31
* @param CartItemRepositoryInterface $cartItemRepository
33
32
* @param StockRegistryInterface $stockRegistry
34
- * @param Config $config
35
- * @param ProductRepositoryInterface $productRepository
36
- * @param LoggerInterface $logger
37
33
*/
38
34
public function __construct (
39
- private readonly CartItemRepositoryInterface $ cartItemRepository ,
40
- private readonly StockRegistryInterface $ stockRegistry ,
41
- private readonly Config $ config ,
42
- private readonly ProductRepositoryInterface $ productRepository ,
43
- private readonly LoggerInterface $ logger
35
+ CartItemRepositoryInterface $ cartItemRepository ,
36
+ StockRegistryInterface $ stockRegistry
44
37
) {
38
+ $ this ->cartItemRepository = $ cartItemRepository ;
39
+ $ this ->stockRegistry = $ stockRegistry ;
45
40
}
46
41
47
42
/**
@@ -50,171 +45,32 @@ public function __construct(
50
45
* @param CartInterface $customerCart
51
46
* @param CartInterface $guestCart
52
47
* @return bool
53
- * @throws NoSuchEntityException
54
48
*/
55
49
public function validateFinalCartQuantities (CartInterface $ customerCart , CartInterface $ guestCart ): bool
56
50
{
57
51
$ modified = false ;
58
- $ this ->cumulativeQty = [];
59
-
52
+ /** @var CartItemInterface $guestCartItem */
60
53
foreach ($ guestCart ->getAllVisibleItems () as $ guestCartItem ) {
61
- foreach ($ customerCart ->getAllVisibleItems () as $ customerCartItem ) {
62
- if (!$ customerCartItem ->compare ($ guestCartItem )) {
63
- continue ;
64
- }
65
-
66
- if ($ this ->config ->getCartMergePreference () === Config::CART_PREFERENCE_CUSTOMER ) {
67
- $ this ->safeDeleteCartItem ((int ) $ guestCart ->getId (), (int ) $ guestCartItem ->getItemId ());
68
- $ modified = true ;
69
- continue ;
70
- }
71
-
72
- $ sku = $ this ->getSkuFromItem ($ customerCartItem );
73
- $ product = $ this ->getProduct ((int ) $ customerCartItem ->getProduct ()->getId ());
74
- $ isAvailable = $ customerCartItem ->getChildren ()
75
- ? $ this ->isCompositeProductQtyValid ($ guestCartItem , $ customerCartItem )
76
- : $ this ->isProductQtyValid ($ product , $ sku , $ guestCartItem ->getQty (), $ customerCartItem ->getQty ());
77
-
78
- if ($ this ->config ->getCartMergePreference () === Config::CART_PREFERENCE_GUEST ) {
79
- $ this ->safeDeleteCartItem ((int ) $ customerCart ->getId (), (int ) $ customerCartItem ->getItemId ());
80
- $ modified = true ;
81
- }
82
-
83
- if (!$ isAvailable ) {
84
- $ this ->safeDeleteCartItem ((int ) $ guestCart ->getId (), (int ) $ guestCartItem ->getItemId ());
85
- $ modified = true ;
54
+ foreach ($ customerCart ->getAllItems () as $ customerCartItem ) {
55
+ if ($ customerCartItem ->compare ($ guestCartItem )) {
56
+ $ product = $ customerCartItem ->getProduct ();
57
+ $ stockCurrentQty = $ this ->stockRegistry ->getStockStatus (
58
+ $ product ->getId (),
59
+ $ product ->getStore ()->getWebsiteId ()
60
+ )->getQty ();
61
+ if ($ stockCurrentQty < $ guestCartItem ->getQty () + $ customerCartItem ->getQty ()) {
62
+ try {
63
+ $ this ->cartItemRepository ->deleteById ($ guestCart ->getId (), $ guestCartItem ->getItemId ());
64
+ $ modified = true ;
65
+ } catch (NoSuchEntityException $ e ) {
66
+ continue ;
67
+ } catch (CouldNotSaveException $ e ) {
68
+ continue ;
69
+ }
70
+ }
86
71
}
87
72
}
88
73
}
89
-
90
74
return $ modified ;
91
75
}
92
-
93
- /**
94
- * Get SKU from Cart Item
95
- *
96
- * @param CartItemInterface $item
97
- * @return string
98
- * @throws NoSuchEntityException
99
- */
100
- private function getSkuFromItem (CartItemInterface $ item ): string
101
- {
102
- return $ item ->getProduct ()->getOptions ()
103
- ? $ this ->getProduct ((int ) $ item ->getProduct ()->getId ())->getSku ()
104
- : $ item ->getProduct ()->getSku ();
105
- }
106
-
107
- /**
108
- * Get current cart item quantity based on merge preference
109
- *
110
- * @param float $guestQty
111
- * @param float $customerQty
112
- * @return float
113
- */
114
- private function getCurrentCartItemQty (float $ guestQty , float $ customerQty ): float
115
- {
116
- return match ($ this ->config ->getCartMergePreference ()) {
117
- Config::CART_PREFERENCE_CUSTOMER => $ customerQty ,
118
- Config::CART_PREFERENCE_GUEST => $ guestQty ,
119
- default => $ guestQty + $ customerQty
120
- };
121
- }
122
-
123
- /**
124
- * Validate product stock availability
125
- *
126
- * @param ProductInterface $product
127
- * @param string $sku
128
- * @param float $guestQty
129
- * @param float $customerQty
130
- * @return bool
131
- */
132
- private function isProductQtyValid (
133
- ProductInterface $ product ,
134
- string $ sku ,
135
- float $ guestQty ,
136
- float $ customerQty
137
- ): bool {
138
- $ salableQty = $ this ->stockRegistry ->getStockStatus (
139
- $ product ->getId (),
140
- $ product ->getStore ()->getWebsiteId ()
141
- )->getQty ();
142
-
143
- $ this ->cumulativeQty [$ sku ] ??= 0 ;
144
- $ this ->cumulativeQty [$ sku ] += $ this ->getCurrentCartItemQty ($ guestQty , $ customerQty );
145
-
146
- return $ salableQty >= $ this ->cumulativeQty [$ sku ];
147
- }
148
-
149
- /**
150
- * Validate composite product quantities
151
- *
152
- * @param Item $guestCartItem
153
- * @param Item $customerCartItem
154
- * @return bool
155
- * @throws NoSuchEntityException
156
- */
157
- private function isCompositeProductQtyValid (
158
- Item $ guestCartItem ,
159
- Item $ customerCartItem
160
- ): bool {
161
- $ guestChildItems = $ this ->retrieveChildItems ($ guestCartItem );
162
- foreach ($ customerCartItem ->getChildren () as $ customerChildItem ) {
163
- $ childProduct = $ customerChildItem ->getProduct ()->getOptions ()
164
- ? $ this ->getProduct ((int ) $ customerChildItem ->getProduct ()->getId ())
165
- : $ customerChildItem ->getProduct ();
166
- $ sku = $ childProduct ->getSku ();
167
- $ customerItemQty = $ customerCartItem ->getQty () * $ customerChildItem ->getQty ();
168
- $ guestItemQty = $ guestCartItem ->getQty () * $ guestChildItems [$ sku ]->getQty ();
169
-
170
- if (!$ this ->isProductQtyValid ($ childProduct , $ sku , $ guestItemQty , $ customerItemQty )) {
171
- return false ;
172
- }
173
- }
174
-
175
- return true ;
176
- }
177
-
178
- /**
179
- * Get product by ID
180
- *
181
- * @param int $productId
182
- * @return ProductInterface
183
- * @throws NoSuchEntityException
184
- */
185
- private function getProduct (int $ productId ): ProductInterface
186
- {
187
- return $ this ->productRepository ->getById ($ productId );
188
- }
189
-
190
- /**
191
- * Retrieve child items from a quote item
192
- *
193
- * @param Item $quoteItem
194
- * @return Item[]
195
- */
196
- private function retrieveChildItems (Item $ quoteItem ): array
197
- {
198
- $ childItems = [];
199
- foreach ($ quoteItem ->getChildren () as $ childItem ) {
200
- $ childItems [$ childItem ->getProduct ()->getSku ()] = $ childItem ;
201
- }
202
- return $ childItems ;
203
- }
204
-
205
- /**
206
- * Safely delete a cart item by ID
207
- *
208
- * @param int $cartId
209
- * @param int $itemId
210
- * @return void
211
- */
212
- private function safeDeleteCartItem (int $ cartId , int $ itemId ): void
213
- {
214
- try {
215
- $ this ->cartItemRepository ->deleteById ($ cartId , $ itemId );
216
- } catch (NoSuchEntityException |CouldNotSaveException $ e ) {
217
- $ this ->logger ->error ($ e );
218
- }
219
- }
220
76
}
0 commit comments