Skip to content

Commit 48d72db

Browse files
author
Mariana Lashch
committed
Merge branch 'MAGETWO-92784' into mpi-PR-1607
2 parents 9bbf0e2 + 067aa85 commit 48d72db

File tree

6 files changed

+444
-111
lines changed

6 files changed

+444
-111
lines changed

app/code/Magento/Quote/Model/Quote/Address/Total/Shipping.php

Lines changed: 131 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace Magento\Quote\Model\Quote\Address\Total;
77

88
use Magento\Framework\Pricing\PriceCurrencyInterface;
9+
use Magento\Quote\Api\Data\AddressInterface;
910
use Magento\Quote\Model\Quote\Address\FreeShippingInterface;
1011

1112
class Shipping extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
@@ -40,7 +41,6 @@ public function __construct(
4041
* @param \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment
4142
* @param \Magento\Quote\Model\Quote\Address\Total $total
4243
* @return $this
43-
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
4444
* @SuppressWarnings(PHPMD.NPathComplexity)
4545
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
4646
*/
@@ -54,111 +54,27 @@ public function collect(
5454
$address = $shippingAssignment->getShipping()->getAddress();
5555
$method = $shippingAssignment->getShipping()->getMethod();
5656

57-
$address->setWeight(0);
58-
$address->setFreeMethodWeight(0);
59-
60-
$addressWeight = $address->getWeight();
61-
$freeMethodWeight = $address->getFreeMethodWeight();
62-
$addressFreeShipping = $address->getFreeShipping();
63-
6457
$total->setTotalAmount($this->getCode(), 0);
6558
$total->setBaseTotalAmount($this->getCode(), 0);
6659

6760
if (!count($shippingAssignment->getItems())) {
6861
return $this;
6962
}
7063

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']);
15076
}
15177

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-
16278
$address->collectShippingRates();
16379

16480
if ($method) {
@@ -215,4 +131,122 @@ public function getLabel()
215131
{
216132
return __('Shipping');
217133
}
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+
}
218252
}

app/code/Magento/Quote/Test/Unit/Model/Quote/Address/Total/ShippingTest.php

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,10 @@ public function testCollect()
158158
$this->shippingAssignment->expects($this->atLeastOnce())
159159
->method('getItems')
160160
->willReturn([$this->cartItem]);
161-
$this->freeShipping->expects($this->once())
162-
->method('isFreeShipping')
161+
$this->freeShipping->method('isFreeShipping')
163162
->with($this->quote, [$this->cartItem])
164163
->willReturn(true);
165-
$this->address->expects($this->once())
166-
->method('setFreeShipping')
164+
$this->address->method('setFreeShipping')
167165
->with(true);
168166
$this->total->expects($this->atLeastOnce())
169167
->method('setTotalAmount');
@@ -175,24 +173,19 @@ public function testCollect()
175173
$this->cartItem->expects($this->atLeastOnce())
176174
->method('isVirtual')
177175
->willReturn(false);
178-
$this->cartItem->expects($this->once())
179-
->method('getParentItem')
176+
$this->cartItem->method('getParentItem')
180177
->willReturn(false);
181-
$this->cartItem->expects($this->once())
182-
->method('getHasChildren')
178+
$this->cartItem->method('getHasChildren')
183179
->willReturn(false);
184-
$this->cartItem->expects($this->once())
185-
->method('getWeight')
180+
$this->cartItem->method('getWeight')
186181
->willReturn(2);
187182
$this->cartItem->expects($this->atLeastOnce())
188183
->method('getQty')
189184
->willReturn(2);
190185
$this->freeShippingAssertions();
191-
$this->cartItem->expects($this->once())
192-
->method('setRowWeight')
186+
$this->cartItem->method('setRowWeight')
193187
->with(0);
194-
$this->address->expects($this->once())
195-
->method('setItemQty')
188+
$this->address->method('setItemQty')
196189
->with(2);
197190
$this->address->expects($this->atLeastOnce())
198191
->method('setWeight');

0 commit comments

Comments
 (0)