Completed
Push — master ( e49075...eb8c45 )
by Tomáš
01:46
created

Client::getProofOfDeliveries()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 24

Duplication

Lines 3
Ratio 12.5 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
dl 3
loc 24
ccs 12
cts 12
cp 1
rs 9.2248
c 0
b 0
f 0
cc 5
nc 4
nop 2
crap 5
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
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
        unset($response['status']);
172
173 15
        if (count($response) !== count($carrierIds)) {
174 3
            throw new BadRequestException($response);
175
        }
176
177 12
        $formatedStatuses = [];
178
179 12
        foreach ($response as $statusResponse) {
180 12 View Code Duplication
            if (isset($statusResponse['status']) && ((int) $statusResponse['status']) !== 200) {
181 2
                throw new BadRequestException($response);
182
            }
183
184 11
            $formatedStatuses[] = [
185 11
                'name'      => $statusResponse['status_text'],
186 11
                'status_id' => $statusResponse['status_id'],
187
                'date'      => null,
188
            ];
189
        }
190
191 10
        return $formatedStatuses;
192
    }
193
194
    /**
195
     * Returns packages from the front (not ordered) for given shipper
196
     *
197
     * @param string $shipper
198
     *
199
     * @return array[]
200
     *
201
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
202
     */
203 6
    public function getOverview(string $shipper): array
204
    {
205 6
        $response = $this->requester->call(API::V1, $shipper, Request::OVERVIEW, [], false);
206
207 4
        return $response;
208
    }
209
210
    /**
211
     * Gets labels
212
     *
213
     * @param string $shipper
214
     * @param array  $packageIds
215
     *
216
     * @return string
217
     *
218
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
219
     */
220 7
    public function getLabels(string $shipper, array $packageIds): string
221
    {
222
        $data = [
223 7
            'package_ids' => $packageIds,
224
        ];
225
226 7
        $response = $this->requester->call(API::V1, $shipper, Request::LABELS, $data);
227
228 4
        return $response['labels_url'];
229
    }
230
231
    /**
232
     * Gets complete information about a package
233
     *
234
     * @param string $shipper
235
     * @param int    $packageId
236
     *
237
     * @return array
238
     *
239
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
240
     */
241 6
    public function getPackageInfo(string $shipper, int $packageId): array
242
    {
243 6
        $response = $this->requester->call(API::V1, $shipper, Request::PACKAGE . '/' . $packageId, [], false);
244
245 4
        return $response;
246
    }
247
248
    /**
249
     * Order shipment for packages
250
     *
251
     * @param string         $shipper
252
     * @param array          $packageIds
253
     * @param \DateTime|null $date
254
     * @param string|null    $note
255
     *
256
     * @return array
257
     *
258
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
259
     */
260 7
    public function orderShipment(string $shipper, array $packageIds, DateTime $date = null, string $note = null): array
261
    {
262
        $data = [
263 7
            'package_ids' => $packageIds,
264 7
            'date'        => $date ? $date->format('Y-m-d') : null,
265 7
            'note'        => $note,
266
        ];
267
268 7
        $response = $this->requester->call(API::V1, $shipper, Request::ORDER, $data);
269
270 4
        unset($response['status']);
271
272 4
        return $response;
273
    }
274
275
    /**
276
     * Get order details
277
     *
278
     * @param string $shipper
279
     * @param int    $orderId
280
     *
281
     * @return array
282
     *
283
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
284
     */
285 7 View Code Duplication
    public function getOrder(string $shipper, int $orderId): array
286
    {
287 7
        $response = $this->requester->call(API::V1, $shipper, Request::ORDER_VIEW . '/' . $orderId, [], false);
288
289 5
        unset($response['status']);
290
291 5
        return $response;
292
    }
293
294
    /**
295
     * Order pickup for packages
296
     *
297
     * @param string      $shipper
298
     * @param \DateTime   $dateFrom
299
     * @param \DateTime   $dateTo
300
     * @param float       $weight
301
     * @param int         $packageCount
302
     * @param string|null $message
303
     *
304
     * @return void
305
     *
306
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
307
     */
308 4
    public function orderPickup(
309
        string $shipper,
310
        DateTime $dateFrom,
311
        DateTime $dateTo,
312
        float $weight,
313
        int $packageCount,
314
        string $message = null
315
    ): void {
316
        $data = [
317 4
            'date'          => $dateFrom->format('Y-m-d'),
318 4
            'time_from'     => $dateFrom->format('H:s'),
319 4
            'time_to'       => $dateTo->format('H:s'),
320 4
            'weight'        => $weight,
321 4
            'package_count' => $packageCount,
322 4
            'message'       => $message,
323
        ];
324
325 4
        $this->requester->call(API::V1, $shipper, Request::ORDER_PICKUP, $data);
326 1
    }
