7
7
8
8
use Magento \Framework \App \ObjectManager ;
9
9
use Magento \Framework \Event \ManagerInterface ;
10
- use Magento \Framework \Exception \NoSuchEntityException ;
11
10
use Magento \Framework \Pricing \PriceCurrencyInterface ;
12
11
use Magento \Quote \Api \Data \AddressInterface ;
13
12
use Magento \Quote \Api \Data \ShippingAssignmentInterface ;
@@ -129,34 +128,71 @@ public function _resetState(): void
129
128
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
130
129
* @SuppressWarnings(PHPMD.NPathComplexity)
131
130
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
132
- * @throws \Zend_Db_Select_Exception|NoSuchEntityException
133
131
*/
134
132
public function collect (
135
133
Quote $ quote ,
136
134
ShippingAssignmentInterface $ shippingAssignment ,
137
135
Total $ total
138
136
) {
139
137
parent ::collect ($ quote , $ shippingAssignment , $ total );
140
- $ this ->addressDiscountAggregator = [];
141
-
142
- $ address = $ this ->getAddress ($ shippingAssignment , $ quote );
143
- $ itemsAggregate = $ this ->getShippingItems ($ shippingAssignment );
144
- $ items = $ this ->extractQuoteItems ($ quote , $ address );
145
-
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
+ }
146
156
if (!$ items || !$ itemsAggregate ) {
147
157
return $ this ;
148
158
}
149
- $ store = $ this ->storeManager ->getStore ($ quote ->getStoreId ());
150
-
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 ([]);
151
168
$ 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
+ }
152
186
$ this ->calculator ->initFromQuote ($ quote );
153
187
$ this ->calculator ->initTotals ($ items , $ address );
154
-
188
+ $ items = $ this -> calculator -> sortItemsByPriority ( $ items , $ address );
155
189
$ itemsToApplyRules = $ items ;
156
-
190
+ $ rules = $ this ->calculator ->getRules ($ address );
191
+ $ totalDiscount = [];
192
+ $ address ->setBaseDiscountAmount (0 );
157
193
/** @var Rule $rule */
158
- foreach ($ this -> calculator -> getRules ( $ address ) as $ rule ) {
159
- $ totalDiscount = 0 ;
194
+ foreach ($ rules as $ rule ) {
195
+ /** @var Item $item */
160
196
foreach ($ itemsToApplyRules as $ key => $ item ) {
161
197
if ($ item ->getNoDiscount () || !$ this ->calculator ->canApplyDiscount ($ item ) || $ item ->getParentItem ()) {
162
198
continue ;
@@ -176,25 +212,24 @@ public function collect(
176
212
break ;
177
213
}
178
214
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
- );
215
+ $ eventArgs ['item ' ] = $ item ;
216
+ $ this ->eventManager ->dispatch ('sales_quote_address_discount_item ' , $ eventArgs );
188
217
189
218
$ this ->calculator ->process ($ item , $ rule );
190
219
$ appliedRuleIds = $ item ->getAppliedRuleIds () ? explode (', ' , $ item ->getAppliedRuleIds ()) : [];
191
220
if ($ rule ->getStopRulesProcessing () && in_array ($ rule ->getId (), $ appliedRuleIds )) {
192
221
unset($ itemsToApplyRules [$ key ]);
193
222
}
194
223
195
- $ totalDiscount += $ this ->getAggregatedItemBaseDiscount ($ item );
224
+ if ($ item ->getChildren () && $ item ->isChildrenCalculated ()) {
225
+ foreach ($ item ->getChildren () as $ child ) {
226
+ $ totalDiscount [$ item ->getId ()] += $ child ->getBaseDiscountAmount ();
227
+ }
228
+ } else {
229
+ $ totalDiscount [$ item ->getId ()] = $ item ->getBaseDiscountAmount ();
230
+ }
196
231
}
197
- $ address ->setBaseDiscountAmount ($ totalDiscount );
232
+ $ address ->setBaseDiscountAmount (array_sum ( array_values ( $ totalDiscount)) );
198
233
}
199
234
$ this ->calculator ->initTotals ($ items , $ address );
200
235
foreach ($ items as $ item ) {
@@ -242,104 +277,6 @@ protected function aggregateItemDiscount(
242
277
return $ this ;
243
278
}
244
279
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
-
343
280
/**
344
281
* Distribute discount at parent item to children items
345
282
*
0 commit comments