Completed
Push — master ( 047014...cb17ac )
by Tomáš
04:02
created

Client::trackPackagesLastStatus()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 32

Duplication

Lines 3
Ratio 9.38 %

Code Coverage

Tests 16
CRAP Score 6

Importance

Changes 0
Metric Value
dl 3
loc 32
c 0
b 0
f 0
rs 8.7857
ccs 16
cts 16
cp 1
cc 6
nc 5
nop 2
crap 6
1
<?php
2
3
namespace Inspirum\Balikobot\Services;
4
5
use DateTime;
6
use Inspirum\Balikobot\Contracts\RequesterInterface;
7
use Inspirum\Balikobot\Definitions\API;
8
use Inspirum\Balikobot\Definitions\Country;
9
use Inspirum\Balikobot\Definitions\Request;
10
use Inspirum\Balikobot\Exceptions\BadRequestException;
11
12
class Client
13
{
14
    /**
15
     * API requester
16
     *
17
     * @var \Inspirum\Balikobot\Contracts\RequesterInterface
18
     */
19
    private $requester;
20
21
    /**
22
     * Balikobot API client
23
     *
24
     * @param \Inspirum\Balikobot\Contracts\RequesterInterface $requester
25
     */
26 225
    public function __construct(RequesterInterface $requester)
27
    {
28 225
        $this->requester = $requester;
29 225
    }
30
31
    /**
32
     * Add package(s) to the Balikobot
33
     *
34
     * @param string $shipper
35
     * @param array  $packages
36
     * @param string $version
37
     *
38
     * @return array[]
39
     *
40
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
41
     */
42 21 View Code Duplication
    public function addPackages(string $shipper, array $packages, string $version = API::V1): array
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
43
    {
44 21
        $response = $this->requester->call($version, $shipper, Request::ADD, $packages);
45
46 12
        if (isset($response[0]['package_id']) === false) {
47 1
            throw new BadRequestException($response);
48
        }
49
50 11
        unset($response['labels_url']);
51 11
        unset($response['status']);
52
53 11
        return $response;
54
    }
55
56
    /**
57
     * Drops a package from the Balikobot – the package must be not ordered
58
     *
59
     * @param string $shipper
60
     * @param int    $packageId
61
     *
62
     * @return void
63
     *
64
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
65
     */
66 2
    public function dropPackage(string $shipper, int $packageId): void
67
    {
68 2
        $this->dropPackages($shipper, [$packageId]);
69 2
    }
70
71
    /**
72
     * Drops a package from the Balikobot – the package must be not ordered
73
     *
74
     * @param string $shipper
75
     * @param array  $packageIds
76
     *
77
     * @return void
78
     *
79
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
80
     */
81 7
    public function dropPackages(string $shipper, array $packageIds): void
82
    {
83 7
        $data = $this->encapsulateIds($packageIds);
84
85 7
        if (count($data) === 0) {
86 1
            return;
87
        }
88
89 6
        $this->requester->call(API::V1, $shipper, Request::DROP, $data);
90 3
    }
91
92
    /**
93
     * Tracks a package
94
     *
95
     * @param string $shipper
96
     * @param string $carrierId
97
     *
98
     * @return array[]
99
     *
100
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
101
     */
102 6
    public function trackPackage(string $shipper, string $carrierId): array
103
    {
104 6
        $response = $this->trackPackages($shipper, [$carrierId]);
105
106 3
        return $response[0];
107
    }
108
109
    /**
110
     * Tracks a packages
111
     *
112
     * @param string $shipper
113
     * @param array  $carrierIds
114
     *
115
     * @return array[]
116
     *
117
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
118
     */
119 16
    public function trackPackages(string $shipper, array $carrierIds): array
120
    {
121 16
        $data = $this->encapsulateIds($carrierIds);
122
123 16
        $response = $this->requester->call(API::V2, $shipper, Request::TRACK, $data, false);
124
125 12
        if (empty($response[0])) {
126 2
            throw new BadRequestException($response);
127
        }
128
129 10
        unset($response['status']);
130
131 10
        if (count($response) !== count($carrierIds)) {
132 1
            throw new BadRequestException($response);
133
        }
134
135 9
        return $response;
136
    }
137
138
    /**
139
     * Tracks a package, get the last info
140
     *
141
     * @param string $shipper
142
     * @param string $carrierId
143
     *
144
     * @return array
145
     *
146
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
147
     */
148 7
    public function trackPackageLastStatus(string $shipper, string $carrierId): array
149
    {
150 7
        $response = $this->trackPackagesLastStatus($shipper, [$carrierId]);
151
152 3
        return $response[0];
153
    }
154
155
    /**
156
     * Tracks a package, get the last info
157
     *
158
     * @param string $shipper
159
     * @param array  $carrierIds
160
     *
161
     * @return array[]
162
     *
163
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
164
     */
165 19
    public function trackPackagesLastStatus(string $shipper, array $carrierIds): array
166
    {
167 19
        $data = $this->encapsulateIds($carrierIds);
168
169 19
        $response = $this->requester->call(API::V1, $shipper, Request::TRACK_STATUS, $data, false);
170
171 15
        if (empty($response[0])) {
172 2
            throw new BadRequestException($response);
173
        }
174
175 13
        unset($response['status']);
176
177 13
        if (count($response) !== count($carrierIds)) {
178 1
            throw new BadRequestException($response);
179
        }
180
181 12
        $formatedStatuses = [];
182
183 12
        foreach ($response as $statusResponse) {
184 12 View Code Duplication
            if (isset($statusResponse['status']) && ((int) $statusResponse['status']) !== 200) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
185 2
                throw new BadRequestException($response);
186
            }
187
188 11
            $formatedStatuses[] = [
189 11
                'name'      => $statusResponse['status_text'],
190 11
                'status_id' => $statusResponse['status_id'],
191
                'date'      => null,
192
            ];
193
        }
194
195 10
        return $formatedStatuses;
196
    }
