From bfff702e93b03e109402f5f2872869320abfdec5 Mon Sep 17 00:00:00 2001 From: Jesse Evers Date: Thu, 13 Jun 2024 18:39:38 -0400 Subject: [PATCH 1/5] Add debugToFile methods to SellingPartnerApi --- .github/workflows/php.yml | 2 +- README.md | 1 + src/SellingPartnerApi.php | 88 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 1 deletion(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index f9088459..2abdbb7c 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -1,4 +1,4 @@ -name: Validate and lint +name: Validate, lint, and test on: push: diff --git a/README.md b/README.md index d0839923..4d00757a 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,7 @@ $connector->debugRequest( Then make requests with the connector as usual, and you'll hit the closure above every time a request is fired. You can also debug responses in a similar fashion – check out the [Saloon docs](https://docs.saloon.dev/digging-deeper/debugging#debugging-responses) for more details. +If you want to output your debug data to a file, you can do so with the `SellingPartnerApi::debugRequestToFile()`, `SellingPartnerApi::debugResponseToFile()`, and `SellingPartnerApi::debugToFile()` methods. These methods all take an `$outputPath` argument and an optional `$die` argument. ## Supported API segments diff --git a/src/SellingPartnerApi.php b/src/SellingPartnerApi.php index 749b9fec..60a76f48 100644 --- a/src/SellingPartnerApi.php +++ b/src/SellingPartnerApi.php @@ -7,6 +7,7 @@ use DateTimeImmutable; use GuzzleHttp\Client; use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\ResponseInterface; use Saloon\Contracts\Authenticator; use Saloon\Contracts\OAuthAuthenticator; use Saloon\Exceptions\Request\RequestException; @@ -30,6 +31,9 @@ use SellingPartnerApi\Seller\TokensV20210301\Dto\CreateRestrictedDataTokenRequest; use SellingPartnerApi\Seller\TokensV20210301\Dto\RestrictedResource; use SellingPartnerApi\Vendor\VendorConnector; +use Symfony\Component\VarDumper\Cloner\VarCloner; +use Symfony\Component\VarDumper\Dumper\CliDumper; +use Symfony\Component\VarDumper\VarDumper; abstract class SellingPartnerApi extends Connector { @@ -189,6 +193,90 @@ public function getUserAgent(): string return "jlevers/selling-partner-api/v$version/php"; } + /** + * I couldn't find any great way of reusing the original Debugger::symfonyRequestDebugger() method from + * the Saloon package, so I'm just going to copy and paste the code here, but with the VarDumper + * configured to dump to a file. + */ + public function debugRequestToFile(string $outputPath, bool $die = false): static + { + return $this->debugRequest( + function (PendingRequest $pendingRequest, RequestInterface $psrRequest) use ($outputPath) { + $headers = []; + foreach ($psrRequest->getHeaders() as $headerName => $value) { + $headers[$headerName] = implode(';', $value); + } + + $className = explode('\\', $pendingRequest->getRequest()::class); + $label = end($className); + + VarDumper::setHandler(function ($var) use ($outputPath, $label) { + $file = fopen($outputPath, 'a'); + + $cloner = new VarCloner(); + $dumper = new CliDumper($file); + $cloned = $cloner->cloneVar($var) + ->withContext(['label' => 'Saloon Request('.$label.') ->']); + $dumper->dump($cloned); + + fclose($file); + }); + VarDumper::dump([ + 'connector' => $pendingRequest->getConnector()::class, + 'request' => $pendingRequest->getRequest()::class, + 'method' => $psrRequest->getMethod(), + 'uri' => (string) $psrRequest->getUri(), + 'headers' => $headers, + 'body' => (string) $psrRequest->getBody(), + ]); + }, + die: $die, + ); + } + + /** + * I couldn't find any great way of reusing the original Debugger::symfonyResponseDebugger() method from + * the Saloon package, so I'm just going to copy and paste the code here, but with the VarDumper + * configured to dump to a file. + */ + public function debugResponseToFile(string $outputPath, bool $die = false): static + { + return $this->debugResponse( + function (Response $response, ResponseInterface $psrResponse) use ($outputPath) { + $headers = []; + foreach ($psrResponse->getHeaders() as $headerName => $value) { + $headers[$headerName] = implode(';', $value); + } + + $className = explode('\\', $response->getRequest()::class); + $label = end($className); + + VarDumper::setHandler(function ($var) use ($outputPath, $label) { + $file = fopen($outputPath, 'a'); + + $cloner = new VarCloner(); + $dumper = new CliDumper($file); + $cloned = $cloner->cloneVar($var) + ->withContext(['label' => 'Saloon Response('.$label.') ->']); + $dumper->dump($cloned); + + fclose($file); + }); + VarDumper::dump([ + 'status' => $response->status(), + 'headers' => $headers, + 'body' => $response->body(), + ]); + }, + die: $die, + ); + } + + public function debugToFile(string $outputPath, bool $die = false): static + { + return $this->debugRequestToFile($outputPath)->debugResponseToFile($outputPath, $die); + } + public function getAccessToken( array $scopes = [], string $scopeSeparator = ' ', From c625e4e86695f18ad581890d7297d9b1a9b9129a Mon Sep 17 00:00:00 2001 From: Jesse Evers Date: Fri, 14 Jun 2024 11:19:01 -0400 Subject: [PATCH 2/5] Reintroduce zulu date formatting to HasArrayableAttributes --- src/Traits/HasArrayableAttributes.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Traits/HasArrayableAttributes.php b/src/Traits/HasArrayableAttributes.php index 2bcb7879..aebc65b5 100644 --- a/src/Traits/HasArrayableAttributes.php +++ b/src/Traits/HasArrayableAttributes.php @@ -61,7 +61,7 @@ public function valueToArray(mixed $value, array|string $type): mixed if (is_null($value)) { return null; } elseif ($value instanceof DateTimeInterface) { - return $value->format(DateTime::RFC3339); + return $this->toZuluString($value); } elseif (is_string($type)) { if (class_exists($type)) { return $value->toArray(); @@ -87,4 +87,9 @@ public function valueToArray(mixed $value, array|string $type): mixed throw new InvalidAttributeTypeException("Unrecognized attribute type `$type`"); } + + private function toZuluString(DateTimeInterface $dateTime) + { + return $dateTime->format('Y-m-d\TH:i:s\Z'); + } } From 5bb4ed0b1dba876d4b18373c19cd2ccab8827f22 Mon Sep 17 00:00:00 2001 From: Jesse Evers Date: Fri, 14 Jun 2024 14:59:58 -0400 Subject: [PATCH 3/5] Serialize and deserialize all dates with ISO-8601 format --- resources/generator-config.json | 3 +- src/Generator/Generators/RequestGenerator.php | 2 +- .../Requests/GetQueries.php | 4 +- .../FBAInboundV0/Requests/ConfirmPreorder.php | 2 +- .../Requests/GetShipmentItems.php | 4 +- .../FBAInboundV0/Requests/GetShipments.php | 4 +- .../Requests/GetInventorySummaries.php | 2 +- .../Requests/ListAllFulfillmentOrders.php | 2 +- .../FeedsV20210630/Requests/GetFeeds.php | 4 +- .../Requests/ListFinancialEventGroups.php | 4 +- .../Requests/ListFinancialEvents.php | 4 +- .../Requests/ListFinancialEventsByGroupId.php | 4 +- .../ReportsV20210630/Requests/GetReports.php | 4 +- src/Traits/Deserializes.php | 6 +- src/Traits/HasArrayableAttributes.php | 10 +-- .../Requests/GetOrders.php | 4 +- .../Requests/GetOrders.php | 4 +- .../Requests/GetCustomerInvoices.php | 4 +- .../Requests/GetPackingSlips.php | 4 +- .../Requests/GetShippingLabels.php | 4 +- .../Requests/GetCustomerInvoices.php | 4 +- .../Requests/GetPackingSlips.php | 4 +- .../Requests/GetShippingLabels.php | 4 +- .../OrdersV1/Requests/GetPurchaseOrders.php | 8 +- .../Requests/GetPurchaseOrdersStatus.php | 8 +- .../Requests/GetShipmentDetails.php | 32 ++++---- tests/SerializationTest.php | 81 +++++++++++++++++++ 27 files changed, 150 insertions(+), 70 deletions(-) diff --git a/resources/generator-config.json b/resources/generator-config.json index dedac60e..4a275b89 100644 --- a/resources/generator-config.json +++ b/resources/generator-config.json @@ -8,5 +8,6 @@ "baseFilesNamespace": "SellingPartnerApi", "namespaceSuffixes": { "resource": null - } + }, + "datetimeFormat": "Y-m-d\\TH:i:s\\Z" } diff --git a/src/Generator/Generators/RequestGenerator.php b/src/Generator/Generators/RequestGenerator.php index 851792f2..b15b4ccb 100644 --- a/src/Generator/Generators/RequestGenerator.php +++ b/src/Generator/Generators/RequestGenerator.php @@ -176,7 +176,7 @@ protected function generateRequestClass(Endpoint $endpoint): PhpFile if (SimpleType::isScalar($bodyType)) { $returnValText = '[$this->%s]'; } elseif ($bodyType === 'DateTime') { - $returnValText = '$this->%s->format(\DateTime::RFC3339)'; + $returnValText = '[$this->%s->format(\''.$this->config->datetimeFormat.'\')]'; } elseif (! Utils::isBuiltinType($bodyType)) { $returnValText = '$this->%s->toArray()'; } else { diff --git a/src/Seller/DataKioskV20231115/Requests/GetQueries.php b/src/Seller/DataKioskV20231115/Requests/GetQueries.php index 989d286a..5d40cb81 100644 --- a/src/Seller/DataKioskV20231115/Requests/GetQueries.php +++ b/src/Seller/DataKioskV20231115/Requests/GetQueries.php @@ -45,8 +45,8 @@ public function defaultQuery(): array return array_filter([ 'processingStatuses' => $this->processingStatuses, 'pageSize' => $this->pageSize, - 'createdSince' => $this->createdSince?->format(\DateTime::RFC3339), - 'createdUntil' => $this->createdUntil?->format(\DateTime::RFC3339), + 'createdSince' => $this->createdSince?->format('Y-m-d\TH:i:s\Z'), + 'createdUntil' => $this->createdUntil?->format('Y-m-d\TH:i:s\Z'), 'paginationToken' => $this->paginationToken, ]); } diff --git a/src/Seller/FBAInboundV0/Requests/ConfirmPreorder.php b/src/Seller/FBAInboundV0/Requests/ConfirmPreorder.php index c9bf4296..b8e151c4 100644 --- a/src/Seller/FBAInboundV0/Requests/ConfirmPreorder.php +++ b/src/Seller/FBAInboundV0/Requests/ConfirmPreorder.php @@ -37,7 +37,7 @@ public function __construct( public function defaultQuery(): array { - return array_filter(['NeedByDate' => $this->needByDate?->format(\DateTime::RFC3339), 'MarketplaceId' => $this->marketplaceId]); + return array_filter(['NeedByDate' => $this->needByDate?->format('Y-m-d\TH:i:s\Z'), 'MarketplaceId' => $this->marketplaceId]); } public function resolveEndpoint(): string diff --git a/src/Seller/FBAInboundV0/Requests/GetShipmentItems.php b/src/Seller/FBAInboundV0/Requests/GetShipmentItems.php index c7982c05..c4d0d3ca 100644 --- a/src/Seller/FBAInboundV0/Requests/GetShipmentItems.php +++ b/src/Seller/FBAInboundV0/Requests/GetShipmentItems.php @@ -44,8 +44,8 @@ public function defaultQuery(): array return array_filter([ 'QueryType' => $this->queryType, 'MarketplaceId' => $this->marketplaceId, - 'LastUpdatedAfter' => $this->lastUpdatedAfter?->format(\DateTime::RFC3339), - 'LastUpdatedBefore' => $this->lastUpdatedBefore?->format(\DateTime::RFC3339), + 'LastUpdatedAfter' => $this->lastUpdatedAfter?->format('Y-m-d\TH:i:s\Z'), + 'LastUpdatedBefore' => $this->lastUpdatedBefore?->format('Y-m-d\TH:i:s\Z'), 'NextToken' => $this->nextToken, ]); } diff --git a/src/Seller/FBAInboundV0/Requests/GetShipments.php b/src/Seller/FBAInboundV0/Requests/GetShipments.php index 66c08ba3..a89bef79 100644 --- a/src/Seller/FBAInboundV0/Requests/GetShipments.php +++ b/src/Seller/FBAInboundV0/Requests/GetShipments.php @@ -50,8 +50,8 @@ public function defaultQuery(): array 'MarketplaceId' => $this->marketplaceId, 'ShipmentStatusList' => $this->shipmentStatusList, 'ShipmentIdList' => $this->shipmentIdList, - 'LastUpdatedAfter' => $this->lastUpdatedAfter?->format(\DateTime::RFC3339), - 'LastUpdatedBefore' => $this->lastUpdatedBefore?->format(\DateTime::RFC3339), + 'LastUpdatedAfter' => $this->lastUpdatedAfter?->format('Y-m-d\TH:i:s\Z'), + 'LastUpdatedBefore' => $this->lastUpdatedBefore?->format('Y-m-d\TH:i:s\Z'), 'NextToken' => $this->nextToken, ]); } diff --git a/src/Seller/FBAInventoryV1/Requests/GetInventorySummaries.php b/src/Seller/FBAInventoryV1/Requests/GetInventorySummaries.php index 90ce38fb..be755efc 100644 --- a/src/Seller/FBAInventoryV1/Requests/GetInventorySummaries.php +++ b/src/Seller/FBAInventoryV1/Requests/GetInventorySummaries.php @@ -52,7 +52,7 @@ public function defaultQuery(): array 'granularityId' => $this->granularityId, 'marketplaceIds' => $this->marketplaceIds, 'details' => $this->details, - 'startDateTime' => $this->startDateTime?->format(\DateTime::RFC3339), + 'startDateTime' => $this->startDateTime?->format('Y-m-d\TH:i:s\Z'), 'sellerSkus' => $this->sellerSkus, 'sellerSku' => $this->sellerSku, 'nextToken' => $this->nextToken, diff --git a/src/Seller/FBAOutboundV20200701/Requests/ListAllFulfillmentOrders.php b/src/Seller/FBAOutboundV20200701/Requests/ListAllFulfillmentOrders.php index 7956de71..f242bf4f 100644 --- a/src/Seller/FBAOutboundV20200701/Requests/ListAllFulfillmentOrders.php +++ b/src/Seller/FBAOutboundV20200701/Requests/ListAllFulfillmentOrders.php @@ -35,7 +35,7 @@ public function __construct( public function defaultQuery(): array { - return array_filter(['queryStartDate' => $this->queryStartDate?->format(\DateTime::RFC3339), 'nextToken' => $this->nextToken]); + return array_filter(['queryStartDate' => $this->queryStartDate?->format('Y-m-d\TH:i:s\Z'), 'nextToken' => $this->nextToken]); } public function resolveEndpoint(): string diff --git a/src/Seller/FeedsV20210630/Requests/GetFeeds.php b/src/Seller/FeedsV20210630/Requests/GetFeeds.php index 8dc27955..b77370a6 100644 --- a/src/Seller/FeedsV20210630/Requests/GetFeeds.php +++ b/src/Seller/FeedsV20210630/Requests/GetFeeds.php @@ -51,8 +51,8 @@ public function defaultQuery(): array 'marketplaceIds' => $this->marketplaceIds, 'pageSize' => $this->pageSize, 'processingStatuses' => $this->processingStatuses, - 'createdSince' => $this->createdSince?->format(\DateTime::RFC3339), - 'createdUntil' => $this->createdUntil?->format(\DateTime::RFC3339), + 'createdSince' => $this->createdSince?->format('Y-m-d\TH:i:s\Z'), + 'createdUntil' => $this->createdUntil?->format('Y-m-d\TH:i:s\Z'), 'nextToken' => $this->nextToken, ]); } diff --git a/src/Seller/FinancesV0/Requests/ListFinancialEventGroups.php b/src/Seller/FinancesV0/Requests/ListFinancialEventGroups.php index 3207051d..de60fb96 100644 --- a/src/Seller/FinancesV0/Requests/ListFinancialEventGroups.php +++ b/src/Seller/FinancesV0/Requests/ListFinancialEventGroups.php @@ -41,8 +41,8 @@ public function defaultQuery(): array { return array_filter([ 'MaxResultsPerPage' => $this->maxResultsPerPage, - 'FinancialEventGroupStartedBefore' => $this->financialEventGroupStartedBefore?->format(\DateTime::RFC3339), - 'FinancialEventGroupStartedAfter' => $this->financialEventGroupStartedAfter?->format(\DateTime::RFC3339), + 'FinancialEventGroupStartedBefore' => $this->financialEventGroupStartedBefore?->format('Y-m-d\TH:i:s\Z'), + 'FinancialEventGroupStartedAfter' => $this->financialEventGroupStartedAfter?->format('Y-m-d\TH:i:s\Z'), 'NextToken' => $this->nextToken, ]); } diff --git a/src/Seller/FinancesV0/Requests/ListFinancialEvents.php b/src/Seller/FinancesV0/Requests/ListFinancialEvents.php index 967f1729..e981cb2a 100644 --- a/src/Seller/FinancesV0/Requests/ListFinancialEvents.php +++ b/src/Seller/FinancesV0/Requests/ListFinancialEvents.php @@ -41,8 +41,8 @@ public function defaultQuery(): array { return array_filter([ 'MaxResultsPerPage' => $this->maxResultsPerPage, - 'PostedAfter' => $this->postedAfter?->format(\DateTime::RFC3339), - 'PostedBefore' => $this->postedBefore?->format(\DateTime::RFC3339), + 'PostedAfter' => $this->postedAfter?->format('Y-m-d\TH:i:s\Z'), + 'PostedBefore' => $this->postedBefore?->format('Y-m-d\TH:i:s\Z'), 'NextToken' => $this->nextToken, ]); } diff --git a/src/Seller/FinancesV0/Requests/ListFinancialEventsByGroupId.php b/src/Seller/FinancesV0/Requests/ListFinancialEventsByGroupId.php index ab85f8d7..77db6259 100644 --- a/src/Seller/FinancesV0/Requests/ListFinancialEventsByGroupId.php +++ b/src/Seller/FinancesV0/Requests/ListFinancialEventsByGroupId.php @@ -43,8 +43,8 @@ public function defaultQuery(): array { return array_filter([ 'MaxResultsPerPage' => $this->maxResultsPerPage, - 'PostedAfter' => $this->postedAfter?->format(\DateTime::RFC3339), - 'PostedBefore' => $this->postedBefore?->format(\DateTime::RFC3339), + 'PostedAfter' => $this->postedAfter?->format('Y-m-d\TH:i:s\Z'), + 'PostedBefore' => $this->postedBefore?->format('Y-m-d\TH:i:s\Z'), 'NextToken' => $this->nextToken, ]); } diff --git a/src/Seller/ReportsV20210630/Requests/GetReports.php b/src/Seller/ReportsV20210630/Requests/GetReports.php index effeecdf..09e5ec06 100644 --- a/src/Seller/ReportsV20210630/Requests/GetReports.php +++ b/src/Seller/ReportsV20210630/Requests/GetReports.php @@ -51,8 +51,8 @@ public function defaultQuery(): array 'processingStatuses' => $this->processingStatuses, 'marketplaceIds' => $this->marketplaceIds, 'pageSize' => $this->pageSize, - 'createdSince' => $this->createdSince?->format(\DateTime::RFC3339), - 'createdUntil' => $this->createdUntil?->format(\DateTime::RFC3339), + 'createdSince' => $this->createdSince?->format('Y-m-d\TH:i:s\Z'), + 'createdUntil' => $this->createdUntil?->format('Y-m-d\TH:i:s\Z'), 'nextToken' => $this->nextToken, ]); } diff --git a/src/Traits/Deserializes.php b/src/Traits/Deserializes.php index e62bf153..5c1e3a2d 100644 --- a/src/Traits/Deserializes.php +++ b/src/Traits/Deserializes.php @@ -12,6 +12,8 @@ trait Deserializes { use HasComplexArrayTypes; + protected static string $datetimeFormat = 'Y-m-d\TH:i:s\Z'; + public static function deserialize(mixed $data): mixed { if (is_null($data)) { @@ -69,7 +71,7 @@ protected static function deserializeValue(mixed $value, array|string $type): mi 'float' => (float) $value, 'bool' => (bool) $value, 'string' => (string) $value, - 'date', 'datetime' => DateTime::createFromFormat(DateTime::RFC3339, $value), + 'date', 'datetime' => DateTime::createFromFormat(static::$datetimeFormat, $value), 'array', 'mixed' => $value, 'null' => null, default => chr(0), @@ -82,7 +84,7 @@ protected static function deserializeValue(mixed $value, array|string $type): mi if (! class_exists($type)) { throw new InvalidAttributeTypeException("Class `$type` does not exist"); } elseif ($type === DateTime::class) { - return DateTime::createFromFormat(DateTime::RFC3339, $value); + return DateTime::createFromFormat(static::$datetimeFormat, $value); } $deserialized = $type::deserialize($value); diff --git a/src/Traits/HasArrayableAttributes.php b/src/Traits/HasArrayableAttributes.php index aebc65b5..41dbcc0c 100644 --- a/src/Traits/HasArrayableAttributes.php +++ b/src/Traits/HasArrayableAttributes.php @@ -4,7 +4,6 @@ namespace SellingPartnerApi\Traits; -use DateTime; use DateTimeInterface; use ReflectionClass; use SellingPartnerApi\Exceptions\InvalidAttributeTypeException; @@ -13,6 +12,8 @@ trait HasArrayableAttributes { use HasComplexArrayTypes; + protected static string $datetimeFormat = 'Y-m-d\TH:i:s\Z'; + /** * @var array{string, string} * @@ -61,7 +62,7 @@ public function valueToArray(mixed $value, array|string $type): mixed if (is_null($value)) { return null; } elseif ($value instanceof DateTimeInterface) { - return $this->toZuluString($value); + return $value->format(static::$datetimeFormat); } elseif (is_string($type)) { if (class_exists($type)) { return $value->toArray(); @@ -87,9 +88,4 @@ public function valueToArray(mixed $value, array|string $type): mixed throw new InvalidAttributeTypeException("Unrecognized attribute type `$type`"); } - - private function toZuluString(DateTimeInterface $dateTime) - { - return $dateTime->format('Y-m-d\TH:i:s\Z'); - } } diff --git a/src/Vendor/DirectFulfillmentOrdersV1/Requests/GetOrders.php b/src/Vendor/DirectFulfillmentOrdersV1/Requests/GetOrders.php index 091e8dac..16a8924d 100644 --- a/src/Vendor/DirectFulfillmentOrdersV1/Requests/GetOrders.php +++ b/src/Vendor/DirectFulfillmentOrdersV1/Requests/GetOrders.php @@ -51,8 +51,8 @@ public function __construct( public function defaultQuery(): array { return array_filter([ - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), 'shipFromPartyId' => $this->shipFromPartyId, 'status' => $this->status, 'limit' => $this->limit, diff --git a/src/Vendor/DirectFulfillmentOrdersV20211228/Requests/GetOrders.php b/src/Vendor/DirectFulfillmentOrdersV20211228/Requests/GetOrders.php index 77dba1cf..ac8ec107 100644 --- a/src/Vendor/DirectFulfillmentOrdersV20211228/Requests/GetOrders.php +++ b/src/Vendor/DirectFulfillmentOrdersV20211228/Requests/GetOrders.php @@ -52,8 +52,8 @@ public function __construct( public function defaultQuery(): array { return array_filter([ - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), 'shipFromPartyId' => $this->shipFromPartyId, 'status' => $this->status, 'limit' => $this->limit, diff --git a/src/Vendor/DirectFulfillmentShippingV1/Requests/GetCustomerInvoices.php b/src/Vendor/DirectFulfillmentShippingV1/Requests/GetCustomerInvoices.php index 7a879332..cfd9bd56 100644 --- a/src/Vendor/DirectFulfillmentShippingV1/Requests/GetCustomerInvoices.php +++ b/src/Vendor/DirectFulfillmentShippingV1/Requests/GetCustomerInvoices.php @@ -48,8 +48,8 @@ public function __construct( public function defaultQuery(): array { return array_filter([ - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), 'shipFromPartyId' => $this->shipFromPartyId, 'limit' => $this->limit, 'sortOrder' => $this->sortOrder, diff --git a/src/Vendor/DirectFulfillmentShippingV1/Requests/GetPackingSlips.php b/src/Vendor/DirectFulfillmentShippingV1/Requests/GetPackingSlips.php index 751f8bc1..350b178d 100644 --- a/src/Vendor/DirectFulfillmentShippingV1/Requests/GetPackingSlips.php +++ b/src/Vendor/DirectFulfillmentShippingV1/Requests/GetPackingSlips.php @@ -47,8 +47,8 @@ public function __construct( public function defaultQuery(): array { return array_filter([ - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), 'shipFromPartyId' => $this->shipFromPartyId, 'limit' => $this->limit, 'sortOrder' => $this->sortOrder, diff --git a/src/Vendor/DirectFulfillmentShippingV1/Requests/GetShippingLabels.php b/src/Vendor/DirectFulfillmentShippingV1/Requests/GetShippingLabels.php index 5d6da398..f9419f22 100644 --- a/src/Vendor/DirectFulfillmentShippingV1/Requests/GetShippingLabels.php +++ b/src/Vendor/DirectFulfillmentShippingV1/Requests/GetShippingLabels.php @@ -44,8 +44,8 @@ public function __construct( public function defaultQuery(): array { return array_filter([ - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), 'shipFromPartyId' => $this->shipFromPartyId, 'limit' => $this->limit, 'sortOrder' => $this->sortOrder, diff --git a/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetCustomerInvoices.php b/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetCustomerInvoices.php index 3d4b4de4..fb3c7dfd 100644 --- a/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetCustomerInvoices.php +++ b/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetCustomerInvoices.php @@ -48,8 +48,8 @@ public function __construct( public function defaultQuery(): array { return array_filter([ - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), 'shipFromPartyId' => $this->shipFromPartyId, 'limit' => $this->limit, 'sortOrder' => $this->sortOrder, diff --git a/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetPackingSlips.php b/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetPackingSlips.php index 390c1319..93ecd8d8 100644 --- a/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetPackingSlips.php +++ b/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetPackingSlips.php @@ -48,8 +48,8 @@ public function __construct( public function defaultQuery(): array { return array_filter([ - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), 'shipFromPartyId' => $this->shipFromPartyId, 'limit' => $this->limit, 'sortOrder' => $this->sortOrder, diff --git a/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetShippingLabels.php b/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetShippingLabels.php index 47e2b9cf..26f793b4 100644 --- a/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetShippingLabels.php +++ b/src/Vendor/DirectFulfillmentShippingV20211228/Requests/GetShippingLabels.php @@ -48,8 +48,8 @@ public function __construct( public function defaultQuery(): array { return array_filter([ - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), 'shipFromPartyId' => $this->shipFromPartyId, 'limit' => $this->limit, 'sortOrder' => $this->sortOrder, diff --git a/src/Vendor/OrdersV1/Requests/GetPurchaseOrders.php b/src/Vendor/OrdersV1/Requests/GetPurchaseOrders.php index 6c2cc6c0..5728015d 100644 --- a/src/Vendor/OrdersV1/Requests/GetPurchaseOrders.php +++ b/src/Vendor/OrdersV1/Requests/GetPurchaseOrders.php @@ -57,13 +57,13 @@ public function defaultQuery(): array { return array_filter([ 'limit' => $this->limit, - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), 'sortOrder' => $this->sortOrder, 'nextToken' => $this->nextToken, 'includeDetails' => $this->includeDetails, - 'changedAfter' => $this->changedAfter?->format(\DateTime::RFC3339), - 'changedBefore' => $this->changedBefore?->format(\DateTime::RFC3339), + 'changedAfter' => $this->changedAfter?->format('Y-m-d\TH:i:s\Z'), + 'changedBefore' => $this->changedBefore?->format('Y-m-d\TH:i:s\Z'), 'poItemState' => $this->poItemState, 'isPOChanged' => $this->isPoChanged, 'purchaseOrderState' => $this->purchaseOrderState, diff --git a/src/Vendor/OrdersV1/Requests/GetPurchaseOrdersStatus.php b/src/Vendor/OrdersV1/Requests/GetPurchaseOrdersStatus.php index 166b78ff..7f46416e 100644 --- a/src/Vendor/OrdersV1/Requests/GetPurchaseOrdersStatus.php +++ b/src/Vendor/OrdersV1/Requests/GetPurchaseOrdersStatus.php @@ -61,10 +61,10 @@ public function defaultQuery(): array 'limit' => $this->limit, 'sortOrder' => $this->sortOrder, 'nextToken' => $this->nextToken, - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), - 'updatedAfter' => $this->updatedAfter?->format(\DateTime::RFC3339), - 'updatedBefore' => $this->updatedBefore?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), + 'updatedAfter' => $this->updatedAfter?->format('Y-m-d\TH:i:s\Z'), + 'updatedBefore' => $this->updatedBefore?->format('Y-m-d\TH:i:s\Z'), 'purchaseOrderNumber' => $this->purchaseOrderNumber, 'purchaseOrderStatus' => $this->purchaseOrderStatus, 'itemConfirmationStatus' => $this->itemConfirmationStatus, diff --git a/src/Vendor/ShipmentsV1/Requests/GetShipmentDetails.php b/src/Vendor/ShipmentsV1/Requests/GetShipmentDetails.php index 55f76c76..5d5cf309 100644 --- a/src/Vendor/ShipmentsV1/Requests/GetShipmentDetails.php +++ b/src/Vendor/ShipmentsV1/Requests/GetShipmentDetails.php @@ -83,22 +83,22 @@ public function defaultQuery(): array 'limit' => $this->limit, 'sortOrder' => $this->sortOrder, 'nextToken' => $this->nextToken, - 'createdAfter' => $this->createdAfter?->format(\DateTime::RFC3339), - 'createdBefore' => $this->createdBefore?->format(\DateTime::RFC3339), - 'shipmentConfirmedBefore' => $this->shipmentConfirmedBefore?->format(\DateTime::RFC3339), - 'shipmentConfirmedAfter' => $this->shipmentConfirmedAfter?->format(\DateTime::RFC3339), - 'packageLabelCreatedBefore' => $this->packageLabelCreatedBefore?->format(\DateTime::RFC3339), - 'packageLabelCreatedAfter' => $this->packageLabelCreatedAfter?->format(\DateTime::RFC3339), - 'shippedBefore' => $this->shippedBefore?->format(\DateTime::RFC3339), - 'shippedAfter' => $this->shippedAfter?->format(\DateTime::RFC3339), - 'estimatedDeliveryBefore' => $this->estimatedDeliveryBefore?->format(\DateTime::RFC3339), - 'estimatedDeliveryAfter' => $this->estimatedDeliveryAfter?->format(\DateTime::RFC3339), - 'shipmentDeliveryBefore' => $this->shipmentDeliveryBefore?->format(\DateTime::RFC3339), - 'shipmentDeliveryAfter' => $this->shipmentDeliveryAfter?->format(\DateTime::RFC3339), - 'requestedPickUpBefore' => $this->requestedPickUpBefore?->format(\DateTime::RFC3339), - 'requestedPickUpAfter' => $this->requestedPickUpAfter?->format(\DateTime::RFC3339), - 'scheduledPickUpBefore' => $this->scheduledPickUpBefore?->format(\DateTime::RFC3339), - 'scheduledPickUpAfter' => $this->scheduledPickUpAfter?->format(\DateTime::RFC3339), + 'createdAfter' => $this->createdAfter?->format('Y-m-d\TH:i:s\Z'), + 'createdBefore' => $this->createdBefore?->format('Y-m-d\TH:i:s\Z'), + 'shipmentConfirmedBefore' => $this->shipmentConfirmedBefore?->format('Y-m-d\TH:i:s\Z'), + 'shipmentConfirmedAfter' => $this->shipmentConfirmedAfter?->format('Y-m-d\TH:i:s\Z'), + 'packageLabelCreatedBefore' => $this->packageLabelCreatedBefore?->format('Y-m-d\TH:i:s\Z'), + 'packageLabelCreatedAfter' => $this->packageLabelCreatedAfter?->format('Y-m-d\TH:i:s\Z'), + 'shippedBefore' => $this->shippedBefore?->format('Y-m-d\TH:i:s\Z'), + 'shippedAfter' => $this->shippedAfter?->format('Y-m-d\TH:i:s\Z'), + 'estimatedDeliveryBefore' => $this->estimatedDeliveryBefore?->format('Y-m-d\TH:i:s\Z'), + 'estimatedDeliveryAfter' => $this->estimatedDeliveryAfter?->format('Y-m-d\TH:i:s\Z'), + 'shipmentDeliveryBefore' => $this->shipmentDeliveryBefore?->format('Y-m-d\TH:i:s\Z'), + 'shipmentDeliveryAfter' => $this->shipmentDeliveryAfter?->format('Y-m-d\TH:i:s\Z'), + 'requestedPickUpBefore' => $this->requestedPickUpBefore?->format('Y-m-d\TH:i:s\Z'), + 'requestedPickUpAfter' => $this->requestedPickUpAfter?->format('Y-m-d\TH:i:s\Z'), + 'scheduledPickUpBefore' => $this->scheduledPickUpBefore?->format('Y-m-d\TH:i:s\Z'), + 'scheduledPickUpAfter' => $this->scheduledPickUpAfter?->format('Y-m-d\TH:i:s\Z'), 'currentShipmentStatus' => $this->currentShipmentStatus, 'vendorShipmentIdentifier' => $this->vendorShipmentIdentifier, 'buyerReferenceNumber' => $this->buyerReferenceNumber, diff --git a/tests/SerializationTest.php b/tests/SerializationTest.php index 0cb7c511..f065d6c7 100644 --- a/tests/SerializationTest.php +++ b/tests/SerializationTest.php @@ -7,6 +7,10 @@ use Saloon\Http\Faking\MockResponse; use SellingPartnerApi\Authentication\GetAccessTokenRequest; use SellingPartnerApi\Enums\Endpoint; +use SellingPartnerApi\Seller\FBAInventoryV1\Requests\GetInventorySummaries; +use SellingPartnerApi\Seller\OrdersV0\Dto\ConfirmShipmentRequest; +use SellingPartnerApi\Seller\OrdersV0\Dto\PackageDetail; +use SellingPartnerApi\Seller\OrdersV0\Requests\ConfirmShipment; use SellingPartnerApi\Seller\ProductPricingV0\Dto\GetItemOffersBatchRequest; use SellingPartnerApi\Seller\ProductPricingV0\Dto\ItemOffersRequest; use SellingPartnerApi\Seller\ProductPricingV0\Requests\GetItemOffersBatch; @@ -83,4 +87,81 @@ public function testNullValuesAreRemovedFromSerialization(): void $mockClient->getLastPendingRequest()->body()->all() ); } + + public function testDatesInQueryParametersAreSerializedInZuluFormat(): void + { + $mockClient = new MockClient([ + GetAccessTokenRequest::class => MockResponse::make( + body: [ + 'access_token' => 'access-token', + 'refresh_token' => 'refresh-token', + 'expires_in' => 3600, + 'token_type' => 'bearer', + ], + ), + GetInventorySummaries::class => MockResponse::make(), + ]); + + $connector = SellingPartnerApi::seller( + clientId: 'client-id', + clientSecret: 'client-secret', + refreshToken: 'refresh-token', + endpoint: Endpoint::NA_SANDBOX, + ); + $connector->withMockClient($mockClient); + + $api = $connector->fbaInventoryV1(); + $api->getInventorySummaries( + granularityType: 'Marketplace', + granularityId: 'marketplace-id', + marketplaceIds: ['marketplace-id'], + startDateTime: new DateTimeImmutable('2024-01-01') + ); + + $query = $mockClient->getLastPendingRequest()->query(); + + $this->assertEquals('2024-01-01T00:00:00Z', $query->get('startDateTime')); + } + + public function testDatesInBodyParametersAreSerializedInZuluFormat(): void + { + $mockClient = new MockClient([ + GetAccessTokenRequest::class => MockResponse::make( + body: [ + 'access_token' => 'access-token', + 'refresh_token' => 'refresh-token', + 'expires_in' => 3600, + 'token_type' => 'bearer', + ], + ), + ConfirmShipment::class => MockResponse::make(), + ]); + + $connector = SellingPartnerApi::seller( + clientId: 'client-id', + clientSecret: 'client-secret', + refreshToken: 'refresh-token', + endpoint: Endpoint::NA_SANDBOX, + ); + $connector->withMockClient($mockClient); + + $api = $connector->ordersV0(); + $api->confirmShipment( + 'order-id', + new ConfirmShipmentRequest( + new PackageDetail( + packageReferenceId: 'package-reference-id', + carrierCode: 'carrier-code', + trackingNumber: 'tracking-number', + shipDate: new DateTimeImmutable('2024-01-01'), + orderItems: [], + ), + 'marketplace-id', + ) + ); + + $body = $mockClient->getLastPendingRequest()->body()->all(); + + $this->assertEquals('2024-01-01T00:00:00Z', $body['packageDetail']['shipDate']); + } } From cf1394851b7ab5aef75e635d82d8c4500d07fd33 Mon Sep 17 00:00:00 2001 From: Jesse Evers Date: Fri, 14 Jun 2024 15:12:04 -0400 Subject: [PATCH 4/5] Update CatalogItemsV20220401 with ItemBrowseClassificationsByMarketplace --- .../seller/catalog-items/v2022-04-01.json | 143 +++++++++++++++++- .../CatalogItemsV0/Dto/RelationshipType.php | 6 +- .../Dto/ItemBrowseClassification.php | 4 +- ...ItemBrowseClassificationsByMarketplace.php | 28 ++++ .../CatalogItemsV20220401/Responses/Item.php | 4 + 5 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 src/Seller/CatalogItemsV20220401/Dto/ItemBrowseClassificationsByMarketplace.php diff --git a/resources/models/seller/catalog-items/v2022-04-01.json b/resources/models/seller/catalog-items/v2022-04-01.json index 567d45b5..39902a02 100644 --- a/resources/models/seller/catalog-items/v2022-04-01.json +++ b/resources/models/seller/catalog-items/v2022-04-01.json @@ -24,7 +24,7 @@ "tags": [ "CatalogItemsV20220401" ], - "description": "Search for and return a list of Amazon catalog items and associated information either by identifier or by keywords.\n\n**Usage Plans:**\n\n| Rate (requests per second) | Burst |\n| ---- | ---- |\n| 2 | 2 |\n\nThe `x-amzn-RateLimit-Limit` response header returns the usage plan rate limits that were applied to the requested operation, when available. The table above indicates the default rate and burst values for this operation. Selling partners whose business demands require higher throughput may observe higher rate and burst values than those shown here. For more information, refer to the [Usage Plans and Rate Limits in the Selling Partner API](doc:usage-plans-and-rate-limits-in-the-sp-api).", + "description": "Search for and return a list of Amazon catalog items and associated information either by identifier or by keywords.\n\n**Usage Plans:**\n\n| Rate (requests per second) | Burst |\n| ---- | ---- |\n| 5 | 5 |\n\nThe `x-amzn-RateLimit-Limit` response header returns the usage plan rate limits that were applied to the requested operation, when available. The table above indicates the default rate and burst values for this operation. Selling partners whose business demands require higher throughput may observe higher rate and burst values than those shown here. For more information, refer to the [Usage Plans and Rate Limits in the Selling Partner API](doc:usage-plans-and-rate-limits-in-the-sp-api).", "operationId": "searchCatalogItems", "parameters": [ { @@ -157,6 +157,7 @@ "type": "string", "enum": [ "attributes", + "classifications", "dimensions", "identifiers", "images", @@ -171,6 +172,10 @@ "value": "attributes", "description": "A JSON object containing structured item attribute data keyed by attribute name. Catalog item attributes conform to the related Amazon product type definitions available in the Selling Partner API for Product Type Definitions." }, + { + "value": "classifications", + "description": "Classifications (browse nodes) for an item in the Amazon catalog." + }, { "value": "dimensions", "description": "Dimensions for an item in the Amazon catalog." @@ -844,6 +849,29 @@ } ] }, + "classifications": [ + { + "marketplaceId": "ATVPDKIKX0DER", + "classifications": [ + { + "displayName": "QLED TVs", + "classificationId": "21489946011", + "parent": { + "displayName": "Televisions", + "classificationId": "172659", + "parent": { + "displayName": "Television & Video", + "classificationId": "1266092011", + "parent": { + "displayName": "Electronics", + "classificationId": "172282" + } + } + } + } + ] + } + ], "dimensions": [ { "marketplaceId": "ATVPDKIKX0DER", @@ -1188,6 +1216,7 @@ }, "includedData": { "value": [ + "classifications", "dimensions", "identifiers", "images", @@ -1224,6 +1253,29 @@ "items": [ { "asin": "B07N4M94X4", + "classifications": [ + { + "marketplaceId": "ATVPDKIKX0DER", + "classifications": [ + { + "displayName": "QLED TVs", + "classificationId": "21489946011", + "parent": { + "displayName": "Televisions", + "classificationId": "172659", + "parent": { + "displayName": "Television & Video", + "classificationId": "1266092011", + "parent": { + "displayName": "Electronics", + "classificationId": "172282" + } + } + } + } + ] + } + ], "dimensions": [ { "marketplaceId": "ATVPDKIKX0DER", @@ -1716,7 +1768,7 @@ "tags": [ "CatalogItemsV20220401" ], - "description": "Retrieves details for an item in the Amazon catalog.\n\n**Usage Plan:**\n\n| Rate (requests per second) | Burst |\n| ---- | ---- |\n| 2 | 2 |\n\nThe `x-amzn-RateLimit-Limit` response header returns the usage plan rate limits that were applied to the requested operation, when available. The table above indicates the default rate and burst values for this operation. Selling partners whose business demands require higher throughput may observe higher rate and burst values than those shown here. For more information, refer to the [Usage Plans and Rate Limits in the Selling Partner API](doc:usage-plans-and-rate-limits-in-the-sp-api).", + "description": "Retrieves details for an item in the Amazon catalog.\n\n**Usage Plan:**\n\n| Rate (requests per second) | Burst |\n| ---- | ---- |\n| 5 | 5 |\n\nThe `x-amzn-RateLimit-Limit` response header returns the usage plan rate limits that were applied to the requested operation, when available. The table above indicates the default rate and burst values for this operation. Selling partners whose business demands require higher throughput may observe higher rate and burst values than those shown here. For more information, refer to the [Usage Plans and Rate Limits in the Selling Partner API](doc:usage-plans-and-rate-limits-in-the-sp-api).", "operationId": "getCatalogItem", "parameters": [ { @@ -1755,6 +1807,7 @@ "type": "string", "enum": [ "attributes", + "classifications", "dimensions", "identifiers", "images", @@ -1769,6 +1822,10 @@ "value": "attributes", "description": "A JSON object containing structured item attribute data keyed by attribute name. Catalog item attributes conform to the related Amazon product type definitions available in the Selling Partner API for Product Type Definitions." }, + { + "value": "classifications", + "description": "Classifications (browse nodes) for an item in the Amazon catalog." + }, { "value": "dimensions", "description": "Dimensions for an item in the Amazon catalog." @@ -2340,6 +2397,29 @@ } ] }, + "classifications": [ + { + "marketplaceId": "ATVPDKIKX0DER", + "classifications": [ + { + "displayName": "QLED TVs", + "classificationId": "21489946011", + "parent": { + "displayName": "Televisions", + "classificationId": "172659", + "parent": { + "displayName": "Television & Video", + "classificationId": "1266092011", + "parent": { + "displayName": "Electronics", + "classificationId": "172282" + } + } + } + } + ] + } + ], "dimensions": [ { "marketplaceId": "ATVPDKIKX0DER", @@ -2679,6 +2759,7 @@ }, "includedData": { "value": [ + "classifications", "dimensions", "identifiers", "images", @@ -2693,6 +2774,29 @@ }, "response": { "asin": "B07N4M94X4", + "classifications": [ + { + "marketplaceId": "ATVPDKIKX0DER", + "classifications": [ + { + "displayName": "QLED TVs", + "classificationId": "21489946011", + "parent": { + "displayName": "Televisions", + "classificationId": "172659", + "parent": { + "displayName": "Television & Video", + "classificationId": "1266092011", + "parent": { + "displayName": "Electronics", + "classificationId": "172282" + } + } + } + } + ] + } + ], "dimensions": [ { "marketplaceId": "ATVPDKIKX0DER", @@ -3230,6 +3334,9 @@ "attributes": { "$ref": "#/components/schemas/ItemAttributes" }, + "classifications": { + "$ref": "#/components/schemas/ItemBrowseClassifications" + }, "dimensions": { "$ref": "#/components/schemas/ItemDimensions" }, @@ -3275,11 +3382,14 @@ "properties": { "displayName": { "type": "string", - "description": "Display name for the classification." + "description": "Display name for the classification (browse node)." }, "classificationId": { "type": "string", "description": "Identifier of the classification (browse node identifier)." + }, + "parent": { + "$ref": "#/components/schemas/ItemBrowseClassification" } }, "description": "Classification (browse node) associated with an Amazon catalog item." @@ -3318,6 +3428,33 @@ }, "description": "Role of an individual contributor in the creation of an item, such as author or actor." }, + "ItemBrowseClassifications": { + "type": "array", + "description": "Array of classifications (browse nodes) associated with the item in the Amazon catalog by Amazon marketplace.", + "items": { + "$ref": "#/components/schemas/ItemBrowseClassificationsByMarketplace" + } + }, + "ItemBrowseClassificationsByMarketplace": { + "required": [ + "marketplaceId" + ], + "type": "object", + "properties": { + "marketplaceId": { + "type": "string", + "description": "Amazon marketplace identifier." + }, + "classifications": { + "type": "array", + "description": "Classifications (browse nodes) associated with the item in the Amazon catalog for the indicated Amazon marketplace.", + "items": { + "$ref": "#/components/schemas/ItemBrowseClassification" + } + } + }, + "description": "Classifications (browse nodes) associated with the item in the Amazon catalog for the indicated Amazon marketplace." + }, "Dimension": { "type": "object", "properties": { diff --git a/src/Seller/CatalogItemsV0/Dto/RelationshipType.php b/src/Seller/CatalogItemsV0/Dto/RelationshipType.php index 42c715aa..0edcbfd4 100644 --- a/src/Seller/CatalogItemsV0/Dto/RelationshipType.php +++ b/src/Seller/CatalogItemsV0/Dto/RelationshipType.php @@ -45,14 +45,14 @@ final class RelationshipType extends Dto * @param ?string $color The color variation of the item. * @param ?string $edition The edition variation of the item. * @param ?string $flavor The flavor variation of the item. - * @param ?string[] $gemType The gem type attributes of the item. + * @param ?string[] $gemType The gem type variations of the item. * @param ?string $golfClubFlex The golf club flex variation of an item. * @param ?string $handOrientation The hand orientation variation of an item. * @param ?string $hardwarePlatform The hardware platform variation of an item. - * @param ?string[] $materialType The material type attributes of the item. + * @param ?string[] $materialType The material type variations of an item. * @param ?string $metalType The metal type variation of an item. * @param ?string $model The model variation of an item. - * @param ?string[] $operatingSystem The operating system attributes of the item. + * @param ?string[] $operatingSystem The operating system variations of an item. * @param ?string $productTypeSubcategory The product type subcategory variation of an item. * @param ?string $ringSize The ring size variation of an item. * @param ?string $shaftMaterial The shaft material variation of an item. diff --git a/src/Seller/CatalogItemsV20220401/Dto/ItemBrowseClassification.php b/src/Seller/CatalogItemsV20220401/Dto/ItemBrowseClassification.php index 89d7fb97..cb479782 100644 --- a/src/Seller/CatalogItemsV20220401/Dto/ItemBrowseClassification.php +++ b/src/Seller/CatalogItemsV20220401/Dto/ItemBrowseClassification.php @@ -15,12 +15,14 @@ final class ItemBrowseClassification extends Dto { /** - * @param string $displayName Display name for the classification. + * @param string $displayName Display name for the classification (browse node). * @param string $classificationId Identifier of the classification (browse node identifier). + * @param ?ItemBrowseClassification $parent Classification (browse node) associated with an Amazon catalog item. */ public function __construct( public readonly string $displayName, public readonly string $classificationId, + public readonly ?ItemBrowseClassification $parent = null, ) { } } diff --git a/src/Seller/CatalogItemsV20220401/Dto/ItemBrowseClassificationsByMarketplace.php b/src/Seller/CatalogItemsV20220401/Dto/ItemBrowseClassificationsByMarketplace.php new file mode 100644 index 00000000..a786fd83 --- /dev/null +++ b/src/Seller/CatalogItemsV20220401/Dto/ItemBrowseClassificationsByMarketplace.php @@ -0,0 +1,28 @@ + [ItemBrowseClassification::class]]; + + /** + * @param string $marketplaceId Amazon marketplace identifier. + * @param ItemBrowseClassification[]|null $classifications Classifications (browse nodes) associated with the item in the Amazon catalog for the indicated Amazon marketplace. + */ + public function __construct( + public readonly string $marketplaceId, + public readonly ?array $classifications = null, + ) { + } +} diff --git a/src/Seller/CatalogItemsV20220401/Responses/Item.php b/src/Seller/CatalogItemsV20220401/Responses/Item.php index 143efc0c..cf562eb5 100644 --- a/src/Seller/CatalogItemsV20220401/Responses/Item.php +++ b/src/Seller/CatalogItemsV20220401/Responses/Item.php @@ -11,6 +11,7 @@ namespace SellingPartnerApi\Seller\CatalogItemsV20220401\Responses; use SellingPartnerApi\Response; +use SellingPartnerApi\Seller\CatalogItemsV20220401\Dto\ItemBrowseClassificationsByMarketplace; use SellingPartnerApi\Seller\CatalogItemsV20220401\Dto\ItemDimensionsByMarketplace; use SellingPartnerApi\Seller\CatalogItemsV20220401\Dto\ItemIdentifiersByMarketplace; use SellingPartnerApi\Seller\CatalogItemsV20220401\Dto\ItemImagesByMarketplace; @@ -23,6 +24,7 @@ final class Item extends Response { protected static array $complexArrayTypes = [ + 'classifications' => [ItemBrowseClassificationsByMarketplace::class], 'dimensions' => [ItemDimensionsByMarketplace::class], 'identifiers' => [ItemIdentifiersByMarketplace::class], 'images' => [ItemImagesByMarketplace::class], @@ -36,6 +38,7 @@ final class Item extends Response /** * @param string $asin Amazon Standard Identification Number (ASIN) is the unique identifier for an item in the Amazon catalog. * @param ?mixed[] $attributes A JSON object that contains structured item attribute data keyed by attribute name. Catalog item attributes conform to the related product type definitions available in the Selling Partner API for Product Type Definitions. + * @param ItemBrowseClassificationsByMarketplace[]|null $classifications Array of classifications (browse nodes) associated with the item in the Amazon catalog by Amazon marketplace. * @param ItemDimensionsByMarketplace[]|null $dimensions Array of dimensions associated with the item in the Amazon catalog by Amazon marketplace. * @param ItemIdentifiersByMarketplace[]|null $identifiers Identifiers associated with the item in the Amazon catalog, such as UPC and EAN identifiers. * @param ItemImagesByMarketplace[]|null $images Images for an item in the Amazon catalog. @@ -48,6 +51,7 @@ final class Item extends Response public function __construct( public readonly string $asin, public readonly ?array $attributes = null, + public readonly ?array $classifications = null, public readonly ?array $dimensions = null, public readonly ?array $identifiers = null, public readonly ?array $images = null, From 496e7edb2c659168f8a6022380f0f53029736b0e Mon Sep 17 00:00:00 2001 From: Jesse Evers Date: Fri, 14 Jun 2024 18:25:34 -0400 Subject: [PATCH 5/5] Fix instances where inline schemas were overwriting each other * DataKiosk pagination * Messaging links and embeds * Solicitation links and embeds --- .../DataKioskV20231115/Dto/Pagination2.php | 24 +++++++++++++++++ .../Responses/GetQueriesResponse.php | 6 ++--- src/Seller/MessagingV1/Dto/Embedded.php | 4 +-- src/Seller/MessagingV1/Dto/Embedded2.php | 24 +++++++++++++++++ .../Dto/GetMessagingActionResponse.php | 8 +++--- .../MessagingV1/Dto/GetSchemaResponse.php | 4 +-- src/Seller/MessagingV1/Dto/Links2.php | 26 +++++++++++++++++++ src/Seller/MessagingV1/Dto/Links3.php | 24 +++++++++++++++++ src/Seller/SolicitationsV1/Dto/Embedded.php | 4 +-- src/Seller/SolicitationsV1/Dto/Embedded2.php | 24 +++++++++++++++++ .../SolicitationsV1/Dto/GetSchemaResponse.php | 4 +-- .../Dto/GetSolicitationActionResponse.php | 8 +++--- src/Seller/SolicitationsV1/Dto/Links2.php | 26 +++++++++++++++++++ src/Seller/SolicitationsV1/Dto/Links3.php | 24 +++++++++++++++++ 14 files changed, 191 insertions(+), 19 deletions(-) create mode 100644 src/Seller/DataKioskV20231115/Dto/Pagination2.php create mode 100644 src/Seller/MessagingV1/Dto/Embedded2.php create mode 100644 src/Seller/MessagingV1/Dto/Links2.php create mode 100644 src/Seller/MessagingV1/Dto/Links3.php create mode 100644 src/Seller/SolicitationsV1/Dto/Embedded2.php create mode 100644 src/Seller/SolicitationsV1/Dto/Links2.php create mode 100644 src/Seller/SolicitationsV1/Dto/Links3.php diff --git a/src/Seller/DataKioskV20231115/Dto/Pagination2.php b/src/Seller/DataKioskV20231115/Dto/Pagination2.php new file mode 100644 index 00000000..208bcebe --- /dev/null +++ b/src/Seller/DataKioskV20231115/Dto/Pagination2.php @@ -0,0 +1,24 @@ + [LinkObject::class]]; + protected static array $complexArrayTypes = ['actions' => [GetMessagingActionResponse::class]]; /** - * @param LinkObject[] $actions Eligible actions for the specified amazonOrderId. + * @param GetMessagingActionResponse[] $actions */ public function __construct( public readonly array $actions, diff --git a/src/Seller/MessagingV1/Dto/Embedded2.php b/src/Seller/MessagingV1/Dto/Embedded2.php new file mode 100644 index 00000000..da54bace --- /dev/null +++ b/src/Seller/MessagingV1/Dto/Embedded2.php @@ -0,0 +1,24 @@ + [Error::class]]; /** - * @param ?Links $links - * @param ?Embedded $embedded + * @param ?Links2 $links + * @param ?Embedded2 $embedded * @param ?MessagingAction $payload A simple object containing the name of the template. * @param Error[]|null $errors A list of error responses returned when a request is unsuccessful. */ public function __construct( - public readonly ?Links $links = null, - public readonly ?Embedded $embedded = null, + public readonly ?Links2 $links = null, + public readonly ?Embedded2 $embedded = null, public readonly ?MessagingAction $payload = null, public readonly ?array $errors = null, ) { diff --git a/src/Seller/MessagingV1/Dto/GetSchemaResponse.php b/src/Seller/MessagingV1/Dto/GetSchemaResponse.php index b5ee5419..50d57138 100644 --- a/src/Seller/MessagingV1/Dto/GetSchemaResponse.php +++ b/src/Seller/MessagingV1/Dto/GetSchemaResponse.php @@ -19,12 +19,12 @@ final class GetSchemaResponse extends Dto protected static array $complexArrayTypes = ['errors' => [Error::class]]; /** - * @param ?Links $links + * @param ?Links3 $links * @param ?array[] $payload A JSON schema document describing the expected payload of the action. This object can be validated against http://json-schema.org/draft-04/schema. * @param Error[]|null $errors A list of error responses returned when a request is unsuccessful. */ public function __construct( - public readonly ?Links $links = null, + public readonly ?Links3 $links = null, public readonly ?array $payload = null, public readonly ?array $errors = null, ) { diff --git a/src/Seller/MessagingV1/Dto/Links2.php b/src/Seller/MessagingV1/Dto/Links2.php new file mode 100644 index 00000000..44aaa391 --- /dev/null +++ b/src/Seller/MessagingV1/Dto/Links2.php @@ -0,0 +1,26 @@ + [LinkObject::class]]; + protected static array $complexArrayTypes = ['actions' => [GetSolicitationActionResponse::class]]; /** - * @param LinkObject[] $actions Eligible actions for the specified amazonOrderId. + * @param GetSolicitationActionResponse[] $actions */ public function __construct( public readonly array $actions, diff --git a/src/Seller/SolicitationsV1/Dto/Embedded2.php b/src/Seller/SolicitationsV1/Dto/Embedded2.php new file mode 100644 index 00000000..d02eba1c --- /dev/null +++ b/src/Seller/SolicitationsV1/Dto/Embedded2.php @@ -0,0 +1,24 @@ + [Error::class]]; /** - * @param ?Links $links + * @param ?Links3 $links * @param ?array[] $payload A JSON schema document describing the expected payload of the action. This object can be validated against http://json-schema.org/draft-04/schema. * @param Error[]|null $errors A list of error responses returned when a request is unsuccessful. */ public function __construct( - public readonly ?Links $links = null, + public readonly ?Links3 $links = null, public readonly ?array $payload = null, public readonly ?array $errors = null, ) { diff --git a/src/Seller/SolicitationsV1/Dto/GetSolicitationActionResponse.php b/src/Seller/SolicitationsV1/Dto/GetSolicitationActionResponse.php index fafafbb1..b2728a5a 100644 --- a/src/Seller/SolicitationsV1/Dto/GetSolicitationActionResponse.php +++ b/src/Seller/SolicitationsV1/Dto/GetSolicitationActionResponse.php @@ -19,14 +19,14 @@ final class GetSolicitationActionResponse extends Dto protected static array $complexArrayTypes = ['errors' => [Error::class]]; /** - * @param ?Links $links - * @param ?Embedded $embedded + * @param ?Links2 $links + * @param ?Embedded2 $embedded * @param ?SolicitationsAction $payload A simple object containing the name of the template. * @param Error[]|null $errors A list of error responses returned when a request is unsuccessful. */ public function __construct( - public readonly ?Links $links = null, - public readonly ?Embedded $embedded = null, + public readonly ?Links2 $links = null, + public readonly ?Embedded2 $embedded = null, public readonly ?SolicitationsAction $payload = null, public readonly ?array $errors = null, ) { diff --git a/src/Seller/SolicitationsV1/Dto/Links2.php b/src/Seller/SolicitationsV1/Dto/Links2.php new file mode 100644 index 00000000..ebd4a9d4 --- /dev/null +++ b/src/Seller/SolicitationsV1/Dto/Links2.php @@ -0,0 +1,26 @@ +