[API][Admin] Extend POST endpoint for creating a product

This commit is contained in:
Grzegorz Sadowski 2023-09-27 15:54:50 +02:00
parent 85a25557ab
commit 1536fd3d71
No known key found for this signature in database
GPG key ID: EF87FF4E6E3BD364
10 changed files with 209 additions and 44 deletions

View file

@ -59,6 +59,9 @@
<attribute name="denormalization_context">
<attribute name="groups">admin:product:create</attribute>
</attribute>
<attribute name="normalization_context">
<attribute name="groups">admin:product:read</attribute>
</attribute>
</collectionOperation>
</collectionOperations>

View file

@ -21,16 +21,17 @@
<group>shop:product:read</group>
</attribute>
<attribute name="code">
<group>admin:product:create</group>
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>shop:product:read</group>
</attribute>
<attribute name="variantSelectionMethod">
<group>admin:product:read</group>
<group>admin:product:create</group>
</attribute>
<attribute name="enabled">
<group>admin:product:create</group>
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
</attribute>
<attribute name="name">
@ -46,19 +47,19 @@
<group>shop:product:read</group>
</attribute>
<attribute name="translations">
<group>admin:product:create</group>
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
</attribute>
<attribute name="mainTaxon">
<group>admin:product:create</group>
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
<group>shop:product:read</group>
</attribute>
<attribute name="productTaxons">
<group>admin:product:create</group>
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
<group>shop:product:read</group>
</attribute>
@ -90,9 +91,11 @@
</attribute>
<attribute name="attributes">
<group>admin:product:read</group>
<group>admin:product:create</group>
</attribute>
<attribute name="channels">
<group>admin:product:read</group>
<group>admin:product:create</group>
</attribute>
<attribute name="createdAt">
<group>admin:product:read</group>

View file

@ -17,9 +17,22 @@
>
<class name="Sylius\Component\Product\Model\ProductAttributeValue">
<attribute name="id">
<group>admin:product:read</group>
<group>shop:product_attribute_value:read</group>
</attribute>
<attribute name="attribute">
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>shop:product_attribute_value:read</group>
</attribute>
<attribute name="value">
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>shop:product_attribute_value:read</group>
</attribute>
<attribute name="localeCode">
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>shop:product_attribute_value:read</group>
</attribute>
<attribute name="name">
@ -31,11 +44,5 @@
<attribute name="code">
<group>shop:product_attribute_value:read</group>
</attribute>
<attribute name="value">
<group>shop:product_attribute_value:read</group>
</attribute>
<attribute name="localeCode">
<group>shop:product_attribute_value:read</group>
</attribute>
</class>
</serializer>

View file

@ -24,34 +24,36 @@
<group>admin:product:create</group>
</attribute>
<attribute name="name">
<group>admin:product:create</group>
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
<group>shop:product:read</group>
</attribute>
<attribute name="slug">
<group>admin:product:create</group>
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
<group>shop:product:read</group>
</attribute>
<attribute name="description">
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>shop:product:read</group>
</attribute>
<attribute name="shortDescription">
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>shop:product:read</group>
</attribute>
<attribute name="metaKeywords">
<group>admin:product:create</group>
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
<group>shop:product:read</group>
</attribute>
<attribute name="metaDescription">
<group>admin:product:create</group>
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
<group>shop:product:read</group>
</attribute>

View file

@ -25,7 +25,7 @@ final class ProductsTest extends JsonApiTestCase
/** @test */
public function it_gets_a_product(): void
{
$fixtures = $this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'product/product.yaml']);
$fixtures = $this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'channel.yaml', 'product/product.yaml']);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
/** @var ProductInterface $product */
@ -46,7 +46,7 @@ final class ProductsTest extends JsonApiTestCase
/** @test */
public function it_gets_products(): void
{
$this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'product/product.yaml']);
$this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'channel.yaml', 'product/product.yaml']);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
$this->client->request(
@ -61,4 +61,64 @@ final class ProductsTest extends JsonApiTestCase
Response::HTTP_OK,
);
}
/** @test */
public function it_creates_a_product(): void
{
$this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'taxonomy.yaml',
'product/product_option.yaml',
'product/product_attribute.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
$this->client->request(
method: 'POST',
uri: '/api/v2/admin/products',
server: $header,
content: json_encode([
'code' => 'MUG',
'variantSelectionMethod' => ProductInterface::VARIANT_SELECTION_MATCH,
'enabled' => true,
'options' => [
'/api/v2/admin/product-options/COLOR',
],
'mainTaxon' => '/api/v2/admin/taxons/MUG',
'channels' => [
'/api/v2/admin/channels/WEB_GB',
],
'attributes' => [[
'attribute' => '/api/v2/admin/product-attributes/dishwasher_safe',
'value' => true,
]],
'translations' => [
'en_US' => [
'locale' => 'en_US',
'slug' => 'mug',
'name' => 'Mug',
'description' => 'This is a mug',
'shortDescription' => 'Short mug description',
'metaKeywords' => 'mug',
'metaDescription' => 'Mug description',
],
'pl_PL' => [
'locale' => 'pl_PL',
'slug' => 'kubek',
'name' => 'Kubek',
'description' => 'To jest kubek',
'shortDescription' => 'Krótki opis kubka',
'metaKeywords' => 'kubek',
'metaDescription' => 'Opis kubka',
],
],
], JSON_THROW_ON_ERROR),
);
$this->assertResponse(
$this->client->getResponse(),
'admin/product/post_product_response',
Response::HTTP_CREATED,
);
}
}