197
198
    /**
199
     * Returns packages from the front (not ordered) for given shipper
200
     *
201
     * @param string $shipper
202
     *
203
     * @return array[]
204
     *
205
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
206
     */
207 6
    public function getOverview(string $shipper): array
208
    {
209 6
        $response = $this->requester->call(API::V1, $shipper, Request::OVERVIEW, [], false);
210
211 4
        return $response;
212
    }
213
214
    /**
215
     * Gets labels
216
     *
217
     * @param string $shipper
218
     * @param array  $packageIds
219
     *
220
     * @return string
221
     *
222
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
223
     */
224 7
    public function getLabels(string $shipper, array $packageIds): string
225
    {
226
        $data = [
227 7
            'package_ids' => $packageIds,
228
        ];
229
230 7
        $response = $this->requester->call(API::V1, $shipper, Request::LABELS, $data);
231
232 4
        return $response['labels_url'];
233
    }
234
235
    /**
236
     * Gets complete information about a package
237
     *
238
     * @param string $shipper
239
     * @param int    $packageId
240
     *
241
     * @return array
242
     *
243
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
244
     */
245 6
    public function getPackageInfo(string $shipper, int $packageId): array
246
    {
247 6
        $response = $this->requester->call(API::V1, $shipper, Request::PACKAGE . '/' . $packageId, [], false);
248
249 4
        return $response;
250
    }
251
252
    /**
253
     * Order shipment for packages
254
     *
255
     * @param string         $shipper
256
     * @param array          $packageIds
257
     * @param \DateTime|null $date
258
     * @param string|null    $note
259
     *
260
     * @return array
261
     *
262
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
263
     */
264 7
    public function orderShipment(string $shipper, array $packageIds, DateTime $date = null, string $note = null): array
265
    {
266
        $data = [
267 7
            'package_ids' => $packageIds,
268 7
            'date'        => $date ? $date->format('Y-m-d') : null,
269 7
            'note'        => $note,
270
        ];
271
272 7
        $response = $this->requester->call(API::V1, $shipper, Request::ORDER, $data);
273
274 4
        unset($response['status']);
275
276 4
        return $response;
277
    }
