Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
All Data Structures Namespaces Files Functions Variables Pages
Tablerate.php
Go to the documentation of this file.
1 <?php
8 
11 
20 {
24  protected $_code = 'tablerate';
25 
29  protected $_isFixed = true;
30 
34  protected $_defaultConditionName = 'package_weight';
35 
39  protected $_conditionNames = [];
40 
45 
50 
54  protected $_tablerateFactory;
55 
66  public function __construct(
67  \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
68  \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory,
69  \Psr\Log\LoggerInterface $logger,
70  \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory,
71  \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $resultMethodFactory,
72  \Magento\OfflineShipping\Model\ResourceModel\Carrier\TablerateFactory $tablerateFactory,
73  array $data = []
74  ) {
75  $this->_rateResultFactory = $rateResultFactory;
76  $this->_resultMethodFactory = $resultMethodFactory;
77  $this->_tablerateFactory = $tablerateFactory;
78  parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
79  foreach ($this->getCode('condition_name') as $k => $v) {
80  $this->_conditionNames[] = $k;
81  }
82  }
83 
93  public function collectRates(RateRequest $request)
94  {
95  if (!$this->getConfigFlag('active')) {
96  return false;
97  }
98 
99  // exclude Virtual products price from Package value if pre-configured
100  if (!$this->getConfigFlag('include_virtual_price') && $request->getAllItems()) {
101  foreach ($request->getAllItems() as $item) {
102  if ($item->getParentItem()) {
103  continue;
104  }
105  if ($item->getHasChildren() && $item->isShipSeparately()) {
106  foreach ($item->getChildren() as $child) {
107  if ($child->getProduct()->isVirtual()) {
108  $request->setPackageValue($request->getPackageValue() - $child->getBaseRowTotal());
109  }
110  }
111  } elseif ($item->getProduct()->isVirtual()) {
112  $request->setPackageValue($request->getPackageValue() - $item->getBaseRowTotal());
113  }
114  }
115  }
116 
117  // Free shipping by qty
118  $freeQty = 0;
119  $freePackageValue = 0;
120 
121  if ($request->getAllItems()) {
122  foreach ($request->getAllItems() as $item) {
123  if ($item->getProduct()->isVirtual() || $item->getParentItem()) {
124  continue;
125  }
126 
127  if ($item->getHasChildren() && $item->isShipSeparately()) {
128  foreach ($item->getChildren() as $child) {
129  if ($child->getFreeShipping() && !$child->getProduct()->isVirtual()) {
130  $freeShipping = is_numeric($child->getFreeShipping()) ? $child->getFreeShipping() : 0;
131  $freeQty += $item->getQty() * ($child->getQty() - $freeShipping);
132  }
133  }
134  } elseif ($item->getFreeShipping() || $item->getAddress()->getFreeShipping()) {
135  $freeShipping = $item->getFreeShipping() ?
136  $item->getFreeShipping() : $item->getAddress()->getFreeShipping();
137  $freeShipping = is_numeric($freeShipping) ? $freeShipping : 0;
138  $freeQty += $item->getQty() - $freeShipping;
139  $freePackageValue += $item->getBaseRowTotal();
140  }
141  }
142  $oldValue = $request->getPackageValue();
143  $request->setPackageValue($oldValue - $freePackageValue);
144  }
145 
146  if (!$request->getConditionName()) {
147  $conditionName = $this->getConfigData('condition_name');
148  $request->setConditionName($conditionName ? $conditionName : $this->_defaultConditionName);
149  }
150 
151  // Package weight and qty free shipping
152  $oldWeight = $request->getPackageWeight();
153  $oldQty = $request->getPackageQty();
154 
155  $request->setPackageWeight($request->getFreeMethodWeight());
156  $request->setPackageQty($oldQty - $freeQty);
157 
159  $result = $this->_rateResultFactory->create();
160  $rate = $this->getRate($request);
161 
162  $request->setPackageWeight($oldWeight);
163  $request->setPackageQty($oldQty);
164 
165  if (!empty($rate) && $rate['price'] >= 0) {
166  if ($request->getPackageQty() == $freeQty) {
167  $shippingPrice = 0;
168  } else {
170  }
171  $method = $this->createShippingMethod($shippingPrice, $rate['cost']);
172  $result->append($method);
173  } elseif ($request->getPackageQty() == $freeQty) {
174 
181  $request->setPackageValue($freePackageValue);
182  $request->setPackageQty($freeQty);
183  $rate = $this->getRate($request);
184  if (!empty($rate) && $rate['price'] >= 0) {
185  $method = $this->createShippingMethod(0, 0);
186  $result->append($method);
187  }
188  } else {
190  $error = $this->_rateErrorFactory->create(
191  [
192  'data' => [
193  'carrier' => $this->_code,
194  'carrier_title' => $this->getConfigData('title'),
195  'error_message' => $this->getConfigData('specificerrmsg'),
196  ],
197  ]
198  );
199  $result->append($error);
200  }
201 
202  return $result;
203  }
204 
211  public function getRate(\Magento\Quote\Model\Quote\Address\RateRequest $request)
212  {
213  return $this->_tablerateFactory->create()->getRate($request);
214  }
215 
224  public function getCode($type, $code = '')
225  {
226  $codes = [
227  'condition_name' => [
228  'package_weight' => __('Weight vs. Destination'),
229  'package_value' => __('Price vs. Destination'),
230  'package_qty' => __('# of Items vs. Destination'),
231  ],
232  'condition_name_short' => [
233  'package_weight' => __('Weight (and above)'),
234  'package_value' => __('Order Subtotal (and above)'),
235  'package_qty' => __('# of Items (and above)'),
236  ],
237  ];
238 
239  if (!isset($codes[$type])) {
240  throw new LocalizedException(
241  __('The "%1" code type for Table Rate is incorrect. Verify the type and try again.', $type)
242  );
243  }
244 
245  if ('' === $code) {
246  return $codes[$type];
247  }
248 
249  if (!isset($codes[$type][$code])) {
250  throw new LocalizedException(
251  __('The "%1: %2" code type for Table Rate is incorrect. Verify the type and try again.', $type, $code)
252  );
253  }
254 
255  return $codes[$type][$code];
256  }
257 
263  public function getAllowedMethods()
264  {
265  return ['bestway' => $this->getConfigData('name')];
266  }
267 
275  private function createShippingMethod($shippingPrice, $cost)
276  {
278  $method = $this->_resultMethodFactory->create();
279 
280  $method->setCarrier('tablerate');
281  $method->setCarrierTitle($this->getConfigData('title'));
282 
283  $method->setMethod('bestway');
284  $method->setMethodTitle($this->getConfigData('name'));
285 
286  $method->setPrice($shippingPrice);
287  $method->setCost($cost);
288  return $method;
289  }
290 }
__construct(\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, \Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory $rateErrorFactory, \Psr\Log\LoggerInterface $logger, \Magento\Shipping\Model\Rate\ResultFactory $rateResultFactory, \Magento\Quote\Model\Quote\Address\RateResult\MethodFactory $resultMethodFactory, \Magento\OfflineShipping\Model\ResourceModel\Carrier\TablerateFactory $tablerateFactory, array $data=[])
Definition: Tablerate.php:66
elseif(isset( $params[ 'redirect_parent']))
Definition: iframe.phtml:17
$shippingPrice
Definition: price.phtml:12
getRate(\Magento\Quote\Model\Quote\Address\RateRequest $request)
Definition: Tablerate.php:211
__()
Definition: __.php:13
$logger
$type
Definition: item.phtml:13
$method
Definition: info.phtml:13
$code
Definition: info.phtml:12