Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Shipping.php
Go to the documentation of this file.
1 <?php
7 
11 
12 class Shipping extends \Magento\Quote\Model\Quote\Address\Total\AbstractTotal
13 {
17  protected $priceCurrency;
18 
22  protected $freeShipping;
23 
28  public function __construct(
31  ) {
32  $this->priceCurrency = $priceCurrency;
33  $this->freeShipping = $freeShipping;
34  $this->setCode('shipping');
35  }
36 
47  public function collect(
48  \Magento\Quote\Model\Quote $quote,
49  \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment,
51  ) {
52  parent::collect($quote, $shippingAssignment, $total);
53 
54  $address = $shippingAssignment->getShipping()->getAddress();
55  $method = $shippingAssignment->getShipping()->getMethod();
56 
57  $total->setTotalAmount($this->getCode(), 0);
58  $total->setBaseTotalAmount($this->getCode(), 0);
59 
60  if (!count($shippingAssignment->getItems())) {
61  return $this;
62  }
63 
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']);
76  }
77 
78  $address->collectShippingRates();
79 
80  if ($method) {
81  foreach ($address->getAllShippingRates() as $rate) {
82  if ($rate->getCode() == $method) {
83  $store = $quote->getStore();
84  $amountPrice = $this->priceCurrency->convert(
85  $rate->getPrice(),
86  $store
87  );
88  $total->setTotalAmount($this->getCode(), $amountPrice);
89  $total->setBaseTotalAmount($this->getCode(), $rate->getPrice());
90  $shippingDescription = $rate->getCarrierTitle() . ' - ' . $rate->getMethodTitle();
91  $address->setShippingDescription(trim($shippingDescription, ' -'));
92  $total->setBaseShippingAmount($rate->getPrice());
93  $total->setShippingAmount($amountPrice);
94  $total->setShippingDescription($address->getShippingDescription());
95  break;
96  }
97  }
98  }
99  return $this;
100  }
101 
110  public function fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
111  {
112  $amount = $total->getShippingAmount();
113  $shippingDescription = $total->getShippingDescription();
114  $title = ($amount != 0 && $shippingDescription)
115  ? __('Shipping & Handling (%1)', $shippingDescription)
116  : __('Shipping & Handling');
117 
118  return [
119  'code' => $this->getCode(),
120  'title' => $title,
121  'value' => $amount
122  ];
123  }
124 
130  public function getLabel()
131  {
132  return __('Shipping');
133  }
134 
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) {
155  if ($item->getProduct()->isVirtual()) {
156  continue;
157  }
158 
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 
233  private function getItemRowWeight(
234  bool $addressFreeShipping,
235  float $itemWeight,
236  float $itemQty,
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  }
252 }
$title
Definition: default.phtml:14
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$quote
__()
Definition: __.php:13
fetch(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Model\Quote\Address\Total $total)
Definition: Shipping.php:110
$address
Definition: customer.php:38
$amount
Definition: order.php:14
$method
Definition: info.phtml:13
__construct(PriceCurrencyInterface $priceCurrency, FreeShippingInterface $freeShipping)
Definition: Shipping.php:28
collect(\Magento\Quote\Model\Quote $quote, \Magento\Quote\Api\Data\ShippingAssignmentInterface $shippingAssignment, \Magento\Quote\Model\Quote\Address\Total $total)
Definition: Shipping.php:47
$items