Skip to content

Commit

Permalink
refactor #13624 [CatalogPromotions] Refactor processing catalog promo…
Browse files Browse the repository at this point in the history
…tions states to use commands (GSadee)

This PR was merged into the 1.11 branch.

Discussion
----------

| Q               | A
| --------------- | -----
| Branch?         | 1.11
| Bug fix?        | no
| New feature?    | no
| BC breaks?      | no
| Deprecations?   | no
| Related tickets | 
| License         | MIT

<!--
 - Bug fixes must be submitted against the 1.10 or 1.11 branch(the lowest possible)
 - Features and deprecations must be submitted against the master 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
-->


Commits
-------

7249a33 [CatalogPromotions] Refactor processing catalog promotions states to use commands
  • Loading branch information
lchrusciel authored Feb 9, 2022
2 parents 6a51d9f + 7249a33 commit 03cd14f
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 95 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?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\CatalogPromotion\Command;

final class UpdateCatalogPromotionState
{
public function __construct(public string $code)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?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\CatalogPromotion\CommandHandler;

use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Bundle\CoreBundle\Processor\CatalogPromotionStateProcessorInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;

final class UpdateCatalogPromotionStateHandler
{
public function __construct(
private CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
private RepositoryInterface $catalogPromotionRepository
) {
}

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

$this->catalogPromotionStateProcessor->process($catalogPromotion);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,22 @@

namespace Sylius\Bundle\CoreBundle\Fixture\Listener;

use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Bundle\CoreBundle\Fixture\CatalogPromotionFixture;
use Sylius\Bundle\CoreBundle\Processor\AllProductVariantsCatalogPromotionsProcessorInterface;
use Sylius\Bundle\CoreBundle\Processor\CatalogPromotionStateProcessorInterface;
use Sylius\Bundle\FixturesBundle\Listener\AbstractListener;
use Sylius\Bundle\FixturesBundle\Listener\AfterFixtureListenerInterface;
use Sylius\Bundle\FixturesBundle\Listener\FixtureEvent;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Promotion\Repository\CatalogPromotionRepositoryInterface;
use Symfony\Component\Messenger\MessageBusInterface;

final class CatalogPromotionExecutorListener extends AbstractListener implements AfterFixtureListenerInterface
{
public function __construct(
private AllProductVariantsCatalogPromotionsProcessorInterface $allCatalogPromotionsProcessor,
private CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
private CatalogPromotionRepositoryInterface $catalogPromotionsRepository,
private MessageBusInterface $messageBus,
private iterable $defaultCriteria = []
) {
}
Expand All @@ -41,8 +43,9 @@ public function afterFixture(FixtureEvent $fixtureEvent, array $options): void

$catalogPromotions = $this->catalogPromotionsRepository->findByCriteria($this->defaultCriteria);

/** @var CatalogPromotionInterface $catalogPromotion */
foreach ($catalogPromotions as $catalogPromotion) {
$this->catalogPromotionStateProcessor->process($catalogPromotion);
$this->messageBus->dispatch(new UpdateCatalogPromotionState($catalogPromotion->getCode()));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,20 @@

namespace Sylius\Bundle\CoreBundle\Listener;

use Doctrine\ORM\EntityManagerInterface;
use Sylius\Bundle\CoreBundle\Processor\CatalogPromotionStateProcessorInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Component\Promotion\Event\CatalogPromotionCreated;
use Sylius\Component\Promotion\Event\CatalogPromotionEnded;
use Sylius\Component\Promotion\Event\CatalogPromotionUpdated;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Symfony\Component\Messenger\MessageBusInterface;

final class CatalogPromotionStateChangedListener
{
public function __construct(
private CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
private RepositoryInterface $catalogPromotionRepository,
private EntityManagerInterface $entityManager
) {
public function __construct(private MessageBusInterface $messageBus)
{
}

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

$this->catalogPromotionStateProcessor->process($catalogPromotion);

$this->entityManager->flush();
$this->messageBus->dispatch(new UpdateCatalogPromotionState($event->code));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ framework:

routing:
'Sylius\Bundle\CoreBundle\Command\ApplyCatalogPromotionsOnVariants': main
'Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState': main
'Sylius\Component\Promotion\Event\CatalogPromotionCreated': main
'Sylius\Component\Promotion\Event\CatalogPromotionEnded': main
'Sylius\Component\Promotion\Event\CatalogPromotionUpdated': main
Expand Down
6 changes: 6 additions & 0 deletions src/Sylius/Bundle/CoreBundle/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,12 @@
<tag name="messenger.message_handler" bus="sylius.command_bus" />
</service>

<service id="Sylius\Bundle\CoreBundle\CatalogPromotion\CommandHandler\UpdateCatalogPromotionStateHandler">
<argument type="service" id="Sylius\Bundle\CoreBundle\Processor\CatalogPromotionStateProcessorInterface" />
<argument type="service" id="sylius.repository.catalog_promotion" />
<tag name="messenger.message_handler" bus="sylius.command_bus" />
</service>

<service
id="Sylius\Bundle\CoreBundle\Checker\ProductVariantForCatalogPromotionEligibilityInterface"
class="Sylius\Bundle\CoreBundle\Checker\ProductVariantForCatalogPromotionEligibility"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

<service id="sylius_fixtures.listener.catalog_promotion_executor" class="Sylius\Bundle\CoreBundle\Fixture\Listener\CatalogPromotionExecutorListener" public="false">
<argument type="service" id="Sylius\Bundle\CoreBundle\Processor\AllProductVariantsCatalogPromotionsProcessorInterface" />
<argument type="service" id="Sylius\Bundle\CoreBundle\Processor\CatalogPromotionStateProcessorInterface" />
<argument type="service" id="Sylius\Bundle\PromotionBundle\Doctrine\ORM\CatalogPromotionRepository" />
<argument type="service" id="sylius.command_bus" />
<argument type="tagged_iterator" tag="sylius.catalog_promotion.criteria" />
<tag name="sylius_fixtures.listener" />
</service>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,7 @@
</service>

<service id="Sylius\Bundle\CoreBundle\Listener\CatalogPromotionStateChangedListener">
<argument type="service" id="Sylius\Bundle\CoreBundle\Processor\CatalogPromotionStateProcessorInterface" />
<argument type="service" id="sylius.repository.catalog_promotion" />
<argument type="service" id="doctrine.orm.entity_manager" />
<argument type="service" id="sylius.command_bus" />
<tag name="messenger.message_handler" bus="sylius.event_bus" />
</service>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?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\CoreBundle\CatalogPromotion\CommandHandler;

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Bundle\CoreBundle\Processor\CatalogPromotionStateProcessorInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;

final class UpdateCatalogPromotionStateHandlerSpec extends ObjectBehavior
{
function let(
CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
RepositoryInterface $catalogPromotionRepository
): void {
$this->beConstructedWith($catalogPromotionStateProcessor, $catalogPromotionRepository);
}

function it_processes_catalog_promotion_that_has_just_been_created(
CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
RepositoryInterface $catalogPromotionRepository,
CatalogPromotionInterface $catalogPromotion
): void {
$catalogPromotionRepository->findOneBy(['code' => 'WINTER_MUGS_SALE'])->willReturn($catalogPromotion);

$catalogPromotionStateProcessor->process($catalogPromotion)->shouldBeCalled();

$this(new UpdateCatalogPromotionState('WINTER_MUGS_SALE'));
}

function it_processes_catalog_promotion_that_has_just_been_updated(
CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
RepositoryInterface $catalogPromotionRepository,
CatalogPromotionInterface $catalogPromotion
): void {
$catalogPromotionRepository->findOneBy(['code' => 'WINTER_MUGS_SALE'])->willReturn($catalogPromotion);

$catalogPromotionStateProcessor->process($catalogPromotion)->shouldBeCalled();

$this(new UpdateCatalogPromotionState('WINTER_MUGS_SALE'));
}

function it_processes_catalog_promotion_that_has_just_been_ended(
CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
RepositoryInterface $catalogPromotionRepository,
CatalogPromotionInterface $catalogPromotion
): void {
$catalogPromotionRepository->findOneBy(['code' => 'WINTER_MUGS_SALE'])->willReturn($catalogPromotion);

$catalogPromotionStateProcessor->process($catalogPromotion)->shouldBeCalled();

$this(new UpdateCatalogPromotionState('WINTER_MUGS_SALE'));
}

function it_does_nothing_if_there_is_no_catalog_promotion_with_given_code(
CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
RepositoryInterface $catalogPromotionRepository
): void {
$catalogPromotionRepository->findOneBy(['code' => 'WINTER_MUGS_SALE'])->willReturn(null);
$catalogPromotionRepository->findAll()->shouldNotBeCalled();

$catalogPromotionStateProcessor->process(Argument::any())->shouldNotBeCalled();

$this(new UpdateCatalogPromotionState('WINTER_MUGS_SALE'));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
namespace spec\Sylius\Bundle\CoreBundle\Fixture\Listener;

use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Bundle\CoreBundle\CatalogPromotion\Command\UpdateCatalogPromotionState;
use Sylius\Bundle\CoreBundle\Fixture\CatalogPromotionFixture;
use Sylius\Bundle\CoreBundle\Processor\AllProductVariantsCatalogPromotionsProcessorInterface;
use Sylius\Bundle\CoreBundle\Processor\CatalogPromotionStateProcessorInterface;
use Sylius\Bundle\FixturesBundle\Fixture\FixtureInterface;
use Sylius\Bundle\FixturesBundle\Listener\AfterFixtureListenerInterface;
use Sylius\Bundle\FixturesBundle\Listener\FixtureEvent;
Expand All @@ -25,20 +26,22 @@
use Sylius\Bundle\PromotionBundle\Criteria\CriteriaInterface;
use Sylius\Component\Core\Model\CatalogPromotionInterface;
use Sylius\Component\Promotion\Repository\CatalogPromotionRepositoryInterface;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\MessageBusInterface;

final class CatalogPromotionExecutorListenerSpec extends ObjectBehavior
{
function let(
AllProductVariantsCatalogPromotionsProcessorInterface $allCatalogPromotionsProcessor,
CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
CatalogPromotionRepositoryInterface $catalogPromotionRepository,
MessageBusInterface $messageBus,
CriteriaInterface $firstCriterion,
CriteriaInterface $secondCriterion
): void {
$this->beConstructedWith(
$allCatalogPromotionsProcessor,
$catalogPromotionStateProcessor,
$catalogPromotionRepository,
$messageBus,
[$firstCriterion, $secondCriterion]
);
}
Expand All @@ -55,10 +58,10 @@ function it_listens_for_after_fixture_events(): void

function it_triggers_catalog_promotion_processing_after_catalog_promotion_fixture_execution(
AllProductVariantsCatalogPromotionsProcessorInterface $allCatalogPromotionsProcessor,
CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
CatalogPromotionRepositoryInterface $catalogPromotionRepository,
MessageBusInterface $messageBus,
SuiteInterface $suite,
CatalogPromotionFixture $catalogPromotionFixture,
CatalogPromotionRepositoryInterface $catalogPromotionRepository,
CatalogPromotionInterface $firstCatalogPromotion,
CatalogPromotionInterface $secondCatalogPromotion,
CriteriaInterface $firstCriterion,
Expand All @@ -69,27 +72,32 @@ function it_triggers_catalog_promotion_processing_after_catalog_promotion_fixtur
->willReturn([$firstCatalogPromotion, $secondCatalogPromotion])
;

$this->afterFixture(new FixtureEvent($suite->getWrappedObject(), $catalogPromotionFixture->getWrappedObject(), []), []);
$firstCatalogPromotion->getCode()->willReturn('WINTER');
$secondCatalogPromotion->getCode()->willReturn('AUTUMN');

$allCatalogPromotionsProcessor->process()->shouldBeCalled();
$catalogPromotionStateProcessor->process($firstCatalogPromotion)->shouldBeCalled();
$catalogPromotionStateProcessor->process($secondCatalogPromotion)->shouldBeCalled();

$firstCommand = new UpdateCatalogPromotionState('WINTER');
$messageBus->dispatch($firstCommand)->willReturn(new Envelope($firstCommand))->shouldBeCalled();

$secondCommand = new UpdateCatalogPromotionState('AUTUMN');
$messageBus->dispatch($secondCommand)->willReturn(new Envelope($secondCommand))->shouldBeCalled();

$this->afterFixture(new FixtureEvent($suite->getWrappedObject(), $catalogPromotionFixture->getWrappedObject(), []), []);
}

function it_does_not_trigger_catalog_promotion_processing_after_any_other_fixture_execution(
AllProductVariantsCatalogPromotionsProcessorInterface $allCatalogPromotionsProcessor,
CatalogPromotionStateProcessorInterface $catalogPromotionStateProcessor,
CatalogPromotionRepositoryInterface $catalogPromotionRepository,
MessageBusInterface $messageBus,
SuiteInterface $suite,
FixtureInterface $fixture,
CatalogPromotionRepositoryInterface $catalogPromotionRepository,
CriteriaInterface $firstCriterion,
CriteriaInterface $secondCriterion
): void {
$catalogPromotionRepository->findByCriteria([$firstCriterion, $secondCriterion])->shouldNotBeCalled();

$this->afterFixture(new FixtureEvent($suite->getWrappedObject(), $fixture->getWrappedObject(), []), []);
$messageBus->dispatch(Argument::any())->shouldNotBeCalled();

$allCatalogPromotionsProcessor->process()->shouldNotBeCalled();
$catalogPromotionStateProcessor->process()->shouldNotBeCalled();
$this->afterFixture(new FixtureEvent($suite->getWrappedObject(), $fixture->getWrappedObject(), []), []);
}
}
Loading

0 comments on commit 03cd14f

Please sign in to comment.