mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-14 17:10:53 +00:00
[API] Promotion Retrieval and Removal (#16613)
| Q | A |-----------------|----- | Branch? | api-platform-3 <!-- see the comment below --> | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no<!-- don't forget to update the UPGRADE-*.md file --> | License | MIT <!-- - Bug fixes must be submitted against the 1.13 branch - Features and deprecations must be submitted against the 1.14 branch - Features, removing deprecations and BC breaks must be submitted against the 2.0 branch - Make sure that the correct base branch is set To be sure you are not breaking any Backward Compatibilities, check the documentation: https://docs.sylius.com/en/latest/book/organization/backward-compatibility-promise.html --> Current endpoints state: <img width="629" alt="image" src="https://github.com/user-attachments/assets/c26c5b91-eabc-4996-b33c-f105b691bfc5"> <img width="1401" alt="image" src="https://github.com/user-attachments/assets/3a9ed70f-f9e4-4796-9a6c-42ddf4efb927"> <img width="1224" alt="image" src="https://github.com/user-attachments/assets/877aac05-a8b1-43bd-b58f-f0ec649cd724">
This commit is contained in:
commit
cebe951f68
22 changed files with 320 additions and 369 deletions
|
|
@ -35,28 +35,6 @@ final class PromotionsTest extends JsonApiTestCase
|
|||
{
|
||||
use AdminUserLoginTrait;
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_promotion(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'channel.yaml', 'promotion/promotion.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var PromotionInterface $promotion */
|
||||
$promotion = $fixtures['promotion_50_off'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'GET',
|
||||
uri: sprintf('/api/v2/admin/promotions/%s', $promotion->getCode()),
|
||||
server: $header,
|
||||
);
|
||||
|
||||
$this->assertResponse(
|
||||
$this->client->getResponse(),
|
||||
'admin/promotion/get_promotion_response',
|
||||
Response::HTTP_OK,
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_gets_promotions(): void
|
||||
{
|
||||
|
|
@ -625,44 +603,4 @@ final class PromotionsTest extends JsonApiTestCase
|
|||
Response::HTTP_OK,
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_promotion(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'channel.yaml', 'promotion/promotion.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var PromotionInterface $promotion */
|
||||
$promotion = $fixtures['promotion_50_off'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'DELETE',
|
||||
uri: sprintf('/api/v2/admin/promotions/%s', $promotion->getCode()),
|
||||
server: $header,
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_NO_CONTENT);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_delete_the_promotion_in_use(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'promotion/promotion.yaml',
|
||||
'promotion/promotion_order.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
/** @var PromotionInterface $promotion */
|
||||
$promotion = $fixtures['promotion_50_off'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'DELETE',
|
||||
uri: sprintf('/api/v2/admin/promotions/%s', $promotion->getCode()),
|
||||
server: $header,
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -860,21 +860,6 @@ parameters:
|
|||
count: 1
|
||||
path: src/Sylius/Bundle/ApiBundle/DataPersister/PromotionCouponDataPersister.php
|
||||
|
||||
-
|
||||
message: "#^Method Sylius\\\\Bundle\\\\ApiBundle\\\\DataPersister\\\\PromotionDataPersister\\:\\:persist\\(\\) has parameter \\$data with no type specified\\.$#"
|
||||
count: 1
|
||||
path: src/Sylius/Bundle/ApiBundle/DataPersister/PromotionDataPersister.php
|
||||
|
||||
-
|
||||
message: "#^Method Sylius\\\\Bundle\\\\ApiBundle\\\\DataPersister\\\\PromotionDataPersister\\:\\:remove\\(\\) has parameter \\$data with no type specified\\.$#"
|
||||
count: 1
|
||||
path: src/Sylius/Bundle/ApiBundle/DataPersister/PromotionDataPersister.php
|
||||
|
||||
-
|
||||
message: "#^Method Sylius\\\\Bundle\\\\ApiBundle\\\\DataPersister\\\\PromotionDataPersister\\:\\:supports\\(\\) has parameter \\$data with no type specified\\.$#"
|
||||
count: 1
|
||||
path: src/Sylius/Bundle/ApiBundle/DataPersister/PromotionDataPersister.php
|
||||
|
||||
-
|
||||
message: "#^Method Sylius\\\\Bundle\\\\ApiBundle\\\\DataPersister\\\\TranslatableDataPersister\\:\\:supports\\(\\) has parameter \\$data with no type specified\\.$#"
|
||||
count: 1
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Bundle\ApiBundle\DataPersister;
|
||||
|
||||
use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
use Sylius\Bundle\ApiBundle\Exception\PromotionCannotBeRemoved;
|
||||
use Sylius\Component\Core\Model\PromotionInterface;
|
||||
|
||||
final class PromotionDataPersister implements ContextAwareDataPersisterInterface
|
||||
{
|
||||
public function __construct(private ContextAwareDataPersisterInterface $decoratedDataPersister)
|
||||
{
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $context */
|
||||
public function supports($data, array $context = []): bool
|
||||
{
|
||||
return $data instanceof PromotionInterface;
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $context */
|
||||
public function persist($data, array $context = [])
|
||||
{
|
||||
return $this->decoratedDataPersister->persist($data, $context);
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $context */
|
||||
public function remove($data, array $context = []): void
|
||||
{
|
||||
try {
|
||||
$this->decoratedDataPersister->remove($data, $context);
|
||||
} catch (ForeignKeyConstraintViolationException) {
|
||||
throw new PromotionCannotBeRemoved();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ final readonly class RestrictingFilterEagerLoadingExtension implements QueryColl
|
|||
*/
|
||||
public function __construct(
|
||||
private QueryCollectionExtensionInterface $decoratedExtension,
|
||||
private array $restrictedResources
|
||||
private array $restrictedResources,
|
||||
) {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
This file is part of the Sylius package.
|
||||
|
||||
(c) Sylius Sp. z o.o.
|
||||
|
||||
For the full copyright and license information, please view the LICENSE
|
||||
file that was distributed with this source code.
|
||||
|
||||
-->
|
||||
|
||||
<properties xmlns="https://api-platform.com/schema/metadata/properties-3.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://api-platform.com/schema/metadata/properties-3.0 https://api-platform.com/schema/metadata/properties-3.0.xsd"
|
||||
>
|
||||
<property resource="Sylius\Component\Core\Model\Promotion" name="id" identifier="false" />
|
||||
<property resource="Sylius\Component\Core\Model\Promotion" name="code" identifier="true" />
|
||||
</properties>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
This file is part of the Sylius package.
|
||||
|
||||
(c) Sylius Sp. z o.o.
|
||||
|
||||
For the full copyright and license information, please view the LICENSE
|
||||
file that was distributed with this source code.
|
||||
|
||||
-->
|
||||
|
||||
<properties xmlns="https://api-platform.com/schema/metadata/properties-3.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://api-platform.com/schema/metadata/properties-3.0 https://api-platform.com/schema/metadata/properties-3.0.xsd"
|
||||
>
|
||||
<property resource="Sylius\Component\Promotion\Model\PromotionTranslation" name="id" identifier="false" />
|
||||
<property resource="Sylius\Component\Promotion\Model\PromotionTranslation" name="locale" identifier="true" />
|
||||
</properties>
|
||||
|
|
@ -28,7 +28,6 @@
|
|||
</validationContext>
|
||||
|
||||
<operations>
|
||||
|
||||
<operation class="ApiPlatform\Metadata\Get" uriTemplate="/admin/product-variant-translations/{id}">
|
||||
<normalizationContext>
|
||||
<values>
|
||||
|
|
@ -41,8 +40,6 @@
|
|||
</values>
|
||||
</normalizationContext>
|
||||
</operation>
|
||||
|
||||
</operations>
|
||||
</resource>
|
||||
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
|
||||
This file is part of the Sylius package.
|
||||
|
||||
(c) Sylius Sp. z o.o.
|
||||
|
||||
For the full copyright and license information, please view the LICENSE
|
||||
file that was distributed with this source code.
|
||||
|
||||
-->
|
||||
|
||||
<resources
|
||||
xmlns="https://api-platform.com/schema/metadata/resources-3.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0 https://api-platform.com/schema/metadata/resources-3.0.xsd"
|
||||
>
|
||||
<resource class="Sylius\Component\Core\Model\Promotion">
|
||||
<operations>
|
||||
<operation class="ApiPlatform\Metadata\Get" uriTemplate="/admin/promotions/{code}">
|
||||
<normalizationContext>
|
||||
<values>
|
||||
<value name="groups">
|
||||
<values>
|
||||
<value>sylius:admin:promotion:show</value>
|
||||
</values>
|
||||
</value>
|
||||
</values>
|
||||
</normalizationContext>
|
||||
</operation>
|
||||
|
||||
<operation
|
||||
class="ApiPlatform\Metadata\Delete"
|
||||
uriTemplate="/admin/promotions/{code}"
|
||||
processor="sylius_api.state_processor.admin.promotion.remove"
|
||||
/>
|
||||
</operations>
|
||||
</resource>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
|
||||
This file is part of the Sylius package.
|
||||
|
||||
(c) Sylius Sp. z o.o.
|
||||
|
||||
For the full copyright and license information, please view the LICENSE
|
||||
file that was distributed with this source code.
|
||||
|
||||
-->
|
||||
|
||||
<resources
|
||||
xmlns="https://api-platform.com/schema/metadata/resources-3.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://api-platform.com/schema/metadata/resources-3.0 https://api-platform.com/schema/metadata/resources-3.0.xsd"
|
||||
>
|
||||
<resource class="Sylius\Component\Promotion\Model\PromotionTranslation">
|
||||
<operations>
|
||||
<operation class="ApiPlatform\Metadata\NotExposed" uriTemplate="/admin/promotions/{code}/translations/{localeCode}">
|
||||
<uriVariables>
|
||||
<uriVariable parameterName="code" fromClass="Sylius\Component\Core\Model\Promotion" fromProperty="translations"/>
|
||||
<uriVariable parameterName="localeCode" fromClass="Sylius\Component\Promotion\Model\PromotionTranslation"/>
|
||||
</uriVariables>
|
||||
</operation>
|
||||
</operations>
|
||||
</resource>
|
||||
</resources>
|
||||
|
|
@ -95,18 +95,6 @@ Example configuration for `order_fixed_discount` action type:
|
|||
</collectionOperations>
|
||||
|
||||
<itemOperations>
|
||||
<itemOperation name="admin_get">
|
||||
<attribute name="method">GET</attribute>
|
||||
<attribute name="normalization_context">
|
||||
<attribute name="groups">
|
||||
<attribute>admin:promotion:show</attribute>
|
||||
<attribute>sylius:admin:promotion:show</attribute>
|
||||
</attribute>
|
||||
<!-- It auto-turned on when adding PATCH itemOperations: https://github.com/api-platform/core/issues/3600 -->
|
||||
<attribute name="skip_null_values">false</attribute>
|
||||
</attribute>
|
||||
</itemOperation>
|
||||
|
||||
<itemOperation name="admin_put">
|
||||
<attribute name="method">PUT</attribute>
|
||||
<attribute name="denormalization_context">
|
||||
|
|
@ -185,10 +173,6 @@ Example configuration for `order_fixed_discount` action type:
|
|||
</attribute>
|
||||
</attribute>
|
||||
</itemOperation>
|
||||
|
||||
<itemOperation name="admin_delete">
|
||||
<attribute name="method">DELETE</attribute>
|
||||
</itemOperation>
|
||||
</itemOperations>
|
||||
|
||||
<subresourceOperations>
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
<?xml version="1.0" ?>
|
||||
|
||||
<!--
|
||||
|
||||
This file is part of the Sylius package.
|
||||
|
||||
(c) Sylius Sp. z o.o.
|
||||
|
||||
For the full copyright and license information, please view the LICENSE
|
||||
file that was distributed with this source code.
|
||||
|
||||
-->
|
||||
|
||||
<resources xmlns="https://api-platform.com/schema/metadata"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://api-platform.com/schema/metadata https://api-platform.com/schema/metadata/metadata-2.0.xsd"
|
||||
>
|
||||
<resource class="%sylius.model.promotion_translation.class%" shortName="PromotionTranslation">
|
||||
<attribute name="validation_groups">sylius</attribute>
|
||||
|
||||
<collectionOperations />
|
||||
|
||||
<itemOperations>
|
||||
<itemOperation name="admin_get">
|
||||
<attribute name="method">GET</attribute>
|
||||
<attribute name="path">/admin/promotion-translations/{id}</attribute>
|
||||
</itemOperation>
|
||||
</itemOperations>
|
||||
|
||||
<property name="id" identifier="true" writable="false" />
|
||||
<property name="label" identifier="false" />
|
||||
<property name="locale" identifier="false" required="true" />
|
||||
</resource>
|
||||
</resources>
|
||||
|
|
@ -13,195 +13,103 @@
|
|||
>
|
||||
<class name="Sylius\Component\Core\Model\Promotion">
|
||||
<attribute name="id">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="createdAt">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="updatedAt">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="name">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="code">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="description">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="priority">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="exclusive">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="appliesToDiscounted">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="usageLimit">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="used">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="startsAt">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="endsAt">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="couponBased">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="coupons">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="rules">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="actions">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="channels">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="translations">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="archivedAt">
|
||||
<group>admin:promotion:read</group>
|
||||
<group>sylius:admin:promotion:read</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
</attribute>
|
||||
</class>
|
||||
</serializer>
|
||||
|
|
|
|||
|
|
@ -16,29 +16,9 @@
|
|||
xsi:schemaLocation="http://symfony.com/schema/dic/serializer-mapping https://symfony.com/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd"
|
||||
>
|
||||
<class name="Sylius\Component\Promotion\Model\PromotionTranslation">
|
||||
<attribute name="id">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="label">
|
||||
<group>admin:promotion:index</group>
|
||||
<group>sylius:admin:promotion:index</group>
|
||||
<group>admin:promotion:show</group>
|
||||
<group>sylius:admin:promotion:show</group>
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
|
||||
<attribute name="locale">
|
||||
<group>admin:promotion:create</group>
|
||||
<group>sylius:admin:promotion:create</group>
|
||||
<group>admin:promotion:update</group>
|
||||
<group>sylius:admin:promotion:update</group>
|
||||
</attribute>
|
||||
</class>
|
||||
</serializer>
|
||||
|
|
|
|||
|
|
@ -71,11 +71,6 @@
|
|||
<tag name="api_platform.data_persister" />
|
||||
</service>
|
||||
|
||||
<service id="Sylius\Bundle\ApiBundle\DataPersister\PromotionDataPersister">
|
||||
<argument type="service" id="api_platform.doctrine.orm.data_persister" />
|
||||
<tag name="api_platform.data_persister" />
|
||||
</service>
|
||||
|
||||
<service id="Sylius\Bundle\ApiBundle\DataPersister\CustomerDataPersister">
|
||||
<argument type="service" id="api_platform.doctrine.orm.data_persister" />
|
||||
<argument type="service" id="sylius.security.password_updater" />
|
||||
|
|
|
|||
|
|
@ -63,6 +63,11 @@
|
|||
<tag name="api_platform.state_processor" />
|
||||
</service>
|
||||
|
||||
<service id="sylius_api.state_processor.admin.promotion.remove" class="Sylius\Bundle\ApiBundle\StateProcessor\Admin\Promotion\RemoveProcessor">
|
||||
<argument type="service" id="api_platform.doctrine.orm.state.remove_processor" />
|
||||
<tag name="api_platform.state_processor" />
|
||||
</service>
|
||||
|
||||
<service id="sylius_api.state_processor.shop.address.persist" class="Sylius\Bundle\ApiBundle\StateProcessor\Shop\Address\PersistProcessor">
|
||||
<argument type="service" id="api_platform.doctrine.orm.state.persist_processor" />
|
||||
<argument type="service" id="Sylius\Bundle\ApiBundle\Context\UserContextInterface" />
|
||||
|
|
|
|||
|
|
@ -93,8 +93,7 @@ final class ShippingMethodNormalizer implements NormalizerInterface, NormalizerA
|
|||
$data instanceof ShippingMethodInterface &&
|
||||
$this->sectionProvider->getSection() instanceof ShopApiSection &&
|
||||
$operation instanceof HttpOperation &&
|
||||
isset($operation->getUriVariables()['tokenValue']) &&
|
||||
isset($operation->getUriVariables()['shipmentId'])
|
||||
isset($operation->getUriVariables()['tokenValue'], $operation->getUriVariables()['shipmentId'])
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Bundle\ApiBundle\StateProcessor\Admin\Promotion;
|
||||
|
||||
use ApiPlatform\Metadata\DeleteOperationInterface;
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProcessorInterface;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
use Sylius\Bundle\ApiBundle\Exception\PromotionCannotBeRemoved;
|
||||
use Sylius\Component\Core\Model\PromotionInterface;
|
||||
use Webmozart\Assert\Assert;
|
||||
|
||||
/**
|
||||
* @implements ProcessorInterface<PromotionInterface>
|
||||
*/
|
||||
final readonly class RemoveProcessor implements ProcessorInterface
|
||||
{
|
||||
public function __construct(private ProcessorInterface $removeProcessor)
|
||||
{
|
||||
}
|
||||
|
||||
public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []): void
|
||||
{
|
||||
Assert::isInstanceOf($data, PromotionInterface::class);
|
||||
Assert::isInstanceOf($operation, DeleteOperationInterface::class);
|
||||
|
||||
try {
|
||||
$this->removeProcessor->process($data, $operation, $uriVariables, $context);
|
||||
} catch (ForeignKeyConstraintViolationException) {
|
||||
throw new PromotionCannotBeRemoved();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace spec\Sylius\Bundle\ApiBundle\DataPersister;
|
||||
|
||||
use ApiPlatform\Core\DataPersister\ContextAwareDataPersisterInterface;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Bundle\ApiBundle\Exception\PromotionCannotBeRemoved;
|
||||
use Sylius\Component\Core\Model\PromotionInterface;
|
||||
|
||||
final class PromotionDataPersisterSpec extends ObjectBehavior
|
||||
{
|
||||
function let(ContextAwareDataPersisterInterface $dataPersister): void
|
||||
{
|
||||
$this->beConstructedWith($dataPersister);
|
||||
}
|
||||
|
||||
function it_is_a_context_aware_persister(): void
|
||||
{
|
||||
$this->shouldImplement(ContextAwareDataPersisterInterface::class);
|
||||
}
|
||||
|
||||
function it_supports_only_promotion(PromotionInterface $promotion): void
|
||||
{
|
||||
$this->supports(new \stdClass())->shouldReturn(false);
|
||||
$this->supports($promotion)->shouldReturn(true);
|
||||
}
|
||||
|
||||
function it_uses_inner_persister_to_persist_promotion(
|
||||
ContextAwareDataPersisterInterface $dataPersister,
|
||||
PromotionInterface $promotion,
|
||||
): void {
|
||||
$dataPersister->persist($promotion, [])->shouldBeCalled();
|
||||
|
||||
$this->persist($promotion);
|
||||
}
|
||||
|
||||
function it_throws_cannot_be_removed_exception_if_constraint_fails_on_removal(
|
||||
ContextAwareDataPersisterInterface $dataPersister,
|
||||
PromotionInterface $promotion,
|
||||
): void {
|
||||
$dataPersister->remove($promotion, [])->willThrow(ForeignKeyConstraintViolationException::class);
|
||||
|
||||
$this->shouldThrow(PromotionCannotBeRemoved::class)->during('remove', [$promotion]);
|
||||
}
|
||||
|
||||
function it_uses_inner_persister_to_remove_promotion(
|
||||
ContextAwareDataPersisterInterface $dataPersister,
|
||||
PromotionInterface $promotion,
|
||||
): void {
|
||||
$dataPersister->remove($promotion, [])->shouldBeCalled();
|
||||
|
||||
$this->remove($promotion);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace spec\Sylius\Bundle\ApiBundle\StateProcessor\Admin\Promotion;
|
||||
|
||||
use ApiPlatform\Metadata\DeleteOperationInterface;
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProcessorInterface;
|
||||
use Doctrine\DBAL\Exception\ForeignKeyConstraintViolationException;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
use Sylius\Bundle\ApiBundle\Exception\PromotionCannotBeRemoved;
|
||||
use Sylius\Component\Core\Model\PromotionInterface;
|
||||
|
||||
final class RemoveProcessorSpec extends ObjectBehavior
|
||||
{
|
||||
function let(ProcessorInterface $removeProcessor): void
|
||||
{
|
||||
$this->beConstructedWith($removeProcessor);
|
||||
}
|
||||
|
||||
function it_is_a_processor_interface(): void
|
||||
{
|
||||
$this->shouldImplement(ProcessorInterface::class);
|
||||
}
|
||||
|
||||
public function it_processes_remove_operation(
|
||||
ProcessorInterface $removeProcessor,
|
||||
Operation $operation,
|
||||
PromotionInterface $Promotion,
|
||||
) {
|
||||
$operation->implement(DeleteOperationInterface::class);
|
||||
$removeProcessor->process($Promotion, $operation, [], [])->willReturn(null);
|
||||
|
||||
$this->process($Promotion, $operation, [], [])->shouldReturn(null);
|
||||
}
|
||||
|
||||
public function it_throws_exception_when_foreign_key_constraint_violation_occurs(
|
||||
ProcessorInterface $removeProcessor,
|
||||
Operation $operation,
|
||||
PromotionInterface $Promotion,
|
||||
) {
|
||||
$operation->implement(DeleteOperationInterface::class);
|
||||
$removeProcessor->process($Promotion, $operation, [], [])->willThrow(ForeignKeyConstraintViolationException::class);
|
||||
|
||||
$this->shouldThrow(PromotionCannotBeRemoved::class)->during('process', [$Promotion, $operation, [], []]);
|
||||
}
|
||||
|
||||
public function it_throws_exception_if_operation_is_not_delete(
|
||||
Operation $operation,
|
||||
PromotionInterface $Promotion,
|
||||
) {
|
||||
$this->shouldThrow(\InvalidArgumentException::class)->during('process', [$Promotion, $operation, [], []]);
|
||||
}
|
||||
|
||||
public function it_throws_exception_if_data_is_not_promotion_interface(
|
||||
Operation $operation,
|
||||
\stdClass $nonPromotion,
|
||||
) {
|
||||
$this->shouldThrow(\InvalidArgumentException::class)->during('process', [$nonPromotion, $operation, [], []]);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,7 +14,6 @@ declare(strict_types=1);
|
|||
namespace spec\Sylius\Bundle\ApiBundle\StateProvider\Common\Adjustment;
|
||||
|
||||
use ApiPlatform\Metadata\GetCollection;
|
||||
use ApiPlatform\Metadata\Operation;
|
||||
use ApiPlatform\State\ProviderInterface;
|
||||
use Doctrine\Common\Collections\ArrayCollection;
|
||||
use PhpSpec\ObjectBehavior;
|
||||
|
|
|
|||
86
tests/Api/Admin/PromotionsTest.php
Normal file
86
tests/Api/Admin/PromotionsTest.php
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Sylius package.
|
||||
*
|
||||
* (c) Sylius Sp. z o.o.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Sylius\Tests\Api\Admin;
|
||||
|
||||
use Sylius\Component\Core\Model\PromotionInterface;
|
||||
use Sylius\Tests\Api\JsonApiTestCase;
|
||||
use Sylius\Tests\Api\Utils\AdminUserLoginTrait;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
final class PromotionsTest extends JsonApiTestCase
|
||||
{
|
||||
use AdminUserLoginTrait;
|
||||
|
||||
/** @test */
|
||||
public function it_gets_a_promotion(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'channel.yaml', 'promotion/promotion.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var PromotionInterface $promotion */
|
||||
$promotion = $fixtures['promotion_50_off'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'GET',
|
||||
uri: sprintf('/api/v2/admin/promotions/%s', $promotion->getCode()),
|
||||
server: $header,
|
||||
);
|
||||
|
||||
$this->assertResponse(
|
||||
$this->client->getResponse(),
|
||||
'admin/promotion/get_promotion_response',
|
||||
Response::HTTP_OK,
|
||||
);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_deletes_a_promotion(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles(['authentication/api_administrator.yaml', 'channel.yaml', 'promotion/promotion.yaml']);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
|
||||
/** @var PromotionInterface $promotion */
|
||||
$promotion = $fixtures['promotion_50_off'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'DELETE',
|
||||
uri: sprintf('/api/v2/admin/promotions/%s', $promotion->getCode()),
|
||||
server: $header,
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_NO_CONTENT);
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_does_not_delete_the_promotion_in_use(): void
|
||||
{
|
||||
$fixtures = $this->loadFixturesFromFiles([
|
||||
'authentication/api_administrator.yaml',
|
||||
'channel.yaml',
|
||||
'promotion/promotion.yaml',
|
||||
'promotion/promotion_order.yaml',
|
||||
]);
|
||||
$header = array_merge($this->logInAdminUser('api@example.com'), self::CONTENT_TYPE_HEADER);
|
||||
/** @var PromotionInterface $promotion */
|
||||
$promotion = $fixtures['promotion_50_off'];
|
||||
|
||||
$this->client->request(
|
||||
method: 'DELETE',
|
||||
uri: sprintf('/api/v2/admin/promotions/%s', $promotion->getCode()),
|
||||
server: $header,
|
||||
);
|
||||
|
||||
$this->assertResponseCode($this->client->getResponse(), Response::HTTP_UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
}
|
||||
|
|
@ -25,9 +25,8 @@
|
|||
"updatedAt": "@date@",
|
||||
"translations": {
|
||||
"en_US": {
|
||||
"@id": "\/api\/v2\/admin\/promotion-translations\/@integer@",
|
||||
"@id": "\/api\/v2\/admin\/promotions\/50_off\/translations\/en_US",
|
||||
"@type": "PromotionTranslation",
|
||||
"id": "@integer@",
|
||||
"label": "-50% on first order!"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue