1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Inspirum\Balikobot\Services; |
4
|
|
|
|
5
|
|
|
use DateTime; |
6
|
|
|
use Inspirum\Balikobot\Contracts\RequesterInterface; |
7
|
|
|
use Inspirum\Balikobot\Definitions\Country; |
8
|
|
|
use Inspirum\Balikobot\Definitions\Request; |
9
|
|
|
use Inspirum\Balikobot\Exceptions\BadRequestException; |
10
|
|
|
|
11
|
|
|
class Client |
12
|
|
|
{ |
13
|
|
|
/** |
14
|
|
|
* API requester. |
15
|
|
|
* |
16
|
|
|
* @var \Inspirum\Balikobot\Contracts\RequesterInterface |
17
|
|
|
*/ |
18
|
|
|
private $requester; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* Balikobot API client. |
22
|
|
|
* |
23
|
|
|
* @param \Inspirum\Balikobot\Contracts\RequesterInterface $requester |
24
|
|
|
*/ |
25
|
157 |
|
public function __construct(RequesterInterface $requester) |
26
|
|
|
{ |
27
|
157 |
|
$this->requester = $requester; |
28
|
157 |
|
} |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Add package(s) to the Balikobot. |
32
|
|
|
* |
33
|
|
|
* @param string $shipper |
34
|
|
|
* @param array $packages |
35
|
|
|
* |
36
|
|
|
* @return array[] |
37
|
|
|
* |
38
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
39
|
|
|
*/ |
40
|
15 |
|
public function addPackages(string $shipper, array $packages): array |
41
|
|
|
{ |
42
|
15 |
|
$response = $this->requester->call('v1', $shipper, Request::ADD, $packages); |
43
|
|
|
|
44
|
6 |
|
if (isset($response[0]['package_id']) === false) { |
45
|
1 |
|
throw new BadRequestException($response); |
46
|
|
|
} |
47
|
|
|
|
48
|
5 |
|
unset($response['labels_url']); |
49
|
5 |
|
unset($response['status']); |
50
|
|
|
|
51
|
5 |
|
return $response; |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Drops a package from the Balikobot. The package must be not ordered. |
56
|
|
|
* |
57
|
|
|
* @param string $shipper |
58
|
|
|
* @param int $packageId |
59
|
|
|
* |
60
|
|
|
* @return void |
61
|
|
|
* |
62
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
63
|
|
|
*/ |
64
|
2 |
|
public function dropPackage(string $shipper, int $packageId): void |
65
|
|
|
{ |
66
|
2 |
|
$this->dropPackages($shipper, [$packageId]); |
67
|
2 |
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Drops a package from the Balikobot. The package must be not ordered. |
71
|
|
|
* |
72
|
|
|
* @param string $shipper |
73
|
|
|
* @param array $packageIds |
74
|
|
|
* |
75
|
|
|
* @return void |
76
|
|
|
* |
77
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
78
|
|
|
*/ |
79
|
7 |
|
public function dropPackages(string $shipper, array $packageIds): void |
80
|
|
|
{ |
81
|
7 |
|
$data = []; |
82
|
|
|
|
83
|
7 |
|
foreach ($packageIds as $packageId) { |
84
|
6 |
|
$data[] = ['id' => $packageId]; |
85
|
|
|
} |
86
|
|
|
|
87
|
7 |
|
if (count($data) === 0) { |
88
|
1 |
|
return; |
89
|
|
|
} |
90
|
|
|
|
91
|
6 |
|
$this->requester->call('v1', $shipper, Request::DROP, $data); |
92
|
3 |
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Tracks a package |
96
|
|
|
* |
97
|
|
|
* @param string $shipper |
98
|
|
|
* @param string $carrierId |
99
|
|
|
* |
100
|
|
|
* @return array[] |
101
|
|
|
* |
102
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
103
|
|
|
*/ |
104
|
8 |
|
public function trackPackage(string $shipper, string $carrierId): array |
105
|
|
|
{ |
106
|
|
|
$data = [ |
107
|
|
|
0 => [ |
108
|
8 |
|
'id' => $carrierId, |
109
|
|
|
], |
110
|
|
|
]; |
111
|
|
|
|
112
|
8 |
|
$response = $this->requester->call('v2', $shipper, Request::TRACK, $data); |
113
|
|
|
|
114
|
5 |
|
if (empty($response[0])) { |
115
|
1 |
|
throw new BadRequestException($response); |
116
|
|
|
} |
117
|
|
|
|
118
|
4 |
|
return $response[0]; |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* Tracks a package, get the last info |
123
|
|
|
* |
124
|
|
|
* @param string $shipper |
125
|
|
|
* @param string $carrierId |
126
|
|
|
* |
127
|
|
|
* @return array |
128
|
|
|
* |
129
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
130
|
|
|
*/ |
131
|
8 |
|
public function trackPackageLastStatus(string $shipper, string $carrierId): array |
132
|
|
|
{ |
133
|
|
|
$data = [ |
134
|
|
|
0 => [ |
135
|
8 |
|
'id' => $carrierId, |
136
|
|
|
], |
137
|
|
|
]; |
138
|
|
|
|
139
|
8 |
|
$response = $this->requester->call('v1', $shipper, Request::TRACK_STATUS, $data, false); |
140
|
|
|
|
141
|
6 |
|
if (empty($response[0])) { |
142
|
1 |
|
throw new BadRequestException($response); |
143
|
|
|
} |
144
|
|
|
|
145
|
|
|
$status = [ |
146
|
5 |
|
'name' => $response[0]['status_text'], |
147
|
5 |
|
'status_id' => $response[0]['status_id'], |
148
|
|
|
'date' => null, |
149
|
|
|
]; |
150
|
|
|
|
151
|
5 |
|
return $status; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Returns packages from the front (not ordered) for given shipper |
156
|
|
|
* |
157
|
|
|
* @param string $shipper |
158
|
|
|
* |
159
|
|
|
* @return array[] |
160
|
|
|
* |
161
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
162
|
|
|
*/ |
163
|
6 |
|
public function getOverview(string $shipper): array |
164
|
|
|
{ |
165
|
6 |
|
$response = $this->requester->call('v1', $shipper, Request::OVERVIEW, [], false); |
166
|
|
|
|
167
|
4 |
|
return $response; |
168
|
|
|
} |
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* Gets labels |
172
|
|
|
* |
173
|
|
|
* @param string $shipper |
174
|
|
|
* @param array $packageIds |
175
|
|
|
* |
176
|
|
|
* @return string |
177
|
|
|
* |
178
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
179
|
|
|
*/ |
180
|
7 |
|
public function getLabels(string $shipper, array $packageIds): string |
181
|
|
|
{ |
182
|
|
|
$data = [ |
183
|
7 |
|
'package_ids' => $packageIds, |
184
|
|
|
]; |
185
|
|
|
|
186
|
7 |
|
$response = $this->requester->call('v1', $shipper, Request::LABELS, $data); |
187
|
|
|
|
188
|
4 |
|
return $response['labels_url']; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Gets complete information about a package |
193
|
|
|
* |
194
|
|
|
* @param string $shipper |
195
|
|
|
* @param int $packageId |
196
|
|
|
* |
197
|
|
|
* @return array |
198
|
|
|
* |
199
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
200
|
|
|
*/ |
201
|
6 |
|
public function getPackageInfo(string $shipper, int $packageId): array |
202
|
|
|
{ |
203
|
6 |
|
$response = $this->requester->call('v1', $shipper, Request::PACKAGE . '/' . $packageId, [], false); |
204
|
|
|
|
205
|
4 |
|
return $response; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Order shipment for packages. |
210
|
|
|
* |
211
|
|
|
* @param string $shipper |
212
|
|
|
* @param array $packageIds |
213
|
|
|
* @param \DateTime|null $date |
214
|
|
|
* @param string|null $note |
215
|
|
|
* |
216
|
|
|
* @return array |
217
|
|
|
* |
218
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
219
|
|
|
*/ |
220
|
7 |
|
public function orderShipment(string $shipper, array $packageIds, DateTime $date = null, string $note = null): array |
221
|
|
|
{ |
222
|
|
|
$data = [ |
223
|
7 |
|
'package_ids' => $packageIds, |
224
|
7 |
|
'date' => $date ? $date->format('Y-m-d') : null, |
225
|
7 |
|
'note' => $note, |
226
|
|
|
]; |
227
|
|
|
|
228
|
7 |
|
$response = $this->requester->call('v1', $shipper, Request::ORDER, $data); |
229
|
|
|
|
230
|
4 |
|
unset($response['status']); |
231
|
|
|
|
232
|
4 |
|
return $response; |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
/** |
236
|
|
|
* Get order details. |
237
|
|
|
* |
238
|
|
|
* @param string $shipper |
239
|
|
|
* @param int $orderId |
240
|
|
|
* |
241
|
|
|
* @return array |
242
|
|
|
* |
243
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
244
|
|
|
*/ |
245
|
7 |
|
public function getOrder(string $shipper, int $orderId): array |
246
|
|
|
{ |
247
|
7 |
|
$response = $this->requester->call('v1', $shipper, Request::ORDER_VIEW . '/' . $orderId, [], false); |
248
|
|
|
|
249
|
5 |
|
unset($response['status']); |
250
|
|
|
|
251
|
5 |
|
return $response; |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Order pickup for packages. |
256
|
|
|
* |
257
|
|
|
* @param string $shipper |
258
|
|
|
* @param \DateTime $dateFrom |
259
|
|
|
* @param \DateTime $dateTo |
260
|
|
|
* @param float $weight |
261
|
|
|
* @param int $packageCount |
262
|
|
|
* @param string|null $message |
263
|
|
|
* |
264
|
|
|
* @return void |
265
|
|
|
* |
266
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
267
|
|
|
*/ |
268
|
4 |
|
public function orderPickup( |
269
|
|
|
string $shipper, |
270
|
|
|
DateTime $dateFrom, |
271
|
|
|
DateTime $dateTo, |
272
|
|
|
float $weight, |
273
|
|
|
int $packageCount, |
274
|
|
|
string $message = null |
275
|
|
|
): void { |
276
|
|
|
$data = [ |
277
|
4 |
|
'date' => $dateFrom->format('Y-m-d'), |
278
|
4 |
|
'time_from' => $dateFrom->format('H:s'), |
279
|
4 |
|
'time_to' => $dateTo->format('H:s'), |
280
|
4 |
|
'weight' => $weight, |
281
|
4 |
|
'package_count' => $packageCount, |
282
|
4 |
|
'message' => $message, |
283
|
|
|
]; |
284
|
|
|
|
285
|
4 |
|
$this->requester->call('v1', $shipper, Request::ORDER_PICKUP, $data); |
286
|
1 |
|
} |
287
|
|
|
|
288
|
|
|
/** |
289
|
|
|
* Returns available services for the given shipper |
290
|
|
|
* |
291
|
|
|
* @param string $shipper |
292
|
|
|
* |
293
|
|
|
* @return string[] |
294
|
|
|
* |
295
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
296
|
|
|
*/ |
297
|
10 |
|
public function getServices(string $shipper): array |
298
|
|
|
{ |
299
|
10 |
|
$response = $this->requester->call('v1', $shipper, Request::SERVICES); |
300
|
|
|
|
301
|
6 |
|
if (isset($response['service_types']) === false) { |
302
|
3 |
|
return []; |
303
|
|
|
} |
304
|
|
|
|
305
|
3 |
|
return $response['service_types']; |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* Returns available manipulation units for the given shipper |
310
|
|
|
* |
311
|
|
|
* @param string $shipper |
312
|
|
|
* |
313
|
|
|
* @return string[] |
314
|
|
|
* |
315
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
316
|
|
|
*/ |
317
|
8 |
View Code Duplication |
public function getManipulationUnits(string $shipper): array |
|
|
|
|
318
|
|
|
{ |
319
|
8 |
|
$response = $this->requester->call('v1', $shipper, Request::MANIPULATION_UNITS); |
320
|
|
|
|
321
|
5 |
|
if ($response['units'] === null) { |
322
|
1 |
|
return []; |
323
|
|
|
} |
324
|
|
|
|
325
|
4 |
|
$units = []; |
326
|
|
|
|
327
|
4 |
|
foreach ($response['units'] as $item) { |
328
|
2 |
|
$units[$item['code']] = $item['name']; |
329
|
|
|
} |
330
|
|
|
|
331
|
4 |
|
return $units; |
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* Returns available branches for the given shipper and its service |
336
|
|
|
* Full branches instead branches request. |
337
|
|
|
* |
338
|
|
|
* @param string $shipper |
339
|
|
|
* @param string $service |
340
|
|
|
* @param bool $fullData |
341
|
|
|
* |
342
|
|
|
* @return array[] |
343
|
|
|
* |
344
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
345
|
|
|
*/ |
346
|
10 |
|
public function getBranches(string $shipper, string $service = null, bool $fullData = false): array |
347
|
|
|
{ |
348
|
10 |
|
$request = $fullData ? Request::FULL_BRANCHES : Request::BRANCHES; |
349
|
|
|
|
350
|
10 |
|
$response = $this->requester->call('v1', $shipper, $request . '/' . $service); |
351
|
|
|
|
352
|
7 |
|
if ($response['branches'] === null) { |
353
|
1 |
|
return []; |
354
|
|
|
} |
355
|
|
|
|
356
|
6 |
|
return $response['branches']; |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* Returns available branches for the given shipper in given location |
361
|
|
|
* |
362
|
|
|
* @param string $shipper |
363
|
|
|
* @param string $country |
364
|
|
|
* @param string $city |
365
|
|
|
* @param string|null $postcode |
366
|
|
|
* @param string|null $street |
367
|
|
|
* @param int|null $maxResults |
368
|
|
|
* @param float|null $radius |
369
|
|
|
* |
370
|
|
|
* @return array[] |
371
|
|
|
* |
372
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
373
|
|
|
*/ |
374
|
8 |
|
public function getBranchesForLocation( |
375
|
|
|
string $shipper, |
376
|
|
|
string $country, |
377
|
|
|
string $city, |
378
|
|
|
string $postcode = null, |
379
|
|
|
string $street = null, |
380
|
|
|
int $maxResults = null, |
381
|
|
|
float $radius = null |
382
|
|
|
): array { |
383
|
8 |
|
Country::validateCode($country); |
384
|
|
|
|
385
|
|
|
$data = [ |
386
|
8 |
|
'country' => $country, |
387
|
8 |
|
'city' => $city, |
388
|
8 |
|
'zip' => $postcode, |
389
|
8 |
|
'street' => $street, |
390
|
8 |
|
'max_results' => $maxResults, |
391
|
8 |
|
'radius' => $radius, |
392
|
|
|
]; |
393
|
|
|
|
394
|
8 |
|
$data = array_filter($data); |
395
|
|
|
|
396
|
8 |
|
$response = $this->requester->call('v1', $shipper, Request::BRANCH_LOCATOR, $data); |
397
|
|
|
|
398
|
5 |
|
if ($response['branches'] === null) { |
399
|
1 |
|
return []; |
400
|
|
|
} |
401
|
|
|
|
402
|
4 |
|
return $response['branches']; |
403
|
|
|
} |
404
|
|
|
|
405
|
|
|
/** |
406
|
|
|
* Returns list of countries where service with cash-on-delivery payment type is available in |
407
|
|
|
* |
408
|
|
|
* @param string $shipper |
409
|
|
|
* |
410
|
|
|
* @return array[] |
411
|
|
|
* |
412
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
413
|
|
|
*/ |
414
|
8 |
View Code Duplication |
public function getCodCountries(string $shipper): array |
|
|
|
|
415
|
|
|
{ |
416
|
8 |
|
$response = $this->requester->call('v1', $shipper, Request::CASH_ON_DELIVERY_COUNTRIES); |
417
|
|
|
|
418
|
5 |
|
if ($response['service_types'] === null) { |
419
|
1 |
|
return []; |
420
|
|
|
} |
421
|
|
|
|
422
|
4 |
|
$services = []; |
423
|
|
|
|
424
|
4 |
|
foreach ($response['service_types'] as $item) { |
425
|
2 |
|
$services[$item['service_type']] = $item['cod_countries']; |
426
|
|
|
} |
427
|
|
|
|
428
|
4 |
|
return $services; |
429
|
|
|
} |
430
|
|
|
|
431
|
|
|
/** |
432
|
|
|
* Returns list of countries where service is available in |
433
|
|
|
* |
434
|
|
|
* @param string $shipper |
435
|
|
|
* |
436
|
|
|
* @return array[] |
437
|
|
|
* |
438
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
439
|
|
|
*/ |
440
|
8 |
View Code Duplication |
public function getCountries(string $shipper): array |
|
|
|
|
441
|
|
|
{ |
442
|
8 |
|
$response = $this->requester->call('v1', $shipper, Request::COUNTRIES); |
443
|
|
|
|
444
|
5 |
|
if ($response['service_types'] === null) { |
445
|
1 |
|
return []; |
446
|
|
|
} |
447
|
|
|
|
448
|
4 |
|
$services = []; |
449
|
|
|
|
450
|
4 |
|
foreach ($response['service_types'] as $item) { |
451
|
2 |
|
$services[$item['service_type']] = $item['countries']; |
452
|
|
|
} |
453
|
|
|
|
454
|
4 |
|
return $services; |
455
|
|
|
} |
456
|
|
|
|
457
|
|
|
/** |
458
|
|
|
* Returns available branches for the given shipper and its service |
459
|
|
|
* |
460
|
|
|
* @param string $shipper |
461
|
|
|
* @param string $service |
462
|
|
|
* @param string|null $country |
463
|
|
|
* |
464
|
|
|
* @return array[] |
465
|
|
|
* |
466
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
467
|
|
|
*/ |
468
|
12 |
|
public function getPostCodes(string $shipper, string $service, string $country = null): array |
469
|
|
|
{ |
470
|
12 |
|
if ($country !== null) { |
471
|
1 |
|
Country::validateCode($country); |
472
|
|
|
|
473
|
1 |
|
$urlPath = $service . '/' . $country; |
474
|
|
|
} else { |
475
|
11 |
|
$urlPath = $service; |
476
|
|
|
} |
477
|
|
|
|
478
|
12 |
|
$response = $this->requester->call('v1', $shipper, Request::ZIP_CODES . '/' . $urlPath); |
479
|
|
|
|
480
|
9 |
|
if ($response['zip_codes'] === null) { |
481
|
1 |
|
return []; |
482
|
|
|
} |
483
|
|
|
|
484
|
8 |
|
$country = $response['country'] ?? $country; |
485
|
8 |
|
$postCodes = []; |
486
|
|
|
|
487
|
8 |
|
foreach ($response['zip_codes'] as $postCode) { |
488
|
5 |
|
$postCodes[] = [ |
489
|
5 |
|
'postcode' => $postCode['zip'] ?? ($postCode['zip_start'] ?? null), |
490
|
5 |
|
'postcode_end' => $postCode['zip_end'] ?? null, |
491
|
5 |
|
'city' => $postCode['city'] ?? null, |
492
|
5 |
|
'country' => $postCode['country'] ?? $country, |
493
|
5 |
|
'1B' => (bool) ($postCode['1B'] ?? false), |
494
|
|
|
]; |
495
|
|
|
} |
496
|
|
|
|
497
|
8 |
|
return $postCodes; |
498
|
|
|
} |
499
|
|
|
|
500
|
|
|
/** |
501
|
|
|
* Check package(s) data. |
502
|
|
|
* |
503
|
|
|
* @param string $shipper |
504
|
|
|
* @param array $packages |
505
|
|
|
* |
506
|
|
|
* @return void |
507
|
|
|
* |
508
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
509
|
|
|
*/ |
510
|
5 |
|
public function checkPackages(string $shipper, array $packages): void |
511
|
|
|
{ |
512
|
5 |
|
$this->requester->call('v1', $shipper, Request::CHECK, $packages); |
513
|
2 |
|
} |
514
|
|
|
|
515
|
|
|
/** |
516
|
|
|
* Returns available manipulation units for the given shipper |
517
|
|
|
* |
518
|
|
|
* @param string $shipper |
519
|
|
|
* |
520
|
|
|
* @return string[] |
521
|
|
|
* |
522
|
|
|
* @throws \Inspirum\Balikobot\Contracts\ExceptionInterface |
523
|
|
|
*/ |
524
|
8 |
View Code Duplication |
public function getAdrUnits(string $shipper): array |
|
|
|
|
525
|
|
|
{ |
526
|
8 |
|
$response = $this->requester->call('v1', $shipper, Request::ADR_UNITS); |
527
|
|
|
|
528
|
5 |
|
if ($response['units'] === null) { |
529
|
1 |
|
return []; |
530
|
|
|
} |
531
|
|
|
|
532
|
4 |
|
$units = []; |
533
|
|
|
|
534
|
4 |
|
foreach ($response['units'] as $item) { |
535
|
2 |
|
$units[$item['code']] = $item['name']; |
536
|
|
|
} |
537
|
|
|
|
538
|
4 |
|
return $units; |
539
|
|
|
} |
540
|
|
|
} |
541
|
|
|
|
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.