Skip to content

Commit

Permalink
Added forceToken support for pricing endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalSalon committed Feb 11, 2022
1 parent adbb569 commit 4f17f04
Show file tree
Hide file tree
Showing 9 changed files with 113 additions and 28 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 4.2.0 - 2022-02-10

### Added

- support for `forceToken` parameter for `updateProductPricing` and `updateVariantPricing` methods of `Article` client
- new `PriceProtectionException` thrown when API returns error with `PRICE_PROTECTION_ERROR` code, used to obtain force token using `getForceToken` method

## 4.1.0 - 2021-12-16

### Added
Expand Down
8 changes: 5 additions & 3 deletions doc/Article.md
Expand Up @@ -317,7 +317,7 @@ Example above prints out

## Update product pricing

Method expects `product` ID and [Pricing](../src/Article/Entity/Common/Pricing.php) entity and does not return anything.
Method expects `product` ID, [Pricing](../src/Article/Entity/Common/Pricing.php) entity and an optional `forceToken` and does not return anything.

```php
/** @var MpApiClient\Common\Interfaces\ArticleClientInterface $articleClient */
Expand Down Expand Up @@ -638,14 +638,16 @@ Example above prints out

## Update variant pricing

Method expects `product` and `variant` IDs and [Pricing](../src/Article/Entity/Common/Pricing.php) entity and does not return anything.
Method expects `product` and `variant` IDs, [Pricing](../src/Article/Entity/Common/Pricing.php) entity and an optional `forceToken` and does not return anything.

```php
/** @var MpApiClient\Common\Interfaces\ArticleClientInterface $articleClient */
/** @var MpApiClient\Exception\PriceProtectionException $e */
$articleClient->updateVariantPricing(
'my-product-id',
'my-variant-id',
new Pricing(99.9, 112.0, 80.5)
new Pricing(99.9, 112.0, 80.5),
$e->getForceToken()
);
```

Expand Down
22 changes: 22 additions & 0 deletions example/Article.php
Expand Up @@ -15,6 +15,7 @@
use MpApiClient\Article\Entity\Common\StatusEnum;
use MpApiClient\Common\Authenticators\ClientIdAuthenticator;
use MpApiClient\Exception\MpApiException;
use MpApiClient\Exception\PriceProtectionException;
use MpApiClient\Filter\Filter;
use MpApiClient\Filter\FilterItem;
use MpApiClient\Filter\FilterOperatorEnum;
Expand Down Expand Up @@ -231,6 +232,16 @@
'my-product-id',
new Pricing(99.9, 112.0, 80.5)
);
} catch (PriceProtectionException $e) {
try {
$client->article()->updateProductPricing(
'my-product-id',
new Pricing(99.9, 112.0, 80.5),
$e->getForceToken()
);
} catch (MpApiException $e) {
echo 'Unexpected error occurred during product pricing update with force token: ' . $e->getMessage();
}
} catch (MpApiException $e) {
echo 'Unexpected error occurred during product pricing update: ' . $e->getMessage();
}
Expand Down Expand Up @@ -429,6 +440,17 @@
'my-variant-id',
new Pricing(99.9, 112.0, 80.5)
);
} catch (PriceProtectionException $e) {
try {
$client->article()->updateVariantPricing(
'my-product-id',
'my-variant-id',
new Pricing(99.9, 112.0, 80.5),
$e->getForceToken()
);
} catch (MpApiException $e) {
echo 'Unexpected error occurred during variant pricing update with force token: ' . $e->getMessage();
}
} catch (MpApiException $e) {
echo 'Unexpected error occurred during variant pricing update: ' . $e->getMessage();
}
Expand Down
16 changes: 12 additions & 4 deletions src/Article/ArticleClient.php
Expand Up @@ -87,9 +87,13 @@ public function getProductPricing(string $productId): Pricing
);
}

public function updateProductPricing(string $productId, Pricing $pricing): void
public function updateProductPricing(string $productId, Pricing $pricing, ?string $forceToken = null): void
{
$this->sendJson('PUT', sprintf(self::PRODUCT_PRICING, $productId), $pricing->getArrayForApi());
$url = sprintf(self::PRODUCT_PRICING, $productId);
if ($forceToken !== null) {
$url = sprintf('%s?force_token=%s', $url, $forceToken);
}
$this->sendJson('PUT', $url, $pricing->getArrayForApi());
}

public function listProductVariants(string $productId, ?Filter $filter): BasicVariantList
Expand Down Expand Up @@ -144,9 +148,13 @@ public function getVariantPricing(string $productId, string $variantId): Pricing
);
}

public function updateVariantPricing(string $productId, string $variantId, Pricing $pricing): void
public function updateVariantPricing(string $productId, string $variantId, Pricing $pricing, ?string $forceToken = null): void
{
$this->sendJson('PUT', sprintf(self::VARIANT_PRICING, $productId, $variantId), $pricing->getArrayForApi());
$url = sprintf(self::VARIANT_PRICING, $productId, $variantId);
if ($forceToken !== null) {
$url = sprintf('%s?force_token=%s', $url, $forceToken);
}
$this->sendJson('PUT', $url, $pricing->getArrayForApi());
}

public function updateBatchAvailability(BatchAvailabilityIterator $availability): void
Expand Down
4 changes: 2 additions & 2 deletions src/Common/Interfaces/ArticleClientInterface.php
Expand Up @@ -59,7 +59,7 @@ public function getProductPricing(string $productId): Pricing;
* @throws MpApiException
* @deprecated Will be replaced with batch endpoint, similar to BatchAvailability
*/
public function updateProductPricing(string $productId, Pricing $pricing): void;
public function updateProductPricing(string $productId, Pricing $pricing, ?string $forceToken = null): void;

/**
* @throws MpApiException
Expand Down Expand Up @@ -102,7 +102,7 @@ public function getVariantPricing(string $productId, string $variantId): Pricing
* @throws MpApiException
* @deprecated Will be replaced with batch endpoint, similar to BatchAvailability
*/
public function updateVariantPricing(string $productId, string $variantId, Pricing $pricing): void;
public function updateVariantPricing(string $productId, string $variantId, Pricing $pricing, ?string $forceToken = null): void;

/**
* @throws MpApiException
Expand Down
56 changes: 39 additions & 17 deletions src/Exception/BadResponseException.php
Expand Up @@ -16,32 +16,54 @@ class BadResponseException extends MpApiException
private array $errorCodes;

/**
* @param string $message
* @param int $code
* @param Throwable|null $previous
* @param ErrorCode[] $errorCodes
* @var array<string, mixed>
*/
final private function __construct(string $message = '', int $code = 0, Throwable $previous = null, array $errorCodes = [])
private array $body;

/**
* @param string $message
* @param int $code
* @param Throwable|null $previous
* @param array<string, mixed> $body
* @param ErrorCode[] $errorCodes
*/
final private function __construct(string $message = '', int $code = 0, Throwable $previous = null, array $body = [], array $errorCodes = [])
{
parent::__construct($message, $code, $previous);
$this->body = $body;
$this->errorCodes = $errorCodes;
}

/**
* @param string $message
* @param int $code
* @param GuzzleBadResponseException $previous
* @param array<int, array<string, mixed>> $errorCodes
* @return static
* @param string $message
* @param int $code
* @param GuzzleBadResponseException $previous
* @param array<string, mixed> $body
* @return BadResponseException
*
* @internal
*/
public static function createFromGuzzle(string $message, int $code, GuzzleBadResponseException $previous, array $body = []): BadResponseException
{
$errorCodes = array_map(fn(array $item): ErrorCode => ErrorCode::createFromApi($item), $body['errorCodes'] ?? []);
if ($errorCodes === []) {
return new static($message, $code, $previous, $body);
}

switch ($errorCodes[0]->getCode()) {
case PriceProtectionException::ERROR_CODE:
return new PriceProtectionException($message, $code, $previous, $body, $errorCodes);
default:
return new static($message, $code, $previous, $body, $errorCodes);
}
}

/**
* @return array<string, mixed>
*/
public static function createFromGuzzle(string $message, int $code, GuzzleBadResponseException $previous, array $errorCodes = []): BadResponseException
public function getBody(): array
{
return new static(
$message,
$code,
$previous,
array_map(fn(array $item): ErrorCode => ErrorCode::createFromApi($item), $errorCodes),
);
return $this->body;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/ExceptionFactory.php
Expand Up @@ -39,7 +39,7 @@ public static function fromGuzzleBadResponse(GuzzleBadResponseException $e): MpA
return TooManyRequestsException::createFromGuzzle($message, $code, $e);
default:
/** @psalm-suppress PossiblyInvalidArgument - https://github.com/vimeo/psalm/issues/4295 */
return BadResponseException::createFromGuzzle($message, $code, $e, $body['errorCodes'] ?? []);
return BadResponseException::createFromGuzzle($message, $code, $e, $body);
}
}

Expand Down
24 changes: 24 additions & 0 deletions src/Exception/PriceProtectionException.php
@@ -0,0 +1,24 @@
<?php declare(strict_types=1);

namespace MpApiClient\Exception;

use LogicException;

final class PriceProtectionException extends BadResponseException
{

public const ERROR_CODE = 'PRICE_PROTECTION_ERROR';

/**
* @throws LogicException
*/
public function getForceToken(): string
{
if (!isset($this->getBody()['data']['data']['forceToken'])) {
throw new LogicException('forceToken not present in response');
}

return (string) $this->getBody()['data']['data']['forceToken'];
}

}
2 changes: 1 addition & 1 deletion src/MpApiClient.php
Expand Up @@ -29,7 +29,7 @@ final class MpApiClient implements ClientInterface, MpApiClientInterface
{

const APP_NAME = 'mp-api-client';
const APP_VERSION = '4.1.0';
const APP_VERSION = '4.2.0';

private BrandClientInterface $brandClient;
private CategoryClientInterface $categoryClient;
Expand Down

0 comments on commit 4f17f04

Please sign in to comment.