Completed
Pull Request — master (#6)
by Tomáš
03:21
created

Client::validateResponseItemHasAttribute()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

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