[API][Admin] Extend GET endpoints for getting product variants

This commit is contained in:
Grzegorz Sadowski 2023-10-11 14:04:27 +02:00
parent a88c39a9de
commit dead3ac6cd
No known key found for this signature in database
GPG key ID: EF87FF4E6E3BD364
9 changed files with 511 additions and 237 deletions

View file

@ -27,8 +27,8 @@
<group>shop:product_variant:read</group>
</attribute>
<attribute name="translations">
<group>admin:product_variant:create</group>
<group>admin:product_variant:read</group>
<group>admin:product_variant:create</group>
<group>admin:product_variant:update</group>
</attribute>
<attribute name="optionValues">
@ -36,8 +36,8 @@
<group>shop:product_variant:read</group>
</attribute>
<attribute name="channelPricings">
<group>admin:product_variant:create</group>
<group>admin:product_variant:read</group>
<group>admin:product_variant:create</group>
<group>admin:product_variant:update</group>
</attribute>
<attribute name="name">
@ -48,5 +48,44 @@
<group>admin:product_variant:create</group>
<group>admin:product_variant:update</group>
</attribute>
<attribute name="position">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="tracked">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="onHold">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="onHand">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="weight">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="width">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="height">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="depth">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="taxCategory">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="shippingCategory">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="shippingRequired">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="createdAt">
<group>admin:product_variant:read</group>
</attribute>
<attribute name="updatedAt">
<group>admin:product_variant:read</group>
</attribute>
</class>
</serializer>

View file

@ -17,25 +17,26 @@
>
<class name="Sylius\Component\Product\Model\ProductVariantTranslation">
<attribute name="id">
<group>shop:order:account:read</group>
<group>admin:product_variant:read</group>
<group>admin:order:read</group>
<group>shop:product_variant:read</group>
<group>shop:order:account:read</group>
</attribute>
<attribute name="name">
<group>shop:order:account:read</group>
<group>admin:order:read</group>
<group>admin:product_variant:read</group>
<group>admin:product_variant:create</group>
<group>admin:product_variant:update</group>
<group>admin:product_variant:read</group>
<group>admin:order:read</group>
<group>shop:product_variant:read</group>
<group>shop:order:account:read</group>
</attribute>
<attribute name="locale">
<group>shop:order:account:read</group>
<group>admin:order:read</group>
<group>admin:product_variant:read</group>
<group>admin:product_variant:create</group>
<group>admin:product_variant:update</group>
<group>admin:product_variant:read</group>
<group>admin:order:read</group>
<group>shop:product_variant:read</group>
<group>shop:order:account:read</group>
</attribute>
</class>
</serializer>

View file