327
328
    /**
329
     * Returns available services for the given shipper
330
     *
331
     * @param string $shipper
332
     *
333
     * @return string[]
334
     *
335
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
336
     */
337 10
    public function getServices(string $shipper): array
338
    {
339 10
        $response = $this->requester->call(API::V1, $shipper, Request::SERVICES);
340
341 6
        return $response['service_types'] ?? [];
342
    }
343
344
    /**
345
     * Returns available manipulation units for the given shipper
346
     *
347
     * @param string $shipper
348
     *
349
     * @return string[]
350
     *
351
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
352
     */
353 8
    public function getManipulationUnits(string $shipper): array
354
    {
355 8
        $response = $this->requester->call(API::V1, $shipper, Request::MANIPULATION_UNITS);
356
357 5
        if ($response['units'] === null) {
358 1
            return [];
359
        }
360
361 4
        return $this->normalizeResponseItems($response['units'], 'code', 'name');
362
    }
363
364
    /**
365
     * Returns available branches for the given shipper and its service
366
     * Full branches instead branches request
367
     *
368
     * @param string $shipper
369
     * @param string $service
370
     * @param bool   $fullData
371
     * @param string $country
372
     *
373
     * @return array[]
374
     *
375
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
376
     */
377 13
    public function getBranches(
378
        string $shipper,
379
        string $service = null,
380
        bool $fullData = false,
381
        string $country = null
382
    ): array {
383 13
        $request = $fullData ? Request::FULL_BRANCHES : Request::BRANCHES;
384
385 13
        $response = $this->requester->call(API::V1, $shipper, $request . '/' . $service . '/' . $country);
386
387 10
        return $response['branches'] ?? [];
388
    }
389
390
    /**
391
     * Returns available branches for the given shipper in given location
392
     *
393
     * @param string      $shipper
394
     * @param string      $country
395
     * @param string      $city
396
     * @param string|null $postcode
397
     * @param string|null $street
398
     * @param int|null    $maxResults
399
     * @param float|null  $radius
400
     * @param string|null $type
401
     *
402
     * @return array[]
403
     *
404
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
405
     */
406 9
    public function getBranchesForLocation(
407
        string $shipper,
408
        string $country,
409
        string $city,
410
        string $postcode = null,
411
        string $street = null,
412
        int $maxResults = null,
413
        float $radius = null,
414
        string $type = null
415
    ): array {
416 9
        Country::validateCode($country);
417
418
        $data = [
419 9
            'country'     => $country,
420 9
            'city'        => $city,
421 9
            'zip'         => $postcode,
422 9
            'street'      => $street,
423 9
            'max_results' => $maxResults,
424 9
            'radius'      => $radius,
425 9
            'type'        => $type,
426
        ];
427
428 9
        $data = array_filter($data);
429
430 9
        $response = $this->requester->call(API::V1, $shipper, Request::BRANCH_LOCATOR, $data);
431
432 6
        return $response['branches'] ?? [];
433
    }
434
435
    /**
436
     * Returns list of countries where service with cash-on-delivery payment type is available in
437
     *
438
     * @param string $shipper
439
     *
440
     * @return array[]
441
     *
442
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
443
     */
444 8
    public function getCodCountries(string $shipper): array
445
    {
446 8
        $response = $this->requester->call(API::V1, $shipper, Request::CASH_ON_DELIVERY_COUNTRIES);
447
448 5
        return $this->normalizeResponseItems($response['service_types'] ?? [], 'service_type', 'cod_countries');
449
    }
450
451
    /**
452
     * Returns list of countries where service is available in
453
     *
454
     * @param string $shipper
455
     *
456
     * @return array[]
457
     *
458
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
459
     */
460 8
    public function getCountries(string $shipper): array
461
    {
462 8
        $response = $this->requester->call(API::V1, $shipper, Request::COUNTRIES);
463
464 5
        return $this->normalizeResponseItems($response['service_types'] ?? [], 'service_type', 'countries');
465
    }
466
467
    /**
468
     * Returns available branches for the given shipper and its service
469
     *
470
     * @param string      $shipper
471
     * @param string      $service
472
     * @param string|null $country
473
     *
474
     * @return array[]
475
     *
476
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
477
     */
478 12
    public function getPostCodes(string $shipper, string $service, string $country = null): array
479
    {
480 12
        if ($country !== null) {
481 1
            Country::validateCode($country);
482
483 1
            $urlPath = $service . '/' . $country;
484
        } else {
485 11
            $urlPath = $service;
486
        }
487
488 12
        $response = $this->requester->call(API::V1, $shipper, Request::ZIP_CODES . '/' . $urlPath);
489
490 9
        $country            = $response['country'] ?? $country;
491 9
        $formattedPostCodes = [];
492
493 9
        foreach ($response['zip_codes'] ?? [] as $postCode) {
494 5
            $formattedPostCodes[] = [
495 5
                'postcode'     => $postCode['zip'] ?? ($postCode['zip_start'] ?? null),
496 5
                'postcode_end' => $postCode['zip_end'] ?? null,
497 5
                'city'         => $postCode['city'] ?? null,
498 5
                'country'      => $postCode['country'] ?? $country,
499 5
                '1B'           => (bool) ($postCode['1B'] ?? false),
500
            ];
501
        }
502
503 9
        return $formattedPostCodes;
504
    }
