Completed
Push — develop ( 678cfb...783309 )
by Ravan
01:18
created

Shipping::getElectedQuotation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
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
     * Quotation used.
39
     *
40
     * @var Quotation
41
     */
42
    protected $electedQuotation;
43
44
    /**
45
     * Quotation string.
46
     *
47
     * @var string
48
     */
49
    protected $quotationToken;
50
51
    /**
52
     * All volumes objects.
53
     *
54
     * @var array
55
     */
56
    protected $volumes = [];
57
58
    /**
59
     * FormatterInterface instance.
60
     *
61
     * @var FormatterInterface
62
     */
63
    protected $formatter;
64
65
    /**
66
     * Axado\Request instance.
67
     *
68
     * @var Request
69
     */
70
    protected $request;
71
72
    /**
73
     * Axado\Response instance.
74
     *
75
     * @var Response
76
     */
77
    protected $response;
78
79
    /**
80
     * Constructor
81
     *
82
     * @param \Axado\Formatter\FormatterInterface $formatter
83
     */
84
    public function __construct(FormatterInterface $formatter = null)
85
    {
86
        $this->formatter = $formatter ?: new JsonFormatter();
87
    }
88
89
    /**
90
     * Get the first quotation and return the price.
91
     *
92
     * @return int|null
93
     */
94
    public function getCosts()
95
    {
96
        if ($quotation = $this->firstQuotation()) {
97
            return $quotation->getCosts();
98
        }
99
100
        return null;
101
    }
102
103
    /**
104
     * Returns the first quotation.
105
     *
106
     * @throws QuotationNotFoundException
107
     *
108
     * @return Quotation
109
     */
110
    public function firstQuotation(): Quotation
111
    {
112
        $quotations = (array) $this->quotations();
113
114
        if (!isset($quotations[0])) {
115
            throw new QuotationNotFoundException(
116
                sprintf(
117
                    'No quotations were found to the given CEP: %s',
118
                    $this->getPostalCodeDestination()
119
                )
120
            );
121
        }
122
123
        $this->electedQuotation = $quotations[0];
124
125
        return $quotations[0];
126
    }
127
128
    /**
129
     * Consult this shipping through api.
130
     *
131
     * @throws ShippingException
132
     *
133
     * @return array
134
     */
135
    public function quotations()
136
    {
137
        if (! $this->isValid()) {
138
            throw new ShippingException(
139
                'This shipping was not filled correctly',
140
                1
141
            );
142
        }
143
144
        if (! $this->response) {
145
            $request = $this->newRequest(static::$token);
146
            $this->response = $request->consultShipping($this->toJson());
147
            $this->quotationToken = $this->response->getQuotationToken();
148
        }
149
150
        return $this->response->quotations();
151
    }
152
153
    /**
154
     * Verify is this instance is Valid.
155
     *
156
     * @return bool
157
     */
158
    protected function isValid(): bool
159
    {
160
        foreach (static::$requiredFields as $field) {
161
            if (! isset($this->attributes[$field]) || ! $this->attributes[$field]) {
162
                return false;
163
            }
164
        }
165
166
        return (bool) $this->volumes;
167
    }
168
169
    /**
170
     * Returns a new instance of Request.
171
     *
172
     * @param string $token
173
     *
174
     * @return Request
175
     */
176
    protected function newRequest(string $token): Request
177
    {
178
        return new Request($token);
179
    }
180
181
    /**
182
     * Return this object in json format.
183
     *
184
     * @return string
185
     */
186
    protected function toJson(): string
187
    {
188
        $this->formatter->setInstance($this);
189
190
        return $this->formatter->format();
191
    }
192
193
    /**
194
     * Getter of postal code destination
195
     *
196
     * @return string|null
197
     */
198
    protected function getPostalCodeDestination()
199
    {
200
        return $this->attributes['cep_destino'] ?? null;
201
    }
202
203
    /**
204
     * Get the first quotation and return the price.
205
     *
206
     * @return int
207
     */
208
    public function getDeadline()
