1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Copyright © 2015 Magento. All rights reserved. |
4
|
|
|
* See COPYING.txt for license details. |
5
|
|
|
*/ |
6
|
|
|
namespace Meanbee\MagentoRoyalmail\Model; |
7
|
|
|
|
8
|
|
|
use Magento\Framework\App\Config\ScopeConfigInterface; |
9
|
|
|
use Magento\Framework\DataObject; |
10
|
|
|
use Magento\Shipping\Model\Carrier\AbstractCarrier; |
11
|
|
|
use Magento\Shipping\Model\Carrier\CarrierInterface; |
12
|
|
|
use Magento\Shipping\Model\Rate\ResultFactory; |
13
|
|
|
use Magento\Quote\Model\Quote\Address\RateResult\ErrorFactory; |
14
|
|
|
use Magento\Quote\Model\Quote\Address\RateResult\Method; |
15
|
|
|
use Magento\Quote\Model\Quote\Address\RateResult\MethodFactory; |
16
|
|
|
use Magento\Quote\Model\Quote\Address\RateRequest; |
17
|
|
|
use Meanbee\Royalmail\Carrier as LibCarrier; |
18
|
|
|
use Psr\Log\LoggerInterface; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Class Carrier Royal Mail shipping model |
22
|
|
|
*/ |
23
|
|
|
class Carrier extends AbstractCarrier implements CarrierInterface |
24
|
|
|
{ |
25
|
|
|
/** |
26
|
|
|
* Carrier's code |
27
|
|
|
* |
28
|
|
|
* @var string |
29
|
|
|
*/ |
30
|
|
|
protected $_code = 'meanbee_royalmail'; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Whether this carrier has fixed rates calculation |
34
|
|
|
* |
35
|
|
|
* @var bool |
36
|
|
|
*/ |
37
|
|
|
protected $_isFixed = true; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @var ResultFactory |
41
|
|
|
*/ |
42
|
|
|
protected $rateResultFactory; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @var MethodFactory |
46
|
|
|
*/ |
47
|
|
|
protected $rateMethodFactory; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @var LibCarrier |
51
|
|
|
*/ |
52
|
|
|
protected $carrier; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* @var Rounder |
56
|
|
|
*/ |
57
|
|
|
protected $rounder; |
58
|
|
|
|
59
|
|
|
/** |
60
|
|
|
* @param ScopeConfigInterface $scopeConfig |
61
|
|
|
* @param ErrorFactory $rateErrorFactory |
62
|
|
|
* @param LoggerInterface $logger |
63
|
|
|
* @param ResultFactory $rateResultFactory |
64
|
|
|
* @param MethodFactory $rateMethodFactory |
65
|
|
|
* @param Rounder $rounder |
66
|
|
|
* @param array $data |
67
|
|
|
*/ |
68
|
8 |
|
public function __construct( |
69
|
|
|
ScopeConfigInterface $scopeConfig, |
70
|
|
|
ErrorFactory $rateErrorFactory, |
71
|
|
|
LoggerInterface $logger, |
72
|
|
|
ResultFactory $rateResultFactory, |
73
|
|
|
MethodFactory $rateMethodFactory, |
74
|
|
|
Rounder $rounder, |
75
|
|
|
array $data = [] |
76
|
|
|
) { |
77
|
8 |
|
$this->rateResultFactory = $rateResultFactory; |
78
|
8 |
|
$this->rateMethodFactory = $rateMethodFactory; |
79
|
8 |
|
$this->rounder = $rounder; |
80
|
8 |
|
parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data); |
81
|
8 |
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Collect and get rates for storefront |
85
|
|
|
* |
86
|
|
|
* @SuppressWarnings(PHPMD.UnusedFormalParameter) |
87
|
|
|
* @param RateRequest $request |
88
|
|
|
* @return DataObject|bool|null |
89
|
|
|
* @api |
90
|
|
|
*/ |
91
|
6 |
|
public function collectRates(RateRequest $request) |
92
|
|
|
{ |
93
|
|
|
/** |
94
|
|
|
* Make sure that Shipping method is enabled |
95
|
|
|
*/ |
96
|
6 |
|
if (!$this->isActive()) { |
97
|
1 |
|
return false; |
98
|
|
|
} |
99
|
|
|
|
100
|
5 |
|
$unit = $this->_scopeConfig->getValue( |
101
|
5 |
|
\Magento\Directory\Helper\Data::XML_PATH_WEIGHT_UNIT, |
102
|
|
|
\Magento\Store\Model\ScopeInterface::SCOPE_STORE |
103
|
5 |
|
); |
104
|
|
|
|
105
|
5 |
|
$weight = $this->getPackageWeightInKg($request->getPackageWeight(), $unit); |
106
|
|
|
|
107
|
5 |
|
$methods = $this->getCarrier()->getRates( |
108
|
5 |
|
$request->getDestCountryId(), |
109
|
5 |
|
$request->getPackageValue(), |
110
|
|
|
$weight |
111
|
5 |
|
); |
112
|
|
|
|
113
|
5 |
|
$methods = $this->removeUnusedParcelSizes($methods, $weight); |
114
|
|
|
|
115
|
5 |
|
$result = $this->rateResultFactory->create(); |
116
|
|
|
|
117
|
5 |
|
$allowedMethods = $this->getAllowedMethods(); |
118
|
|
|
|
119
|
5 |
|
if (empty($allowedMethods)) { |
120
|
1 |
|
return $result; |
121
|
|
|
} |
122
|
|
|
|
123
|
|
|
/** @var \Meanbee\RoyalMail\Method $method */ |
124
|
4 |
|
foreach ($methods as $method) { |
125
|
2 |
|
if (!array_key_exists($method->getCode(), $allowedMethods)) { |
126
|
1 |
|
continue; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
/** @var Method $rate */ |
130
|
1 |
|
$rate = $this->rateMethodFactory->create(); |
131
|
1 |
|
$rate->setData('carrier', $this->getCarrierCode()); |
132
|
1 |
|
$rate->setData('carrier_title', $this->getConfigData('title')); |
133
|
1 |
|
$rate->setData('method_title', $method->getName()); |
134
|
2 |
|
$rate->setData('method', $method->getCode()); |
135
|
1 |
|
$rate->setPrice( |
136
|
1 |
|
$this->rounder->round( |
137
|
1 |
|
$this->getConfigData('rounding_rule'), |
|
|
|
|
138
|
1 |
|
$this->getFinalPriceWithHandlingFee($method->getPrice()) |
139
|
1 |
|
) |
140
|
1 |
|
); |
141
|
1 |
|
$result->append($rate); |
142
|
4 |
|
} |
143
|
|
|
|
144
|
4 |
|
return $result; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
|
148
|
|
|
/** |
149
|
|
|
* Gets the methods selected in the admin area of the extension |
150
|
|
|
* to ensure that not allowed methods can be removed in the collect |
151
|
|
|
* rates method |
152
|
|
|
* |
153
|
|
|
* @return array |
154
|
|
|
*/ |
155
|
6 |
|
public function getAllowedMethods() |
156
|
|
|
{ |
157
|
6 |
|
$configMethods = explode(',', $this->getConfigData('allowed_methods')); |
158
|
6 |
|
$allMethods = $this->getMethods(); |
159
|
|
|
|
160
|
6 |
|
return array_intersect_key($allMethods, array_flip($configMethods)); |
161
|
|
|
} |
162
|
|
|
/** |
163
|
|
|
* Gets the clean method names from the royal mail library data |
164
|
|
|
* class. These names link directly to method names, but are used |
165
|
|
|
* to ensure that duplicates are not created as similar names |
166
|
|
|
* exists for multiple methods. |
167
|
|
|
* |
168
|
|
|
* @return array |
169
|
|
|
*/ |
170
|
7 |
|
public function getMethods() |
171
|
|
|
{ |
172
|
7 |
|
return $this->getCarrier()->getAllMethods(); |
173
|
|
|
} |
174
|
|
|
|
175
|
|
|
/** |
176
|
|
|
* @return LibCarrier |
177
|
|
|
*/ |
178
|
7 |
|
public function getCarrier() |
179
|
|
|
{ |
180
|
|
|
/** |
181
|
|
|
* Bug in Magento, when production mode is enabled |
182
|
|
|
* if you're trying to inject an external library, magento won't discover |
183
|
|
|
* the correct dependencies. Even if it is clearly defined in di.xml. |
184
|
|
|
* This odd behaviour results in an instance of ObjectManager being injected. |
185
|
|
|
* Solution is to skip DI, and instantiate yourself. |
186
|
|
|
* |
187
|
|
|
* @TODO Once issue is resolved, we can use the constructor instantiated $carrier object. |
188
|
|
|
* @link https://github.com/magento/magento2/issues/6739 |
189
|
|
|
*/ |
190
|
7 |
|
if (!$this->carrier) { |
191
|
|
|
$this->carrier = new LibCarrier(); |
192
|
|
|
} |
193
|
|
|
|
194
|
7 |
|
return $this->carrier; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* @deprecated |
199
|
|
|
* @param $libCarrier |
200
|
|
|
* @return $this |
201
|
|
|
*/ |
202
|
8 |
|
public function setCarrier($libCarrier) |
203
|
|
|
{ |
204
|
8 |
|
$this->carrier = $libCarrier; |
205
|
8 |
|
return $this; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Get package weight in Kilograms converting from lbs if necessary. |
210
|
|
|
* |
211
|
|
|
* @param $weight |
212
|
|
|
* @param $unit |
213
|
|
|
* @return mixed |
214
|
|
|
*/ |
215
|
5 |
|
protected function getPackageWeightInKg($weight, $unit) |
216
|
|
|
{ |
217
|
5 |
|
if ($unit == 'lbs') { |
218
|
1 |
|
$weight = $weight * 0.453592; |
219
|
1 |
|
} |
220
|
|
|
|
221
|
5 |
|
return $weight; |
222
|
|
|
} |
223
|
|
|
|
224
|
|
|
/** |
225
|
|
|
* Both small and medium sized parcels can serve up to 2KG. |
226
|
|
|
* Configuration option determines which size we show to customer. |
227
|
|
|
* |
228
|
|
|
* @param \Meanbee\RoyalMail\Method[] $methods |
229
|
|
|
* @param int $weight |
230
|
|
|
* @return \Meanbee\RoyalMail\Method[] |
231
|
|
|
*/ |
232
|
5 |
|
protected function removeUnusedParcelSizes($methods, $weight) |
233
|
|
|
{ |
234
|
5 |
|
$parcelSize = $this->getConfigData('parcel_size'); |
235
|
5 |
|
if ($weight <= 2 && $parcelSize) { |
236
|
1 |
|
foreach ($methods as $key => $method) { |
237
|
1 |
|
if ($method->getSize() && $method->getSize() != $parcelSize) { |
238
|
1 |
|
unset($methods[$key]); |
239
|
1 |
|
} |
240
|
1 |
|
} |
241
|
1 |
|
} |
242
|
|
|
|
243
|
5 |
|
return $methods; |
244
|
|
|
} |
245
|
|
|
} |
246
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.