505
506
    /**
507
     * Check package(s) data
508
     *
509
     * @param string $shipper
510
     * @param array  $packages
511
     *
512
     * @return void
513
     *
514
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
515
     */
516 5
    public function checkPackages(string $shipper, array $packages): void
517
    {
518 5
        $this->requester->call(API::V1, $shipper, Request::CHECK, $packages);
519 2
    }
520
521
    /**
522
     * Returns available manipulation units for the given shipper
523
     *
524
     * @param string $shipper
525
     *
526
     * @return string[]
527
     *
528
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
529
     */
530 8
    public function getAdrUnits(string $shipper): array
531
    {
532 8
        $response = $this->requester->call(API::V1, $shipper, Request::ADR_UNITS);
533
534 5
        return $this->normalizeResponseItems($response['units'] ?? [], 'code', 'name');
535
    }
536
537
    /**
538
     * Returns available activated services for the given shipper
539
     *
540
     * @param string $shipper
541
     *
542
     * @return array
543
     *
544
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
545
     */
546 6 View Code Duplication
    public function getActivatedServices(string $shipper): array
547
    {
548 6
        $response = $this->requester->call(API::V1, $shipper, Request::ACTIVATEDSERVICES);
549
550 4
        unset($response['status']);
551
552 4
        return $response;
553
    }
554
555
    /**
556
     * Order shipments from place B (typically supplier / previous consignee) to place A (shipping point)
557
     *
558
     * @param string $shipper
559
     * @param array  $packages
560
     *
561
     * @return array
562
     *
563
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
564
     */
565 9 View Code Duplication
    public function orderB2AShipment(string $shipper, array $packages): array
566
    {
567 9
        $response = $this->requester->call(API::V1, $shipper, Request::B2A, $packages);
568
569 6
        if (isset($response[0]['package_id']) === false) {
570 1
            throw new BadRequestException($response);
571
        }
572
573 5
        unset($response['status']);
574
575 5
        return $response;
576
    }
577
578
    /**
579
     * Get PDF link with signed consignment delivery document by the recipient
580
     *
581
     * @param string $shipper
582
     * @param string $carrierId
583
     *
584
     * @return string
585
     *
586
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
587
     */
588 7
    public function getProofOfDelivery(string $shipper, string $carrierId): string
589
    {
590 7
        $response = $this->getProofOfDeliveries($shipper, [$carrierId]);
591
592 3
        return $response[0];
593
    }
594
595
    /**
596
     * Get array of PDF links with signed consignment delivery document by the recipient
597
     *
598
     * @param string $shipper
599
     * @param array  $carrierIds
600
     *
601
     * @return string[]
602
     *
603
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
604
     */
605 19
    public function getProofOfDeliveries(string $shipper, array $carrierIds): array
606
    {
607 19
        $data = $this->encapsulateIds($carrierIds);
608
609 19
        $response = $this->requester->call(API::V1, $shipper, Request::PROOF_OF_DELIVERY, $data, false);
610
611 15
        unset($response['status']);
612
613 15
        if (count($response) !== count($carrierIds)) {
614 3
            throw new BadRequestException($response);
615
        }
616
617 12
        $formatedLinks = [];
618
619 12
        foreach ($response as $statusResponse) {
620 12 View Code Duplication
            if (isset($statusResponse['status']) && ((int) $statusResponse['status']) !== 200) {
621 2
                throw new BadRequestException($response);
622
            }
623
624 11
            $formatedLinks[] = $statusResponse['file_url'];
625
        }
626
627 10
        return $formatedLinks;
628
    }
629
630
    /**
631
     * Normalize response items
632
     *
633
     * @param array  $items
634
     * @param string $keyName
635
     * @param string $valueName
636
     *
637
     * @return array
638
     */
639 19
    private function normalizeResponseItems(array $items, string $keyName, string $valueName): array
640
    {
641 19
        $services = [];
642
643 19
        foreach ($items as $item) {
644 8
            $services[$item[$keyName]] = $item[$valueName];
645
        }
646
647 19
        return $services;
648
    }
649
650
    /**
651
     * Encapsulate ids
652
     *
653
     * @param array $ids
654
     *
655
     * @return array[]
656
     */
657 61
    private function encapsulateIds(array $ids): array
658
    {
659
        return array_map(function ($carrierId) {
660
            return [
661 60
                'id' => $carrierId,
662
            ];
663 61
        }, $ids);
664
    }
665
}
666