Skip to content

Commit 2f5acf7

Browse files
committed
Add CatalogPromotionUpdate entity and related files
1 parent 883cbaa commit 2f5acf7

11 files changed

+348
-2
lines changed

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"symfony/form": "^5.4 || ^6.4 || ^7.0",
3838
"symfony/messenger": "^5.4 || ^6.4 || ^7.0",
3939
"symfony/options-resolver": "^5.4 || ^6.4 || ^7.0",
40+
"symfony/uid": "^5.4 || ^6.4 || ^7.0",
4041
"symfony/validator": "^5.4 || ^6.4 || ^7.0",
4142
"webmozart/assert": "^1.11"
4243
},

src/Command/ProcessCommand.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace Setono\SyliusCatalogPromotionPlugin\Command;
66

7-
use Setono\SyliusCatalogPromotionPlugin\Message\Command\ProcessCatalogPromotions;
7+
use Setono\SyliusCatalogPromotionPlugin\Message\Command\StartCatalogPromotionUpdate;
88
use Symfony\Component\Console\Command\Command;
99
use Symfony\Component\Console\Input\InputInterface;
1010
use Symfony\Component\Console\Output\OutputInterface;
@@ -23,7 +23,7 @@ public function __construct(private readonly MessageBusInterface $commandBus)
2323

2424
protected function execute(InputInterface $input, OutputInterface $output): int
2525
{
26-
$this->commandBus->dispatch(new ProcessCatalogPromotions());
26+
$this->commandBus->dispatch(new StartCatalogPromotionUpdate());
2727

2828
return 0;
2929
}

src/DependencyInjection/Configuration.php

