7
7
8
8
use Magento \Framework \App \ObjectManager ;
9
9
use Magento \Framework \Event \ManagerInterface ;
10
+ use Magento \Framework \Exception \NoSuchEntityException ;
10
11
use Magento \Framework \Pricing \PriceCurrencyInterface ;
11
12
use Magento \Quote \Api \Data \AddressInterface ;
12
13
use Magento \Quote \Api \Data \ShippingAssignmentInterface ;
@@ -128,71 +129,34 @@ public function _resetState(): void
128
129
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
129
130
* @SuppressWarnings(PHPMD.NPathComplexity)
130
131
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
132
+ * @throws \Zend_Db_Select_Exception|NoSuchEntityException
131
133
*/
132
134
public function collect (
133
135
Quote $ quote ,
134
136
ShippingAssignmentInterface $ shippingAssignment ,
135
137
Total $ total
136
138
) {
137
139
parent ::collect ($ quote , $ shippingAssignment , $ total );
138
- $ store = $ this ->storeManager ->getStore ($ quote ->getStoreId ());
139
- /** @var Address $address */
140
- $ address = $ shippingAssignment ->getShipping ()->getAddress ();
141
- if ($ quote ->currentPaymentWasSet ()) {
142
- $ address ->setPaymentMethod ($ quote ->getPayment ()->getMethod ());
143
- }
144
- $ this ->calculator ->reset ($ address );
145
- $ itemsAggregate = [];
146
- foreach ($ shippingAssignment ->getItems () as $ item ) {
147
- $ itemId = $ item ->getId ();
148
- $ itemsAggregate [$ itemId ] = $ item ;
149
- }
150
- $ items = [];
151
- foreach ($ quote ->getAllAddresses () as $ quoteAddress ) {
152
- foreach ($ quoteAddress ->getAllItems () as $ item ) {
153
- $ items [] = $ item ;
154
- }
155
- }
140
+ $ this ->addressDiscountAggregator = [];
141
+
142
+ $ address = $ this ->getAddress ($ shippingAssignment , $ quote );
143
+ $ itemsAggregate = $ this ->getShippingItems ($ shippingAssignment );
144
+ $ items = $ this ->extractQuoteItems ($ quote , $ address );
145
+
156
146
if (!$ items || !$ itemsAggregate ) {
157
147
return $ this ;
158
148
}
159
- $ eventArgs = [
160
- 'website_id ' => $ store ->getWebsiteId (),
161
- 'customer_group_id ' => $ quote ->getCustomerGroupId (),
162
- 'coupon_code ' => $ quote ->getCouponCode (),
163
- ];
164
- $ address ->setDiscountDescription ([]);
165
- $ address ->getExtensionAttributes ()->setDiscounts ([]);
166
- $ this ->addressDiscountAggregator = [];
167
- $ address ->setCartFixedRules ([]);
149
+ $ store = $ this ->storeManager ->getStore ($ quote ->getStoreId ());
150
+
168
151
$ quote ->setCartFixedRules ([]);
169
- foreach ($ items as $ item ) {
170
- $ item ->setAppliedRuleIds (null );
171
- if ($ item ->getExtensionAttributes ()) {
172
- $ item ->getExtensionAttributes ()->setDiscounts (null );
173
- }
174
- $ item ->setDiscountAmount (0 );
175
- $ item ->setBaseDiscountAmount (0 );
176
- $ item ->setDiscountPercent (0 );
177
- if ($ item ->getChildren () && $ item ->isChildrenCalculated ()) {
178
- foreach ($ item ->getChildren () as $ child ) {
179
- $ child ->setDiscountAmount (0 );
180
- $ child ->setBaseDiscountAmount (0 );
181
- $ child ->setDiscountPercent (0 );
182
- }
183
- }
184
- $ item ->getAddress ()->setBaseDiscountAmount (0 );
185
- }
186
152
$ this ->calculator ->initFromQuote ($ quote );
187
153
$ this ->calculator ->initTotals ($ items , $ address );
188
- $ items = $ this -> calculator -> sortItemsByPriority ( $ items , $ address );
154
+
189
155
$ itemsToApplyRules = $ items ;
190
- $ rules = $ this ->calculator ->getRules ($ address );
191
- $ totalDiscount = [];
192
- $ address ->setBaseDiscountAmount (0 );
156
+
193
157
/** @var Rule $rule */
194
- foreach ($ rules as $ rule ) {
195
- /** @var Item $item */
158
+ foreach ($ this -> calculator -> getRules ( $ address ) as $ rule ) {
159
+ $ totalDiscount = 0 ;
196
160
foreach ($ itemsToApplyRules as $ key => $ item ) {
197
161
if ($ item ->getNoDiscount () || !$ this ->calculator ->canApplyDiscount ($ item ) || $ item ->getParentItem ()) {
198
162
continue ;
@@ -212,18 +176,25 @@ public function collect(
212
176
break ;
213
177
}
214
178
215
- $ eventArgs ['item ' ] = $ item ;
216
- $ this ->eventManager ->dispatch ('sales_quote_address_discount_item ' , $ eventArgs );
179
+ $ this ->eventManager ->dispatch (
180
+ 'sales_quote_address_discount_item ' ,
181
+ [
182
+ 'website_id ' => $ store ->getWebsiteId (),
183
+ 'customer_group_id ' => $ quote ->getCustomerGroupId (),
184
+ 'coupon_code ' => $ quote ->getCouponCode (),
185
+ 'item ' => $ item
186
+ ]
187
+ );
217
188
218
189
$ this ->calculator ->process ($ item , $ rule );
219
190
$ appliedRuleIds = $ item ->getAppliedRuleIds () ? explode (', ' , $ item ->getAppliedRuleIds ()) : [];
220
191
if ($ rule ->getStopRulesProcessing () && in_array ($ rule ->getId (), $ appliedRuleIds )) {
221
192
unset($ itemsToApplyRules [$ key ]);
222
193
}
223
194
224
- $ totalDiscount[ $ item -> getId ()] = $ item -> getBaseDiscountAmount ( );
195
+ $ totalDiscount + = $ this -> getAggregatedItemBaseDiscount ( $ item );
225
196
}
226
- $ address ->setBaseDiscountAmount (array_sum ( array_values ( $ totalDiscount)) );
197
+ $ address ->setBaseDiscountAmount ($ totalDiscount );
227
198
}
228
199
$ this ->calculator ->initTotals ($ items , $ address );
229
200
foreach ($ items as $ item ) {
@@ -271,6 +242,104 @@ protected function aggregateItemDiscount(
271
242
return $ this ;
272
243
}
273
244
245
+ /**
246
+ * Get quote items
247
+ *
248
+ * @param Quote $quote
249
+ * @param AddressInterface $address
250
+ * @return Address\Item[]
251
+ * @throws \Zend_Db_Select_Exception
252
+ */
253
+ private function extractQuoteItems (Quote $ quote , AddressInterface $ address ): array
254
+ {
255
+ $ items = [];
256
+ foreach ($ quote ->getAllAddresses () as $ quoteAddress ) {
257
+ foreach ($ quoteAddress ->getAllItems () as $ item ) {
258
+ $ item ->setAppliedRuleIds (null );
259
+ if ($ item ->getExtensionAttributes ()) {
260
+ $ item ->getExtensionAttributes ()->setDiscounts (null );
261
+ }
262
+ $ item ->setDiscountAmount (0 );
263
+ $ item ->setBaseDiscountAmount (0 );
264
+ $ item ->setDiscountPercent (0 );
265
+ if ($ item ->getChildren () && $ item ->isChildrenCalculated ()) {
266
+ foreach ($ item ->getChildren () as $ child ) {
267
+ $ child ->setDiscountAmount (0 );
268
+ $ child ->setBaseDiscountAmount (0 );
269
+ $ child ->setDiscountPercent (0 );
270
+ }
271
+ }
272
+ $ item ->getAddress ()->setBaseDiscountAmount (0 );
273
+ $ items [] = $ item ;
274
+ }
275
+ }
276
+
277
+ if ($ items ) {
278
+ $ items = $ this ->calculator ->sortItemsByPriority ($ items , $ address );
279
+ }
280
+
281
+ return $ items ;
282
+ }
283
+
284
+ /**
285
+ * Get shipping items
286
+ *
287
+ * @param ShippingAssignmentInterface $shippingAssignment
288
+ * @return array
289
+ */
290
+ private function getShippingItems (ShippingAssignmentInterface $ shippingAssignment ): array
291
+ {
292
+ $ itemsAggregate = [];
293
+ foreach ($ shippingAssignment ->getItems () as $ item ) {
294
+ $ itemId = $ item ->getId ();
295
+ $ itemsAggregate [$ itemId ] = $ item ;
296
+ }
297
+
298
+ return $ itemsAggregate ;
299
+ }
300
+
301
+ /**
302
+ * Prepare quote address
303
+ *
304
+ * @param ShippingAssignmentInterface $shippingAssignment
305
+ * @param Quote $quote
306
+ * @return AddressInterface
307
+ */
308
+ private function getAddress (ShippingAssignmentInterface $ shippingAssignment , Quote $ quote ): AddressInterface
309
+ {
310
+ $ address = $ shippingAssignment ->getShipping ()->getAddress ();
311
+ if ($ quote ->currentPaymentWasSet ()) {
312
+ $ address ->setPaymentMethod ($ quote ->getPayment ()->getMethod ());
313
+ }
314
+
315
+ $ this ->calculator ->reset ($ address );
316
+ $ address ->setDiscountDescription ([]);
317
+ $ address ->getExtensionAttributes ()->setDiscounts ([]);
318
+ $ address ->setCartFixedRules ([]);
319
+ $ address ->setBaseDiscountAmount (0 );
320
+ return $ address ;
321
+ }
322
+
323
+ /**
324
+ * Calculate quote item base discount
325
+ *
326
+ * @param Item $item
327
+ * @return float
328
+ */
329
+ private function getAggregatedItemBaseDiscount (Item $ item ): float
330
+ {
331
+ $ baseDiscount = 0 ;
332
+ if ($ item ->getChildren () && $ item ->isChildrenCalculated ()) {
333
+ foreach ($ item ->getChildren () as $ child ) {
334
+ $ baseDiscount += $ child ->getBaseDiscountAmount ();
335
+ }
336
+ } else {
337
+ $ baseDiscount = $ item ->getBaseDiscountAmount ();
338
+ }
339
+
340
+ return $ baseDiscount ;
341
+ }
342
+
274
343
/**
275
344
* Distribute discount at parent item to children items
276
345
*
0 commit comments