View file

@ -23,29 +23,6 @@ Sylius\Component\Core\Model\Product:
en_US: '@product_translation_socks_en_US'
options: ['@product_option_color']
Sylius\Component\Core\Model\Channel:
channel_web:
code: 'WEB'
name: 'Web Channel'
hostname: 'localhost'
description: 'Lorem ipsum'
baseCurrency: '@currency_usd'
defaultLocale: '@locale_en'
locales: ['@locale_en', '@locale_pl']
color: 'black'
enabled: true
taxCalculationStrategy: 'order_item_units_based'
Sylius\Component\Currency\Model\Currency:
currency_usd:
code: 'USD'
Sylius\Component\Locale\Model\Locale:
locale_en:
code: 'en_US'
locale_pl:
code: 'pl_PL'
Sylius\Component\Core\Model\ProductTranslation:
product_translation_mug_en_US:
locale: 'en_US'

View file

@ -0,0 +1,29 @@
Sylius\Component\Product\Model\ProductOption:
product_option_color:
code: '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

@ -25,8 +25,22 @@
"\/api\/v2\/admin\/product-reviews\/@integer@"
],
"attributes": [
"\/api\/v2\/admin\/product-attribute-values\/@integer@",
"\/api\/v2\/admin\/product-attribute-values\/@integer@"
{
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
"value": "Ceramic",
"localeCode": "en_US"
},
{
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
"value": "Ceramika",
"localeCode": "pl_PL"
}
],
"images": [
{

View file

@ -64,8 +64,22 @@
"\/api\/v2\/admin\/product-reviews\/@integer@"
],
"attributes": [
"\/api\/v2\/admin\/product-attribute-values\/@integer@",
"\/api\/v2\/admin\/product-attribute-values\/@integer@"
{
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
"value": "Ceramic",
"localeCode": "en_US"
},
{
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
"value": "Ceramika",
"localeCode": "pl_PL"
}
],
"images": [
{

View file

@ -0,0 +1,56 @@
{
"@context": "\/api\/v2\/contexts\/Product",
"@id": "\/api\/v2\/admin\/products\/MUG",
"@type": "Product",
"id": @integer@,
"code": "MUG",
"variantSelectionMethod": "match",
"enabled": true,
"options": [
"\/api\/v2\/admin\/product-options\/COLOR"
],
"variants": [],
"mainTaxon": "\/api\/v2\/admin\/taxons\/MUG",
"productTaxons": [],
"channels": [
"\/api\/v2\/admin\/channels\/WEB_GB"
],
"reviews": [],
"attributes": [
{
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/dishwasher_safe",
"value": true,
"localeCode": null
}
],
"images": [],
"translations": {
"en_US": {
"@id": "\/api\/v2\/admin\/product-translations\/@integer@",
"@type": "ProductTranslation",
"id": @integer@,
"name": "Mug",
"slug": "mug",
"description": "This is a mug",
"shortDescription": "Short mug description",
"metaKeywords": "mug",
"metaDescription": "Mug description"
},
"pl_PL": {
"@id": "\/api\/v2\/admin\/product-translations\/@integer@",
"@type": "ProductTranslation",
"id": @integer@,
"name": "Kubek",
"slug": "kubek",
"description": "To jest kubek",
"shortDescription": "Krótki opis kubka",
"metaKeywords": "kubek",
"metaDescription": "Opis kubka"
}
},
"createdAt": @date@,
"updatedAt": @date@
}