Shipping   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 314
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 32
c 3
b 0
f 0
lcom 1
cbo 7
dl 0
loc 314
rs 9.6

21 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 2
A quotations() 0 13 3
A firstQuotation() 0 13 2
A getCosts() 0 4 1
A getDeadline() 0 4 1
A getAttributes() 0 4 1
A setPostalCodeOrigin() 0 4 1
A setPostalCodeDestination() 0 4 1
A setTotalPrice() 0 6 1
A setAdditionalPrice() 0 6 1
B calculateAdditionalPrice() 0 17 5
A getTotalPrice() 0 4 1
A getAdditionalPrice() 0 4 1
A setAdditionalDays() 0 4 1
A addVolume() 0 4 1
A allVolumes() 0 4 1
A clearVolumes() 0 4 1
A isValid() 0 10 4
A newRequest() 0 4 1
A toJson() 0 6 1
A getPostalCodeDestination() 0 4 1
1
<?php
2
namespace Axado;
3
4
use Axado\Exception\QuotationNotFoundException;
5
use Axado\Exception\ShippingException;
6
use Axado\Formatter\FormatterInterface;
7
use Axado\Formatter\JsonFormatter;
8
use Axado\Volume\VolumeInterface;
9
10
class Shipping
11
{
12
    /**
13
     * Requires fields in Shipping.
14
     *
15
     * @var array
16
     */
17
    public static $requiredFields = [
18
        'cep_origem',
19
        'cep_destino',
20
        'valor_notafiscal',
21
    ];
22
23
    /**
24
     * Token string to Axado.
25
     *
26
     * @var string
27
     */
28
    public static $token;
29
30
    /**
31
     * All attributes.
32
     *
33
     * @var array
34
     */
35
    protected $attributes = [];
36
37
    /**
38
     * All volumes objects.
39
     *
40
     * @var array
41
     */
42
    protected $volumes = [];
43
44
    /**
45
     * FormatterInterface instance.
46
     *
47
     * @var FormatterInterface
48
     */
49
    protected $formatter;
50
51
    /**
52
     * Axado\Request instance.
53
     *
54
     * @var Request
55
     */
56
    protected $request;
57
58
    /**
59
     * Axado\Response instance.
60
     *
61
     * @var Response
62
     */
63
    protected $response;
64
65
    /**
66
     * Constructor.
67
     *
68
     * @param \Axado\Formatter\FormatterInterface $formatter
69
     */
70
    public function __construct(FormatterInterface $formatter = null)
71
    {
72
        $this->formatter = $formatter ?: new JsonFormatter();
73
    }
74
75
    /**
76
     * Consult this shipping through api.
77
     *
78
     * @throws ShippingException
79
     *
80
     * @return array
81
     */
82
    public function quotations()
83
    {
84
        if (!$this->isValid()) {
85
            throw new ShippingException('This shipping was not filled correctly');
86
        }
87
88
        if (!$this->response) {
89
            $request = $this->newRequest(static::$token);
90
            $this->response = $request->consultShipping($this->toJson());
91
        }
92
93
        return $this->response->quotations();
94
    }
95
96
    /**
97
     * Returns the first quotation.
98
     *
99
     * @throws QuotationNotFoundException
100
     *
101
     * @return Quotation
102
     */
103
    public function firstQuotation(): Quotation
104
    {
105
        if (!$quotation = $this->quotations()[0] ?? null) {
106
            throw new QuotationNotFoundException(
107
                sprintf(
108
                    'No quotations were found to the given CEP: %s',
109
                    $this->getPostalCodeDestination()
110
                )
111
            );
112
        }
113
114
        return $quotation;
115
    }
116
117
    /**
118
     * Get the first quotation and return the price.
119
     *
120
     * @return string|null
121
     */
122
    public function getCosts()
123
    {
124
        return $this->firstQuotation()->getCosts();
125
    }
126
127
    /**
128
     * Get the first quotation and return the price.
129
     *
130
     * @return string|null
131
     */
132
    public function getDeadline()
133
    {
134
        return $this->firstQuotation()->getDeadline();
135
    }
136
137
    /**
138
     * Return the attributes.
139
     *
140
     * @return array
141
     */
142
    public function getAttributes(): array
143
    {
144
        return $this->attributes;
145
    }
146
147
    /**
148
     * Setter to Postal Code origin.
149
     *
150
     * @param string $cep
151
     */
152
    public function setPostalCodeOrigin($cep)
153
    {
154
        $this->attributes['cep_origem'] = (string) $cep;
155
    }
156
157
    /**
158
     * Setter to Postal Code destination.
159
     *
160
     * @param string $cep
161
     */
162
    public function setPostalCodeDestination($cep)
163
    {
164
        $this->attributes['cep_destino'] = (string) $cep;
165
    }
166
167
    /**
168
     * Setter to Total price of sale.
169
     *
170
     * @param float $price
171
     */
172
    public function setTotalPrice($price)
173
    {
174
        $this->attributes['valor_notafiscal'] = (float) $price;
175
176
        $this->setAdditionalPrice($this->getAdditionalPrice());
177
    }
178
179
    /**
180
     * Setter to Additional price to add to shipping costs.
181
     *
182
     * @param float $price
183
     */
184
    public function setAdditionalPrice($price)
185
    {
186
        $additionalPrice = $this->calculateAdditionalPrice($price);
187
188
        $this->attributes['preco_adicional'] = $additionalPrice;
189
    }
190
191
    /**
192
     * Calculate the additional price.
193
     *
194
     * @param string $price
195
     *
196
     * @return float
197
     */
198
    public function calculateAdditionalPrice($price)
199
    {
200
        $tempPrice = $price;
201
        $totalPrice = $this->getTotalPrice();
202
203
        if (preg_match('/%/', $price) && (float) $price && $totalPrice) {
204
            if ($price = (float) $price) {
205
                $price = $totalPrice * $price / 100;
206
            } else {
207
                $price = $tempPrice;
208
            }
209
        } else {
210
            $price = $tempPrice;
211
        }
212
213
        return $price;
214
    }
215
216
    /**
217
     * Getter to Total price of sale.
218
     *
219
     * @return float|null
220
     */
221
    public function getTotalPrice()
222
    {
223
        return $this->attributes['valor_notafiscal'] ?? null;
224
    }
225
226
    /**
227
     * Getter to of Additional price.
228
     *
229
     * @return float|null
230
     */
231
    public function getAdditionalPrice()
232
    {
233
        return $this->attributes['preco_adicional'] ?? null;
234
    }
235
236
    /**
237
     * Setter to additional days.
238
     *
239
     * @param int $days
240
     */
241
    public function setAdditionalDays($days)
242
    {
243
        $this->attributes['prazo_adicional'] = (int) $days;
244
    }
245
246
    /**
247
     * Add a volume object to send through Axado api.
248
     *
249
     * @param VolumeInterface $volume
250
     */
251
    public function addVolume(VolumeInterface $volume)
252
    {
253
        $this->volumes[] = $volume;
254
    }
255
256
    /**
257
     * Return all volumes at this instance.
258
     *
259
     * @return array
260
     */
261
    public function allVolumes(): array
262
    {
263
        return $this->volumes;
264
    }
265
266
    /**
267
     * Clean all volumes.
268
     */
269
    public function clearVolumes()
270
    {
271
        $this->volumes = [];
272
    }
273
274
    /**
275
     * Verify is this instance is Valid.
276
     *
277
     * @return bool
278
     */
279
    protected function isValid(): bool
280
    {
281
        foreach (static::$requiredFields as $field) {
282
            if (!isset($this->attributes[$field]) || !$this->attributes[$field]) {
283
                return false;
284
            }
285
        }
286
287
        return (bool) $this->volumes;
288
    }
289
290
    /**
291
     * Returns a new instance of Request.
292
     *
293
     * @param string $token
294
     *
295
     * @return Request
296
     */
297
    protected function newRequest(string $token): Request
298
    {
299
        return new Request($token);
300
    }
301
302
    /**
303
     * Return this object in json format.
304
     *
305
     * @return string
306
     */
307
    protected function toJson(): string
308
    {
309
        $this->formatter->setInstance($this);
310
311
        return $this->formatter->format();
312
    }
313
314
    /**
315
     * Getter of postal code destination.
316
     *
317
     * @return string|null
318
     */
319
    protected function getPostalCodeDestination()
320
    {
321
        return $this->attributes['cep_destino'] ?? null;
322
    }
323
}
324