Completed
Pull Request — master (#8)
by Tomáš
03:09
created

Client::getManipulationUnits()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 10
c 0
b 0
f 0
rs 9.9332
ccs 6
cts 6
cp 1
cc 2
nc 1
nop 2
crap 2
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\Request;
9
10
class Client
11
{
12
    /**
13
     * API requester
14
     *
15
     * @var \Inspirum\Balikobot\Contracts\RequesterInterface
16
     */
17
    private $requester;
18
19
    /**
20
     * Request and Response formatter
21
     *
22
     * @var \Inspirum\Balikobot\Services\Formatter
23
     */
24
    private $formatter;
25
26
    /**
27
     * Response validator
28
     *
29
     * @var \Inspirum\Balikobot\Services\Validator
30
     */
31
    private $validator;
32
33
    /**
34
     * Balikobot API client
35
     *
36
     * @param \Inspirum\Balikobot\Contracts\RequesterInterface $requester
37
     */
38 323
    public function __construct(RequesterInterface $requester)
39
    {
40 323
        $this->requester = $requester;
41 323
        $this->validator = new Validator();
42 323
        $this->formatter = new Formatter($this->validator);
43 323
    }
44
45
    /**
46
     * Add package(s) to the Balikobot
47
     *
48
     * @param string                     $shipper
49
     * @param array<array<string,mixed>> $packages
50
     * @param mixed|null                 $labelsUrl
51
     *
52
     * @return array<array<string,mixed>>
53
     *
54
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
55
     */
56 30
    public function addPackages(string $shipper, array $packages, &$labelsUrl = null): array
57
    {
58 30
        $response = $this->requester->call(API::V2V1, $shipper, Request::ADD, ['packages' => $packages]);
59
60 16
        if (isset($response['labels_url'])) {
61 11
            $labelsUrl = $response['labels_url'];
62
        }
63
64 16
        $response = $response['packages'] ?? [];
65
66 16
        $this->validator->validateIndexes($response, count($packages));
67
68 15
        $this->validator->validateResponseItemHasAttribute($response, 'package_id', $response);
69
70 13
        return $response;
71
    }
72
73
    /**
74
     * Drops a package from the Balikobot – the package must be not ordered
75
     *
76
     * @param string $shipper
77
     * @param string $packageId
78
     *
79
     * @return void
80
     *
81
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
82
     */
83 2
    public function dropPackage(string $shipper, string $packageId): void
84
    {
85 2
        $this->dropPackages($shipper, [$packageId]);
86 2
    }
87
88
    /**
89
     * Drops a package from the Balikobot – the package must be not ordered
90
     *
91
     * @param string        $shipper
92
     * @param array<string> $packageIds
93
     *
94
     * @return void
95
     *
96
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
97
     */
98 9
    public function dropPackages(string $shipper, array $packageIds): void
99
    {
100 9
        if (count($packageIds) > 0) {
101 8
            $this->requester->call(API::V2V1, $shipper, Request::DROP, ['package_ids' => $packageIds]);
102
        }
103 5
    }
104
105
    /**
106
     * Tracks a package
107
     *
108
     * @param string $shipper
109
     * @param string $carrierId
110
     *
111
     * @return array<array<string,float|string>>
112
     *
113
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
114
     */
115 7
    public function trackPackage(string $shipper, string $carrierId): array
116
    {
117 7
        return $this->trackPackages($shipper, [$carrierId])[0];
118
    }
119
120
    /**
121
     * Tracks a packages
122
     *
123
     * @param string        $shipper
124
     * @param array<string> $carrierIds
125
     *
126
     * @return array<array<array<string,float|string>>>
127
     *
128
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
129
     */
130 22
    public function trackPackages(string $shipper, array $carrierIds): array
131
    {
132 22
        $response = $this->requester->call(API::V2V2, $shipper, Request::TRACK, ['carrier_ids' => $carrierIds], false);
133
134 18
        $response = $response['packages'] ?? [];
135
136 18
        $this->validator->validateIndexes($response, count($carrierIds));
137
138 13
        return $this->formatter->normalizeTrackPackagesResponse($response);
139
    }
140
141
    /**
142
     * Tracks a package, get the last info
143
     *
144
     * @param string $shipper
145
     * @param string $carrierId
146
     *
147
     * @return array<string,float|string|null>
148
     *
149
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
150
     */
151 7
    public function trackPackageLastStatus(string $shipper, string $carrierId): array
152
    {
153 7
        return $this->trackPackagesLastStatus($shipper, [$carrierId])[0];
154
    }
155
156
    /**
157
     * Tracks a package, get the last info
158
     *
159
     * @param string        $shipper
160
     * @param array<string> $carrierIds
161
     *
162
     * @return array<array<string,float|string|null>>
163
     *
164
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
165
     */
166 20
    public function trackPackagesLastStatus(string $shipper, array $carrierIds): array
167
    {
168 20
        $response = $this->requester->call(
169 20
            API::V2V2,
170
            $shipper,
171 20
            Request::TRACK_STATUS,
172 20
            ['carrier_ids' => $carrierIds],
173 20
            false
174
        );
175
176 16
        $response = $response['packages'] ?? [];
177
178 16
        $this->validator->validateIndexes($response, count($carrierIds));
179
180 13
        return $this->formatter->normalizeTrackPackagesLastStatusResponse($response);
181
    }
182
183
    /**
184
     * Returns packages from the front (not ordered) for given shipper
185
     *
186
     * @param string $shipper
187
     *
188
     * @return array<array<string,int|string>>
189
     *
190
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
191
     */
192 7
    public function getOverview(string $shipper): array
193
    {
194 7
        return $this->requester->call(API::V2V1, $shipper, Request::OVERVIEW, [], false);
195
    }
196
197
    /**
198
     * Gets labels
199
     *
200
     * @param string        $shipper
201
     * @param array<string> $packageIds
202
     *
203
     * @return string
204
     *
205
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
206
     */
207 9
    public function getLabels(string $shipper, array $packageIds): string
208
    {
209 9
        $response = $this->requester->call(API::V2V1, $shipper, Request::LABELS, ['package_ids' => $packageIds]);
210
211 5
        return $response['labels_url'];
212
    }
213
214
    /**
215
     * Gets complete information about a package by its package ID
216
     *
217
     * @param string $shipper
218
     * @param string $packageId
219
     *
220
     * @return array<string,int|string>
221
     *
222
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
223
     */
224 4
    public function getPackageInfo(string $shipper, string $packageId): array
225
    {
226 4
        return $this->requester->call(API::V2V1, $shipper, Request::PACKAGE . '/' . $packageId, [], false);
227
    }
228
229
    /**
230
     * Gets complete information about a package by its carrier ID
231
     *
232
     * @param string $shipper
233
     * @param string $carrierId
234
     *
235
     * @return array<string,int|string>
236
     *
237
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
238
     */
239 8
    public function getPackageInfoByCarrierId(string $shipper, string $carrierId): array
240
    {
241 8
        return $this->requester->call(
242 8
            API::V2V1,
243
            $shipper,
244 8
            Request::PACKAGE . '/carrier_id/' . $carrierId,
245 8
            [],
246 8
            false
247
        );
248
    }
249
250
    /**
251
     * Order shipment for packages
252
     *
253
     * @param string        $shipper
254
     * @param array<string> $packageIds
255
     *
256
     * @return array<string,int|string>
257
     *
258
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
259
     */
260 10
    public function orderShipment(string $shipper, array $packageIds): array
261
    {
262 10
        $response = $this->requester->call(API::V2V1, $shipper, Request::ORDER, ['package_ids' => $packageIds]);
263
264 6
        return $this->formatter->withoutStatus($response);
265
    }
266
267
    /**
268
     * Get order details
269
     *
270
     * @param string $shipper
271
     * @param string $orderId
272
     *
273
     * @return array<string,int|string|array>
274
     *
275
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
276
     */
277 9
    public function getOrder(string $shipper, string $orderId): array
278
    {
279 9
        $response = $this->requester->call(API::V2V1, $shipper, Request::ORDER_VIEW . '/' . $orderId, [], false);
280
281 6
        return $this->formatter->withoutStatus($response);
282
    }
283
284
    /**
285
     * Order pickup for packages
286
     *
287
     * @param string      $shipper
288
     * @param \DateTime   $dateFrom
289
     * @param \DateTime   $dateTo
290
     * @param float       $weight
291
     * @param int         $packageCount
292
     * @param string|null $message
293
     *
294
     * @return void
295
     *
296
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
297
     */
298 4
    public function orderPickup(
299
        string $shipper,
300
        DateTime $dateFrom,
301
        DateTime $dateTo,
302
        float $weight,
303
        int $packageCount,
304
        string $message = null
305
    ): void {
306 4
        $this->requester->call(API::V2V1, $shipper, Request::ORDER_PICKUP, [
307 4
            'date'          => $dateFrom->format('Y-m-d'),
308 4
            'time_from'     => $dateFrom->format('H:s'),
309 4
            'time_to'       => $dateTo->format('H:s'),
310 4
            'weight'        => $weight,
311 4
            'package_count' => $packageCount,
312 4
            'message'       => $message,
313
        ]);
314 1
    }
315
316
    /**
317
     * Returns available services for the given shipper
318
     *
319
     * @param string $shipper
320
     *
321
     * @return array<string,string>
322
     *
323
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
324
     */
325 13
    public function getServices(string $shipper): array
326
    {
327 13
        $response = $this->requester->call(API::V2V1, $shipper, Request::SERVICES);
328
329 9
        return $this->formatter->normalizeResponseItems($response['service_types'] ?? [], 'service_type', 'name');
330
    }
331
332
    /**
333
     * Returns available B2A services for the given shipper
334
     *
335
     * @param string $shipper
336
     *
337
     * @return array<string,string>
338
     *
339
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
340
     */
341 9
    public function getB2AServices(string $shipper): array
342
    {
343 9
        $response = $this->requester->call(API::V2V1, $shipper, Request::B2A . '/' . Request::SERVICES);
344
345 6
        return $response['service_types'] ?? [];
346
    }
347
348
    /**
349
     * Returns all manipulation units for the given shipper
350
     *
351
     * @param string $shipper
352
     * @param bool   $fullData
353
     *
354
     * @return array<string,string|array>
355
     *
356
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
357
     */
358 12
    public function getManipulationUnits(string $shipper, bool $fullData = false): array
359
    {
360 12
        $response = $this->requester->call(API::V2V1, $shipper, Request::MANIPULATION_UNITS);
361
362 9
        return $this->formatter->normalizeResponseItems(
363 9
            $response['units'] ?? [],
364 9
            'code',
365 9
            $fullData === false ? 'name' : null
366
        );
367
    }
368
369
    /**
370
     * Returns available manipulation units for the given shipper
371
     *
372
     * @param string $shipper
373
     * @param bool   $fullData
374
     *
375
     * @return array<string,string|array>
376
     *
377
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
378
     */
379 12
    public function getActivatedManipulationUnits(string $shipper, bool $fullData = false): array
380
    {
381 12
        $response = $this->requester->call(API::V2V1, $shipper, Request::ACTIVATED_MANIPULATION_UNITS);
382
383 9
        return $this->formatter->normalizeResponseItems(
384 9
            $response['units'] ?? [],
385 9
            'code',
386 9
            $fullData === false ? 'name' : null
387
        );
388
    }
389
390
    /**
391
     * Returns available branches for the given shipper and its service
392
     * Full branches instead branches request
393
     *
394
     * @param string      $shipper
395
     * @param string|null $service
396
     * @param bool        $fullBranchesRequest
397
     * @param string|null $country
398
     *
399
     * @return array<array<string,mixed>>
400
     *
401
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
402
     */
403 18
    public function getBranches(
404
        string $shipper,
405
        ?string $service,
406
        bool $fullBranchesRequest = false,
407
        string $country = null
408
    ): array {
409 18
        $usedRequest = $fullBranchesRequest ? Request::FULL_BRANCHES : Request::BRANCHES;
410
411 18
        if ($service !== null) {
412 17
            $usedRequest .= '/service/' . $service;
413
        }
414
415 18
        if ($country !== null) {
416 5
            $usedRequest .= '/country/' . $country;
417
        }
418
419 18
        $response = $this->requester->call(API::V2V1, $shipper, $usedRequest);
420
421 15
        return $response['branches'] ?? [];
422
    }
423
424
    /**
425
     * Returns available branches for the given shipper in given location
426
     *
427
     * @param string      $shipper
428
     * @param string      $country
429
     * @param string      $city
430
     * @param string|null $postcode
431
     * @param string|null $street
432
     * @param int|null    $maxResults
433
     * @param float|null  $radius
434
     * @param string|null $type
435
     *
436
     * @return array<array<string,mixed>>
437
     *
438
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
439
     */
440 11
    public function getBranchesForLocation(
441
        string $shipper,
442
        string $country,
443
        string $city,
444
        string $postcode = null,
445
        string $street = null,
446
        int $maxResults = null,
447
        float $radius = null,
448
        string $type = null
449
    ): array {
450 11
        $response = $this->requester->call(
451 11
            API::V2V1,
452
            $shipper,
453 11
            Request::BRANCH_LOCATOR,
454 11
            array_filter(
455
                [
456 11
                    'country'     => $country,
457 11
                    'city'        => $city,
458 11
                    'zip'         => $postcode,
459 11
                    'street'      => $street,
460 11
                    'max_results' => $maxResults,
461 11
                    'radius'      => $radius,
462 11
                    'type'        => $type,
463
                ]
464
            )
465
        );
466
467 7
        return $response['branches'] ?? [];
468
    }
469
470
    /**
471
     * Returns list of countries where service with cash-on-delivery payment type is available in
472
     *
473
     * @param string $shipper
474
     *
475
     * @return array<array<int|string,array<string,array>>>
476
     *
477
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
478
     */
479 9
    public function getCodCountries(string $shipper): array
480
    {
481 9
        $response = $this->requester->call(API::V2V1, $shipper, Request::CASH_ON_DELIVERY_COUNTRIES);
482
483 6
        return $this->formatter->normalizeResponseItems(
484 6
            $response['service_types'] ?? [],
485 6
            'service_type',
486 6
            'cod_countries'
487
        );
488
    }
489
490
    /**
491
     * Returns list of countries where service is available in
492
     *
493
     * @param string $shipper
494
     *
495
     * @return array<array<int|string,string>>
496
     *
497
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
498
     */
499 9
    public function getCountries(string $shipper): array
500
    {
501 9
        $response = $this->requester->call(API::V2V1, $shipper, Request::COUNTRIES);
502
503 6
        return $this->formatter->normalizeResponseItems(
504 6
            $response['service_types'] ?? [],
505 6
            'service_type',
506 6
            'countries'
507
        );
508
    }
509
510
    /**
511
     * Returns available branches for the given shipper and its service
512
     *
513
     * @param string      $shipper
514
     * @param string      $service
515
     * @param string|null $country
516
     *
517
     * @return array<array<string,mixed>>
518
     *
519
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
520
     */
521 13
    public function getPostCodes(string $shipper, string $service, string $country = null): array
522
    {
523 13
        $response = $this->requester->call(API::V2V1, $shipper, Request::ZIP_CODES . '/' . $service . '/' . $country);
524
525 10
        return $this->formatter->normalizePostCodesResponse($response, $country);
526
    }
527
528
    /**
529
     * Check package(s) data
530
     *
531
     * @param string               $shipper
532
     * @param array<array<string>> $packages
533
     *
534
     * @return void
535
     *
536
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
537
     */
538 7
    public function checkPackages(string $shipper, array $packages): void
539
    {
540 7
        $this->requester->call(API::V2V1, $shipper, Request::CHECK, ['packages' => $packages]);
541 3
    }
542
543
    /**
544
     * Returns available manipulation units for the given shipper
545
     *
546
     * @param string $shipper
547
     * @param bool   $fullData
548
     *
549
     * @return array<string>
550
     *
551
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
552
     */
553 12
    public function getAdrUnits(string $shipper, bool $fullData = false): array
554
    {
555 12
        $response = $this->requester->call(API::V2V1, $shipper, Request::ADR_UNITS);
556
557 9
        return $this->formatter->normalizeResponseItems(
558 9
            $response['units'] ?? [],
559 9
            'code',
560 9
            $fullData === false ? 'name' : null
561
        );
562
    }
563
564
    /**
565
     * Returns available activated services for the given shipper
566
     *
567
     * @param string $shipper
568
     *
569
     * @return array<string,mixed>
570
     *
571
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
572
     */
573 7
    public function getActivatedServices(string $shipper): array
574
    {
575 7
        $response = $this->requester->call(API::V2V1, $shipper, Request::ACTIVATED_SERVICES);
576
577 5
        return $this->formatter->withoutStatus($response);
578
    }
579
580
    /**
581
     * Order shipments from place B (typically supplier / previous consignee) to place A (shipping point)
582
     *
583
     * @param string                     $shipper
584
     * @param array<array<string,mixed>> $packages
585
     *
586
     * @return array<array<string,mixed>>
587
     *
588
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
589
     */
590 13
    public function orderB2AShipment(string $shipper, array $packages): array
591
    {
592 13
        $response = $this->requester->call(API::V1, $shipper, Request::B2A, $packages);
593
594 9
        $response = $this->formatter->withoutStatus($response);
595
596 9
        $this->validator->validateIndexes($response, count($packages));
597
598 8
        $this->validator->validateResponseItemHasAttribute($response, 'package_id', $response);
599
600 6
        return $response;
601
    }
602
603
    /**
604
     * Get PDF link with signed consignment delivery document by the recipient
605
     *
606
     * @param string $shipper
607
     * @param string $carrierId
608
     *
609
     * @return string
610
     *
611
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
612
     */
613 7
    public function getProofOfDelivery(string $shipper, string $carrierId): string
614
    {
615 7
        return $this->getProofOfDeliveries($shipper, [$carrierId])[0];
616
    }
617
618
    /**
619
     * Get array of PDF links with signed consignment delivery document by the recipient
620
     *
621
     * @param string        $shipper
622
     * @param array<string> $carrierIds
623
     *
624
     * @return array<string>
625
     *
626
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
627
     */
628 21
    public function getProofOfDeliveries(string $shipper, array $carrierIds): array
629
    {
630 21
        $response = $this->requester->call(
631 21
            API::V2V1,
632
            $shipper,
633 21
            Request::PROOF_OF_DELIVERY,
634 21
            $this->formatter->encapsulateIds($carrierIds, 'id'),
635 21
            false
636
        );
637
638 17
        $response = $this->formatter->withoutStatus($response);
639
640 17
        $this->validator->validateIndexes($response, count($carrierIds));
641
642 13
        return $this->formatter->normalizeProofOfDeliveriesResponse($response);
643
    }
644
645
    /**
646
     * Obtain the price of carriage at consignment level
647
     *
648
     * @param string                     $shipper
649
     * @param array<array<string,mixed>> $packages
650
     *
651
     * @return array<array<string,mixed>>
652
     *
653
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
654
     */
655 12
    public function getTransportCosts(string $shipper, array $packages): array
656
    {
657 12
        $response = $this->requester->call(API::V2V1, $shipper, Request::TRANSPORT_COSTS, ['packages' => $packages]);
658
659 8
        $response = $response['packages'];
660
661 8
        $this->validator->validateIndexes($response, count($packages));
662
663 7
        $this->validator->validateResponseItemHasAttribute($response, 'eid', $response);
664
665 5
        return $response;
666
    }
667
668
    /**
669
     * Get information on individual countries of the world
670
     *
671
     * @return array<array<string,mixed>>
672
     *
673
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
674
     */
675 9
    public function getCountriesData(): array
676
    {
677 9
        $response = $this->requester->call(API::V2V1, '', Request::GET_COUNTRIES_DATA);
678
679 6
        return $this->formatter->normalizeResponseItems($response['countries'] ?? [], 'iso_code', null);
680
    }
681
682
    /**
683
     * Method for obtaining news in the Balikobot API
684
     *
685
     * @return array<string,mixed>
686
     *
687
     * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface
688
     */
689 4
    public function getChangelog(): array
690
    {
691 4
        $response = $this->requester->call(API::V2V1, '', Request::CHANGELOG);
692
693 1
        return $this->formatter->withoutStatus($response);
694
    }
695
}
696