6
6
namespace Magento \Quote \Model \Quote \Address \Total ;
7
7
8
8
use Magento \Framework \Pricing \PriceCurrencyInterface ;
9
+ use Magento \Quote \Api \Data \AddressInterface ;
9
10
use Magento \Quote \Model \Quote \Address \FreeShippingInterface ;
10
11
11
12
class Shipping extends \Magento \Quote \Model \Quote \Address \Total \AbstractTotal
@@ -40,7 +41,6 @@ public function __construct(
40
41
* @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
41
42
* @param \Magento\Quote\Model\Quote\Address\Total $total
42
43
* @return $this
43
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
44
44
* @SuppressWarnings(PHPMD.NPathComplexity)
45
45
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
46
46
*/
@@ -54,111 +54,27 @@ public function collect(
54
54
$ address = $ shippingAssignment ->getShipping ()->getAddress ();
55
55
$ method = $ shippingAssignment ->getShipping ()->getMethod ();
56
56
57
- $ address ->setWeight (0 );
58
- $ address ->setFreeMethodWeight (0 );
59
-
60
- $ addressWeight = $ address ->getWeight ();
61
- $ freeMethodWeight = $ address ->getFreeMethodWeight ();
62
- $ addressFreeShipping = $ address ->getFreeShipping ();
63
-
64
57
$ total ->setTotalAmount ($ this ->getCode (), 0 );
65
58
$ total ->setBaseTotalAmount ($ this ->getCode (), 0 );
66
59
67
60
if (!count ($ shippingAssignment ->getItems ())) {
68
61
return $ this ;
69
62
}
70
63
71
- $ addressQty = 0 ;
72
- foreach ($ shippingAssignment ->getItems () as $ item ) {
73
- /**
74
- * Skip if this item is virtual
75
- */
76
- if ($ item ->getProduct ()->isVirtual ()) {
77
- continue ;
78
- }
79
-
80
- /**
81
- * Children weight we calculate for parent
82
- */
83
- if ($ item ->getParentItem ()) {
84
- continue ;
85
- }
86
-
87
- if ($ item ->getHasChildren () && $ item ->isShipSeparately ()) {
88
- foreach ($ item ->getChildren () as $ child ) {
89
- if ($ child ->getProduct ()->isVirtual ()) {
90
- continue ;
91
- }
92
- $ addressQty += $ child ->getTotalQty ();
93
-
94
- if (!$ item ->getProduct ()->getWeightType ()) {
95
- $ itemWeight = $ child ->getWeight ();
96
- $ itemQty = $ child ->getTotalQty ();
97
- $ rowWeight = $ itemWeight * $ itemQty ;
98
- $ addressWeight += $ rowWeight ;
99
- if ($ addressFreeShipping || $ child ->getFreeShipping () === true ) {
100
- $ rowWeight = 0 ;
101
- } elseif (is_numeric ($ child ->getFreeShipping ())) {
102
- $ freeQty = $ child ->getFreeShipping ();
103
- if ($ itemQty > $ freeQty ) {
104
- $ rowWeight = $ itemWeight * ($ itemQty - $ freeQty );
105
- } else {
106
- $ rowWeight = 0 ;
107
- }
108
- }
109
- $ freeMethodWeight += $ rowWeight ;
110
- $ item ->setRowWeight ($ rowWeight );
111
- }
112
- }
113
- if ($ item ->getProduct ()->getWeightType ()) {
114
- $ itemWeight = $ item ->getWeight ();
115
- $ rowWeight = $ itemWeight * $ item ->getQty ();
116
- $ addressWeight += $ rowWeight ;
117
- if ($ addressFreeShipping || $ item ->getFreeShipping () === true ) {
118
- $ rowWeight = 0 ;
119
- } elseif (is_numeric ($ item ->getFreeShipping ())) {
120
- $ freeQty = $ item ->getFreeShipping ();
121
- if ($ item ->getQty () > $ freeQty ) {
122
- $ rowWeight = $ itemWeight * ($ item ->getQty () - $ freeQty );
123
- } else {
124
- $ rowWeight = 0 ;
125
- }
126
- }
127
- $ freeMethodWeight += $ rowWeight ;
128
- $ item ->setRowWeight ($ rowWeight );
129
- }
130
- } else {
131
- if (!$ item ->getProduct ()->isVirtual ()) {
132
- $ addressQty += $ item ->getQty ();
133
- }
134
- $ itemWeight = $ item ->getWeight ();
135
- $ rowWeight = $ itemWeight * $ item ->getQty ();
136
- $ addressWeight += $ rowWeight ;
137
- if ($ addressFreeShipping || $ item ->getFreeShipping () === true ) {
138
- $ rowWeight = 0 ;
139
- } elseif (is_numeric ($ item ->getFreeShipping ())) {
140
- $ freeQty = $ item ->getFreeShipping ();
141
- if ($ item ->getQty () > $ freeQty ) {
142
- $ rowWeight = $ itemWeight * ($ item ->getQty () - $ freeQty );
143
- } else {
144
- $ rowWeight = 0 ;
145
- }
146
- }
147
- $ freeMethodWeight += $ rowWeight ;
148
- $ item ->setRowWeight ($ rowWeight );
149
- }
64
+ $ data = $ this ->getAssignmentWeightData ($ address , $ shippingAssignment ->getItems ());
65
+ $ address ->setItemQty ($ data ['addressQty ' ]);
66
+ $ address ->setWeight ($ data ['addressWeight ' ]);
67
+ $ address ->setFreeMethodWeight ($ data ['freeMethodWeight ' ]);
68
+ $ addressFreeShipping = (bool )$ address ->getFreeShipping ();
69
+ $ isFreeShipping = $ this ->freeShipping ->isFreeShipping ($ quote , $ shippingAssignment ->getItems ());
70
+ $ address ->setFreeShipping ($ isFreeShipping );
71
+ if (!$ addressFreeShipping && $ isFreeShipping ) {
72
+ $ data = $ this ->getAssignmentWeightData ($ address , $ shippingAssignment ->getItems ());
73
+ $ address ->setItemQty ($ data ['addressQty ' ]);
74
+ $ address ->setWeight ($ data ['addressWeight ' ]);
75
+ $ address ->setFreeMethodWeight ($ data ['freeMethodWeight ' ]);
150
76
}
151
77
152
- if (isset ($ addressQty )) {
153
- $ address ->setItemQty ($ addressQty );
154
- }
155
-
156
- $ address ->setWeight ($ addressWeight );
157
- $ address ->setFreeMethodWeight ($ freeMethodWeight );
158
- $ address ->setFreeShipping (
159
- $ this ->freeShipping ->isFreeShipping ($ quote , $ shippingAssignment ->getItems ())
160
- );
161
-
162
78
$ address ->collectShippingRates ();
163
79
164
80
if ($ method ) {
@@ -215,4 +131,122 @@ public function getLabel()
215
131
{
216
132
return __ ('Shipping ' );
217
133
}
134
+
135
+ /**
136
+ * Gets shipping assignments data like items weight, address weight, items quantity.
137
+ *
138
+ * @param AddressInterface $address
139
+ * @param array $items
140
+ * @return array
141
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
142
+ */
143
+ private function getAssignmentWeightData (AddressInterface $ address , array $ items ): array
144
+ {
145
+ $ address ->setWeight (0 );
146
+ $ address ->setFreeMethodWeight (0 );
147
+ $ addressWeight = $ address ->getWeight ();
148
+ $ freeMethodWeight = $ address ->getFreeMethodWeight ();
149
+ $ addressFreeShipping = (bool )$ address ->getFreeShipping ();
150
+ $ addressQty = 0 ;
151
+ foreach ($ items as $ item ) {
152
+ /**
153
+ * Skip if this item is virtual
154
+ */
155
+ if ($ item ->getProduct ()->isVirtual ()) {
156
+ continue ;
157
+ }
158
+
159
+ /**
160
+ * Children weight we calculate for parent
161
+ */
162
+ if ($ item ->getParentItem ()) {
163
+ continue ;
164
+ }
165
+
166
+ $ itemQty = (float )$ item ->getQty ();
167
+ $ itemWeight = (float )$ item ->getWeight ();
168
+
169
+ if ($ item ->getHasChildren () && $ item ->isShipSeparately ()) {
170
+ foreach ($ item ->getChildren () as $ child ) {
171
+ if ($ child ->getProduct ()->isVirtual ()) {
172
+ continue ;
173
+ }
174
+ $ addressQty += $ child ->getTotalQty ();
175
+
176
+ if (!$ item ->getProduct ()->getWeightType ()) {
177
+ $ itemWeight = (float )$ child ->getWeight ();
178
+ $ itemQty = (float )$ child ->getTotalQty ();
179
+ $ addressWeight += ($ itemWeight * $ itemQty );
180
+ $ rowWeight = $ this ->getItemRowWeight (
181
+ $ addressFreeShipping ,
182
+ $ itemWeight ,
183
+ $ itemQty ,
184
+ $ child ->getFreeShipping ()
185
+ );
186
+ $ freeMethodWeight += $ rowWeight ;
187
+ $ item ->setRowWeight ($ rowWeight );
188
+ }
189
+ }
190
+ if ($ item ->getProduct ()->getWeightType ()) {
191
+ $ addressWeight += ($ itemWeight * $ itemQty );
192
+ $ rowWeight = $ this ->getItemRowWeight (
193
+ $ addressFreeShipping ,
194
+ $ itemWeight ,
195
+ $ itemQty ,
196
+ $ item ->getFreeShipping ()
197
+ );
198
+ $ freeMethodWeight += $ rowWeight ;
199
+ $ item ->setRowWeight ($ rowWeight );
200
+ }
201
+ } else {
202
+ if (!$ item ->getProduct ()->isVirtual ()) {
203
+ $ addressQty += $ itemQty ;
204
+ }
205
+ $ addressWeight += ($ itemWeight * $ itemQty );
206
+ $ rowWeight = $ this ->getItemRowWeight (
207
+ $ addressFreeShipping ,
208
+ $ itemWeight ,
209
+ $ itemQty ,
210
+ $ item ->getFreeShipping ()
211
+ );
212
+ $ freeMethodWeight += $ rowWeight ;
213
+ $ item ->setRowWeight ($ rowWeight );
214
+ }
215
+ }
216
+
217
+ return [
218
+ 'addressQty ' => $ addressQty ,
219
+ 'addressWeight ' => $ addressWeight ,
220
+ 'freeMethodWeight ' => $ freeMethodWeight
221
+ ];
222
+ }
223
+
224
+ /**
225
+ * Calculates item row weight.
226
+ *
227
+ * @param bool $addressFreeShipping
228
+ * @param float $itemWeight
229
+ * @param float $itemQty
230
+ * @param $freeShipping
231
+ * @return float
232
+ */
233
+ private function getItemRowWeight (
234
+ bool $ addressFreeShipping ,
235
+ float $ itemWeight ,
236
+ float $ itemQty ,
237
+ $ freeShipping
238
+ ): float {
239
+ $ rowWeight = $ itemWeight * $ itemQty ;
240
+ if ($ addressFreeShipping || $ freeShipping === true ) {
241
+ $ rowWeight = 0 ;
242
+ } elseif (is_numeric ($ freeShipping )) {
243
+ $ freeQty = $ freeShipping ;
244
+ if ($ itemQty > $ freeQty ) {
245
+ $ rowWeight = $ itemWeight * ($ itemQty - $ freeQty );
246
+ } else {
247
+ $ rowWeight = 0 ;
248
+ }
249
+ }
250
+ return (float )$ rowWeight ;
251
+ }
218
252
}
0 commit comments