278
279
    /**
280
     * Get order details
281
     *
282
     * @param string $shipper
283
     * @param int    $orderId
284
     *
285
     * @return array
286
     *
287
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
288
     */
289 7 View Code Duplication
    public function getOrder(string $shipper, int $orderId): array
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
290
    {
291 7
        $response = $this->requester->call(API::V1, $shipper, Request::ORDER_VIEW . '/' . $orderId, [], false);
292
293 5
        unset($response['status']);
294
295 5
        return $response;
296
    }
297
298
    /**
299
     * Order pickup for packages
300
     *
301
     * @param string      $shipper
302
     * @param \DateTime   $dateFrom
303
     * @param \DateTime   $dateTo
304
     * @param float       $weight
305
     * @param int         $packageCount
306
     * @param string|null $message
307
     *
308
     * @return void
309
     *
310
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
311
     */
312 4
    public function orderPickup(
313
        string $shipper,
314
        DateTime $dateFrom,
315
        DateTime $dateTo,
316
        float $weight,
317
        int $packageCount,
318
        string $message = null
319
    ): void {
320
        $data = [
321 4
            'date'          => $dateFrom->format('Y-m-d'),
322 4
            'time_from'     => $dateFrom->format('H:s'),
323 4
            'time_to'       => $dateTo->format('H:s'),
324 4
            'weight'        => $weight,
325 4
            'package_count' => $packageCount,
326 4
            'message'       => $message,
327
        ];
328
329 4
        $this->requester->call(API::V1, $shipper, Request::ORDER_PICKUP, $data);
330 1
    }
331
332
    /**
333
     * Returns available services for the given shipper
334
     *
335
     * @param string $shipper
336
     *
337
     * @return string[]
338
     *
339
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
340
     */
341 10
    public function getServices(string $shipper): array
342
    {
343 10
        $response = $this->requester->call(API::V1, $shipper, Request::SERVICES);
344
345 6
        if (isset($response['service_types']) === false) {
346 3
            return [];
347
        }
348
349 3
        return $response['service_types'];
350
    }
351
352
    /**
353
     * Returns available manipulation units for the given shipper
354
     *
355
     * @param string $shipper
356
     *
357
     * @return string[]
358
     *
359
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
360
     */
361 8 View Code Duplication
    public function getManipulationUnits(string $shipper): array
362
    {
363 8
        $response = $this->requester->call(API::V1, $shipper, Request::MANIPULATION_UNITS);
364
365 5
        if ($response['units'] === null) {
366 1
            return [];
367
        }
368
369 4
        $units = [];
370
371 4
        foreach ($response['units'] as $item) {
372 2
            $units[$item['code']] = $item['name'];
373
        }
374
375 4
        return $units;
376
    }
377
378
    /**
379
     * Returns available branches for the given shipper and its service
380
     * Full branches instead branches request
381
     *
382
     * @param string $shipper
383
     * @param string $service
384
     * @param bool   $fullData
385
     * @param string $country
386
     *
387
     * @return array[]
388
     *
389
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
390
     */
391 13
    public function getBranches(string $shipper, string $service = null, bool $fullData = false, string $country = null): array
392
    {
393 13
        $request = $fullData ? Request::FULL_BRANCHES : Request::BRANCHES;
394
395 13
        $response = $this->requester->call(API::V1, $shipper, $request . '/' . $service . '/' . $country);
396
397 10
        if ($response['branches'] === null) {
398 1
            return [];
399
        }
400
401 9
        return $response['branches'];
402
    }
403
404
    /**
405
     * Returns available branches for the given shipper in given location
406
     *
407
     * @param string      $shipper
408
     * @param string      $country
409
     * @param string      $city
410
     * @param string|null $postcode
411
     * @param string|null $street
412
     * @param int|null    $maxResults
413
     * @param float|null  $radius
414
     * @param string|null $type
415
     *
416
     * @return array[]
417
     *
418
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
419
     */
