[API] Extend PUT endpoint for updating the product

This commit is contained in:
Grzegorz Sadowski 2023-10-02 09:47:59 +02:00
parent 1536fd3d71
commit 24f56b3d6f
No known key found for this signature in database
GPG key ID: EF87FF4E6E3BD364
8 changed files with 213 additions and 17 deletions

View file

@ -115,7 +115,10 @@
<attribute name="method">PUT</attribute>
<attribute name="path">/admin/products/{code}</attribute>
<attribute name="denormalization_context">
<attribute name="groups">admin:product:update</attribute>
<attribute name="groups">admin:product:create</attribute>
</attribute>
<attribute name="normalization_context">
<attribute name="groups">admin:product:read</attribute>
</attribute>
</itemOperation>

View file

@ -92,10 +92,12 @@
<attribute name="attributes">
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
</attribute>
<attribute name="channels">
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
</attribute>
<attribute name="createdAt">
<group>admin:product:read</group>

View file

@ -23,16 +23,19 @@
<attribute name="attribute">
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
<group>shop:product_attribute_value:read</group>
</attribute>
<attribute name="value">
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
<group>shop:product_attribute_value:read</group>
</attribute>
<attribute name="localeCode">
<group>admin:product:read</group>
<group>admin:product:create</group>
<group>admin:product:update</group>
<group>shop:product_attribute_value:read</group>
</attribute>
<attribute name="name">

View file

@ -25,11 +25,16 @@ final class ProductsTest extends JsonApiTestCase
/** @test */
public function it_gets_a_product(): void
{
$fixtures = $this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'channel.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 */
$product = $fixtures['product_mug'];
$this->client->request(
method: 'GET',
uri: sprintf('/api/v2/admin/products/%s', $product->getCode()),
@ -121,4 +126,84 @@ final class ProductsTest extends JsonApiTestCase
Response::HTTP_CREATED,
);
}
/** @test */
public function it_updates_the_existing_product(): void
{
$fixtures = $this->loadFixturesFromFiles([
'authentication/api_administrator.yaml',
'channel.yaml',
'product/product.yaml',
'product/product_attribute.yaml',
]);
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
/** @var ProductInterface $product */
$product = $fixtures['product_mug'];
$this->client->request(
method: 'PUT',
uri: sprintf('/api/v2/admin/products/%s', $product->getCode()),
server: $header,
content: json_encode([
'enabled' => false,
'mainTaxon' => '/api/v2/admin/taxons/CAPS',
'channels' => [
'/api/v2/admin/channels/MOBILE',
],
'attributes' => [
[
'@id' => sprintf(
'/api/v2/admin/product-attribute-values/%s',
$product->getAttributeByCodeAndLocale('MATERIAL', 'en_US')->getId()
),
'attribute' => '/api/v2/admin/product-attributes/MATERIAL',
'value' => 'Cotton',
'localeCode' => 'en_US',
],
[
'@id' => sprintf(
'/api/v2/admin/product-attribute-values/%s',
$product->getAttributeByCodeAndLocale('MATERIAL', 'pl_PL')->getId()
),
'attribute' => '/api/v2/admin/product-attributes/MATERIAL',
'value' => 'Bawełna',
'localeCode' => 'pl_PL',
],
[
'attribute' => '/api/v2/admin/product-attributes/dishwasher_safe',
'value' => true,
]
],
'translations' => [
'en_US' => [
'@id' => sprintf('/api/v2/admin/product-translations/%s', $product->getTranslation('en_US')->getId()),
'locale' => 'en_US',
'slug' => 'caps/cap',
'name' => 'Cap',
'description' => 'This is a cap',
'shortDescription' => 'Short cap description',
'metaKeywords' => 'cap',
'metaDescription' => 'Cap description',
],
'pl_PL' => [
'@id' => sprintf('/api/v2/admin/product-translations/%s', $product->getTranslation('pl_PL')->getId()),
'locale' => 'pl_PL',
'slug' => 'czapki/czapka',
'name' => 'Czapka',
'description' => 'To jest czapka',
'shortDescription' => 'Krótki opis czapki',
'metaKeywords' => 'czapka',
'metaDescription' => 'Opis czapki',
],
],
], JSON_THROW_ON_ERROR),
);
$this->assertResponse(
$this->client->getResponse(),
'admin/product/put_product_response',
Response::HTTP_OK,
);
}
}

View file

