Passed
Push — main ( 2bc5a4...5ffc2f )
by Vasil
16:31 queued 13:09
created

Speedy::calculation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 1
dl 0
loc 13
ccs 9
cts 9
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace VasilDakov\Speedy;
6
7
use Fig\Http\Message\RequestMethodInterface;
8
use Psr\Http\Client\ClientExceptionInterface;
9
use Psr\Http\Client\ClientInterface;
10
use Psr\Http\Message\RequestFactoryInterface;
11
use Psr\Http\Message\RequestInterface;
12
use VasilDakov\Speedy\Exception\JsonException;
13
use VasilDakov\Speedy\Service\Calculation\CalculationRequest;
14
use VasilDakov\Speedy\Service\Calculation\CalculationResponse;
15
use VasilDakov\Speedy\Service\Calculation\CalculationResponseFactory;
16
use VasilDakov\Speedy\Service\Client\GetContractClientsRequest;
17
use VasilDakov\Speedy\Service\Location;
18
use VasilDakov\Speedy\Service\Location\Complex\FindComplexRequest;
19
use VasilDakov\Speedy\Service\Location\Office\FindOfficeRequest;
20
use VasilDakov\Speedy\Service\Location\Site\FindSiteRequest;
21
use VasilDakov\Speedy\Service\Location\State\FindStateRequest;
22
use VasilDakov\Speedy\Service\Location\Street\FindStreetRequest;
23
use VasilDakov\Speedy\Service\Printing\PrintRequest;
24
use VasilDakov\Speedy\Service\Printing\PrintResponse;
25
use VasilDakov\Speedy\Service\Service\DestinationServicesRequest;
26
use VasilDakov\Speedy\Service\Service\DestinationServicesResponse;
27
use VasilDakov\Speedy\Service\Service\DestinationServicesResponseFactory;
28
use VasilDakov\Speedy\Service\Shipment\CancelShipmentRequest;
29
use VasilDakov\Speedy\Service\Shipment\CancelShipmentResponse;
30
use VasilDakov\Speedy\Service\Shipment\CancelShipmentResponseFactory;
31
use VasilDakov\Speedy\Service\Shipment\CreateShipmentRequest;
32
use VasilDakov\Speedy\Service\Track\TrackRequest;
33
use VasilDakov\Speedy\Service\Track\TrackResponse;
34
use VasilDakov\Speedy\Service\Track\TrackResponseFactory;
35
36
/**
37
 * Class Speedy.
38
 *
39
 * @author    Vasil Dakov <[email protected]>
40
 * @copyright 2009-2022 Neutrino.bg
41
 *
42
 * @version   1.0
43
 */
