Completed
Pull Request — master (#4)
by Ash
31:32
created

Carrier   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 225
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 97.06%

Importance

Changes 0
Metric Value
wmc 19
lcom 1
cbo 6
dl 0
loc 225
ccs 66
cts 68
cp 0.9706
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 1
B collectRates() 0 55 5
A getAllowedMethods() 0 7 1
A getMethods() 0 4 1
A getCarrier() 0 18 2
A setCarrier() 0 5 1
A getPackageWeightInKg() 0 8 2
B removeUnusedParcelSizes() 0 13 6
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 LibCarrier $carrier
67
     * @param array $data
68
     */
69 8
    public function __construct(
70
        ScopeConfigInterface $scopeConfig,
71
        ErrorFactory $rateErrorFactory,
72
        LoggerInterface $logger,
73
        ResultFactory $rateResultFactory,
74
        MethodFactory $rateMethodFactory,
75
        Rounder $rounder,
76
        LibCarrier $carrier,
0 ignored issues
show
Unused Code introduced by
The parameter $carrier is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
77
        array $data = []
78
    ) {
79 8
        $this->rateResultFactory = $rateResultFactory;
80 8
        $this->rateMethodFactory = $rateMethodFactory;
81 8
        $this->rounder = $rounder;
82 8
        parent::__construct($scopeConfig, $rateErrorFactory, $logger, $data);
83 8
    }
84
85
    /**
86
     * Collect and get rates for storefront
87
     *
88
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
89
     * @param RateRequest $request
90
     * @return DataObject|bool|null
91
     * @api
92
     */
93 6
    public function collectRates(RateRequest $request)
94
    {
95
        /**
96
         * Make sure that Shipping method is enabled
97
         */
98 6
        if (!$this->isActive()) {
99 1
            return false;
100
        }
101
102 5
        $unit = $this->_scopeConfig->getValue(
103 5
            \Magento\Directory\Helper\Data::XML_PATH_WEIGHT_UNIT,
104
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
105 5
        );
106
107 5
        $weight = $this->getPackageWeightInKg($request->getPackageWeight(), $unit);
108
109 5
        $methods = $this->getCarrier()->getRates(
110 5
            $request->getDestCountryId(),
111 5
            $request->getPackageValue(),
112
            $weight
113 5
        );
114
115 5
        $methods = $this->removeUnusedParcelSizes($methods, $weight);
116
117 5
        $result = $this->rateResultFactory->create();
118
119 5
        $allowedMethods = $this->getAllowedMethods();
120
121 5
        if (empty($allowedMethods)) {
122 1
            return $result;
123
        }
124
125
        /** @var \Meanbee\RoyalMail\Method $method */
126 4
        foreach ($methods as $method) {
127 2
            if (!array_key_exists($method->getCode(), $allowedMethods)) {
128 1
                continue;
129
            }
130
131
            /** @var Method $rate */
132 1
            $rate = $this->rateMethodFactory->create();
133 1
            $rate->setData('carrier', $this->getCarrierCode());
134 2
            $rate->setData('carrier_title', $this->getConfigData('title'));
135 1
            $rate->setData('method_title', $method->getName());
136 1
            $rate->setData('method', $method->getCode());
137 1
            $rate->setPrice(
138 1
                $this->rounder->round(
139 1
                    $this->getConfigData('rounding_rule'),
0 ignored issues
show
Bug introduced by
It seems like $this->getConfigData('rounding_rule') targeting Magento\Shipping\Model\C...arrier::getConfigData() can also be of type false or null; however, Meanbee\MagentoRoyalmail\Model\Rounder::round() does only seem to accept string, maybe add an additional type check?

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.

Loading history...
140 1
                    $this->getFinalPriceWithHandlingFee($method->getPrice())
141 1
                )
142 1
            );
143 1
            $result->append($rate);
144 4
        }
145
146 4
        return $result;
147
    }
148
149
150
    /**
151
     * Gets the methods selected in the admin area of the extension
152
     * to ensure that not allowed methods can be removed in the collect
153
     * rates method
154
     *
155
     * @return array
156
     */
157 6
    public function getAllowedMethods()
158
    {
159 6
        $configMethods = explode(',', $this->getConfigData('allowed_methods'));
160 6
        $allMethods = $this->getMethods();
161
162 6
        return array_intersect_key($allMethods, array_flip($configMethods));
163
    }
164
    /**
165
     * Gets the clean method names from the royal mail library data
166
     * class. These names link directly to method names, but are used
167
     * to ensure that duplicates are not created as similar names
168
     * exists for multiple methods.
169
     *
170
     * @return array
171
     */
172 7
    public function getMethods()
173
    {
174 7
        return $this->getCarrier()->getAllMethods();
175
    }
176
177
    /**
178
     * @return LibCarrier
179
     */
180 7
    public function getCarrier()
181
    {
182
        /**
183
         * Bug in Magento, when production mode is enabled
184
         * if you're trying to inject an external library, magento won't discover
185
         * the correct dependencies. Even if it is clearly defined in di.xml.
186
         * This odd behaviour results in an instance of ObjectManager being injected.
187
         * Solution is to skip DI, and instantiate yourself.
188
         *
189
         * @TODO Once issue is resolved, we can use the constructor instantiated $carrier object.
190
         * @link https://github.com/magento/magento2/issues/6739
191
         */
192 7
        if (!$this->carrier) {
193
            $this->carrier = new LibCarrier();
194
        }
195
196 7
        return $this->carrier;
197
    }
198
199
    /**
200
     * @deprecated
201
     * @param $libCarrier
202
     * @return $this
203
     */
204 8
    public function setCarrier($libCarrier)
205
    {
206 8
        $this->carrier = $libCarrier;
207 8
        return $this;
208
    }
209
210
    /**
211
     * Get package weight in Kilograms converting from lbs if necessary.
212
     *
213
     * @param $weight
214
     * @param $unit
215
     * @return mixed
216
     */
217 5
    protected function getPackageWeightInKg($weight, $unit)
218
    {
219 5
        if ($unit == 'lbs') {
220 1
            $weight = $weight * 0.453592;
221 1
        }
222
223 5
        return $weight;
224
    }
225
226
    /**
227
     * Both small and medium sized parcels can serve up to 2KG.
228
     * Configuration option determines which size we show to customer.
229
     *
230
     * @param \Meanbee\RoyalMail\Method[] $methods
231
     * @param int $weight
232
     * @return \Meanbee\RoyalMail\Method[]
233
     */
234 5
    protected function removeUnusedParcelSizes($methods, $weight)
235
    {
236 5
        $parcelSize = $this->getConfigData('parcel_size');
237 5
        if ($weight <= 2 && $parcelSize) {
238 1
            foreach ($methods as $key => $method) {
239 1
                if ($method->getSize() && $method->getSize() != $parcelSize) {
240 1
                    unset($methods[$key]);
241 1
                }
242 1
            }
243 1
        }
244
245 5
        return $methods;
246
    }
247
}
248