@ -14,7 +14,6 @@ declare(strict_types=1);
namespace Sylius\Tests\Api\Admin;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\ProductInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Tests\Api\JsonApiTestCase;
use Sylius\Tests\Api\Utils\AdminUserLoginTrait;
@ -25,9 +24,14 @@ final class ProductVariantsTest extends JsonApiTestCase
use AdminUserLoginTrait;
/** @test */
public function it_denies_access_to_a_products_list_for_not_authenticated_user(): void
public function it_denies_access_to_a_product_variants_list_for_not_authenticated_user(): void
{
$this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml']);
$this->loadFixturesFromFiles([
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$this->client->request('GET', '/api/v2/admin/product-variants');
@ -38,7 +42,13 @@ final class ProductVariantsTest extends JsonApiTestCase
/** @test */
public function it_gets_all_product_variants(): void
{
$this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
$this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
$this->client->request(
@ -54,7 +64,13 @@ final class ProductVariantsTest extends JsonApiTestCase
/** @test */
public function it_gets_a_product_variant(): void
{
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
$fixtures = $this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
/** @var ProductVariantInterface $productVariant */
@ -70,10 +86,217 @@ final class ProductVariantsTest extends JsonApiTestCase
$this->assertResponse($response, 'admin/product_variant/get_product_variant_response', Response::HTTP_OK);
}
/** @test */
public function it_creates_product_variant_enabled_by_default(): void
{
$this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'MUG_3',
'position' => 1,
'product' => '/api/v2/admin/products/MUG_SW',
'channelPricings' => ['WEB' => [
'channelCode' => 'WEB',
'price' => 4000,
'originalPrice' => 5000,
'minimumPrice' => 2000,
]],
'translations' => [
'en_US' => [
'locale' => 'en_US',
'name' => 'Yellow mug',
],
],
], JSON_THROW_ON_ERROR),
);
$this->assertResponse(
$this->client->getResponse(),
'admin/product_variant/post_product_variant_response',
Response::HTTP_CREATED,
);
}
/** @test */
public function it_creates_disabled_product_variant(): void
{
$this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'MUG_3',
'position' => 1,
'product' => '/api/v2/admin/products/MUG_SW',
'channelPricings' => ['WEB' => [
'channelCode' => 'WEB',
'price' => 4000,
'originalPrice' => 5000,
'minimumPrice' => 2000,
]],
'enabled' => false,
], JSON_THROW_ON_ERROR),
);
$this->assertResponse(
$this->client->getResponse(),
'admin/product_variant/post_product_variant_disabled_response',
Response::HTTP_CREATED,
);
}
/** @test */
public function it_does_not_allow_to_create_product_variant_with_invalid_channel_code(): void
{
$this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'CUP',
'product' => '/api/v2/admin/products/MUG_SW',
'channelPricings' => ['NON-EXISTING-CHANNEL' => [
'channelCode' => 'NON-EXISTING-CHANNEL',
'price' => 4000,
]],
], JSON_THROW_ON_ERROR),
);
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
}
/** @test */
public function it_does_not_allow_to_create_product_variant_without_channel_code(): void
{
$this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'CUP',
'product' => '/api/v2/admin/products/MUG_SW',
'channelPricings' => [
'NON-EXISTING-CHANNEL' => ['price' => 4000]
],
], JSON_THROW_ON_ERROR),
);
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
}
/** @test */
public function it_does_not_allow_to_create_product_variant_without_product(): void
{
$this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'CUP',
'channelPricings' => ['WEB' => [
'channelCode' => 'WEB',
'price' => 4000,
]],
], JSON_THROW_ON_ERROR),
);
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
}
/** @test */
public function it_does_not_allow_to_create_product_variant_with_invalid_locale_code(): void
{
$this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'CUP',
'product' => '/api/v2/admin/products/MUG_SW',
'channelPricings' => ['WEB' => [
'channelCode' => 'WEB',
'price' => 4000,
'originalPrice' => 5000,
'minimumPrice' => 2000,
]],
'translations' => [
'NON-EXISTING-LOCALE-CODE' => [
'locale' => 'NON-EXISTING-LOCALE-CODE',
'name' => 'Yellow mug',
],
],
], JSON_THROW_ON_ERROR),
);
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
}
/** @test */
public function it_updates_channel_pricing_and_translation_of_a_product_variant(): void
{
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
$fixtures = $this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
/** @var ProductVariantInterface $productVariant */
@ -113,190 +336,16 @@ final class ProductVariantsTest extends JsonApiTestCase
);
}
/** @test */
public function it_creates_product_variant_enabled_by_default(): void
{
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
/** @var ProductInterface $product */
$product = $fixtures['product'];
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'MUG_2',
'position' => 1,
'product' => sprintf('/api/v2/admin/products/%s', $product->getCode()),
'channelPricings' => ['WEB' => [
'channelCode' => 'WEB',
'price' => 4000,
'originalPrice' => 5000,
'minimumPrice' => 2000,
]],
'translations' => [
'en_US' => [
'locale' => 'en_US',
'name' => 'Yellow mug',
],
],
], JSON_THROW_ON_ERROR),
);
$this->assertResponse(
$this->client->getResponse(),
'admin/product_variant/post_product_variant_response',
Response::HTTP_CREATED,
);
}
/** @test */
public function it_creates_disabled_product_variant(): void
{
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
/** @var ProductInterface $product */
$product = $fixtures['product'];
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'MUG_2',
'position' => 1,
'product' => sprintf('/api/v2/admin/products/%s', $product->getCode()),
'channelPricings' => ['WEB' => [
'channelCode' => 'WEB',
'price' => 4000,
'originalPrice' => 5000,
'minimumPrice' => 2000,
]],
'enabled' => false,
], JSON_THROW_ON_ERROR),
);
$this->assertResponse(
$this->client->getResponse(),
'admin/product_variant/post_product_variant_disabled_response',
Response::HTTP_CREATED,
);
}
/** @test */
public function it_does_not_allow_to_create_product_variant_with_invalid_channel_code(): void
{
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
/** @var ProductInterface $product */
$product = $fixtures['product'];
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'CUP',
'product' => sprintf('/api/v2/admin/products/%s', $product->getCode()),
'channelPricings' => ['NON-EXISTING-CHANNEL' => [
'channelCode' => 'NON-EXISTING-CHANNEL',
'price' => 4000,
]],
], JSON_THROW_ON_ERROR),
);
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
}
/** @test */
public function it_does_not_allow_to_create_product_variant_without_channel_code(): void
{
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
/** @var ProductInterface $product */
$product = $fixtures['product'];
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'CUP',
'product' => sprintf('/api/v2/admin/products/%s', $product->getCode()),
'channelPricings' => [
'NON-EXISTING-CHANNEL' => ['price' => 4000]
],
], JSON_THROW_ON_ERROR),
);
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
}
/** @test */
public function it_does_not_allow_to_create_product_variant_without_product(): void
{
$this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'CUP',
'channelPricings' => ['WEB' => [
'channelCode' => 'WEB',
'price' => 4000,
]],
], JSON_THROW_ON_ERROR),
);
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
}
/** @test */
public function it_does_not_allow_to_create_product_variant_with_invalid_locale_code(): void
{
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
/** @var ProductInterface $product */
$product = $fixtures['product'];
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/product-variants',
server: $header,
content: json_encode([
'code' => 'CUP',
'product' => sprintf('/api/v2/admin/products/%s', $product->getCode()),
'channelPricings' => ['WEB' => [
'channelCode' => 'WEB',
'price' => 4000,
'originalPrice' => 5000,
'minimumPrice' => 2000,
]],
'translations' => [
'NON-EXISTING-LOCALE-CODE' => [
'locale' => 'NON-EXISTING-LOCALE-CODE',
'name' => 'Yellow mug',
],
],
], JSON_THROW_ON_ERROR),
);
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
}
/** @test */
public function it_does_not_allow_to_update_product_variant_with_invalid_locale_code(): void
{
$fixtures = $this->loadFixturesFromFiles(['channel.yaml', 'product/product_variant.yaml', 'authentication/api_administrator.yaml']);
$fixtures = $this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'tax_category.yaml',
'shipping_category.yaml',
'product/product_variant.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
/** @var ProductVariantInterface $productVariant */

View file

@ -2,28 +2,96 @@ Sylius\Component\Core\Model\Product:
product:
fallbackLocale: en_US
currentLocale: en
code: MUG_SW
code: 'MUG_SW'
Sylius\Component\Product\Model\ProductVariantTranslation:
product_variant_translation:
name: 'Mug'
locale: en_US
translatable: '@product_variant'
product_variant_2_translation:
name: 'Mug 2'
locale: en_US
translatable: '@product_variant_2'
Sylius\Component\Core\Model\ProductVariant:
product_variant:
code: MUG
code: 'MUG'
version: 1
product: '@product'
fallbackLocale: en_US
currentLocale: en
position: 1
optionValues: ['@product_option_value_color_blue']
channelPricings:
channel_web: '@product_variant_channel_web_pricing'
translations:
- '@product_variant_translation'
enabled: true
tracked: true
onHold: 0
onHand: 10
weight: 100.50
width: 100.50
height: 100.50
depth: 100.50
taxCategory: '@tax_category_default'
shippingCategory: '@shipping_category_default'
shippingRequired: true
product_variant_2:
code: 'MUG_2'
product: '@product'
fallbackLocale: en_US
currentLocale: en
position: 2
channelPricings:
channel_web: '@product_variant_2_channel_web_pricing'
translations:
- '@product_variant_2_translation'
Sylius\Component\Core\Model\ChannelPricing:
product_variant_channel_web_pricing:
channelCode: 'WEB'
price: 2000
product_variant_2_channel_web_pricing:
channelCode: 'WEB'
price: 3000
Sylius\Component\Product\Model\ProductOption:
product_option_color:
code: 'COLOR'
currentLocale: 'en_US'
translations:
- '@product_option_translation_en_EN'
Sylius\Component\Product\Model\ProductOptionTranslation:
product_option_translation_en_EN:
locale: 'en_US'
name: 'Color'
translatable: '@product_option_color'
Sylius\Component\Product\Model\ProductOptionValue:
product_option_value_color_blue:
code: 'COLOR_BLUE'
currentLocale: 'en_US'
fallbackLocale: 'en_US'
option: '@product_option_color'
translations:
- '@product_option_value_translation_blue'
product_option_value_color_red:
code: 'COLOR_RED'
currentLocale: 'en_US'
fallbackLocale: 'en_US'
option: '@product_option_color'
translations:
- '@product_option_value_translation_red'
Sylius\Component\Product\Model\ProductOptionValueTranslation:
product_option_value_translation_blue:
locale: 'en_US'
value: 'Blue'
translatable: '@product_option_value_color_blue'
product_option_value_translation_red:
locale: 'en_US'
value: 'Red'
translatable: '@product_option_value_color_red'

View file

@ -1,9 +1,12 @@
{
"@context":"\/api\/v2\/contexts\/ProductVariant",
"@id":"\/api\/v2\/admin\/product-variants\/MUG",
"@type":"ProductVariant",
"code":"MUG",
"product":"\/api\/v2\/admin\/products\/MUG_SW",
"@context": "\/api\/v2\/contexts\/ProductVariant",
"@id": "\/api\/v2\/admin\/product-variants\/MUG",
"@type": "ProductVariant",
"code": "MUG",
"product": "\/api\/v2\/admin\/products\/MUG_SW",
"optionValues":[
"\/api\/v2\/admin\/product-option-values\/COLOR_BLUE"
],
"channelPricings": {
"WEB": {
"@id": "/api/v2/admin/channel-pricings/@integer@",
@ -15,14 +18,27 @@
"minimumPrice": 0
}
},
"optionValues":[],
"translations": {
"en_US": {
"@id":"\/api\/v2\/admin\/product-variant-translations\/@integer@",
"@type":"ProductVariantTranslation",
"name":"Mug",
"locale":"en_US"
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
"@type": "ProductVariantTranslation",
"id": @integer@,
"name": "Mug",
"locale": "en_US"
}
},
"enabled": true
"enabled": true,
"position": 1,
"tracked": true,
"onHold": 0,
"onHand": 10,
"weight": 100.5,
"width": 100.5,
"height": 100.5,
"depth": 100.5,
"taxCategory": "\/api\/v2\/admin\/tax-categories\/default",
"shippingCategory": "\/api\/v2\/admin\/shipping-categories\/default",
"shippingRequired": true,
"createdAt": @date@,
"updatedAt": @date@
}

View file

@ -8,6 +8,9 @@
"@type": "ProductVariant",
"code": "MUG",
"product": "\/api\/v2\/admin\/products\/MUG_SW",
"optionValues":[
"\/api\/v2\/admin\/product-option-values\/COLOR_BLUE"
],
"channelPricings": {
"WEB": {
"@id": "/api/v2/admin/channel-pricings/@integer@",
@ -19,19 +22,73 @@
"minimumPrice": 0
}
},
"optionValues": [],
"enabled": true,
"translations": {
"en_US": {
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
"@type": "ProductVariantTranslation",
"id": @integer@,
"name": "Mug",
"locale": "en_US"
}
}
},
"enabled": true,
"position": 1,
"tracked": true,
"onHold": 0,
"onHand": 10,
"weight": 100.5,
"width": 100.5,
"height": 100.5,
"depth": 100.5,
"taxCategory": "\/api\/v2\/admin\/tax-categories\/default",
"shippingCategory": "\/api\/v2\/admin\/shipping-categories\/default",
"shippingRequired": true,
"createdAt": @date@,
"updatedAt": @date@
},
{
"@id": "\/api\/v2\/admin\/product-variants/MUG_2",
"@type": "ProductVariant",
"code": "MUG_2",
"product": "\/api\/v2\/admin\/products\/MUG_SW",
"optionValues": [],
"channelPricings": {
"WEB": {
"@id": "/api/v2/admin/channel-pricings/@integer@",
"@type": "ChannelPricing",
"channelCode": "WEB",
"price": 3000,
"originalPrice": null,
"lowestPriceBeforeDiscount": null,
"minimumPrice": 0
}
},
"translations": {
"en_US": {
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
"@type": "ProductVariantTranslation",
"id": @integer@,
"name": "Mug 2",
"locale": "en_US"
}
},
"enabled": true,
"position": 2,
"tracked": false,
"onHold": 0,
"onHand": 0,
"weight": null,
"width": null,
"height": null,
"depth": null,
"taxCategory": null,
"shippingCategory": null,
"shippingRequired": true,
"createdAt": @date@,
"updatedAt": @date@
}
],
"hydra:totalItems": 1,
"hydra:totalItems": 2,
"hydra:search": {
"@type": "hydra:IriTemplate",
"hydra:template": "\/api\/v2\/admin\/product-variants{?catalogPromotion}",

View file

@ -1,9 +1,10 @@
{
"@context":"\/api\/v2\/contexts\/ProductVariant",
"@id":"\/api\/v2\/admin\/product-variants\/MUG_2",
"@type":"ProductVariant",
"code":"MUG_2",
"product":"\/api\/v2\/admin\/products\/MUG_SW",
"@context": "\/api\/v2\/contexts\/ProductVariant",
"@id": "\/api\/v2\/admin\/product-variants\/MUG_3",
"@type": "ProductVariant",
"code": "MUG_3",
"product": "\/api\/v2\/admin\/products\/MUG_SW",
"optionValues": [],
"channelPricings": {
"WEB": {
"@id": "\/api\/v2\/admin\/channel-pricings\/@integer@",
@ -15,7 +16,19 @@
"lowestPriceBeforeDiscount": null
}
},
"translations": [],
"enabled": false,
"optionValues": [],
"translations": []
"position": 3,
"tracked": false,
"onHold": 0,
"onHand": 0,
"weight": null,
"width": null,
"height": null,
"depth": null,
"taxCategory": null,
"shippingCategory": null,
"shippingRequired": true,
"createdAt": @date@,
"updatedAt": @date@
}

View file

@ -1,9 +1,10 @@
{
"@context":"\/api\/v2\/contexts\/ProductVariant",
"@id":"\/api\/v2\/admin\/product-variants\/MUG_2",
"@type":"ProductVariant",
"code":"MUG_2",
"product":"\/api\/v2\/admin\/products\/MUG_SW",
"@context": "\/api\/v2\/contexts\/ProductVariant",
"@id": "\/api\/v2\/admin\/product-variants\/MUG_3",
"@type": "ProductVariant",
"code": "MUG_3",
"product": "\/api\/v2\/admin\/products\/MUG_SW",
"optionValues": [],
"channelPricings": {
"WEB": {
"@id": "\/api\/v2\/admin\/channel-pricings\/@integer@",
@ -15,14 +16,27 @@
"lowestPriceBeforeDiscount": null
}
},
"enabled": true,
"optionValues": [],
"translations": {
"en_US": {
"@id":"\/api\/v2\/admin\/product-variant-translations\/@integer@",
"@type":"ProductVariantTranslation",
"name":"Yellow mug",
"locale":"en_US"
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
"@type": "ProductVariantTranslation",
"id":@integer@,
"name": "Yellow mug",
"locale": "en_US"
}
}
},
"enabled": true,
"position": 3,
"tracked": false,
"onHold": 0,
"onHand": 0,
"weight": null,
"width": null,
"height": null,
"depth": null,
"taxCategory": null,
"shippingCategory": null,
"shippingRequired": true,
"createdAt": @date@,
"updatedAt": @date@
}

