diff --git a/.gitignore b/.gitignore index 06189e5..695dc6a 100644 --- a/.gitignore +++ b/.gitignore @@ -5,5 +5,5 @@ program.php output.log /doc/* -!/doc/sami.php /.php_cs.cache +/.phpunit.result.cache diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ac1779..d5b6cae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v2.0.0 (28 Oct 2021) + +- Updated guzzlehttp/guzzle to V7.4.0 +- Updated psr/log to 1.1.0 +- Updated the Billbee API Endpoint + ## v1.9.0 (1 Jun 2021) New Features: @@ -12,19 +18,42 @@ New Features: ## v1.8.3 (4 May 2021) Bugfixes -- URL encode the `$extRef` in `getOrderByOrderNumber` and the `$externalId` in `getOrderByPartner` before sending the request to the API. +- URL encode the `$extRef` in `getOrderByOrderNumber` and the `$externalId` in `getOrderByPartner` before sending the request to the API. + +## v2.0.0-RC3 (21 Apr 2021) + +Changed the required PHP CPU architecture to 64bit + +## v2.0.0-RC2 (15 Mar 2021) + +Updated from master ## v1.8.2 (15 Mar 2021) Bugfixes - SoldAmount fixed ([PR #39](https://github.com/billbeeio/billbee-php-sdk/pull/39)) +## v2.0.0-RC1 (22 Feb 2021) + +_See [UPGRADE.md](UPGRADE.md) for migration details._ + +New Features +- PHP 8 added to composer.json + +Misc: +- Copyright updated ([PR #34](https://github.com/billbeeio/billbee-php-sdk/pull/34)) +- Added phpstan for static code analysis ([PR #36](https://github.com/billbeeio/billbee-php-sdk/pull/36)) + +Breaking changes: +- The code has been reorganized. The client does not implement the endpoints directly anymore. ([PR #35](https://github.com/billbeeio/billbee-php-sdk/pull/35)) + -Updated the min. PHP Version to 7.3 ([PR #37](https://github.com/billbeeio/billbee-php-sdk/pull/37)) + ## v1.8.1 (22 Feb 2021) New Features - PHP 8 added to composer.json -## 1.8.0 (9 Dec 2019) +## v1.8.0 (9 Dec 2019) New features: - `DELETE /api/v1/products/{id}` added. (`Client::deleteProduct($id)`) ([PR #31](https://github.com/billbeeio/billbee-php-sdk/pull/31)) @@ -33,11 +62,11 @@ New features: - `Product::$widthCm` - `Product::$lengthCm` - `Product::$heightCm` - - `Product::$billOfMaterial` + - `Product::$billOfMaterial` - `GET /api/v1/products/PatchableFields` added. (`Client::getPatchableProductFields()`) ([PR #33](https://github.com/billbeeio/billbee-php-sdk/pull/33)) - `PATCH /api/v1/products/{id}` added. (`Client::patchProduct($productId, $model)`) ([PR #33](https://github.com/billbeeio/billbee-php-sdk/pull/33)) -## 1.7.0 (15 Nov 2019) +## v1.7.0 (15 Nov 2019) New features: - `GET /api/v1/cloudstorages` added. (`Client::getCloudStorages()`) ([PR #18](https://github.com/billbeeio/billbee-php-sdk/pull/18)) - `GET /api/v1/products/category` added. (`Client::getCategories()`) ([PR #19](https://github.com/billbeeio/billbee-php-sdk/pull/19)) @@ -55,7 +84,7 @@ Misc: - Added a code documentation generator ([PR #24](https://github.com/billbeeio/billbee-php-sdk/pull/24)) - Fixed code style ([PR #24](https://github.com/billbeeio/billbee-php-sdk/pull/24)) -## 1.6.2 (16 Sep 2019) +## v1.6.2 (16 Sep 2019) New features: - Added the `SoldProduct` model which is used in `OrderItem::$product` @@ -63,7 +92,7 @@ New features: Bug Fixes: - Added a mapping for `Order::$paymentTransactionId` and `Order::$deliverySourceCountryCode` -## 1.6.1 (24 Jul 2019) +## v1.6.1 (24 Jul 2019) Bug Fixes: - Fixed `use-before-initialize` bug in the `Client::__construct` ([PR #15](https://github.com/billbeeio/billbee-php-sdk/pull/15)) @@ -121,7 +150,7 @@ General: ## v1.1.4 (23 Aug 2018) -- `articleTitleSource` and `excludeTags` arguments added to `getOrders()` ([PR #5](https://github.com/billbeeio/billbee-php-sdk/pull/5)) +- `articleTitleSource` and `excludeTags` arguments added to `getOrders()` ([PR #5](https://github.com/billbeeio/billbee-php-sdk/pull/5)) - `AutosubtractReservedAmount` parameter added to stock model - Customer Endpoints implemented - Links updated from `app01.billbee.de` to `app.billbee.io` @@ -131,8 +160,6 @@ General: - Code folding optimized - Imports optimized - - ## v1.1.3 (20 Aug 2018) - `/api/v1/products/custom-fields` endpoints added - `/api/v1/webhooks` endpoints added diff --git a/README.md b/README.md index 280d2ff..3562824 100644 --- a/README.md +++ b/README.md @@ -26,28 +26,34 @@ $ composer require billbee/billbee-api ## Usage Simply instantiate a client object for accessing the api: + ```php getProducts($page = 1, $pageSize = 10); +$productsResponse = $client->products()->getProducts($page = 1, $pageSize = 10); /** @var \BillbeeDe\BillbeeAPI\Model\Product $product */ foreach ($productsResponse->data as $product) { @@ -56,35 +62,37 @@ foreach ($productsResponse->data as $product) { ``` ## Example: Batch requests -```php +```php useBatching = true; # Enable batching +$client = new Client($user, $apiPassword, $apiKey); +$client->enableBatchMode(); -$client->getProducts(1, 1); # Adds the request to the batch pool / returns null -$client->getOrders(1, 1); # Adds the request to the batch pool / returns null -$client->getEvents(1, 1); # Adds the request to the batch pool / returns null +$client->products()->getProducts(1, 1); # Adds the request to the batch pool / returns null +$client->orders()->getOrders(1, 1); # Adds the request to the batch pool / returns null +$client->events()->getEvents(1, 1); # Adds the request to the batch pool / returns null $results = $client->executeBatch(); # Results contain all responses in the added order -/** @var \BillbeeDe\BillbeeAPI\Response\GetProductsResponse $productsResult */ +/** @var Response\GetProductsResponse $productsResult */ $productsResult = $results[0]; -/** @var \BillbeeDe\BillbeeAPI\Response\GetOrdersResponse $ordersResult */ +/** @var Response\GetOrdersResponse $ordersResult */ $ordersResult = $results[1]; -/** @var \BillbeeDe\BillbeeAPI\Response\GetEventsResponse $eventsResult */ +/** @var Response\GetEventsResponse $eventsResult */ $eventsResult = $results[2]; ``` ## Testing -Clone the repository, copy the `test_config.dist.yml` to `test_config.yml` and fill it. Run `phpunit` ## Contributing diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 0000000..601f3c7 --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,100 @@ +# Migration Guide + +## Minimum PHP Version +Since PHP 5.6 - PHP 7.1 isn't supported anymore and the PHP 7.2 Security support ends in Nov 2020 the minimal PHP Version +was increased to 7.3. + +## `Client::$useBatching` + +This field was made private. The Client itself implements the `\BillbeeDe\BillbeeAPI\BatchClientInterface`. Use the +following methods for migration + +- `BatchClientInterface::enableBatchMode()` +- `BatchClientInterface::disableBatchMode()` +- `BatchClientInterface::isBatchModeEnabled()` + +## Endpoints + +The client does not implement the request actions anymore. Instead, we provide "Endpoints" which groups the requests by +its topic. This change was made for testing purposes. + +### `Client::cloudStorages()` (`CloudStorageEndpoint`) +Former methods: +- `Client::getCloudStorages()` + +### `Client::customers()` (`CustomersEndpoint`) +Former methods: +- `Client::getCustomers()` +- `Client::getCustomer()` +- `Client::getCustomerAddresses()` +- `Client::getCustomerAddress()` +- `Client::getCustomerOrders()` +- `Client::createCustomer()` +- `Client::updateCustomer()` + +### `Client::events()` (`EventsEndpoint`) +Former methods: +- `Client::getEvents()` + +### `Client::invoices()` (`InvoiceEndpoint`) +Former methods: +- `Client::getInvoices()` + +### `Client::layouts()` (`LayoutsEndpoint`) +Former methods: +- `Client::getLayouts()` + +### `Client::orders()` (`OrdersEndpoint`) +Former methods: +- `Client::getOrders()` +- `Client::getPatchableFields()` +- `Client::getOrder()` +- `Client::getOrderByOrderNumber()` +- `Client::getOrderByPartner()` +- `Client::createOrder()` +- `Client::addOrderTags()` +- `Client::addOrderShipment()` +- `Client::createDeliveryNote()` +- `Client::createInvoice()` +- `Client::sendMessage()` +- `Client::setOrderTags()` +- `Client::setOrderState()` +- `Client::patchOrder()` + +### `Client::productCustomFields()` (`ProductCustomFieldsEndpoint`) +Former methods: +- `Client::getCustomFieldDefinitions()` +- `Client::getCustomFieldDefinition()` + +### `Client::products()` (`ProductsEndpoint`) +Former methods: +- `Client::updateStock()` +- `Client::updateStockMultiple()` +- `Client::updateStockCode()` +- `Client::createProduct()` +- `Client::patchProduct()` +- `Client::deleteProduct()` + +### `Client::provisioning()` (`ProvisioningEndpoint`) +Former methods: +- `Client::getTermsInfo()` + +### `Client::search()` (`SearchEndpoint`) +Former methods: +- `Client::search()` + +### `Client::shipments()` (`ShipmentsEndpoint`) +Former methods: +- `Client::getShippingProviders()` +- `Client::shipWithLabel()` + +### `Client::webHooks()` (`WebHooksEndpoint`) +Former methods: +- `Client::getWebHooks()` +- `Client::getWebHook()` +- `Client::getWebHookFilters()` +- `Client::createWebHook()` +- `Client::updateWebHook()` +- `Client::deleteAllWebHooks()` +- `Client::deleteWebHookById()` +- `Client::deleteWebHook()` \ No newline at end of file diff --git a/composer.json b/composer.json index 39f1929..442bf7f 100644 --- a/composer.json +++ b/composer.json @@ -3,18 +3,18 @@ "description": "The official Billbee API SDK for PHP", "type": "library", "require": { - "php": "5.6.* || ^7.0 || ^8.0", + "php-64bit": "^7.3 || ^8.0", "ext-curl": "*", "ext-json": "*", "mintware-de/data-model-mapper": "^1.0", "mintware-de/dmm-json": "^1.0", - "guzzlehttp/guzzle": "^6.3", - "psr/log": "^1.0" + "guzzlehttp/guzzle": "^7.4.0", + "psr/log": "^1.1.0" }, "require-dev": { - "phpunit/phpunit": "~5.7", - "symfony/yaml": "~3.3", - "friendsofphp/php-cs-fixer": "^2.15" + "phpunit/phpunit": "^9.4.1", + "friendsofphp/php-cs-fixer": "^2.15", + "phpstan/phpstan": "^0.12.49" }, "license": "MIT", "authors": [ @@ -35,7 +35,7 @@ "php-cs-fixer fix ./src/ --using-cache=no --rules=@PSR2", "php-cs-fixer fix ./tests/ --using-cache=no --rules=@PSR2" ], - "generate-doc": "sami update doc/sami.php" + "analyse": "phpstan analyse" }, "archive": { "exclude": [ diff --git a/doc/sami.php b/doc/sami.php deleted file mode 100644 index b62d5db..0000000 --- a/doc/sami.php +++ /dev/null @@ -1,54 +0,0 @@ - - */ - -use Sami\Sami; -use Symfony\Component\Finder\Finder; -use Sami\Parser\Filter\FilterInterface; -use Sami\Reflection\MethodReflection; -use Sami\Reflection\PropertyReflection; -use Sami\Reflection\ClassReflection; - -$iterator = Finder::create() - ->files() - ->name('*.php') - ->exclude('vendor') - ->exclude('tests') - ->in(__DIR__ . '/../src'); - -class IncludeProtectedFilter implements FilterInterface -{ - public function acceptClass(ClassReflection $class) - { - return true; - } - - public function acceptMethod(MethodReflection $method) - { - return !$method->isPrivate() && !$method->isProtected(); - } - - public function acceptProperty(PropertyReflection $property) - { - return !$property->isPrivate() && !$property->isProtected(); - } -} - -$sami = new Sami($iterator, array( - 'build_dir' => __DIR__ . '/generated', - 'cache_dir' => __DIR__ . '/cache' -)); - -$sami['filter'] = function () { - return new IncludeProtectedFilter(); -}; - -return $sami; diff --git a/doc/usage_without_composer.md b/doc/usage_without_composer.md index 9a2ffcb..0635c20 100644 --- a/doc/usage_without_composer.md +++ b/doc/usage_without_composer.md @@ -42,30 +42,34 @@ move vendor sdk-dist/vendor Now copy the `sdk-dist` to your target directory and `require_once` the `autoload.php` For example: + ```php useBatching = true; # Enable batching +$client = new Client($user, $apiPassword, $apiKey); +$client->enableBatchMode(); # Enable batching -$client->getProducts(1, 1); # Adds the request to the batch pool / returns null -$client->getOrders(1, 1); # Adds the request to the batch pool / returns null -$client->getEvents(1, 1); # Adds the request to the batch pool / returns null +$client->products()->getProducts(1, 1); # Adds the request to the batch pool / returns null +$client->orders()->getOrders(1, 1); # Adds the request to the batch pool / returns null +$client->events()->getEvents(1, 1); # Adds the request to the batch pool / returns null $results = $client->executeBatch(); # Results contain all responses in the added order -/** @var \BillbeeDe\BillbeeAPI\Response\GetProductsResponse $productsResult */ +/** @var Response\GetProductsResponse $productsResult */ $productsResult = $results[0]; -/** @var \BillbeeDe\BillbeeAPI\Response\GetOrdersResponse $ordersResult */ +/** @var Response\GetOrdersResponse $ordersResult */ $ordersResult = $results[1]; -/** @var \BillbeeDe\BillbeeAPI\Response\GetEventsResponse $eventsResult */ +/** @var Response\GetEventsResponse $eventsResult */ $eventsResult = $results[2]; ``` diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..01a07a2 --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,6 @@ +parameters: + level: 5 + paths: + - src + bootstrapFiles: + - vendor/autoload.php diff --git a/phpunit.xml b/phpunit.xml index c56d897..3e35479 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,23 +1,24 @@ + - - - - - ./tests/ - - - - - ./src - - - \ No newline at end of file + + + + ./src + + + + + ./tests + + + diff --git a/src/BatchClientInterface.php b/src/BatchClientInterface.php new file mode 100644 index 0000000..22952c3 --- /dev/null +++ b/src/BatchClientInterface.php @@ -0,0 +1,31 @@ + + */ + +namespace BillbeeDe\BillbeeAPI; + +interface BatchClientInterface +{ + /** + * Returns the batch pool size + * @return int + */ + public function getPoolSize(); + + public function enableBatchMode(); + + public function disableBatchMode(); + + /** + * @return bool True if the client use batching, otherwise false + */ + public function isBatchModeEnabled(); +} diff --git a/src/Client.php b/src/Client.php index bdde84f..8178e3e 100644 --- a/src/Client.php +++ b/src/Client.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -12,1527 +12,230 @@ namespace BillbeeDe\BillbeeAPI; -use BillbeeDe\BillbeeAPI\Exception\InvalidIdException; +use BillbeeDe\BillbeeAPI\Endpoint\CloudStorageEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\CustomersEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\EventsEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\InvoiceEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\LayoutsEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\OrdersEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\ProductCustomFieldsEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\ProductsEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\ProvisioningEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\SearchEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\ShipmentsEndpoint; +use BillbeeDe\BillbeeAPI\Endpoint\WebHooksEndpoint; use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; use BillbeeDe\BillbeeAPI\Logger\DiagnosticsLogger; -use BillbeeDe\BillbeeAPI\Model as Model; use BillbeeDe\BillbeeAPI\Response as Response; -use BillbeeDe\BillbeeAPI\Type as Type; -use DateTime; use Exception; use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Psr7\Message; use GuzzleHttp\RequestOptions; -use InvalidArgumentException; use MintWare\DMM\ObjectMapper; use MintWare\DMM\Serializer\JsonSerializer; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use function GuzzleHttp\Psr7\parse_response; use Psr\Log\LoggerInterface; -class Client extends AbstractClient +class Client implements ClientInterface, BatchClientInterface { - /** - * The API Endpoint - * - * @var string - */ - protected $endpoint = 'https://app.billbee.io/api/v1/'; - - /** - * The JSON Object Mapper - * - * @var ObjectMapper - */ - protected $jom = null; - - /** - * If true, the requests will be performed using a batch call. - * Each single call returns null. - * Call the executeBatch method to execute all calls and retrieve the responses - * - * @see Client::executeBatch() - * - * @var bool - */ - public $useBatching = false; - - /** - * Contains all requests in batch mode - * - * @var array - */ - protected $requestPool = []; - - /** - * If true, the requests will be logged - * - * @var bool - */ - private $logRequests = false; - - /** - * Instantiates a new Billbee API client - * - * @param string $username The Billbee username - * @param string $apiPassword The API password for the user - * @param string $apiKey The API Key - * @param LoggerInterface $logger Sets a optional logger - * @throws Exception - */ - public function __construct($username, $apiPassword, $apiKey, LoggerInterface $logger = null) - { - parent::__construct([ - 'base_uri' => $this->endpoint, - 'auth' => [$username, $apiPassword], - 'headers' => [ - 'X-Billbee-Api-Key' => $apiKey, - ] - ]); - - $this->setLogger($logger); - try { - $this->jom = new ObjectMapper(new JsonSerializer()); - } catch (Exception $ex) { - if ($logger !== null) { - $this->logger->critical('Object Mapper could not be created.'); - } - throw $ex; - } - } - - #region PRODUCTS - - #region GET - - /** - * Get a list of all products optionally filtered by date - * - * @param int $page The start page - * @param int $pageSize The page size - * @param DateTime|null $minCreatedAt The date of creation of the products - * @return Response\GetProductsResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getProducts($page = 1, $pageSize = 50, DateTime $minCreatedAt = null) - { - $query = [ - 'page' => max(1, $page), - 'pageSize' => max(1, $pageSize), - ]; - - if ($minCreatedAt !== null && $minCreatedAt instanceof DateTime) { - $query['minCreatedAt'] = $minCreatedAt->format('c'); - } - - return $this->requestGET( - 'products', - $query, - Response\GetProductsResponse::class - ); - } - - /** - * Get a single product by Id - * - * @param int $productId The product id - * @param string $lookupBy Either the value id, ean or the value sku to specify the meaning of the id parameter - * @return Response\GetProductResponse The product response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - * @see \BillbeeDe\BillbeeAPI\Type\ProductLookupBy - */ - public function getProduct($productId, $lookupBy = Type\ProductLookupBy::ID) - { - return $this->requestGET( - 'products/' . $productId, - ['lookupBy' => $lookupBy], - Response\GetProductResponse::class - ); - } - - /** - * Get a list of all defined categories - * - * @return Response\GetCategoriesResponse The category response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - * - */ - public function getCategories() - { - return $this->requestGET( - 'products/category', - [], - Response\GetCategoriesResponse::class - ); - } - - /** - * - * Returns a list of fields which can be updated with the patchProduct call - * - * @return Response\GetPatchableFieldsResponse - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - * - * @see Client::patchProduct($productId, $model) - */ - public function getPatchableProductFields() - { - return $this->requestGET( - 'products/PatchableFields', - [], - Response\GetPatchableFieldsResponse::class - ); - } - - #endregion - - #region POST - - /** - * Updates the stock for a single product - * - * @param Model\Stock $stockModel The stock model - * @return Response\UpdateStockResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function updateStock(Model\Stock $stockModel) - { - return $this->requestPOST( - 'products/updatestock', - $stockModel, - Response\UpdateStockResponse::class - ); - } - - /** - * Updates the stock for multiple products - * - * @param Model\Stock[] $stockModels The stock models - * @return Response\UpdateStockResponse[] The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function updateStockMultiple($stockModels) - { - return $this->requestPOST( - 'products/updatestockmultiple', - $stockModels, - Response\UpdateStockResponse::class . '[]' - ); - } - - /** - * Updates the stock code for a single products - * - * @param Model\StockCode $stockCodeModel The stock code model - * @return Response\BaseResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function updateStockCode(Model\StockCode $stockCodeModel) - { - return $this->requestPOST( - 'products/updatestockcode', - $this->jom->serialize($stockCodeModel), - Response\BaseResponse::class - ); - } - - /** - * Creates a new product - * - * @param Model\Product $product - * @return Response\GetProductResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function createProduct(Model\Product $product) - { - return $this->requestPOST( - 'products', - $this->jom->serialize($product), - Response\GetProductResponse::class - ); - } - - #endregion - - #region PATCH - - /** - * Updates one or more fields of a product - * - * @param int $productId The internal id of the product - * @param array $model The fields to patch - * - * @return Response\GetProductResponse The order - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - * - * @see Client::getPatchableProductFields() - */ - public function patchProduct($productId, $model) - { - return $this->requestPATCH( - 'products/' . $productId, - $model, - Response\GetProductResponse::class - ); - } - - #endregion - - #region DELETE - - /** - * Deletes a product by id - * - * @param int $productId The Id of the product - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function deleteProduct($productId) - { - $this->requestDELETE( - 'products/' . $productId, - [], - Response\BaseResponse::class - ); - } - - #endregion - - #endregion - - #region PROVISIONING - - #region GET - - /** - * Returns information about Billbee terms and conditions - * - * @return Response\GetTermsInfoResponse The terms info response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getTermsInfo() - { - return $this->requestGET( - 'automaticprovision/termsinfo', - [], - Response\GetTermsInfoResponse::class - ); - } - - #endregion - - #endregion - - #region EVENTS - - #region GET - - /** - * Get a list of all events optionally filtered by date and / or event type - * - * @param int $page The start page - * @param int $pageSize The page size - * @param DateTime $minDate Start date - * @param DateTime $maxDate End date - * @param array $typeIds An array of event type id's - * @param int $orderId Filter for specific order id - * - * @return Response\GetEventsResponse The events - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getEvents( - $page = 1, - $pageSize = 50, - DateTime $minDate = null, - DateTime $maxDate = null, - $typeIds = [], - $orderId = null - ) { - $query = [ - 'page' => max(1, $page), - 'pageSize' => max(1, $pageSize), - ]; - - if ($minDate !== null && $minDate instanceof DateTime) { - $query['minDate'] = $minDate->format('c'); - } - - if ($maxDate !== null && $maxDate instanceof DateTime) { - $query['maxDate'] = $maxDate->format('c'); - } - - if (is_array($typeIds) && count($typeIds) > 0) { - $query['typeId'] = $typeIds; - } - - if ($orderId != null) { - $query['orderId'] = $orderId; - } - - return $this->requestGET( - 'events', - $query, - Response\GetEventsResponse::class - ); - } - - #endregion - - #endregion - - #region ORDERS - - #region GET - - /** - * Get a list of all orders optionally filtered by date - * - * @param int $page Specifies the page to request - * @param int $pageSize Specifies the pagesize. Defaults to 50, max value is 250 - * @param DateTime|null $minOrderDate Specifies the oldest order date to include in the response - * @param DateTime|null $maxOrderDate Specifies the newest order date to include in the response - * @param int[] $shopId Specifies a list of shop ids for which invoices should be included - * @param int[] $orderStateId Specifies a list of state ids to include in the response - * @param string[] $tag Specifies a list of tags the order must have attached to be included in the response - * @param null $minimumOrderId If given, all delivered orders have an Id greater than or equal to the given minimumOrderId - * @param DateTime|null $modifiedAtMin If given, the last modification has to be newer than the given date - * @param DateTime|null $modifiedAtMax If given, the last modification has to be older or equal than the given date. - * @param int $articleTitleSource The source field for the article title. - * @param boolean $excludeTags If true the list of tags passed to the call are used to filter orders to not include these tags - * - * @return Response\GetOrdersResponse The orders - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getOrders( - $page = 1, - $pageSize = 50, - DateTime $minOrderDate = null, - DateTime $maxOrderDate = null, - $shopId = [], - $orderStateId = [], - $tag = [], - $minimumOrderId = null, - DateTime $modifiedAtMin = null, - DateTime $modifiedAtMax = null, - $articleTitleSource = Type\ArticleSource::ORDER_POSITION, - $excludeTags = false - ) { - $query = [ - 'page' => max(1, $page), - 'pageSize' => max(1, $pageSize), - ]; - - if ($minOrderDate !== null && $minOrderDate instanceof DateTime) { - $query['minOrderDate'] = $minOrderDate->format('c'); - } - - if ($maxOrderDate !== null && $maxOrderDate instanceof DateTime) { - $query['maxOrderDate'] = $maxOrderDate->format('c'); - } - - if ($shopId !== null && (is_numeric($shopId) || is_array($shopId))) { - if (is_numeric($shopId)) { - $shopId = [$shopId]; - } elseif (is_array($shopId)) { - foreach ($shopId as $value) { - if (!is_numeric($value)) { - throw new InvalidArgumentException('shopId must be an instance of int or an array of int'); - } - } - } - $shopId = array_filter($shopId); - if (count($shopId) > 0) { - $query['shopId'] = $shopId; - } - } - - if ($orderStateId !== null && (is_numeric($orderStateId) || is_array($orderStateId))) { - if (is_numeric($orderStateId)) { - $orderStateId = [$orderStateId]; - } elseif (is_array($orderStateId)) { - foreach ($orderStateId as $value) { - if (!is_numeric($value)) { - throw new InvalidArgumentException('orderStateId must be an instance of int or an array of int'); - } - } - } - $orderStateId = array_filter($orderStateId); - if (count($orderStateId) > 0) { - $query['orderStateId'] = $orderStateId; - } - - if ($tag !== null && (is_string($tag) || is_array($tag))) { - if (is_string($tag)) { - $tag = [$tag]; - } - $tag = array_filter($tag); - if (count($tag) > 0) { - $query['tag'] = $tag; - } - } - } - - if ($minimumOrderId !== null && !empty($minimumOrderId)) { - $query['minimumBillBeeOrderId'] = $minimumOrderId; - } - - if ($modifiedAtMin !== null && $modifiedAtMin instanceof DateTime) { - $query['modifiedAtMin'] = $modifiedAtMin->format('c'); - } - - if ($modifiedAtMax !== null && $modifiedAtMax instanceof DateTime) { - $query['modifiedAtMax'] = $modifiedAtMax->format('c'); - } - - if (!is_numeric($articleTitleSource) || $articleTitleSource < 0 || $articleTitleSource > 2) { - throw new InvalidArgumentException(sprintf( - 'The articleTitleSource is invalid. Check %s for valid values', - Type\ArticleSource::class - )); - } - $query['articleTitleSource'] = $articleTitleSource; - - if (is_bool($excludeTags) && $excludeTags === true) { - $query['excludeTags'] = 'true'; - } - - return $this->requestGET( - 'orders', - $query, - Response\GetOrdersResponse::class - ); - } - - /** - * Returns a list of fields which can be updated with the patchOrder call - * - * @return Response\GetPatchableFieldsResponse - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getPatchableFields() - { - return $this->requestGET( - 'orders/PatchableFields', - [], - Response\GetPatchableFieldsResponse::class - ); - } - - /** - * Get a single order by its internal billbee id - * - * @param int $id The internal billbee id of the order - * - * @return Response\GetOrderResponse The order response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getOrder($id) - { - return $this->requestGET( - 'orders/' . $id, - [], - Response\GetOrderResponse::class - ); - } - - /** - * Get a single order by its internal billbee id - * - * @param string $extRef The internal billbee id of the order - * - * @return Response\GetOrderResponse The order response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getOrderByOrderNumber($extRef) - { - if (!strstr($extRef, '%')) { - $extRef = urlencode($extRef); - } - return $this->requestGET( - 'orders/findbyextref/' . $extRef, - [], - Response\GetOrderResponse::class - ); - } - - - /** - * Find a single order by its external id (order number) - * - * @param string $externalId The order id in the partner system - * @param string $partner The partner name. Possible partners in Partner-Class - * - * @return Response\GetOrderResponse The order response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - * - * @see \BillbeeDe\BillbeeAPI\Type\Partner - */ - public function getOrderByPartner($externalId, $partner) - { - if (!strstr($externalId, '%')) { - $externalId = urlencode($externalId); - } - return $this->requestGET( - 'orders/find/' . $externalId . '/' . $partner, - [], - Response\GetOrderByPartnerResponse::class - ); - } - - #endregion - - #region POST - - /** - * Get a single order by its internal billbee id - * - * @param Model\Order $order The order Data - * @param int $shopId The id of the shop - * - * @return Response\BaseResponse The response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function createOrder(Model\Order $order, $shopId) - { - return $this->requestPOST( - 'orders?shopId=' . $shopId, - $this->jom->serialize($order), - Response\BaseResponse::class - ); - } - - /** - * Attach one or more tags to an order - * - * @param int $orderId The internal id of the order - * @param string[] $tags Tags to attach - * - * @return Response\BaseResponse The response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function addOrderTags($orderId, $tags = []) - { - if (!is_array($tags)) { - $tags = [$tags]; - } - return $this->requestPOST( - 'orders/' . $orderId . '/tags', - json_encode(['Tags' => $tags]), - Response\BaseResponse::class - ); - } - - /** - * Attach one or more tags to an order - * - * @param int $orderId The internal id of the order - * @param Model\Shipment $shipment The Shipment - * - * @return bool True if the shipment was added - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function addOrderShipment($orderId, Model\Shipment $shipment) - { - $res = $this->requestPOST( - 'orders/' . $orderId . '/shipment', - $this->jom->serialize($shipment), - Response\BaseResponse::class - ); - return $res === '' || $res === null; - } - - /** - * Create an delivery note for an existing order - * - * @param int $orderId The internal id of the order - * @param bool $includePdf If true, the PDF is included in the response as base64 encoded string - * - * @return Response\CreateDeliveryNoteResponse The response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function createDeliveryNote($orderId, $includePdf) - { - return $this->requestPOST( - 'orders/CreateDeliveryNote/' . $orderId . '?includePdf=' . ($includePdf ? 'True' : 'False'), - [], - Response\CreateDeliveryNoteResponse::class - ); - } - - /** - * Create an invoice for an existing order - * - * @param int $orderId The internal id of the order - * @param bool $includePdf If true, the PDF is included in the response as base64 encoded string - * @param int|null $templateId The internal id of a template - * @param int|null $sendToCloudId The internal id of an cloud storage where the invoice is uploaded to - * - * @return Response\CreateDeliveryNoteResponse The response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function createInvoice($orderId, $includePdf, $templateId = null, $sendToCloudId = null) - { - $node = 'orders/CreateInvoice/' . $orderId . '?includeInvoicePdf=' . ($includePdf ? 'True' : 'False'); - if ($templateId != null && is_numeric($templateId)) { - $node .= '&templateId=' . $templateId; - } - if ($sendToCloudId != null && is_numeric($sendToCloudId)) { - $node .= '&sendToCloudId=' . $sendToCloudId; - } - return $this->requestPOST( - $node, - [], - Response\CreateInvoiceResponse::class - ); - } - - /** - * Sends a message to the customer - * - * @param int $orderId The internal id of the order - * @param Model\MessageForCustomer $message The message model - * @return bool True if the message was send, otherwise false - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - * @throws InvalidArgumentException If the request is not valid - */ - public function sendMessage($orderId, Model\MessageForCustomer $message) - { - if ($message->sendMode < 0 || $message->sendMode > 4) { - $msg = sprintf("The sendMode is invalid. Check the %s class for valid values", Type\SendMode::class); - throw new InvalidArgumentException($msg); - } elseif (!is_array($message->subject) || count($message->subject) == 0) { - throw new InvalidArgumentException("You have to specify a message subject"); - } elseif (!is_array($message->body) || count($message->body) == 0) { - throw new InvalidArgumentException("You have to specify a message body"); - } elseif ($message->sendMode == Type\SendMode::EXTERNAL_EMAIL && empty($message->alternativeEmailAddress)) { - $msg = "With sendMode == 4 it's required to specify an alternativeEmailAddress"; - throw new InvalidArgumentException($msg); - } - - if ($message->sendMode != Type\SendMode::EXTERNAL_EMAIL && !empty($message->alternativeEmailAddress)) { - $this->logger->warning('The alternative email address is ignored because sendMode != 4'); - } - - $res = $this->requestPOST( - 'orders/' . $orderId . '/send-message', - $this->jom->serialize($message), - Response\BaseResponse::class - ); - - return $res === '' || $res === null; - } - - #endregion - - #region PUT - - /** - * Updates/Sets the tags attached to an order - * - * @param int $orderId The internal id of the order - * @param string[] $tags Tags to attach - * - * @return Response\BaseResponse The response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function setOrderTags($orderId, $tags = []) - { - if (!is_array($tags)) { - $tags = [$tags]; - } - return $this->requestPUT( - 'orders/' . $orderId . '/tags', - json_encode(['Tags' => $tags]), - Response\BaseResponse::class - ); - } - - /** - * Changes the main state of a single order - * - * @param int $orderId The internal id of the order - * @param int $newState The new OrderState - * - * @return bool True if the state was updated - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - * - * @see \BillbeeDe\BillbeeAPI\Type\OrderState - */ - public function setOrderState($orderId, $newState) - { - $res = $this->requestPUT( - 'orders/' . $orderId . '/orderstate', - json_encode(['NewStateId' => $newState]), - Response\BaseResponse::class - ); - return $res === null; - } - - #endregion - - #region PATCH - - /** - * Updates one or more fields of an order - * - * @param int $orderId The internal id of the order - * @param array $model The fields to patch - * - * @return Response\GetOrderResponse The order - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function patchOrder($orderId, $model) - { - return $this->requestPATCH( - 'orders/' . $orderId, - $model, - Response\GetOrderResponse::class - ); - } - - #endregion - - #endregion - - #region INVOICE - - #region GET - - /** - * Get a list of all invoices - * - * @param DateTime $minInvoiceDate Specifies the oldest invoice date to include - * @param DateTime $maxInvoiceDate Specifies the newest invoice date to include - * @param int $page Specifies the page to request - * @param int $pageSize Specifies the number of elements per page. Defaults to 50, max value is 250 - * @param array $shopId Specifies a list of shop ids for which invoices should be included - * @param array $orderStateId Specifies a list of state ids to include in the response - * @param array $tag Specifies a list of tags to include in the response - * @param DateTime $minPayDate Specifies the oldest pay date to include - * @param DateTime $maxPayDate Specifies the newest pay date to include - * @param bool $includePositions Specifies to include the positions - * - * @return Response\GetInvoicesResponse The Invoices - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getInvoices( - $page = 1, - $pageSize = 50, - DateTime $minInvoiceDate = null, - DateTime $maxInvoiceDate = null, - $shopId = [], - $orderStateId = [], - $tag = [], - DateTime $minPayDate = null, - DateTime $maxPayDate = null, - $includePositions = false - ) { - $query = [ - 'page' => max(1, $page), - 'pageSize' => max(1, $pageSize), - ]; - - if ($minInvoiceDate !== null && $minInvoiceDate instanceof DateTime) { - $query['minInvoiceDate'] = $minInvoiceDate->format('c'); - } - - if ($maxInvoiceDate !== null && $maxInvoiceDate instanceof DateTime) { - $query['maxInvoiceDate'] = $maxInvoiceDate->format('c'); - } - - if ($shopId !== null && (is_numeric($shopId) || is_array($shopId))) { - if (is_numeric($shopId)) { - $shopId = [$shopId]; - } elseif (is_array($shopId)) { - foreach ($shopId as $value) { - if (!is_numeric($value)) { - throw new InvalidArgumentException('shopId must be an instance of int or an array of int'); - } - } - } - $shopId = array_filter($shopId); - if (count($shopId) > 0) { - $query['shopId'] = $shopId; - } - } - - if ($orderStateId !== null && (is_numeric($orderStateId) || is_array($orderStateId))) { - if (is_numeric($orderStateId)) { - $orderStateId = [$orderStateId]; - } elseif (is_array($orderStateId)) { - foreach ($orderStateId as $value) { - if (!is_numeric($value)) { - throw new InvalidArgumentException('orderStateId must be an instance of int or an array of int'); - } - } - } - $orderStateId = array_filter($orderStateId); - if (count($orderStateId) > 0) { - $query['orderStateId'] = $orderStateId; - } - } - - if ($tag !== null && (is_string($tag) || is_array($tag))) { - if (is_string($tag)) { - $tag = [$tag]; - } - $tag = array_filter($tag); - if (count($tag) > 0) { - $query['tag'] = $tag; - } - } - - if ($minPayDate !== null && $minPayDate instanceof DateTime) { - $query['minPayDate'] = $minPayDate->format('c'); - } - - if ($maxPayDate !== null && $maxPayDate instanceof DateTime) { - $query['maxPayDate'] = $maxPayDate->format('c'); - } - - if (is_bool($includePositions) && $includePositions === true) { - $query['includePositions'] = 'true'; - } - - return $this->requestGET( - 'orders/invoices', - $query, - Response\GetInvoicesResponse::class - ); - } - - #endregion - - #endregion - - #region SHIPMENTS - - #region GET - - /** - * Query all defined shipping providers - * - * @return Response\GetShippingProvidersResponse The shipping providers response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getShippingProviders() - { - $providers = $this->requestGET( - 'shipment/shippingproviders', - [], - Model\ShippingProvider::class . '[]' - ); - - $response = new Response\GetShippingProvidersResponse(); - $response->data = $providers; - return $response; - } - - #endregion - - #region POST - - /** - * Creates a shipment for an order in billbee - * - * @return Response\ShipWithLabelResponse The response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function shipWithLabel(Model\ShipmentWithLabel $shipment) - { - $result = $this->requestPOST( - 'shipment/shipwithlabel', - $this->jom->serialize($shipment), - Response\ShipWithLabelResponse::class - ); - - return $result; - } - - #endregion - - #endregion - - #region PRODUCT CUSTOM FIELDS - - #region GET - - /** - * Get a list of all custom fields - * - * @param int $page The start page - * @param int $pageSize The page size - * @return Response\GetCustomFieldDefinitionsResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getCustomFieldDefinitions($page = 1, $pageSize = 50) - { - $query = [ - 'page' => max(1, $page), - 'pageSize' => max(1, $pageSize), - ]; - - return $this->requestGET( - 'products/custom-fields', - $query, - Response\GetCustomFieldDefinitionsResponse::class - ); - } - - /** - * Get a single custom field - * - * @param int $id The id of the custom field - * @return Response\GetCustomFieldDefinitionResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws InvalidIdException If the id is not an integer or negative - * @throws Exception If the response cannot be parsed - */ - public function getCustomFieldDefinition($id) - { - if (!is_integer($id) || $id < 1) { - throw new InvalidIdException(); - } - - return $this->requestGET( - 'products/custom-fields/' . $id, - [], - Response\GetCustomFieldDefinitionResponse::class - ); - } - - #endregion - - #endregion - - #region WEB HOOKS - - #region GET + use LoggerAwareTrait; /** - * Get a list of all registered web hooks - * - * @return Model\WebHook[] The Response + * The API Endpoint * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed + * @var string */ - public function getWebHooks() - { - return $this->requestGET( - 'webhooks', - [], - Model\WebHook::class . '[]' - ); - } + protected $endpoint = 'https://api.billbee.io/api/v1/'; /** - * Get a web hook by id - * - * @param int $id The id of the web hook - * @return Model\WebHook The Response + * The JSON Object Mapper * - * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @var ObjectMapper */ - public function getWebHook($id) - { - return $this->requestGET( - 'webhooks/' . $id, - [], - Model\WebHook::class - ); - } + protected $jom = null; /** - * Get a list of all available filters + * If true, the requests will be performed using a batch call. + * Each single call returns null. + * Call the executeBatch method to execute all calls and retrieve the responses * - * @return array The Response + * @see Client::executeBatch() * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed + * @var bool */ - public function getWebHookFilters() - { - return $this->requestGET( - 'webhooks/filters', - [], - Model\WebHookFilter::class . '[]' - ); - } - - #endregion - - #region POST + private $useBatching = false; /** - * Creates a new web hook - * - * @param Model\WebHook $webHook The web hook which should be created - * @return Model\WebHook The created web hook + * Contains all requests in batch mode * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed + * @var array */ - public function createWebHook(Model\WebHook $webHook) - { - return $this->requestPOST( - 'webhooks', - $this->jom->serialize($webHook), - Model\WebHook::class - ); - } - - #endregion - - #region PUT + protected $requestPool = []; /** - * Updates a web hook - * - * @param Model\WebHook $webHook The web hook - * @return bool True if the web hook was updated + * If true, the requests will be logged * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws InvalidArgumentException If the web hook has no id - * @throws Exception If the response cannot be parsed + * @var bool */ - public function updateWebHook(Model\WebHook $webHook) - { - if ($webHook->id === null) { - throw new InvalidArgumentException('The id of the webHook cannot be empty'); - } + private $logRequests = false; - $res = $this->requestPUT( - 'webhooks/' . $webHook->id, - $this->jom->serialize($webHook), - Model\WebHook::class - ); + /** @var ProductsEndpoint */ + private $productsEndpoint; - return $res === null; - } + /** @var ProvisioningEndpoint */ + private $provisioningEndpoint; - #endregion + /** @var EventsEndpoint */ + private $eventsEndpoint; - #region DELETE + /** @var OrdersEndpoint */ + private $ordersEndpoint; - /** - * Deletes all existing WebHook registrations. - * - * @return bool True if the web hooks was deleted - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function deleteAllWebHooks() - { - $res = $this->requestDELETE( - 'webhooks', - [], - Response\BaseResponse::class - ); - return $res === null; - } + /** @var InvoiceEndpoint */ + private $invoicesEndpoint; - /** - * Deletes an existing WebHook registration - * - * @param int $id The id of the web hook which should be deleted - * @return bool True if the web hook was deleted - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws InvalidArgumentException If the web hook has no id - * @throws Exception If the response cannot be parsed - */ - public function deleteWebHookById($id) - { - $webHook = new Model\WebHook(); - $webHook->id = $id; - return $this->deleteWebHook($webHook); - } + /** @var ShipmentsEndpoint */ + private $shipmentsEndpoint; - /** - * Deletes an existing WebHook registration - * - * @param Model\WebHook $webHook The web hook which should be deleted - * @return bool True if the web hook was deleted - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws InvalidArgumentException If the web hook has no id - * @throws Exception If the response cannot be parsed - */ - public function deleteWebHook(Model\WebHook $webHook) - { - if ($webHook->id === null) { - throw new InvalidArgumentException('The id of the webHook cannot be empty'); - } + /** @var ProductCustomFieldsEndpoint */ + private $customFieldsEndpoint; - $res = $this->requestDELETE( - 'webhooks/' . $webHook->id, - [], - Response\BaseResponse::class - ); - return $res === null; - } + /** @var WebHooksEndpoint */ + private $webHooksEndpoint; - #endregion + /** @var CustomersEndpoint */ + private $customersEndpoint; - #endregion + /** @var CloudStorageEndpoint */ + private $cloudStoragesEndpoint; - #region CUSTOMERS + /** @var LayoutsEndpoint */ + private $layoutsEndpoint; - #region GET + /** @var SearchEndpoint */ + private $searchEndpoint; - /** - * Get a list of all customers - * - * @return Response\GetCustomersResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getCustomers() - { - return $this->requestGET( - 'customers', - [], - Response\GetCustomersResponse::class - ); - } + /** @var CustomClient */ + private $client; /** - * Get a single customers - * - * @param int $id The id of the customer - * @return Response\GetCustomerResponse The Response + * Instantiates a new Billbee API client * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws InvalidIdException If the id is not an integer or negative - * @throws Exception If the response cannot be parsed + * @param string $username The Billbee username + * @param string $apiPassword The API password for the user + * @param string $apiKey The API Key + * @param LoggerInterface $logger Sets a optional logger + * @throws Exception */ - public function getCustomer($id) + public function __construct($username, $apiPassword, $apiKey, LoggerInterface $logger = null) { - if ($id === null || !is_integer($id) || $id < 1) { - throw new InvalidIdException(); + $this->client = new CustomClient([ + 'base_uri' => $this->endpoint, + 'auth' => [$username, $apiPassword], + 'headers' => [ + 'X-Billbee-Api-Key' => $apiKey, + ] + ]); + + $this->setLogger($logger); + $this->client->setLogger($logger); + try { + $this->jom = new ObjectMapper(new JsonSerializer()); + } catch (Exception $ex) { + if ($logger !== null) { + $this->logger->critical('Object Mapper could not be created.'); + } + throw $ex; } - return $this->requestGET( - 'customers/' . $id, - [], - Response\GetCustomerResponse::class - ); + + $serializer = $this->jom->getSerializer(); + $this->productsEndpoint = new ProductsEndpoint($this, $serializer); + $this->provisioningEndpoint = new ProvisioningEndpoint($this); + $this->eventsEndpoint = new EventsEndpoint($this); + $this->ordersEndpoint = new OrdersEndpoint($this, $serializer, $logger); + $this->invoicesEndpoint = new InvoiceEndpoint($this); + $this->shipmentsEndpoint = new ShipmentsEndpoint($this, $serializer); + $this->customFieldsEndpoint = new ProductCustomFieldsEndpoint($this); + $this->webHooksEndpoint = new WebHooksEndpoint($this, $serializer); + $this->customersEndpoint = new CustomersEndpoint($this, $serializer); + $this->cloudStoragesEndpoint = new CloudStorageEndpoint($this); + $this->layoutsEndpoint = new LayoutsEndpoint($this); + $this->searchEndpoint = new SearchEndpoint($this); } - /** - * Get the addresses for a single customers - * - * @param int $id The id of the customer - * @param int $page The start page - * @param int $pageSize The page size - * - * @return Response\GetCustomerAddressesResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws InvalidIdException If the id is not an integer or negative - * @throws Exception If the response cannot be parsed - */ - public function getCustomerAddresses($id, $page = 1, $pageSize = 50) + /** @return ProductsEndpoint */ + public function products() { - if ($id === null || !is_integer($id) || $id < 1) { - throw new InvalidIdException(); - } + return $this->productsEndpoint; + } - $query = [ - 'page' => max(1, $page), - 'pageSize' => max(1, $pageSize), - ]; - return $this->requestGET( - 'customers/' . $id . '/addresses', - $query, - Response\GetCustomerAddressesResponse::class - ); + /** @return ProvisioningEndpoint */ + public function provisioning() + { + return $this->provisioningEndpoint; } - /** - * Queries a single address from a customer - * - * @param int $id The id of the address - * - * @return Response\GetCustomerAddressResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws InvalidIdException If the id is not an integer or negative - * @throws Exception If the response cannot be parsed - */ - public function getCustomerAddress($id) + /** @return EventsEndpoint */ + public function events() { - return $this->requestGET( - 'customers/addresses/' . $id, - [], - Response\GetCustomerAddressResponse::class - ); + return $this->eventsEndpoint; } - /** - * Get the orders for a single customers - * - * @param int $id The id of the customer - * @param int $page The start page - * @param int $pageSize The page size - * - * @return Response\GetOrdersResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws InvalidIdException If the id is not an integer or negative - * @throws Exception If the response cannot be parsed - */ - public function getCustomerOrders($id, $page = 1, $pageSize = 50) + /** @return OrdersEndpoint */ + public function orders() { - if ($id === null || !is_integer($id) || $id < 1) { - throw new InvalidIdException(); - } - - $query = [ - 'page' => max(1, $page), - 'pageSize' => max(1, $pageSize), - ]; - - return $this->requestGET( - 'customers/' . $id . '/orders', - $query, - Response\GetOrdersResponse::class - ); + return $this->ordersEndpoint; } - #endregion - - #region POST - - /** - * Creates a new customers - * - * @param Model\Customer $customer The customer - * @param Model\CustomerAddress $address The customers address - * @return Response\GetCustomerResponse The created customer - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function createCustomer(Model\Customer $customer, Model\CustomerAddress $address) + /** @return InvoiceEndpoint */ + public function invoices() { - $customerModel = json_decode($this->jom->serialize($customer), true); - $customerModel['Address'] = json_decode($this->jom->serialize($address), true); - - return $this->requestPOST( - 'customers', - json_encode($customerModel), - Response\GetCustomerResponse::class - ); + return $this->invoicesEndpoint; } - #endregion - - #region PUT - - /** - * Updates a customer - * - * @param Model\Customer $customer The customer - * @return Response\GetCustomersResponse The customer - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws InvalidIdException If the customers id is invalid - * @throws Exception If the response cannot be parsed - */ - public function updateCustomer(Model\Customer $customer) + /** @return ShipmentsEndpoint */ + public function shipments() { - if (!is_integer($customer->id) || $customer->id < 1) { - throw new InvalidIdException(); - } - - return $this->requestPUT( - 'customers/' . $customer->id, - $this->jom->serialize($customer), - Response\GetCustomerResponse::class - ); + return $this->shipmentsEndpoint; } - #endregion - - #region PATCH - - /** - * Updates one or more fields of an address - * - * @param int $addressId The internal id of the address - * @param array $model The fields to patch - * - * @return Response\GetCustomerAddressResponse The address - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - * - */ - public function patchAddress($addressId, $model) + /** @return ProductCustomFieldsEndpoint */ + public function productCustomFields() { - return $this->requestPATCH( - 'customers/addresses/' . $addressId, - $model, - Response\GetCustomerAddressResponse::class - ); + return $this->customFieldsEndpoint; } - #endregion - - #endregion - - #region CLOUD STORAGE - - #region GET - - /** - * Get a list of all cloud storages - * - * @return Response\GetCloudStoragesResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getCloudStorages() + /** @return WebHooksEndpoint */ + public function webHooks() { - return $this->requestGET( - 'cloudstorages', - [], - Response\GetCloudStoragesResponse::class - ); + return $this->webHooksEndpoint; } - #endregion - - #endregion - - #region LAYOUTS - - #region GET - - /** - * Get a list of all layouts - * - * @return Response\GetLayoutsResponse The Response - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - public function getLayouts() + /** @return CustomersEndpoint */ + public function customers() { - return $this->requestGET( - 'layouts', - [], - Response\GetLayoutsResponse::class - ); + return $this->customersEndpoint; } - #endregion - - #endregion - - #region SEARCH - - #region GET - - /** - * Search for products, customers and orders. Type can be "order", "product" and / or "customer" - * Term can contains lucene query syntax - * - * @param string $term The search string - * @param string[] $type The data types which should be searched for the search string - * @param int $searchMode The Search mode - * - * @return Response\SearchDataResponse - * @throws QuotaExceededException If the maximum number of calls per second exceeded - */ - public function search( - $term, - $type = [ - Type\SearchType::PRODUCT, - Type\SearchType::ORDER, - Type\SearchType::CUSTOMER - ], - $searchMode = Type\SearchMode::_EXPERT - ) { - return $this->requestPOST( - 'search', // Search endpoint - [ - 'Type' => $type, - 'Term' => $term, - 'SearchMode' => $searchMode, - ], - Response\SearchDataResponse::class - ); + /** @return CloudStorageEndpoint */ + public function cloudStorages() + { + return $this->cloudStoragesEndpoint; } - #endregion + /** @return LayoutsEndpoint */ + public function layouts() + { + return $this->layoutsEndpoint; + } - #endregion + /** @return SearchEndpoint */ + public function search() + { + return $this->searchEndpoint; + } /** * Execute all requests in the pool @@ -1559,7 +262,7 @@ public function executeBatch() $boundary .= implode("\r\n--batch\r\n", $boundaries); $boundary .= "\r\n--batch--\r\n"; - $request = $this->createRequest('POST', 'batch', [ + $request = $this->client->createRequest('POST', 'batch', [ 'headers' => [ 'Content-Type' => 'multipart/mixed; boundary="batch"', 'Mime-Version' => '1.0', @@ -1586,50 +289,54 @@ public function getPoolSize() return count($this->requestPool); } - /** - * Starts an GET request - * - * @param string $node The requested node - * @param array $query The parameters - * @param string $responseClass The response class - * - * @return mixed The mapped response object + /**+ + * Enables the batch mode + * Requests will be performed using a batch call. + * Each single call returns null. + * Call the executeBatch method to execute all calls and retrieve the responses * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed + * @see Client::executeBatch() + */ + public function enableBatchMode() + { + $this->useBatching = true; + } + + /**+ + * Disables the batch mode + * Requests are executed directly and returns the result. */ - protected function requestGET( + public function disableBatchMode() + { + $this->useBatching = false; + } + + public function isBatchModeEnabled() + { + return $this->useBatching; + } + + public function get( $node, $query, $responseClass ) { return $this->internalRequest($responseClass, function () use ($node, $query) { - return $this->createRequest('GET', $node, [ - 'query' => $query + return $this->client->createRequest('GET', $node, [ + 'query' => $query, ]); }); } - /** - * Starts an POST request - * - * @param string $node The requested node - * @param mixed $data The body - * @param string $responseClass The response class - * - * @return mixed The mapped response object - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - protected function requestPOST( + public function post( $node, $data, $responseClass ) { return $this->internalRequest($responseClass, function () use ($data, $node) { $field = is_string($data) ? 'body' : 'json'; - return $this->createRequest('POST', $node, [ + + return $this->client->createRequest('POST', $node, [ $field => $data, 'headers' => [ 'Content-Type' => 'application/json', @@ -1638,26 +345,15 @@ protected function requestPOST( }); } - /** - * Starts an PUT request - * - * @param string $node The requested node - * @param mixed $data The body - * @param string $responseClass The response class - * - * @return mixed The mapped response object - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - protected function requestPUT( + public function put( $node, $data, $responseClass ) { return $this->internalRequest($responseClass, function () use ($data, $node) { $field = is_string($data) ? 'body' : 'json'; - return $this->createRequest('PUT', $node, [ + + return $this->client->createRequest('PUT', $node, [ $field => $data, 'headers' => [ 'Content-Type' => 'application/json', @@ -1678,14 +374,15 @@ protected function requestPUT( * @throws QuotaExceededException If the maximum number of calls per second exceeded * @throws Exception If the response cannot be parsed */ - protected function requestPATCH( + public function patch( $node, $data, $responseClass ) { return $this->internalRequest($responseClass, function () use ($data, $node) { $field = is_string($data) ? 'body' : 'json'; - return $this->createRequest('PATCH', $node, [ + + return $this->client->createRequest('PATCH', $node, [ $field => $data, 'headers' => [ 'Content-Type' => 'application/json', @@ -1694,26 +391,14 @@ protected function requestPATCH( }); } - /** - * Starts an DELETE request - * - * @param string $node The requested node - * @param array $query The parameters - * @param string $responseClass The response class - * - * @return mixed The mapped response object - * - * @throws QuotaExceededException If the maximum number of calls per second exceeded - * @throws Exception If the response cannot be parsed - */ - protected function requestDELETE( + public function delete( $node, $query, $responseClass ) { return $this->internalRequest($responseClass, function () use ($node, $query) { - return $this->createRequest('DELETE', $node, [ - 'query' => $query + return $this->client->createRequest('DELETE', $node, [ + 'query' => $query, ]); }); } @@ -1721,7 +406,7 @@ protected function requestDELETE( /** * Handles a general request * - * @param string $responseClass The response class + * @param string|null $responseClass The response class * @param callable $requestFactory A callable which creates the request object * * @param bool $ignorePool If true and batching is enabled, the request will be executed instead of queueing to pool @@ -1732,7 +417,6 @@ protected function requestDELETE( */ private function internalRequest($responseClass, callable $requestFactory, $ignorePool = false) { - /** @var \GuzzleHttp\Psr7\Request $request */ if ($this->useBatching === true && $ignorePool === false) { $req = [ 'responseClass' => $responseClass, @@ -1743,7 +427,6 @@ private function internalRequest($responseClass, callable $requestFactory, $igno return null; } - $contents = null; try { $request = $requestFactory(); @@ -1754,7 +437,7 @@ private function internalRequest($responseClass, callable $requestFactory, $igno ]); } /** @var ResponseInterface $res */ - $res = $this->sendAsync($request, [RequestOptions::SYNCHRONOUS => true])->wait(); + $res = $this->client->sendAsync($request, [RequestOptions::SYNCHRONOUS => true])->wait(); $contents = $res->getBody()->getContents(); if ($this->logRequests || $this->logger instanceof DiagnosticsLogger) { @@ -1789,7 +472,7 @@ private function internalRequest($responseClass, callable $requestFactory, $igno $responses = $this->getResponsesFromBody($contents); foreach ($responses as $i => $response) { $responseClass = $this->requestPool[$i]['responseClass']; - $contents = parse_response($response)->getBody()->getContents(); + $contents = Message::parseResponse($response)->getBody()->getContents(); try { if (trim($contents) != '' && trim($responseClass) != '') { $data[$i] = $this->jom->map($contents, $responseClass); diff --git a/src/ClientInterface.php b/src/ClientInterface.php new file mode 100644 index 0000000..db1e7b5 --- /dev/null +++ b/src/ClientInterface.php @@ -0,0 +1,89 @@ + + */ + +namespace BillbeeDe\BillbeeAPI; + +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use Exception; + +interface ClientInterface +{ + /** + * Starts an GET request + * + * @param string $node The requested node + * @param array $query The parameters + * @param string $responseClass The response class + * + * @return mixed The mapped response object + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function get($node, $query, $responseClass); + + /** + * Starts an POST request + * + * @param string $node The requested node + * @param mixed $data The body + * @param string $responseClass The response class + * + * @return mixed The mapped response object + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function post($node, $data, $responseClass); + + /** + * Starts an PUT request + * + * @param string $node The requested node + * @param mixed $data The body + * @param string $responseClass The response class + * + * @return mixed The mapped response object + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function put($node, $data, $responseClass); + + /** + * Starts an PATCH request + * + * @param string $node The requested node + * @param mixed $data The body + * @param string $responseClass The response class + * + * @return mixed The mapped response object + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function patch($node, $data, $responseClass); + + /** + * Starts an DELETE request + * + * @param string $node The requested node + * @param array $query The parameters + * @param string $responseClass The response class + * + * @return mixed The mapped response object + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function delete($node, $query, $responseClass); +} diff --git a/src/AbstractClient.php b/src/CustomClient.php similarity index 71% rename from src/AbstractClient.php rename to src/CustomClient.php index 98abe05..099652f 100644 --- a/src/AbstractClient.php +++ b/src/CustomClient.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -13,26 +13,32 @@ namespace BillbeeDe\BillbeeAPI; use GuzzleHttp\Psr7 as Psr7; +use GuzzleHttp\Psr7\Utils; +use InvalidArgumentException; use Psr\Http\Message\RequestInterface; -use Psr\Log\LoggerInterface; -use Psr\Log\NullLogger; +use Psr\Http\Message\UriInterface; /** * Helper class to make guzzle methods protected instead of private * @package BillbeeDe\BillbeeAPI */ -abstract class AbstractClient extends \GuzzleHttp\Client +class CustomClient extends \GuzzleHttp\Client { - /** @var \Psr\Log\LoggerInterface */ - protected $logger; + use LoggerAwareTrait; - protected function createRequest($method, $uri, $options) + /** + * @param string $method + * @param string $uri + * @param array $options + * @return RequestInterface + */ + public function createRequest(string $method, ?string $uri, array $options) { $options = $this->prepareDefaults($options); // Remove request modifying parameter because it can be done up-front. - $headers = isset($options['headers']) ? $options['headers'] : []; - $body = isset($options['body']) ? $options['body'] : null; - $version = isset($options['version']) ? $options['version'] : '1.1'; + $headers = $options['headers'] ?? []; + $body = $options['body'] ?? null; + $version = $options['version'] ?? '1.1'; // Merge the URI into the base URI. $uri = $this->buildUri($uri, $options); @@ -40,18 +46,19 @@ protected function createRequest($method, $uri, $options) if (count($headers) > 0 || strlen($body) > 0) { $this->logger->debug('Request headers + body', ['headers' => $headers, 'body' => $body]); } + return $this->applyOptions(new Psr7\Request($method, $uri, $headers, $body, $version), $options); } /** Guzzle overrides */ - protected function buildUri($uri, array $config) + protected function buildUri(?string $uri, array $config): UriInterface { // for BC we accept null which would otherwise fail in uri_for - $uri = Psr7\uri_for($uri === null ? '' : $uri); + $uri = Utils::uriFor($uri === null ? '' : $uri); if (isset($config['base_uri'])) { - $uri = Psr7\UriResolver::resolve(Psr7\uri_for($config['base_uri']), $uri); + $uri = Psr7\UriResolver::resolve(Utils::uriFor($config['base_uri']), $uri); } return $uri->getScheme() === '' && $uri->getHost() !== '' ? $uri->withScheme('http') : $uri; @@ -75,7 +82,7 @@ protected function prepareDefaults($options) $defaults['_conditional'] = null; unset($options['headers']); } elseif (!is_array($options['headers'])) { - throw new \InvalidArgumentException('headers must be an array'); + throw new InvalidArgumentException('headers must be an array'); } } @@ -92,17 +99,22 @@ protected function prepareDefaults($options) return $result; } + /** + * @param RequestInterface $request + * @param array $options + * @return RequestInterface + */ protected function applyOptions(RequestInterface $request, array &$options) { $modify = []; if (isset($options['form_params'])) { if (isset($options['multipart'])) { - throw new \InvalidArgumentException('You cannot use ' - . 'form_params and multipart at the same time. Use the ' - . 'form_params option if you want to send application/' - . 'x-www-form-urlencoded requests, and the multipart ' - . 'option to send multipart/form-data requests.'); + throw new InvalidArgumentException('You cannot use ' + .'form_params and multipart at the same time. Use the ' + .'form_params option if you want to send application/' + .'x-www-form-urlencoded requests, and the multipart ' + .'option to send multipart/form-data requests.'); } $options['body'] = http_build_query($options['form_params'], '', '&'); unset($options['form_params']); @@ -139,7 +151,7 @@ protected function applyOptions(RequestInterface $request, array &$options) if (is_array($options['body'])) { $this->invalidBody(); } - $modify['body'] = Psr7\stream_for($options['body']); + $modify['body'] = Utils::streamFor($options['body']); unset($options['body']); } @@ -149,7 +161,7 @@ protected function applyOptions(RequestInterface $request, array &$options) switch ($type) { case 'basic': $modify['set_headers']['Authorization'] = 'Basic ' - . base64_encode("$value[0]:$value[1]"); + .base64_encode("$value[0]:$value[1]"); break; case 'digest': $options['curl'][CURLOPT_HTTPAUTH] = CURLAUTH_DIGEST; @@ -165,10 +177,10 @@ protected function applyOptions(RequestInterface $request, array &$options) if (isset($options['query'])) { $value = $options['query']; if (is_array($value)) { - $value = http_build_query($value, null, '&', PHP_QUERY_RFC3986); + $value = http_build_query($value, '', '&', PHP_QUERY_RFC3986); } if (!is_string($value)) { - throw new \InvalidArgumentException('query must be a string or array'); + throw new InvalidArgumentException('query must be a string or array'); } $modify['query'] = $value; unset($options['query']); @@ -177,15 +189,15 @@ protected function applyOptions(RequestInterface $request, array &$options) // Ensure that sink is not an invalid value. if (isset($options['sink'])) { if (is_bool($options['sink'])) { - throw new \InvalidArgumentException('sink must not be a boolean'); + throw new InvalidArgumentException('sink must not be a boolean'); } } - $request = Psr7\modify_request($request, $modify); + $request = Utils::modifyRequest($request, $modify); if ($request->getBody() instanceof Psr7\MultipartStream) { // Use a multipart/form-data POST if a Content-Type is not set. $options['_conditional']['Content-Type'] = 'multipart/form-data; boundary=' - . $request->getBody()->getBoundary(); + .$request->getBody()->getBoundary(); } // Merge in conditional headers if they are not present. @@ -197,7 +209,7 @@ protected function applyOptions(RequestInterface $request, array &$options) $modify['set_headers'][$k] = $v; } } - $request = Psr7\modify_request($request, $modify); + $request = Utils::modifyRequest($request, $modify); // Don't pass this internal value along to middleware/handlers. unset($options['_conditional']); } @@ -207,31 +219,10 @@ protected function applyOptions(RequestInterface $request, array &$options) protected function invalidBody() { - throw new \InvalidArgumentException('Passing in the "body" request ' - . 'option as an array to send a POST request has been deprecated. ' - . 'Please use the "form_params" request option to send a ' - . 'application/x-www-form-urlencoded request, or the "multipart" ' - . 'request option to send a multipart/form-data request.'); - } - - /** - * Returns the current registered logger - * @return LoggerInterface - */ - public function getLogger() - { - return $this->logger; - } - - /** - * Sets the logger - * @param LoggerInterface $logger - */ - public function setLogger(LoggerInterface $logger = null) - { - if ($logger == null) { - $logger = new NullLogger(); - } - $this->logger = $logger; + throw new InvalidArgumentException('Passing in the "body" request ' + .'option as an array to send a POST request has been deprecated. ' + .'Please use the "form_params" request option to send a ' + .'application/x-www-form-urlencoded request, or the "multipart" ' + .'request option to send a multipart/form-data request.'); } } diff --git a/src/Endpoint/CloudStorageEndpoint.php b/src/Endpoint/CloudStorageEndpoint.php new file mode 100644 index 0000000..0988a10 --- /dev/null +++ b/src/Endpoint/CloudStorageEndpoint.php @@ -0,0 +1,46 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Response as Response; +use Exception; + +class CloudStorageEndpoint +{ + /** @var ClientInterface */ + private $client; + + public function __construct(ClientInterface $client) + { + $this->client = $client; + } + + /** + * Get a list of all cloud storages + * + * @return Response\GetCloudStoragesResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getCloudStorages() + { + return $this->client->get( + 'cloudstorages', + [], + Response\GetCloudStoragesResponse::class + ); + } +} diff --git a/src/Endpoint/CustomersEndpoint.php b/src/Endpoint/CustomersEndpoint.php new file mode 100644 index 0000000..f8ff79e --- /dev/null +++ b/src/Endpoint/CustomersEndpoint.php @@ -0,0 +1,240 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\InvalidIdException; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Model as Model; +use BillbeeDe\BillbeeAPI\Response as Response; +use Exception; +use MintWare\DMM\Serializer\SerializerInterface; + +class CustomersEndpoint +{ + /** @var ClientInterface */ + private $client; + + /** @var SerializerInterface */ + private $serializer; + + public function __construct(ClientInterface $client, SerializerInterface $serializer) + { + $this->client = $client; + $this->serializer = $serializer; + } + + #region GET + + /** + * Get a list of all customers + * + * @return Response\GetCustomersResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getCustomers() + { + return $this->client->get( + 'customers', + [], + Response\GetCustomersResponse::class + ); + } + + /** + * Get a single customers + * + * @param int|null $id The id of the customer + * @return Response\GetCustomerResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws InvalidIdException If the id is not an integer or negative + * @throws Exception If the response cannot be parsed + */ + public function getCustomer($id) + { + if ($id === null || !is_integer($id) || $id < 1) { + throw new InvalidIdException(); + } + return $this->client->get( + 'customers/' . $id, + [], + Response\GetCustomerResponse::class + ); + } + + /** + * Get the addresses for a single customers + * + * @param int|null $id The id of the customer + * @param int $page The start page + * @param int $pageSize The page size + * + * @return Response\GetCustomerAddressesResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws InvalidIdException If the id is not an integer or negative + * @throws Exception If the response cannot be parsed + */ + public function getCustomerAddresses($id, $page = 1, $pageSize = 50) + { + if ($id === null || !is_integer($id) || $id < 1) { + throw new InvalidIdException(); + } + + $query = [ + 'page' => max(1, $page), + 'pageSize' => max(1, $pageSize), + ]; + + return $this->client->get( + 'customers/' . $id . '/addresses', + $query, + Response\GetCustomerAddressesResponse::class + ); + } + + /** + * Queries a single address from a customer + * + * @param int|null $id The id of the address + * + * @return Response\GetCustomerAddressResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws InvalidIdException If the id is not an integer or negative + * @throws Exception If the response cannot be parsed + */ + public function getCustomerAddress($id) + { + if ($id === null || !is_integer($id) || $id < 1) { + throw new InvalidIdException(); + } + + return $this->client->get( + 'customers/addresses/' . $id, + [], + Response\GetCustomerAddressResponse::class + ); + } + + /** + * Get the orders for a single customers + * + * @param int|null $id The id of the customer + * @param int $page The start page + * @param int $pageSize The page size + * + * @return Response\GetOrdersResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws InvalidIdException If the id is not an integer or negative + * @throws Exception If the response cannot be parsed + */ + public function getCustomerOrders($id, $page = 1, $pageSize = 50) + { + if ($id === null || !is_integer($id) || $id < 1) { + throw new InvalidIdException(); + } + + $query = [ + 'page' => max(1, $page), + 'pageSize' => max(1, $pageSize), + ]; + + return $this->client->get( + 'customers/' . $id . '/orders', + $query, + Response\GetOrdersResponse::class + ); + } + + #endregion + + #region POST + + /** + * Creates a new customers + * + * @param Model\CreateCustomerRequest $request The customer + * @return Response\GetCustomerResponse The created customer + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function createCustomer(Model\CreateCustomerRequest $request) + { + return $this->client->post( + 'customers', + json_encode($request), + Response\GetCustomerResponse::class + ); + } + + #endregion + + #region PUT + + /** + * Updates a customer + * + * @param Model\Customer $customer The customer + * @return Response\GetCustomersResponse The customer + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws InvalidIdException If the customers id is invalid + * @throws Exception If the response cannot be parsed + */ + public function updateCustomer(Model\Customer $customer) + { + if (!is_integer($customer->id) || $customer->id < 1) { + throw new InvalidIdException(); + } + + return $this->client->put( + 'customers/' . $customer->id, + $this->serializer->serialize($customer), + Response\GetCustomerResponse::class + ); + } + + #endregion + + + #region PATCH + + /** + * Updates one or more fields of an address + * + * @param int $addressId The internal id of the address + * @param array $model The fields to patch + * + * @return Response\GetCustomerAddressResponse The address + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + * + */ + public function patchAddress($addressId, $model) + { + return $this->client->patch( + 'customers/addresses/' . $addressId, + $model, + Response\GetCustomerAddressResponse::class + ); + } + + #endregion +} diff --git a/src/Endpoint/EventsEndpoint.php b/src/Endpoint/EventsEndpoint.php new file mode 100644 index 0000000..4ec8482 --- /dev/null +++ b/src/Endpoint/EventsEndpoint.php @@ -0,0 +1,81 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Response as Response; +use DateTimeInterface; +use Exception; + +class EventsEndpoint +{ + /** @var ClientInterface */ + private $client; + + public function __construct(ClientInterface $client) + { + $this->client = $client; + } + + /** + * Get a list of all events optionally filtered by date and / or event type + * + * @param int $page The start page + * @param int $pageSize The page size + * @param DateTimeInterface $minDate Start date + * @param DateTimeInterface $maxDate End date + * @param array $typeIds An array of event type id's + * @param int $orderId Filter for specific order id + * + * @return Response\GetEventsResponse The events + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getEvents( + $page = 1, + $pageSize = 50, + DateTimeInterface $minDate = null, + DateTimeInterface $maxDate = null, + $typeIds = [], + $orderId = null + ) { + $query = [ + 'page' => max(1, $page), + 'pageSize' => max(1, $pageSize), + ]; + + if ($minDate !== null) { + $query['minDate'] = $minDate->format('c'); + } + + if ($maxDate !== null) { + $query['maxDate'] = $maxDate->format('c'); + } + + if (is_array($typeIds) && count($typeIds) > 0) { + $query['typeId'] = $typeIds; + } + + if ($orderId != null) { + $query['orderId'] = $orderId; + } + + return $this->client->get( + 'events', + $query, + Response\GetEventsResponse::class + ); + } +} diff --git a/src/Endpoint/InvoiceEndpoint.php b/src/Endpoint/InvoiceEndpoint.php new file mode 100644 index 0000000..87d204e --- /dev/null +++ b/src/Endpoint/InvoiceEndpoint.php @@ -0,0 +1,125 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Response as Response; +use DateTimeInterface; +use Exception; +use InvalidArgumentException; + +class InvoiceEndpoint +{ + /** @var ClientInterface */ + private $client; + + public function __construct(ClientInterface $client) + { + $this->client = $client; + } + + /** + * Get a list of all invoices + * + * @param DateTimeInterface $minInvoiceDate Specifies the oldest invoice date to include + * @param DateTimeInterface $maxInvoiceDate Specifies the newest invoice date to include + * @param int $page Specifies the page to request + * @param int $pageSize Specifies the number of elements per page. Defaults to 50, max value is 250 + * @param array $shopId Specifies a list of shop ids for which invoices should be included + * @param array $orderStateId Specifies a list of state ids to include in the response + * @param array $tag Specifies a list of tags to include in the response + * @param DateTimeInterface $minPayDate Specifies the oldest pay date to include + * @param DateTimeInterface $maxPayDate Specifies the newest pay date to include + * @param bool $includePositions Specifies to include the positions + * + * @return Response\GetInvoicesResponse The Invoices + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getInvoices( + $page = 1, + $pageSize = 50, + DateTimeInterface $minInvoiceDate = null, + DateTimeInterface $maxInvoiceDate = null, + array $shopId = [], + array $orderStateId = [], + array $tag = [], + DateTimeInterface $minPayDate = null, + DateTimeInterface $maxPayDate = null, + $includePositions = false + ) { + $query = [ + 'page' => max(1, $page), + 'pageSize' => max(1, $pageSize), + ]; + + if ($minInvoiceDate !== null) { + $query['minInvoiceDate'] = $minInvoiceDate->format('c'); + } + + if ($maxInvoiceDate !== null) { + $query['maxInvoiceDate'] = $maxInvoiceDate->format('c'); + } + + if (!empty($shopId)) { + $shopId = array_values(array_filter(array_unique($shopId))); + foreach ($shopId as $value) { + if (!is_numeric($value)) { + throw new InvalidArgumentException('shopId must be an array of int'); + } + } + if (count($shopId) > 0) { + $query['shopId'] = $shopId; + } + } + + if (!empty($orderStateId)) { + $orderStateId = array_values(array_filter(array_unique($orderStateId))); + foreach ($orderStateId as $value) { + if (!is_numeric($value)) { + throw new InvalidArgumentException('orderStateId must be an array of int'); + } + } + if (count($orderStateId) > 0) { + $query['orderStateId'] = $orderStateId; + } + } + + if (!empty($tag)) { + $tag = array_values(array_filter(array_unique($tag))); + if (count($tag) > 0) { + $query['tag'] = $tag; + } + } + + if ($minPayDate !== null) { + $query['minPayDate'] = $minPayDate->format('c'); + } + + if ($maxPayDate !== null) { + $query['maxPayDate'] = $maxPayDate->format('c'); + } + + if (is_bool($includePositions) && $includePositions) { + $query['includePositions'] = 'true'; + } + + return $this->client->get( + 'orders/invoices', + $query, + Response\GetInvoicesResponse::class + ); + } +} diff --git a/src/Endpoint/LayoutsEndpoint.php b/src/Endpoint/LayoutsEndpoint.php new file mode 100644 index 0000000..26c1cee --- /dev/null +++ b/src/Endpoint/LayoutsEndpoint.php @@ -0,0 +1,47 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Response as Response; +use Exception; + +class LayoutsEndpoint +{ + /** @var ClientInterface */ + private $client; + + + public function __construct(ClientInterface $client) + { + $this->client = $client; + } + + /** + * Get a list of all layouts + * + * @return Response\GetLayoutsResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getLayouts() + { + return $this->client->get( + 'layouts', + [], + Response\GetLayoutsResponse::class + ); + } +} diff --git a/src/Endpoint/OrdersEndpoint.php b/src/Endpoint/OrdersEndpoint.php new file mode 100644 index 0000000..5402be1 --- /dev/null +++ b/src/Endpoint/OrdersEndpoint.php @@ -0,0 +1,478 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Model as Model; +use BillbeeDe\BillbeeAPI\Response as Response; +use BillbeeDe\BillbeeAPI\Type as Type; +use DateTimeInterface; +use Exception; +use InvalidArgumentException; +use MintWare\DMM\Serializer\SerializerInterface; +use Psr\Log\LoggerInterface; + +class OrdersEndpoint +{ + /** @var ClientInterface */ + private $client; + + /** @var LoggerInterface|null */ + private $logger; + + /** @var SerializerInterface */ + private $serializer; + + public function __construct( + ClientInterface $client, + SerializerInterface $serializer, + LoggerInterface $logger = null + ) { + $this->client = $client; + $this->serializer = $serializer; + $this->logger = $logger; + } + + #region GET + + /** + * Get a list of all orders optionally filtered by date + * + * @param int $page Specifies the page to request + * @param int $pageSize Specifies the pagesize. Defaults to 50, max value is 250 + * @param DateTimeInterface|null $minOrderDate Specifies the oldest order date to include in the response + * @param DateTimeInterface|null $maxOrderDate Specifies the newest order date to include in the response + * @param int[] $shopId Specifies a list of shop ids for which invoices should be included + * @param int[] $orderStateId Specifies a list of state ids to include in the response + * @param string[] $tag Specifies a list of tags the order must have attached to be included in the response + * @param null $minimumOrderId If given, all delivered orders have an Id greater than or equal to the given minimumOrderId + * @param DateTimeInterface|null $modifiedAtMin If given, the last modification has to be newer than the given date + * @param DateTimeInterface|null $modifiedAtMax If given, the last modification has to be older or equal than the given date. + * @param int $articleTitleSource The source field for the article title. + * @param boolean $excludeTags If true the list of tags passed to the call are used to filter orders to not include these tags + * + * @return Response\GetOrdersResponse The orders + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getOrders( + $page = 1, + $pageSize = 50, + DateTimeInterface $minOrderDate = null, + DateTimeInterface $maxOrderDate = null, + array $shopId = [], + array $orderStateId = [], + array $tag = [], + $minimumOrderId = null, + DateTimeInterface $modifiedAtMin = null, + DateTimeInterface $modifiedAtMax = null, + $articleTitleSource = Type\ArticleSource::ORDER_POSITION, + $excludeTags = false + ) { + $query = [ + 'page' => max(1, $page), + 'pageSize' => max(1, $pageSize), + ]; + + if ($minOrderDate !== null) { + $query['minOrderDate'] = $minOrderDate->format('c'); + } + + if ($maxOrderDate !== null) { + $query['maxOrderDate'] = $maxOrderDate->format('c'); + } + + if (!empty($shopId)) { + $shopId = array_values(array_unique(array_filter($shopId))); + foreach ($shopId as $value) { + if (!is_numeric($value)) { + throw new InvalidArgumentException('All elements in shopId must be numeric.'); + } + } + if (!empty($shopId)) { + $query['shopId'] = $shopId; + } + } + + if (!empty($orderStateId)) { + $orderStateId = array_values(array_unique(array_filter($orderStateId))); + foreach ($orderStateId as $value) { + if (!is_numeric($value)) { + throw new InvalidArgumentException('All elements in orderStateId must be numeric.'); + } + } + if (!empty($orderStateId)) { + $query['orderStateId'] = $orderStateId; + } + } + + if (!empty($tag)) { + $tag = array_values(array_unique(array_filter($tag))); + if (!empty($tag)) { + $query['tag'] = $tag; + } + } + + if (!empty($minimumOrderId)) { + $query['minimumBillBeeOrderId'] = $minimumOrderId; + } + + if ($modifiedAtMin !== null) { + $query['modifiedAtMin'] = $modifiedAtMin->format('c'); + } + + if ($modifiedAtMax !== null) { + $query['modifiedAtMax'] = $modifiedAtMax->format('c'); + } + + if (!is_numeric($articleTitleSource) || $articleTitleSource < 0 || $articleTitleSource > 2) { + throw new InvalidArgumentException(sprintf( + 'The articleTitleSource is invalid. Check %s for valid values', + Type\ArticleSource::class + )); + } + $query['articleTitleSource'] = $articleTitleSource; + + if (is_bool($excludeTags) && $excludeTags) { + $query['excludeTags'] = 'true'; + } + + return $this->client->get( + 'orders', + $query, + Response\GetOrdersResponse::class + ); + } + + /** + * Returns a list of fields which can be updated with the patchOrder call + * + * @return Response\GetPatchableFieldsResponse + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getPatchableFields() + { + return $this->client->get( + 'orders/PatchableFields', + [], + Response\GetPatchableFieldsResponse::class + ); + } + + /** + * Get a single order by its internal billbee id + * + * @param int $id The internal billbee id of the order + * + * @return Response\GetOrderResponse The order response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getOrder($id) + { + return $this->client->get( + 'orders/'.$id, + [], + Response\GetOrderResponse::class + ); + } + + /** + * Get a single order by its internal billbee id + * + * @param string $extRef The internal billbee id of the order + * + * @return Response\GetOrderResponse The order response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getOrderByOrderNumber($extRef) + { + if (!strstr($extRef, '%')) { + $extRef = urlencode($extRef); + } + + return $this->client->get( + 'orders/findbyextref/'.$extRef, + [], + Response\GetOrderResponse::class + ); + } + + + /** + * Find a single order by its external id (order number) + * + * @param string $externalId The order id in the partner system + * @param string $partner The partner name. Possible partners in Partner-Class + * + * @return Response\GetOrderResponse The order response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + * + * @see \BillbeeDe\BillbeeAPI\Type\Partner + */ + public function getOrderByPartner($externalId, $partner) + { + if (!strstr($externalId, '%')) { + $externalId = urlencode($externalId); + } + + return $this->client->get( + 'orders/find/'.$externalId.'/'.$partner, + [], + Response\GetOrderByPartnerResponse::class + ); + } + + #endregion + + #region POST + + /** + * Get a single order by its internal billbee id + * + * @param Model\Order $order The order Data + * @param int $shopId The id of the shop + * + * @return Response\BaseResponse The response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function createOrder(Model\Order $order, $shopId) + { + return $this->client->post( + 'orders?shopId='.$shopId, + $this->serializer->serialize($order), + Response\BaseResponse::class + ); + } + + /** + * Attach one or more tags to an order + * + * @param int $orderId The internal id of the order + * @param string[] $tags Tags to attach + * + * @return Response\BaseResponse The response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function addOrderTags($orderId, array $tags = []) + { + return $this->client->post( + 'orders/'.$orderId.'/tags', + json_encode(['Tags' => $tags]), + Response\BaseResponse::class + ); + } + + /** + * Attach one or more tags to an order + * + * @param int $orderId The internal id of the order + * @param Model\Shipment $shipment The Shipment + * + * @return bool True if the shipment was added + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function addOrderShipment($orderId, Model\Shipment $shipment) + { + $res = $this->client->post( + 'orders/'.$orderId.'/shipment', + $this->serializer->serialize($shipment), + Response\BaseResponse::class + ); + + return $res === '' || $res === null; + } + + /** + * Create an delivery note for an existing order + * + * @param int $orderId The internal id of the order + * @param bool $includePdf If true, the PDF is included in the response as base64 encoded string + * + * @return Response\CreateDeliveryNoteResponse The response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function createDeliveryNote($orderId, $includePdf = false) + { + return $this->client->post( + 'orders/CreateDeliveryNote/'.$orderId.'?includePdf='.($includePdf ? 'True' : 'False'), + [], + Response\CreateDeliveryNoteResponse::class + ); + } + + /** + * Create an invoice for an existing order + * + * @param int $orderId The internal id of the order + * @param bool $includePdf If true, the PDF is included in the response as base64 encoded string + * @param int|null $templateId The internal id of a template + * @param int|null $sendToCloudId The internal id of an cloud storage where the invoice is uploaded to + * + * @return Response\CreateDeliveryNoteResponse The response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function createInvoice($orderId, $includePdf = false, $templateId = null, $sendToCloudId = null) + { + $node = 'orders/CreateInvoice/'.$orderId.'?includeInvoicePdf='.($includePdf ? 'True' : 'False'); + if ($templateId != null && is_numeric($templateId)) { + $node .= '&templateId='.$templateId; + } + if ($sendToCloudId != null && is_numeric($sendToCloudId)) { + $node .= '&sendToCloudId='.$sendToCloudId; + } + + return $this->client->post( + $node, + [], + Response\CreateInvoiceResponse::class + ); + } + + /** + * Sends a message to the customer + * + * @param int $orderId The internal id of the order + * @param Model\MessageForCustomer $message The message model + * @return bool True if the message was send, otherwise false + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + * @throws InvalidArgumentException If the request is not valid + */ + public function sendMessage($orderId, Model\MessageForCustomer $message) + { + if ($message->sendMode < 0 || $message->sendMode > 4) { + $msg = sprintf("The sendMode is invalid. Check the %s class for valid values", Type\SendMode::class); + throw new InvalidArgumentException($msg); + } + if (!is_array($message->subject) || count($message->subject) == 0) { + throw new InvalidArgumentException("You have to specify a message subject"); + } + if (!is_array($message->body) || count($message->body) == 0) { + throw new InvalidArgumentException("You have to specify a message body"); + } + if ($message->sendMode == Type\SendMode::EXTERNAL_EMAIL && empty($message->alternativeEmailAddress)) { + $msg = "With sendMode == 4 it's required to specify an alternativeEmailAddress"; + throw new InvalidArgumentException($msg); + } + + if ($message->sendMode != Type\SendMode::EXTERNAL_EMAIL + && !empty($message->alternativeEmailAddress) + && $this->logger != null + ) { + $this->logger->warning('The alternative email address is ignored because sendMode != 4'); + } + + $res = $this->client->post( + 'orders/'.$orderId.'/send-message', + $this->serializer->serialize($message), + Response\BaseResponse::class + ); + + return $res === '' || $res === null; + } + + #endregion + + #region PUT + + /** + * Updates/Sets the tags attached to an order + * + * @param int $orderId The internal id of the order + * @param string[] $tags Tags to attach + * + * @return Response\BaseResponse The response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function setOrderTags($orderId, array $tags = []) + { + return $this->client->put( + 'orders/'.$orderId.'/tags', + json_encode(['Tags' => $tags]), + Response\BaseResponse::class + ); + } + + /** + * Changes the main state of a single order + * + * @param int $orderId The internal id of the order + * @param int $newState The new OrderState + * + * @return bool True if the state was updated + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + * + * @see \BillbeeDe\BillbeeAPI\Type\OrderState + */ + public function setOrderState($orderId, $newState) + { + $res = $this->client->put( + 'orders/'.$orderId.'/orderstate', + json_encode(['NewStateId' => $newState]), + Response\BaseResponse::class + ); + + return $res === null; + } + + #endregion + + #region PATCH + + /** + * Updates one or more fields of an order + * + * @param int $orderId The internal id of the order + * @param array $model The fields to patch + * + * @return Response\GetOrderResponse The order + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function patchOrder($orderId, $model) + { + return $this->client->patch( + 'orders/'.$orderId, + $model, + Response\GetOrderResponse::class + ); + } + + #endregion +} diff --git a/src/Endpoint/ProductCustomFieldsEndpoint.php b/src/Endpoint/ProductCustomFieldsEndpoint.php new file mode 100644 index 0000000..f13274c --- /dev/null +++ b/src/Endpoint/ProductCustomFieldsEndpoint.php @@ -0,0 +1,82 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\InvalidIdException; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Response as Response; +use Exception; + +class ProductCustomFieldsEndpoint +{ + /** @var ClientInterface */ + private $client; + + public function __construct(ClientInterface $client) + { + $this->client = $client; + } + + + #region GET + + /** + * Get a list of all custom fields + * + * @param int $page The start page + * @param int $pageSize The page size + * @return Response\GetCustomFieldDefinitionsResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getCustomFieldDefinitions($page = 1, $pageSize = 50) + { + $query = [ + 'page' => max(1, $page), + 'pageSize' => max(1, $pageSize), + ]; + + return $this->client->get( + 'products/custom-fields', + $query, + Response\GetCustomFieldDefinitionsResponse::class + ); + } + + /** + * Get a single custom field + * + * @param int $id The id of the custom field + * @return Response\GetCustomFieldDefinitionResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws InvalidIdException If the id is not an integer or negative + * @throws Exception If the response cannot be parsed + */ + public function getCustomFieldDefinition($id) + { + if (!is_integer($id) || $id < 1) { + throw new InvalidIdException(); + } + + return $this->client->get( + 'products/custom-fields/' . $id, + [], + Response\GetCustomFieldDefinitionResponse::class + ); + } + + #endregion +} diff --git a/src/Endpoint/ProductsEndpoint.php b/src/Endpoint/ProductsEndpoint.php new file mode 100644 index 0000000..040dd68 --- /dev/null +++ b/src/Endpoint/ProductsEndpoint.php @@ -0,0 +1,246 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Model as Model; +use BillbeeDe\BillbeeAPI\Response as Response; +use BillbeeDe\BillbeeAPI\Type as Type; +use DateTime; +use Exception; +use MintWare\DMM\Serializer\SerializerInterface; + +class ProductsEndpoint +{ + /** @var ClientInterface */ + private $client; + + /** @var SerializerInterface */ + private $serializer; + + public function __construct(ClientInterface $client, SerializerInterface $serializer) + { + $this->client = $client; + $this->serializer = $serializer; + } + + /** + * Get a list of all products optionally filtered by date + * + * @param int $page The start page + * @param int $pageSize The page size + * @param DateTime|null $minCreatedAt The date of creation of the products + * @return Response\GetProductsResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getProducts($page = 1, $pageSize = 50, DateTime $minCreatedAt = null) + { + $query = [ + 'page' => max(1, $page), + 'pageSize' => max(1, $pageSize), + ]; + + if ($minCreatedAt !== null && $minCreatedAt instanceof DateTime) { + $query['minCreatedAt'] = $minCreatedAt->format('c'); + } + + return $this->client->get( + 'products', + $query, + Response\GetProductsResponse::class + ); + } + + /** + * Get a single product by Id + * + * @param int $productId The product id + * @param string $lookupBy Either the value id, ean or the value sku to specify the meaning of the id parameter + * @return Response\GetProductResponse The product response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + * @see \BillbeeDe\BillbeeAPI\Type\ProductLookupBy + */ + public function getProduct($productId, $lookupBy = Type\ProductLookupBy::ID) + { + return $this->client->get( + 'products/' . $productId, + ['lookupBy' => $lookupBy], + Response\GetProductResponse::class + ); + } + + /** + * Get a list of all defined categories + * + * @return Response\GetCategoriesResponse The category response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getCategories() + { + return $this->client->get( + 'products/category', + [], + Response\GetCategoriesResponse::class + ); + } + + /** + * + * Returns a list of fields which can be updated with the patchProduct call + * + * @return Response\GetPatchableFieldsResponse + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + * + * @see Client::patchProduct($productId, $model) + */ + public function getPatchableProductFields() + { + return $this->client->get( + 'products/PatchableFields', + [], + Response\GetPatchableFieldsResponse::class + ); + } + + #endregion + + #region POST + + /** + * Updates the stock for a single product + * + * @param Model\Stock $stockModel The stock model + * @return Response\UpdateStockResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function updateStock(Model\Stock $stockModel) + { + return $this->client->post( + 'products/updatestock', + $stockModel, + Response\UpdateStockResponse::class + ); + } + + /** + * Updates the stock for multiple products + * + * @param Model\Stock[] $stockModels The stock models + * @return Response\UpdateStockResponse[] The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function updateStockMultiple(array $stockModels) + { + return $this->client->post( + 'products/updatestockmultiple', + $stockModels, + Response\UpdateStockResponse::class . '[]' + ); + } + + /** + * Updates the stock code for a single products + * + * @param Model\StockCode $stockCodeModel The stock code model + * @return Response\BaseResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function updateStockCode(Model\StockCode $stockCodeModel) + { + return $this->client->post( + 'products/updatestockcode', + $this->serializer->serialize($stockCodeModel), + Response\BaseResponse::class + ); + } + + /** + * Creates a new product + * + * @param Model\Product $product + * @return Response\GetProductResponse The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function createProduct(Model\Product $product) + { + return $this->client->post( + 'products', + $this->serializer->serialize($product), + Response\GetProductResponse::class + ); + } + + #endregion + + #region PATCH + + /** + * Updates one or more fields of a product + * + * @param int $productId The internal id of the product + * @param array $model The fields to patch + * + * @return Response\GetProductResponse The order + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + * + * @see Client::getPatchableProductFields() + */ + public function patchProduct($productId, $model) + { + return $this->client->patch( + 'products/' . $productId, + $model, + Response\GetProductResponse::class + ); + } + + #endregion + + #region DELETE + + /** + * Deletes a product by id + * + * @param int $productId The Id of the product + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function deleteProduct($productId) + { + $this->client->delete( + 'products/' . $productId, + [], + Response\BaseResponse::class + ); + } +} diff --git a/src/Endpoint/ProvisioningEndpoint.php b/src/Endpoint/ProvisioningEndpoint.php new file mode 100644 index 0000000..f948e06 --- /dev/null +++ b/src/Endpoint/ProvisioningEndpoint.php @@ -0,0 +1,46 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Response as Response; +use Exception; + +class ProvisioningEndpoint +{ + /** @var ClientInterface */ + private $client; + + public function __construct(ClientInterface $client) + { + $this->client = $client; + } + + /** + * Returns information about Billbee terms and conditions + * + * @return Response\GetTermsInfoResponse The terms info response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getTermsInfo() + { + return $this->client->get( + 'automaticprovision/termsinfo', + [], + Response\GetTermsInfoResponse::class + ); + } +} diff --git a/src/Endpoint/SearchEndpoint.php b/src/Endpoint/SearchEndpoint.php new file mode 100644 index 0000000..a3a5fe7 --- /dev/null +++ b/src/Endpoint/SearchEndpoint.php @@ -0,0 +1,61 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Response as Response; +use BillbeeDe\BillbeeAPI\Type as Type; + +class SearchEndpoint +{ + /** @var ClientInterface */ + private $client; + + + public function __construct(ClientInterface $client) + { + $this->client = $client; + } + + /** + * Search for products, customers and orders. Type can be "order", "product" and / or "customer" + * Term can contains lucene query syntax + * + * @param string $term The search string + * @param string[] $type The data types which should be searched for the search string + * @param int $searchMode The Search mode + * + * @return Response\SearchDataResponse + * @throws QuotaExceededException If the maximum number of calls per second exceeded + */ + public function search( + $term, + $type = [ + Type\SearchType::PRODUCT, + Type\SearchType::ORDER, + Type\SearchType::CUSTOMER, + ], + $searchMode = Type\SearchMode::_EXPERT + ) { + return $this->client->post( + 'search', + [ + 'Type' => $type, + 'Term' => $term, + 'SearchMode' => $searchMode, + ], + Response\SearchDataResponse::class + ); + } +} diff --git a/src/Endpoint/ShipmentsEndpoint.php b/src/Endpoint/ShipmentsEndpoint.php new file mode 100644 index 0000000..493cbbe --- /dev/null +++ b/src/Endpoint/ShipmentsEndpoint.php @@ -0,0 +1,86 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\BatchClientInterface; +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Model as Model; +use BillbeeDe\BillbeeAPI\Response as Response; +use Exception; +use MintWare\DMM\Serializer\SerializerInterface; + +class ShipmentsEndpoint +{ + /** @var ClientInterface */ + private $client; + /** @var SerializerInterface */ + private $serializer; + + public function __construct(ClientInterface $client, SerializerInterface $serializer) + { + $this->client = $client; + $this->serializer = $serializer; + } + + #region GET + + /** + * Query all defined shipping providers + * + * @return Response\GetShippingProvidersResponse|null The shipping providers response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getShippingProviders() + { + $providers = $this->client->get( + 'shipment/shippingproviders', + [], + Model\ShippingProvider::class.'[]' + ); + + if ($this->client instanceof BatchClientInterface && $this->client->isBatchModeEnabled()) { + return null; + } + + $response = new Response\GetShippingProvidersResponse(); + $response->data = $providers; + + return $response; + } + + #endregion + + #region POST + + /** + * Creates a shipment for an order in billbee + * + * @return Response\ShipWithLabelResponse The response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function shipWithLabel(Model\ShipmentWithLabel $shipment) + { + return $this->client->post( + 'shipment/shipwithlabel', + $this->serializer->serialize($shipment), + Response\ShipWithLabelResponse::class + ); + } + + #endregion +} diff --git a/src/Endpoint/WebHooksEndpoint.php b/src/Endpoint/WebHooksEndpoint.php new file mode 100644 index 0000000..549a67d --- /dev/null +++ b/src/Endpoint/WebHooksEndpoint.php @@ -0,0 +1,205 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; +use BillbeeDe\BillbeeAPI\Model as Model; +use BillbeeDe\BillbeeAPI\Response as Response; +use Exception; +use InvalidArgumentException; +use MintWare\DMM\Serializer\SerializerInterface; + +class WebHooksEndpoint +{ + /** @var ClientInterface */ + private $client; + + /** @var SerializerInterface */ + private $serializer; + + public function __construct(ClientInterface $client, SerializerInterface $serializer) + { + $this->client = $client; + $this->serializer = $serializer; + } + + #region GET + + /** + * Get a list of all registered web hooks + * + * @return Model\WebHook[] The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getWebHooks() + { + return $this->client->get( + 'webhooks', + [], + Model\WebHook::class . '[]' + ); + } + + /** + * Get a web hook by id + * + * @param string $id The id of the web hook + * @return Model\WebHook The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + */ + public function getWebHook($id) + { + return $this->client->get( + 'webhooks/' . $id, + [], + Model\WebHook::class + ); + } + + /** + * Get a list of all available filters + * + * @return array The Response + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function getWebHookFilters() + { + return $this->client->get( + 'webhooks/filters', + [], + Model\WebHookFilter::class . '[]' + ); + } + + #endregion + + #region POST + + /** + * Creates a new web hook + * + * @param Model\WebHook $webHook The web hook which should be created + * @return Model\WebHook The created web hook + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function createWebHook(Model\WebHook $webHook) + { + return $this->client->post( + 'webhooks', + $this->serializer->serialize($webHook), + Model\WebHook::class + ); + } + + #endregion + + #region PUT + + /** + * Updates a web hook + * + * @param Model\WebHook $webHook The web hook + * @return bool True if the web hook was updated + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws InvalidArgumentException If the web hook has no id + * @throws Exception If the response cannot be parsed + */ + public function updateWebHook(Model\WebHook $webHook) + { + if ($webHook->id === null) { + throw new InvalidArgumentException('The id of the webHook cannot be empty'); + } + + $res = $this->client->put( + 'webhooks/' . $webHook->id, + $this->serializer->serialize($webHook), + Model\WebHook::class + ); + + return $res === null; + } + + #endregion + + #region DELETE + + /** + * Deletes all existing WebHook registrations. + * + * @return bool True if the web hooks was deleted + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws Exception If the response cannot be parsed + */ + public function deleteAllWebHooks() + { + $res = $this->client->delete( + 'webhooks', + [], + Response\BaseResponse::class + ); + return $res === null; + } + + /** + * Deletes an existing WebHook registration + * + * @param string $id The id of the web hook which should be deleted + * @return bool True if the web hook was deleted + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws InvalidArgumentException If the web hook has no id + * @throws Exception If the response cannot be parsed + */ + public function deleteWebHookById($id) + { + $webHook = new Model\WebHook(); + $webHook->id = $id; + return $this->deleteWebHook($webHook); + } + + /** + * Deletes an existing WebHook registration + * + * @param Model\WebHook $webHook The web hook which should be deleted + * @return bool True if the web hook was deleted + * + * @throws QuotaExceededException If the maximum number of calls per second exceeded + * @throws InvalidArgumentException If the web hook has no id + * @throws Exception If the response cannot be parsed + */ + public function deleteWebHook(Model\WebHook $webHook) + { + if ($webHook->id === null) { + throw new InvalidArgumentException('The id of the webHook cannot be empty'); + } + + $res = $this->client->delete( + 'webhooks/' . $webHook->id, + [], + Response\BaseResponse::class + ); + return $res === null; + } + + #endregion +} diff --git a/src/Exception/InvalidIdException.php b/src/Exception/InvalidIdException.php index ee8b701..5056557 100644 --- a/src/Exception/InvalidIdException.php +++ b/src/Exception/InvalidIdException.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -12,9 +12,11 @@ namespace BillbeeDe\BillbeeAPI\Exception; -class InvalidIdException extends \InvalidArgumentException +use InvalidArgumentException; + +class InvalidIdException extends InvalidArgumentException { - public function __construct($code = 0, \Throwable $previous = null) + public function __construct($code = 0, $previous = null) { parent::__construct('Id must be an instance of integer and positive', $code, $previous); } diff --git a/src/Exception/QuotaExceededException.php b/src/Exception/QuotaExceededException.php index 9fc60ed..6cd2a98 100644 --- a/src/Exception/QuotaExceededException.php +++ b/src/Exception/QuotaExceededException.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -12,11 +12,11 @@ namespace BillbeeDe\BillbeeAPI\Exception; -use Throwable; +use Exception; -class QuotaExceededException extends \Exception +class QuotaExceededException extends Exception { - public function __construct($message = "", $code = 0, Throwable $previous = null) + public function __construct($message = "", $code = 0, $previous = null) { parent::__construct($message, $code, $previous); } diff --git a/src/Logger/DiagnosticsLogger.php b/src/Logger/DiagnosticsLogger.php index f6d55b7..21a65c0 100644 --- a/src/Logger/DiagnosticsLogger.php +++ b/src/Logger/DiagnosticsLogger.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -17,77 +17,88 @@ class DiagnosticsLogger implements LoggerInterface { + const EMERGENCY = 'EMERGENCY'; + const ALERT = 'ALERT'; + const CRITICAL = 'CRITICAL'; + const ERROR = 'ERROR'; + const WARNING = 'WARNING'; + const NOTICE = 'NOTICE'; + const INFO = 'INFO'; + const DEBUG = 'DEBUG'; + /** @var string */ private $logFile; public function __construct($logFile = null) { if ($logFile === null) { $filename = sprintf('billbee_api_%s.log', date('Y-m-d-H-i-s')); - $logFile = sprintf('%s/%s', __DIR__, $filename); - if (stristr($logFile, '/vendor/')) { - $parts = explode('/', '/vendor'); - $logFile = $parts[0] . $filename; - } + $logFile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . $filename; } - echo "Diagnostics Output at " . $logFile . PHP_EOL; - $this->logFile = $logFile; } + /** + * @return string The path to the log file + */ + public function getLogFile() + { + return $this->logFile; + } + /** @inheritdoc */ public function emergency($message, array $context = array()) { - $this->log('EMERGENCY', $message, $context); + $this->log(self::EMERGENCY, $message, $context); } /** @inheritdoc */ public function alert($message, array $context = array()) { - $this->log('ALERT', $message, $context); + $this->log(self::ALERT, $message, $context); } /** @inheritdoc */ public function critical($message, array $context = array()) { - $this->log('CRITICAL', $message, $context); + $this->log(self::CRITICAL, $message, $context); } /** @inheritdoc */ public function error($message, array $context = array()) { - $this->log('ERROR', $message, $context); + $this->log(self::ERROR, $message, $context); } /** @inheritdoc */ public function warning($message, array $context = array()) { - $this->log('WARNING', $message, $context); + $this->log(self::WARNING, $message, $context); } /** @inheritdoc */ public function notice($message, array $context = array()) { - $this->log('NOTICE', $message, $context); + $this->log(self::NOTICE, $message, $context); } /** @inheritdoc */ public function info($message, array $context = array()) { - $this->log('INFO', $message, $context); + $this->log(self::INFO, $message, $context); } /** @inheritdoc */ public function debug($message, array $context = array()) { - $this->log('DEBUG', $message, $context); + $this->log(self::DEBUG, $message, $context); } /** @inheritdoc */ public function log($level, $message, array $context = array()) { - $level = str_pad($level . ':', 9, ' ', STR_PAD_RIGHT); - /** @noinspection PhpUnhandledExceptionInspection */ + $level = str_pad($level . ':', 10, ' ', STR_PAD_RIGHT); + $date = (new DateTime('now'))->format('Y-m-d H:i:s.v'); $line = sprintf( "[%s] %s Message: %s; Context: %s\n", diff --git a/src/LoggerAwareTrait.php b/src/LoggerAwareTrait.php new file mode 100644 index 0000000..0fbd2a4 --- /dev/null +++ b/src/LoggerAwareTrait.php @@ -0,0 +1,33 @@ +logger; + } + + /** + * Sets the logger + * @param LoggerInterface $logger + */ + public function setLogger(LoggerInterface $logger = null) + { + if ($logger == null) { + $logger = new NullLogger(); + } + $this->logger = $logger; + } +} diff --git a/src/Model/Address.php b/src/Model/Address.php index 45aff34..dd4cf2e 100644 --- a/src/Model/Address.php +++ b/src/Model/Address.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/BillOfMaterialProduct.php b/src/Model/BillOfMaterialProduct.php index 2db5025..1f58c4c 100644 --- a/src/Model/BillOfMaterialProduct.php +++ b/src/Model/BillOfMaterialProduct.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Category.php b/src/Model/Category.php index b94a2a7..97ce9e2 100644 --- a/src/Model/Category.php +++ b/src/Model/Category.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/CloudStorage.php b/src/Model/CloudStorage.php index 4b6692f..ab55b5a 100644 --- a/src/Model/CloudStorage.php +++ b/src/Model/CloudStorage.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Comment.php b/src/Model/Comment.php index 8f568a4..64e0f7e 100644 --- a/src/Model/Comment.php +++ b/src/Model/Comment.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/CreateCustomerRequest.php b/src/Model/CreateCustomerRequest.php new file mode 100644 index 0000000..5330aec --- /dev/null +++ b/src/Model/CreateCustomerRequest.php @@ -0,0 +1,24 @@ + + */ + +namespace BillbeeDe\BillbeeAPI\Model; + +use MintWare\DMM\DataField; + +class CreateCustomerRequest extends Customer +{ + /** + * @var CustomerAddress + * @DataField(name="Address", type="BillbeeDe\BillbeeAPI\Model\CustomerAddress") + */ + public $address; +} diff --git a/src/Model/CustomFieldDefinition.php b/src/Model/CustomFieldDefinition.php index d1d65c3..1a454a2 100644 --- a/src/Model/CustomFieldDefinition.php +++ b/src/Model/CustomFieldDefinition.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Customer.php b/src/Model/Customer.php index 51414d4..a60bd7e 100644 --- a/src/Model/Customer.php +++ b/src/Model/Customer.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/CustomerAddress.php b/src/Model/CustomerAddress.php index a88285f..314ed67 100644 --- a/src/Model/CustomerAddress.php +++ b/src/Model/CustomerAddress.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/DeliveryNoteDocument.php b/src/Model/DeliveryNoteDocument.php index b1d0eb5..b9669cf 100644 --- a/src/Model/DeliveryNoteDocument.php +++ b/src/Model/DeliveryNoteDocument.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Dimensions.php b/src/Model/Dimensions.php index e5fbbad..48e0fc3 100644 --- a/src/Model/Dimensions.php +++ b/src/Model/Dimensions.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Event.php b/src/Model/Event.php index 8828c29..5127188 100644 --- a/src/Model/Event.php +++ b/src/Model/Event.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Image.php b/src/Model/Image.php index 55d9933..edd1f81 100644 --- a/src/Model/Image.php +++ b/src/Model/Image.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -50,5 +50,5 @@ class Image * @var bool * @DataField(name="IsDefault", type="bool") */ - public $isDefault = 1; + public $isDefault = true; } diff --git a/src/Model/Invoice.php b/src/Model/Invoice.php index 3646759..01f8f00 100644 --- a/src/Model/Invoice.php +++ b/src/Model/Invoice.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/InvoiceDocument.php b/src/Model/InvoiceDocument.php index 4f5d831..f258209 100644 --- a/src/Model/InvoiceDocument.php +++ b/src/Model/InvoiceDocument.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/InvoicePosition.php b/src/Model/InvoicePosition.php index 1bfd4a4..ba75778 100644 --- a/src/Model/InvoicePosition.php +++ b/src/Model/InvoicePosition.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Layout.php b/src/Model/Layout.php index 27811b9..15558af 100644 --- a/src/Model/Layout.php +++ b/src/Model/Layout.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/MessageForCustomer.php b/src/Model/MessageForCustomer.php index 3cf6084..2a0ad03 100644 --- a/src/Model/MessageForCustomer.php +++ b/src/Model/MessageForCustomer.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Order.php b/src/Model/Order.php index 57408ab..2e7dfc5 100644 --- a/src/Model/Order.php +++ b/src/Model/Order.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/OrderItem.php b/src/Model/OrderItem.php index ce7b60a..e8e8768 100644 --- a/src/Model/OrderItem.php +++ b/src/Model/OrderItem.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -29,7 +29,7 @@ class OrderItem public $transactionId; /** - * @var object + * @var SoldProduct * @DataField(name="Product", type="BillbeeDe\BillbeeAPI\Model\SoldProduct") */ public $product; diff --git a/src/Model/OrderItemAttribute.php b/src/Model/OrderItemAttribute.php index fbb17bd..2ef1d58 100644 --- a/src/Model/OrderItemAttribute.php +++ b/src/Model/OrderItemAttribute.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/PartnerOrder.php b/src/Model/PartnerOrder.php index 0c752b4..49cfe0a 100644 --- a/src/Model/PartnerOrder.php +++ b/src/Model/PartnerOrder.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Product.php b/src/Model/Product.php index d45053f..260eb09 100644 --- a/src/Model/Product.php +++ b/src/Model/Product.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -366,19 +366,19 @@ class Product public $isCustomizable = false; /** - * @var int + * @var int|null * @DataField(name="DeliveryTime", type="int") */ public $deliveryTime = Product::DELIVERY_NA; /** - * @var int + * @var int|null * @DataField(name="Recipient", type="int") */ public $recipient = Product::RECIPIENT_NA; /** - * @var int + * @var int|null * @DataField(name="Occasion", type="int") */ public $occasion = Product::OCCASION_NA; @@ -402,10 +402,10 @@ class Product public $taricNumber = ''; /** - * @var CustomFieldDefinition[] + * @var ProductCustomField[] * @DataField(name="CustomFields", type="\BillbeeDe\BillbeeAPI\Model\ProductCustomField[]") */ - public $customFields = ''; + public $customFields = []; /** * @var int diff --git a/src/Model/ProductCustomField.php b/src/Model/ProductCustomField.php index ab032a9..1763a29 100644 --- a/src/Model/ProductCustomField.php +++ b/src/Model/ProductCustomField.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Search/CustomerResult.php b/src/Model/Search/CustomerResult.php index 1ff3450..8415ac6 100644 --- a/src/Model/Search/CustomerResult.php +++ b/src/Model/Search/CustomerResult.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Search/OrderResult.php b/src/Model/Search/OrderResult.php index c08dba9..d194cf3 100644 --- a/src/Model/Search/OrderResult.php +++ b/src/Model/Search/OrderResult.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Search/ProductResult.php b/src/Model/Search/ProductResult.php index 72cb21f..14dda5c 100644 --- a/src/Model/Search/ProductResult.php +++ b/src/Model/Search/ProductResult.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Seller.php b/src/Model/Seller.php index 5e98ee6..882960a 100644 --- a/src/Model/Seller.php +++ b/src/Model/Seller.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Shipment.php b/src/Model/Shipment.php index 99684d3..9b0987a 100644 --- a/src/Model/Shipment.php +++ b/src/Model/Shipment.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/ShipmentWithLabel.php b/src/Model/ShipmentWithLabel.php index e330063..d00d1ea 100644 --- a/src/Model/ShipmentWithLabel.php +++ b/src/Model/ShipmentWithLabel.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/ShippingProduct.php b/src/Model/ShippingProduct.php index 68163e2..179d5d2 100644 --- a/src/Model/ShippingProduct.php +++ b/src/Model/ShippingProduct.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/ShippingProvider.php b/src/Model/ShippingProvider.php index 43345bf..768932a 100644 --- a/src/Model/ShippingProvider.php +++ b/src/Model/ShippingProvider.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/SoldProduct.php b/src/Model/SoldProduct.php index 4e7590e..26b42de 100644 --- a/src/Model/SoldProduct.php +++ b/src/Model/SoldProduct.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/Source.php b/src/Model/Source.php index 5486eed..b00b680 100644 --- a/src/Model/Source.php +++ b/src/Model/Source.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -17,10 +17,10 @@ class Source { /** - * @var int + * @var int|null * @DataField(name="Id", type="int") */ - public $id; + public $id = null; /** * @var string @@ -41,13 +41,13 @@ class Source public $apiAccountName = ''; /** - * @var int + * @var int|null * @DataField(name="ApiAccountId", type="int") */ - public $apiAccountId = ''; + public $apiAccountId = null; /** - * @var float + * @var float|null * @DataField(name="ExportFactor", type="float") */ public $exportFactor = null; @@ -59,7 +59,7 @@ class Source public $stockSyncInactive = false; /** - * @var float + * @var float|null * @DataField(name="StockSyncMin", type="float") */ public $stockSyncMin = null; diff --git a/src/Model/Stock.php b/src/Model/Stock.php index eaa9ca7..b3eb02d 100644 --- a/src/Model/Stock.php +++ b/src/Model/Stock.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -12,7 +12,9 @@ namespace BillbeeDe\BillbeeAPI\Model; -class Stock implements \JsonSerializable +use JsonSerializable; + +class Stock implements JsonSerializable { /** * The SKU of the Product @@ -22,7 +24,7 @@ class Stock implements \JsonSerializable /** * The Id of the stock - * @var int + * @var int|null */ protected $stockId = null; diff --git a/src/Model/StockCode.php b/src/Model/StockCode.php index 084a55e..3843ae9 100644 --- a/src/Model/StockCode.php +++ b/src/Model/StockCode.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/TermsInfo.php b/src/Model/TermsInfo.php index bf2dc4e..192bfaf 100644 --- a/src/Model/TermsInfo.php +++ b/src/Model/TermsInfo.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/TranslatableText.php b/src/Model/TranslatableText.php index bbb3a33..b1b4c55 100644 --- a/src/Model/TranslatableText.php +++ b/src/Model/TranslatableText.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/WebHook.php b/src/Model/WebHook.php index 61fee2b..018fb3f 100644 --- a/src/Model/WebHook.php +++ b/src/Model/WebHook.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Model/WebHookFilter.php b/src/Model/WebHookFilter.php index 24c8c0b..125df13 100644 --- a/src/Model/WebHookFilter.php +++ b/src/Model/WebHookFilter.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/BaseResponse.php b/src/Response/BaseResponse.php index f183b69..25f67fd 100644 --- a/src/Response/BaseResponse.php +++ b/src/Response/BaseResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -16,15 +16,27 @@ class BaseResponse { - /** @DataField(name="Paging", type="array") */ + /** + * @var array + * @DataField(name="Paging", type="array") + */ public $paging = []; - /** @DataField(name="ErrorMessage", type="string") */ + /** + * @var string + * @DataField(name="ErrorMessage", type="string") + */ public $errorMessage = ''; - /** @DataField(name="ErrorCode", type="int") */ + /** + * @var int + * @DataField(name="ErrorCode", type="int") + */ public $errorCode = 0; - /** @DataField(name="Data", type="array") */ + /** + * @var array + * @DataField(name="Data", type="array") + */ public $data = []; } diff --git a/src/Response/CreateDeliveryNoteResponse.php b/src/Response/CreateDeliveryNoteResponse.php index a7624fd..f3d5b01 100644 --- a/src/Response/CreateDeliveryNoteResponse.php +++ b/src/Response/CreateDeliveryNoteResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/CreateInvoiceResponse.php b/src/Response/CreateInvoiceResponse.php index bb4a990..2ffdd2a 100644 --- a/src/Response/CreateInvoiceResponse.php +++ b/src/Response/CreateInvoiceResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetCategoriesResponse.php b/src/Response/GetCategoriesResponse.php index 1d88839..a048725 100644 --- a/src/Response/GetCategoriesResponse.php +++ b/src/Response/GetCategoriesResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetCloudStoragesResponse.php b/src/Response/GetCloudStoragesResponse.php index ff02462..2d5119f 100644 --- a/src/Response/GetCloudStoragesResponse.php +++ b/src/Response/GetCloudStoragesResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetCustomFieldDefinitionResponse.php b/src/Response/GetCustomFieldDefinitionResponse.php index e1df2ae..2fb1d42 100644 --- a/src/Response/GetCustomFieldDefinitionResponse.php +++ b/src/Response/GetCustomFieldDefinitionResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetCustomFieldDefinitionsResponse.php b/src/Response/GetCustomFieldDefinitionsResponse.php index fa24382..7fb27ac 100644 --- a/src/Response/GetCustomFieldDefinitionsResponse.php +++ b/src/Response/GetCustomFieldDefinitionsResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetCustomerAddressResponse.php b/src/Response/GetCustomerAddressResponse.php index 218a0b0..2726cc6 100644 --- a/src/Response/GetCustomerAddressResponse.php +++ b/src/Response/GetCustomerAddressResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetCustomerAddressesResponse.php b/src/Response/GetCustomerAddressesResponse.php index 4c4229e..557ead4 100644 --- a/src/Response/GetCustomerAddressesResponse.php +++ b/src/Response/GetCustomerAddressesResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetCustomerResponse.php b/src/Response/GetCustomerResponse.php index 8e668d2..22cde33 100644 --- a/src/Response/GetCustomerResponse.php +++ b/src/Response/GetCustomerResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetCustomersResponse.php b/src/Response/GetCustomersResponse.php index afd1736..6385c62 100644 --- a/src/Response/GetCustomersResponse.php +++ b/src/Response/GetCustomersResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetEventsResponse.php b/src/Response/GetEventsResponse.php index e00b033..3e1ff4f 100644 --- a/src/Response/GetEventsResponse.php +++ b/src/Response/GetEventsResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetInvoicesResponse.php b/src/Response/GetInvoicesResponse.php index 7a8068d..c574a28 100644 --- a/src/Response/GetInvoicesResponse.php +++ b/src/Response/GetInvoicesResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetLayoutsResponse.php b/src/Response/GetLayoutsResponse.php index 1dffc2b..41f6be7 100644 --- a/src/Response/GetLayoutsResponse.php +++ b/src/Response/GetLayoutsResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetOrderByPartnerResponse.php b/src/Response/GetOrderByPartnerResponse.php index ac756d0..7babf6d 100644 --- a/src/Response/GetOrderByPartnerResponse.php +++ b/src/Response/GetOrderByPartnerResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetOrderResponse.php b/src/Response/GetOrderResponse.php index 134e322..88abb2f 100644 --- a/src/Response/GetOrderResponse.php +++ b/src/Response/GetOrderResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetOrdersResponse.php b/src/Response/GetOrdersResponse.php index d30032c..2baba5e 100644 --- a/src/Response/GetOrdersResponse.php +++ b/src/Response/GetOrdersResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetPatchableFieldsResponse.php b/src/Response/GetPatchableFieldsResponse.php index 2d8e053..2228423 100644 --- a/src/Response/GetPatchableFieldsResponse.php +++ b/src/Response/GetPatchableFieldsResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetProductResponse.php b/src/Response/GetProductResponse.php index a8713fb..dc035c4 100644 --- a/src/Response/GetProductResponse.php +++ b/src/Response/GetProductResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetProductsResponse.php b/src/Response/GetProductsResponse.php index 5c4304e..74c0766 100644 --- a/src/Response/GetProductsResponse.php +++ b/src/Response/GetProductsResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetShippingProvidersResponse.php b/src/Response/GetShippingProvidersResponse.php index 3cfcdd3..9cdf1c4 100644 --- a/src/Response/GetShippingProvidersResponse.php +++ b/src/Response/GetShippingProvidersResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/GetTermsInfoResponse.php b/src/Response/GetTermsInfoResponse.php index ea2892a..e4d0597 100644 --- a/src/Response/GetTermsInfoResponse.php +++ b/src/Response/GetTermsInfoResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/Model/ShipmentWithLabelResult.php b/src/Response/Model/ShipmentWithLabelResult.php index 2379c4e..24ed5ae 100644 --- a/src/Response/Model/ShipmentWithLabelResult.php +++ b/src/Response/Model/ShipmentWithLabelResult.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/SearchDataResponse.php b/src/Response/SearchDataResponse.php index d770dc1..c05f670 100644 --- a/src/Response/SearchDataResponse.php +++ b/src/Response/SearchDataResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/ShipWithLabelResponse.php b/src/Response/ShipWithLabelResponse.php index 99dbfd1..2f040ad 100644 --- a/src/Response/ShipWithLabelResponse.php +++ b/src/Response/ShipWithLabelResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Response/UpdateStockResponse.php b/src/Response/UpdateStockResponse.php index e26f012..260870b 100644 --- a/src/Response/UpdateStockResponse.php +++ b/src/Response/UpdateStockResponse.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -17,7 +17,7 @@ class UpdateStockResponse extends BaseResponse { /** - * @var array + * @var array * @DataField(name="Data", type="array") */ public $data = []; diff --git a/src/Transformer/DefinitionConfigTransformer.php b/src/Transformer/DefinitionConfigTransformer.php index f6cb82e..c4ab731 100644 --- a/src/Transformer/DefinitionConfigTransformer.php +++ b/src/Transformer/DefinitionConfigTransformer.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -12,7 +12,9 @@ namespace BillbeeDe\BillbeeAPI\Transformer; -class DefinitionConfigTransformer implements \MintWare\DMM\TransformerInterface +use MintWare\DMM\TransformerInterface; + +class DefinitionConfigTransformer implements TransformerInterface { /** @inheritdoc */ public static function transform($data) diff --git a/src/Type/ArticleSource.php b/src/Type/ArticleSource.php index 30fa434..a49a8a5 100644 --- a/src/Type/ArticleSource.php +++ b/src/Type/ArticleSource.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/CustomFieldDefinitionType.php b/src/Type/CustomFieldDefinitionType.php index 579311d..136bc3a 100644 --- a/src/Type/CustomFieldDefinitionType.php +++ b/src/Type/CustomFieldDefinitionType.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/EventType.php b/src/Type/EventType.php index b076cb0..388ec1b 100644 --- a/src/Type/EventType.php +++ b/src/Type/EventType.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/InvoiceType.php b/src/Type/InvoiceType.php index 9f623d3..1470d00 100644 --- a/src/Type/InvoiceType.php +++ b/src/Type/InvoiceType.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/LayoutType.php b/src/Type/LayoutType.php index 8ea0e1b..6b84031 100644 --- a/src/Type/LayoutType.php +++ b/src/Type/LayoutType.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/OrderState.php b/src/Type/OrderState.php index 54894e6..6b6f63b 100644 --- a/src/Type/OrderState.php +++ b/src/Type/OrderState.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/Partner.php b/src/Type/Partner.php index 1107228..5289283 100644 --- a/src/Type/Partner.php +++ b/src/Type/Partner.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/PaymentType.php b/src/Type/PaymentType.php index c1bf449..c5abe13 100644 --- a/src/Type/PaymentType.php +++ b/src/Type/PaymentType.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/ProductCondition.php b/src/Type/ProductCondition.php index ee715d7..668fce8 100644 --- a/src/Type/ProductCondition.php +++ b/src/Type/ProductCondition.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/ProductLookupBy.php b/src/Type/ProductLookupBy.php index 539e040..9795aa2 100644 --- a/src/Type/ProductLookupBy.php +++ b/src/Type/ProductLookupBy.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/SearchMode.php b/src/Type/SearchMode.php index 60a7476..aa6a003 100644 --- a/src/Type/SearchMode.php +++ b/src/Type/SearchMode.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/SearchType.php b/src/Type/SearchType.php index ca42f9d..3ad9643 100644 --- a/src/Type/SearchType.php +++ b/src/Type/SearchType.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/src/Type/SendMode.php b/src/Type/SendMode.php index 9c3a004..968fe71 100644 --- a/src/Type/SendMode.php +++ b/src/Type/SendMode.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/test_config.dist.yml b/test_config.dist.yml deleted file mode 100644 index fd3b806..0000000 --- a/test_config.dist.yml +++ /dev/null @@ -1,23 +0,0 @@ -# To pass all tests you need >=20 orders with the state "confirmed" (bestätigt) -username: '' # Your Billbee Username -password: '' # Your Billbee API Password -api_key: '' # Your Billbee API Key -sample_product: '' # A existing product (Id) with an valid SKU -shop_id: '' # A existing shop (Id) -tag: '' # A order tag which is set at over 20 orders -sample_order: '' # A existing order (Id) -sample_order_number: '' # A existing order (External Reference) -partner_id: '' # A order id from a external system -partner: '' # The partner name of the external system. Take a look in Partner-Class -custom_field_definition_id: '' # The id of a custom field definition -web_hook_uri: '' # The uri for testing webhooks -test_delete_web_hooks: false # If true, the delete all web hooks call will be tested -customer_id: '' # Id of a customer -address_id: '' # Id of an address -cloud_storage_id: 0 # Id of an cloud storage -category_id: 0 # Id of a category -layout_id: 0 # Id of a layout -# Test Shipping: -shippable_order_id: '' # Id of an order which can be shipped -shipping_provider_id: '' # The Id of a shipping provider -shipping_provider_product: '' # The Id of a shipping provider product \ No newline at end of file diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 2f7f332..3e6c2a0 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -13,1350 +13,83 @@ namespace BillbeeDe\Tests\BillbeeAPI; use BillbeeDe\BillbeeAPI\Client; -use BillbeeDe\BillbeeAPI\Exception\InvalidIdException; -use BillbeeDe\BillbeeAPI\Exception\QuotaExceededException; -use BillbeeDe\BillbeeAPI\Model\Customer; -use BillbeeDe\BillbeeAPI\Model\CustomerAddress; -use BillbeeDe\BillbeeAPI\Model\CustomFieldDefinition; -use BillbeeDe\BillbeeAPI\Model\DeliveryNoteDocument; -use BillbeeDe\BillbeeAPI\Model\Dimensions; -use BillbeeDe\BillbeeAPI\Model\Event; -use BillbeeDe\BillbeeAPI\Model\Invoice; -use BillbeeDe\BillbeeAPI\Model\InvoiceDocument; -use BillbeeDe\BillbeeAPI\Model\InvoicePosition; -use BillbeeDe\BillbeeAPI\Model\MessageForCustomer; -use BillbeeDe\BillbeeAPI\Model\Order; -use BillbeeDe\BillbeeAPI\Model\OrderItem; -use BillbeeDe\BillbeeAPI\Model\PartnerOrder; -use BillbeeDe\BillbeeAPI\Model\Product; -use BillbeeDe\BillbeeAPI\Model\Search\CustomerResult; -use BillbeeDe\BillbeeAPI\Model\Search\OrderResult; -use BillbeeDe\BillbeeAPI\Model\Search\ProductResult; -use BillbeeDe\BillbeeAPI\Model\Shipment; -use BillbeeDe\BillbeeAPI\Model\ShipmentWithLabel; -use BillbeeDe\BillbeeAPI\Model\ShippingProvider; -use BillbeeDe\BillbeeAPI\Model\Stock; -use BillbeeDe\BillbeeAPI\Model\StockCode; -use BillbeeDe\BillbeeAPI\Model\TermsInfo; -use BillbeeDe\BillbeeAPI\Model\TranslatableText; -use BillbeeDe\BillbeeAPI\Model\WebHook; -use BillbeeDe\BillbeeAPI\Model\WebHookFilter; -use BillbeeDe\BillbeeAPI\Response\BaseResponse; -use BillbeeDe\BillbeeAPI\Response\CreateDeliveryNoteResponse; -use BillbeeDe\BillbeeAPI\Response\CreateInvoiceResponse; -use BillbeeDe\BillbeeAPI\Response\GetCustomerAddressesResponse; -use BillbeeDe\BillbeeAPI\Response\GetCustomerAddressResponse; -use BillbeeDe\BillbeeAPI\Response\GetCustomerResponse; -use BillbeeDe\BillbeeAPI\Response\GetCustomersResponse; -use BillbeeDe\BillbeeAPI\Response\GetEventsResponse; -use BillbeeDe\BillbeeAPI\Response\GetInvoicesResponse; -use BillbeeDe\BillbeeAPI\Response\GetOrderByPartnerResponse; -use BillbeeDe\BillbeeAPI\Response\GetOrderResponse; -use BillbeeDe\BillbeeAPI\Response\GetOrdersResponse; -use BillbeeDe\BillbeeAPI\Response\GetPatchableFieldsResponse; -use BillbeeDe\BillbeeAPI\Response\GetProductResponse; -use BillbeeDe\BillbeeAPI\Response\GetProductsResponse; -use BillbeeDe\BillbeeAPI\Response\GetShippingProvidersResponse; -use BillbeeDe\BillbeeAPI\Response\GetTermsInfoResponse; -use BillbeeDe\BillbeeAPI\Response\UpdateStockResponse; -use BillbeeDe\BillbeeAPI\Type\ArticleSource; -use BillbeeDe\BillbeeAPI\Type\EventType; -use BillbeeDe\BillbeeAPI\Type\OrderState; -use BillbeeDe\BillbeeAPI\Type\SearchType; -use DateTime; +use BillbeeDe\BillbeeAPI\ClientInterface; use Exception; -use GuzzleHttp\Exception\ClientException; -use InvalidArgumentException; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; -use Symfony\Component\Yaml\Yaml; class ClientTest extends TestCase { - protected $username = ''; - protected $password = ''; - protected $apiKey = ''; - protected $sampleProductId = ''; - protected $shopId = ''; - protected $tag = ''; - protected $sampleOrderId = ''; - protected $sampleOrderNumber = ''; - protected $partner = ''; - protected $partnerId = ''; - protected $customFieldDefinitionId = ''; - protected $webHookUri = ''; - protected $testDeleteWebHooks = false; - protected $customerId = ''; - protected $addressId; - protected $shippableOrderId; - protected $shippingProviderId; - protected $shippingProviderProduct; - protected $cloudStorageId = 0; - protected $categoryId = 0; - protected $layoutId = 0; + private $client; - public function __construct($name = null, array $data = [], $dataName = '') + protected function setUp(): void { - parent::__construct($name, $data, $dataName); - - $data = Yaml::parse(file_get_contents(__DIR__ . '/../test_config.yml')); - list( - $this->username, - $this->password, - $this->apiKey, - $this->sampleProductId, - $this->shopId, - $this->tag, - $this->sampleOrderId, - $this->sampleOrderNumber, - $this->partner, - $this->partnerId, - $this->customFieldDefinitionId, - $this->webHookUri, - $this->testDeleteWebHooks, - $this->customerId, - $this->addressId, - $this->shippableOrderId, - $this->shippingProviderId, - $this->shippingProviderProduct, - $this->cloudStorageId, - $this->categoryId, - $this->layoutId, - ) = [ - $data['username'], - $data['password'], - $data['api_key'], - $data['sample_product'], - $data['shop_id'], - $data['tag'], - $data['sample_order'], - $data['sample_order_number'], - $data['partner'], - $data['partner_id'], - $data['custom_field_definition_id'], - $data['web_hook_uri'], - $data['test_delete_web_hooks'], - $data['customer_id'], - $data['address_id'], - $data['shippable_order_id'], - $data['shipping_provider_id'], - $data['shipping_provider_product'], - $data['cloud_storage_id'], - $data['category_id'], - $data['layout_id'], - ]; - } - - /** @throws Exception */ - public function testConstruct() - { - $client = $this->getClient(); - $this->assertInstanceOf(Client::class, $client); - } - - /** @throws Exception */ - public function testGetProductsFails() - { - $client = $this->getClient(); - $client->getProducts(1, 1, new DateTime('now')); - $client->getProducts(1, 1, new DateTime('now')); - - $this->expectException(QuotaExceededException::class); - $this->expectExceptionMessage('quota exceeded'); - $client->getProducts(1, 1, new DateTime('now')); - $client->getProducts(1, 1, new DateTime('now')); - } - - /** @throws Exception */ - public function testGetProducts() - { - $client = $this->getClient(); - sleep(1); - - $productsResponse = $client->getProducts(1, 1); - $this->assertTrue($productsResponse instanceof GetProductsResponse); - $this->assertGreaterThan(0, $productsResponse->data); - $this->assertTrue($productsResponse->data[0] instanceof Product); - - $productsResponse2 = $client->getProducts(2, 1); - $this->assertTrue($productsResponse2 instanceof GetProductsResponse); - $this->assertGreaterThan(0, $productsResponse2->data); - $this->assertNotEquals($productsResponse->data[0], $productsResponse2->data[0]); - } - - /** @throws Exception */ - public function testGetProduct() - { - $client = $this->getClient(); - sleep(1); - - $productResponse = $client->getProduct($this->sampleProductId); - - $this->assertTrue($productResponse instanceof GetProductResponse); - $this->assertTrue($productResponse->data instanceof Product); - } - - /** @throws Exception */ - public function testGetTermsInfo() - { - $client = $this->getClient(); - sleep(1); - - $termsInfoResponse = $client->getTermsInfo(); - - $this->assertTrue($termsInfoResponse instanceof GetTermsInfoResponse); - $this->assertTrue($termsInfoResponse->data instanceof TermsInfo); - } - - /** @throws Exception */ - public function testGetEvents() - { - $client = $this->getClient(); - sleep(1); - - $eventsResponse = $client->getEvents( - 2, - 10, - new DateTime('01.01.2017'), - new DateTime(), - [EventType::ORDER_IMPORTED], - $this->sampleOrderId - ); - $this->assertInstanceOf(GetEventsResponse::class, $eventsResponse); - $this->assertEquals(0, $eventsResponse->errorCode); - $this->assertTrue(is_array($eventsResponse->data)); - $this->assertGreaterThanOrEqual(0, count($eventsResponse->data)); - if (count($eventsResponse->data) > 0) { - $this->assertInstanceOf(Event::class, $eventsResponse->data[0]); + if ($this->client === null) { + $this->client = new Client('Hello', 'World', '12344'); } } /** @throws Exception */ - public function testGetShippingProviders() - { - $client = $this->getClient(); - sleep(1); - - $shippingProvidersResponse = $client->getShippingProviders(); - $this->assertInstanceOf(GetShippingProvidersResponse::class, $shippingProvidersResponse); - $this->assertTrue(is_array($shippingProvidersResponse->data)); - $this->assertGreaterThan(1, count($shippingProvidersResponse->data)); - $this->assertInstanceOf(ShippingProvider::class, $shippingProvidersResponse->data[0]); - } - - /** @throws Exception */ - public function testGetInvoicesFailsWrongShopId() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('shopId must be an instance of int or an array of int'); - $client->getInvoices( - 2, - 10, - new DateTime('01.01.2017'), - new DateTime(), - ['asdf'], - 2, - [], - new DateTime('01.01.2017'), - new DateTime(), - false - ); - } - - /** @throws Exception */ - public function testGetInvoicesFailsWrongStateId() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('orderStateId must be an instance of int or an array of int'); - $client->getInvoices( - 2, - 10, - new DateTime('01.01.2017'), - new DateTime(), - $this->shopId, - ['asdf'], - [], - new DateTime('01.01.2017'), - new DateTime(), - false - ); - } - - /** @throws Exception */ - public function testGetInvoices() - { - $client = $this->getClient(); - sleep(1); - - $invoices = $client->getInvoices( - 1, - 10, - new DateTime('01.01.2017'), - new DateTime(), - $this->shopId, - 2, - $this->tag, - new DateTime('01.01.2017'), - new DateTime(), - false - ); - $this->assertEquals(0, $invoices->errorCode); - $this->assertInstanceOf(GetInvoicesResponse::class, $invoices); - $this->assertTrue(is_array($invoices->data)); - $this->assertGreaterThanOrEqual(0, count($invoices->data)); - $this->assertInstanceOf(Invoice::class, $invoices->data[0]); - if (isset($invoices->data[0])) { - $this->assertCount(0, $invoices->data[0]->positions); - } - } - - /** @throws Exception */ - public function testGetInvoicesAndPositions() - { - $client = $this->getClient(); - sleep(1); - - $invoices = $client->getInvoices( - 1, - 10, - new DateTime('01.01.2017'), - new DateTime(), - [$this->shopId], - [2], - $this->tag, - new DateTime('01.01.2017'), - new DateTime(), - true - ); - - $this->assertEquals(0, $invoices->errorCode); - $this->assertInstanceOf(GetInvoicesResponse::class, $invoices); - $this->assertTrue(is_array($invoices->data)); - $this->assertGreaterThanOrEqual(0, count($invoices->data)); - $this->assertInstanceOf(Invoice::class, $invoices->data[0]); - $this->assertGreaterThan(0, count($invoices->data[0]->positions)); - if (isset($invoices->data[0])) { - $this->assertInstanceOf(InvoicePosition::class, $invoices->data[0]->positions[0]); - } - } - - /** @throws Exception */ - public function testGetOrders() - { - $client = $this->getClient(); - sleep(1); - $orders = $client->getOrders( - 1, - 19, - new DateTime('01.01.2017'), - new DateTime(), - [$this->shopId], - [2], - $this->tag, - 1, - new DateTime('01.01.2017'), - new DateTime(), - ArticleSource::ORDER_POSITION, - true - ); - - $this->assertEquals(0, $orders->errorCode); - $this->assertInstanceOf(GetOrdersResponse::class, $orders); - $this->assertTrue(is_array($orders->data)); - $this->assertGreaterThanOrEqual(0, count($orders->data)); - if (isset($orders->data[0])) { - $this->assertInstanceOf(Order::class, $orders->data[0]); - $this->assertGreaterThan(0, count($orders->data[0]->orderItems)); - $this->assertInstanceOf(OrderItem::class, $orders->data[0]->orderItems[0]); - } - sleep(1); - $orders2 = $client->getOrders( - 1, - 19, - new DateTime('01.01.2017'), - new DateTime(), - $this->shopId, // No array - 2, // No array - $this->tag, - 1, - new DateTime('01.01.2017'), - new DateTime(), - ArticleSource::ORDER_POSITION, - true - ); - - $this->assertEquals($orders, $orders2); - } - - /** @throws Exception */ - public function testGetOrdersFailsShopIdNaN() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('shopId must be an instance of int or an array of int'); - - $client->getOrders( - 2, - 19, - new DateTime('01.01.2017'), - new DateTime(), - ['hello'], - [2], - $this->tag, - 1, - new DateTime('01.01.2017'), - new DateTime() - ); - } - - /** @throws Exception */ - public function testGetOrdersFailsOrderStateIdNaN() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('orderStateId must be an instance of int or an array of int'); - - $client->getOrders( - 2, - 19, - new DateTime('01.01.2017'), - new DateTime(), - [1], - ['hello'], - $this->tag, - 1, - new DateTime('01.01.2017'), - new DateTime() - ); - } - - /** @throws Exception */ - public function testGetOrdersFailsArticleSourceInvalid() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('The articleTitleSource is invalid. Check ' . ArticleSource::class . ' for valid values'); - - $client->getOrders( - 2, - 19, - new DateTime('01.01.2017'), - new DateTime(), - [1], - [], - $this->tag, - 1, - new DateTime('01.01.2017'), - new DateTime(), - 3 - ); - - $client->getOrders( - 2, - 19, - new DateTime('01.01.2017'), - new DateTime(), - [1], - [], - $this->tag, - 1, - new DateTime('01.01.2017'), - new DateTime(), - false - ); - } - - /** @throws Exception */ - public function testGetOrder() - { - $client = $this->getClient(); - sleep(1); - /** @var GetOrderResponse $order */ - $order = $client->getOrder($this->sampleOrderId); - $this->assertInstanceOf(GetOrderResponse::class, $order); - $this->assertInstanceOf(Order::class, $order->data); - $this->assertInstanceOf(Customer::class, $order->data->customer); - } - - /** @throws Exception */ - public function testGetOrderByOrderNumber() - { - $client = $this->getClient(); - sleep(1); - /** @var GetOrderResponse $order */ - $order = $client->getOrderByOrderNumber($this->sampleOrderNumber); - $this->assertInstanceOf(GetOrderResponse::class, $order); - $this->assertInstanceOf(Order::class, $order->data); - $this->assertSame($this->sampleOrderNumber, $order->data->orderNumber); - } - - /** @throws Exception */ - public function testUpdateStock() - { - $client = $this->getClient(); - sleep(1); - - $product = $client->getProduct($this->sampleProductId); - $stockModel = Stock::fromProduct($product->data); - - $stockModel->setDeltaQuantity(1); - - $currentStockResult = $client->updateStock($stockModel); - $this->assertInstanceOf(UpdateStockResponse::class, $currentStockResult); - $this->assertSame($stockModel->getNewQuantity(), $currentStockResult->data['CurrentStock']); - sleep(1); - $product = $client->getProduct($this->sampleProductId); - $this->assertSame($product->data->stockCurrent, $currentStockResult->data['CurrentStock']); - } - - /** @throws Exception */ - public function testUpdateStockMultiple() - { - $client = $this->getClient(); - sleep(1); - - $products = $client->getProducts(1, 10); - - $stockModels = []; - foreach ($products->data as $product) { - if (empty($product->sku)) { - continue; - } - $stockModel = Stock::fromProduct($product); - $stockModel->setDeltaQuantity(1); - $stockModels[] = $stockModel; - } - - $currentStockResult = $client->updateStockMultiple($stockModels); - $this->assertInstanceOf(UpdateStockResponse::class, reset($currentStockResult)); - foreach ($stockModels as $i => $stockModel) { - $this->assertSame($stockModel->getNewQuantity(), $currentStockResult[$i]->data['CurrentStock']); - } - } - - /** @throws Exception */ - public function testUpdateStockCode() - { - $client = $this->getClient(); - sleep(1); - $product = $client->getProduct($this->sampleProductId); - $stockCode = StockCode::fromProduct($product->data); - $stockCode->stockCode = 'asdasd'; - $stockCode->stockId = 0; - - $result = $client->updateStockCode($stockCode); - $this->assertInstanceOf(BaseResponse::class, $result); - } - - /** @throws Exception */ - public function testCreateOrder() - { - $client = $this->getClient(); - sleep(1); - - $order = $client->getOrder($this->sampleOrderId)->data; - $order->externalId = 'API_ORDER_' . substr(md5(time()), 0, 4); - $order->orderNumber = 'API_ORDER_1'; - $res = $client->createOrder($order, $this->shopId); - - $this->assertInstanceOf(BaseResponse::class, $res); - } - - /** @throws Exception */ - public function testAddOrderTags() - { - $client = $this->getClient(); - sleep(1); - $order = $client->getOrder($this->sampleOrderId)->data; - $hash = substr(md5(time()), 0, 4); - $client->addOrderTags($order->id, $hash); - sleep(1); - $order = $client->getOrder($this->sampleOrderId)->data; - $this->assertContains($hash, $order->tags); - } - - /** @throws Exception */ - public function testSetOrderTags() - { - $client = $this->getClient(); - sleep(1); - $order = $client->getOrder($this->sampleOrderId)->data; - $hash = substr(md5(time()), 0, 4); - $client->setOrderTags($order->id, $hash); - sleep(1); - $order = $client->getOrder($this->sampleOrderId)->data; - $this->assertEquals([$hash], $order->tags); - } - - /** @throws Exception */ - public function testSetOrderState() - { - $client = $this->getClient(); - sleep(1); - $res = $client->setOrderState($this->sampleOrderId, OrderState::SHIPPED); - $this->assertTrue($res); - } - - /** @throws Exception */ - public function testAddOrderShipment() - { - $client = $this->getClient(); - sleep(1); - - /** @var Shipment $shipment */ - $shipment = $this->createMock(Shipment::class); - $shipment->shippingProviderId = $this->shippingProviderId; - $shipment->shippingProductId = $this->shippingProviderProduct; - $shipment->orderId = 'A-123'; - $shipment->comment = 'PRIO VERSENDEN'; - $shipment->shippingId = 'B-456'; - - $res = $client->addOrderShipment($this->sampleOrderId, $shipment); - $this->assertTrue($res); - } - - /** @throws Exception */ - public function testGetOrderByPartner() - { - $client = $this->getClient(); - sleep(1); - - $res = $client->getOrderByPartner($this->partnerId, $this->partner); - $this->assertInstanceOf(GetOrderByPartnerResponse::class, $res); - $this->assertInstanceOf(PartnerOrder::class, $res->data); - } - - /** @throws Exception */ - public function testCreateDeliveryNote() - { - $client = $this->getClient(); - sleep(1); - - /** @var CreateDeliveryNoteResponse $res */ - $res = $client->createDeliveryNote($this->sampleOrderId, false); - $this->assertInstanceOf(CreateDeliveryNoteResponse::class, $res); - $this->assertInstanceOf(DeliveryNoteDocument::class, $res->data); - $this->assertEmpty($res->data->pdfData); - $this->assertNotEmpty($res->data->pdfDownloadUrl); - - /** @var CreateDeliveryNoteResponse $res */ - $res = $client->createDeliveryNote($this->sampleOrderId, true); - $this->assertInstanceOf(CreateDeliveryNoteResponse::class, $res); - $this->assertInstanceOf(DeliveryNoteDocument::class, $res->data); - $this->assertNotEmpty($res->data->pdfData); - $this->assertEmpty($res->data->pdfDownloadUrl); - } - - /** @throws Exception */ - public function testCreateInvoice() - { - $client = $this->getClient(); - sleep(1); - - /** @var CreateInvoiceResponse $res */ - $res = $client->createInvoice($this->sampleOrderId, false); - $this->assertInstanceOf(CreateInvoiceResponse::class, $res); - $this->assertInstanceOf(InvoiceDocument::class, $res->data); - $this->assertEmpty($res->data->pdfData); - $this->assertNotEmpty($res->data->pdfDownloadUrl); - - /** @var CreateInvoiceResponse $res */ - $res = $client->createInvoice($this->sampleOrderId, true); - $this->assertInstanceOf(CreateInvoiceResponse::class, $res); - $this->assertInstanceOf(InvoiceDocument::class, $res->data); - $this->assertNotEmpty($res->data->pdfData); - $this->assertEmpty($res->data->pdfDownloadUrl); - } - - /** @throws Exception */ - public function testGetPatchableFields() - { - $client = $this->getClient(); - /** @var GetPatchableFieldsResponse $result */ - $result = $client->getPatchableFields(); - $this->assertInstanceOf(GetPatchableFieldsResponse::class, $result); - $this->assertGreaterThanOrEqual(1, $result->data); - } - - /** @throws Exception */ - public function testPatchOrder() + public function testConstruct() { - $client = $this->getClient(); - $orderResponse = $client->getOrder($this->sampleOrderId); - $order = $orderResponse->data; - - $oldPrefix = $order->invoiceNumberPrefix; - $newPrefix = substr(md5($oldPrefix), 0, 8); - - $model = ['InvoiceNumberPrefix' => $newPrefix]; - $patchOrderResult = $client->patchOrder($this->sampleOrderId, $model); - $this->assertEquals(0, $patchOrderResult->errorCode); - $patchedOrder = $patchOrderResult->data; - $this->assertEquals($newPrefix, $patchedOrder->invoiceNumberPrefix); - - sleep(1); - $orderResponse = $client->getOrder($this->sampleOrderId); - $order = $orderResponse->data; - $this->assertEquals($newPrefix, $order->invoiceNumberPrefix); + $this->assertInstanceOf(ClientInterface::class, $this->client); } /** @throws Exception */ public function testBatchRequests() { - $client = $this->getClient(); - $client->useBatching = true; - $this->assertEquals(0, $client->getPoolSize()); - $this->assertNull($client->getProducts(1, 1)); - $this->assertEquals(1, $client->getPoolSize()); - $this->assertNull($client->getOrders(1, 1)); - $this->assertNull($client->getEvents(3, 1)); - $this->assertEquals(3, $client->getPoolSize()); - - $results = $client->executeBatch(); - $this->assertEquals(0, $client->getPoolSize()); - $this->assertCount(3, $results); - $this->assertInstanceOf(GetProductsResponse::class, $results[0]); - $this->assertInstanceOf(GetOrdersResponse::class, $results[1]); - $this->assertInstanceOf(GetEventsResponse::class, $results[2]); - $client->useBatching = false; - } - - /** @throws Exception */ - public function testGetCustomFieldDefinitions() - { - $client = $this->getClient(); - sleep(1); - - $definitions = $client->getCustomFieldDefinitions(); - $this->assertGreaterThanOrEqual(0, count($definitions->data)); - - if (count($definitions->data) > 0) { - $this->assertInstanceOf(CustomFieldDefinition::class, $definitions->data[0]); - } - } - - /** @throws Exception */ - public function testGetCustomFieldDefinitionFailsNaN() - { - $client = $this->getClient(); - sleep(1); - - $this->expectException(InvalidIdException::class); - $this->expectExceptionMessage('Id must be an instance of integer and positive'); - $client->getCustomFieldDefinition('hello'); - } - - /** @throws Exception */ - public function testGetCustomFieldDefinitionFailsNegative() - { - $client = $this->getClient(); - - $this->expectException(InvalidIdException::class); - $this->expectExceptionMessage('Id must be an instance of integer and positive'); - $client->getCustomFieldDefinition(-1); - } - - /** @throws Exception */ - public function testGetCustomFieldDefinition() - { - $client = $this->getClient(); - - $definition = $client->getCustomFieldDefinition($this->customFieldDefinitionId); - $this->assertInstanceOf(CustomFieldDefinition::class, $definition->data); - } - - /** @throws Exception */ - public function testGetAllWebHooks() - { - $client = $this->getClient(); - $webHooks = $client->getWebHooks(); - $this->assertTrue(is_array($webHooks)); - - if (count($webHooks) > 0) { - $this->assertInstanceOf(WebHook::class, $webHooks[0]); - } - } - - /** @throws Exception */ - public function testWebHookFilters() - { - $client = $this->getClient(); - $filters = $client->getWebHookFilters(); - $this->assertTrue(is_array($filters)); - $this->assertGreaterThan(0, count($filters)); - - $this->assertInstanceOf(WebHookFilter::class, $filters[0]); - } - - /** @throws Exception */ - public function testCreateUpdateGetDeleteWebHook() - { - $client = $this->getClient(); - - $hook = new WebHook(); - $hook->id = md5('Hello World' . time()); - $hook->secret = md5('4711'); - $hook->isPaused = true; - $hook->description = 'A nice webhook'; - $hook->filters = ['*']; - $hook->webHookUri = $this->webHookUri; - - $this->createWebHookAndCompare($client, $hook); - - $hook->description = 'A updated web hook'; - $updateRes = $client->updateWebHook($hook); - $this->assertTrue($updateRes); - - $this->getWebHookAndCompare($client, $hook); - - $getRes = $client->deleteWebHook($hook); - $this->assertTrue($getRes); - - try { - $client->getWebHook($hook->id); - $this->fail('The webhook was not deleted'); - } catch (Exception $ex) { - } - - $this->createWebHookAndCompare($client, $hook); - $this->getWebHookAndCompare($client, $hook); - $client->deleteWebHookById($hook->id); - $this->assertTrue($getRes); - - try { - $client->getWebHook($hook->id); - $this->fail('The webhook was not deleted'); - } catch (Exception $ex) { - } - } - - /** - * @param Client $client - * @param $hook - * @throws Exception - */ - private function createWebHookAndCompare($client, $hook) - { - sleep(1); - $createRes = $client->createWebHook($hook); - $this->assertEquals($hook->id, $createRes->id); - $this->assertEquals($hook->secret, $createRes->secret); - $this->assertEquals($hook->description, $createRes->description); - $this->assertEquals($hook->filters, $createRes->filters); - $this->assertEquals($hook->webHookUri, $createRes->webHookUri); - } - - /** - * @param Client $client - * @param $hook - * @throws Exception - */ - private function getWebHookAndCompare($client, $hook) - { - sleep(1); - $getRes = $client->getWebHook($hook->id); - $this->assertEquals($hook->id, $getRes->id); - $this->assertEquals($hook->secret, $getRes->secret); - $this->assertEquals($hook->description, $getRes->description); - $this->assertEquals($hook->filters, $getRes->filters); - $this->assertEquals($hook->webHookUri, $getRes->webHookUri); - } - - /** @throws Exception */ - public function testDeleteWebHookFailsInvalidId() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('The id of the webHook cannot be empty'); - $client->deleteWebHookById(null); - } - - /** @throws Exception */ - public function testUpdateWebHookFailsInvalidId() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('The id of the webHook cannot be empty'); - $client->updateWebHook(new WebHook()); - } - - /** @throws Exception */ - public function testDeleteAllWebHooks() - { - if ($this->testDeleteWebHooks === true) { - $client = $this->getClient(); - $res = $client->deleteAllWebHooks(); - $this->assertTrue($res); - } - } - - /** @throws Exception */ - public function testSendMessageFailsSendMode() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('The sendMode is invalid. Check the BillbeeDe\\BillbeeAPI\\Type\\SendMode class for valid values'); - $client->sendMessage(null, new MessageForCustomer([], [], 6)); - } - - /** @throws Exception */ - public function testSendMessageFailsNoSubject() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('You have to specify a message subject'); - $client->sendMessage(null, new MessageForCustomer([], [], 0)); - } - - /** @throws Exception */ - public function testSendMessageFailsNoBody() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('You have to specify a message body'); - $client->sendMessage(null, new MessageForCustomer([new TranslatableText()], [], 0)); - } - - /** @throws Exception */ - public function testSendMessageFailsNoExternalAddress() - { - $client = $this->getClient(); - - $this->expectException(InvalidArgumentException::class); - $this->expectExceptionMessage('With sendMode == 4 it\'s required to specify an alternativeEmailAddress'); - $client->sendMessage(null, new MessageForCustomer([new TranslatableText()], [new TranslatableText()], 4)); + $this->assertFalse($this->client->isBatchModeEnabled()); + $this->client->enableBatchMode(); + $this->assertTrue($this->client->isBatchModeEnabled()); + $this->assertEquals(0, $this->client->getPoolSize()); + $this->assertNull($this->client->products()->getProducts(1, 1)); + $this->assertEquals(1, $this->client->getPoolSize()); + $this->assertNull($this->client->orders()->getOrders(1, 1)); + $this->assertNull($this->client->events()->getEvents(3, 1)); + $this->assertEquals(3, $this->client->getPoolSize()); + $this->assertNull($this->client->provisioning()->getTermsInfo()); + $this->assertNull($this->client->invoices()->getInvoices()); + $this->assertNull($this->client->shipments()->getShippingProviders()); + $this->assertNull($this->client->productCustomFields()->getCustomFieldDefinitions()); + $this->assertNull($this->client->webHooks()->getWebHooks()); + $this->assertNull($this->client->customers()->getCustomers()); + $this->assertNull($this->client->cloudStorages()->getCloudStorages()); + $this->assertNull($this->client->layouts()->getLayouts()); + $this->assertNull($this->client->search()->search('Hello World')); + $this->assertEquals(12, $this->client->getPoolSize()); + + $this->assertTrue($this->client->isBatchModeEnabled()); + $this->client->disableBatchMode(); + $this->assertFalse($this->client->isBatchModeEnabled()); } /** @throws Exception */ public function testGetSetLogger() { - $client = $this->getClient(); - $this->assertInstanceOf(LoggerInterface::class, $client->getLogger()); - $this->assertInstanceOf(NullLogger::class, $client->getLogger()); + $this->assertInstanceOf(LoggerInterface::class, $this->client->getLogger()); + $this->assertInstanceOf(NullLogger::class, $this->client->getLogger()); - $client->setLogger(new EchoLogger()); - $this->assertInstanceOf(LoggerInterface::class, $client->getLogger()); - $this->assertInstanceOf(EchoLogger::class, $client->getLogger()); + $this->client->setLogger(new EchoLogger()); + $this->assertInstanceOf(LoggerInterface::class, $this->client->getLogger()); + $this->assertInstanceOf(EchoLogger::class, $this->client->getLogger()); - $client->setLogger(); - $this->assertInstanceOf(LoggerInterface::class, $client->getLogger()); - $this->assertInstanceOf(NullLogger::class, $client->getLogger()); + $this->client->setLogger(); + $this->assertInstanceOf(LoggerInterface::class, $this->client->getLogger()); + $this->assertInstanceOf(NullLogger::class, $this->client->getLogger()); - $client->setLogger(null); - $this->assertInstanceOf(LoggerInterface::class, $client->getLogger()); - $this->assertInstanceOf(NullLogger::class, $client->getLogger()); - } - - /** @throws Exception */ - public function testGetCustomers() - { - $client = $this->getClient(); - $customersResponse = $client->getCustomers(); - $this->assertInstanceOf(GetCustomersResponse::class, $customersResponse); - $this->assertEquals(0, $customersResponse->errorCode); - $this->assertGreaterThanOrEqual(0, $customersResponse->data); - - if (count($customersResponse->data) > 0) { - $this->assertInstanceOf(Customer::class, $customersResponse->data[0]); - } - } - - /** @throws Exception */ - public function testGetCustomerFails() - { - $client = $this->getClient(); - $this->expectException(InvalidIdException::class); - $this->expectExceptionMessage('Id must be an instance of integer and positive'); - $client->getCustomer(null); - } - - /** @throws Exception */ - public function testGetCustomer() - { - $client = $this->getClient(); - $customerResponse = $client->getCustomer($this->customerId); - $this->assertInstanceOf(GetCustomerResponse::class, $customerResponse); - $this->assertEquals(0, $customerResponse->errorCode); - $this->assertInstanceOf(Customer::class, $customerResponse->data); - $this->assertEquals($this->customerId, $customerResponse->data->id); - } - - /** @throws Exception */ - public function testGetCustomerAddressesFails() - { - $client = $this->getClient(); - $this->expectException(InvalidIdException::class); - $this->expectExceptionMessage('Id must be an instance of integer and positive'); - $client->getCustomerAddresses(null); - } - - /** @throws Exception */ - public function testGetCustomerAddresses() - { - $client = $this->getClient(); - sleep(1); - $addressesResponse = $client->getCustomerAddresses($this->customerId); - $this->assertInstanceOf(GetCustomerAddressesResponse::class, $addressesResponse); - $this->assertEquals(0, $addressesResponse->errorCode); - - if (count($addressesResponse->data) > 0) { - $this->assertInstanceOf(CustomerAddress::class, $addressesResponse->data[0]); - } - } - - /** @throws Exception */ - public function testGetCustomerAddress() - { - $client = $this->getClient(); - $addressResponse = $client->getCustomerAddress($this->addressId); - $this->assertInstanceOf(GetCustomerAddressResponse::class, $addressResponse); - $this->assertEquals(0, $addressResponse->errorCode); - $this->assertInstanceOf(CustomerAddress::class, $addressResponse->data); - $this->assertEquals($this->addressId, $addressResponse->data->id); - } - - /** @throws Exception */ - public function testGetCustomerOrdersFails() - { - $client = $this->getClient(); - - $this->expectException(InvalidIdException::class); - $this->expectExceptionMessage('Id must be an instance of integer and positive'); - $client->getCustomerOrders(null); - } - - /** @throws Exception */ - public function testGetCustomerOrders() - { - $client = $this->getClient(); - $customerOrdersResponse = $client->getCustomerOrders($this->customerId); - $this->assertInstanceOf(GetOrdersResponse::class, $customerOrdersResponse); - $this->assertEquals(0, $customerOrdersResponse->errorCode); - $this->assertGreaterThanOrEqual(0, $customerOrdersResponse->data); - - if (count($customerOrdersResponse->data) > 0) { - $this->assertInstanceOf(Order::class, $customerOrdersResponse->data[0]); - } - } - - /** @throws Exception */ - public function testCreateCustomer() - { - $client = $this->getClient(); - sleep(1); - - $customer = new Customer(); - $customer->email = 'max@mustermann.de'; - $customer->name = 'Max Mustermann'; - $customer->tel1 = '0123456'; - $customer->tel2 = '124658'; - $customer->vatId = '4711'; - - $address = new CustomerAddress(); - $address->id = 0; - $address->customerId = 0; - $address->firstName = 'Max'; - $address->lastName = 'Mustermann'; - $address->zip = '00000'; - $address->countryCode = 'DE'; - $address->city = 'Musterstadt'; - $address->email = 'max@mustermann.de'; - $address->addressType = CustomerAddress::TYPE_INVOICE; - $address->street = 'Test Straße'; - $address->houseNumber = '1'; - - $resp = $client->createCustomer($customer, $address); - $this->assertInstanceOf(GetCustomerResponse::class, $resp); - $this->assertEquals(0, $resp->errorCode); - $this->assertInstanceOf(Customer::class, $resp->data); - - $this->assertEquals($customer->email, $resp->data->email); - $this->assertEquals($customer->name, $resp->data->name); - $this->assertEquals($customer->tel1, $resp->data->tel1); - $this->assertEquals($customer->tel2, $resp->data->tel2); - $this->assertEquals($customer->vatId, $resp->data->vatId); - } - - /** @throws Exception */ - public function testUpdateCustomerFails() - { - $this->expectException(InvalidIdException::class); - $this->expectExceptionMessage('Id must be an instance of integer and positive'); - $this->getClient()->updateCustomer(new Customer()); - } - - /** @throws Exception */ - public function testUpdateCustomer() - { - $hash = md5(microtime(1)); - - $client = $this->getClient(); - sleep(1); - $customerResp = $client->getCustomer($this->customerId); - $customer = $customerResp->data; - - $originalName = $customer->name; - - $newName = $customer->name . ' | ' . $hash; - $customer->name = $newName; - $client->updateCustomer($customer); - sleep(1); - $customer2Resp = $client->getCustomer($this->customerId); - sleep(1); - $customer2 = $customer2Resp->data; - - $this->assertEquals($newName, $customer2->name); - - $customer2->name = $originalName; - - sleep(1); - $client->updateCustomer($customer2); - } - - /** @throws Exception */ - public function testShipOrderWithLabel() - { - if (empty($this->shippableOrderId) - || empty($this->shippingProviderId) - || empty($this->shippingProviderProduct)) { - return; - } - - $client = $this->getClient(); - sleep(1); - $shipment = new ShipmentWithLabel(); - $shipment->changeStateToSend = true; - $shipment->clientReference = 'Hallo Welt'; - $shipment->dimension = new Dimensions(15, 15, 10); - $shipment->orderId = $this->shippableOrderId; - $shipment->providerId = $this->shippingProviderId; - $shipment->productId = $this->shippingProviderProduct; - $shipment->shipDate = new DateTime('now'); - $shipment->weightInGram = 130; - - $client->shipWithLabel($shipment); + $this->client->setLogger(null); + $this->assertInstanceOf(LoggerInterface::class, $this->client->getLogger()); + $this->assertInstanceOf(NullLogger::class, $this->client->getLogger()); } /** @throws Exception */ public function testGetSetLogRequests() { - $client = $this->getClient(); - $this->assertFalse($client->getLogRequests()); - $client->setLogRequests(true); - $this->assertTrue($client->getLogRequests()); - $client->setLogRequests(false); - $this->assertFalse($client->getLogRequests()); - } - - /** @throws Exception */ - public function testGetCloudStorages() - { - if ($this->cloudStorageId == 0) { - return; - } - - $client = $this->getClient(); - sleep(1); - $cloudStorages = $client->getCloudStorages(); - $this->assertGreaterThanOrEqual(1, count($cloudStorages->data)); - - $containsCloudStorage = false; - foreach ($cloudStorages->data as $cloudStorage) { - if ($cloudStorage->id == $this->cloudStorageId) { - $containsCloudStorage = true; - break; - } - } - - $this->assertTrue($containsCloudStorage); - } - - /** @throws Exception */ - public function testGetCategories() - { - if ($this->categoryId == 0) { - return; - } - - $client = $this->getClient(); - sleep(1); - $categories = $client->getCategories(); - $this->assertGreaterThanOrEqual(1, count($categories->data)); - - $containsCategory = false; - foreach ($categories->data as $category) { - if ($category->id == $this->categoryId) { - $containsCategory = true; - break; - } - } - - $this->assertTrue($containsCategory); - } - - /** @throws Exception */ - public function testGetLayouts() - { - if ($this->layoutId == 0) { - return; - } - - $client = $this->getClient(); - sleep(1); - $layouts = $client->getLayouts(); - $this->assertGreaterThanOrEqual(1, count($layouts->data)); - - $containsLayout = false; - foreach ($layouts->data as $layout) { - if ($layout->id == $this->layoutId) { - $containsLayout = true; - break; - } - } - - $this->assertTrue($containsLayout); - } - - /** @throws Exception */ - public function testCreateAndDeleteProduct() - { - if ($this->sampleProductId == 0) { - return; - } - - $client = $this->getClient(); - sleep(1); - $response = $client->getProduct($this->sampleProductId); - $this->assertNotNull($response->data); - - $product = $response->data; - $product->id = null; - $product->sku = md5(time()); - sleep(1); - - $createResponse = $client->createProduct($product); - $this->assertNotNull($createResponse->data); - $this->assertInstanceOf(Product::class, $createResponse->data); - $this->assertEquals($product->sku, $createResponse->data->sku); - - sleep(1); - $newProductId = $createResponse->data->id; - $client->deleteProduct($newProductId); - - $this->expectException(ClientException::class); - $client->getProduct($newProductId); - } - - /** @throws Exception */ - public function testDeleteProductFails() - { - $client = $this->getClient(); - sleep(1); - - $this->expectException(ClientException::class); - $this->expectExceptionMessage('{"ErrorMessage":"Der Artikel 0 ist nicht vorhanden","ErrorCode":2,"Data":null}'); - $client->deleteProduct(0); - } - - /** @throws Exception */ - public function testUpdateProduct() - { - if ($this->sampleProductId == 0) { - return; - } - - $client = $this->getClient(); - sleep(1); - $response = $client->getProduct($this->sampleProductId); - $this->assertNotNull($response->data); - - $product = $response->data; - - $originalTitle = $product->title[0]->text; - sleep(1); - - $patchResponse = $client->patchProduct($product->id, [ - 'ShortText' => base64_encode($originalTitle) - ]); - $this->assertNotNull($patchResponse->data); - $this->assertInstanceOf(Product::class, $patchResponse->data); - $this->assertEquals($originalTitle, $product->title[0]->text); - - $client->patchProduct($product->id, [ - 'ShortText' => $originalTitle - ]); - } - - /** @throws Exception */ - public function testSearch() - { - $client = $this->getClient(); - - if ($this->sampleProductId != 0) { - sleep(1); - $response = $client->search($this->sampleProductId, [SearchType::PRODUCT]); - $this->assertNotNull($response->products); - $this->assertGreaterThanOrEqual(1, count($response->products)); - $filtered = array_filter($response->products, function (ProductResult $x) { - return $x->id === $this->sampleProductId; - }); - $this->assertGreaterThanOrEqual(1, count($filtered)); - } - - if ($this->sampleOrderId != 0) { - sleep(1); - $response = $client->search($this->sampleOrderId, [SearchType::ORDER]); - $this->assertNotNull($response->products); - $this->assertGreaterThanOrEqual(1, count($response->orders)); - $filtered = array_filter($response->orders, function (OrderResult $x) { - return $x->id === $this->sampleOrderId; - }); - $this->assertGreaterThanOrEqual(1, count($filtered)); - } - - if ($this->customerId != 0) { - sleep(1); - $response = $client->search($this->customerId, [SearchType::CUSTOMER]); - $this->assertNotNull($response->products); - $this->assertGreaterThanOrEqual(1, count($response->customers)); - $filtered = array_filter($response->customers, function (CustomerResult $x) { - return $x->id === $this->customerId; - }); - $this->assertGreaterThanOrEqual(1, count($filtered)); - } - } - - /** @throws Exception */ - public function testGetPatchableProductFields() - { - $client = $this->getClient(); - sleep(1); - /** @var GetPatchableFieldsResponse $result */ - $result = $client->getPatchableProductFields(); - $this->assertInstanceOf(GetPatchableFieldsResponse::class, $result); - $this->assertGreaterThanOrEqual(1, $result->data); - } - - /** @throws Exception */ - public function getClient() - { - static $client = null; - if ($client === null) { - $client = new Client($this->username, $this->password, $this->apiKey); - } - return $client; + $this->assertFalse($this->client->getLogRequests()); + $this->client->setLogRequests(true); + $this->assertTrue($this->client->getLogRequests()); + $this->client->setLogRequests(false); + $this->assertFalse($this->client->getLogRequests()); } } diff --git a/tests/EchoLogger.php b/tests/EchoLogger.php index 843a82b..e2d5255 100644 --- a/tests/EchoLogger.php +++ b/tests/EchoLogger.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/tests/Endpoint/CloudStorageEndpointTest.php b/tests/Endpoint/CloudStorageEndpointTest.php new file mode 100644 index 0000000..89eb6c6 --- /dev/null +++ b/tests/Endpoint/CloudStorageEndpointTest.php @@ -0,0 +1,46 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\CloudStorageEndpoint; +use BillbeeDe\BillbeeAPI\Response\GetCloudStoragesResponse; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use PHPUnit\Framework\TestCase; + +class CloudStorageEndpointTest extends TestCase +{ + /** @var CloudStorageEndpoint() */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new CloudStorageEndpoint($this->client); + } + + public function testGetCloudStorages() + { + $this->endpoint->getCloudStorages(); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('cloudstorages', $node); + $this->assertSame([], $data); + $this->assertSame(GetCloudStoragesResponse::class, $class); + } +} diff --git a/tests/Endpoint/CustomersEndpointTest.php b/tests/Endpoint/CustomersEndpointTest.php new file mode 100644 index 0000000..5769008 --- /dev/null +++ b/tests/Endpoint/CustomersEndpointTest.php @@ -0,0 +1,300 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\CustomersEndpoint; +use BillbeeDe\BillbeeAPI\Exception\InvalidIdException; +use BillbeeDe\BillbeeAPI\Model\CreateCustomerRequest; +use BillbeeDe\BillbeeAPI\Model\Customer; +use BillbeeDe\BillbeeAPI\Response\GetCustomerAddressesResponse; +use BillbeeDe\BillbeeAPI\Response\GetCustomerAddressResponse; +use BillbeeDe\BillbeeAPI\Response\GetCustomerResponse; +use BillbeeDe\BillbeeAPI\Response\GetCustomersResponse; +use BillbeeDe\BillbeeAPI\Response\GetOrdersResponse; +use BillbeeDe\Tests\BillbeeAPI\FakeSerializer; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use PHPUnit\Framework\TestCase; + +class CustomersEndpointTest extends TestCase +{ + + /** @var CustomersEndpoint) */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new CustomersEndpoint($this->client, new FakeSerializer()); + } + + public function testGetCustomers() + { + $this->endpoint->getCustomers(); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('customers', $node); + $this->assertSame([], $data); + $this->assertSame(GetCustomersResponse::class, $class); + } + + public function testGetCustomerFailsNegativeId() + { + $this->expectException(InvalidIdException::class); + $this->expectExceptionMessage('Id must be an instance of integer and positive'); + $this->endpoint->getCustomer(-1); + } + + public function testGetCustomerFailsNonNumericId() + { + $this->expectException(InvalidIdException::class); + $this->expectExceptionMessage('Id must be an instance of integer and positive'); + $this->endpoint->getCustomer('test'); + } + + public function testGetCustomer() + { + $this->endpoint->getCustomer(123); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123', $node); + $this->assertSame([], $data); + $this->assertSame(GetCustomerResponse::class, $class); + } + + public function testGetCustomerAddressesFailsNegativeId() + { + $this->expectException(InvalidIdException::class); + $this->expectExceptionMessage('Id must be an instance of integer and positive'); + $this->endpoint->getCustomerAddresses(-1); + } + + public function testGetCustomerAddressesFailsNonNumericId() + { + $this->expectException(InvalidIdException::class); + $this->expectExceptionMessage('Id must be an instance of integer and positive'); + $this->endpoint->getCustomerAddresses('test'); + } + + public function testGetCustomerAddresses() + { + $this->endpoint->getCustomerAddresses(123); + $this->endpoint->getCustomerAddresses(123, -1, 2); + $this->endpoint->getCustomerAddresses(123, 2, -1); + $this->endpoint->getCustomerAddresses(123, -1, -1); + $this->endpoint->getCustomerAddresses(123, 5, 5); + + $requests = $this->client->getRequests(); + $this->assertCount(5, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123/addresses', $node); + $this->assertSame([ + 'page' => 1, + 'pageSize' => 50, + ], $data); + $this->assertSame(GetCustomerAddressesResponse::class, $class); + + list($method, $node, $data, $class) = $requests[1]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123/addresses', $node); + $this->assertSame([ + 'page' => 1, + 'pageSize' => 2, + ], $data); + $this->assertSame(GetCustomerAddressesResponse::class, $class); + + list($method, $node, $data, $class) = $requests[2]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123/addresses', $node); + $this->assertSame([ + 'page' => 2, + 'pageSize' => 1, + ], $data); + $this->assertSame(GetCustomerAddressesResponse::class, $class); + + list($method, $node, $data, $class) = $requests[3]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123/addresses', $node); + $this->assertSame([ + 'page' => 1, + 'pageSize' => 1, + ], $data); + $this->assertSame(GetCustomerAddressesResponse::class, $class); + + list($method, $node, $data, $class) = $requests[4]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123/addresses', $node); + $this->assertSame([ + 'page' => 5, + 'pageSize' => 5, + ], $data); + $this->assertSame(GetCustomerAddressesResponse::class, $class); + } + + public function testGetCustomerAddressFailsNegativeId() + { + $this->expectException(InvalidIdException::class); + $this->expectExceptionMessage('Id must be an instance of integer and positive'); + $this->endpoint->getCustomerAddress(-1); + } + + public function testGetCustomerAddressFailsNonNumericId() + { + $this->expectException(InvalidIdException::class); + $this->expectExceptionMessage('Id must be an instance of integer and positive'); + $this->endpoint->getCustomerAddress('test'); + } + + public function testGetCustomerAddress() + { + $this->endpoint->getCustomerAddress(123); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('customers/addresses/123', $node); + $this->assertSame([], $data); + $this->assertSame(GetCustomerAddressResponse::class, $class); + } + + + public function testGetCustomerOrdersFailsNegativeId() + { + $this->expectException(InvalidIdException::class); + $this->expectExceptionMessage('Id must be an instance of integer and positive'); + $this->endpoint->getCustomerOrders(-1); + } + + public function testGetCustomerOrdersFailsNonNumericId() + { + $this->expectException(InvalidIdException::class); + $this->expectExceptionMessage('Id must be an instance of integer and positive'); + $this->endpoint->getCustomerOrders('test'); + } + + public function testGetCustomerOrders() + { + $this->endpoint->getCustomerOrders(123); + $this->endpoint->getCustomerOrders(123, -1, 2); + $this->endpoint->getCustomerOrders(123, 2, -1); + $this->endpoint->getCustomerOrders(123, -1, -1); + $this->endpoint->getCustomerOrders(123, 5, 5); + $requests = $this->client->getRequests(); + $this->assertCount(5, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123/orders', $node); + $this->assertSame([ + 'page' => 1, + 'pageSize' => 50, + ], $data); + $this->assertSame(GetOrdersResponse::class, $class); + + list($method, $node, $data, $class) = $requests[1]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123/orders', $node); + $this->assertSame([ + 'page' => 1, + 'pageSize' => 2, + ], $data); + $this->assertSame(GetOrdersResponse::class, $class); + + list($method, $node, $data, $class) = $requests[2]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123/orders', $node); + $this->assertSame([ + 'page' => 2, + 'pageSize' => 1, + ], $data); + $this->assertSame(GetOrdersResponse::class, $class); + + list($method, $node, $data, $class) = $requests[3]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123/orders', $node); + $this->assertSame([ + 'page' => 1, + 'pageSize' => 1, + ], $data); + $this->assertSame(GetOrdersResponse::class, $class); + + list($method, $node, $data, $class) = $requests[4]; + $this->assertSame('GET', $method); + $this->assertSame('customers/123/orders', $node); + $this->assertSame([ + 'page' => 5, + 'pageSize' => 5, + ], $data); + $this->assertSame(GetOrdersResponse::class, $class); + } + + + public function testUpdateCustomerFailsNegativeId() + { + $this->expectException(InvalidIdException::class); + $this->expectExceptionMessage('Id must be an instance of integer and positive'); + $customer = new Customer(); + $customer->id = -1; + $this->endpoint->updateCustomer($customer); + } + + public function testUpdateCustomerFailsNonNumericId() + { + $this->expectException(InvalidIdException::class); + $this->expectExceptionMessage('Id must be an instance of integer and positive'); + $customer = new Customer(); + $customer->id = 'test'; + $this->endpoint->updateCustomer($customer); + } + + public function testUpdateCustomer() + { + $customer = new Customer(); + $customer->id = 123; + $this->endpoint->updateCustomer($customer); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('PUT', $method); + $this->assertSame('customers/123', $node); + $this->assertSame($customer, $data); + $this->assertSame(GetCustomerResponse::class, $class); + } + + public function testCreateCustomer() + { + $request = new CreateCustomerRequest(); + + $this->endpoint->createCustomer($request); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('customers', $node); + $this->assertSame('{"address":null,"id":null,"name":null,"email":null,"tel1":null,"tel2":null,"number":null,"priceGroupId":null,"languageId":null,"vatId":null}', $data); + $this->assertSame(GetCustomerResponse::class, $class); + } +} diff --git a/tests/Endpoint/EventsEndpointTest.php b/tests/Endpoint/EventsEndpointTest.php new file mode 100644 index 0000000..08650f8 --- /dev/null +++ b/tests/Endpoint/EventsEndpointTest.php @@ -0,0 +1,77 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\EventsEndpoint; +use BillbeeDe\BillbeeAPI\Response\GetEventsResponse; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use DateTime; +use PHPUnit\Framework\TestCase; + +class EventsEndpointTest extends TestCase +{ + /** @var EventsEndpoint */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new EventsEndpoint($this->client); + } + + public function testGetEvents() + { + $this->endpoint->getEvents(); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('events', $node); + $this->assertSame([ + 'page' => 1, + 'pageSize' => 50, + ], $data); + $this->assertSame(GetEventsResponse::class, $class); + } + + public function testGetEventsAdvanced() + { + $this->endpoint->getEvents( + 10, + 35, + new DateTime('2020-01-01T00:00:00'), + new DateTime('2020-12-31T23:59:59'), + [1, 2, 5], + 123 + ); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('events', $node); + $this->assertSame([ + 'page' => 10, + 'pageSize' => 35, + 'minDate' => '2020-01-01T00:00:00+00:00', + 'maxDate' => '2020-12-31T23:59:59+00:00', + 'typeId' => [1, 2, 5], + 'orderId' => 123, + ], $data); + $this->assertSame(GetEventsResponse::class, $class); + } +} diff --git a/tests/Endpoint/InvoiceEndpointTest.php b/tests/Endpoint/InvoiceEndpointTest.php new file mode 100644 index 0000000..a02ddc4 --- /dev/null +++ b/tests/Endpoint/InvoiceEndpointTest.php @@ -0,0 +1,100 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\InvoiceEndpoint; +use BillbeeDe\BillbeeAPI\Response\GetInvoicesResponse; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use DateTime; +use InvalidArgumentException; +use PHPUnit\Framework\TestCase; + +class InvoiceEndpointTest extends TestCase +{ + /** @var InvoiceEndpoint() */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new InvoiceEndpoint($this->client); + } + + public function testGetInvoicesFailsInvalidShopId() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('shopId must be an array of int'); + $this->endpoint->getInvoices(1, 50, null, null, ['test']); + } + + public function testGetInvoicesFailsInvalidOrderStateId() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('orderStateId must be an array of int'); + $this->endpoint->getInvoices(1, 50, null, null, [], ['test']); + } + + public function testGetInvoices() + { + $this->endpoint->getInvoices(); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('orders/invoices', $node); + $this->assertSame([ + 'page' => 1, + 'pageSize' => 50, + ], $data); + $this->assertSame(GetInvoicesResponse::class, $class); + } + + public function testGetInvoicesAdvanced() + { + $this->endpoint->getInvoices( + 12, + 24, + new DateTime('2020-01-01T00:00:00'), + new DateTime('2020-12-31T00:00:00'), + [1, 233, 1], + [1, 2, 3, 4, 4], + ['test', 'test', 'test1'], + new DateTime('2020-01-01T01:00:00'), + new DateTime('2020-12-31T01:00:00'), + true + ); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('orders/invoices', $node); + $this->assertSame([ + 'page' => 12, + 'pageSize' => 24, + 'minInvoiceDate' => '2020-01-01T00:00:00+00:00', + 'maxInvoiceDate' => '2020-12-31T00:00:00+00:00', + 'shopId' => [1, 233], + 'orderStateId' => [1, 2, 3, 4], + 'tag' => ['test', 'test1'], + 'minPayDate' => '2020-01-01T01:00:00+00:00', + 'maxPayDate' => '2020-12-31T01:00:00+00:00', + 'includePositions' => 'true', + ], $data); + $this->assertSame(GetInvoicesResponse::class, $class); + } +} diff --git a/tests/Endpoint/LayoutsEndpointTest.php b/tests/Endpoint/LayoutsEndpointTest.php new file mode 100644 index 0000000..34f4104 --- /dev/null +++ b/tests/Endpoint/LayoutsEndpointTest.php @@ -0,0 +1,47 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\LayoutsEndpoint; +use BillbeeDe\BillbeeAPI\Response\GetLayoutsResponse; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use PHPUnit\Framework\TestCase; + +class LayoutsEndpointTest extends TestCase +{ + /** @var LayoutsEndpoint */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new LayoutsEndpoint($this->client); + } + + public function testGetLayouts() + { + $this->endpoint->getLayouts(); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('layouts', $node); + $this->assertSame([], $query); + $this->assertSame(GetLayoutsResponse::class, $class); + } +} diff --git a/tests/Endpoint/OrdersEndpointTest.php b/tests/Endpoint/OrdersEndpointTest.php new file mode 100644 index 0000000..a66423a --- /dev/null +++ b/tests/Endpoint/OrdersEndpointTest.php @@ -0,0 +1,437 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\OrdersEndpoint; +use BillbeeDe\BillbeeAPI\Model\MessageForCustomer; +use BillbeeDe\BillbeeAPI\Model\Order; +use BillbeeDe\BillbeeAPI\Model\Shipment; +use BillbeeDe\BillbeeAPI\Response\BaseResponse; +use BillbeeDe\BillbeeAPI\Response\CreateDeliveryNoteResponse; +use BillbeeDe\BillbeeAPI\Response\CreateInvoiceResponse; +use BillbeeDe\BillbeeAPI\Response\GetOrderByPartnerResponse; +use BillbeeDe\BillbeeAPI\Response\GetOrderResponse; +use BillbeeDe\BillbeeAPI\Response\GetOrdersResponse; +use BillbeeDe\BillbeeAPI\Response\GetPatchableFieldsResponse; +use BillbeeDe\BillbeeAPI\Type\ArticleSource; +use BillbeeDe\BillbeeAPI\Type\SendMode; +use BillbeeDe\Tests\BillbeeAPI\FakeSerializer; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use DateTime; +use InvalidArgumentException; +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; + +class OrdersEndpointTest extends TestCase +{ + /** @var OrdersEndpoint */ + private $endpoint; + + /** @var TestClient */ + private $client; + + /** @var LoggerInterface */ + private $loggerMock; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->loggerMock = $this->createMock(LoggerInterface::class); + $this->endpoint = new OrdersEndpoint($this->client, new FakeSerializer(), $this->loggerMock); + } + + public function testGetOrders() + { + $this->endpoint->getOrders(); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('orders', $node); + $this->assertSame([ + 'page' => 1, + 'pageSize' => 50, + 'articleTitleSource' => ArticleSource::ORDER_POSITION, + ], $data); + $this->assertSame(GetOrdersResponse::class, $class); + } + + public function testGetOrdersAdvanced() + { + $this->endpoint->getOrders( + 3, + 11, + new DateTime('2020-01-01T00:00:00'), + new DateTime('2020-12-31T00:00:00'), + [11, 3, 4, 22, 3, 4], + [1, 2, 3, 4, 4, 5], + ['test', 'test2', 'test'], + 1, + new DateTime('2020-01-01T01:00:00'), + new DateTime('2020-12-31T01:00:00'), + ArticleSource::ARTICLE_TITLE, + true + ); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('orders', $node); + $this->assertSame([ + 'page' => 3, + 'pageSize' => 11, + 'minOrderDate' => '2020-01-01T00:00:00+00:00', + 'maxOrderDate' => '2020-12-31T00:00:00+00:00', + 'shopId' => [11, 3, 4, 22], + 'orderStateId' => [1, 2, 3, 4, 5], + 'tag' => ['test', 'test2'], + 'minimumBillBeeOrderId' => 1, + 'modifiedAtMin' => '2020-01-01T01:00:00+00:00', + 'modifiedAtMax' => '2020-12-31T01:00:00+00:00', + 'articleTitleSource' => ArticleSource::ARTICLE_TITLE, + 'excludeTags' => 'true', + ], $data); + $this->assertSame(GetOrdersResponse::class, $class); + } + + public function testGetOrdersFailsInvalidShopId() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('All elements in shopId must be numeric.'); + + $this->endpoint->getOrders( + 1, + 50, + null, + null, + ['abc'] + ); + } + + public function testGetOrdersFailsInvalidOrderStateId() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('All elements in orderStateId must be numeric.'); + + $this->endpoint->getOrders( + 1, + 50, + null, + null, + [], + ['abc'] + ); + } + + public function testGetOrdersFailsNonNumericArticleTitleSource() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The articleTitleSource is invalid. Check BillbeeDe\BillbeeAPI\Type\ArticleSource for valid values'); + + $this->endpoint->getOrders( + 1, + 50, + null, + null, + [], + [], + [], + null, + null, + null, + 'abc' + ); + } + + public function testGetOrdersFailsNegativeArticleTitleSource() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The articleTitleSource is invalid. Check BillbeeDe\BillbeeAPI\Type\ArticleSource for valid values'); + + $this->endpoint->getOrders( + 1, + 50, + null, + null, + [], + [], + [], + null, + null, + null, + -1 + ); + } + + public function testGetOrdersFailsInvalidArticleTitleSource() + { + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The articleTitleSource is invalid. Check BillbeeDe\BillbeeAPI\Type\ArticleSource for valid values'); + + $this->endpoint->getOrders( + 1, + 50, + null, + null, + [], + [], + [], + null, + null, + null, + 400 + ); + } + + public function testGetPatchableFields() + { + $this->endpoint->getPatchableFields(); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('orders/PatchableFields', $node); + $this->assertSame([], $data); + $this->assertSame(GetPatchableFieldsResponse::class, $class); + } + + public function testGetOrder() + { + $this->endpoint->getOrder(3421); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('orders/3421', $node); + $this->assertSame([], $data); + $this->assertSame(GetOrderResponse::class, $class); + } + + public function testGetOrderByOrderNumber() + { + $this->endpoint->getOrderByOrderNumber('foo221'); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('orders/findbyextref/foo221', $node); + $this->assertSame([], $data); + $this->assertSame(GetOrderResponse::class, $class); + } + + public function testGetOrderByPartner() + { + $this->endpoint->getOrderByPartner('foo221', 'demo'); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('orders/find/foo221/demo', $node); + $this->assertSame([], $data); + $this->assertSame(GetOrderByPartnerResponse::class, $class); + } + + public function testCreateOrder() + { + $order = new Order(); + $this->endpoint->createOrder($order, 521); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('orders?shopId=521', $node); + $this->assertSame($order, $data); + $this->assertSame(BaseResponse::class, $class); + } + + public function testAddOrderTags() + { + $this->endpoint->addOrderTags(521, ['test', 'test2']); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('orders/521/tags', $node); + $this->assertSame('{"Tags":["test","test2"]}', $data); + $this->assertSame(BaseResponse::class, $class); + } + + public function testAddOrderShipment() + { + $shipment = new Shipment(); + $result = $this->endpoint->addOrderShipment(521, $shipment); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('orders/521/shipment', $node); + $this->assertSame($shipment, $data); + $this->assertSame(BaseResponse::class, $class); + $this->assertTrue($result); + } + + public function testCreateDeliveryNote() + { + $this->endpoint->createDeliveryNote(521); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('orders/CreateDeliveryNote/521?includePdf=False', $node); + $this->assertSame([], $data); + $this->assertSame(CreateDeliveryNoteResponse::class, $class); + } + + public function testCreateDeliveryNoteWithIncludePdf() + { + $this->endpoint->createDeliveryNote(521, true); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('orders/CreateDeliveryNote/521?includePdf=True', $node); + $this->assertSame([], $data); + $this->assertSame(CreateDeliveryNoteResponse::class, $class); + } + + public function testCreateInvoice() + { + $this->endpoint->createInvoice(521); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('orders/CreateInvoice/521?includeInvoicePdf=False', $node); + $this->assertSame([], $data); + $this->assertSame(CreateInvoiceResponse::class, $class); + } + + public function testCreateInvoiceAdvanced() + { + $this->endpoint->createInvoice(521, true, 234, 543); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('orders/CreateInvoice/521?includeInvoicePdf=True&templateId=234&sendToCloudId=543', $node); + $this->assertSame([], $data); + $this->assertSame(CreateInvoiceResponse::class, $class); + } + + public function testSendMessageFailsInvalidSendMode() + { + $message = new MessageForCustomer([], [], -1); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The sendMode is invalid. Check the BillbeeDe\BillbeeAPI\Type\SendMode class for valid values'); + + $this->endpoint->sendMessage(521, $message); + } + + public function testSendMessageFailsNoSubject() + { + $message = new MessageForCustomer(); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('You have to specify a message subject'); + + $this->endpoint->sendMessage(521, $message); + } + + public function testSendMessageFailsNoBody() + { + $message = new MessageForCustomer(['de' => 'test']); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('You have to specify a message body'); + + $this->endpoint->sendMessage(521, $message); + } + + public function testSendMessageFailsNoAlternateEmail() + { + $message = new MessageForCustomer(['de' => 'test'], ['de' => 'test2'], SendMode::EXTERNAL_EMAIL); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage("With sendMode == 4 it's required to specify an alternativeEmailAddress"); + + $this->endpoint->sendMessage(521, $message); + } + + public function testSendMessage() + { + $message = new MessageForCustomer(['de' => 'test'], ['de' => 'test2'], SendMode::EMAIL, 'foo@bar.tld'); + $this->endpoint->sendMessage(521, $message); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('orders/521/send-message', $node); + $this->assertSame($message, $data); + $this->assertSame(BaseResponse::class, $class); + } + + public function testSetOrderTags() + { + $this->endpoint->setOrderTags(521, ['test', 'test2']); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('PUT', $method); + $this->assertSame('orders/521/tags', $node); + $this->assertSame('{"Tags":["test","test2"]}', $data); + $this->assertSame(BaseResponse::class, $class); + } + + public function testSetOrderState() + { + $this->endpoint->setOrderState(521, 23); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('PUT', $method); + $this->assertSame('orders/521/orderstate', $node); + $this->assertSame('{"NewStateId":23}', $data); + $this->assertSame(BaseResponse::class, $class); + } + + public function testPatchOrder() + { + $model = ['hello' => 'world']; + $this->endpoint->patchOrder(521, $model); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('PATCH', $method); + $this->assertSame('orders/521', $node); + $this->assertSame($model, $data); + $this->assertSame(GetOrderResponse::class, $class); + } +} diff --git a/tests/Endpoint/ProductCustomFieldsEndpointTest.php b/tests/Endpoint/ProductCustomFieldsEndpointTest.php new file mode 100644 index 0000000..fea5a11 --- /dev/null +++ b/tests/Endpoint/ProductCustomFieldsEndpointTest.php @@ -0,0 +1,72 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\ProductCustomFieldsEndpoint; +use BillbeeDe\BillbeeAPI\Exception\InvalidIdException; +use BillbeeDe\BillbeeAPI\Response\GetCustomFieldDefinitionResponse; +use BillbeeDe\BillbeeAPI\Response\GetCustomFieldDefinitionsResponse; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use PHPUnit\Framework\TestCase; + +class ProductCustomFieldsEndpointTest extends TestCase +{ + /** @var ProductCustomFieldsEndpoint */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new ProductCustomFieldsEndpoint($this->client); + } + + public function testGetCustomFieldDefinitions() + { + $this->endpoint->getCustomFieldDefinitions(4, 100); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('products/custom-fields', $node); + $this->assertSame([ + 'page' => 4, + 'pageSize' => 100, + ], $query); + $this->assertSame(GetCustomFieldDefinitionsResponse::class, $class); + } + + public function testGetCustomFieldDefinitionFailsInvalidId() + { + $this->expectException(InvalidIdException::class); + $this->endpoint->getCustomFieldDefinition('1234b3x'); + } + + public function testGetCustomFieldDefinition() + { + $this->endpoint->getCustomFieldDefinition(200); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('products/custom-fields/200', $node); + $this->assertSame([], $query); + $this->assertSame(GetCustomFieldDefinitionResponse::class, $class); + } +} diff --git a/tests/Endpoint/ProductsEndpointTest.php b/tests/Endpoint/ProductsEndpointTest.php new file mode 100644 index 0000000..992749c --- /dev/null +++ b/tests/Endpoint/ProductsEndpointTest.php @@ -0,0 +1,213 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\ProductsEndpoint; +use BillbeeDe\BillbeeAPI\Model\Stock; +use BillbeeDe\BillbeeAPI\Model\StockCode; +use BillbeeDe\BillbeeAPI\Response\BaseResponse; +use BillbeeDe\BillbeeAPI\Response\GetCategoriesResponse; +use BillbeeDe\BillbeeAPI\Response\GetPatchableFieldsResponse; +use BillbeeDe\BillbeeAPI\Response\GetProductResponse; +use BillbeeDe\BillbeeAPI\Response\GetProductsResponse; +use BillbeeDe\BillbeeAPI\Response\UpdateStockResponse; +use BillbeeDe\BillbeeAPI\Type\ProductLookupBy; +use BillbeeDe\Tests\BillbeeAPI\FakeSerializer; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use DateTime; +use Exception; +use PHPUnit\Framework\TestCase; + +class ProductsEndpointTest extends TestCase +{ + /** @var ProductsEndpoint */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new ProductsEndpoint($this->client, new FakeSerializer()); + } + + + /** @throws Exception */ + public function testGetProducts() + { + $this->endpoint->getProducts(1, 1); + $this->endpoint->getProducts(2, 10, new DateTime('2020-10-01T00:00:00')); + + $requests = $this->client->getRequests(); + $this->assertCount(2, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('products', $node); + $this->assertSame(['page' => 1, 'pageSize' => 1], $query); + $this->assertSame(GetProductsResponse::class, $class); + + list($method, $node, $query, $class) = $requests[1]; + $this->assertSame('GET', $method); + $this->assertSame('products', $node); + $this->assertSame([ + 'page' => 2, + 'pageSize' => 10, + 'minCreatedAt' => '2020-10-01T00:00:00+00:00' + ], $query); + $this->assertSame(GetProductsResponse::class, $class); + } + + /** @throws Exception */ + public function testGetProduct() + { + $this->endpoint->getProduct(4711); + $this->endpoint->getProduct(1234, ProductLookupBy::EAN); + + $requests = $this->client->getRequests(); + $this->assertCount(2, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('products/4711', $node); + $this->assertSame(['lookupBy' => ProductLookupBy::ID], $query); + $this->assertSame(GetProductResponse::class, $class); + + list($method, $node, $query, $class) = $requests[1]; + $this->assertSame('GET', $method); + $this->assertSame('products/1234', $node); + $this->assertSame(['lookupBy' => ProductLookupBy::EAN], $query); + $this->assertSame(GetProductResponse::class, $class); + } + + public function testGetCategories() + { + $this->endpoint->getCategories(); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('products/category', $node); + $this->assertSame([], $query); + $this->assertSame(GetCategoriesResponse::class, $class); + } + + /** @throws Exception */ + public function testGetPatchableProductFields() + { + $this->endpoint->getPatchableProductFields(); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('products/PatchableFields', $node); + $this->assertSame([], $query); + $this->assertSame(GetPatchableFieldsResponse::class, $class); + } + + /** @throws Exception */ + public function testUpdateStock() + { + $stockModel = new Stock(4711, 1234, 0); + + $this->endpoint->updateStock($stockModel); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('products/updatestock', $node); + $this->assertSame($stockModel, $data); + $this->assertSame(UpdateStockResponse::class, $class); + } + + + /** @throws Exception */ + public function testUpdateStockMultiple() + { + $stockModel1 = new Stock(4711, 1234, 0); + $stockModel2 = new Stock(1234, 500, 600); + + $this->endpoint->updateStockMultiple([$stockModel1, $stockModel2]); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('products/updatestockmultiple', $node); + $this->assertSame([$stockModel1, $stockModel2], $data); + $this->assertSame(UpdateStockResponse::class . '[]', $class); + } + + /** @throws Exception */ + public function testUpdateStockCode() + { + $stockCode = new StockCode(); + $stockCode->sku = '1234'; + $stockCode->stockCode = '54321'; + $stockCode->stockId = 1234; + + $this->endpoint->updateStockCode($stockCode); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('products/updatestockcode', $node); + $this->assertSame($stockCode, $data); + $this->assertSame(BaseResponse::class, $class); + } + + public function testCreateProduct() + { + $product = unserialize('O:34:"BillbeeDe\BillbeeAPI\Model\Product":54:{s:2:"id";i:1234;s:4:"type";i:1;s:5:"title";a:3:{i:0;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:8:"Title DE";s:12:"languageCode";s:2:"DE";}i:1;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:8:"Title EN";s:12:"languageCode";s:2:"EN";}i:2;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:8:"Title Fr";s:12:"languageCode";s:2:"FR";}}s:11:"invoiceText";a:3:{i:0;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:6:"Inv DE";s:12:"languageCode";s:2:"DE";}i:1;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:6:"Inv EN";s:12:"languageCode";s:2:"EN";}i:2;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:6:"Inv Fr";s:12:"languageCode";s:2:"FR";}}s:16:"shortDescription";a:3:{i:0;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:13:"Short Desc DE";s:12:"languageCode";s:2:"DE";}i:1;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:13:"Short Desc EN";s:12:"languageCode";s:2:"EN";}i:2;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:13:"Short Desc Fr";s:12:"languageCode";s:2:"FR";}}s:6:"images";a:1:{i:0;O:32:"BillbeeDe\BillbeeAPI\Model\Image":6:{s:2:"id";i:4711;s:3:"url";s:68:"https://cdn.stocksnap.io/img-thumbs/960w/fruit-slices_NNIRPAXZFX.jpg";s:12:"thumbPathExt";s:63:"ab665923-d288-45ff-8d9e-410d10dda01e/40986800/100/493289770.png";s:8:"thumbUrl";s:110:"https://billbee-articleimages.s3.amazonaws.com/ab665923-d288-45ff-8d9e-410d10dda01e/40986800/100/493289770.png";s:8:"position";i:1;s:9:"isDefault";b:1;}}s:11:"description";a:3:{i:0;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:7:"Desc DE";s:12:"languageCode";s:2:"DE";}i:1;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:7:"Desc EN";s:12:"languageCode";s:2:"EN";}i:2;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:7:"Desc Fr";s:12:"languageCode";s:2:"FR";}}s:10:"attributes";a:3:{i:0;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:13:"Basic Attr DE";s:12:"languageCode";s:2:"DE";}i:1;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:13:"Basic Attr EN";s:12:"languageCode";s:2:"EN";}i:2;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:13:"Basic Attr Fr";s:12:"languageCode";s:2:"FR";}}s:3:"sku";s:8:"SKU 1234";s:3:"ean";s:13:"1234123412341";s:7:"sources";a:0:{}s:9:"category1";N;s:9:"category2";N;s:9:"category3";N;s:12:"manufacturer";s:0:"";s:8:"vatIndex";i:1;s:5:"price";d:0;s:9:"costPrice";d:0;s:13:"vatRateNormal";d:16;s:14:"vatRateReduced";d:5;s:9:"materials";a:3:{i:0;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:12:"Materials DE";s:12:"languageCode";s:2:"DE";}i:1;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:12:"Materials EN";s:12:"languageCode";s:2:"EN";}i:2;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:12:"Materials Fr";s:12:"languageCode";s:2:"FR";}}s:4:"tags";a:3:{i:0;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:7:"Tags DE";s:12:"languageCode";s:2:"DE";}i:1;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:7:"Tags EN";s:12:"languageCode";s:2:"EN";}i:2;O:43:"BillbeeDe\BillbeeAPI\Model\TranslatableText":2:{s:4:"text";s:7:"Tags Fr";s:12:"languageCode";s:2:"FR";}}s:12:"stockDesired";d:0;s:12:"stockCurrent";d:3876;s:12:"stockWarning";d:0;s:8:"lowStock";b:0;s:9:"stockCode";s:10:"Stock Code";s:23:"stockReduceItemsPerSale";d:1;s:6:"stocks";a:1:{i:0;a:7:{s:4:"Name";N;s:7:"StockId";i:266;s:12:"StockCurrent";d:3744;s:12:"StockWarning";N;s:9:"StockCode";N;s:17:"UnfulfilledAmount";N;s:12:"StockDesired";N;}}s:6:"weight";i:1230;s:9:"weightNet";i:1200;s:4:"unit";i:1;s:12:"unitsPerItem";d:1;s:10:"soldAmount";i:0;s:12:"soldSumGross";d:0;s:10:"soldSumNet";d:0;s:20:"soldSumNetLast30Days";d:0;s:22:"soldSumGrossLast30Days";d:0;s:20:"soldAmountLast30Days";d:0;s:17:"shippingProductId";i:0;s:9:"isDigital";b:0;s:14:"isCustomizable";b:0;s:12:"deliveryTime";N;s:9:"recipient";N;s:8:"occasion";N;s:15:"countryOfOrigin";s:0:"";s:17:"exportDescription";s:0:"";s:11:"taricNumber";s:0:"";s:12:"customFields";a:0:{}s:9:"condition";i:1;s:7:"widthCm";N;s:8:"lengthCm";N;s:8:"heightCm";N;s:14:"billOfMaterial";a:0:{}}'); + $this->endpoint->createProduct($product); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('products', $node); + $this->assertSame($product, $data); + $this->assertSame(GetProductResponse::class, $class); + } + + public function testPatchProduct() + { + $this->endpoint->patchProduct(1234, ['foo' => 'bar']); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('PATCH', $method); + $this->assertSame('products/1234', $node); + $this->assertSame(['foo' => 'bar'], $data); + $this->assertSame(GetProductResponse::class, $class); + } + + public function testDeleteProduct() + { + $this->endpoint->deleteProduct(1234); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('DELETE', $method); + $this->assertSame('products/1234', $node); + $this->assertSame([], $data); + $this->assertSame(BaseResponse::class, $class); + } +} diff --git a/tests/Endpoint/ProvisioningEndpointTest.php b/tests/Endpoint/ProvisioningEndpointTest.php new file mode 100644 index 0000000..fffe281 --- /dev/null +++ b/tests/Endpoint/ProvisioningEndpointTest.php @@ -0,0 +1,50 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\ProvisioningEndpoint; +use BillbeeDe\BillbeeAPI\Response\GetTermsInfoResponse; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use Exception; +use PHPUnit\Framework\TestCase; + +class ProvisioningEndpointTest extends TestCase +{ + /** @var ProvisioningEndpoint() */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new ProvisioningEndpoint($this->client); + } + + + /** @throws Exception */ + public function testGetTermsInfo() + { + $this->endpoint->getTermsInfo(); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('automaticprovision/termsinfo', $node); + $this->assertSame([], $query); + $this->assertSame(GetTermsInfoResponse::class, $class); + } +} diff --git a/tests/Endpoint/SearchEndpointTest.php b/tests/Endpoint/SearchEndpointTest.php new file mode 100644 index 0000000..e2cd893 --- /dev/null +++ b/tests/Endpoint/SearchEndpointTest.php @@ -0,0 +1,57 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\SearchEndpoint; +use BillbeeDe\BillbeeAPI\Response\SearchDataResponse; +use BillbeeDe\BillbeeAPI\Type\SearchMode; +use BillbeeDe\BillbeeAPI\Type\SearchType; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use PHPUnit\Framework\TestCase; + +class SearchEndpointTest extends TestCase +{ + /** @var SearchEndpoint */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new SearchEndpoint($this->client); + } + + public function testSearch() + { + $term = 'Hello World'; + $type = [SearchType::ORDER]; + $searchMode = SearchMode::_SUGGEST; + + $this->endpoint->search($term, $type, $searchMode); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('search', $node); + $this->assertSame([ + 'Type' => $type, + 'Term' => $term, + 'SearchMode' => $searchMode, + ], $query); + $this->assertSame(SearchDataResponse::class, $class); + } +} diff --git a/tests/Endpoint/ShipmentsEndpointTest.php b/tests/Endpoint/ShipmentsEndpointTest.php new file mode 100644 index 0000000..66760b5 --- /dev/null +++ b/tests/Endpoint/ShipmentsEndpointTest.php @@ -0,0 +1,64 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\ShipmentsEndpoint; +use BillbeeDe\BillbeeAPI\Model\ShipmentWithLabel; +use BillbeeDe\BillbeeAPI\Model\ShippingProvider; +use BillbeeDe\BillbeeAPI\Response\ShipWithLabelResponse; +use BillbeeDe\Tests\BillbeeAPI\FakeSerializer; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use PHPUnit\Framework\TestCase; + +class ShipmentsEndpointTest extends TestCase +{ + /** @var ShipmentsEndpoint */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new ShipmentsEndpoint($this->client, new FakeSerializer()); + } + + public function testGetShippingProviders() + { + $this->endpoint->getShippingProviders(); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('shipment/shippingproviders', $node); + $this->assertSame([], $query); + $this->assertSame(ShippingProvider::class . '[]', $class); + } + + public function testShipWithLabel() + { + $shipment = new ShipmentWithLabel(); + + $this->endpoint->shipWithLabel($shipment); + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $data, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('shipment/shipwithlabel', $node); + $this->assertSame($shipment, $data); + $this->assertSame(ShipWithLabelResponse::class, $class); + } +} diff --git a/tests/Endpoint/WebHooksEndpointTest.php b/tests/Endpoint/WebHooksEndpointTest.php new file mode 100644 index 0000000..ade2f9d --- /dev/null +++ b/tests/Endpoint/WebHooksEndpointTest.php @@ -0,0 +1,172 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Endpoint; + +use BillbeeDe\BillbeeAPI\Endpoint\WebHooksEndpoint; +use BillbeeDe\BillbeeAPI\Model\WebHook; +use BillbeeDe\BillbeeAPI\Model\WebHookFilter; +use BillbeeDe\BillbeeAPI\Response\BaseResponse; +use BillbeeDe\Tests\BillbeeAPI\FakeSerializer; +use BillbeeDe\Tests\BillbeeAPI\TestClient; +use InvalidArgumentException; +use PHPUnit\Framework\TestCase; + +class WebHooksEndpointTest extends TestCase +{ + /** @var WebHooksEndpoint */ + private $endpoint; + + /** @var TestClient */ + private $client; + + protected function setUp(): void + { + $this->client = new TestClient(); + $this->endpoint = new WebHooksEndpoint($this->client, new FakeSerializer()); + } + + public function testGetWebHooks() + { + $this->endpoint->getWebHooks(); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('webhooks', $node); + $this->assertSame([], $query); + $this->assertSame(WebHook::class.'[]', $class); + } + + public function testGetWebHook() + { + $this->endpoint->getWebHook('abasd'); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('webhooks/abasd', $node); + $this->assertSame([], $query); + $this->assertSame(WebHook::class, $class); + } + + public function testGetWebHookFilters() + { + $this->endpoint->getWebHookFilters(); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('GET', $method); + $this->assertSame('webhooks/filters', $node); + $this->assertSame([], $query); + $this->assertSame(WebHookFilter::class.'[]', $class); + } + + public function testCreateWebHook() + { + $webHook = new WebHook(); + $this->endpoint->createWebHook($webHook); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('POST', $method); + $this->assertSame('webhooks', $node); + $this->assertSame($webHook, $query); + $this->assertSame(WebHook::class, $class); + } + + public function testUpdateWebHookFailsMissingId() + { + $webHook = new WebHook(); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The id of the webHook cannot be empty'); + $this->endpoint->updateWebHook($webHook); + } + + public function testUpdateWebHook() + { + $webHook = new WebHook(); + $webHook->id = 'HelloWorld'; + $this->endpoint->updateWebHook($webHook); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('PUT', $method); + $this->assertSame('webhooks/HelloWorld', $node); + $this->assertSame($webHook, $query); + $this->assertSame(WebHook::class, $class); + } + + public function testDeleteAllWebHooks() + { + $this->endpoint->deleteAllWebHooks(); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('DELETE', $method); + $this->assertSame('webhooks', $node); + $this->assertSame([], $query); + $this->assertSame(BaseResponse::class, $class); + } + + public function testDeleteWebHookById() + { + $this->endpoint->deleteWebHookById('HelloWorld'); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('DELETE', $method); + $this->assertSame('webhooks/HelloWorld', $node); + $this->assertSame([], $query); + $this->assertSame(BaseResponse::class, $class); + } + + public function testDeleteWebHookFailsMissingId() + { + $webHook = new WebHook(); + + $this->expectException(InvalidArgumentException::class); + $this->expectExceptionMessage('The id of the webHook cannot be empty'); + $this->endpoint->deleteWebHook($webHook); + } + + public function testDeleteWebHook() + { + $webHook = new WebHook(); + $webHook->id = 'HelloWorld'; + $this->endpoint->deleteWebHook($webHook); + + $requests = $this->client->getRequests(); + $this->assertCount(1, $requests); + + list($method, $node, $query, $class) = $requests[0]; + $this->assertSame('DELETE', $method); + $this->assertSame('webhooks/HelloWorld', $node); + $this->assertSame([], $query); + $this->assertSame(BaseResponse::class, $class); + } +} diff --git a/tests/FakeSerializer.php b/tests/FakeSerializer.php new file mode 100644 index 0000000..e4516f7 --- /dev/null +++ b/tests/FakeSerializer.php @@ -0,0 +1,28 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI; + +use MintWare\DMM\Serializer\SerializerInterface; + +class FakeSerializer implements SerializerInterface +{ + public function deserialize($data) + { + return $data; + } + + public function serialize($data) + { + return $data; + } +} diff --git a/tests/Logger/DiagnosticsLoggerTest.php b/tests/Logger/DiagnosticsLoggerTest.php new file mode 100644 index 0000000..29b117d --- /dev/null +++ b/tests/Logger/DiagnosticsLoggerTest.php @@ -0,0 +1,80 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI\Logger; + +use BillbeeDe\BillbeeAPI\Logger\DiagnosticsLogger; +use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; + +class DiagnosticsLoggerTest extends TestCase +{ + /** @var DiagnosticsLogger */ + private $logger; + + protected function setUp(): void + { + $this->logger = new DiagnosticsLogger(); + } + + protected function tearDown(): void + { + $logFile = $this->logger->getLogFile(); + if (is_file($logFile)) { + unlink($logFile); + } + } + + public function testConstructor() + { + $this->assertInstanceOf(LoggerInterface::class, $this->logger); + + $logFile = $this->logger->getLogFile(); + $this->assertNotNull($logFile); + $this->assertGreaterThan(1, strpos($logFile, 'billbee_api_')); + $this->assertEquals(0, strpos($logFile, sys_get_temp_dir())); + } + + public function testLogging() + { + $this->logger->emergency('Message 1', ['a' => 'b']); + $this->logger->alert('Message 2', ['b' => 'c']); + $this->logger->critical('Message 3', ['c' => 'd']); + $this->logger->error('Message 4', ['d' => 'e']); + $this->logger->warning('Message 5', ['e' => 'f']); + $this->logger->notice('Message 6', ['f' => 'g']); + $this->logger->info('Message 7', ['g' => 'h']); + $this->logger->debug('Message 8', ['h' => 'i']); + $this->logger->log('CUSTOM', 'Message 9', ['i' => 'j']); + + $fileContent = file_get_contents($this->logger->getLogFile()); + $emergencyPos = strpos($fileContent, 'EMERGENCY: Message: Message 1; Context: {"a":"b"}'); + $alertPos = strpos($fileContent, 'ALERT: Message: Message 2; Context: {"b":"c"}'); + $criticalPos = strpos($fileContent, 'CRITICAL: Message: Message 3; Context: {"c":"d"}'); + $errorPos = strpos($fileContent, 'ERROR: Message: Message 4; Context: {"d":"e"}'); + $warningPos = strpos($fileContent, 'WARNING: Message: Message 5; Context: {"e":"f"}'); + $noticePos = strpos($fileContent, 'NOTICE: Message: Message 6; Context: {"f":"g"}'); + $infoPos = strpos($fileContent, 'INFO: Message: Message 7; Context: {"g":"h"}'); + $debugPos = strpos($fileContent, 'DEBUG: Message: Message 8; Context: {"h":"i"}'); + $customPos = strpos($fileContent, 'CUSTOM: Message: Message 9; Context: {"i":"j"}'); + + $this->assertGreaterThan(-1, $emergencyPos); + $this->assertGreaterThan($emergencyPos, $alertPos); + $this->assertGreaterThan($alertPos, $criticalPos); + $this->assertGreaterThan($criticalPos, $errorPos); + $this->assertGreaterThan($errorPos, $warningPos); + $this->assertGreaterThan($warningPos, $noticePos); + $this->assertGreaterThan($noticePos, $infoPos); + $this->assertGreaterThan($infoPos, $debugPos); + $this->assertGreaterThan($debugPos, $customPos); + } +} diff --git a/tests/Model/ShipmentTest.php b/tests/Model/ShipmentTest.php index 48276b1..0cb5c59 100644 --- a/tests/Model/ShipmentTest.php +++ b/tests/Model/ShipmentTest.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/tests/Model/StockCodeTest.php b/tests/Model/StockCodeTest.php index 478116d..85a8f7e 100644 --- a/tests/Model/StockCodeTest.php +++ b/tests/Model/StockCodeTest.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/tests/Model/StockTest.php b/tests/Model/StockTest.php index 799a621..9cb2346 100644 --- a/tests/Model/StockTest.php +++ b/tests/Model/StockTest.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. diff --git a/tests/TestClient.php b/tests/TestClient.php new file mode 100644 index 0000000..7a9d17e --- /dev/null +++ b/tests/TestClient.php @@ -0,0 +1,77 @@ + + */ + +namespace BillbeeDe\Tests\BillbeeAPI; + +use BillbeeDe\BillbeeAPI\ClientInterface; +use MintWare\DMM\ObjectMapper; +use MintWare\DMM\Serializer\JsonSerializer; + +class TestClient implements ClientInterface +{ + private $requests = []; + + /** @var ObjectMapper */ + private $mapper; + + public function __construct() + { + $this->mapper = new ObjectMapper(new JsonSerializer()); + } + + public function get($node, $query, $responseClass) + { + return $this->handle('GET', $node, $query, $responseClass); + } + + public function post($node, $data, $responseClass) + { + return $this->handle('POST', $node, $data, $responseClass); + } + + public function put($node, $data, $responseClass) + { + return $this->handle('PUT', $node, $data, $responseClass); + } + + public function patch($node, $data, $responseClass) + { + return $this->handle('PATCH', $node, $data, $responseClass); + } + + public function delete($node, $query, $responseClass) + { + return $this->handle('DELETE', $node, $query, $responseClass); + } + + public function getRequests() + { + return $this->requests; + } + + public function clearRequests() + { + $this->requests = []; + } + + private function handle($method, $node, $query, $responseClass) + { + array_push($this->requests, [ + $method, + $node, + $query, + $responseClass, + ]); + + return null; + } +} diff --git a/tests/Transformer/DefinitionConfigTransformerTest.php b/tests/Transformer/DefinitionConfigTransformerTest.php index b6dca12..ccf518e 100644 --- a/tests/Transformer/DefinitionConfigTransformerTest.php +++ b/tests/Transformer/DefinitionConfigTransformerTest.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code. @@ -17,47 +17,51 @@ class DefinitionConfigTransformerTest extends TestCase { + /** @return void */ public function testTransformWithoutChoices() { $config = [ 'a' => 'b', - 'c' => 'd' + 'c' => 'd', ]; $transformed = DefinitionConfigTransformer::transform($config); $this->assertEquals($config, $transformed); } + /** @return void */ public function testReverseTransformWithoutChoices() { $config = [ 'a' => 'b', - 'c' => 'd' + 'c' => 'd', ]; $transformed = DefinitionConfigTransformer::reverseTransform($config); $this->assertEquals($config, $transformed); } + /** @return void */ public function testTransformWithChoices() { $config = [ 'a' => 'b', 'c' => 'd', - 'Choices' => "red\ngreen\nblue" + 'Choices' => "red\ngreen\nblue", ]; $transformed = DefinitionConfigTransformer::transform($config); $this->assertEquals([ 'a' => 'b', 'c' => 'd', - 'Choices' => ["red", "green", "blue"] + 'Choices' => ["red", "green", "blue"], ], $transformed); } + /** @return void */ public function testReverseTransformWithChoices() { $config = [ 'a' => 'b', 'c' => 'd', - 'Choices' => ["red", "green", "blue"] + 'Choices' => ["red", "green", "blue"], ]; $transformed = DefinitionConfigTransformer::reverseTransform($config); $this->assertEquals([ diff --git a/tests/autoload.php b/tests/autoload.php index 4c9c37d..5443eeb 100644 --- a/tests/autoload.php +++ b/tests/autoload.php @@ -2,7 +2,7 @@ /** * This file is part of the Billbee API package. * - * Copyright 2017 - 2020 by Billbee GmbH + * Copyright 2017 - 2021 by Billbee GmbH * * For the full copyright and license information, please read the LICENSE * file that was distributed with this source code.