diff --git a/.styleci.yml b/.styleci.yml deleted file mode 100755 index 1027d9e..0000000 --- a/.styleci.yml +++ /dev/null @@ -1,11 +0,0 @@ -preset: psr2 - -enabled: - - blank_line_before_try - - blank_line_before_catch - - blank_line_before_return - - no_spaces_after_function_name - -finder: - name: - - "*.sphp" \ No newline at end of file diff --git a/composer.json b/composer.json index d4813b9..5fa4337 100755 --- a/composer.json +++ b/composer.json @@ -4,7 +4,8 @@ "keywords": [ "inspirum", "inspishop", - "balikobot" + "balikobot", + "api-client" ], "homepage": "https://github.com/inspirum/balikobot-php", "license": "MIT", @@ -17,18 +18,21 @@ } ], "require": { - "php": ">=8.0", + "php": ">=8.1", "ext-curl": "*", "ext-json": "*", "psr/http-message": "^1.0", - "guzzlehttp/psr7": "^2.0" + "guzzlehttp/psr7": "^2.0", + "inspirum/arrayable": "^1.0" }, "require-dev": { - "inspirum/coding-standard": "^1.0", - "phpstan/phpstan": "^1.6", + "inspirum/coding-standard": "^1.1", + "phpstan/phpstan": "^1.8", "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "^3.6" + "squizlabs/php_codesniffer": "^3.7" }, + "minimum-stability": "dev", + "prefer-stable": true, "autoload": { "psr-4": { "Inspirum\\Balikobot\\": "src" @@ -89,7 +93,7 @@ "@composerUnused" ], "phpunit": "./vendor/bin/phpunit", - "phpcs": "./vendor/bin/phpcs -p -s --extensions=php --colors --report-width=140 --parallel=50 || true", + "phpcs": "./vendor/bin/phpcs -p -s --extensions=php --colors --report-width=140 --parallel=50", "phpstan": "./vendor/bin/phpstan analyse -c phpstan.neon.dist", "phpcbf": "./vendor/bin/phpcbf -p --extensions=php --parallel=50", "infection": "./tools/infection", diff --git a/src/Client/Client.php b/src/Client/Client.php index f0d055b..5e6db78 100644 --- a/src/Client/Client.php +++ b/src/Client/Client.php @@ -4,6 +4,10 @@ namespace Inspirum\Balikobot\Client; +use Inspirum\Balikobot\Client\Request\CarrierType; +use Inspirum\Balikobot\Client\Request\Method; +use Inspirum\Balikobot\Client\Request\Version; + interface Client { /** @@ -11,14 +15,14 @@ interface Client * * @param array $data * - * @return array + * @return array * * @throws \Inspirum\Balikobot\Exception\Exception */ public function call( - string $version, - ?string $carrier, - string $request, + Version $version, + ?CarrierType $carrier, + Method $request, array $data = [], string $path = '', bool $shouldHaveStatus = true, diff --git a/src/Client/DefaultClient.php b/src/Client/DefaultClient.php index a2389c7..ca84eb0 100644 --- a/src/Client/DefaultClient.php +++ b/src/Client/DefaultClient.php @@ -5,8 +5,11 @@ namespace Inspirum\Balikobot\Client; use GuzzleHttp\Psr7\InflateStream; +use Inspirum\Balikobot\Client\Request\CarrierType; +use Inspirum\Balikobot\Client\Request\Method; +use Inspirum\Balikobot\Client\Request\Version; +use Inspirum\Balikobot\Client\Response\Validator; use Inspirum\Balikobot\Exception\BadRequestException; -use Inspirum\Balikobot\Response\Validator; use JsonException; use Psr\Http\Message\StreamInterface; use Throwable; @@ -24,19 +27,17 @@ public function __construct( ) { } - /** - * @inheritDoc - */ + /** @inheritDoc */ public function call( - string $version, - ?string $carrier, - string $request, + Version $version, + ?CarrierType $carrier, + Method $request, array $data = [], string $path = '', bool $shouldHaveStatus = true, bool $gzip = false, ): array { - $url = $this->resolveUrl($version, $carrier, $request, $path, $gzip); + $url = $this->resolveUrl($version->getValue(), $carrier?->getValue(), $request->getValue(), $path, $gzip); $response = $this->requester->request($url, $data); @@ -55,14 +56,14 @@ private function resolveUrl(string $version, ?string $carrier, string $request, $url = trim(str_replace('//', '/', $url), '/'); if ($gzip) { - $url = sprintf('%s?gzip=1', $path); + $url = sprintf('%s?gzip=1', $url); } return sprintf('%s/%s', $version, $url); } /** - * @return array + * @return array * * @throws \Inspirum\Balikobot\Exception\Exception */ @@ -97,7 +98,7 @@ private function getContents(StreamInterface $stream, bool $gzip): string } /** - * @param array $response + * @param array $response * * @throws \Inspirum\Balikobot\Exception\Exception */ diff --git a/src/Client/CurlRequester.php b/src/Client/DefaultCurlRequester.php similarity index 96% rename from src/Client/CurlRequester.php rename to src/Client/DefaultCurlRequester.php index 2141adc..b8422ba 100644 --- a/src/Client/CurlRequester.php +++ b/src/Client/DefaultCurlRequester.php @@ -28,7 +28,7 @@ use const CURLOPT_SSL_VERIFYPEER; use const CURLOPT_URL; -final class CurlRequester implements Requester +final class DefaultCurlRequester implements Requester { public function __construct( private string $apiUser, @@ -37,9 +37,7 @@ public function __construct( ) { } - /** - * @inheritDoc - */ + /** @inheritDoc */ public function request(string $url, array $data = []): ResponseInterface { // init curl diff --git a/src/Client/Request/CarrierType.php b/src/Client/Request/CarrierType.php new file mode 100644 index 0000000..9af9e1c --- /dev/null +++ b/src/Client/Request/CarrierType.php @@ -0,0 +1,10 @@ + $response * - * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface + * @throws \Inspirum\Balikobot\Exception\Exception */ public function validateStatus(int $statusCode, array $response = []): void { @@ -28,7 +29,7 @@ public function validateStatus(int $statusCode, array $response = []): void // request error if ($statusCode >= 400) { - throw new BadRequestException($response, (int) ($response['status'] ?? $statusCode)); + throw new BadRequestException($response, (int) max($statusCode, $response['status'] ?? 0)); } } @@ -41,7 +42,7 @@ public function validateStatus(int $statusCode, array $response = []): void * * @return void * - * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface + * @throws \Inspirum\Balikobot\Exception\Exception */ public function validateResponseStatus( array $responseItem, @@ -64,7 +65,7 @@ public function validateResponseStatus( * * @return void * - * @throws \Inspirum\Balikobot\Exceptions\BadRequestException + * @throws \Inspirum\Balikobot\Exception\BadRequestException */ public function validateResponseItemHasAttribute(array $items, string $attribute, array $response): void { @@ -79,15 +80,12 @@ public function validateResponseItemHasAttribute(array $items, string $attribute * Validate response array has correct indexes * * @param array $response - * @param int $count * - * @return void - * - * @throws \Inspirum\Balikobot\Exceptions\BadRequestException + * @throws \Inspirum\Balikobot\Exception\BadRequestException */ public function validateIndexes(array $response, int $count): void { - if (array_keys($response) !== range(0, $count - 1)) { + if (array_is_list($response) === false || count($response) !== $count) { throw new BadRequestException($response); } } diff --git a/src/Contracts/RequesterInterface.php b/src/Contracts/RequesterInterface.php deleted file mode 100644 index 0a21b3b..0000000 --- a/src/Contracts/RequesterInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - $data - * @param bool $shouldHaveStatus - * @param bool $gzip - * - * @return array - * - * @throws \Inspirum\Balikobot\Contracts\ExceptionInterface - */ - public function call( - string $version, - string $shipper, - string $request, - array $data = [], - bool $shouldHaveStatus = true, - bool $gzip = false, - ): array; - - /** - * Get API response - * - * @param string $url - * @param array $data - * - * @return \Psr\Http\Message\ResponseInterface - */ - public function request(string $url, array $data = []): ResponseInterface; -} diff --git a/src/Definitions/API.php b/src/Definitions/API.php deleted file mode 100644 index 8aca42b..0000000 --- a/src/Definitions/API.php +++ /dev/null @@ -1,58 +0,0 @@ - - */ - public const URL = [ - self::V1 => 'https://api.balikobot.cz/', - self::V2 => 'https://api.balikobot.cz/v2/', - self::V3 => 'https://api.balikobot.cz/v3/', - self::V2V1 => 'https://apiv2.balikobot.cz/', - self::V2V2 => 'https://apiv2.balikobot.cz/v2/', - ]; -} diff --git a/src/Definitions/Carrier.php b/src/Definitions/Carrier.php new file mode 100644 index 0000000..6ea034a --- /dev/null +++ b/src/Definitions/Carrier.php @@ -0,0 +1,62 @@ +value; + } + + public static function hasBranchCountryFilterSupport(CarrierType $carrier, ?ServiceType $service): bool + { + // TODO: + return false; + } + + public static function hasFullBranchesSupport(CarrierType $carrier, ?ServiceType $service): bool + { + // TODO: + return false; + } +} diff --git a/src/Definitions/Option.php b/src/Definitions/Option.php index 5ff623c..4809cde 100644 --- a/src/Definitions/Option.php +++ b/src/Definitions/Option.php @@ -358,7 +358,7 @@ final class Option /** * Manipulation unit code * - * @see Client::getManipulationUnits() + * @see RawClient::getManipulationUnits() * * @var string */ @@ -375,7 +375,7 @@ final class Option /** * Manipulation unit code * - * @see Client::getManipulationUnits() + * @see RawClient::getManipulationUnits() * * @var string */ diff --git a/src/Definitions/Request.php b/src/Definitions/Request.php index ee47a97..b40b312 100644 --- a/src/Definitions/Request.php +++ b/src/Definitions/Request.php @@ -4,230 +4,46 @@ namespace Inspirum\Balikobot\Definitions; -final class Request -{ - /** - * Add a package - * - * @var string - */ - public const ADD = 'add'; - - /** - * Drop a package - * - * @var string - */ - public const DROP = 'drop'; - - /** - * Track a package - * - * @var string - */ - public const TRACK = 'track'; - - /** - * Track a package; get the last brief info - * - * @var string - */ - public const TRACK_STATUS = 'trackstatus'; - - /** - * List of packages - * - * @var string - */ - public const OVERVIEW = 'overview'; - - /** - * Get labels - * - * @var string - */ - public const LABELS = 'labels'; - - /** - * Get the package info - * - * @var string - */ - public const PACKAGE = 'package'; - - /** - * Order shipment - * - * @var string - */ - public const ORDER = 'order'; - - /** - * Get the shipment details - * - * @var string - */ - public const ORDER_VIEW = 'orderview'; - - /** - * Get the shipment pickup details - * - * @var string - */ - public const ORDER_PICKUP = 'orderpickup'; - - /** - * List of offered services - * - * @var string - */ - public const SERVICES = 'services'; - - /** - * List of units for palette shipping - * - * @var string - */ - public const MANIPULATION_UNITS = 'manipulationunits'; - - /** - * List of activated units for palette shipping - * - * @var string - */ - public const ACTIVATED_MANIPULATION_UNITS = 'activatedmanipulationunits'; - - /** - * List of available branches - * - * @var string - */ - public const BRANCHES = 'branches'; - - /** - * List of available branches with details - * - * @var string - */ - public const FULL_BRANCHES = 'fullbranches'; - - /** - * List of available branches with details for given location - * - * @var string - */ - public const BRANCH_LOCATOR = 'branchlocator'; +use Inspirum\Balikobot\Client\Request\Method; - /** - * List of services with countries which support cash-on-delivery payment type - * - * @var string - */ - public const CASH_ON_DELIVERY_COUNTRIES = 'cod4services'; - - /** - * List of available countries - * - * @var string - */ - public const COUNTRIES = 'countries4service'; - - /** - * List of available zip codes - * - * @var string - */ - public const ZIP_CODES = 'zipcodes'; - - /** - * Check add-package data - * - * @var string - */ - public const CHECK = 'check'; - - /** - * List of ADR units - * - * @var string - */ - public const ADR_UNITS = 'adrunits'; - - /** - * Detailed list of ADR units - * - * @var string - */ - public const FULL_ADR_UNITS = 'fulladrunits'; - - /** - * List of activated services for production API keys - * - * @var string - */ - public const ACTIVATED_SERVICES = 'activatedservices'; - - /** - * Order shipments from place B (typically supplier / previous consignee) to place A (shipping point) - * - * @var string - */ - public const B2A = 'b2a'; - - /** - * Get PDF with signed consignment delivery document by the recipient - * - * @var string - */ - public const PROOF_OF_DELIVERY = 'pod'; - - /** - * Method for obtaining the price of carriage at consignment level - * - * @var string - */ - public const TRANSPORT_COSTS = 'transportcosts'; - - /** - * Method for obtaining information on individual countries of the world - * - * @var string - */ - public const GET_COUNTRIES_DATA = 'getCountriesData'; - - /** - * Method for obtaining news in the Balikobot API - * - * @var string - */ - public const CHANGELOG = 'changelog'; - - /** - * Method for obtaining a list of additional services by individual transport services - * - * @var string - */ - public const ADD_SERVICE_OPTIONS = 'addserviceoptions'; - - /** - * Experimental method for easier carrier integration - * List of available input attributes for the ADD method of the selected carrier - * - * @var string - */ - public const ADD_ATTRIBUTES = 'addattributes'; - - /** - * Method for obtaining info about used API keys - * - * @var string - */ - public const INFO_WHO_AM_I = 'info/whoami'; - - /** - * Method for obtaining a list of active carriers. - * - * @var string - */ - public const CARRIER_MY = 'carriers/my'; +enum Request: string implements Method +{ + case TRACK = 'track'; + case TRACK_STATUS = 'trackstatus'; + case BRANCHES = 'branches'; + case FULL_BRANCHES = 'fullbranches'; + case BRANCH_LOCATOR = 'branchlocator'; + case ADD = 'add'; + case DROP = 'drop'; + case OVERVIEW = 'overview'; + case LABELS = 'labels'; + case PACKAGE = 'package'; + case ORDER = 'order'; + case ORDER_VIEW = 'orderview'; + case ORDER_PICKUP = 'orderpickup'; + case CHECK = 'check'; + case PROOF_OF_DELIVERY = 'pod'; + case TRANSPORT_COSTS = 'transportcosts'; + case ADD_SERVICE_OPTIONS = 'addserviceoptions'; + case ADD_ATTRIBUTES = 'addattributes'; + case B2A = 'b2a'; + case B2A_SERVICES = 'b2a/services'; + case INFO_WHO_AM_I = 'info/whoami'; + case INFO_CARRIERS = 'info/carriers'; + case CHANGELOG = 'changelog'; + case SERVICES = 'services'; + case ACTIVATED_SERVICES = 'activatedservices'; + case GET_COUNTRIES_DATA = 'getCountriesData'; + case MANIPULATION_UNITS = 'manipulationunits'; + case ACTIVATED_MANIPULATION_UNITS = 'activatedmanipulationunits'; + case CASH_ON_DELIVERY_COUNTRIES = 'cod4services'; + case COUNTRIES = 'countries4service'; + case ZIP_CODES = 'zipcodes'; + case ADR_UNITS = 'adrunits'; + case FULL_ADR_UNITS = 'fulladrunits'; + + public function getValue(): string + { + return $this->value; + } } diff --git a/src/Definitions/Response.php b/src/Definitions/Response.php index 556a091..8390a59 100644 --- a/src/Definitions/Response.php +++ b/src/Definitions/Response.php @@ -6,10 +6,7 @@ final class Response { - /** - * @var array - */ - public static array $statusCodesErrors = [ + public const STATUS_CODE_ERRORS = [ 200 => 'OK, operace proběhla v pořádku.', 208 => 'Položka s doloženým ID již existuje. Data, která jsou navrácena, patří k původnímu záznamu.', 400 => 'Operace neproběhla v pořádku, zkontrolujte konkrétní data.', @@ -26,20 +23,14 @@ final class Response 500 => 'Nepodařilo se rozeznat chybový stav.', ]; - /** - * @var array - */ - public static array $packageDataErrors = [ + public const PACKAGE_DATA_ERRORS = [ 406 => 'Nedorazila žádná data ke zpracování.', 409 => 'Nepovolená kombinace služeb dobírky a výměnné zásilky.', 413 => 'Špatný formát dat.', 416 => 'Datum má špatný formát nebo není povoleno.', ]; - /** - * @var array> - */ - public static array $packageDataKeyErrors = [ + public const PACKAGE_DATA_KEY_ERRORS = [ 406 => [ 'eid' => 'Nedorazilo eshop ID.', 'service_type' => 'Nedorazilo ID vybrané služby přepravce.', diff --git a/src/Definitions/ServiceType.php b/src/Definitions/ServiceType.php index 0511be7..585303b 100644 --- a/src/Definitions/ServiceType.php +++ b/src/Definitions/ServiceType.php @@ -2504,8 +2504,6 @@ final class ServiceType */ public const LIFTAGO_STANDARD_22 = 'standard-20-22'; - - /** * MPL Business parcel (Domestic) * @@ -2548,9 +2546,7 @@ final class ServiceType */ public const MAGYARPOSTA_EUROPE_STANDARD = 'A_125_HAR'; - /** - * @return array - */ + /** @return array */ public static function cp(): array { return [ @@ -2582,9 +2578,7 @@ public static function cp(): array ]; } - /** - * @return array - */ + /** @return array */ public static function dpd(): array { return [ @@ -2599,9 +2593,7 @@ public static function dpd(): array ]; } - /** - * @return array - */ + /** @return array */ public static function dhl(): array { return [ @@ -2615,9 +2607,7 @@ public static function dhl(): array ]; } - /** - * @return array - */ + /** @return array */ public static function geis(): array { return [ @@ -2630,9 +2620,7 @@ public static function geis(): array ]; } - /** - * @return array - */ + /** @return array */ public static function gls(): array { return [ @@ -2645,9 +2633,7 @@ public static function gls(): array ]; } - /** - * @return array - */ + /** @return array */ public static function intime(): array { return [ @@ -2665,9 +2651,7 @@ public static function intime(): array ]; } - /** - * @return array - */ + /** @return array */ public static function pbh(): array { return [ @@ -2700,9 +2684,7 @@ public static function pbh(): array ]; } - /** - * @return array - */ + /** @return array */ public static function ppl(): array { return [ @@ -2719,9 +2701,7 @@ public static function ppl(): array ]; } - /** - * @return array - */ + /** @return array */ public static function sp(): array { return [ @@ -2738,9 +2718,7 @@ public static function sp(): array ]; } - /** - * @return array - */ + /** @return array */ public static function sps(): array { return [ @@ -2751,9 +2729,7 @@ public static function sps(): array ]; } - /** - * @return array - */ + /** @return array */ public static function topTrans(): array { return [ @@ -2766,9 +2742,7 @@ public static function topTrans(): array ]; } - /** - * @return array - */ + /** @return array */ public static function ulozenka(): array { return [ @@ -2789,9 +2763,7 @@ public static function ulozenka(): array ]; } - /** - * @return array - */ + /** @return array */ public static function ups(): array { return [ @@ -2802,9 +2774,7 @@ public static function ups(): array ]; } - /** - * @return array - */ + /** @return array */ public static function zasilkovna(): array { return [ @@ -2914,9 +2884,7 @@ public static function zasilkovna(): array ]; } - /** - * @return array - */ + /** @return array */ public static function tnt(): array { return [ @@ -2940,9 +2908,7 @@ public static function tnt(): array ]; } - /** - * @return array - */ + /** @return array */ public static function gw(): array { return [ @@ -2958,9 +2924,7 @@ public static function gw(): array ]; } - /** - * @return array - */ + /** @return array */ public static function gwcz(): array { return [ @@ -2972,9 +2936,7 @@ public static function gwcz(): array ]; } - /** - * @return array - */ + /** @return array */ public static function messenger(): array { return [ @@ -2991,9 +2953,7 @@ public static function messenger(): array ]; } - /** - * @return array - */ + /** @return array */ public static function dhlde(): array { return [ @@ -3005,9 +2965,7 @@ public static function dhlde(): array ]; } - /** - * @return array - */ + /** @return array */ public static function fedex(): array { return [ @@ -3016,9 +2974,7 @@ public static function fedex(): array ]; } - /** - * @return array - */ + /** @return array */ public static function fofr(): array { return [ @@ -3032,9 +2988,7 @@ public static function fofr(): array ]; } - /** - * @return array - */ + /** @return array */ public static function dachser(): array { return [ @@ -3051,9 +3005,7 @@ public static function dachser(): array ]; } - /** - * @return array - */ + /** @return array */ public static function dhlparcel(): array { return [ @@ -3061,9 +3013,7 @@ public static function dhlparcel(): array ]; } - /** - * @return array - */ + /** @return array */ public static function raben(): array { return [ @@ -3076,9 +3026,7 @@ public static function raben(): array ]; } - /** - * @return array - */ + /** @return array */ public static function spring(): array { return [ @@ -3088,9 +3036,7 @@ public static function spring(): array ]; } - /** - * @return array - */ + /** @return array */ public static function dsv(): array { return [ @@ -3099,9 +3045,7 @@ public static function dsv(): array ]; } - /** - * @return array - */ + /** @return array */ public static function dhlfreightec(): array { return [ @@ -3112,9 +3056,7 @@ public static function dhlfreightec(): array ]; } - /** - * @return array - */ + /** @return array */ public static function kurier(): array { return [ @@ -3124,9 +3066,7 @@ public static function kurier(): array ]; } - /** - * @return array - */ + /** @return array */ public static function dbschenker(): array { return [ @@ -3144,9 +3084,7 @@ public static function dbschenker(): array ]; } - /** - * @return array - */ + /** @return array */ public static function airway(): array { return [ @@ -3162,9 +3100,7 @@ public static function airway(): array ]; } - /** - * @return array - */ + /** @return array */ public static function japo(): array { return [ @@ -3172,9 +3108,7 @@ public static function japo(): array ]; } - /** - * @return array - */ + /** @return array */ public static function liftago(): array { return [ @@ -3191,9 +3125,7 @@ public static function liftago(): array ]; } - /** - * @return array - */ + /** @return array */ public static function magyarposta(): array { return [ @@ -3214,39 +3146,39 @@ public static function magyarposta(): array public static function all(): array { return [ - Shipper::CP => self::cp(), - Shipper::DPD => self::dpd(), - Shipper::DHL => self::dhl(), - Shipper::GEIS => self::geis(), - Shipper::GLS => self::gls(), - Shipper::INTIME => self::intime(), - Shipper::PBH => self::pbh(), - Shipper::PPL => self::ppl(), - Shipper::SP => self::sp(), - Shipper::SPS => self::sps(), - Shipper::TOPTRANS => self::topTrans(), - Shipper::ULOZENKA => self::ulozenka(), - Shipper::UPS => self::ups(), - Shipper::ZASILKOVNA => self::zasilkovna(), - Shipper::TNT => self::tnt(), - Shipper::GW => self::gw(), - Shipper::GWCZ => self::gwcz(), - Shipper::MESSENGER => self::messenger(), - Shipper::DHLDE => self::dhlde(), - Shipper::FEDEX => self::fedex(), - Shipper::FOFR => self::fofr(), - Shipper::DACHSER => self::dachser(), - Shipper::DHLPARCEL => self::dhlparcel(), - Shipper::RABEN => self::raben(), - Shipper::SPRING => self::spring(), - Shipper::DSV => self::dsv(), - Shipper::DHLFREIGHTEC => self::dhlfreightec(), - Shipper::KURIER => self::kurier(), - Shipper::DBSCHENKER => self::dbschenker(), - Shipper::AIRWAY => self::airway(), - Shipper::JAPO => self::japo(), - Shipper::LIFTAGO => self::liftago(), - Shipper::MAGYARPOSTA => self::magyarposta(), + Carrier::CP->value => self::cp(), + Carrier::DPD->value => self::dpd(), + Carrier::DHL->value => self::dhl(), + Carrier::GEIS->value => self::geis(), + Carrier::GLS->value => self::gls(), + Carrier::INTIME->value => self::intime(), + Carrier::PBH->value => self::pbh(), + Carrier::PPL->value => self::ppl(), + Carrier::SP->value => self::sp(), + Carrier::SPS->value => self::sps(), + Carrier::TOPTRANS->value => self::topTrans(), + Carrier::ULOZENKA->value => self::ulozenka(), + Carrier::UPS->value => self::ups(), + Carrier::ZASILKOVNA->value => self::zasilkovna(), + Carrier::TNT->value => self::tnt(), + Carrier::GW->value => self::gw(), + Carrier::GWCZ->value => self::gwcz(), + Carrier::MESSENGER->value => self::messenger(), + Carrier::DHLDE->value => self::dhlde(), + Carrier::FEDEX->value => self::fedex(), + Carrier::FOFR->value => self::fofr(), + Carrier::DACHSER->value => self::dachser(), + Carrier::DHLPARCEL->value => self::dhlparcel(), + Carrier::RABEN->value => self::raben(), + Carrier::SPRING->value => self::spring(), + Carrier::DSV->value => self::dsv(), + Carrier::DHLFREIGHTEC->value => self::dhlfreightec(), + Carrier::KURIER->value => self::kurier(), + Carrier::DBSCHENKER->value => self::dbschenker(), + Carrier::AIRWAY->value => self::airway(), + Carrier::JAPO->value => self::japo(), + Carrier::LIFTAGO->value => self::liftago(), + Carrier::MAGYARPOSTA->value => self::magyarposta(), ]; } } diff --git a/src/Definitions/Version.php b/src/Definitions/Version.php new file mode 100644 index 0000000..b368f25 --- /dev/null +++ b/src/Definitions/Version.php @@ -0,0 +1,19 @@ +value; + } +} diff --git a/src/Exception/BadRequestException.php b/src/Exception/BadRequestException.php index be506d2..9cd6deb 100644 --- a/src/Exception/BadRequestException.php +++ b/src/Exception/BadRequestException.php @@ -9,7 +9,7 @@ use function is_array; use function is_numeric; -class BadRequestException extends BaseException +final class BadRequestException extends BaseException { /** * BadRequestException constructor diff --git a/src/Exception/UnauthorizedException.php b/src/Exception/UnauthorizedException.php index 8bb9a7b..9397848 100644 --- a/src/Exception/UnauthorizedException.php +++ b/src/Exception/UnauthorizedException.php @@ -6,7 +6,7 @@ use Throwable; -class UnauthorizedException extends BaseException +final class UnauthorizedException extends BaseException { /** * UnauthorizedException constructor diff --git a/src/Model/Account/Account.php b/src/Model/Account/Account.php new file mode 100644 index 0000000..e1c9c39 --- /dev/null +++ b/src/Model/Account/Account.php @@ -0,0 +1,48 @@ + + */ +final class Account extends BaseModel +{ + public function __construct( + public readonly string $name, + public readonly string $contactPerson, + public readonly string $email, + public readonly string $phone, + public readonly string $url, + public readonly string $street, + public readonly string $city, + public readonly string $zip, + public readonly string $country, + public readonly bool $live, + public readonly CarrierCollection $carriers, + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'name' => $this->name, + 'contactPerson' => $this->contactPerson, + 'email' => $this->email, + 'phone' => $this->phone, + 'url' => $this->url, + 'street' => $this->street, + 'city' => $this->city, + 'zip' => $this->zip, + 'country' => $this->country, + 'live' => $this->live, + 'carriers' => $this->carriers->toArray(), + + ]; + } +} diff --git a/src/Model/Account/AccountFactory.php b/src/Model/Account/AccountFactory.php new file mode 100644 index 0000000..3df60da --- /dev/null +++ b/src/Model/Account/AccountFactory.php @@ -0,0 +1,13 @@ + $response + */ + public function create(array $response): Account; +} diff --git a/src/Model/Account/DefaultAccountFactory.php b/src/Model/Account/DefaultAccountFactory.php new file mode 100644 index 0000000..f8e31b6 --- /dev/null +++ b/src/Model/Account/DefaultAccountFactory.php @@ -0,0 +1,32 @@ +carrierFactory->createCollection($response), + ); + } +} diff --git a/src/Model/AdrUnit/AdrUnit.php b/src/Model/AdrUnit/AdrUnit.php new file mode 100644 index 0000000..606c584 --- /dev/null +++ b/src/Model/AdrUnit/AdrUnit.php @@ -0,0 +1,40 @@ + + */ +class AdrUnit extends BaseModel +{ + public function __construct( + public readonly CarrierType $carrier, + public readonly string $id, + public readonly string $code, + public readonly string $name, + public readonly string $class, + public readonly ?string $packaging, + public readonly ?string $tunnelCode, + public readonly string $transportCategory + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'id' => $this->id, + 'code' => $this->code, + 'name' => $this->name, + 'class' => $this->class, + 'packaging' => $this->packaging, + 'tunnelCode' => $this->tunnelCode, + 'transportCategory' => $this->transportCategory, + ]; + } +} diff --git a/src/Model/AdrUnit/AdrUnitCollection.php b/src/Model/AdrUnit/AdrUnitCollection.php new file mode 100644 index 0000000..d8243d0 --- /dev/null +++ b/src/Model/AdrUnit/AdrUnitCollection.php @@ -0,0 +1,14 @@ + + */ +final class AdrUnitCollection extends BaseCollection +{ +} diff --git a/src/Model/AdrUnit/AdrUnitFactory.php b/src/Model/AdrUnit/AdrUnitFactory.php new file mode 100644 index 0000000..d3d5c79 --- /dev/null +++ b/src/Model/AdrUnit/AdrUnitFactory.php @@ -0,0 +1,20 @@ + $data + */ + public function create(CarrierType $carrier, array $data): AdrUnit; + + /** + * @param array $data + */ + public function createCollection(CarrierType $carrier, array $data): AdrUnitCollection; +} diff --git a/src/Model/AdrUnit/DefaultAdrUnitFactory.php b/src/Model/AdrUnit/DefaultAdrUnitFactory.php new file mode 100644 index 0000000..5e2e8bd --- /dev/null +++ b/src/Model/AdrUnit/DefaultAdrUnitFactory.php @@ -0,0 +1,34 @@ + $this->create($carrier, $unit), $data['units'] ?? []), + ); + } +} diff --git a/src/Model/Aggregates/OrderedPackageCollection.php b/src/Model/Aggregates/OrderedPackageCollection.php deleted file mode 100644 index 5d7bdc4..0000000 --- a/src/Model/Aggregates/OrderedPackageCollection.php +++ /dev/null @@ -1,224 +0,0 @@ - - * @implements \IteratorAggregate - */ -class OrderedPackageCollection implements ArrayAccess, Countable, IteratorAggregate -{ - /** - * Packages - * - * @var array - */ - private array $packages = []; - - /** - * Shipper code - * - * @var string|null - */ - private ?string $shipper; - - /** - * Labels URL - * - * @var string|null - */ - private ?string $labelsUrl = null; - - /** - * OrderedPackageCollection constructor - * - * @param string|null $shipper - */ - public function __construct(?string $shipper = null) - { - $this->shipper = $shipper; - } - - /** - * Add package - * - * @param \Inspirum\Balikobot\Model\Values\OrderedPackage $package - * - * @return void - * - * @throws \InvalidArgumentException - */ - public function add(OrderedPackage $package): void - { - // validate package shipper - $this->validateShipper($package); - - // add package to collection - $this->packages[] = $package; - } - - /** - * Get shipper - * - * @return string - */ - public function getShipper(): string - { - if ($this->shipper === null) { - throw new RuntimeException('Collection is empty'); - } - - return $this->shipper; - } - - /** - * Get package IDs - * - * @return array - */ - public function getPackageIds(): array - { - return array_map(static fn(OrderedPackage $package) => $package->getPackageId(), $this->packages); - } - - /** - * Get carrier IDs - * - * @return array - */ - public function getCarrierIds(): array - { - return array_map(static fn(OrderedPackage $package) => $package->getCarrierId(), $this->packages); - } - - /** - * @param string|null $labelsUrl - * - * @return void - */ - public function setLabelsUrl(?string $labelsUrl): void - { - $this->labelsUrl = $labelsUrl; - } - - /** - * @return string|null - */ - public function getLabelsUrl(): ?string - { - return $this->labelsUrl; - } - - /** - * Validate shipper - * - * @param \Inspirum\Balikobot\Model\Values\OrderedPackage $package - * - * @return void - * - * @throws \InvalidArgumentException - */ - private function validateShipper(OrderedPackage $package): void - { - // set shipper if first package in collection - if ($this->shipper === null) { - $this->shipper = $package->getShipper(); - } - - // validate shipper - if ($this->shipper !== $package->getShipper()) { - throw new InvalidArgumentException( - sprintf( - 'Package is from different shipper ("%s" instead of "%s")', - $package->getShipper(), - $this->shipper - ) - ); - } - } - - /** - * Determine if an item exists at an offset - * - * @param int $key - * - * @return bool - */ - public function offsetExists(mixed $key): bool - { - return array_key_exists($key, $this->packages); - } - - /** - * Get an item at a given offset - * - * @param int $key - * - * @return \Inspirum\Balikobot\Model\Values\OrderedPackage - */ - public function offsetGet(mixed $key): OrderedPackage - { - return $this->packages[$key]; - } - - /** - * Set the item at a given offset - * - * @param int $key - * @param \Inspirum\Balikobot\Model\Values\OrderedPackage $value - * - * @return void - */ - public function offsetSet(mixed $key, mixed $value): void - { - $this->validateShipper($value); - - $this->packages[$key] = $value; - } - - /** - * Unset the item at a given offset - * - * @param int $key - * - * @return void - */ - public function offsetUnset(mixed $key): void - { - unset($this->packages[$key]); - } - - /** - * Count elements of an object - * - * @return int - */ - public function count(): int - { - return count($this->packages); - } - - /** - * Get an iterator for the items - * - * @return \ArrayIterator - */ - public function getIterator(): ArrayIterator - { - return new ArrayIterator($this->packages); - } -} diff --git a/src/Model/Aggregates/PackageCollection.php b/src/Model/Aggregates/PackageCollection.php deleted file mode 100644 index c06d8bb..0000000 --- a/src/Model/Aggregates/PackageCollection.php +++ /dev/null @@ -1,168 +0,0 @@ - - * @implements \IteratorAggregate - */ -class PackageCollection implements ArrayAccess, Countable, IteratorAggregate -{ - /** - * Packages - * - * @var array - */ - private array $packages = []; - - /** - * Shipper code - * - * @var string - */ - private string $shipper; - - /** - * PackageCollection constructor - * - * @param string $shipper - */ - public function __construct(string $shipper) - { - $this->shipper = $shipper; - } - - /** - * Add package to collection - * - * @param \Inspirum\Balikobot\Model\Values\Package $package - * - * @return void - */ - public function add(Package $package): void - { - // clone package - $package = clone $package; - - // set collection EID - if ($package->hasEID() === false) { - $package->setEID($this->newEID()); - } - - // add package to collection - $this->packages[] = $package; - } - - /** - * Get packages shipper - * - * @return string - */ - public function getShipper(): string - { - return $this->shipper; - } - - /** - * Get the collection of packages as a plain array - * - * @return array> - */ - public function toArray(): array - { - return array_map(static fn(Package $package) => $package->toArray(), $this->packages); - } - - /** - * Get new EID for package batch - * - * @return string - */ - private function newEID(): string - { - return substr(time() . uniqid(), -20, 20); - } - - /** - * Determine if an item exists at an offset - * - * @param int $key - * - * @return bool - */ - public function offsetExists(mixed $key): bool - { - return array_key_exists($key, $this->packages); - } - - /** - * Get an item at a given offset - * - * @param int $key - * - * @return \Inspirum\Balikobot\Model\Values\Package - */ - public function offsetGet(mixed $key): Package - { - return $this->packages[$key]; - } - - /** - * Set the item at a given offset - * - * @param int $key - * @param \Inspirum\Balikobot\Model\Values\Package $value - * - * @return void - */ - public function offsetSet(mixed $key, mixed $value): void - { - $this->packages[$key] = $value; - } - - /** - * Unset the item at a given offset - * - * @param int $key - * - * @return void - */ - public function offsetUnset(mixed $key): void - { - unset($this->packages[$key]); - } - - /** - * Count elements of an object - * - * @return int - */ - public function count(): int - { - return count($this->packages); - } - - /** - * Get an iterator for the items - * - * @return \ArrayIterator - */ - public function getIterator(): ArrayIterator - { - return new ArrayIterator($this->packages); - } -} diff --git a/src/Model/Aggregates/PackageTransportCostCollection.php b/src/Model/Aggregates/PackageTransportCostCollection.php deleted file mode 100644 index 150c065..0000000 --- a/src/Model/Aggregates/PackageTransportCostCollection.php +++ /dev/null @@ -1,224 +0,0 @@ - - * @implements \IteratorAggregate - */ -class PackageTransportCostCollection implements ArrayAccess, Countable, IteratorAggregate -{ - /** - * Package costs - * - * @var array|\Inspirum\Balikobot\Model\Values\PackageTransportCost[] - */ - private array $costs = []; - - /** - * Shipper code - * - * @var string|null - */ - private ?string $shipper; - - /** - * OrderedPackageCollection constructor - * - * @param string|null $shipper - */ - public function __construct(?string $shipper = null) - { - $this->shipper = $shipper; - } - - /** - * Add package cost - * - * @param \Inspirum\Balikobot\Model\Values\PackageTransportCost $package - * - * @return void - * - * @throws \InvalidArgumentException - */ - public function add(PackageTransportCost $package): void - { - // validate package cost shipper - $this->validateShipper($package); - - // add package cost to collection - $this->costs[] = $package; - } - - /** - * Get shipper - * - * @return string - */ - public function getShipper(): string - { - if ($this->shipper === null) { - throw new RuntimeException('Collection is empty'); - } - - return $this->shipper; - } - - /** - * Get EIDs - * - * @return array - */ - public function getBatchIds(): array - { - return array_map(static fn(PackageTransportCost $transportCost) => $transportCost->getBatchId(), $this->costs); - } - - /** - * Get total cost for all packages - * - * @return float - */ - public function getTotalCost(): float - { - $totalCost = 0.0; - $currencyCode = $this->getCurrencyCode(); - - foreach ($this->costs as $cost) { - if ($cost->getCurrencyCode() !== $currencyCode) { - throw new RuntimeException('Package cost currency codes are not the same'); - } - - $totalCost += $cost->getTotalCost(); - } - - return $totalCost; - } - - /** - * Get currency code - * - * @return string - */ - public function getCurrencyCode(): string - { - if (empty($this->costs)) { - throw new RuntimeException('Collection is empty'); - } - - return $this->costs[0]->getCurrencyCode(); - } - - /** - * Validate shipper - * - * @param \Inspirum\Balikobot\Model\Values\PackageTransportCost $package - * - * @return void - * - * @throws \InvalidArgumentException - */ - private function validateShipper(PackageTransportCost $package): void - { - // set shipper if first package in collection - if ($this->shipper === null) { - $this->shipper = $package->getShipper(); - } - - // validate shipper - if ($this->shipper !== $package->getShipper()) { - throw new InvalidArgumentException( - sprintf( - 'Package is from different shipper ("%s" instead of "%s")', - $package->getShipper(), - $this->shipper - ) - ); - } - } - - /** - * Determine if an item exists at an offset - * - * @param int $key - * - * @return bool - */ - public function offsetExists(mixed $key): bool - { - return array_key_exists($key, $this->costs); - } - - /** - * Get an item at a given offset - * - * @param int $key - * - * @return \Inspirum\Balikobot\Model\Values\PackageTransportCost - */ - public function offsetGet(mixed $key): PackageTransportCost - { - return $this->costs[$key]; - } - - /** - * Set the item at a given offset - * - * @param int $key - * @param \Inspirum\Balikobot\Model\Values\PackageTransportCost $value - * - * @return void - */ - public function offsetSet(mixed $key, mixed $value): void - { - $this->validateShipper($value); - - $this->costs[$key] = $value; - } - - /** - * Unset the item at a given offset - * - * @param int $key - * - * @return void - */ - public function offsetUnset(mixed $key): void - { - unset($this->costs[$key]); - } - - /** - * Count elements of an object - * - * @return int - */ - public function count(): int - { - return count($this->costs); - } - - /** - * Get an iterator for the items - * - * @return \ArrayIterator - */ - public function getIterator(): ArrayIterator - { - return new ArrayIterator($this->costs); - } -} diff --git a/src/Model/Attribute/Attribute.php b/src/Model/Attribute/Attribute.php new file mode 100644 index 0000000..960c9f8 --- /dev/null +++ b/src/Model/Attribute/Attribute.php @@ -0,0 +1,30 @@ + + */ +final class Attribute extends BaseModel +{ + public function __construct( + public readonly string $name, + public readonly string $dataType, + public readonly string $maxLength, + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'name' => $this->name, + 'dataType' => $this->dataType, + 'maxLength' => $this->maxLength, + ]; + } +} diff --git a/src/Model/Attribute/AttributeCollection.php b/src/Model/Attribute/AttributeCollection.php new file mode 100644 index 0000000..4ddd0cf --- /dev/null +++ b/src/Model/Attribute/AttributeCollection.php @@ -0,0 +1,14 @@ + + */ +final class AttributeCollection extends BaseCollection +{ +} diff --git a/src/Model/Attribute/AttributeFactory.php b/src/Model/Attribute/AttributeFactory.php new file mode 100644 index 0000000..e86405b --- /dev/null +++ b/src/Model/Attribute/AttributeFactory.php @@ -0,0 +1,18 @@ + $data + */ + public function create(array $data): Attribute; + + /** + * @param array $data + */ + public function createCollection(array $data): AttributeCollection; +} diff --git a/src/Model/Attribute/DefaultAttributeFactory.php b/src/Model/Attribute/DefaultAttributeFactory.php new file mode 100644 index 0000000..f7f649b --- /dev/null +++ b/src/Model/Attribute/DefaultAttributeFactory.php @@ -0,0 +1,28 @@ + $this->create($attribute), $data['units'] ?? []), + ); + } +} diff --git a/src/Model/BasePerCarrierCollection.php b/src/Model/BasePerCarrierCollection.php new file mode 100644 index 0000000..2838a61 --- /dev/null +++ b/src/Model/BasePerCarrierCollection.php @@ -0,0 +1,128 @@ +&\Inspirum\Balikobot\Model\WithCarrierId) + * @extends \Inspirum\Arrayable\BaseCollection + * @implements \Inspirum\Balikobot\Model\PerCarrierCollection + */ +abstract class BasePerCarrierCollection extends BaseCollection implements PerCarrierCollection +{ + /** + * @param array $items + */ + public function __construct( + private ?CarrierType $carrier = null, + array $items = [], + ) { + parent::__construct([]); + + foreach ($items as $key => $value) { + $this->offsetSet($key, $value); + } + } + + /** + * @throws \RuntimeException + */ + public function getCarrier(): CarrierType + { + return $this->carrier ?? throw new RuntimeException('Collection is empty'); + } + + /** + * @param TValue $item + * + * @throws \InvalidArgumentException + */ + public function add(WithCarrierId $item): void + { + $this->offsetAdd($item); + } + + /** + * @param TKey $key + * @param TValue $value + */ + public function offsetSet(mixed $key, mixed $value): void + { + $this->validateCarrier($value); + + parent::offsetSet($key, $value); + } + + /** + * @param TValue $value + */ + public function offsetAdd(mixed $value): void + { + $this->validateCarrier($value); + + parent::offsetAdd($value); + } + + /** + * @return TValue|null + */ + public function getForCarrierId(string $carrierId): ?WithCarrierId + { + return $this->first(static fn(WithCarrierId $item) => $item->getCarrierId() === $carrierId); + } + + /** + * @param callable(TValue): bool $filter + * + * @return TValue|null + */ + protected function first(callable $filter): ?WithCarrierId + { + foreach ($this->items as $package) { + if ($filter($package)) { + return $package; + } + } + + return null; + } + + /** @inheritDoc */ + public function getCarrierIds(): array + { + return array_map(static fn(WithCarrierId $item) => $item->getCarrierId(), $this->items); + } + + /** + * @throws \InvalidArgumentException + */ + private function validateCarrier(WithCarrierId $item): void + { + if ($this->carrier === null) { + $this->carrier = $item->getCarrier(); + + return; + } + + if ($this->carrier !== $item->getCarrier()) { + throw new InvalidArgumentException( + sprintf( + 'Item carrier mismatch ("%s" instead "%s")', + $item->getCarrier()->getValue(), + $this->carrier->getValue() + ) + ); + } + } +} diff --git a/src/Model/Branch/Branch.php b/src/Model/Branch/Branch.php new file mode 100644 index 0000000..f146650 --- /dev/null +++ b/src/Model/Branch/Branch.php @@ -0,0 +1,65 @@ + + */ +class Branch extends BaseModel +{ + public function __construct( + public readonly CarrierType $carrier, + public readonly ?ServiceType $service, + public readonly string $branchId, + public readonly ?string $id, + public readonly ?string $uid, + public readonly string $type, + public readonly string $name, + public readonly string $city, + public readonly string $street, + public readonly string $zip, + public readonly ?string $country = null, + public readonly ?string $cityPart = null, + public readonly ?string $district = null, + public readonly ?string $region = null, + public readonly ?string $currency = null, + public readonly ?string $photoSmall = null, + public readonly ?string $photoBig = null, + public readonly ?string $url = null, + public readonly ?float $latitude = null, + public readonly ?float $longitude = null, + public readonly ?string $directionsGlobal = null, + public readonly ?string $directionsCar = null, + public readonly ?string $directionsPublic = null, + public readonly ?bool $wheelchairAccessible = null, + public readonly ?bool $claimAssistant = null, + public readonly ?bool $dressingRoom = null, + public readonly ?string $openingMonday = null, + public readonly ?string $openingTuesday = null, + public readonly ?string $openingWednesday = null, + public readonly ?string $openingThursday = null, + public readonly ?string $openingFriday = null, + public readonly ?string $openingSaturday = null, + public readonly ?string $openingSunday = null, + public readonly ?float $maxWeight = null + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'carrier' => $this->carrier->getValue(), + 'service' => $this->service, + 'branchId' => $this->branchId, + 'id' => $this->id, + 'uid' => $this->uid, + ]; + } +} diff --git a/src/Model/Branch/BranchFactory.php b/src/Model/Branch/BranchFactory.php new file mode 100644 index 0000000..9aa3807 --- /dev/null +++ b/src/Model/Branch/BranchFactory.php @@ -0,0 +1,18 @@ + $data + */ + public function createFromData(CarrierType $carrier, ?ServiceType $service, array $data): Branch; +} diff --git a/src/Model/Factories/BranchFactory.php b/src/Model/Branch/DefaultBranchFactory.php similarity index 58% rename from src/Model/Factories/BranchFactory.php rename to src/Model/Branch/DefaultBranchFactory.php index 081a17f..bd18ff9 100644 --- a/src/Model/Factories/BranchFactory.php +++ b/src/Model/Branch/DefaultBranchFactory.php @@ -2,28 +2,21 @@ declare(strict_types=1); -namespace Inspirum\Balikobot\Model\Factories; +namespace Inspirum\Balikobot\Model\Branch; +use Inspirum\Balikobot\Client\Request\CarrierType; +use Inspirum\Balikobot\Definitions\Carrier; use Inspirum\Balikobot\Definitions\ServiceType; -use Inspirum\Balikobot\Definitions\Shipper; -use Inspirum\Balikobot\Model\Values\Branch; use function sprintf; +use function str_replace; use function trim; -class BranchFactory +class DefaultBranchFactory implements BranchFactory { - /** - * Create branch from API response data - * - * @param string $shipper - * @param string|null $service - * @param array $data - * - * @return \Inspirum\Balikobot\Model\Values\Branch - */ - public static function createFromData(string $shipper, ?string $service, array $data): Branch + /** @inheritDoc */ + public function createFromData(CarrierType $carrier, ?\Inspirum\Balikobot\Client\Request\ServiceType $service, array $data): Branch { - if ($shipper === Shipper::CP && $service === ServiceType::CP_NP) { + if ($carrier->getValue() === Carrier::CP->getValue() && $service?->getValue() === ServiceType::CP_NP) { $data['country'] ??= 'CZ'; } @@ -42,16 +35,25 @@ public static function createFromData(string $shipper, ?string $service, array $ $data['street'] = trim(sprintf('%s %s', $data['street'] ?: ($data['city'] ?? ''), $streetNumber)); } + $id = $data['branch_id'] ?? (isset($data['id']) ? (string) $data['id'] : null); + $zip = $data['zip'] ?? '00000'; + $name = $data['name'] ?? $zip; + return new Branch( - $shipper, + $carrier, $service, - $data['branch_id'] ?? (isset($data['id']) ? (string) $data['id'] : null), + $this->resolveBranchId($carrier, $service, [ + 'id' => $id, + 'zip' => $zip, + 'name' => $name, + ]), + $id, $data['branch_uid'] ?? null, $data['type'] ?? 'branch', - $data['name'] ?? ($data['zip'] ?? '00000'), + $name, $data['city'] ?? '', $data['street'] ?? ($data['address'] ?? ''), - $data['zip'] ?? '00000', + $zip, $data['country'] ?? null, $data['city_part'] ?? null, $data['district'] ?? null, @@ -78,4 +80,29 @@ public static function createFromData(string $shipper, ?string $service, array $ isset($data['max_weight']) ? (float) $data['max_weight'] : null ); } + + /** + * @param array $data + */ + private function resolveBranchId(CarrierType $carrier, ?\Inspirum\Balikobot\Client\Request\ServiceType $service, array $data): string + { + // get key used in branch_id when calling add request + if ( + $carrier->getValue() === Carrier::CP->getValue() + || $carrier->getValue() === Carrier::SP->getValue() + || ($carrier->getValue() === Carrier::ULOZENKA->getValue() && $service?->getValue() === ServiceType::ULOZENKA_CP_NP) + ) { + return str_replace(' ', '', $data['zip']); + } + + if ($carrier->getValue() === Carrier::PPL->getValue()) { + return str_replace('KM', '', (string) $data['id']); + } + + if ($carrier->getValue() === Carrier::INTIME->getValue()) { + return $data['name']; + } + + return (string) $data['id']; + } } diff --git a/src/Model/Carrier/Carrier.php b/src/Model/Carrier/Carrier.php new file mode 100644 index 0000000..58e2c73 --- /dev/null +++ b/src/Model/Carrier/Carrier.php @@ -0,0 +1,55 @@ + + */ +final class Carrier extends BaseModel implements CarrierType +{ + /** + * @param array $methods + */ + public function __construct( + public readonly string $code, + public readonly string $name, + public readonly array $methods = [], + ) { + } + + public function getValue(): string + { + return $this->code; + } + + public static function from(string $value): static + { + return new self($value, ''); + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'code' => $this->code, + 'name' => $this->name, + 'methods' => array_map(static fn(MethodCollection $methods) => $methods->toArray(), $this->methods), + ]; + } + + /** + * @return array> + */ + public function getMethods(Version $version): array + { + return $this->methods[$version->getValue()]->toArray(); + } +} diff --git a/src/Model/Carrier/CarrierCollection.php b/src/Model/Carrier/CarrierCollection.php new file mode 100644 index 0000000..6818823 --- /dev/null +++ b/src/Model/Carrier/CarrierCollection.php @@ -0,0 +1,14 @@ + + */ +final class CarrierCollection extends BaseCollection +{ +} diff --git a/src/Model/Carrier/CarrierFactory.php b/src/Model/Carrier/CarrierFactory.php new file mode 100644 index 0000000..9145383 --- /dev/null +++ b/src/Model/Carrier/CarrierFactory.php @@ -0,0 +1,20 @@ + $data + */ + public function create(CarrierType $carrier, array $data): Carrier; + + /** + * @param array> $data + */ + public function createCollection(array $data): CarrierCollection; +} diff --git a/src/Model/Carrier/DefaultCarrierFactory.php b/src/Model/Carrier/DefaultCarrierFactory.php new file mode 100644 index 0000000..41f380c --- /dev/null +++ b/src/Model/Carrier/DefaultCarrierFactory.php @@ -0,0 +1,36 @@ +getValue(), $data['name'], array_map(fn(array $methods) => $this->methodFactory->createCollection($methods), array_filter([ + Version::V2V1->getValue() => $data['methods'] ?? [], + Version::V2V2->getValue() => $data['v2_methods'] ?? [], + ]))); + } + + /** @inheritDoc */ + public function createCollection(array $data): CarrierCollection + { + return new CarrierCollection( + array_map(fn(array $carrier): Carrier => $this->create(Carrier::from($carrier['slug']), $carrier), $data['carriers']), + ); + } +} diff --git a/src/Model/Changelog/Changelog.php b/src/Model/Changelog/Changelog.php new file mode 100644 index 0000000..a34cd3a --- /dev/null +++ b/src/Model/Changelog/Changelog.php @@ -0,0 +1,31 @@ + + */ +final class Changelog extends BaseModel +{ + public function __construct( + public readonly string $version, + public readonly DateTimeInterface $date, + public readonly ChangelogStatusCollection $changes, + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'code' => $this->version, + 'date' => $this->date->format('Y-m-d'), + 'changes' => $this->changes->toArray(), + ]; + } +} diff --git a/src/Model/Changelog/ChangelogCollection.php b/src/Model/Changelog/ChangelogCollection.php new file mode 100644 index 0000000..6246bf5 --- /dev/null +++ b/src/Model/Changelog/ChangelogCollection.php @@ -0,0 +1,18 @@ + + */ +final class ChangelogCollection extends BaseCollection +{ + public function getLatestVersion(): string + { + return $this->offsetGet(0)->version; + } +} diff --git a/src/Model/Changelog/ChangelogFactory.php b/src/Model/Changelog/ChangelogFactory.php new file mode 100644 index 0000000..0795022 --- /dev/null +++ b/src/Model/Changelog/ChangelogFactory.php @@ -0,0 +1,18 @@ + $data + */ + public function create(array $data): Changelog; + + /** + * @param array $data + */ + public function createCollection(array $data): ChangelogCollection; +} diff --git a/src/Model/Changelog/ChangelogStatus.php b/src/Model/Changelog/ChangelogStatus.php new file mode 100644 index 0000000..765c644 --- /dev/null +++ b/src/Model/Changelog/ChangelogStatus.php @@ -0,0 +1,28 @@ + + */ +final class ChangelogStatus extends BaseModel +{ + public function __construct( + public readonly string $name, + public readonly string $description, + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'name' => $this->name, + 'description' => $this->description, + ]; + } +} diff --git a/src/Model/Changelog/ChangelogStatusCollection.php b/src/Model/Changelog/ChangelogStatusCollection.php new file mode 100644 index 0000000..34bf860 --- /dev/null +++ b/src/Model/Changelog/ChangelogStatusCollection.php @@ -0,0 +1,14 @@ + + */ +final class ChangelogStatusCollection extends BaseCollection +{ +} diff --git a/src/Model/Changelog/DefaultChangelogFactory.php b/src/Model/Changelog/DefaultChangelogFactory.php new file mode 100644 index 0000000..2320936 --- /dev/null +++ b/src/Model/Changelog/DefaultChangelogFactory.php @@ -0,0 +1,50 @@ +createStatusCollection($data), + ); + } + + /** @inheritDoc */ + public function createCollection(array $data): ChangelogCollection + { + return new ChangelogCollection( + array_map(fn(array $version): Changelog => $this->create($version), $data['versions']), + ); + } + + /** + * @param array $data + */ + private function createStatus(array $data): ChangelogStatus + { + return new ChangelogStatus( + $data['name'], + $data['description'], + ); + } + + /** + * @param array $data + */ + private function createStatusCollection(array $data): ChangelogStatusCollection + { + return new ChangelogStatusCollection( + array_map(fn(array $change): ChangelogStatus => $this->createStatus($change), $data['changes']) + ); + } +} diff --git a/src/Model/Country/CodCountry.php b/src/Model/Country/CodCountry.php new file mode 100644 index 0000000..7dfda7d --- /dev/null +++ b/src/Model/Country/CodCountry.php @@ -0,0 +1,30 @@ + + */ +class CodCountry extends BaseModel +{ + public function __construct( + public readonly string $code, + public readonly string $currencyCode, + public readonly float $maxPrice, + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'code' => $this->code, + 'currencyCode' => $this->currencyCode, + 'maxPrice' => $this->maxPrice, + ]; + } +} diff --git a/src/Model/Country/Country.php b/src/Model/Country/Country.php new file mode 100644 index 0000000..b5b62db --- /dev/null +++ b/src/Model/Country/Country.php @@ -0,0 +1,48 @@ + + */ +class Country extends BaseModel +{ + /** + * @param array $names + * @param array $phonePrefixes + */ + public function __construct( + public readonly array $names, + public readonly string $code, + public readonly string $currencyCode, + public readonly array $phonePrefixes, + public readonly string $continent + ) { + } + + public function getName(string $locale): ?string + { + return $this->names[$locale] ?? null; + } + + public function getPhonePrefix(): string + { + return $this->phonePrefixes[0]; + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'names' => $this->names, + 'code' => $this->code, + 'currencyCode' => $this->currencyCode, + 'phonePrefixes' => $this->phonePrefixes, + 'continent' => $this->continent, + ]; + } +} diff --git a/src/Model/Country/CountryCollection.php b/src/Model/Country/CountryCollection.php new file mode 100644 index 0000000..c4b0330 --- /dev/null +++ b/src/Model/Country/CountryCollection.php @@ -0,0 +1,14 @@ + + */ +final class CountryCollection extends BaseCollection +{ +} diff --git a/src/Model/Country/CountryFactory.php b/src/Model/Country/CountryFactory.php new file mode 100644 index 0000000..d15c14b --- /dev/null +++ b/src/Model/Country/CountryFactory.php @@ -0,0 +1,32 @@ + $data + */ + public function create(array $data): Country; + + /** + * @param array $data + */ + public function createCollection(array $data): CountryCollection; + + /** + * @param array $data + * + * @return array + */ + public function createCodeCollection(array $data): array; + + /** + * @param array $data + * + * @return array<\Inspirum\Balikobot\Model\Country\CodCountry> + */ + public function createCodCountryCollection(array $data): array; +} diff --git a/src/Model/Country/DefaultCountryFactory.php b/src/Model/Country/DefaultCountryFactory.php new file mode 100644 index 0000000..27beb9e --- /dev/null +++ b/src/Model/Country/DefaultCountryFactory.php @@ -0,0 +1,55 @@ + $data['name_cz'], + 'en' => $data['name_en'], + ], + $data['iso_code'], + $data['currency'], + is_array($data['phone_prefix']) ? $data['phone_prefix'] : [$data['phone_prefix']], + $data['continent'] + ); + } + + /** @inheritDoc */ + public function createCollection(array $data): CountryCollection + { + return new CountryCollection( + array_map(fn(array $country): Country => $this->create($country), $data['countries'] ?? []) + ); + } + + /** @inheritDoc */ + public function createCodeCollection(array $data): array + { + return $data['countries'] ?? []; + } + + /** @inheritDoc */ + public function createCodCountryCollection(array $data): array + { + $codCountries = []; + foreach ($data['cod_countries'] ?? [] as $countryCode => $country) { + $codCountries[] = new CodCountry( + $countryCode, + $country['currency'], + $country['max_price'], + ); + } + + return $codCountries; + } +} diff --git a/src/Model/Method/DefaultMethodFactory.php b/src/Model/Method/DefaultMethodFactory.php new file mode 100644 index 0000000..7b498bd --- /dev/null +++ b/src/Model/Method/DefaultMethodFactory.php @@ -0,0 +1,26 @@ + $data + */ + public function create(array $data): Method + { + return new Method($data['method']); + } + + /** + * @param array> $data + */ + public function createCollection(array $data): MethodCollection + { + return new MethodCollection(array_map(fn(array $method): Method => $this->create($method), $data)); + } +} diff --git a/src/Model/Method/Method.php b/src/Model/Method/Method.php new file mode 100644 index 0000000..617201c --- /dev/null +++ b/src/Model/Method/Method.php @@ -0,0 +1,31 @@ + + */ +final class Method extends BaseModel implements \Inspirum\Balikobot\Client\Request\Method +{ + public function __construct( + public readonly string $code, + ) { + } + + public function getValue(): string + { + return $this->code; + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'code' => $this->code, + ]; + } +} diff --git a/src/Model/Method/MethodCollection.php b/src/Model/Method/MethodCollection.php new file mode 100644 index 0000000..46ed93a --- /dev/null +++ b/src/Model/Method/MethodCollection.php @@ -0,0 +1,14 @@ + + */ +final class MethodCollection extends BaseCollection +{ +} diff --git a/src/Model/Method/MethodFactory.php b/src/Model/Method/MethodFactory.php new file mode 100644 index 0000000..cc40a06 --- /dev/null +++ b/src/Model/Method/MethodFactory.php @@ -0,0 +1,18 @@ + $data + */ + public function create(array $data): Method; + + /** + * @param array> $data + */ + public function createCollection(array $data): MethodCollection; +} diff --git a/src/Model/OrderedShipment/DefaultOrderedShipmentFactory.php b/src/Model/OrderedShipment/DefaultOrderedShipmentFactory.php new file mode 100644 index 0000000..d60669d --- /dev/null +++ b/src/Model/OrderedShipment/DefaultOrderedShipmentFactory.php @@ -0,0 +1,23 @@ + + */ +class OrderedShipment extends BaseModel +{ + /** + * @param array $packageIds + */ + public function __construct( + public readonly string $orderId, + public readonly CarrierType $carrier, + public readonly array $packageIds, + public readonly string $handoverUrl, + public readonly string $labelsUrl, + public readonly ?string $fileUrl = null + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'carrier' => $this->carrier->getValue(), + 'orderId' => $this->orderId, + 'packageIds' => $this->packageIds, + 'handoverUrl' => $this->handoverUrl, + 'labelsUrl' => $this->labelsUrl, + 'fileUrl' => $this->fileUrl, + ]; + } +} diff --git a/src/Model/OrderedShipment/OrderedShipmentFactory.php b/src/Model/OrderedShipment/OrderedShipmentFactory.php new file mode 100644 index 0000000..a1ccebb --- /dev/null +++ b/src/Model/OrderedShipment/OrderedShipmentFactory.php @@ -0,0 +1,16 @@ + $packageIds + * @param array $data + */ + public function create(CarrierType $carrier, array $packageIds, array $data): OrderedShipment; +} diff --git a/src/Model/Package/DefaultPackageFactory.php b/src/Model/Package/DefaultPackageFactory.php new file mode 100644 index 0000000..f76243b --- /dev/null +++ b/src/Model/Package/DefaultPackageFactory.php @@ -0,0 +1,56 @@ +validator->validateIndexes($packagesResponse, count($packages)); + } + + $orderedPackages = new PackageCollection( + $carrier, + labelsUrl: $data['labels_url'] ?? null, + ); + + foreach ($packagesResponse as $packageIndex => $package) { + $this->validator->validateResponseStatus($package, $data); + + $orderedPackages->add($this->create($carrier, $package)); + } + + return $orderedPackages; + } +} diff --git a/src/Model/Package/Package.php b/src/Model/Package/Package.php new file mode 100644 index 0000000..0c8ae2e --- /dev/null +++ b/src/Model/Package/Package.php @@ -0,0 +1,59 @@ + + */ +class Package extends BaseModel implements WithCarrierId +{ + /** + * @param array $pieces + */ + public function __construct( + public readonly CarrierType $carrier, + public readonly string $packageId, + public readonly string $batchId, + public readonly string $carrierId, + public readonly ?string $trackUrl = null, + public readonly ?string $labelUrl = null, + public readonly ?string $carrierIdSwap = null, + public readonly array $pieces = [], + public readonly ?string $finalCarrierId = null, + public readonly ?string $finalTrackUrl = null, + ) { + } + + public function getCarrier(): CarrierType + { + return $this->carrier; + } + + public function getCarrierId(): string + { + return $this->carrierId; + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'carrier' => $this->carrier->getValue(), + 'carrierId' => $this->carrierId, + 'packageId' => $this->packageId, + 'batchId' => $this->batchId, + 'trackUrl' => $this->trackUrl, + 'labelUrl' => $this->labelUrl, + 'carrierIdSwap' => $this->carrierIdSwap, + 'pieces' => $this->pieces, + 'finalCarrierId' => $this->finalCarrierId, + 'finalTrackUrl' => $this->finalTrackUrl, + ]; + } +} diff --git a/src/Model/Package/PackageCollection.php b/src/Model/Package/PackageCollection.php new file mode 100644 index 0000000..8568d46 --- /dev/null +++ b/src/Model/Package/PackageCollection.php @@ -0,0 +1,39 @@ + + */ +class PackageCollection extends BasePerCarrierCollection +{ + /** + * @param array<\Inspirum\Balikobot\Model\Package\Package> $packages + */ + public function __construct( + ?CarrierType $carrier = null, + array $packages = [], + private ?string $labelsUrl = null, + ) { + parent::__construct($carrier, $packages); + } + + /** + * @return array + */ + public function getPackageIds(): array + { + return array_map(static fn(Package $package) => $package->packageId, $this->items); + } + + public function getLabelsUrl(): ?string + { + return $this->labelsUrl; + } +} diff --git a/src/Model/Package/PackageFactory.php b/src/Model/Package/PackageFactory.php new file mode 100644 index 0000000..1382898 --- /dev/null +++ b/src/Model/Package/PackageFactory.php @@ -0,0 +1,21 @@ + $data + */ + public function create(CarrierType $carrier, array $data): Package; + + /** + * @param array>|null $packages + * @param array $data + */ + public function createCollection(CarrierType $carrier, ?array $packages, array $data): PackageCollection; +} diff --git a/src/Model/PackageData/BasePackage.php b/src/Model/PackageData/BasePackage.php new file mode 100644 index 0000000..be65787 --- /dev/null +++ b/src/Model/PackageData/BasePackage.php @@ -0,0 +1,54 @@ + + * @implements \ArrayAccess + */ +abstract class BasePackage extends BaseModel implements ArrayAccess +{ + use CommonData; + + /** + * @param array $data + */ + public function __construct(private array $data = []) + { + } + + public function offsetExists(mixed $key): bool + { + return array_key_exists($key, $this->data); + } + + public function offsetGet(mixed $key): mixed + { + return $this->data[$key]; + } + + public function offsetSet(mixed $key, mixed $value): void + { + $this->data[$key] = $value; + } + + public function offsetUnset(mixed $key): void + { + unset($this->data[$key]); + } + + /** + * @return array + */ + public function __toArray(): array + { + return $this->data; + } +} diff --git a/src/Model/PackageData/DefaultPackageDataFactory.php b/src/Model/PackageData/DefaultPackageDataFactory.php new file mode 100644 index 0000000..9812540 --- /dev/null +++ b/src/Model/PackageData/DefaultPackageDataFactory.php @@ -0,0 +1,26 @@ + $data + */ + public function create(array $data): PackageData + { + unset( + $data['package_id'], + $data['eshop_id'], + $data['carrier_id'], + $data['track_url'], + $data['label_url'], + $data['carrier_id_swap'], + $data['pieces'] + ); + + return new PackageData($data); + } +} diff --git a/src/Model/Values/Package/CashOnDeliveryData.php b/src/Model/PackageData/Package/CashOnDeliveryData.php similarity index 77% rename from src/Model/Values/Package/CashOnDeliveryData.php rename to src/Model/PackageData/Package/CashOnDeliveryData.php index eddacf4..82d3bd1 100644 --- a/src/Model/Values/Package/CashOnDeliveryData.php +++ b/src/Model/PackageData/Package/CashOnDeliveryData.php @@ -2,22 +2,12 @@ declare(strict_types=1); -namespace Inspirum\Balikobot\Model\Values\Package; +namespace Inspirum\Balikobot\Model\PackageData\Package; use Inspirum\Balikobot\Definitions\Option; trait CashOnDeliveryData { - /** - * Set the item at a given offset - * - * @param string $key - * @param mixed $value - * - * @return void - */ - abstract public function offsetSet(string $key, mixed $value): void; - /** * @param float $codPrice * diff --git a/src/Model/Values/Package/CommonData.php b/src/Model/PackageData/Package/CommonData.php similarity index 79% rename from src/Model/Values/Package/CommonData.php rename to src/Model/PackageData/Package/CommonData.php index 8ddf00b..ace089f 100644 --- a/src/Model/Values/Package/CommonData.php +++ b/src/Model/PackageData/Package/CommonData.php @@ -2,41 +2,13 @@ declare(strict_types=1); -namespace Inspirum\Balikobot\Model\Values\Package; +namespace Inspirum\Balikobot\Model\PackageData\Package; use Inspirum\Balikobot\Definitions\Option; use function implode; trait CommonData { - /** - * Set the item at a given offset - * - * @param string $key - * @param mixed $value - * - * @return void - */ - abstract public function offsetSet(string $key, mixed $value): void; - - /** - * Get an item at a given offset - * - * @param string $key - * - * @return mixed - */ - abstract public function offsetGet(string $key): mixed; - - /** - * Determine if an item exists at an offset - * - * @param string $key - * - * @return bool - */ - abstract public function offsetExists(string $key): bool; - /** * Set EID * diff --git a/src/Model/Values/Package/CustomerData.php b/src/Model/PackageData/Package/CustomerData.php similarity index 91% rename from src/Model/Values/Package/CustomerData.php rename to src/Model/PackageData/Package/CustomerData.php index 738b07e..df51864 100644 --- a/src/Model/Values/Package/CustomerData.php +++ b/src/Model/PackageData/Package/CustomerData.php @@ -2,22 +2,12 @@ declare(strict_types=1); -namespace Inspirum\Balikobot\Model\Values\Package; +namespace Inspirum\Balikobot\Model\PackageData\Package; use Inspirum\Balikobot\Definitions\Option; trait CustomerData { - /** - * Set the item at a given offset - * - * @param string $key - * @param mixed $value - * - * @return void - */ - abstract public function offsetSet(string $key, mixed $value): void; - /** * @param string $name * diff --git a/src/Model/Values/Package/DeliveryData.php b/src/Model/PackageData/Package/DeliveryData.php similarity index 97% rename from src/Model/Values/Package/DeliveryData.php rename to src/Model/PackageData/Package/DeliveryData.php index 16760a3..e7cecbf 100644 --- a/src/Model/Values/Package/DeliveryData.php +++ b/src/Model/PackageData/Package/DeliveryData.php @@ -2,23 +2,13 @@ declare(strict_types=1); -namespace Inspirum\Balikobot\Model\Values\Package; +namespace Inspirum\Balikobot\Model\PackageData\Package; use DateTime; use Inspirum\Balikobot\Definitions\Option; trait DeliveryData { - /** - * Set the item at a given offset - * - * @param string $key - * @param mixed $value - * - * @return void - */ - abstract public function offsetSet(string $key, mixed $value): void; - /** * @param string $noteDriver * diff --git a/src/Model/Values/Package/ForeignCountryDeliveryData.php b/src/Model/PackageData/Package/ForeignCountryDeliveryData.php similarity index 78% rename from src/Model/Values/Package/ForeignCountryDeliveryData.php rename to src/Model/PackageData/Package/ForeignCountryDeliveryData.php index a816f49..575f7e5 100644 --- a/src/Model/Values/Package/ForeignCountryDeliveryData.php +++ b/src/Model/PackageData/Package/ForeignCountryDeliveryData.php @@ -2,22 +2,12 @@ declare(strict_types=1); -namespace Inspirum\Balikobot\Model\Values\Package; +namespace Inspirum\Balikobot\Model\PackageData\Package; use Inspirum\Balikobot\Definitions\Option; trait ForeignCountryDeliveryData { - /** - * Set the item at a given offset - * - * @param string $key - * @param mixed $value - * - * @return void - */ - abstract public function offsetSet(string $key, mixed $value): void; - /** * @param string $invoiceNumber * diff --git a/src/Model/Values/Package/NotificationData.php b/src/Model/PackageData/Package/NotificationData.php similarity index 90% rename from src/Model/Values/Package/NotificationData.php rename to src/Model/PackageData/Package/NotificationData.php index 76e6625..0f8d2e6 100644 --- a/src/Model/Values/Package/NotificationData.php +++ b/src/Model/PackageData/Package/NotificationData.php @@ -2,22 +2,12 @@ declare(strict_types=1); -namespace Inspirum\Balikobot\Model\Values\Package; +namespace Inspirum\Balikobot\Model\PackageData\Package; use Inspirum\Balikobot\Definitions\Option; trait NotificationData { - /** - * Set the item at a given offset - * - * @param string $key - * @param mixed $value - * - * @return void - */ - abstract public function offsetSet(string $key, mixed $value): void; - /** * @param bool $notification * diff --git a/src/Model/Values/Package/PackageData.php b/src/Model/PackageData/Package/ParcelData.php similarity index 85% rename from src/Model/Values/Package/PackageData.php rename to src/Model/PackageData/Package/ParcelData.php index d5ae836..0c9d9a0 100644 --- a/src/Model/Values/Package/PackageData.php +++ b/src/Model/PackageData/Package/ParcelData.php @@ -2,22 +2,12 @@ declare(strict_types=1); -namespace Inspirum\Balikobot\Model\Values\Package; +namespace Inspirum\Balikobot\Model\PackageData\Package; use Inspirum\Balikobot\Definitions\Option; -trait PackageData +trait ParcelData { - /** - * Set the item at a given offset - * - * @param string $key - * @param mixed $value - * - * @return void - */ - abstract public function offsetSet(string $key, mixed $value): void; - /** * @param float $width * diff --git a/src/Model/Values/Package/ParcelPackageData.php b/src/Model/PackageData/Package/ParcelPackageData.php similarity index 95% rename from src/Model/Values/Package/ParcelPackageData.php rename to src/Model/PackageData/Package/ParcelPackageData.php index 2140e69..c272ce4 100644 --- a/src/Model/Values/Package/ParcelPackageData.php +++ b/src/Model/PackageData/Package/ParcelPackageData.php @@ -2,23 +2,13 @@ declare(strict_types=1); -namespace Inspirum\Balikobot\Model\Values\Package; +namespace Inspirum\Balikobot\Model\PackageData\Package; use DateTime; use Inspirum\Balikobot\Definitions\Option; trait ParcelPackageData { - /** - * Set the item at a given offset - * - * @param string $key - * @param mixed $value - * - * @return void - */ - abstract public function offsetSet(string $key, mixed $value): void; - /** * @param string $muType * diff --git a/src/Model/PackageData/PackageData.php b/src/Model/PackageData/PackageData.php new file mode 100644 index 0000000..e9930e7 --- /dev/null +++ b/src/Model/PackageData/PackageData.php @@ -0,0 +1,24 @@ + + */ +class PackageDataCollection extends BaseCollection +{ + /** + * @param array<\Inspirum\Balikobot\Model\PackageData\PackageData> $packages + */ + public function __construct( + private CarrierType $carrier, + array $packages = [], + ) { + parent::__construct([]); + + foreach ($packages as $package) { + $this->add($package); + } + } + + public function getCarrier(): CarrierType + { + return $this->carrier; + } + + public function add(PackageData $package): void + { + $package = clone $package; + + if ($package->hasEID() === false) { + $package->setEID($this->newEID()); + } + + $this->offsetAdd($package); + } + + private function newEID(): string + { + return substr(time() . uniqid(), -20, 20); + } +} diff --git a/src/Model/PackageData/PackageDataFactory.php b/src/Model/PackageData/PackageDataFactory.php new file mode 100644 index 0000000..7626951 --- /dev/null +++ b/src/Model/PackageData/PackageDataFactory.php @@ -0,0 +1,13 @@ + $data + */ + public function create(array $data): PackageData; +} diff --git a/src/Model/PerCarrierCollection.php b/src/Model/PerCarrierCollection.php new file mode 100644 index 0000000..09aabf6 --- /dev/null +++ b/src/Model/PerCarrierCollection.php @@ -0,0 +1,25 @@ + + */ + public function getCarrierIds(): array; +} diff --git a/src/Model/PostCode/DefaultPostCodeFactory.php b/src/Model/PostCode/DefaultPostCodeFactory.php new file mode 100644 index 0000000..c5fe38a --- /dev/null +++ b/src/Model/PostCode/DefaultPostCodeFactory.php @@ -0,0 +1,25 @@ + + */ +class PostCode extends BaseModel +{ + public function __construct( + public readonly CarrierType $carrier, + public readonly ?ServiceType $service, + public readonly string $postcode, + public readonly ?string $postcodeEnd, + public readonly ?string $city, + public readonly ?string $country, + public readonly bool $morningDelivery + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'carrier' => $this->carrier->getValue(), + 'service' => $this->service, + 'postcode' => $this->postcode, + 'postcodeEnd' => $this->postcodeEnd, + 'city' => $this->city, + 'country' => $this->country, + 'morningDelivery' => $this->morningDelivery, + ]; + } +} diff --git a/src/Model/PostCode/PostCodeFactory.php b/src/Model/PostCode/PostCodeFactory.php new file mode 100644 index 0000000..ac74746 --- /dev/null +++ b/src/Model/PostCode/PostCodeFactory.php @@ -0,0 +1,16 @@ + $data + */ + public function create(CarrierType $carrier, ?ServiceType $service, array $data): PostCode; +} diff --git a/src/Model/Service/DefaultServiceFactory.php b/src/Model/Service/DefaultServiceFactory.php new file mode 100644 index 0000000..ecc4d47 --- /dev/null +++ b/src/Model/Service/DefaultServiceFactory.php @@ -0,0 +1,66 @@ +createOptionCollection($carrier, $data), + array_key_exists('countries', $data) + ? $this->countryFactory->createCodeCollection($data) + : null, + array_key_exists('cod_countries', $data) + ? $this->countryFactory->createCodCountryCollection($data) + : null, + ); + } + + /** @inheritDoc */ + public function createCollection(CarrierType $carrier, array $data): ServiceCollection + { + return new ServiceCollection( + $carrier, + array_map(fn(array $service): Service => $this->create($carrier, $service), $data['service_types'] ?? []), + $data['active_parcel'] ?? null, + $data['active_cargo'] ?? null, + ); + } + + /** + * @param array $data + */ + public function createOption(array $data): ServiceOption + { + return new ServiceOption( + $data['code'], + $data['name'], + ); + } + + /** + * @param array $data + */ + private function createOptionCollection(CarrierType $carrier, array $data): ServiceOptionCollection + { + return new ServiceOptionCollection( + array_map(fn(array $data): ServiceOption => $this->createOption($data), $data['services'] ?? []) + ); + } +} diff --git a/src/Model/Service/Service.php b/src/Model/Service/Service.php new file mode 100644 index 0000000..13a2f51 --- /dev/null +++ b/src/Model/Service/Service.php @@ -0,0 +1,49 @@ + + */ +final class Service extends BaseModel implements ServiceType +{ + /** + * @param array|null $countries + * @param array<\Inspirum\Balikobot\Model\Country\CodCountry>|null $codCountries + */ + public function __construct( + public readonly string $type, + public readonly ?string $name, + public readonly ?ServiceOptionCollection $options = null, + public readonly ?array $countries = null, + public readonly ?array $codCountries = null, + ) { + } + + public static function from(string $value): static + { + return new self($value, null); + } + + public function getValue(): string + { + return $this->type; + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'type' => $this->type, + 'name' => $this->name, + 'options' => $this->options?->toArray(), + 'countries' => $this->countries, + 'codCountries' => $this->codCountries, + ]; + } +} diff --git a/src/Model/Service/ServiceCollection.php b/src/Model/Service/ServiceCollection.php new file mode 100644 index 0000000..fbe61de --- /dev/null +++ b/src/Model/Service/ServiceCollection.php @@ -0,0 +1,51 @@ + + */ +final class ServiceCollection extends BaseCollection +{ + /** + * @param array $services + */ + public function __construct( + private readonly CarrierType $carrier, + private readonly array $services, + private readonly ?bool $parcel = null, + private readonly ?bool $cargo = null, + ) { + parent::__construct($this->services); + } + + public function getCarrier(): CarrierType + { + return $this->carrier; + } + + /** + * @return array<\Inspirum\Balikobot\Client\Request\ServiceType> + */ + public function getServiceTypes(): array + { + return array_map(static fn(Service $service): ServiceType => $service, $this->services); + } + + public function supportsParcel(): ?bool + { + return $this->parcel; + } + + public function supportsCargo(): ?bool + { + return $this->cargo; + } +} diff --git a/src/Model/Service/ServiceFactory.php b/src/Model/Service/ServiceFactory.php new file mode 100644 index 0000000..010e240 --- /dev/null +++ b/src/Model/Service/ServiceFactory.php @@ -0,0 +1,20 @@ + $data + */ + public function create(CarrierType $carrier, array $data): Service; + + /** + * @param array $data + */ + public function createCollection(CarrierType $carrier, array $data): ServiceCollection; +} diff --git a/src/Model/Service/ServiceOption.php b/src/Model/Service/ServiceOption.php new file mode 100644 index 0000000..ecdc970 --- /dev/null +++ b/src/Model/Service/ServiceOption.php @@ -0,0 +1,28 @@ + + */ +final class ServiceOption extends BaseModel +{ + public function __construct( + public readonly string $code, + public readonly string $name, + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'code' => $this->code, + 'name' => $this->name, + ]; + } +} diff --git a/src/Model/Service/ServiceOptionCollection.php b/src/Model/Service/ServiceOptionCollection.php new file mode 100644 index 0000000..027a530 --- /dev/null +++ b/src/Model/Service/ServiceOptionCollection.php @@ -0,0 +1,14 @@ + + */ +final class ServiceOptionCollection extends BaseCollection +{ +} diff --git a/src/Model/Status/DefaultPackageStatusFactory.php b/src/Model/Status/DefaultPackageStatusFactory.php new file mode 100644 index 0000000..65b5af3 --- /dev/null +++ b/src/Model/Status/DefaultPackageStatusFactory.php @@ -0,0 +1,113 @@ +validator->validateResponseStatus($data, $response); + + try { + return new Status( + $carrier, + (string) $data['carrier_id'], + (float) $data['status_id'], + (string) $data['status_text'], + (string) $data['status_text'], + 'event', + null, + ); + } catch (Throwable $exception) { + throw new BadRequestException($response, previous: $exception); + } + } + + /** @inheritDoc */ + public function createCollection(CarrierType $carrier, array $carrierIds, array $data): StatusesCollection + { + $packages = $data['packages'] ?? []; + $this->validator->validateIndexes($packages, count($carrierIds)); + + $statuses = new StatusesCollection($carrier, array_map( + fn(array $status): Statuses => $this->createStatuses($carrier, $status, $data), + $packages, + )); + + return $statuses; + } + + /** + * @param array>> $data + * @param array $response + * + * @throws \Inspirum\Balikobot\Exception\Exception + */ + private function createStatuses(CarrierType $carrier, array $data, array $response = []): Statuses + { + $this->validator->validateResponseStatus($data, $response); + assert(is_string($data['carrier_id'])); + assert(is_array($data['states'] ?? [])); + + return new Statuses( + $carrier, + (string) $data['carrier_id'], + array_map( + fn(array $status): Status => $this->create($carrier, (string) $data['carrier_id'], $status, $response), + $data['states'] ?? [], + ), + ); + } + + /** @inheritDoc */ + public function createLastStatusCollection(CarrierType $carrier, array $carrierIds, array $data): StatusCollection + { + $packages = $data['packages'] ?? []; + $this->validator->validateIndexes($packages, count($carrierIds)); + + $statuses = new StatusCollection($carrier, array_map( + fn(array $status): Status => $this->createLastStatus($carrier, $status, $data), + $packages, + )); + + return $statuses; + } +} diff --git a/src/Model/Status/PackageStatusFactory.php b/src/Model/Status/PackageStatusFactory.php new file mode 100644 index 0000000..9194700 --- /dev/null +++ b/src/Model/Status/PackageStatusFactory.php @@ -0,0 +1,34 @@ + $data + * @param array $response + */ + public function create(CarrierType $carrier, string $carrierId, array $data, array $response = []): Status; + + /** + * @param array $data + * @param array $response + */ + public function createLastStatus(CarrierType $carrier, array $data, array $response = []): Status; + + /** + * @param array $carrierIds + * @param array $data + */ + public function createCollection(CarrierType $carrier, array $carrierIds, array $data): StatusesCollection; + + /** + * @param array $carrierIds + * @param array $data + */ + public function createLastStatusCollection(CarrierType $carrier, array $carrierIds, array $data): StatusCollection; +} diff --git a/src/Model/Status/Status.php b/src/Model/Status/Status.php new file mode 100644 index 0000000..9e8f318 --- /dev/null +++ b/src/Model/Status/Status.php @@ -0,0 +1,51 @@ + + */ +final class Status extends BaseModel implements WithCarrierId +{ + public function __construct( + public readonly CarrierType $carrier, + public readonly string $carrierId, + public readonly float $id, + public readonly string $name, + public readonly string $description, + public readonly string $type, + public readonly ?DateTimeInterface $date, + ) { + } + + public function getCarrier(): CarrierType + { + return $this->carrier; + } + + public function getCarrierId(): string + { + return $this->carrierId; + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'carrier' => $this->carrier->getValue(), + 'carrierId' => $this->carrierId, + 'id' => $this->id, + 'name' => $this->name, + 'description' => $this->description, + 'type' => $this->type, + 'date' => $this->date?->format(DateTimeInterface::ATOM), + ]; + } +} diff --git a/src/Model/Status/StatusCollection.php b/src/Model/Status/StatusCollection.php new file mode 100644 index 0000000..ccf8833 --- /dev/null +++ b/src/Model/Status/StatusCollection.php @@ -0,0 +1,14 @@ + + */ +final class StatusCollection extends BasePerCarrierCollection +{ +} diff --git a/src/Model/Status/Statuses.php b/src/Model/Status/Statuses.php new file mode 100644 index 0000000..0a44283 --- /dev/null +++ b/src/Model/Status/Statuses.php @@ -0,0 +1,92 @@ + + */ +final class Statuses extends BaseCollection implements WithCarrierId +{ + /** + * @param array<\Inspirum\Balikobot\Model\Status\Status> $states + */ + public function __construct( + private CarrierType $carrier, + private string $carrierId, + array $states, + ) { + parent::__construct([]); + + foreach ($states as $key => $value) { + $this->offsetSet($key, $value); + } + } + + public function offsetSet(mixed $key, mixed $value): void + { + $this->validateCarrierId($value); + + parent::offsetSet($key, $value); + } + + public function offsetAdd(mixed $value): void + { + $this->validateCarrierId($value); + + parent::offsetAdd($value); + } + + /** + * @throws \InvalidArgumentException + */ + private function validateCarrierId(Status $item): void + { + if ($this->carrierId !== $item->getCarrierId()) { + throw new InvalidArgumentException( + sprintf( + 'Item carrier ID mismatch ("%s" instead "%s")', + $item->getCarrierId(), + $this->carrierId, + ) + ); + } + } + + public function getCarrier(): CarrierType + { + return $this->carrier; + } + + public function getCarrierId(): string + { + return $this->carrierId; + } + + /** + * @return array<\Inspirum\Balikobot\Model\Status\Status> + */ + public function getStates(): array + { + return $this->items; + } + + /** + * @return array> + */ + public function __toArray(): array + { + return [ + 'carrier' => $this->carrier->getValue(), + 'carrierId' => $this->carrierId, + 'states' => parent::__toArray(), + ]; + } +} diff --git a/src/Model/Status/StatusesCollection.php b/src/Model/Status/StatusesCollection.php new file mode 100644 index 0000000..a89a669 --- /dev/null +++ b/src/Model/Status/StatusesCollection.php @@ -0,0 +1,14 @@ + + */ +final class StatusesCollection extends BasePerCarrierCollection +{ +} diff --git a/src/Model/TransportCost/DefaultTransportCostFactory.php b/src/Model/TransportCost/DefaultTransportCostFactory.php new file mode 100644 index 0000000..afdba3e --- /dev/null +++ b/src/Model/TransportCost/DefaultTransportCostFactory.php @@ -0,0 +1,42 @@ + new TransportCostPart($part['name'], $part['cost'], $data['currency']), $data['costs_breakdown'] ?? []) + ); + } + + /** @inheritDoc */ + public function createCollection(CarrierType $carrier, array $data): TransportCostCollection + { + unset($data['status']); + +// $this->validator->validateIndexes($data, count($packages)); + +// $this->validator->validateResponseItemHasAttribute($data, 'eid', $data); + + $transportCosts = new TransportCostCollection($carrier); + + foreach ($data as $package) { + $transportCost = $this->create($carrier, $package); + $transportCosts->offsetAdd($transportCost); + } + + return $transportCosts; + } +} diff --git a/src/Model/TransportCost/TransportCost.php b/src/Model/TransportCost/TransportCost.php new file mode 100644 index 0000000..7090ff1 --- /dev/null +++ b/src/Model/TransportCost/TransportCost.php @@ -0,0 +1,40 @@ + + */ +class TransportCost extends BaseModel +{ + /** + * @param array<\Inspirum\Balikobot\Model\TransportCost\TransportCostPart> $costsBreakdown + */ + public function __construct( + public readonly string $batchId, + public readonly CarrierType $carrier, + public readonly float $totalCost, + public readonly string $currencyCode, + public readonly array $costsBreakdown = [] + ) { + } + + /** + * @return array + */ + public function __toArray(): array + { + return [ + 'batchId' => $this->batchId, + 'carrier' => $this->carrier->getValue(), + 'totalCost' => $this->totalCost, + 'currencyCode' => $this->currencyCode, + 'costsBreakdown' => $this->costsBreakdown, + ]; + } +} diff --git a/src/Model/TransportCost/TransportCostCollection.php b/src/Model/TransportCost/TransportCostCollection.php new file mode 100644 index 0000000..25a9bdf --- /dev/null +++ b/src/Model/TransportCost/TransportCostCollection.php @@ -0,0 +1,60 @@ + + */ +class TransportCostCollection extends BaseCollection +{ + public function __construct( + private ?CarrierType $carrier, + ) { + parent::__construct([]); + } + + public function getCarrier(): CarrierType + { + return $this->carrier ?? throw new RuntimeException('Collection is empty'); + } + + /** + * @return array + */ + public function getBatchIds(): array + { + return array_map(static fn(TransportCost $transportCost) => $transportCost->batchId, $this->items); + } + + public function getTotalCost(): float + { + $totalCost = 0.0; + $currencyCode = $this->getCurrencyCode(); + + foreach ($this->getItems() as $cost) { + if ($cost->currencyCode !== $currencyCode) { + throw new RuntimeException('Package cost currency codes are not the same'); + } + + $totalCost += $cost->totalCost; + } + + return $totalCost; + } + + public function getCurrencyCode(): string + { + if (empty($this->costs)) { + throw new RuntimeException('Collection is empty'); + } + + return $this->costs[0]->currencyCode; + } +} diff --git a/src/Model/TransportCost/TransportCostFactory.php b/src/Model/TransportCost/TransportCostFactory.php new file mode 100644 index 0000000..0a9976c --- /dev/null +++ b/src/Model/TransportCost/TransportCostFactory.php @@ -0,0 +1,20 @@ + $data + */ + public function create(CarrierType $carrier, array $data): TransportCost; + + /** + * @param array $data + */ + public function createCollection(CarrierType $carrier, array $data): TransportCostCollection; +} diff --git a/src/Model/TransportCost/TransportCostPart.php b/src/Model/TransportCost/TransportCostPart.php new file mode 100644 index 0000000..a5f082f --- /dev/null +++ b/src/Model/TransportCost/TransportCostPart.php @@ -0,0 +1,30 @@ + + */ +class TransportCostPart extends BaseModel +{ + public function __construct( + private string $name, + private float $cost, + private string $currencyCode, + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'name' => $this->name, + 'cost' => $this->cost, + 'currencyCode' => $this->currencyCode, + ]; + } +} diff --git a/src/Model/Unit/DefaultUnitFactory.php b/src/Model/Unit/DefaultUnitFactory.php new file mode 100644 index 0000000..263be72 --- /dev/null +++ b/src/Model/Unit/DefaultUnitFactory.php @@ -0,0 +1,24 @@ + $this->create($unit), $data['units'] ?? []), + ); + } +} diff --git a/src/Model/Unit/Unit.php b/src/Model/Unit/Unit.php new file mode 100644 index 0000000..5754781 --- /dev/null +++ b/src/Model/Unit/Unit.php @@ -0,0 +1,28 @@ + + */ +final class Unit extends BaseModel +{ + public function __construct( + public readonly string $code, + public readonly string $name, + ) { + } + + /** @inheritDoc */ + public function __toArray(): array + { + return [ + 'code' => $this->code, + 'name' => $this->name, + ]; + } +} diff --git a/src/Model/Unit/UnitCollection.php b/src/Model/Unit/UnitCollection.php new file mode 100644 index 0000000..cd911c9 --- /dev/null +++ b/src/Model/Unit/UnitCollection.php @@ -0,0 +1,14 @@ + + */ +final class UnitCollection extends BaseCollection +{ +} diff --git a/src/Model/Unit/UnitFactory.php b/src/Model/Unit/UnitFactory.php new file mode 100644 index 0000000..6ab27a3 --- /dev/null +++ b/src/Model/Unit/UnitFactory.php @@ -0,0 +1,18 @@ + $data + */ + public function create(array $data): Unit; + + /** + * @param array $data + */ + public function createCollection(array $data): UnitCollection; +} diff --git a/src/Model/Values/AbstractPackage.php b/src/Model/Values/AbstractPackage.php deleted file mode 100644 index d360720..0000000 --- a/src/Model/Values/AbstractPackage.php +++ /dev/null @@ -1,93 +0,0 @@ - - */ -abstract class AbstractPackage implements ArrayAccess -{ - use CommonData; - - /** - * Package data - * - * @var array - */ - private array $data; - - /** - * Package constructor - * - * @param array $data - */ - public function __construct(array $data = []) - { - $this->data = $data; - } - - /** - * Determine if an item exists at an offset - * - * @param string $key - * - * @return bool - */ - public function offsetExists(mixed $key): bool - { - return array_key_exists($key, $this->data); - } - - /** - * Get an item at a given offset - * - * @param string $key - * - * @return mixed - */ - public function offsetGet(mixed $key): mixed - { - return $this->data[$key]; - } - - /** - * Set the item at a given offset - * - * @param string $key - * @param mixed $value - * - * @return void - */ - public function offsetSet(mixed $key, mixed $value): void - { - $this->data[$key] = $value; - } - - /** - * Unset the item at a given offset - * - * @param string $key - * - * @return void - */ - public function offsetUnset(mixed $key): void - { - unset($this->data[$key]); - } - - /** - * Get the collection of packages as a plain array - * - * @return array - */ - public function toArray(): array - { - return $this->data; - } -} diff --git a/src/Model/Values/AdrUnit.php b/src/Model/Values/AdrUnit.php deleted file mode 100644 index 955bbbd..0000000 --- a/src/Model/Values/AdrUnit.php +++ /dev/null @@ -1,164 +0,0 @@ -shipper = $shipper; - $this->id = $id; - $this->code = $code; - $this->name = $name; - $this->class = $class; - $this->packaging = $packaging; - $this->tunnelCode = $tunnelCode; - $this->transportCategory = $transportCategory; - } - - /** - * @return string - */ - public function getShipper(): string - { - return $this->shipper; - } - - /** - * @return string - */ - public function getId(): string - { - return $this->id; - } - - /** - * @return string - */ - public function getCode(): string - { - return $this->code; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getClass(): string - { - return $this->class; - } - - /** - * @return string|null - */ - public function getPackaging(): ?string - { - return $this->packaging; - } - - /** - * @return string|null - */ - public function getTunnelCode(): ?string - { - return $this->tunnelCode; - } - - /** - * @return string - */ - public function getTransportCategory(): string - { - return $this->transportCategory; - } - - /** - * New instance from data - * - * @param string $shipper - * @param array $data - * - * @return \Inspirum\Balikobot\Model\Values\AdrUnit - */ - public static function newInstanceFromData(string $shipper, array $data): self - { - return new self( - $shipper, - $data['id'], - $data['code'], - $data['name'], - $data['class'], - $data['packaging'], - $data['tunnel_code'], - $data['transport_category'], - ); - } -} diff --git a/src/Model/Values/Branch.php b/src/Model/Values/Branch.php deleted file mode 100644 index 3e21ad1..0000000 --- a/src/Model/Values/Branch.php +++ /dev/null @@ -1,606 +0,0 @@ -shipper = $shipper; - $this->service = $service; - $this->id = $id; - $this->uid = $uid; - $this->type = $type; - $this->name = $name; - $this->city = $city; - $this->street = $street; - $this->zip = $zip; - $this->cityPart = $cityPart; - $this->district = $district; - $this->region = $region; - $this->country = $country; - $this->currency = $currency; - $this->photoSmall = $photoSmall; - $this->photoBig = $photoBig; - $this->url = $url; - $this->latitude = $latitude; - $this->longitude = $longitude; - $this->directionsGlobal = $directionsGlobal; - $this->directionsCar = $directionsCar; - $this->directionsPublic = $directionsPublic; - $this->wheelchairAccessible = $wheelchairAccessible; - $this->claimAssistant = $claimAssistant; - $this->dressingRoom = $dressingRoom; - $this->openingMonday = $openingMonday; - $this->openingTuesday = $openingTuesday; - $this->openingWednesday = $openingWednesday; - $this->openingThursday = $openingThursday; - $this->openingFriday = $openingFriday; - $this->openingSaturday = $openingSaturday; - $this->openingSunday = $openingSunday; - $this->maxWeight = $maxWeight; - $this->branchId = $this->resolveBranchId(); - } - - /** - * @return string - */ - public function getShipper(): string - { - return $this->shipper; - } - - /** - * @return string|null - */ - public function getServiceType(): ?string - { - return $this->service; - } - - /** - * @return string - */ - public function getBranchId(): string - { - return $this->branchId; - } - - /** - * @return string|null - */ - public function getId(): ?string - { - return $this->id; - } - - /** - * @return string|null - */ - public function getUId(): ?string - { - return $this->uid; - } - - /** - * @return string - */ - public function getType(): string - { - return $this->type; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getCity(): string - { - return $this->city; - } - - /** - * @return string - */ - public function getStreet(): string - { - return $this->street; - } - - /** - * @return string - */ - public function getZip(): string - { - return $this->zip; - } - - /** - * @return string|null - */ - public function getCityPart(): ?string - { - return $this->cityPart; - } - - /** - * @return string|null - */ - public function getDistrict(): ?string - { - return $this->district; - } - - /** - * @return string|null - */ - public function getRegion(): ?string - { - return $this->region; - } - - /** - * @return string|null - */ - public function getCountry(): ?string - { - return $this->country; - } - - /** - * @return string|null - */ - public function getCurrency(): ?string - { - return $this->currency; - } - - /** - * @return string|null - */ - public function getPhotoSmall(): ?string - { - return $this->photoSmall; - } - - /** - * @return string|null - */ - public function getPhotoBig(): ?string - { - return $this->photoBig; - } - - /** - * @return string|null - */ - public function getUrl(): ?string - { - return $this->url; - } - - /** - * @return float|null - */ - public function getLatitude(): ?float - { - return $this->latitude; - } - - /** - * @return float|null - */ - public function getLongitude(): ?float - { - return $this->longitude; - } - - /** - * @return string|null - */ - public function getDirectionsGlobal(): ?string - { - return $this->directionsGlobal; - } - - /** - * @return string|null - */ - public function getDirectionsCar(): ?string - { - return $this->directionsCar; - } - - /** - * @return string|null - */ - public function getDirectionsPublic(): ?string - { - return $this->directionsPublic; - } - - /** - * @return bool|null - */ - public function getWheelchairAccessible(): ?bool - { - return $this->wheelchairAccessible; - } - - /** - * @return bool|null - */ - public function getClaimAssistant(): ?bool - { - return $this->claimAssistant; - } - - /** - * @return bool|null - */ - public function getDressingRoom(): ?bool - { - return $this->dressingRoom; - } - - /** - * @return string|null - */ - public function getOpeningMonday(): ?string - { - return $this->openingMonday; - } - - /** - * @return string|null - */ - public function getOpeningTuesday(): ?string - { - return $this->openingTuesday; - } - - /** - * @return string|null - */ - public function getOpeningWednesday(): ?string - { - return $this->openingWednesday; - } - - /** - * @return string|null - */ - public function getOpeningThursday(): ?string - { - return $this->openingThursday; - } - - /** - * @return string|null - */ - public function getOpeningFriday(): ?string - { - return $this->openingFriday; - } - - /** - * @return string|null - */ - public function getOpeningSaturday(): ?string - { - return $this->openingSaturday; - } - - /** - * @return string|null - */ - public function getOpeningSunday(): ?string - { - return $this->openingSunday; - } - - /** - * @return float|null - */ - public function getMaxWeight(): ?float - { - return $this->maxWeight; - } - - /** - * Resolve branch ID - * - * @return string - */ - private function resolveBranchId(): string - { - // get key used in branch_id when calling add request - if ( - $this->shipper === Shipper::CP - || $this->shipper === Shipper::SP - || ($this->shipper === Shipper::ULOZENKA && $this->service === ServiceType::ULOZENKA_CP_NP) - ) { - return str_replace(' ', '', $this->zip); - } - - if ($this->shipper === Shipper::PPL) { - return str_replace('KM', '', (string) $this->id); - } - - if ($this->shipper === Shipper::INTIME) { - return $this->name; - } - - return (string) $this->id; - } - - /** - * New instance from data - * - * @param string $shipper - * @param string|null $service - * @param array $data - * - * @return \Inspirum\Balikobot\Model\Values\Branch - */ - public static function newInstanceFromData(string $shipper, ?string $service, array $data): self - { - return BranchFactory::createFromData($shipper, $service, $data); - } -} diff --git a/src/Model/Values/Country.php b/src/Model/Values/Country.php deleted file mode 100644 index 53859fd..0000000 --- a/src/Model/Values/Country.php +++ /dev/null @@ -1,145 +0,0 @@ - - */ - private array $names; - - /** - * Alpha-2 country code - * - * @var string - */ - private string $code; - - /** - * Continent name - * - * @var string - */ - private string $continent; - - /** - * Phone prefixes - * - * @var array - */ - private array $phonePrefixes; - - /** - * Currency code - * - * @var string - */ - private string $currencyCode; - - /** - * Country constructor - * - * @param array $names - * @param string $code - * @param string $currencyCode - * @param array $phonePrefixes - * @param string $continent - */ - public function __construct( - array $names, - string $code, - string $currencyCode, - array $phonePrefixes, - string $continent - ) { - $this->names = $names; - $this->code = $code; - $this->currencyCode = $currencyCode; - $this->phonePrefixes = $phonePrefixes; - $this->continent = $continent; - } - - /** - * @return array - */ - public function getNames(): array - { - return $this->names; - } - - /** - * @param string $locale - * - * @return string|null - */ - public function getName(string $locale): ?string - { - return $this->names[$locale] ?? null; - } - - /** - * @return string - */ - public function getCode(): string - { - return $this->code; - } - - /** - * @return string - */ - public function getContinent(): string - { - return $this->continent; - } - - /** - * @return string - */ - public function getPhonePrefix(): string - { - return $this->phonePrefixes[0]; - } - - /** - * @return array - */ - public function getPhonePrefixes(): array - { - return $this->phonePrefixes; - } - - /** - * @return string - */ - public function getCurrencyCode(): string - { - return $this->currencyCode; - } - - /** - * @param array $data - * - * @return \Inspirum\Balikobot\Model\Values\Country - */ - public static function newInstanceFromData(array $data): self - { - return new self( - [ - 'cs' => $data['name_cz'], - 'en' => $data['name_en'], - ], - $data['iso_code'], - $data['currency'], - is_array($data['phone_prefix']) ? $data['phone_prefix'] : [$data['phone_prefix']], - $data['continent'] - ); - } -} diff --git a/src/Model/Values/OrderedPackage.php b/src/Model/Values/OrderedPackage.php deleted file mode 100644 index 8773195..0000000 --- a/src/Model/Values/OrderedPackage.php +++ /dev/null @@ -1,218 +0,0 @@ - - */ - private array $pieces; - - /** - * Final carrier ID - * - * @var string|null - */ - private ?string $finalCarrierId; - - /** - * Final track URL - * - * @var string|null - */ - private ?string $finalTrackUrl; - - /** - * OrderedPackage constructor - * - * @param string $packageId - * @param string $shipper - * @param string $batchId - * @param string $carrierId - * @param string|null $trackUrl - * @param string|null $labelUrl - * @param string|null $carrierIdSwap - * @param array $pieces - * @param string|null $finalCarrierId - * @param string|null $finalTrackUrl - */ - public function __construct( - string $packageId, - string $shipper, - string $batchId, - string $carrierId, - ?string $trackUrl = null, - ?string $labelUrl = null, - ?string $carrierIdSwap = null, - array $pieces = [], - ?string $finalCarrierId = null, - ?string $finalTrackUrl = null - ) { - $this->packageId = $packageId; - $this->shipper = $shipper; - $this->batchId = $batchId; - $this->carrierId = $carrierId; - $this->trackUrl = $trackUrl; - $this->labelUrl = $labelUrl; - $this->carrierIdSwap = $carrierIdSwap; - $this->pieces = $pieces; - $this->finalCarrierId = $finalCarrierId; - $this->finalTrackUrl = $finalTrackUrl; - } - - /** - * @return string - */ - public function getPackageId(): string - { - return $this->packageId; - } - - /** - * @return string - */ - public function getBatchId(): string - { - return $this->batchId; - } - - /** - * @return string - */ - public function getCarrierId(): string - { - return $this->carrierId; - } - - /** - * @return string|null - */ - public function getTrackUrl(): ?string - { - return $this->trackUrl; - } - - /** - * @return string|null - */ - public function getLabelUrl(): ?string - { - return $this->labelUrl; - } - - /** - * @return string|null - */ - public function getCarrierIdSwap(): ?string - { - return $this->carrierIdSwap; - } - - /** - * @return array - */ - public function getPieces(): array - { - return $this->pieces; - } - - /** - * @return string - */ - public function getShipper(): string - { - return $this->shipper; - } - - /** - * @return string|null - */ - public function getFinalCarrierId(): ?string - { - return $this->finalCarrierId; - } - - /** - * @return string|null - */ - public function getFinalTrackUrl(): ?string - { - return $this->finalTrackUrl; - } - - /** - * @param string $shipper - * @param array $data - * - * @return \Inspirum\Balikobot\Model\Values\OrderedPackage - */ - public static function newInstanceFromData(string $shipper, array $data): self - { - return new self( - (string) $data['package_id'], - $shipper, - $data['eid'], - (string) ($data['carrier_id'] ?? ''), - $data['track_url'] ?? null, - $data['label_url'] ?? null, - $data['carrier_id_swap'] ?? null, - $data['pieces'] ?? [], - $data['carrier_id_final'] ?? null, - $data['track_url_final'] ?? null - ); - } -} diff --git a/src/Model/Values/OrderedShipment.php b/src/Model/Values/OrderedShipment.php deleted file mode 100644 index c1a7e62..0000000 --- a/src/Model/Values/OrderedShipment.php +++ /dev/null @@ -1,133 +0,0 @@ - - */ - private array $packageIds; - - /** - * OrderedShipment constructor - * - * @param string $orderId - * @param string $shipper - * @param array $packageIds - * @param string $handoverUrl - * @param string $labelsUrl - * @param string|null $fileUrl - */ - public function __construct( - string $orderId, - string $shipper, - array $packageIds, - string $handoverUrl, - string $labelsUrl, - ?string $fileUrl = null - ) { - $this->orderId = $orderId; - $this->shipper = $shipper; - $this->packageIds = $packageIds; - $this->handoverUrl = $handoverUrl; - $this->labelsUrl = $labelsUrl; - $this->fileUrl = $fileUrl; - } - - /** - * @return string - */ - public function getOrderId(): string - { - return $this->orderId; - } - - /** - * @return string - */ - public function getHandoverUrl(): string - { - return $this->handoverUrl; - } - - /** - * @return string - */ - public function getLabelsUrl(): string - { - return $this->labelsUrl; - } - - /** - * @return string|null - */ - public function getFileUrl(): ?string - { - return $this->fileUrl; - } - - /** - * @return string - */ - public function getShipper(): string - { - return $this->shipper; - } - - /** - * Get package IDs - * - * @return array - */ - public function getPackageIds(): array - { - return $this->packageIds; - } - - /** - * @param string $shipper - * @param array $packageIds - * @param array $data - * - * @return \Inspirum\Balikobot\Model\Values\OrderedShipment - */ - public static function newInstanceFromData(string $shipper, array $packageIds, array $data): self - { - return new self( - $data['order_id'], - $shipper, - $packageIds, - $data['handover_url'], - $data['labels_url'], - $data['file_url'] ?? null - ); - } -} diff --git a/src/Model/Values/Package.php b/src/Model/Values/Package.php deleted file mode 100644 index 903d82b..0000000 --- a/src/Model/Values/Package.php +++ /dev/null @@ -1,24 +0,0 @@ -id = $id; - $this->type = $type; - $this->name = $name; - $this->description = $description; - $this->date = $date; - } - - /** - * @return float - */ - public function getId(): float - { - return $this->id; - } - - /** - * @return int - */ - public function getGroupId(): int - { - return (int) $this->id; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getType(): string - { - return $this->type; - } - - /** - * @return string - */ - public function getDescription(): string - { - return $this->description; - } - - /** - * @return \DateTime|null - */ - public function getDate(): ?DateTime - { - return $this->date; - } - - /** - * @param array $data - * - * @return \Inspirum\Balikobot\Model\Values\PackageStatus - */ - public static function newInstanceFromData(array $data): self - { - try { - $date = $data['date'] ? new DateTime($data['date']) : null; - } catch (Throwable) { - $date = null; - } - - return new self( - $data['status_id_v2'] ?? $data['status_id'], - $data['type'] ?? 'event', - $data['name_balikobot'] ?? ($data['name_internal'] ?? $data['name']), - $data['name'], - $date - ); - } -} diff --git a/src/Model/Values/PackageTransportCost.php b/src/Model/Values/PackageTransportCost.php deleted file mode 100644 index 07616f5..0000000 --- a/src/Model/Values/PackageTransportCost.php +++ /dev/null @@ -1,125 +0,0 @@ - - */ - private array $costsBreakdown; - - /** - * PackageTransportCost constructor - * - * @param string $batchId - * @param string $shipper - * @param float $totalCost - * @param string $currencyCode - * @param array<\Inspirum\Balikobot\Model\Values\PackageTransportCostPart> $costsBreakdown - */ - public function __construct( - string $batchId, - string $shipper, - float $totalCost, - string $currencyCode, - array $costsBreakdown = [] - ) { - $this->batchId = $batchId; - $this->shipper = $shipper; - $this->totalCost = $totalCost; - $this->currencyCode = $currencyCode; - $this->costsBreakdown = $costsBreakdown; - } - - /** - * @return string - */ - public function getBatchId(): string - { - return $this->batchId; - } - - /** - * @return string - */ - public function getShipper(): string - { - return $this->shipper; - } - - /** - * @return float - */ - public function getTotalCost(): float - { - return $this->totalCost; - } - - /** - * @return string - */ - public function getCurrencyCode(): string - { - return $this->currencyCode; - } - - /** - * @return array<\Inspirum\Balikobot\Model\Values\PackageTransportCostPart> - */ - public function getCostsBreakdown(): array - { - return $this->costsBreakdown; - } - - /** - * @param string $shipper - * @param array $data - * - * @return \Inspirum\Balikobot\Model\Values\PackageTransportCost - */ - public static function newInstanceFromData(string $shipper, array $data): self - { - return new self( - $data['eid'], - $shipper, - $data['costs_total'], - $data['currency'], - array_map(static fn(array $part) => new PackageTransportCostPart($part['name'], $part['cost'], $data['currency']), $data['costs_breakdown'] ?? []) - ); - } -} diff --git a/src/Model/Values/PackageTransportCostPart.php b/src/Model/Values/PackageTransportCostPart.php deleted file mode 100644 index ed30721..0000000 --- a/src/Model/Values/PackageTransportCostPart.php +++ /dev/null @@ -1,67 +0,0 @@ -name = $name; - $this->cost = $cost; - $this->currencyCode = $currencyCode; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return float - */ - public function getCost(): float - { - return $this->cost; - } - - /** - * @return string - */ - public function getCurrencyCode(): string - { - return $this->currencyCode; - } -} diff --git a/src/Model/Values/PostCode.php b/src/Model/Values/PostCode.php deleted file mode 100644 index 6e74f49..0000000 --- a/src/Model/Values/PostCode.php +++ /dev/null @@ -1,150 +0,0 @@ -shipper = $shipper; - $this->service = $service; - $this->postcode = $postcode; - $this->postcodeEnd = $postcodeEnd; - $this->city = $city; - $this->country = $country; - $this->morningDelivery = $morningDelivery; - } - - /** - * @return string - */ - public function getShipper(): string - { - return $this->shipper; - } - - /** - * @return string|null - */ - public function getService(): ?string - { - return $this->service; - } - - /** - * @return string - */ - public function getPostcode(): string - { - return $this->postcode; - } - - /** - * @return string|null - */ - public function getPostcodeEnd(): ?string - { - return $this->postcodeEnd; - } - - /** - * @return string|null - */ - public function getCity(): ?string - { - return $this->city; - } - - /** - * @return string|null - */ - public function getCountry(): ?string - { - return $this->country; - } - - /** - * @return bool - */ - public function isMorningDelivery(): bool - { - return $this->morningDelivery; - } - - /** - * New instance from data - * - * @param string $shipper - * @param string|null $service - * @param array $data - * - * @return \Inspirum\Balikobot\Model\Values\PostCode - */ - public static function newInstanceFromData(string $shipper, ?string $service, array $data): self - { - return new self( - $shipper, - $service, - $data['postcode'], - $data['postcode_end'] ?? null, - $data['city'] ?? null, - $data['country'] ?? null, - $data['1B'] ?? false - ); - } -} diff --git a/src/Model/WithCarrierId.php b/src/Model/WithCarrierId.php new file mode 100644 index 0000000..1739de4 --- /dev/null +++ b/src/Model/WithCarrierId.php @@ -0,0 +1,14 @@ +client->call(Version::V2V1, null, Request::INFO_WHO_AM_I); + + return $this->accountFactory->create($response); + } + + public function getCarriers(): CarrierCollection + { + $response = $this->client->call(Version::V2V1, null, Request::INFO_CARRIERS); + + return $this->carrierFactory->createCollection($response); + } + + public function getCarrier(CarrierType $carrier): Carrier + { + $response = $this->client->call(Version::V2V1, null, Request::INFO_CARRIERS, path: $carrier->getValue()); + + return $this->carrierFactory->create($carrier, $response); + } + + public function getChangelog(): ChangelogCollection + { + $response = $this->client->call(Version::V2V1, null, Request::CHANGELOG); + + return $this->changelogFactory->createCollection($response); + } +} diff --git a/src/Service/DefaultTrackService.php b/src/Service/DefaultTrackService.php index cdac1d5..11eb6eb 100644 --- a/src/Service/DefaultTrackService.php +++ b/src/Service/DefaultTrackService.php @@ -5,52 +5,43 @@ namespace Inspirum\Balikobot\Service; use Inspirum\Balikobot\Client\Client; +use Inspirum\Balikobot\Client\Request\CarrierType; use Inspirum\Balikobot\Definitions\Request; use Inspirum\Balikobot\Definitions\Version; -use Inspirum\Balikobot\Model\Aggregates\OrderedPackageCollection; -use Inspirum\Balikobot\Model\PackageStatus; -use Inspirum\Balikobot\Model\PackageStatusFactory; -use Inspirum\Balikobot\Model\Values\OrderedPackage; -use Inspirum\Balikobot\Response\Validator; -use function count; +use Inspirum\Balikobot\Model\Package\Package; +use Inspirum\Balikobot\Model\Package\PackageCollection; +use Inspirum\Balikobot\Model\Status\PackageStatusFactory; +use Inspirum\Balikobot\Model\Status\Status; +use Inspirum\Balikobot\Model\Status\StatusCollection; +use Inspirum\Balikobot\Model\Status\Statuses; +use Inspirum\Balikobot\Model\Status\StatusesCollection; +use OutOfBoundsException; class DefaultTrackService implements TrackService { public function __construct( private Client $client, - private Validator $validator, private PackageStatusFactory $packageStatusFactory, ) { } - /** - * @inheritDoc - */ - public function trackPackage(OrderedPackage $package): array + public function trackPackage(Package $package): Statuses { return $this->trackPackageById($package->carrier, $package->carrierId); } - /** - * @inheritDoc - */ - public function trackPackageById(string $carrier, string $carrierId): array + public function trackPackageById(CarrierType $carrier, string $carrierId): Statuses { - return $this->trackPackagesByIds($carrier, [$carrierId])[0]; + return $this->trackPackagesByIds($carrier, [$carrierId])->getForCarrierId($carrierId) ?? throw new OutOfBoundsException(); } - /** - * @inheritDoc - */ - public function trackPackages(OrderedPackageCollection $packages): array + public function trackPackages(PackageCollection $packages): StatusesCollection { return $this->trackPackagesByIds($packages->getCarrier(), $packages->getCarrierIds()); } - /** - * @inheritDoc - */ - public function trackPackagesByIds(string $carrier, array $carrierIds): array + /** @inheritDoc */ + public function trackPackagesByIds(CarrierType $carrier, array $carrierIds): StatusesCollection { $response = $this->client->call( Version::V2V2, @@ -60,44 +51,26 @@ public function trackPackagesByIds(string $carrier, array $carrierIds): array shouldHaveStatus: false, ); - $packages = $response['packages'] ?? []; - $this->validator->validateIndexes($packages, count($carrierIds)); - - $statuses = []; - foreach ($packages as $packageIndex => $package) { - $this->validator->validateResponseStatus($package, $response); - - $statuses[(int) $packageIndex] = []; - foreach ($package['states'] ?? [] as $status) { - $statuses[(int) $packageIndex][] = $this->packageStatusFactory->createFromStatusData($status, $response); - } - } - - return $statuses; + return $this->packageStatusFactory->createCollection($carrier, $carrierIds, $response); } - public function trackPackageLastStatus(OrderedPackage $package): PackageStatus + public function trackPackageLastStatus(Package $package): Status { return $this->trackPackageLastStatusById($package->carrier, $package->carrierId); } - public function trackPackageLastStatusById(string $carrier, string $carrierId): PackageStatus + public function trackPackageLastStatusById(CarrierType $carrier, string $carrierId): Status { - return $this->trackPackagesLastStatusesByIds($carrier, [$carrierId])[0]; + return $this->trackPackagesLastStatusesByIds($carrier, [$carrierId])->getForCarrierId($carrierId) ?? throw new OutOfBoundsException(); } - /** - * @inheritDoc - */ - public function trackPackagesLastStatuses(OrderedPackageCollection $packages): array + public function trackPackagesLastStatuses(PackageCollection $packages): StatusCollection { return $this->trackPackagesLastStatusesByIds($packages->getCarrier(), $packages->getCarrierIds()); } - /** - * @inheritDoc - */ - public function trackPackagesLastStatusesByIds(string $carrier, array $carrierIds): array + /** @inheritDoc */ + public function trackPackagesLastStatusesByIds(CarrierType $carrier, array $carrierIds): StatusCollection { $response = $this->client->call( Version::V2V2, @@ -107,16 +80,6 @@ public function trackPackagesLastStatusesByIds(string $carrier, array $carrierId shouldHaveStatus: false, ); - $packages = $response['packages'] ?? []; - $this->validator->validateIndexes($packages, count($carrierIds)); - - $statuses = []; - foreach ($packages as $packageIndex => $status) { - $this->validator->validateResponseStatus($status, $response); - - $statuses[(int) $packageIndex] = $this->packageStatusFactory->createFromLastStatusData($status, $response); - } - - return $statuses; + return $this->packageStatusFactory->createLastStatusCollection($carrier, $carrierIds, $response); } } diff --git a/src/Service/InfoService.php b/src/Service/InfoService.php new file mode 100644 index 0000000..590fbab --- /dev/null +++ b/src/Service/InfoService.php @@ -0,0 +1,42 @@ + - * * @throws \Inspirum\Balikobot\Exception\Exception */ - public function trackPackage(OrderedPackage $package): array; + public function trackPackage(Package $package): Statuses; /** * Tracks a package by carrier ID * - * @return array<\Inspirum\Balikobot\Model\PackageStatus> - * * @throws \Inspirum\Balikobot\Exception\Exception */ - public function trackPackageById(string $carrier, string $carrierId): array; + public function trackPackageById(CarrierType $carrier, string $carrierId): Statuses; /** * Track packages * - * @return array> - * * @throws \Inspirum\Balikobot\Exception\Exception */ - public function trackPackages(OrderedPackageCollection $packages): array; + public function trackPackages(PackageCollection $packages): StatusesCollection; /** - * Tracks a packages by carrier IDs + * Track packages by carrier IDs * * @param array $carrierIds * - * @return array> - * * @throws \Inspirum\Balikobot\Exception\Exception */ - public function trackPackagesByIds(string $carrier, array $carrierIds): array; + public function trackPackagesByIds(CarrierType $carrier, array $carrierIds): StatusesCollection; /** * Track package last status * * @throws \Inspirum\Balikobot\Exception\Exception */ - public function trackPackageLastStatus(OrderedPackage $package): PackageStatus; + public function trackPackageLastStatus(Package $package): Status; /** * Track package last status by carrier ID * * @throws \Inspirum\Balikobot\Exception\Exception */ - public function trackPackageLastStatusById(string $carrier, string $carrierId): PackageStatus; + public function trackPackageLastStatusById(CarrierType $carrier, string $carrierId): Status; /** * Track packages last statuses * - * @return array<\Inspirum\Balikobot\Model\PackageStatus> - * * @throws \Inspirum\Balikobot\Exception\Exception */ - public function trackPackagesLastStatuses(OrderedPackageCollection $packages): array; + public function trackPackagesLastStatuses(PackageCollection $packages): StatusCollection; /** * Tracks a package, get the last info * * @param array $carrierIds * - * @return array<\Inspirum\Balikobot\Model\PackageStatus> - * * @throws \Inspirum\Balikobot\Exception\Exception */ - public function trackPackagesLastStatusesByIds(string $carrier, array $carrierIds): array; + public function trackPackagesLastStatusesByIds(CarrierType $carrier, array $carrierIds): StatusCollection; } diff --git a/tests/Unit/Balikobot/GetAccountInfoMethodTest.php b/tests/Unit/Balikobot/GetAccountInfoMethodTest.php deleted file mode 100644 index c280b7b..0000000 --- a/tests/Unit/Balikobot/GetAccountInfoMethodTest.php +++ /dev/null @@ -1,52 +0,0 @@ -newRequesterWithMockedRequestMethod(200, [ - 'status' => 200, - 'account' => [ - 'name' => 'Balikobot-Test_obchod.cz', - 'contact_person' => 'DPD_2', - 'street' => 'Kovářská 12', - 'city' => 'Praha 9', - 'zip' => '19000', - 'country' => 'CZ', - 'email' => 'info@balikobot.cz', - 'url' => 'http://www.balikobot_test2.cz', - 'phone' => '+420123456789', - ], - 'live_account' => false, - 'carriers' => [ - [ - 'name' => 'Česká pošta', - 'slug' => 'cp', - ], - [ - 'name' => 'PPL', - 'slug' => 'ppl', - ], - [ - 'name' => 'DPD', - 'slug' => 'dpd', - ], - ], - ], [ - 'https://apiv2.balikobot.cz/info/whoami', - [], - ]); - - $service = new Balikobot($requester); - - $service->getAccountInfo(); - - self::assertTrue(true); - } -} diff --git a/tests/Unit/Balikobot/GetActiveShippersMethodTest.php b/tests/Unit/Balikobot/GetActiveShippersMethodTest.php deleted file mode 100644 index 5dc7082..0000000 --- a/tests/Unit/Balikobot/GetActiveShippersMethodTest.php +++ /dev/null @@ -1,54 +0,0 @@ -newRequesterWithMockedRequestMethod(200, [ - 'status' => 200, - 'carriers' => [], - ], [ - 'https://apiv2.balikobot.cz/carriers/my', - [], - ]); - - $service = new Balikobot($requester); - - $service->getActiveShippers(); - - self::assertTrue(true); - } - - public function testResponseData(): void - { - $service = $this->newMockedBalikobot(200, [ - 'status' => 200, - 'carriers' => [ - 'cp', - 'ppl', - 'dpd', - 'geis', - 'gls', - ], - ]); - - $units = $service->getActiveShippers(); - - self::assertEquals( - [ - 'cp', - 'ppl', - 'dpd', - 'geis', - 'gls', - ], - $units, - ); - } -} diff --git a/tests/Unit/Balikobot/GetChangelogMethodTest.php b/tests/Unit/Balikobot/GetChangelogMethodTest.php deleted file mode 100644 index 0e33cf7..0000000 --- a/tests/Unit/Balikobot/GetChangelogMethodTest.php +++ /dev/null @@ -1,48 +0,0 @@ -newRequesterWithMockedRequestMethod(200, [ - 'status' => 200, - 'api_v1_documentation_cz' => 'https://balikobot.docs.apiary.io/', - 'api_v2_documentation_cz' => 'https://balikobotv2.docs.apiary.io/', - 'api_v1_documentation_en' => 'https://balikoboteng.docs.apiary.io/', - 'api_v2_documentation_en' => 'https://balikobotv2eng.docs.apiary.io/', - 'version' => '1.900', - 'date' => '2020-12-18', - 'versions' => [ - 0 => [ - 'version' => '1.900', - 'date' => '2020-12-18', - 'changes' => [ - 0 => [ - 'name' => 'ADD Zásilkovna', - 'description' => '- delivery_costs a delivery_costs_eur - přidání GB', - ], - 1 => [ - 'name' => 'ADD PbH', - 'description' => '- content data - přidání GB', - ], - ], - ], - ], - ], [ - 'https://apiv2.balikobot.cz/changelog', - [], - ]); - - $service = new Balikobot($requester); - - $service->getChangelog(); - - self::assertTrue(true); - } -} diff --git a/tests/Unit/BranchTest.php b/tests/Unit/BranchTest.php deleted file mode 100644 index 56e8e91..0000000 --- a/tests/Unit/BranchTest.php +++ /dev/null @@ -1,328 +0,0 @@ - '1234', - 'type' => 'type', - 'name' => 'name', - 'city' => 'city', - 'street' => 'street 27/8', - 'zip' => 'zip', - 'country' => 'country', - 'city_part' => 'city_part', - 'district' => 'district', - 'region' => 'region', - 'currency' => 'currency', - 'photo_small' => 'photo_small', - 'photo_big' => 'photo_big', - 'url' => 'url', - 'latitude' => 123.45, - 'longitude' => 67.890, - 'directions_global' => 'directions_global', - 'directions_car' => 'directions_car', - 'directions_public' => 'directions_public', - 'wheelchair_accessible' => false, - 'claim_assistant' => true, - 'dressing_room' => true, - 'opening_monday' => 'opening_monday', - 'opening_tuesday' => 'opening_tuesday', - 'opening_wednesday' => 'opening_wednesday', - 'opening_thursday' => 'opening_thursday', - 'opening_friday' => 'opening_friday', - 'opening_saturday' => 'opening_saturday', - 'opening_sunday' => 'opening_sunday', - 'max_weight' => '5', - ]); - - self::assertEquals('cp', $branch->getShipper()); - self::assertEquals('NP', $branch->getServiceType()); - self::assertEquals('1234', $branch->getId()); - self::assertEquals('type', $branch->getType()); - self::assertEquals('name', $branch->getName()); - self::assertEquals('city', $branch->getCity()); - self::assertEquals('street 27/8', $branch->getStreet()); - self::assertEquals('zip', $branch->getZip()); - self::assertEquals('country', $branch->getCountry()); - self::assertEquals('city_part', $branch->getCityPart()); - self::assertEquals('district', $branch->getDistrict()); - self::assertEquals('region', $branch->getRegion()); - self::assertEquals('currency', $branch->getCurrency()); - self::assertEquals('photo_small', $branch->getPhotoSmall()); - self::assertEquals('photo_big', $branch->getPhotoBig()); - self::assertEquals('url', $branch->getUrl()); - self::assertEquals(123.45, $branch->getLatitude()); - self::assertEquals(67.890, $branch->getLongitude()); - self::assertEquals('directions_global', $branch->getDirectionsGlobal()); - self::assertEquals('directions_car', $branch->getDirectionsCar()); - self::assertEquals('directions_public', $branch->getDirectionsPublic()); - self::assertEquals(false, $branch->getWheelchairAccessible()); - self::assertEquals(true, $branch->getClaimAssistant()); - self::assertEquals(true, $branch->getDressingRoom()); - self::assertEquals('opening_monday', $branch->getOpeningMonday()); - self::assertEquals('opening_tuesday', $branch->getOpeningTuesday()); - self::assertEquals('opening_wednesday', $branch->getOpeningWednesday()); - self::assertEquals('opening_thursday', $branch->getOpeningThursday()); - self::assertEquals('opening_friday', $branch->getOpeningFriday()); - self::assertEquals('opening_saturday', $branch->getOpeningSaturday()); - self::assertEquals('opening_sunday', $branch->getOpeningSunday()); - self::assertEquals(5.0, $branch->getMaxWeight()); - } - - public function testBranchUid(): void - { - $branch = Branch::newInstanceFromData('ppl', '2', [ - 'branch_uid' => '2-ppl-branch-KMBA01081885107', - 'branch_id' => 'KMBA01081885107', - 'id' => '1234', - ]); - - self::assertEquals('KMBA01081885107', $branch->getId()); - self::assertEquals('2-ppl-branch-KMBA01081885107', $branch->getUId()); - } - - public function testStaticConstructorWithMissingData(): void - { - $branch = Branch::newInstanceFromData('ppl', '1', [ - 'zip' => 'zip', - ]); - - self::assertEquals('ppl', $branch->getShipper()); - self::assertEquals('1', $branch->getServiceType()); - self::assertEquals(null, $branch->getId()); - self::assertEquals('branch', $branch->getType()); - self::assertEquals('zip', $branch->getName()); - self::assertEquals(null, $branch->getCity()); - self::assertEquals(null, $branch->getStreet()); - self::assertEquals('zip', $branch->getZip()); - self::assertEquals(null, $branch->getCountry()); - self::assertEquals(null, $branch->getCityPart()); - self::assertEquals(null, $branch->getDistrict()); - self::assertEquals(null, $branch->getRegion()); - self::assertEquals(null, $branch->getCurrency()); - self::assertEquals(null, $branch->getPhotoSmall()); - self::assertEquals(null, $branch->getPhotoBig()); - self::assertEquals(null, $branch->getUrl()); - self::assertEquals(null, $branch->getLatitude()); - self::assertEquals(null, $branch->getLongitude()); - self::assertEquals(null, $branch->getDirectionsGlobal()); - self::assertEquals(null, $branch->getDirectionsCar()); - self::assertEquals(null, $branch->getDirectionsPublic()); - self::assertEquals(null, $branch->getWheelchairAccessible()); - self::assertEquals(null, $branch->getClaimAssistant()); - self::assertEquals(null, $branch->getDressingRoom()); - self::assertEquals(null, $branch->getOpeningMonday()); - self::assertEquals(null, $branch->getOpeningTuesday()); - self::assertEquals(null, $branch->getOpeningWednesday()); - self::assertEquals(null, $branch->getOpeningThursday()); - self::assertEquals(null, $branch->getOpeningFriday()); - self::assertEquals(null, $branch->getOpeningSaturday()); - self::assertEquals(null, $branch->getOpeningSunday()); - self::assertEquals(null, $branch->getMaxWeight()); - } - - public function testStaticConstructorWithMissingDataForCPNP(): void - { - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - ]); - - self::assertEquals('cp', $branch->getShipper()); - self::assertEquals('NP', $branch->getServiceType()); - self::assertEquals(null, $branch->getId()); - self::assertEquals('branch', $branch->getType()); - self::assertEquals('zip', $branch->getName()); - self::assertEquals(null, $branch->getCity()); - self::assertEquals(null, $branch->getStreet()); - self::assertEquals('zip', $branch->getZip()); - self::assertEquals('CZ', $branch->getCountry()); - self::assertEquals(null, $branch->getCityPart()); - self::assertEquals(null, $branch->getDistrict()); - self::assertEquals(null, $branch->getRegion()); - self::assertEquals(null, $branch->getCurrency()); - self::assertEquals(null, $branch->getPhotoSmall()); - self::assertEquals(null, $branch->getPhotoBig()); - self::assertEquals(null, $branch->getUrl()); - self::assertEquals(null, $branch->getLatitude()); - self::assertEquals(null, $branch->getLongitude()); - self::assertEquals(null, $branch->getDirectionsGlobal()); - self::assertEquals(null, $branch->getDirectionsCar()); - self::assertEquals(null, $branch->getDirectionsPublic()); - self::assertEquals(null, $branch->getWheelchairAccessible()); - self::assertEquals(null, $branch->getClaimAssistant()); - self::assertEquals(null, $branch->getDressingRoom()); - self::assertEquals(null, $branch->getOpeningMonday()); - self::assertEquals(null, $branch->getOpeningTuesday()); - self::assertEquals(null, $branch->getOpeningWednesday()); - self::assertEquals(null, $branch->getOpeningThursday()); - self::assertEquals(null, $branch->getOpeningFriday()); - self::assertEquals(null, $branch->getOpeningSaturday()); - self::assertEquals(null, $branch->getOpeningSunday()); - self::assertEquals(null, $branch->getMaxWeight()); - } - - public function testStaticConstructorFallbackName(): void - { - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - 'address' => 'address', - ]); - - self::assertEquals('zip', $branch->getName()); - self::assertEquals('branch', $branch->getType()); - self::assertEquals('address', $branch->getStreet()); - } - - public function testStaticConstructorStreetNumber(): void - { - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - 'street' => 'street', - 'house_number' => '8', - 'orientation_number' => '896', - ]); - - self::assertEquals('street 8/896', $branch->getStreet()); - - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - 'street' => 'street', - 'house_number' => '8', - 'orientation_number' => '0', - ]); - - self::assertEquals('street 8', $branch->getStreet()); - - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - 'street' => 'street', - 'orientation_number' => '897', - ]); - - self::assertEquals('street 897', $branch->getStreet()); - - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - 'street' => 'street', - 'house_number' => '2', - ]); - - self::assertEquals('street 2', $branch->getStreet()); - - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - 'street' => 'street 1', - 'house_number' => '2', - 'orientation_number' => '3', - ]); - - self::assertEquals('street 1 2/3', $branch->getStreet()); - - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - 'address' => 'address', - 'house_number' => '2', - 'orientation_number' => '3', - ]); - - self::assertEquals('address', $branch->getStreet()); - - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - 'street' => '', - 'house_number' => '3', - 'orientation_number' => '4', - ]); - - self::assertEquals('3/4', $branch->getStreet()); - - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - 'city' => 'Vrbovec', - 'street' => '', - 'house_number' => '146', - 'orientation_number' => '0', - ]); - - self::assertEquals('Vrbovec 146', $branch->getStreet()); - - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'zip' => 'zip', - 'city' => 'Vrbovec', - 'street' => '', - 'address' => 'address', - 'house_number' => '147', - 'orientation_number' => '0', - ]); - - self::assertEquals('Vrbovec 147', $branch->getStreet()); - } - - public function testBranchIdResolver(): void - { - $branch = Branch::newInstanceFromData('cp', 'NP', [ - 'id' => 11, - 'name' => 'Branch Name', - 'zip' => '110 00', - ]); - - self::assertEquals('11000', $branch->getBranchId()); - - $branch = Branch::newInstanceFromData('sp', 'NP', [ - 'id' => '11', - 'name' => 'Branch Name', - 'zip' => '110 00', - ]); - - self::assertEquals('11000', $branch->getBranchId()); - - $branch = Branch::newInstanceFromData('ulozenka', '7', [ - 'id' => '11', - 'name' => 'Branch Name', - 'zip' => '110 00', - ]); - - self::assertEquals('11000', $branch->getBranchId()); - - $branch = Branch::newInstanceFromData('ppl', 'NP', [ - 'id' => 'KM1234', - 'name' => 'Branch Name', - 'zip' => '110 00', - ]); - - self::assertEquals('1234', $branch->getBranchId()); - - $branch = Branch::newInstanceFromData('ppl', 'NP', [ - 'id' => 'K1M234', - 'name' => 'Branch Name', - 'zip' => '110 00', - ]); - - self::assertEquals('K1M234', $branch->getBranchId()); - - $branch = Branch::newInstanceFromData('intime', 'NP', [ - 'id' => '11', - 'name' => 'Branch Name', - 'zip' => '110 00', - ]); - - self::assertEquals('Branch Name', $branch->getBranchId()); - - $branch = Branch::newInstanceFromData('zasilkovna', null, [ - 'id' => '167', - 'name' => 'Branch Name', - 'zip' => '110 00', - ]); - - self::assertEquals('167', $branch->getBranchId()); - } -} diff --git a/tests/Unit/Client/CurlRequesterTest.php b/tests/Unit/Client/CurlRequesterTest.php index a1beb25..82ecfbf 100644 --- a/tests/Unit/Client/CurlRequesterTest.php +++ b/tests/Unit/Client/CurlRequesterTest.php @@ -4,7 +4,7 @@ namespace Inspirum\Balikobot\Tests\Unit\Client; -use Inspirum\Balikobot\Client\CurlRequester; +use Inspirum\Balikobot\Client\DefaultCurlRequester; use Inspirum\Balikobot\Tests\BaseTestCase; use RuntimeException; @@ -14,7 +14,7 @@ public function testThrowsErrorOnRequestError(): void { $this->expectException(RuntimeException::class); - $requester = new CurlRequester('test', 'test'); + $requester = new DefaultCurlRequester('test', 'test'); $requester->request('dummy'); } diff --git a/tests/Unit/Client/DefaultClientTest.php b/tests/Unit/Client/DefaultClientTest.php index 960115a..7f25d5c 100644 --- a/tests/Unit/Client/DefaultClientTest.php +++ b/tests/Unit/Client/DefaultClientTest.php @@ -5,13 +5,13 @@ namespace Inspirum\Balikobot\Tests\Unit\Client; use Inspirum\Balikobot\Client\DefaultClient; +use Inspirum\Balikobot\Client\Response\Validator; use Inspirum\Balikobot\Definitions\Carrier; use Inspirum\Balikobot\Definitions\Request; use Inspirum\Balikobot\Definitions\Version; use Inspirum\Balikobot\Exception\BadRequestException; use Inspirum\Balikobot\Exception\Exception; use Inspirum\Balikobot\Exception\UnauthorizedException; -use Inspirum\Balikobot\Response\Validator; use Inspirum\Balikobot\Tests\BaseTestCase; use Throwable; use function gzcompress; @@ -21,8 +21,8 @@ final class DefaultClientTest extends BaseTestCase { /** - * @param array|string $response - * @param \Throwable|array|bool $result + * @param array|string $response + * @param \Throwable|array|bool $result * * @dataProvider providesTestCall() */ @@ -50,7 +50,7 @@ public function testCall( } /** - * @return iterable> + * @return iterable> */ public function providesTestCall(): iterable { @@ -172,7 +172,7 @@ public function testCallExceptions( } /** - * @return iterable> + * @return iterable> */ public function providerCallException(): iterable { diff --git a/tests/Unit/Client/GetAccountInfoMethodTest.php b/tests/Unit/Client/GetAccountInfoMethodTest.php deleted file mode 100644 index cbb7cf3..0000000 --- a/tests/Unit/Client/GetAccountInfoMethodTest.php +++ /dev/null @@ -1,110 +0,0 @@ -expectException(BadRequestException::class); - - $client = $this->newMockedClient(400, [ - 'status' => 200, - ]); - - $client->getAccountInfo(); - } - - public function testRequestShouldHaveStatus(): void - { - $this->expectException(BadRequestException::class); - - $client = $this->newMockedClient(200, []); - - $client->getAccountInfo(); - } - - public function testThrowsExceptionOnBadStatusCode(): void - { - $this->expectException(BadRequestException::class); - - $client = $this->newMockedClient(200, [ - 'status' => 400, - 'account' => [ - 'name' => 'Balikobot-Test_obchod.cz', - 'contact_person' => 'DPD_2', - 'street' => 'Kovářská 12', - 'city' => 'Praha 9', - 'zip' => '19000', - 'country' => 'CZ', - 'email' => 'info@balikobot.cz', - 'url' => 'http://www.balikobot_test2.cz', - 'phone' => '+420123456789', - ], - 'live_account' => false, - 'carriers' => [ - [ - 'name' => 'Česká pošta', - 'slug' => 'cp', - ], - [ - 'name' => 'PPL', - 'slug' => 'ppl', - ], - [ - 'name' => 'DPD', - 'slug' => 'dpd', - ], - ], - ]); - - $client->getAccountInfo(); - } - - public function testMakeRequest(): void - { - $requester = $this->newRequesterWithMockedRequestMethod(200, [ - 'status' => 200, - 'account' => [ - 'name' => 'Balikobot-Test_obchod.cz', - 'contact_person' => 'DPD_2', - 'street' => 'Kovářská 12', - 'city' => 'Praha 9', - 'zip' => '19000', - 'country' => 'CZ', - 'email' => 'info@balikobot.cz', - 'url' => 'http://www.balikobot_test2.cz', - 'phone' => '+420123456789', - ], - 'live_account' => false, - 'carriers' => [ - [ - 'name' => 'Česká pošta', - 'slug' => 'cp', - ], - [ - 'name' => 'PPL', - 'slug' => 'ppl', - ], - [ - 'name' => 'DPD', - 'slug' => 'dpd', - ], - ], - ], [ - 'https://apiv2.balikobot.cz/info/whoami', - [], - ]); - - $client = new Client($requester); - - $client->getAccountInfo(); - - self::assertTrue(true); - } -} diff --git a/tests/Unit/Client/GetActiveShippersMethodTest.php b/tests/Unit/Client/GetActiveShippersMethodTest.php deleted file mode 100644 index 70281ac..0000000 --- a/tests/Unit/Client/GetActiveShippersMethodTest.php +++ /dev/null @@ -1,99 +0,0 @@ -expectException(BadRequestException::class); - - $client = $this->newMockedClient(400, [ - 'status' => 200, - ]); - - $client->getActiveShippers(); - } - - public function testRequestShouldHaveStatus(): void - { - $this->expectException(BadRequestException::class); - - $client = $this->newMockedClient(200, []); - - $client->getActiveShippers(); - } - - public function testThrowsExceptionOnBadStatusCode(): void - { - $this->expectException(BadRequestException::class); - - $client = $this->newMockedClient(200, [ - 'status' => 400, - 'carriers' => [ - 'cp', - 'ppl', - 'dpd', - 'geis', - 'gls', - ], - ]); - - $client->getActiveShippers(); - } - - public function testMakeRequest(): void - { - $requester = $this->newRequesterWithMockedRequestMethod(200, [ - 'status' => 200, - 'carriers' => [ - 'cp', - 'ppl', - 'dpd', - 'geis', - 'gls', - ], - ], [ - 'https://apiv2.balikobot.cz/carriers/my', - [], - ]); - - $client = new Client($requester); - - $client->getActiveShippers(); - - self::assertTrue(true); - } - - public function testOnlyShippersAreReturned(): void - { - $client = $this->newMockedClient(200, [ - 'status' => 200, - 'carriers' => [ - 'cp', - 'ppl', - 'dpd', - 'geis', - 'gls', - ], - ]); - - $shippers = $client->getActiveShippers(); - - self::assertEquals( - [ - 'cp', - 'ppl', - 'dpd', - 'geis', - 'gls', - ], - $shippers, - ); - } -} diff --git a/tests/Unit/Client/GetChangelogMethodTest.php b/tests/Unit/Client/GetChangelogMethodTest.php deleted file mode 100644 index 7f96991..0000000 --- a/tests/Unit/Client/GetChangelogMethodTest.php +++ /dev/null @@ -1,87 +0,0 @@ -expectException(BadRequestException::class); - - $client = $this->newMockedClient(400, [ - 'status' => 200, - ]); - - $client->getChangelog(); - } - - public function testRequestShouldHaveStatus(): void - { - $this->expectException(BadRequestException::class); - - $client = $this->newMockedClient(200, []); - - $client->getChangelog(); - } - - public function testThrowsExceptionOnBadStatusCode(): void - { - $this->expectException(BadRequestException::class); - - $client = $this->newMockedClient(200, [ - 'status' => 400, - 'api_v1_documentation_cz' => 'https://balikobot.docs.apiary.io/', - 'api_v2_documentation_cz' => 'https://balikobotv2.docs.apiary.io/', - 'api_v1_documentation_en' => 'https://balikoboteng.docs.apiary.io/', - 'api_v2_documentation_en' => 'https://balikobotv2eng.docs.apiary.io/', - 'version' => '1.900', - 'date' => '2020-12-18', - 'versions' => [], - ]); - - $client->getChangelog(); - } - - public function testMakeRequest(): void - { - $requester = $this->newRequesterWithMockedRequestMethod(200, [ - 'status' => 200, - 'api_v1_documentation_cz' => 'https://balikobot.docs.apiary.io/', - 'api_v2_documentation_cz' => 'https://balikobotv2.docs.apiary.io/', - 'api_v1_documentation_en' => 'https://balikoboteng.docs.apiary.io/', - 'api_v2_documentation_en' => 'https://balikobotv2eng.docs.apiary.io/', - 'version' => '1.900', - 'date' => '2020-12-18', - 'versions' => [ - 0 => [ - 'version' => '1.900', - 'date' => '2020-12-18', - 'changes' => [ - 0 => [ - 'name' => 'ADD Zásilkovna', - 'description' => '- delivery_costs a delivery_costs_eur - přidání GB', - ], - 1 => [ - 'name' => 'ADD PbH', - 'description' => '- content data - přidání GB', - ], - ], - ], - ], - ], [ - 'https://apiv2.balikobot.cz/changelog', - [], - ]); - - $client = new Client($requester); - - $client->getChangelog(); - - self::assertTrue(true); - } -} diff --git a/tests/Unit/Model/DefaultBranchFactoryTest.php b/tests/Unit/Model/DefaultBranchFactoryTest.php new file mode 100644 index 0000000..e60ce71 --- /dev/null +++ b/tests/Unit/Model/DefaultBranchFactoryTest.php @@ -0,0 +1,350 @@ +newDefaultBranchFactory(); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'id' => '1234', + 'type' => 'type', + 'name' => 'name', + 'city' => 'city', + 'street' => 'street 27/8', + 'zip' => 'zip', + 'country' => 'country', + 'city_part' => 'city_part', + 'district' => 'district', + 'region' => 'region', + 'currency' => 'currency', + 'photo_small' => 'photo_small', + 'photo_big' => 'photo_big', + 'url' => 'url', + 'latitude' => 123.45, + 'longitude' => 67.890, + 'directions_global' => 'directions_global', + 'directions_car' => 'directions_car', + 'directions_public' => 'directions_public', + 'wheelchair_accessible' => false, + 'claim_assistant' => true, + 'dressing_room' => true, + 'opening_monday' => 'opening_monday', + 'opening_tuesday' => 'opening_tuesday', + 'opening_wednesday' => 'opening_wednesday', + 'opening_thursday' => 'opening_thursday', + 'opening_friday' => 'opening_friday', + 'opening_saturday' => 'opening_saturday', + 'opening_sunday' => 'opening_sunday', + 'max_weight' => '5', + ]); + + self::assertSame('cp', $branch->carrier->getValue()); + self::assertSame('NP', $branch->service?->getValue()); + self::assertSame('1234', $branch->id); + self::assertSame('type', $branch->type); + self::assertSame('name', $branch->name); + self::assertSame('city', $branch->city); + self::assertSame('street 27/8', $branch->street); + self::assertSame('zip', $branch->zip); + self::assertSame('country', $branch->country); + self::assertSame('city_part', $branch->cityPart); + self::assertSame('district', $branch->district); + self::assertSame('region', $branch->region); + self::assertSame('currency', $branch->currency); + self::assertSame('photo_small', $branch->photoSmall); + self::assertSame('photo_big', $branch->photoBig); + self::assertSame('url', $branch->url); + self::assertSame(123.45, $branch->latitude); + self::assertSame(67.890, $branch->longitude); + self::assertSame('directions_global', $branch->directionsGlobal); + self::assertSame('directions_car', $branch->directionsCar); + self::assertSame('directions_public', $branch->directionsPublic); + self::assertSame(false, $branch->wheelchairAccessible); + self::assertSame(true, $branch->claimAssistant); + self::assertSame(true, $branch->dressingRoom); + self::assertSame('opening_monday', $branch->openingMonday); + self::assertSame('opening_tuesday', $branch->openingTuesday); + self::assertSame('opening_wednesday', $branch->openingWednesday); + self::assertSame('opening_thursday', $branch->openingThursday); + self::assertSame('opening_friday', $branch->openingFriday); + self::assertSame('opening_saturday', $branch->openingSaturday); + self::assertSame('opening_sunday', $branch->openingSunday); + self::assertSame(5.0, $branch->maxWeight); + } + + public function testBranchUid(): void + { + $factory = $this->newDefaultBranchFactory(); + + $branch = $factory->createFromData(Carrier::from('ppl'), Service::from('2'), [ + 'branch_uid' => '2-ppl-branch-KMBA01081885107', + 'branch_id' => 'KMBA01081885107', + 'id' => '1234', + ]); + + self::assertSame('KMBA01081885107', $branch->id); + self::assertSame('2-ppl-branch-KMBA01081885107', $branch->uid); + } + + public function testStaticConstructorWithMissingData(): void + { + $factory = $this->newDefaultBranchFactory(); + + $branch = $factory->createFromData(Carrier::from('ppl'), Service::from('1'), [ + 'zip' => 'zip', + ]); + + self::assertSame('ppl', $branch->carrier->getValue()); + self::assertSame('1', $branch->service?->getValue()); + self::assertSame(null, $branch->id); + self::assertSame('branch', $branch->type); + self::assertSame('zip', $branch->name); + self::assertSame('', $branch->city); + self::assertSame('', $branch->street); + self::assertSame('zip', $branch->zip); + self::assertSame(null, $branch->country); + self::assertSame(null, $branch->cityPart); + self::assertSame(null, $branch->district); + self::assertSame(null, $branch->region); + self::assertSame(null, $branch->currency); + self::assertSame(null, $branch->photoSmall); + self::assertSame(null, $branch->photoBig); + self::assertSame(null, $branch->url); + self::assertSame(null, $branch->latitude); + self::assertSame(null, $branch->longitude); + self::assertSame(null, $branch->directionsGlobal); + self::assertSame(null, $branch->directionsCar); + self::assertSame(null, $branch->directionsPublic); + self::assertSame(null, $branch->wheelchairAccessible); + self::assertSame(null, $branch->claimAssistant); + self::assertSame(null, $branch->dressingRoom); + self::assertSame(null, $branch->openingMonday); + self::assertSame(null, $branch->openingTuesday); + self::assertSame(null, $branch->openingWednesday); + self::assertSame(null, $branch->openingThursday); + self::assertSame(null, $branch->openingFriday); + self::assertSame(null, $branch->openingSaturday); + self::assertSame(null, $branch->openingSunday); + self::assertSame(null, $branch->maxWeight); + } + + public function testStaticConstructorWithMissingDataForCPNP(): void + { + $factory = $this->newDefaultBranchFactory(); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + ]); + + self::assertSame('cp', $branch->carrier->getValue()); + self::assertSame('NP', $branch->service?->getValue()); + self::assertSame(null, $branch->id); + self::assertSame('branch', $branch->type); + self::assertSame('zip', $branch->name); + self::assertSame('', $branch->city); + self::assertSame('', $branch->street); + self::assertSame('zip', $branch->zip); + self::assertSame('CZ', $branch->country); + self::assertSame(null, $branch->cityPart); + self::assertSame(null, $branch->district); + self::assertSame(null, $branch->region); + self::assertSame(null, $branch->currency); + self::assertSame(null, $branch->photoSmall); + self::assertSame(null, $branch->photoBig); + self::assertSame(null, $branch->url); + self::assertSame(null, $branch->latitude); + self::assertSame(null, $branch->longitude); + self::assertSame(null, $branch->directionsGlobal); + self::assertSame(null, $branch->directionsCar); + self::assertSame(null, $branch->directionsPublic); + self::assertSame(null, $branch->wheelchairAccessible); + self::assertSame(null, $branch->claimAssistant); + self::assertSame(null, $branch->dressingRoom); + self::assertSame(null, $branch->openingMonday); + self::assertSame(null, $branch->openingTuesday); + self::assertSame(null, $branch->openingWednesday); + self::assertSame(null, $branch->openingThursday); + self::assertSame(null, $branch->openingFriday); + self::assertSame(null, $branch->openingSaturday); + self::assertSame(null, $branch->openingSunday); + self::assertSame(null, $branch->maxWeight); + } + + public function testStaticConstructorFallbackName(): void + { + $factory = $this->newDefaultBranchFactory(); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + 'address' => 'address', + ]); + + self::assertSame('zip', $branch->name); + self::assertSame('branch', $branch->type); + self::assertSame('address', $branch->street); + } + + public function testStaticConstructorStreetNumber(): void + { + $factory = $this->newDefaultBranchFactory(); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + 'street' => 'street', + 'house_number' => '8', + 'orientation_number' => '896', + ]); + + self::assertSame('street 8/896', $branch->street); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + 'street' => 'street', + 'house_number' => '8', + 'orientation_number' => '0', + ]); + + self::assertSame('street 8', $branch->street); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + 'street' => 'street', + 'orientation_number' => '897', + ]); + + self::assertSame('street 897', $branch->street); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + 'street' => 'street', + 'house_number' => '2', + ]); + + self::assertSame('street 2', $branch->street); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + 'street' => 'street 1', + 'house_number' => '2', + 'orientation_number' => '3', + ]); + + self::assertSame('street 1 2/3', $branch->street); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + 'address' => 'address', + 'house_number' => '2', + 'orientation_number' => '3', + ]); + + self::assertSame('address', $branch->street); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + 'street' => '', + 'house_number' => '3', + 'orientation_number' => '4', + ]); + + self::assertSame('3/4', $branch->street); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + 'city' => 'Vrbovec', + 'street' => '', + 'house_number' => '146', + 'orientation_number' => '0', + ]); + + self::assertSame('Vrbovec 146', $branch->street); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'zip' => 'zip', + 'city' => 'Vrbovec', + 'street' => '', + 'address' => 'address', + 'house_number' => '147', + 'orientation_number' => '0', + ]); + + self::assertSame('Vrbovec 147', $branch->street); + } + + public function testBranchIdResolver(): void + { + $factory = $this->newDefaultBranchFactory(); + + $branch = $factory->createFromData(Carrier::from('cp'), Service::from('NP'), [ + 'id' => 11, + 'name' => 'Branch Name', + 'zip' => '110 00', + ]); + + self::assertSame('11000', $branch->branchId); + + $branch = $factory->createFromData(Carrier::from('sp'), Service::from('NP'), [ + 'id' => '11', + 'name' => 'Branch Name', + 'zip' => '110 00', + ]); + + self::assertSame('11000', $branch->branchId); + + $branch = $factory->createFromData(Carrier::from('ulozenka'), Service::from('7'), [ + 'id' => '11', + 'name' => 'Branch Name', + 'zip' => '110 00', + ]); + + self::assertSame('11000', $branch->branchId); + + $branch = $factory->createFromData(Carrier::from('ppl'), Service::from('NP'), [ + 'id' => 'KM1234', + 'name' => 'Branch Name', + 'zip' => '110 00', + ]); + + self::assertSame('1234', $branch->branchId); + + $branch = $factory->createFromData(Carrier::from('ppl'), Service::from('NP'), [ + 'id' => 'K1M234', + 'name' => 'Branch Name', + 'zip' => '110 00', + ]); + + self::assertSame('K1M234', $branch->branchId); + + $branch = $factory->createFromData(Carrier::from('intime'), Service::from('NP'), [ + 'id' => '11', + 'name' => 'Branch Name', + 'zip' => '110 00', + ]); + + self::assertSame('Branch Name', $branch->branchId); + + $branch = $factory->createFromData(Carrier::from('zasilkovna'), null, [ + 'id' => '167', + 'name' => 'Branch Name', + 'zip' => '110 00', + ]); + + self::assertSame('167', $branch->branchId); + } + + private function newDefaultBranchFactory(): BranchFactory + { + return new DefaultBranchFactory(); + } +} diff --git a/tests/Unit/Model/DefaultPackageStatusFactoryTest.php b/tests/Unit/Model/DefaultPackageStatusFactoryTest.php index a7e4f5e..6d92f58 100644 --- a/tests/Unit/Model/DefaultPackageStatusFactoryTest.php +++ b/tests/Unit/Model/DefaultPackageStatusFactoryTest.php @@ -5,33 +5,38 @@ namespace Inspirum\Balikobot\Tests\Unit; use DateTimeImmutable; -use Inspirum\Balikobot\Model\DefaultPackageStatusFactory; -use Inspirum\Balikobot\Model\PackageStatus; -use Inspirum\Balikobot\Model\PackageStatusFactory; +use Inspirum\Balikobot\Client\Request\CarrierType; +use Inspirum\Balikobot\Client\Response\Validator; +use Inspirum\Balikobot\Model\Carrier\Carrier; +use Inspirum\Balikobot\Model\Status\DefaultPackageStatusFactory; +use Inspirum\Balikobot\Model\Status\PackageStatusFactory; +use Inspirum\Balikobot\Model\Status\Status; use Inspirum\Balikobot\Tests\BaseTestCase; final class DefaultPackageStatusFactoryTest extends BaseTestCase { /** - * @param array $data + * @param array $data * * @dataProvider providesTestCreateFromStatusData */ - public function testCreateFromStatusData(array $data, PackageStatus $expectedStatus): void + public function testCreateFromStatusData(CarrierType $carrier, string $carrierId, array $data, Status $expectedStatus): void { $factory = $this->newDefaultPackageStatusFactory(); - $status = $factory->createFromStatusData($data); + $status = $factory->create($carrier, $carrierId, $data); self::assertEquals($expectedStatus, $status); } /** - * @return iterable> + * @return iterable> */ public function providesTestCreateFromStatusData(): iterable { yield 'v2' => [ + 'carrier' => Carrier::from('cp'), + 'carrierId' => '1', 'data' => [ 'date' => '2018-11-07 14:15:01', 'name' => 'Doručení', @@ -39,18 +44,22 @@ public function providesTestCreateFromStatusData(): iterable 'status_id' => 2.1, 'type' => 'notification', ], - 'status' => new PackageStatus(2.1, 'Zásilka byla doručena příjemci.', 'Doručení', 'notification', new DateTimeImmutable('2018-11-07 14:15:01')), + 'status' => new Status(Carrier::from('cp'), '1', 2.1, 'Zásilka byla doručena příjemci.', 'Doručení', 'notification', new DateTimeImmutable('2018-11-07 14:15:01')), ]; yield 'missing_data' => [ + 'carrier' => Carrier::from('cp'), + 'carrierId' => '2', 'data' => [ 'name' => 'Doručení', 'status_id' => 2, ], - 'status' => new PackageStatus(2.0, 'Doručení', 'Doručení', 'event', null), + 'status' => new Status(Carrier::from('cp'), '2', 2.0, 'Doručení', 'Doručení', 'event', null), ]; yield 'v3' => [ + 'carrier' => Carrier::from('cp'), + 'carrierId' => '3', 'data' => [ 'date' => '2018-11-08 14:18:01', 'name' => 'Doručení', @@ -59,12 +68,14 @@ public function providesTestCreateFromStatusData(): iterable 'status_id_v2' => 2.3, 'type' => 'event', ], - 'status' => new PackageStatus(2.3, 'Zásilka byla doručena příjemci.', 'Doručení', 'event', new DateTimeImmutable('2018-11-08 14:18:01')), + 'status' => new Status(Carrier::from('cp'), '3', 2.3, 'Zásilka byla doručena příjemci.', 'Doručení', 'event', new DateTimeImmutable('2018-11-08 14:18:01')), ]; } private function newDefaultPackageStatusFactory(): PackageStatusFactory { - return new DefaultPackageStatusFactory(); + $validator = new Validator(); + + return new DefaultPackageStatusFactory($validator); } } diff --git a/tests/Unit/Service/DefaultInfoServiceTest.php b/tests/Unit/Service/DefaultInfoServiceTest.php new file mode 100644 index 0000000..a2e5687 --- /dev/null +++ b/tests/Unit/Service/DefaultInfoServiceTest.php @@ -0,0 +1,520 @@ + $response + * @param array $carrierIds + * @param array|null $request + * + * @dataProvider providesTestAccountInfo + */ + public function testAccountInfo( + int $statusCode, + array $response, + Account|Throwable|null $result, + ?array $request = null, + ): void { + if ($result instanceof Throwable) { + $this->expectException($result::class); + $this->expectExceptionMessage($result->getMessage()); + } + + $service = $this->newInfoService($statusCode, $response, $request); + + $res = $service->getAccountInfo(); + + if ($result !== null) { + self::assertEquals($result, $res); + } + } + + /** + * @return iterable> + */ + public function providesTestAccountInfo(): iterable + { + yield 'response_without_status' => [ + 'statusCode' => 200, + 'response' => [ + 'account' => [ + 'name' => 'Balikobot-Test_obchod.cz', + 'contact_person' => 'DPD_2', + 'street' => 'Kovářská 12', + 'city' => 'Praha 9', + 'zip' => '19000', + 'country' => 'CZ', + 'email' => 'info@balikobot.cz', + 'url' => 'http://www.balikobot_test2.cz', + 'phone' => '+420123456789', + ], + 'live_account' => false, + 'carriers' => [ + [ + 'name' => 'Česká pošta', + 'slug' => 'cp', + ], + [ + 'name' => 'PPL', + 'slug' => 'ppl', + ], + [ + 'name' => 'DPD', + 'slug' => 'dpd', + ], + ], + ], + 'result' => new BadRequestException([], 500), + 'request' => null, + ]; + + yield 'valid_request' => [ + 'statusCode' => 200, + 'response' => [ + 'status' => 200, + 'account' => [ + 'name' => 'Balikobot-Test_obchod.cz', + 'contact_person' => 'DPD_2', + 'street' => 'Kovářská 12', + 'city' => 'Praha 9', + 'zip' => '19000', + 'country' => 'CZ', + 'email' => 'info@balikobot.cz', + 'url' => 'http://www.balikobot_test2.cz', + 'phone' => '+420123456789', + ], + 'live_account' => false, + 'carriers' => [ + [ + 'name' => 'Česká pošta', + 'slug' => 'cp', + ], + [ + 'name' => 'PPL', + 'slug' => 'ppl', + ], + [ + 'name' => 'DPD', + 'slug' => 'dpd', + ], + ], + ], + 'result' => new Account( + 'Balikobot-Test_obchod.cz', + 'DPD_2', + 'info@balikobot.cz', + '+420123456789', + 'http://www.balikobot_test2.cz', + 'Kovářská 12', + 'Praha 9', + '19000', + 'CZ', + false, + new CarrierCollection([ + new Carrier( + 'cp', + 'Česká pošta', + ), + new Carrier( + 'ppl', + 'PPL', + ), + new Carrier( + 'dpd', + 'DPD', + ), + ]) + ), + 'request' => [ + 'https://apiv2.balikobot.cz/info/whoami', + ], + ]; + } + + /** + * @param array $response + * @param array $carrierIds + * @param array|null $request + * + * @dataProvider providesTestGetCarriers + */ + public function testGetCarriers( + int $statusCode, + array $response, + CarrierCollection|Throwable|null $result, + ?array $request = null, + ): void { + if ($result instanceof Throwable) { + $this->expectException($result::class); + $this->expectExceptionMessage($result->getMessage()); + } + + $service = $this->newInfoService($statusCode, $response, $request); + + $res = $service->getCarriers(); + + if ($result !== null) { + self::assertEquals($result, $res); + } + } + + /** + * @return iterable> + */ + public function providesTestGetCarriers(): iterable + { + yield 'response_without_status' => [ + 'statusCode' => 200, + 'response' => [ + 'carriers' => [ + [ + 'name' => 'Česká pošta', + 'slug' => 'cp', + 'endpoint' => 'https://api.balikobot.cz/cp', + ], + [ + 'name' => 'PPL', + 'slug' => 'ppl', + 'endpoint' => 'https://api.balikobot.cz/ppl', + ], + [ + 'name' => 'Magyar Posta', + 'slug' => 'magyarposta', + 'endpoint' => 'https://api.balikobot.cz/magyarposta', + ], + ], + ], + 'result' => new BadRequestException([], 500), + 'request' => null, + ]; + + yield 'valid_request' => [ + 'statusCode' => 200, + 'response' => [ + 'status' => 200, + 'carriers' => [ + [ + 'name' => 'Česká pošta', + 'slug' => 'cp', + 'endpoint' => 'https://api.balikobot.cz/cp', + ], + [ + 'name' => 'PPL', + 'slug' => 'ppl', + 'endpoint' => 'https://api.balikobot.cz/ppl', + ], + [ + 'name' => 'Magyar Posta', + 'slug' => 'magyarposta', + 'endpoint' => 'https://api.balikobot.cz/magyarposta', + ], + ], + ], + 'result' => new CarrierCollection([ + new Carrier( + 'cp', + 'Česká pošta', + ), + new Carrier( + 'ppl', + 'PPL', + ), + new Carrier( + 'magyarposta', + 'Magyar Posta', + ), + ]), + 'request' => [ + 'https://apiv2.balikobot.cz/info/carriers', + ], + ]; + } + + /** + * @param array $response + * @param array $carrierIds + * @param array|null $request + * + * @dataProvider providesTestGetCarrier + */ + public function testGetCarrier( + int $statusCode, + CarrierType $carrier, + array $response, + Carrier|Throwable|null $result, + ?array $request = null, + ): void { + if ($result instanceof Throwable) { + $this->expectException($result::class); + $this->expectExceptionMessage($result->getMessage()); + } + + $service = $this->newInfoService($statusCode, $response, $request); + + $res = $service->getCarrier($carrier); + + if ($result !== null) { + self::assertEquals($result, $res); + } + } + + /** + * @return iterable> + */ + public function providesTestGetCarrier(): iterable + { + yield 'response_without_status' => [ + 'statusCode' => 200, + 'carrier' => \Inspirum\Balikobot\Definitions\Carrier::ZASILKOVNA, + 'response' => [ + 'name' => 'Zásilkovna', + 'v2_methods_available' => true, + 'methods' => [ + [ + 'method' => 'ADD', + 'endpoint' => 'https://api.balikobot.cz/zasilkovna/add', + ], + [ + 'method' => 'TRACKSTATUS', + 'endpoint' => 'https://api.balikobot.cz/zasilkovna/trackstatus', + ], + ], + 'v2_methods' => [ + [ + 'method' => 'ADD', + 'endpoint' => 'https://api.balikobot.cz/v2/zasilkovna/add', + ], + [ + 'method' => 'DROP', + 'endpoint' => 'https://api.balikobot.cz/v2/zasilkovna/drop', + ], + ], + ], + 'result' => new BadRequestException([], 500), + 'request' => null, + ]; + + yield 'valid_request' => [ + 'statusCode' => 200, + 'carrier' => \Inspirum\Balikobot\Definitions\Carrier::ZASILKOVNA, + 'response' => [ + 'status' => 200, + 'name' => 'Zásilkovna', + 'v2_methods_available' => true, + 'methods' => [ + [ + 'method' => 'ADD', + 'endpoint' => 'https://api.balikobot.cz/zasilkovna/add', + ], + [ + 'method' => 'TRACKSTATUS', + 'endpoint' => 'https://api.balikobot.cz/zasilkovna/trackstatus', + ], + ], + 'v2_methods' => [ + [ + 'method' => 'ADD', + 'endpoint' => 'https://api.balikobot.cz/v2/zasilkovna/add', + ], + [ + 'method' => 'DROP', + 'endpoint' => 'https://api.balikobot.cz/v2/zasilkovna/drop', + ], + ], + ], + 'result' => new Carrier( + 'zasilkovna', + 'Zásilkovna', + [ + 'https://apiv2.balikobot.cz' => new MethodCollection([ + new Method('ADD'), + new Method('TRACKSTATUS'), + ]), + 'https://apiv2.balikobot.cz/v2' => new MethodCollection([ + new Method('ADD'), + new Method('DROP'), + ]), + ] + ), + 'request' => [ + 'https://apiv2.balikobot.cz/info/carriers/zasilkovna', + ], + ]; + } + + /** + * @param array $response + * @param array $carrierIds + * @param array|null $request + * + * @dataProvider providesTestGetChangelog + */ + public function testGetChangelog( + int $statusCode, + array $response, + ChangelogCollection|Throwable|null $result, + ?array $request = null, + ): void { + if ($result instanceof Throwable) { + $this->expectException($result::class); + $this->expectExceptionMessage($result->getMessage()); + } + + $service = $this->newInfoService($statusCode, $response, $request); + + $res = $service->getChangelog(); + + if ($result !== null) { + self::assertEquals($result, $res); + } + } + + /** + * @return iterable> + */ + public function providesTestGetChangelog(): iterable + { + yield 'response_without_status' => [ + 'statusCode' => 200, + 'response' => [ + 'api_v1_documentation_cz' => 'https://balikobot.docs.apiary.io/', + 'api_v2_documentation_cz' => 'https://balikobotv2.docs.apiary.io/', + 'api_v1_documentation_en' => 'https://balikoboteng.docs.apiary.io/', + 'api_v2_documentation_en' => 'https://balikobotv2eng.docs.apiary.io/', + 'version' => '1.900', + 'date' => '2020-12-18', + 'versions' => [ + 0 => [ + 'version' => '1.900', + 'date' => '2020-12-18', + 'changes' => [ + 0 => [ + 'name' => 'ADD Zásilkovna', + 'description' => '- delivery_costs a delivery_costs_eur - přidání GB', + ], + 1 => [ + 'name' => 'ADD PbH', + 'description' => '- content data - přidání GB', + ], + ], + ], + ], + ], + 'result' => new BadRequestException([], 500), + 'request' => null, + ]; + + yield 'valid_request' => [ + 'statusCode' => 200, + 'response' => [ + 'status' => 200, + 'status_message' => 'Operace proběhla v pořádku.', + 'api_v1_documentation_cz' => 'https://balikobot.docs.apiary.io/', + 'api_v2_documentation_cz' => 'https://balikobotv2.docs.apiary.io/', + 'api_v1_documentation_en' => 'https://balikoboteng.docs.apiary.io/', + 'api_v2_documentation_en' => 'https://balikobotv2eng.docs.apiary.io/', + 'version' => '1.900', + 'date' => '2020-12-18', + 'versions' => [ + 0 => [ + 'version' => '1.900', + 'date' => '2020-12-18', + 'changes' => [ + 0 => [ + 'name' => 'ADD Zásilkovna', + 'description' => '- delivery_costs a delivery_costs_eur - přidání GB', + ], + 1 => [ + 'name' => 'ADD PbH', + 'description' => '- content data - přidání GB', + ], + ], + ], + 1 => [ + 'version' => '1.899', + 'date' => '2020-12-07', + 'changes' => [ + 0 => [ + 'name' => 'ADD Gebrüder Weiss Česká republika', + 'description' => '- nový atribut rec_floor_number - číslo patra', + ], + ], + ], + ], + ], + 'result' => new ChangelogCollection([ + new Changelog( + '1.900', + new DateTimeImmutable('2020-12-18'), + new ChangelogStatusCollection([ + new ChangelogStatus( + 'ADD Zásilkovna', + '- delivery_costs a delivery_costs_eur - přidání GB', + ), + new ChangelogStatus( + 'ADD PbH', + '- content data - přidání GB', + ), + ]) + ), + new Changelog( + '1.899', + new DateTimeImmutable('2020-12-07'), + new ChangelogStatusCollection([ + new ChangelogStatus( + 'ADD Gebrüder Weiss Česká republika', + '- nový atribut rec_floor_number - číslo patra', + ), + ]) + ), + ]), + 'request' => [ + 'https://apiv2.balikobot.cz/changelog', + ], + ]; + } + + /** + * @param array|string $response + * @param array|null $request + */ + private function newInfoService(int $statusCode, array|string $response, ?array $request = null): InfoService + { + $requester = $this->newRequester($statusCode, $response, $request); + $validator = new Validator(); + $client = new DefaultClient($requester, $validator); + $methodFactory = new DefaultMethodFactory(); + $carrierFactory = new DefaultCarrierFactory($methodFactory); + $accountFactory = new DefaultAccountFactory($carrierFactory); + $changelogFactory = new DefaultChangelogFactory(); + + return new DefaultInfoService($client, $accountFactory, $carrierFactory, $changelogFactory); + } +} diff --git a/tests/Unit/Service/DefaultTrackServiceTest.php b/tests/Unit/Service/DefaultTrackServiceTest.php index ee09891..bca81e0 100644 --- a/tests/Unit/Service/DefaultTrackServiceTest.php +++ b/tests/Unit/Service/DefaultTrackServiceTest.php @@ -6,13 +6,17 @@ use DateTimeImmutable; use Inspirum\Balikobot\Client\DefaultClient; +use Inspirum\Balikobot\Client\Request\CarrierType; +use Inspirum\Balikobot\Client\Response\Validator; use Inspirum\Balikobot\Definitions\Carrier; use Inspirum\Balikobot\Exception\BadRequestException; -use Inspirum\Balikobot\Model\Aggregates\OrderedPackageCollection; -use Inspirum\Balikobot\Model\DefaultPackageStatusFactory; -use Inspirum\Balikobot\Model\PackageStatus; -use Inspirum\Balikobot\Model\Values\OrderedPackage; -use Inspirum\Balikobot\Response\Validator; +use Inspirum\Balikobot\Model\Package\Package; +use Inspirum\Balikobot\Model\Package\PackageCollection; +use Inspirum\Balikobot\Model\Status\DefaultPackageStatusFactory; +use Inspirum\Balikobot\Model\Status\Status; +use Inspirum\Balikobot\Model\Status\StatusCollection; +use Inspirum\Balikobot\Model\Status\Statuses; +use Inspirum\Balikobot\Model\Status\StatusesCollection; use Inspirum\Balikobot\Service\DefaultTrackService; use Inspirum\Balikobot\Tests\BaseTestCase; use Throwable; @@ -20,19 +24,18 @@ final class DefaultTrackServiceTest extends BaseTestCase { /** - * @param array $response - * @param array $carrierIds - * @param array>|\Throwable|null $result - * @param array|null $request + * @param array $response + * @param array $carrierIds + * @param array|null $request * * @dataProvider providesTestTrackPackagesByIds */ public function testTrackPackagesByIds( int $statusCode, array $response, - string $carrier, + CarrierType $carrier, array $carrierIds, - array|Throwable|null $result, + StatusesCollection|Throwable|null $result, ?array $request = null, ): void { if ($result instanceof Throwable) { @@ -50,7 +53,7 @@ public function testTrackPackagesByIds( } /** - * @return iterable> + * @return iterable> */ public function providesTestTrackPackagesByIds(): iterable { @@ -84,24 +87,31 @@ public function providesTestTrackPackagesByIds(): iterable ], 'carrier' => Carrier::CP, 'carrierIds' => ['1'], - 'result' => [ - 0 => [ - new PackageStatus( - 2.2, - 'Zásilka je v přepravě.', - 'Doručování zásilky', - 'event', - new DateTimeImmutable('2018-11-07 14:15:01'), - ), - new PackageStatus( - 1.2, - 'Zásilka byla doručena příjemci.', - 'Dodání zásilky. (77072 - Depo Olomouc 72)', - 'event', - new DateTimeImmutable('2018-11-08 18:00:00'), - ), - ], - ], + 'result' => new StatusesCollection( + Carrier::CP, + [ + new Statuses(Carrier::CP, '1', [ + new Status( + Carrier::CP, + '1', + 2.2, + 'Zásilka je v přepravě.', + 'Doručování zásilky', + 'event', + new DateTimeImmutable('2018-11-07 14:15:01'), + ), + new Status( + Carrier::CP, + '1', + 1.2, + 'Zásilka byla doručena příjemci.', + 'Dodání zásilky. (77072 - Depo Olomouc 72)', + 'event', + new DateTimeImmutable('2018-11-08 18:00:00'), + ), + ]), + ] + ), ]; yield 'missing_data_error' => [ @@ -347,49 +357,68 @@ public function testTrackPackagesByIdsProxy(): void $service = $this->createPartialMock(DefaultTrackService::class, ['trackPackagesByIds']); $expectedStatuses = [ - 0 => [ - new PackageStatus(1.1, 'name', 'desc', 'event', new DateTimeImmutable()), - ], - 1 => [ - new PackageStatus(1.1, 'name', 'desc', 'event', new DateTimeImmutable()), - new PackageStatus(2.0, 'name', 'desc', 'event', new DateTimeImmutable()), - ], + new StatusesCollection( + Carrier::PPL, + [ + new Statuses(Carrier::PPL, '1234', [ + new Status(Carrier::PPL, '1234', 1.1, 'name', 'desc', 'event', new DateTimeImmutable()), + ]), + ] + ), + new StatusesCollection( + Carrier::CP, + [ + new Statuses(Carrier::CP, '3456', [ + new Status(Carrier::CP, '3456', 1.1, 'name', 'desc', 'event', new DateTimeImmutable()), + ]), + ] + ), + new StatusesCollection( + Carrier::CP, + [ + new Statuses(Carrier::CP, 'Z123', [ + new Status(Carrier::ZASILKOVNA, 'Z123', 1.1, 'name', 'desc', 'event', new DateTimeImmutable()), + ]), + new Statuses(Carrier::CP, 'Z234', [ + new Status(Carrier::ZASILKOVNA, 'Z234', 2.0, 'name', 'desc', 'event', new DateTimeImmutable()), + ]), + ] + ), ]; $service->expects(self::exactly(3))->method('trackPackagesByIds')->withConsecutive( [Carrier::PPL, ['1234']], [Carrier::CP, ['3456']], [Carrier::ZASILKOVNA, ['Z123', 'Z234']], - )->willReturn($expectedStatuses); + )->willReturn(...$expectedStatuses); - $actualStatuses = $service->trackPackage(new OrderedPackage('1', '0001', Carrier::PPL, '1234')); - self::assertSame($expectedStatuses[0], $actualStatuses); + $actualStatuses = $service->trackPackage(new Package(Carrier::PPL, '1', '0001', '1234')); + self::assertSame($expectedStatuses[0][0], $actualStatuses); $actualStatuses = $service->trackPackageById(Carrier::CP, '3456'); - self::assertSame($expectedStatuses[0], $actualStatuses); + self::assertSame($expectedStatuses[1][0], $actualStatuses); - $packages = new OrderedPackageCollection(); - $packages->add(new OrderedPackage('1', '0001', Carrier::ZASILKOVNA, 'Z123')); - $packages->add(new OrderedPackage('2', '0001', Carrier::ZASILKOVNA, 'Z234')); + $packages = new PackageCollection(); + $packages->add(new Package(Carrier::ZASILKOVNA, '1', '0001', 'Z123')); + $packages->add(new Package(Carrier::ZASILKOVNA, '2', '0001', 'Z234')); $actualStatuses = $service->trackPackages($packages); - self::assertSame($expectedStatuses, $actualStatuses); + self::assertSame($expectedStatuses[2], $actualStatuses); } /** - * @param array $response - * @param array $carrierIds - * @param array|\Throwable|null $result - * @param array|null $request + * @param array $response + * @param array $carrierIds + * @param array|null $request * * @dataProvider providesTestTrackPackagesLastStatusesByIds */ public function testTrackPackagesLastStatusesByIds( int $statusCode, array $response, - string $carrier, + CarrierType $carrier, array $carrierIds, - array|Throwable|null $result, + StatusCollection|Throwable|null $result, ?array $request = null, ): void { if ($result instanceof Throwable) { @@ -407,7 +436,7 @@ public function testTrackPackagesLastStatusesByIds( } /** - * @return iterable> + * @return iterable> */ public function providesTestTrackPackagesLastStatusesByIds(): iterable { @@ -422,7 +451,7 @@ public function providesTestTrackPackagesLastStatusesByIds(): iterable 'status_text' => 'Zásilka byla doručena příjemci.', ], 1 => [ - 'carrier_id' => '1', + 'carrier_id' => '2', 'status' => 200, 'status_id' => 2.2, 'status_text' => 'Zásilka je v přepravě.', @@ -431,22 +460,29 @@ public function providesTestTrackPackagesLastStatusesByIds(): iterable ], 'carrier' => Carrier::CP, 'carrierIds' => ['1', '2'], - 'result' => [ - new PackageStatus( - 1.2, - 'Zásilka byla doručena příjemci.', - 'Zásilka byla doručena příjemci.', - 'event', - null, - ), - new PackageStatus( - 2.2, - 'Zásilka je v přepravě.', - 'Zásilka je v přepravě.', - 'event', - null, - ), - ], + 'result' => new StatusCollection( + Carrier::CP, + [ + new Status( + Carrier::CP, + '1', + 1.2, + 'Zásilka byla doručena příjemci.', + 'Zásilka byla doručena příjemci.', + 'event', + null, + ), + new Status( + Carrier::CP, + '2', + 2.2, + 'Zásilka je v přepravě.', + 'Zásilka je v přepravě.', + 'event', + null, + ), + ], + ), ]; yield 'missing_data_error' => [ @@ -545,8 +581,8 @@ public function providesTestTrackPackagesLastStatusesByIds(): iterable 'status_text' => 'Zásilka byla doručena příjemci.', ], 1 => [ - 'carrier_id' => '1234', - 'status' => 404, + 'carrier_id' => '1234', + 'status' => 404, ], ], ], @@ -561,28 +597,36 @@ public function testTrackPackagesLastStatusesByIdsProxy(): void $service = $this->createPartialMock(DefaultTrackService::class, ['trackPackagesLastStatusesByIds']); $expectedStatuses = [ - 0 => new PackageStatus(1.1, 'name1', 'name1', 'event', null), - 1 => new PackageStatus(2.1, 'name2', 'name2', 'event', null), + new StatusCollection(Carrier::PPL, [ + 0 => new Status(Carrier::PPL, '1234', 1.1, 'name1', 'name1', 'event', null), + ]), + new StatusCollection(Carrier::CP, [ + 0 => new Status(Carrier::CP, '3456', 1.1, 'name1', 'name1', 'event', null), + ]), + new StatusCollection(Carrier::ZASILKOVNA, [ + 0 => new Status(Carrier::ZASILKOVNA, 'Z123', 1.1, 'name1', 'name1', 'event', null), + 1 => new Status(Carrier::ZASILKOVNA, 'Z234', 2.1, 'name2', 'name2', 'event', null), + ]), ]; $service->expects(self::exactly(3))->method('trackPackagesLastStatusesByIds')->withConsecutive( [Carrier::PPL, ['1234']], [Carrier::CP, ['3456']], [Carrier::ZASILKOVNA, ['Z123', 'Z234']], - )->willReturn($expectedStatuses); + )->willReturnOnConsecutiveCalls(...$expectedStatuses); - $actualStatuses = $service->trackPackageLastStatus(new OrderedPackage('1', '0001', Carrier::PPL, '1234')); - self::assertSame($expectedStatuses[0], $actualStatuses); + $actualStatuses = $service->trackPackageLastStatus(new Package(Carrier::PPL, '1', '0001', '1234')); + self::assertSame($expectedStatuses[0][0], $actualStatuses); $actualStatuses = $service->trackPackageLastStatusById(Carrier::CP, '3456'); - self::assertSame($expectedStatuses[0], $actualStatuses); + self::assertSame($expectedStatuses[1][0], $actualStatuses); - $packages = new OrderedPackageCollection(); - $packages->add(new OrderedPackage('1', '0001', Carrier::ZASILKOVNA, 'Z123')); - $packages->add(new OrderedPackage('2', '0001', Carrier::ZASILKOVNA, 'Z234')); + $packages = new PackageCollection(); + $packages->add(new Package(Carrier::ZASILKOVNA, '1', '0001', 'Z123')); + $packages->add(new Package(Carrier::ZASILKOVNA, '2', '0001', 'Z234')); $actualStatuses = $service->trackPackagesLastStatuses($packages); - self::assertSame($expectedStatuses, $actualStatuses); + self::assertSame($expectedStatuses[2], $actualStatuses); } /** @@ -594,8 +638,8 @@ private function newTrackService(int $statusCode, array|string $response, ?array $requester = $this->newRequester($statusCode, $response, $request); $validator = new Validator(); $client = new DefaultClient($requester, $validator); - $statusFactory = new DefaultPackageStatusFactory(); + $statusFactory = new DefaultPackageStatusFactory($validator); - return new DefaultTrackService($client, $validator, $statusFactory); + return new DefaultTrackService($client, $statusFactory); } }