View file

@ -2,6 +2,11 @@
"@context": "\/api\/v2\/contexts\/ProductVariant",
"@id": "\/api\/v2\/admin\/product-variants\/MUG",
"@type": "ProductVariant",
"code": "MUG",
"product": "\/api\/v2\/admin\/products\/MUG_SW",
"optionValues":[
"\/api\/v2\/admin\/product-option-values\/COLOR_BLUE"
],
"channelPricings": {
"WEB": {
"@id": "\/api\/v2\/admin\/channel-pricings\/@integer@",
@ -13,22 +18,34 @@
"minimumPrice": 210
}
},
"code": "MUG",
"product": "\/api\/v2\/admin\/products\/MUG_SW",
"optionValues": [],
"enabled": true,
"translations": {
"de_DE": {
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
"@type": "ProductVariantTranslation",
"id": @integer@,
"name": "Orange Tasse",
"locale": "de_DE"
},
"pl_PL": {
"@id": "\/api\/v2\/admin\/product-variant-translations\/@integer@",
"@type": "ProductVariantTranslation",
"id": @integer@,
"name": "Pomarańczowy kubek",
"locale": "pl_PL"
}
}
},
"enabled": true,
"position": 1,
"tracked": true,
"onHold": 0,
"onHand": 10,
"weight": 100.5,
"width": 100.5,
"height": 100.5,
"depth": 100.5,
"taxCategory": "\/api\/v2\/admin\/tax-categories\/default",
"shippingCategory": "\/api\/v2\/admin\/shipping-categories\/default",
"shippingRequired": true,
"createdAt": @date@,
"updatedAt": @date@
}