Skip to content

Commit

Permalink
feature #13131 [CatalogPromotions][API] Reapply promotions after acti…
Browse files Browse the repository at this point in the history
…on removal (arti0090)

This PR was merged into the 1.11-dev branch.

Discussion
----------

| Q               | A
| --------------- | -----
| Branch?         | master 
| Bug fix?        | no
| New feature?    | yes
| BC breaks?      | no
| Deprecations?   | no
| License         | MIT


Commits
-------

76641e8 [CatalogPromotions][API] Reapply promotions after action removal
074f306 Remove apply from removing listener
4780fa9 Remove apply from removing listener
0203c74 Refactor duplicated code to new class
2e189ec Rebase, commit before change to Event Subscribers
547f3b6 Change the event to API events
7d8b2f1 Remove unneded logic and hcange method name
  • Loading branch information
GSadee authored Sep 29, 2021
2 parents 15d38e9 + 7d8b2f1 commit 9e778cd
Show file tree
Hide file tree
Showing 12 changed files with 290 additions and 52 deletions.
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 @ui @javascript
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 @ui @javascript
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 @ui @javascript
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 @@ -230,7 +230,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 @@ -281,6 +281,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

0 comments on commit 9e778cd

Please sign in to comment.