420 9
    public function getBranchesForLocation(
421
        string $shipper,
422
        string $country,
423
        string $city,
424
        string $postcode = null,
425
        string $street = null,
426
        int $maxResults = null,
427
        float $radius = null,
428
        string $type = null
429
    ): array {
430 9
        Country::validateCode($country);
431
432
        $data = [
433 9
            'country'     => $country,
434 9
            'city'        => $city,
435 9
            'zip'         => $postcode,
436 9
            'street'      => $street,
437 9
            'max_results' => $maxResults,
438 9
            'radius'      => $radius,
439 9
            'type'        => $type,
440
        ];
441
442 9
        $data = array_filter($data);
443
444 9
        $response = $this->requester->call(API::V1, $shipper, Request::BRANCH_LOCATOR, $data);
445
446 6
        if ($response['branches'] === null) {
447 1
            return [];
448
        }
449
450 5
        return $response['branches'];
451
    }
452
453
    /**
454
     * Returns list of countries where service with cash-on-delivery payment type is available in
455
     *
456
     * @param string $shipper
457
     *
458
     * @return array[]
459
     *
460
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
461
     */
462 8 View Code Duplication
    public function getCodCountries(string $shipper): array
463
    {
464 8
        $response = $this->requester->call(API::V1, $shipper, Request::CASH_ON_DELIVERY_COUNTRIES);
465
466 5
        if ($response['service_types'] === null) {
467 1
            return [];
468
        }
469
470 4
        $services = [];
471
472 4
        foreach ($response['service_types'] as $item) {
473 2
            $services[$item['service_type']] = $item['cod_countries'];
474
        }
475
476 4
        return $services;
477
    }
478
479
    /**
480
     * Returns list of countries where service is available in
481
     *
482
     * @param string $shipper
483
     *
484
     * @return array[]
485
     *
486
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
487
     */
488 8 View Code Duplication
    public function getCountries(string $shipper): array
489
    {
490 8
        $response = $this->requester->call(API::V1, $shipper, Request::COUNTRIES);
491
492 5
        if ($response['service_types'] === null) {
493 1
            return [];
494
        }
495
496 4
        $services = [];
497
498 4
        foreach ($response['service_types'] as $item) {
499 2
            $services[$item['service_type']] = $item['countries'];
500
        }
501
502 4
        return $services;
503
    }
504
505
    /**
506
     * Returns available branches for the given shipper and its service
507
     *
508
     * @param string      $shipper
509
     * @param string      $service
510
     * @param string|null $country
511
     *
512
     * @return array[]
513
     *
514
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
515
     */
516 12
    public function getPostCodes(string $shipper, string $service, string $country = null): array
517
    {
518 12
        if ($country !== null) {
519 1
            Country::validateCode($country);
520
521 1
            $urlPath = $service . '/' . $country;
522
        } else {
523 11
            $urlPath = $service;
524
        }
525
526 12
        $response = $this->requester->call(API::V1, $shipper, Request::ZIP_CODES . '/' . $urlPath);
527
528 9
        if ($response['zip_codes'] === null) {
529 1
            return [];
530
        }
531
532 8
        $country            = $response['country'] ?? $country;
533 8
        $formattedPostCodes = [];
534
535 8
        foreach ($response['zip_codes'] as $postCode) {
536 5
            $formattedPostCodes[] = [
537 5
                'postcode'     => $postCode['zip'] ?? ($postCode['zip_start'] ?? null),
538 5
                'postcode_end' => $postCode['zip_end'] ?? null,
539 5
                'city'         => $postCode['city'] ?? null,
540 5
                'country'      => $postCode['country'] ?? $country,
541 5
                '1B'           => (bool) ($postCode['1B'] ?? false),
542
            ];
543
        }
544
545 8
        return $formattedPostCodes;
546
    }
547
548
    /**
549
     * Check package(s) data
550
     *
551
     * @param string $shipper
552
     * @param array  $packages
553
     *
554
     * @return void
555
     *
556
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
557
     */
558 5
    public function checkPackages(string $shipper, array $packages): void
