Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CatalogPromotions][API] Reapply promotions after action removal #13131

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,44 @@ Feature: Reapplying catalog promotion after editing its action
When I modify a catalog promotion "Summer sale"
And I add action that gives "25%" percentage discount
And I save my changes
Then the visitor view "Python T-Shirt" variant
And this product variant price should be "$7.50"
And the visitor view "Python T-Shirt" variant
Then this product variant price should be "$7.50"
And this product original price should be "$10.00"

@api
Scenario: Reapplying catalog promotion after editing its action
When I modify a catalog promotion "Winter sale"
And I edit its action so that it reduces price by "25%"
And I save my changes
Then the visitor view "PHP T-Shirt" variant
And this product variant price should be "$15.00"
And the visitor view "PHP T-Shirt" variant
Then this product variant price should be "$15.00"
And this product original price should be "$20.00"

@api
Scenario: Reapplying catalog promotion after removing and adding new action
When I modify a catalog promotion "Winter sale"
And I remove its every action
And I save my changes
And I add action that gives "10%" percentage discount
And I save my changes
Then the visitor view "PHP T-Shirt" variant
And this product variant price should be "$18.00"
And the visitor view "PHP T-Shirt" variant
Then this product variant price should be "$18.00"
And this product original price should be "$20.00"

@api
Scenario: Reapplying catalog promotion after adding another action
When I modify a catalog promotion "Winter sale"
And I add another action that gives "10%" percentage discount
And I save my changes
Then the visitor view "PHP T-Shirt" variant
And this product variant price should be "$9.00"
And the visitor view "PHP T-Shirt" variant
Then this product variant price should be "$9.00"
And this product original price should be "$20.00"