209
    {
210
        if ($quotation = $this->firstQuotation()) {
211
            return $quotation->getDeadline();
212
        }
213
214
        return null;
215
    }
216
217
    /**
218
     * Marking this shipping quotation as contracted to Axado API.
219
     */
220
    public function flagAsContracted()
221
    {
222
        $request = $this->newRequest(static::$token);
223
        $token = $this->quotationToken;
224
225
        $request->flagAsContracted($this, $token);
226
    }
227
228
    /**
229
     * Getter for quotation elected.
230
     *
231
     * @return Quotation
232
     */
233
    public function getElectedQuotation()
234
    {
235
        return $this->electedQuotation;
236
    }
237
238
    /**
239
     * Return the attributes.
240
     *
241
     * @return array
242
     */
243
    public function getAttributes(): array
244
    {
245
        return $this->attributes;
246
    }
247
248
    /**
249
     * Setter to Postal Code origin.
250
     *
251
     * @param string $cep
252
     */
253
    public function setPostalCodeOrigin($cep)
254
    {
255
        $this->attributes['cep_origem'] = (string) $cep;
256
    }
257
258
    /**
259
     * Setter to Postal Code destination.
260
     *
261
     * @param string $cep
262
     */
263
    public function setPostalCodeDestination($cep)
264
    {
265
        $this->attributes['cep_destino'] = (string) $cep;
266
    }
267
268
    /**
269
     * Setter to Total price of sale.
270
     *
271
     * @param float $price
272
     */
273
    public function setTotalPrice($price)
274
    {
275
        $this->attributes['valor_notafiscal'] = (float) $price;
276
277
        $this->setAdditionalPrice($this->getAdditionalPrice());
278
    }
279
280
    /**
281
     * Setter to Additional price to add to shipping costs.
282
     *
283
     * @param float $price
284
     */
285
    public function setAdditionalPrice($price)
286
    {
287
        $additionalPrice = $this->calculateAdditionalPrice($price);
288
289
        $this->attributes['preco_adicional'] = $additionalPrice;
290
    }
291
292
    /**
293
     * Calculate the additional price.
294
     *
295
     * @param  string $price
296
     *
297
     * @return float
298
     */
299
    public function calculateAdditionalPrice($price)
300
    {
301
        $tempPrice = $price;
302
        $totalPrice = $this->getTotalPrice();
303
304
        if (preg_match('/%/', $price) && (float) $price && $totalPrice) {
305
            if ($price = (float) $price) {
306
                $price = $totalPrice * $price / 100;
307
            } else {
308
                $price = $tempPrice;
309
            }
310
        } else {
311
            $price = $tempPrice;
312
        }
313
314
        return $price;
315
    }
316
317
    /**
318
     * Getter to Total price of sale.
319
     *
320
     * @return float|null
321
     */
322
    public function getTotalPrice()
323
    {
324
        return $this->attributes['valor_notafiscal'] ?? null;
325
    }
326
327
    /**
328
     * Getter to of Additional price.
329
     *
330
     * @return float|null
331
     */
332
    public function getAdditionalPrice()
333
    {
334
        return $this->attributes['preco_adicional'] ?? null;
335
    }
336
337
    /**
338
     * Setter to additional days.
339
     *
340
     * @param int $days
341
     */
342
    public function setAdditionalDays($days)
343
    {
344
        $this->attributes['prazo_adicional'] = (int) $days;
345
    }
346
347
    /**
348
     * Add a volume object to send through Axado api.
349
     *
350
     * @param VolumeInterface $volume
351
     */
352
    public function addVolume(VolumeInterface $volume)
353
    {
354
        $this->volumes[] = $volume;
355
    }
356
357
    /**
358
     * Return all volumes at this instance.
359
     *
360
     * @return array
361
     */
362
    public function allVolumes(): array
363
    {
364
        return $this->volumes;
365
    }
366
367
    /**
368
     * Clean all volumes.
369
     */
370
    public function clearVolumes()
371
    {
372
        $this->volumes = [];
373
    }
374
}
375