Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
TotalsCollector.php
Go to the documentation of this file.
1 <?php
2 
9 
11 use Magento\Quote\Model\Quote\Address\Total\CollectorFactory;
13 
19 {
25  protected $totalCollector;
26 
31 
37  protected $eventManager;
38 
42  protected $storeManager;
43 
47  protected $totalFactory;
48 
52  protected $collectorList;
53 
59  protected $quoteValidator;
60 
64  protected $shippingFactory;
65 
70 
83  public function __construct(
85  CollectorFactory $totalCollectorFactory,
86  \Magento\Framework\Event\ManagerInterface $eventManager,
90  \Magento\Quote\Model\ShippingFactory $shippingFactory,
91  \Magento\Quote\Model\ShippingAssignmentFactory $shippingAssignmentFactory,
93  ) {
94  $this->totalCollector = $totalCollector;
95  $this->totalCollectorFactory = $totalCollectorFactory;
96  $this->eventManager = $eventManager;
97  $this->storeManager = $storeManager;
98  $this->totalFactory = $totalFactory;
99  $this->collectorList = $collectorList;
100  $this->shippingFactory = $shippingFactory;
101  $this->shippingAssignmentFactory = $shippingAssignmentFactory;
102  $this->quoteValidator = $quoteValidator;
103  }
104 
109  public function collectQuoteTotals(\Magento\Quote\Model\Quote $quote)
110  {
111  if ($quote->isVirtual()) {
112  return $this->collectAddressTotals($quote, $quote->getBillingAddress());
113  }
114  return $this->collectAddressTotals($quote, $quote->getShippingAddress());
115  }
116 
121  public function collect(\Magento\Quote\Model\Quote $quote)
122  {
124  $total = $this->totalFactory->create(\Magento\Quote\Model\Quote\Address\Total::class);
125 
126  $this->eventManager->dispatch(
127  'sales_quote_collect_totals_before',
128  ['quote' => $quote]
129  );
130 
131  $this->_collectItemsQtys($quote);
132 
133  $total->setSubtotal(0);
134  $total->setBaseSubtotal(0);
135 
136  $total->setSubtotalWithDiscount(0);
137  $total->setBaseSubtotalWithDiscount(0);
138 
139  $total->setGrandTotal(0);
140  $total->setBaseGrandTotal(0);
141 
143  foreach ($quote->getAllAddresses() as $address) {
144  $addressTotal = $this->collectAddressTotals($quote, $address);
145 
146  $total->setShippingAmount($addressTotal->getShippingAmount());
147  $total->setBaseShippingAmount($addressTotal->getBaseShippingAmount());
148  $total->setShippingDescription($addressTotal->getShippingDescription());
149 
150  $total->setSubtotal((float)$total->getSubtotal() + $addressTotal->getSubtotal());
151  $total->setBaseSubtotal((float)$total->getBaseSubtotal() + $addressTotal->getBaseSubtotal());
152 
153  $total->setSubtotalWithDiscount(
154  (float)$total->getSubtotalWithDiscount() + $addressTotal->getSubtotalWithDiscount()
155  );
156  $total->setBaseSubtotalWithDiscount(
157  (float)$total->getBaseSubtotalWithDiscount() + $addressTotal->getBaseSubtotalWithDiscount()
158  );
159 
160  $total->setGrandTotal((float)$total->getGrandTotal() + $addressTotal->getGrandTotal());
161  $total->setBaseGrandTotal((float)$total->getBaseGrandTotal() + $addressTotal->getBaseGrandTotal());
162  }
163 
164  $this->quoteValidator->validateQuoteAmount($quote, $quote->getGrandTotal());
165  $this->quoteValidator->validateQuoteAmount($quote, $quote->getBaseGrandTotal());
166  $this->_validateCouponCode($quote);
167  $this->eventManager->dispatch(
168  'sales_quote_collect_totals_after',
169  ['quote' => $quote]
170  );
171  return $total;
172  }
173 
178  protected function _validateCouponCode(\Magento\Quote\Model\Quote $quote)
179  {
180  $code = $quote->getData('coupon_code');
181  if (strlen($code)) {
182  $addressHasCoupon = false;
183  $addresses = $quote->getAllAddresses();
184  if (count($addresses) > 0) {
185  foreach ($addresses as $address) {
186  if ($address->hasCouponCode()) {
187  $addressHasCoupon = true;
188  }
189  }
190  if (!$addressHasCoupon) {
191  $quote->setCouponCode('');
192  }
193  }
194  }
195  return $this;
196  }
197 
204  protected function _collectItemsQtys(\Magento\Quote\Model\Quote $quote)
205  {
206  $quote->setItemsCount(0);
207  $quote->setItemsQty(0);
208  $quote->setVirtualItemsQty(0);
209 
210  foreach ($quote->getAllVisibleItems() as $item) {
211  if ($item->getParentItem()) {
212  continue;
213  }
214 
215  $children = $item->getChildren();
216  if ($children && $item->isShipSeparately()) {
217  foreach ($children as $child) {
218  if ($child->getProduct()->getIsVirtual()) {
219  $quote->setVirtualItemsQty($quote->getVirtualItemsQty() + $child->getQty() * $item->getQty());
220  }
221  }
222  }
223 
224  if ($item->getProduct()->getIsVirtual()) {
225  $quote->setVirtualItemsQty($quote->getVirtualItemsQty() + $item->getQty());
226  }
227  $quote->setItemsCount($quote->getItemsCount() + 1);
228  $quote->setItemsQty((float)$quote->getItemsQty() + $item->getQty());
229  }
230  return $this;
231  }
232 
238  public function collectAddressTotals(
239  \Magento\Quote\Model\Quote $quote,
241  ) {
243  $shippingAssignment = $this->shippingAssignmentFactory->create();
244 
246  $shipping = $this->shippingFactory->create();
247  $shipping->setMethod($address->getShippingMethod());
248  $shipping->setAddress($address);
249  $shippingAssignment->setShipping($shipping);
250  $shippingAssignment->setItems($address->getAllItems());
251 
253  $total = $this->totalFactory->create(\Magento\Quote\Model\Quote\Address\Total::class);
254  $this->eventManager->dispatch(
255  'sales_quote_address_collect_totals_before',
256  [
257  'quote' => $quote,
258  'shipping_assignment' => $shippingAssignment,
259  'total' => $total
260  ]
261  );
262 
263  foreach ($this->collectorList->getCollectors($quote->getStoreId()) as $collector) {
265  $collector->collect($quote, $shippingAssignment, $total);
266  }
267 
268  $this->eventManager->dispatch(
269  'sales_quote_address_collect_totals_after',
270  [
271  'quote' => $quote,
272  'shipping_assignment' => $shippingAssignment,
273  'total' => $total
274  ]
275  );
276 
277  $address->addData($total->getData());
278  $address->setAppliedTaxes($total->getAppliedTaxes());
279  return $total;
280  }
281 }
_validateCouponCode(\Magento\Quote\Model\Quote $quote)
$addresses
Definition: address_list.php:7
$quote
_collectItemsQtys(\Magento\Quote\Model\Quote $quote)
$address
Definition: customer.php:38
$children
Definition: actions.phtml:11
__construct(Collector $totalCollector, CollectorFactory $totalCollectorFactory, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Quote\Model\Quote\Address\TotalFactory $totalFactory, \Magento\Quote\Model\Quote\TotalsCollectorList $collectorList, \Magento\Quote\Model\ShippingFactory $shippingFactory, \Magento\Quote\Model\ShippingAssignmentFactory $shippingAssignmentFactory, \Magento\Quote\Model\QuoteValidator $quoteValidator)
$code
Definition: info.phtml:12
collectQuoteTotals(\Magento\Quote\Model\Quote $quote)