@api
Scenario: Restoring original price after removing action from catalog promotion configuration
When I modify a catalog promotion "Winter sale"
And I remove its every action
And I save my changes
And the visitor view "PHP T-Shirt" variant
Then the product variant price should be "$20.00"
And the product original price should be "$20.00"
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public function iRemoveItsEveryAction(): void
{
$content = $this->client->getContent();
$content['actions'] = [];
$this->client->updateRequestData($content);
$this->client->setRequestData($content);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* 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\EventSubscriber;

use ApiPlatform\Core\EventListener\EventPriorities;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionUpdated;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Messenger\MessageBusInterface;

final class CatalogPromotionEventSubscriber implements EventSubscriberInterface
{
private MessageBusInterface $eventBus;

public function __construct(MessageBusInterface $eventBus)
{
$this->eventBus = $eventBus;
}

public static function getSubscribedEvents(): array
{
return [
KernelEvents::VIEW => ['postWrite', EventPriorities::POST_WRITE],
];
}

public function postWrite(ViewEvent $event): void
{
$entity = $event->getControllerResult();

if (!$entity instanceof CatalogPromotionInterface) {
return;
}

$method = $event->getRequest()->getMethod();

if ($method === Request::METHOD_PUT || $method === Request::METHOD_PATCH) {
$this->eventBus->dispatch(new CatalogPromotionUpdated($entity->getCode()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@
<tag name="kernel.event_subscriber" />
</service>

<service id="Sylius\Bundle\ApiBundle\EventSubscriber\CatalogPromotionEventSubscriber">
<argument type="service" id="sylius.event_bus" />
<tag name="kernel.event_subscriber" />
</service>

<service id="Sylius\Bundle\ApiBundle\EventSubscriber\KernelRequestEventSubscriber">
<argument>%sylius_api.enabled%</argument>
<argument>%sylius.security.new_api_route%</argument>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* 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\EventSubscriber;

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Component\Core\Event\ProductVariantUpdated;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Core\Model\ProductVariantInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionUpdated;
use Sylius\Component\Promotion\Model\CatalogPromotionActionInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;

final class CatalogPromotionEventSubscriberSpec extends ObjectBehavior
{
function let(MessageBusInterface $eventBus): void
{
$this->beConstructedWith($eventBus);
}

function it_dispatches_catalog_promotion_updated_after_writing_catalog_promotion(
MessageBusInterface $eventBus,
CatalogPromotionInterface $catalogPromotion,
HttpKernelInterface $kernel,
Request $request
): void {
$request->getMethod()->willReturn(Request::METHOD_PUT);

$catalogPromotion->getCode()->willReturn('Winter_sale');

$message = new CatalogPromotionUpdated('Winter_sale');
$eventBus->dispatch($message)->willReturn(new Envelope($message))->shouldBeCalled();

$this->postWrite(new ViewEvent(
$kernel->getWrappedObject(),
$request->getWrappedObject(),
HttpKernelInterface::MASTER_REQUEST,
$catalogPromotion->getWrappedObject()
));
}

function it_does_nothing_after_writing_other_entity(
MessageBusInterface $eventBus,
HttpKernelInterface $kernel,
Request $request
): void {
$eventBus->dispatch(Argument::any())->shouldNotBeCalled();

$this->postWrite(new ViewEvent(
$kernel->getWrappedObject(),
$request->getWrappedObject(),
HttpKernelInterface::MASTER_REQUEST,
new \stdClass()
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,35 @@
namespace Sylius\Bundle\CoreBundle\Listener;

use Doctrine\ORM\EntityManagerInterface;
use Sylius\Bundle\CoreBundle\Processor\CatalogPromotionClearerInterface;
use Sylius\Bundle\CoreBundle\Processor\CatalogPromotionProcessorInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Bundle\CoreBundle\Processor\AllCatalogPromotionsProcessorInterface;
use Sylius\Component\Promotion\Event\CatalogPromotionUpdated;
use Sylius\Component\Resource\Repository\RepositoryInterface;

final class CatalogPromotionUpdateListener
{
private CatalogPromotionClearerInterface $catalogPromotionClearer;

private CatalogPromotionProcessorInterface $catalogPromotionProcessor;
private AllCatalogPromotionsProcessorInterface $catalogPromotionsProcessor;

private RepositoryInterface $catalogPromotionRepository;

private EntityManagerInterface $entityManager;

public function __construct(
CatalogPromotionClearerInterface $catalogPromotionClearer,
CatalogPromotionProcessorInterface $catalogPromotionProcessor,
AllCatalogPromotionsProcessorInterface $catalogPromotionsProcessor,
RepositoryInterface $catalogPromotionRepository,
EntityManagerInterface $entityManager
) {
$this->catalogPromotionClearer = $catalogPromotionClearer;
$this->catalogPromotionProcessor = $catalogPromotionProcessor;
$this->catalogPromotionsProcessor = $catalogPromotionsProcessor;
$this->catalogPromotionRepository = $catalogPromotionRepository;
$this->entityManager = $entityManager;
}

public function __invoke(CatalogPromotionUpdated $event): void
{
/** @var CatalogPromotionInterface|null $catalogPromotion */
$catalogPromotion = $this->catalogPromotionRepository->findOneBy(['code' => $event->code]);
if ($catalogPromotion === null) {
if (null === $this->catalogPromotionRepository->findOneBy(['code' => $event->code])) {
return;
}

$this->catalogPromotionClearer->clear();

foreach ($this->catalogPromotionRepository->findAll() as $catalogPromotion) {
$this->catalogPromotionProcessor->process($catalogPromotion);
}
$this->catalogPromotionsProcessor->process();

$this->entityManager->flush();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* 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\CoreBundle\Processor;

use Sylius\Component\Resource\Repository\RepositoryInterface;

final class AllCatalogPromotionsProcessor implements AllCatalogPromotionsProcessorInterface
{
private CatalogPromotionClearerInterface $catalogPromotionClearer;

private CatalogPromotionProcessorInterface $catalogPromotionProcessor;

private RepositoryInterface $catalogPromotionRepository;

public function __construct(
CatalogPromotionClearerInterface $catalogPromotionClearer,
CatalogPromotionProcessorInterface $catalogPromotionProcessor,
RepositoryInterface $catalogPromotionRepository
) {
$this->catalogPromotionClearer = $catalogPromotionClearer;
$this->catalogPromotionProcessor = $catalogPromotionProcessor;
$this->catalogPromotionRepository = $catalogPromotionRepository;
}

public function process(): void
{
$this->catalogPromotionClearer->clear();

foreach ($this->catalogPromotionRepository->findAll() as $catalogPromotion) {
$this->catalogPromotionProcessor->process($catalogPromotion);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* 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\CoreBundle\Processor;

interface AllCatalogPromotionsProcessorInterface
{
public function process(): void;
}
9 changes: 9 additions & 0 deletions src/Sylius/Bundle/CoreBundle/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,15 @@
<argument type="service" id="Sylius\Bundle\CoreBundle\Applicator\CatalogPromotionApplicatorInterface" />
</service>

<service
id="Sylius\Bundle\CoreBundle\Processor\AllCatalogPromotionsProcessor"
class="Sylius\Bundle\CoreBundle\Processor\AllCatalogPromotionsProcessor"
>
<argument type="service" id="Sylius\Bundle\CoreBundle\Processor\CatalogPromotionClearerInterface" />
<argument type="service" id="Sylius\Bundle\CoreBundle\Processor\CatalogPromotionProcessorInterface" />
<argument type="service" id="sylius.repository.catalog_promotion" />
</service>

<service
id="Sylius\Bundle\CoreBundle\Processor\CatalogPromotionClearerInterface"
class="Sylius\Bundle\CoreBundle\Processor\CatalogPromotionClearer"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@
</service>

<service id="Sylius\Bundle\CoreBundle\Listener\CatalogPromotionUpdateListener">
<argument type="service" id="Sylius\Bundle\CoreBundle\Processor\CatalogPromotionClearerInterface" />
<argument type="service" id="Sylius\Bundle\CoreBundle\Processor\CatalogPromotionProcessorInterface" />
<argument type="service" id="Sylius\Bundle\CoreBundle\Processor\AllCatalogPromotionsProcessor" />
<argument type="service" id="sylius.repository.catalog_promotion" />
<argument type="service" id="doctrine.orm.entity_manager" />
<tag name="messenger.message_handler" bus="sylius.event_bus" />
Expand Down
Loading