@ -1,13 +1,17 @@
Sylius\Component\Core\Model\Product:
product_mug:
code: 'MUG'
channels: ['@channel_web']
enabled: true
options: ['@product_option_color']
mainTaxon: '@taxon_mugs'
channels: ['@channel_web']
currentLocale: 'en_US'
translations:
en_US: '@product_translation_mug_en_US'
pl_PL: '@product_translation_mug_pl_PL'
options: ['@product_option_color']
attributes:
- '@product_attribute_value_material_en_US'
- '@product_attribute_value_material_pl_PL'
product_cap:
code: 'CAP'
channels: ['@channel_web']
@ -63,6 +67,7 @@ Sylius\Component\Core\Model\ProductVariant:
optionValues: ['@product_option_value_color_blue']
channelPricings:
WEB: '@channel_pricing_mug_blue_web'
MOBILE: '@channel_pricing_mug_blue_mobile'
product_variant_mug_red:
code: 'MUG_RED'
product: '@product_mug'
@ -72,6 +77,7 @@ Sylius\Component\Core\Model\ProductVariant:
optionValues: ['@product_option_value_color_red']
channelPricings:
WEB: '@channel_pricing_mug_red_web'
MOBILE: '@channel_pricing_mug_red_mobile'
Sylius\Component\Product\Model\ProductVariantTranslation:
product_variant_translation_mug_blue:
@ -91,6 +97,13 @@ Sylius\Component\Core\Model\ChannelPricing:
channel_pricing_mug_red_web:
channelCode: 'WEB'
price: 2000
channel_pricing_mug_blue_mobile:
channelCode: 'MOBILE'
price: 2500
originalPrice: 3500
channel_pricing_mug_red_mobile:
channelCode: 'MOBILE'
price: 2500
Sylius\Component\Product\Model\ProductOption:
product_option_color:
@ -125,6 +138,8 @@ Sylius\Component\Product\Model\ProductOptionValueTranslation:
Sylius\Component\Core\Model\Taxon:
taxon_mugs:
code: 'MUGS'
taxon_caps:
code: 'CAPS'
Sylius\Component\Core\Model\ProductTaxon:
product_taxon:
@ -156,33 +171,33 @@ Sylius\Component\Core\Model\Customer:
emailCanonical: 'john.doe@example.com'
Sylius\Component\Product\Model\ProductAttribute:
product_attribute_mug_material:
product_attribute_material:
translatable: true
fallbackLocale: 'en_US'
currentLocale: 'en_US'
code: 'MUG_MATERIAL'
code: 'MATERIAL'
type: 'text'
storageType: 'text'
translations:
- '@product_attribute_translation_mug_material_en_US'
- '@product_attribute_translation_material_en_US'
Sylius\Component\Product\Model\ProductAttributeValue:
product_attribute_value_mug_material_en_US:
product_attribute_value_material_en_US:
localeCode: 'en_US'
product: '@product_mug'
attribute: '@product_attribute_mug_material'
attribute: '@product_attribute_material'
value: 'Ceramic'
product_attribute_value_mug_material_pl_PL:
product_attribute_value_material_pl_PL:
localeCode: 'pl_PL'
product: '@product_mug'
attribute: '@product_attribute_mug_material'
attribute: '@product_attribute_material'
value: 'Ceramika'
Sylius\Component\Product\Model\ProductAttributeTranslation:
product_attribute_translation_mug_material_en_US:
product_attribute_translation_material_en_US:
locale: 'en_US'
name: 'Mug material'
translatable: '@product_attribute_mug_material'
translatable: '@product_attribute_material'
Sylius\Component\Core\Model\ProductImage:
product_mug_thumbnail:

View file

@ -29,7 +29,7 @@
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
"value": "Ceramic",
"localeCode": "en_US"
},
@ -37,7 +37,7 @@
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
"value": "Ceramika",
"localeCode": "pl_PL"
}

View file

@ -68,7 +68,7 @@
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
"value": "Ceramic",
"localeCode": "en_US"
},
@ -76,7 +76,7 @@
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/MUG_MATERIAL",
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
"value": "Ceramika",
"localeCode": "pl_PL"
}

View file

@ -0,0 +1,88 @@
{
"@context": "\/api\/v2\/contexts\/Product",
"@id": "\/api\/v2\/admin\/products\/MUG",
"@type": "Product",
"id": @integer@,
"code": "MUG",
"variantSelectionMethod": "choice",
"enabled": false,
"options": [
"\/api\/v2\/admin\/product-options\/COLOR"
],
"variants": [
"\/api\/v2\/admin\/product-variants\/MUG_BLUE",
"\/api\/v2\/admin\/product-variants\/MUG_RED"
],
"mainTaxon": "\/api\/v2\/admin\/taxons\/CAPS",
"productTaxons": [
"\/api\/v2\/admin\/product-taxons\/@integer@"
],
"channels": [
"\/api\/v2\/admin\/channels\/MOBILE"
],
"reviews": [
"\/api\/v2\/admin\/product-reviews\/@integer@",
"\/api\/v2\/admin\/product-reviews\/@integer@"
],
"attributes": [
{
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
"value": "Cotton",
"localeCode": "en_US"
},
{
"@id": "\/api\/v2\/admin\/product-attribute-values\/@integer@",
"@type": "ProductAttributeValue",
"id": @integer@,
"attribute": "\/api\/v2\/admin\/product-attributes\/MATERIAL",
"value": "Bawełna",
"localeCode": "pl_PL"
},
{
"@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": [
{
"@id": "\/api\/v2\/admin\/product-images\/@integer@",
"@type": "ProductImage",
"id": @integer@,
"type": "thumbnail",
"path": "\/media\/image\/product.jpg"
}
],
"translations": {
"en_US": {
"@id": "\/api\/v2\/admin\/product-translations\/@integer@",
"@type": "ProductTranslation",
"id": @integer@,
"name": "Cap",
"slug": "caps/cap",
"description": "This is a cap",
"shortDescription": "Short cap description",
"metaKeywords": "cap",
"metaDescription": "Cap description"
},
"pl_PL": {
"@id": "\/api\/v2\/admin\/product-translations\/@integer@",
"@type": "ProductTranslation",
"id": @integer@,
"name": "Czapka",
"slug": "czapki/czapka",
"description": "To jest czapka",
"shortDescription": "Krótki opis czapki",
"metaKeywords": "czapka",
"metaDescription": "Opis czapki"
}
},
"createdAt": @date@,
"updatedAt": @date@
}