+16
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Setono\SyliusCatalogPromotionPlugin\Form\Type\PromotionRuleType;
88
use Setono\SyliusCatalogPromotionPlugin\Form\Type\PromotionType;
9+
use Setono\SyliusCatalogPromotionPlugin\Model\CatalogPromotionUpdate;
910
use Setono\SyliusCatalogPromotionPlugin\Model\Promotion;
1011
use Setono\SyliusCatalogPromotionPlugin\Model\PromotionRule;
1112
use Setono\SyliusCatalogPromotionPlugin\Repository\PromotionRepository;
@@ -37,6 +38,21 @@ private function addResourcesSection(ArrayNodeDefinition $node): void
3738
->arrayNode('resources')
3839
->addDefaultsIfNotSet()
3940
->children()
41+
->arrayNode('catalog_promotion_update')
42+
->addDefaultsIfNotSet()
43+
->children()
44+
->variableNode('options')->end()
45+
->arrayNode('classes')
46+
->addDefaultsIfNotSet()
47+
->children()
48+
->scalarNode('model')->defaultValue(CatalogPromotionUpdate::class)->cannotBeEmpty()->end()
49+
->scalarNode('controller')->defaultValue(ResourceController::class)->cannotBeEmpty()->end()
50+
->scalarNode('repository')->cannotBeEmpty()->end()
51+
->scalarNode('factory')->defaultValue(Factory::class)->end()
52+
->end()
53+
->end()
54+
->end()
55+
->end()
4056
->arrayNode('promotion')
4157
->addDefaultsIfNotSet()
4258
->children()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Factory;
6+
7+
use Setono\SyliusCatalogPromotionPlugin\Model\CatalogPromotionUpdateInterface;
8+
use Sylius\Component\Resource\Factory\FactoryInterface;
9+
use Webmozart\Assert\Assert;
10+
11+
final class CatalogPromotionUpdateFactory implements CatalogPromotionUpdateFactoryInterface
12+
{
13+
public function __construct(private readonly FactoryInterface $decorated)
14+
{
15+
}
16+
17+
public function createNew(): CatalogPromotionUpdateInterface
18+
{
19+
$obj = $this->decorated->createNew();
20+
Assert::isInstanceOf($obj, CatalogPromotionUpdateInterface::class);
21+
22+
return $obj;
23+
}
24+
25+
public function createWithCatalogPromotions(array $catalogPromotions): CatalogPromotionUpdateInterface
26+
{
27+
$obj = $this->createNew();
28+
$obj->setCatalogPromotions($catalogPromotions);
29+
30+
return $obj;
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Factory;
6+
7+
use Setono\SyliusCatalogPromotionPlugin\Model\CatalogPromotionUpdateInterface;
8+
use Sylius\Component\Resource\Factory\FactoryInterface;
9+
10+
interface CatalogPromotionUpdateFactoryInterface extends FactoryInterface
11+
{
12+
public function createNew(): CatalogPromotionUpdateInterface;
13+
14+
/**
15+
* @param list<string> $catalogPromotions
16+
*/
17+
public function createWithCatalogPromotions(array $catalogPromotions): CatalogPromotionUpdateInterface;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Message\Command;
6+
7+
use Setono\SyliusCatalogPromotionPlugin\Model\CatalogPromotionUpdateInterface;
8+
9+
final class ProcessCatalogPromotionUpdate implements AsyncCommandInterface
10+
{
11+
public readonly int $catalogPromotion;
12+
13+
public function __construct(CatalogPromotionUpdateInterface|int $catalogPromotionUpdate)
14+
{
15+
$this->catalogPromotion = $catalogPromotionUpdate instanceof CatalogPromotionUpdateInterface ? (int) $catalogPromotionUpdate->getId() : $catalogPromotionUpdate;
16+
}
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Message\Command;
6+
7+
use Setono\SyliusCatalogPromotionPlugin\Model\PromotionInterface;
8+
9+
final class StartCatalogPromotionUpdate
10+
{
11+
/**
12+
* A list of catalog promotion codes to process. If empty, all catalog promotions will be processed
13+
*
14+
* @var list<string>
15+
*/
16+
public readonly array $catalogPromotions;
17+
18+
/**
19+
* @param list<string|PromotionInterface> $catalogPromotions
20+
*/
21+
public function __construct(
22+
array $catalogPromotions = [],
23+
) {
24+
$this->catalogPromotions = array_map(
25+
static fn (string|PromotionInterface $catalogPromotion) => $catalogPromotion instanceof PromotionInterface ? (string) $catalogPromotion->getCode() : $catalogPromotion,
26+
$catalogPromotions,
27+
);
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Message\CommandHandler;
6+
7+
use Doctrine\Persistence\ManagerRegistry;
8+
use Setono\Doctrine\ORMTrait;
9+
use Setono\SyliusCatalogPromotionPlugin\Factory\CatalogPromotionUpdateFactoryInterface;
10+
use Setono\SyliusCatalogPromotionPlugin\Message\Command\ProcessCatalogPromotionUpdate;
11+
use Setono\SyliusCatalogPromotionPlugin\Message\Command\StartCatalogPromotionUpdate;
12+
use Setono\SyliusCatalogPromotionPlugin\Model\CatalogPromotionUpdateInterface;
13+
use Setono\SyliusCatalogPromotionPlugin\Model\PromotionInterface;
14+
use Setono\SyliusCatalogPromotionPlugin\Repository\PromotionRepositoryInterface;
15+
use Symfony\Component\Messenger\MessageBusInterface;
16+
17+
final class StartCatalogPromotionUpdateHandler
18+
{
19+
use ORMTrait;
20+
21+
public function __construct(
22+
private readonly PromotionRepositoryInterface $promotionRepository,
23+
private readonly CatalogPromotionUpdateFactoryInterface $catalogPromotionUpdateFactory,
24+
private readonly MessageBusInterface $commandBus,
25+
ManagerRegistry $managerRegistry,
26+
) {
27+
$this->managerRegistry = $managerRegistry;
28+
}
29+
30+
public function __invoke(StartCatalogPromotionUpdate $message): CatalogPromotionUpdateInterface
31+
{
32+
$catalogPromotions = $message->catalogPromotions;
33+
if ([] === $message->catalogPromotions) {
34+
$catalogPromotions = array_map(
35+
static fn (PromotionInterface $promotion): string => (string) $promotion->getCode(),
36+
$this->promotionRepository->findForProcessing($message->catalogPromotions),
37+
);
38+
}
39+
40+
$catalogPromotionUpdate = $this->catalogPromotionUpdateFactory->createWithCatalogPromotions($catalogPromotions);
41+
$manager = $this->getManager($catalogPromotionUpdate);
42+
$manager->persist($catalogPromotionUpdate);
43+
$manager->flush();
44+
45+
$this->commandBus->dispatch(new ProcessCatalogPromotionUpdate($catalogPromotionUpdate));
46+
47+
return $catalogPromotionUpdate;
48+
}
49+
}

src/Model/CatalogPromotionUpdate.php

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Model;
6+
7+
use Sylius\Component\Resource\Model\TimestampableTrait;
8+
use Symfony\Component\Uid\Uuid;
9+
10+
class CatalogPromotionUpdate implements CatalogPromotionUpdateInterface
11+
{
12+
use TimestampableTrait;
13+
14+
protected ?int $id = null;
15+
16+
protected int $version = 1;
17+
18+
protected string $state = self::STATE_PENDING;
19+
20+
protected string $correlationId;
21+
22+
/** @var list<string> */
23+
protected array $catalogPromotions = [];
24+
25+
protected ?int $productsEligibleForUpdate = null;
26+
27+
protected int $productsUpdated = 0;
28+
29+
public function __construct()
30+
{
31+
$this->correlationId = (string) Uuid::v7();
32+
}
33+
34+
public function getId(): ?int
35+
{
36+
return $this->id;
37+
}
38+
39+
public function getVersion(): ?int
40+
{
41+
return $this->version;
42+
}
43+
44+
public function setVersion(?int $version): void
45+
{
46+
$this->version = (int) $version;
47+
}
48+
49+
public function getState(): string
50+
{
51+
return $this->state;
52+
}
53+
54+
public function setState(string $state): void
55+
{
56+
$this->state = $state;
57+
}
58+
59+
public function getCorrelationId(): string
60+
{
61+
return $this->correlationId;
62+
}
63+
64+
public function setCorrelationId(string $correlationId): void
65+
{
66+
$this->correlationId = $correlationId;
67+
}
68+
69+
public function getCatalogPromotions(): array
70+
{
71+
return $this->catalogPromotions;
72+
}
73+
74+
public function setCatalogPromotions(array $catalogPromotions): void
75+
{
76+
$this->catalogPromotions = $catalogPromotions;
77+
}
78+
79+
public function getProductsEligibleForUpdate(): ?int
80+
{
81+
return $this->productsEligibleForUpdate;
82+
}
83+
84+
public function setProductsEligibleForUpdate(int $productsEligibleForUpdate): void
85+
{
86+
$this->productsEligibleForUpdate = $productsEligibleForUpdate;
87+
}
88+
89+
public function getProductsUpdated(): int
90+
{
91+
return $this->productsUpdated;
92+
}
93+
94+
public function setProductsUpdated(int $productsUpdated): void
95+
{
96+
$this->productsUpdated = $productsUpdated;
97+
}
98+
99+
public function incrementProductsUpdated(int $increment = 1): void
100+
{
101+
$this->productsUpdated += $increment;
102+
}
103+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusCatalogPromotionPlugin\Model;
6+
7+
use Sylius\Component\Resource\Model\ResourceInterface;
8+
use Sylius\Component\Resource\Model\TimestampableInterface;
9+
use Sylius\Component\Resource\Model\VersionedInterface;
10+
11+
interface CatalogPromotionUpdateInterface extends ResourceInterface, TimestampableInterface, VersionedInterface
12+
{
13+
public const STATE_PENDING = 'pending';
14+
15+
public const STATE_PROCESSING = 'processing';
16+
17+
public const STATE_COMPLETED = 'completed';
18+
19+
public const STATE_FAILED = 'failed';
20+
21+
public function getId(): ?int;
22+
23+
public function getState(): string;
24+
25+
public function setState(string $state): void;
26+
27+
public function getCorrelationId(): string;
28+
29+
public function setCorrelationId(string $correlationId): void;
30+
31+
/**
32+
* A list of catalog promotions codes that the update is for
33+
*
34+
* @return list<string>
35+
*/
36+
public function getCatalogPromotions(): array;
37+
38+
/**
39+
* @param list<string> $catalogPromotions
40+
*/
41+
public function setCatalogPromotions(array $catalogPromotions): void;
42+
43+
/**
44+
* The number of products that are eligible for update. This should be set when the update is created
45+
*/
46+
public function getProductsEligibleForUpdate(): ?int;
47+
48+
public function setProductsEligibleForUpdate(int $productsEligibleForUpdate): void;
49+
50+
public function getProductsUpdated(): int;
51+
52+
public function setProductsUpdated(int $productsUpdated): void;
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<doctrine-mapping xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
6+
xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping
7+
http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
8+
<mapped-superclass name="Setono\SyliusCatalogPromotionPlugin\Model\CatalogPromotionUpdate"
9+
table="setono_sylius_catalog_promotion__catalog_promotion_update">
10+
<id name="id" type="integer">
11+
<generator strategy="AUTO"/>
12+
</id>
13+
14+
<field name="version" type="integer" version="true"/>
15+
<field name="state"/>
16+
<field name="correlationId"/>
17+
<field name="catalogPromotions" type="json"/>
18+
<field name="productsEligibleForUpdate" type="integer"/>
19+
<field name="productsUpdated" type="integer"/>
20+
21+
<field name="createdAt" column="created_at" type="datetime">
22+
<gedmo:timestampable on="create"/>
23+
</field>
24+
<field name="updatedAt" column="updated_at" type="datetime" nullable="true">
25+
<gedmo:timestampable on="update"/>
26+
</field>
27+
</mapped-superclass>
28+
</doctrine-mapping>

0 commit comments

Comments
 (0)