44
final class Speedy implements SpeedyInterface
45
{
46
    public const API_URL = 'https://api.speedy.bg/v1';
47
    public const USER_NAME = 'userName';
48
    public const PASSWORD = 'password';
49
    public const LANGUAGE = 'language';
50
    public const CLIENT_SYSTEM_ID = 'clientSystemId';
51
    public const SENDER = 'sender';
52
    public const CLIENT_ID = 'clientId';
53
    public const PRIVATE_PERSON = 'privatePerson';
54
    public const DROP_OFF_OFFICE_ID = 'dropoffOfficeId';
55
    public const PICKUP_OFFICE_ID = 'pickupOfficeId';
56
    public const ADDRESS_LOCATION = 'addressLocation';
57
    public const COUNTRY_ID = 'countryId';
58
    public const STATE_ID = 'stateId';
59
    public const SITE_ID = 'siteId';
60
    public const SITE_TYPE = 'siteType';
61
    public const SITE_NAME = 'siteName';
62
    public const POST_CODE = 'postCode';
63
    public const RECIPIENT = 'recipient';
64
    public const SERVICE = 'service';
65
    public const PICKUP_DATE = 'pickupDate';
66
    public const AUTO_ADJUST_PICKUP_DATE = 'autoAdjustPickupDate';
67
    public const SERVICE_IDS = 'serviceIds';
68
    public const DEFERRED_DAYS = 'deferredDays';
69
    public const SATURDAY_DELIVERY = 'saturdayDelivery';
70
    public const ADDITIONAL_SERVICES = 'additionalServices';
71
    public const FIXED_TIME_DELIVERY = 'fixedTimeDelivery';
72
    public const SPECIAL_DELIVERY_ID = 'specialDeliveryId';
73
    public const DELIVERY_TO_FLOOR = 'deliveryToFloor';
74
    public const COD = 'cod';
75
    public const AMOUNT = 'amount';
76
    public const CURRENCY_CODE = 'currencyCode';
77
    public const PROCESSING_TYPE = 'processingType';
78
    public const PAYOUT_TO_THIRD_PARTY = 'payoutToThirdParty';
79
    public const INCLUDE_SHIPPING_PRICE = 'includeShippingPrice';
80
    public const OBP_DETAILS = 'obpDetails';
81
    public const OPTION = 'option';
82
    public const RETURN_SHIPMENT_SERVICE_ID = 'returnShipmentServiceId';
83
    public const RETURN_SHIPMENT_PAYER = 'returnShipmentPayer';
84
    public const DECLARED_VALUE = 'declaredValue';
85
    public const FRAGILE = 'fragile';
86
    public const IGNORE_IF_NOT_APPLICABLE = 'ignoreIfNotApplicable';
87
    public const RETURNS = 'returns';
88
    public const ROD = 'rod';
89
    public const ENABLED = 'enabled';
90
    public const COMMENT = 'comment';
91
    public const RETURN_TO_CLIENT_ID = 'returnToClientId';
92
    public const RETURN_TO_OFFICE_ID = 'returnToOfficeId';
93
    public const THIRD_PARTY_PAYER = 'thirdPartyPayer';
94
    public const RETURN_RECEIPT = 'returnReceipt';
95
    public const SWAP = 'swap';
96
    public const SERVICE_ID = 'serviceId';
97
    public const PARCELS_COUNT = 'parcelsCount';
98
    public const ROP = 'rop';
99
    public const PALLETS = 'pallets';
100
    public const RETURN_VOUCHER = 'returnVoucher';
101
    public const PAYER = 'payer';
102
    public const CONTENT = 'content';
103
    public const TOTAL_WEIGHT = 'totalWeight';
104
    public const DOCUMENTS = 'documents';
105
    public const PALLETIZED = 'palletized';
106
    public const PARCELS = 'parcels';
107
    public const ID = 'id';
108
    public const SEQ_NO = 'seqNo';
109
    public const PACKAGE_UNIQUE_NUMBER = 'packageUniqueNumber';
110
    public const WEIGHT = 'weight';
111
    public const EXTERNAL_CARRIER_PARCEL_NUMBER = 'externalCarrierParcelNumber';
112
    public const SIZE = 'size';
113
    public const WIDTH = 'width';
114
    public const DEPTH = 'depth';
115
    public const HEIGHT = 'height';
116
    public const PAYMENT = 'payment';
117
    public const COURIER_SERVICE_PAYER = 'courierServicePayer';
118
    public const DECLARED_VALUE_PAYER = 'declaredValuePayer';
119
    public const PACKAGE_PAYER = 'packagePayer';
120
    public const THIRD_PARTY_CLIENT_ID = 'thirdPartyClientId';
121
    public const DISCOUNT_CARD_ID = 'discountCardId';
122
    public const CONTRACT_ID = 'contractId';
123
    public const CARD_ID = 'cardId';
124
    public const NAME = 'name';
125
    public const TYPE = 'type';
126
    public const MUNICIPALITY = 'municipality';
127
    public const REGION = 'region';
128
    public const LIMIT = 'limit';
129
    public const ISO_ALPHA_3 = 'isoAlpha3';
130
    public const ISO_ALPHA_2 = 'isoAlpha2';
131
    public const ADDRESS = 'address';
132
    public const STREET_ID = 'streetId';
133
    public const STREET_TYPE = 'streetType';
134
    public const STREET_NAME = 'streetName';
135
    public const STREET_NO = 'streetNo';
136
    public const COMPLEX_ID = 'complexId';
137
    public const COMPLEX_TYPE = 'complexType';
138
    public const COMPLEX_NAME = 'complexName';
139
    public const BLOCK_NO = 'blockNo';
140
    public const ENTRANCE_NO = 'entranceNo';
141
    public const FLOOR_NO = 'floorNo';
142
    public const APARTMENT_NO = 'apartmentNo';
143
    public const POI_ID = 'poiId';
144
    public const ADDRESS_NOTE = 'addressNote';
145
    public const ADDRESS_LINE_1 = 'addressLine1';
146
    public const ADDRESS_LINE_2 = 'addressLine2';
147
    public const X = 'x';
148
    public const Y = 'y';
149
    public const SHIPMENT_NOTE = 'shipmentNote';
150
    public const REF_1 = 'ref1';
151
    public const REF_2 = 'ref2';
152
    public const PHONE_1 = 'phone1';
153
    public const PHONE_2 = 'phone2';
154
    public const PHONE_3 = 'phone3';
155
    public const NUMBER = 'number';
156
    public const EXTENSION = 'extension';
157
    public const CLIENT_NAME = 'clientName';
158
    public const CONTACT_NAME = 'contactName';
159
    public const EMAIL = 'email';
160
    public const OBJECT_NAME = 'objectName';
161
    public const CONTENTS = 'contents';
162
    public const PACKAGE = 'package';
163
    public const PENDING_PARCELS = 'pendingParcels';
164
    public const STARTING_DATE = 'startingDate';
165
    public const SENDER_HAS_PAYMENT = 'senderHasPayment';
166
    public const SHIPMENT_ID = 'shipmentId';
167
    public const FORMAT = 'format';
168
    public const PAPER_SIZE = 'paperSize';
169
    public const PRINTER_NAME = 'printerName';
170
    public const DPI = 'dpi';
171
    public const PARCEL = 'parcel';
172
    public const ADDITIONAL_BARCODE = 'additionalBarcode';
173
    public const VALUE = 'value';
174
    public const LABEL = 'label';
175
    public const SHIPMENT_IDS = 'shipmentIds';
176
    public const LAST_OPERATION_ONLY = 'lastOperationOnly';
177
    public const CONSOLIDATION_REF = 'consolidationRef';
178
    public const REQUIRE_UNSUCCESSFUL_DELIVERY_STICKER_IMAGE = 'requireUnsuccessfulDeliveryStickerImage';
179
    public const EXCISE_GOODS = 'exciseGoods';
180
    public const SENDER_BANK_ACCOUNT = 'senderBankAccount';
181
    public const IBAN = 'iban';
182
    public const ACCOUNT_HOLDER = 'accountHolder';
183
184
    private Configuration $configuration;
185
186
    /**
187
     * PSR-18: HTTP Client.
188
     */
189
    private ClientInterface $client;
190
191
    /**
192
     * PSR-17: HTTP Factories.
193
     */
194
    private RequestFactoryInterface $factory;
195
196 13
    public function __construct(
197
        Configuration $configuration,
198
        ClientInterface $client,
199
        RequestFactoryInterface $factory
200
    ) {
201 13
        $this->configuration = $configuration;
202 13
        $this->client = $client;
203 13
        $this->factory = $factory;
204
    }
205
206 12
    private function createRequest(string $method, string $uri, array $data): RequestInterface
207
    {
208 12
        $request = $this->factory->createRequest($method, $uri);
209 12
        $request = $request->withAddedHeader('Content-Type', 'application/json');
210 12
        $request->getBody()->write(\json_encode($data));
211
212 12
        return $request;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $request returns the type Psr\Http\Message\MessageInterface which includes types incompatible with the type-hinted return Psr\Http\Message\RequestInterface.
Loading history...
213
    }
214
215 12
    private function createPayload(array $data): array
216
    {
217 12
        $config = $this->configuration->toArray();
218
219 12
        return \array_merge($config, $data);
220
    }
221
222
    /**
223
     * @throws ClientExceptionInterface
224
     * @throws JsonException
225
     */
226 12
    private function getContents(RequestInterface $request): string
227
    {
228 12
        $response = $this->client->sendRequest($request);
229
230 12
        $json = $response->getBody()->getContents();
231 12
        if (false === \json_validate($json)) {
232
            throw new JsonException(\json_last_error_msg(), \json_last_error());
233
        }
234
235 12
        return $json;
236
    }
237
238
    /**
239
     * @throws ClientExceptionInterface|JsonException
240
     */
241 1
    public function getContractClient(GetContractClientsRequest $req): string
242
    {
243 1
        $payload = $this->createPayload($req->toArray());
244
245 1
        $request = $this->createRequest(
246 1
            RequestMethodInterface::METHOD_POST,
247 1
            self::API_URL . '/client/contract',
248 1
            $payload
249 1
        );
250
251 1
        return $this->getContents($request);
252
    }
253
254
    /**
255
     * @throws ClientExceptionInterface|JsonException
256
     */
257 1
    public function findCountry(Location\Country\FindCountryRequest $req): string
258
    {
259 1
        $payload = $this->createPayload($req->toArray());
260
261 1
        $request = $this->createRequest(
262 1
            RequestMethodInterface::METHOD_POST,
263 1
            self::API_URL . '/location/country',
264 1
            $payload
265 1
        );
266
267 1
        return $this->getContents($request);
268
    }
269
270
    /**
271
     * @param FindStateRequest $req
272
     *
273
     * @return string
274
     * @throws ClientExceptionInterface
275
     * @throws JsonException
276
     */
277 1
    public function findState(Location\State\FindStateRequest $req): string
278
    {
279 1
        $payload = $this->createPayload($req->toArray());
280
281 1
        $request = $this->createRequest(
282 1
            RequestMethodInterface::METHOD_POST,
283 1
            self::API_URL . '/location/state',
284 1
            $payload
285 1
        );
286
287 1
        return $this->getContents($request);
288
    }
289
290
    /**
291
     * @param FindSiteRequest $req
292
     *
293
     * @throws ClientExceptionInterface|JsonException
294
     */
295 1
    public function findSite(Location\Site\FindSiteRequest $req): string
296
    {
297 1
        $payload = $this->createPayload($req->toArray());
298
299 1
        $request = $this->createRequest(
300 1
            RequestMethodInterface::METHOD_POST,
301 1
            self::API_URL . '/location/site',
302 1
            $payload
303 1
        );
304
305 1
        return $this->getContents($request);
306
307
        // return (new Location\Site\FindSiteResponseFactory())($json);
308
    }
309
310
    /**
311
     * @param FindOfficeRequest $req
312
     *
313
     * @return string
314
     * @throws ClientExceptionInterface
315
     * @throws JsonException
316
     */
317 1
    public function findOffice(Location\Office\FindOfficeRequest $req): string
318
    {
319 1
        $payload = $this->createPayload($req->toArray());
320
321 1
        $request = $this->createRequest(
322 1
            RequestMethodInterface::METHOD_POST,
323 1
            self::API_URL . '/location/office',
324 1
            $payload
325 1
        );
326
327 1
        return $this->getContents($request);
328
329
        // return (new Location\Office\FindOfficeResponseFactory())($json);
330
    }
331
332
    /**
333
     * @param FindComplexRequest $req
334
     *
335
     * @return string
336
     * @throws ClientExceptionInterface
337
     * @throws JsonException
338
     */
339 1
    public function findComplex(Location\Complex\FindComplexRequest $req): string
340
    {
341 1
        $payload = $this->createPayload($req->toArray());
342
343 1
        $request = $this->createRequest(
344 1
            RequestMethodInterface::METHOD_POST,
345 1
            self::API_URL . '/location/complex',
346 1
            $payload
347 1
        );
348
349 1
        return $this->getContents($request);
350
351
        // return (new Location\Complex\FindComplexResponseFactory())($json);
352
    }
353
354
    /**
355
     * @param FindStreetRequest $req
356
     *
357
     * @return string
358
     * @throws ClientExceptionInterface
359
     * @throws JsonException
360
     */
361 1
    public function findStreet(Location\Street\FindStreetRequest $req): string
362
    {
363 1
        $payload = $this->createPayload($req->toArray());
364
365 1
        $request = $this->createRequest(
366 1
            RequestMethodInterface::METHOD_POST,
367 1
            self::API_URL . '/location/street',
368 1
            $payload
369 1
        );
370
371 1
        return $this->getContents($request);
372
373
        // return (new Location\Street\FindStreetResponseFactory())($json);
374
    }
375
376
    /**
377
     * @throws ClientExceptionInterface|JsonException
378
     */
379 1
    public function calculate(CalculationRequest $object): string
380
    {
381 1
        $payload = $this->createPayload($object->toArray());
382
383 1
        $request = $this->createRequest(
384 1
            RequestMethodInterface::METHOD_POST,
385 1
            self::API_URL . '/calculate',
386 1
            $payload
387 1
        );
388
389 1
        return $this->getContents($request);
390
391
        // return (new CalculationResponseFactory())($json);
392
    }
393
394
    /**
395
     * @throws ClientExceptionInterface|JsonException
396
     */
397 1
    public function track(TrackRequest $object): string
398
    {
399 1
        $payload = $this->createPayload($object->toArray());
400
401 1
        $request = $this->createRequest(
402 1
            RequestMethodInterface::METHOD_POST,
403 1
            self::API_URL . '/track',
404 1
            $payload
405 1
        );
406
407 1
        return $this->getContents($request);
408
409
        //return (new TrackResponseFactory())($json);
410
    }
411
412 1
    public function print(PrintRequest $object): string
413
    {
414 1
        $payload = $this->createPayload($object->toArray());
415
416 1
        $request = $this->createRequest(
417 1
            RequestMethodInterface::METHOD_POST,
418 1
            self::API_URL . '/print',
419 1
            $payload
420 1
        );
421
422 1
        return $this->getContents($request);
423
    }
424
425
    /**
426
     * @throws ClientExceptionInterface|JsonException
427
     */
428 1
    public function createShipment(CreateShipmentRequest $req): string
429
    {
430 1
        $payload = $this->createPayload($req->toArray());
431
432 1
        $request = $this->createRequest(
433 1
            RequestMethodInterface::METHOD_POST,
434 1
            self::API_URL . '/shipment',
435 1
            $payload
436 1
        );
437
438 1
        return $this->getContents($request);
439
    }
440
441
    /**
442
     * @throws ClientExceptionInterface
443
     */
444
    public function cancelShipment(CancelShipmentRequest $object): CancelShipmentResponse
445
    {
446
        $payload = $this->createPayload($object->toArray());
447
448
        $request = $this->createRequest(
449
            RequestMethodInterface::METHOD_POST,
450
            self::API_URL . '/shipment/cancel',
451
            $payload
452
        );
453
454
        $json = $this->getContents($request);
455
456
        /* @var CancelShipmentResponse */
457
        return (new CancelShipmentResponseFactory())($json);
458
    }
459
460
461
    /**
462
     * @throws JsonException
463
     * @throws ClientExceptionInterface
464
     */
465 1
    public function destination(DestinationServicesRequest $object): string
466
    {
467 1
        $payload = $this->createPayload($object->toArray());
468
469 1
        $request = $this->createRequest(
470 1
            RequestMethodInterface::METHOD_POST,
471 1
            self::API_URL . '/services/destination',
472 1
            $payload
473 1
        );
474
475 1
        return $this->getContents($request);
476
    }
477
}
478