559
    {
560 5
        $this->requester->call(API::V1, $shipper, Request::CHECK, $packages);
561 2
    }
562
563
    /**
564
     * Returns available manipulation units for the given shipper
565
     *
566
     * @param string $shipper
567
     *
568
     * @return string[]
569
     *
570
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
571
     */
572 8 View Code Duplication
    public function getAdrUnits(string $shipper): array
573
    {
574 8
        $response = $this->requester->call(API::V1, $shipper, Request::ADR_UNITS);
575
576 5
        if ($response['units'] === null) {
577 1
            return [];
578
        }
579
580 4
        $units = [];
581
582 4
        foreach ($response['units'] as $item) {
583 2
            $units[$item['code']] = $item['name'];
584
        }
585
586 4
        return $units;
587
    }
588
589
    /**
590
     * Returns available activated services for the given shipper
591
     *
592
     * @param string $shipper
593
     *
594
     * @return array
595
     *
596
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
597
     */
598 6 View Code Duplication
    public function getActivatedServices(string $shipper): array
1 ignored issue
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
599
    {
600 6
        $response = $this->requester->call(API::V1, $shipper, Request::ACTIVATEDSERVICES);
601
602 4
        unset($response['status']);
603
604 4
        return $response;
605
    }
606
607
    /**
608
     * Order shipments from place B (typically supplier / previous consignee) to place A (shipping point)
609
     *
610
     * @param string $shipper
611
     * @param array  $packages
612
     *
613
     * @return array
614
     *
615
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
616
     */
617 9 View Code Duplication
    public function orderB2AShipment(string $shipper, array $packages): array
618
    {
619 9
        $response = $this->requester->call(API::V1, $shipper, Request::B2A, $packages);
620
621 6
        if (isset($response[0]['package_id']) === false) {
622 1
            throw new BadRequestException($response);
623
        }
624
625 5
        unset($response['status']);
626
627 5
        return $response;
628
    }
629
630
    /**
631
     * Get PDF link with signed consignment delivery document by the recipient
632
     *
633
     * @param string $shipper
634
     * @param string $carrierId
635
     *
636
     * @return string
637
     *
638
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
639
     */
640 7
    public function getProofOfDelivery(string $shipper, string $carrierId): string
641
    {
642 7
        $response = $this->getProofOfDeliveries($shipper, [$carrierId]);
643
644 3
        return $response[0];
645
    }
646
647
    /**
648
     * Get array of PDF links with signed consignment delivery document by the recipient
649
     *
650
     * @param string $shipper
651
     * @param array  $carrierIds
652
     *
653
     * @return string[]
654
     *
655
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
656
     */
657 19
    public function getProofOfDeliveries(string $shipper, array $carrierIds): array
658
    {
659 19
        $data = $this->encapsulateIds($carrierIds);
660
661 19
        $response = $this->requester->call(API::V1, $shipper, Request::PROOF_OF_DELIVERY, $data, false);
662
663 15
        if (empty($response[0])) {
664 3
            throw new BadRequestException($response);
665
        }
666
667 12
        unset($response['status']);
668
669 12
        if (count($response) !== count($carrierIds)) {
670 1
            throw new BadRequestException($response);
671
        }
672
673 11
        $formatedLinks = [];
674
675 11
        foreach ($response as $statusResponse) {
676 11 View Code Duplication
            if (isset($statusResponse['status']) && ((int) $statusResponse['status']) !== 200) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
677 1
                throw new BadRequestException($response);
678
            }
679
680 11
            $formatedLinks[] = $statusResponse['file_url'];
681
        }
682
683 10
        return $formatedLinks;
684
    }
685
686
    /**
687
     * Encapsulate ids
688
     *
689
     * @param array $ids
690
     *
691
     * @return array[]
692
     */
693 61
    private function encapsulateIds(array $ids): array
694
    {
695
        return array_map(function ($carrierId) {
696
            return [
697 60
                'id' => $carrierId,
698
            ];
699 61
        }, $ids);
700
    }
701
}
702