diff --git a/composer.json b/composer.json
index 3e9fa1a6..9a1f7903 100644
--- a/composer.json
+++ b/composer.json
@@ -14,7 +14,7 @@
"spryker/mail": "^4.6.0",
"spryker/mail-extension": "^1.0.0",
"spryker/message-broker": "^1.2.1",
- "spryker/oms-extension": "^1.3.0",
+ "spryker/oms-extension": "^1.4.0",
"spryker/propel": "^3.28.0",
"spryker/propel-orm": "^1.16.0",
"spryker/sales": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^10.0.0 || ^11.0.0",
diff --git a/src/Spryker/Shared/Oms/Transfer/oms.transfer.xml b/src/Spryker/Shared/Oms/Transfer/oms.transfer.xml
index bc2d554d..6a6c69ac 100644
--- a/src/Spryker/Shared/Oms/Transfer/oms.transfer.xml
+++ b/src/Spryker/Shared/Oms/Transfer/oms.transfer.xml
@@ -281,4 +281,10 @@
+
+
+
+
+
+
diff --git a/src/Spryker/Zed/Oms/Business/Notifier/EventTriggeredNotifier.php b/src/Spryker/Zed/Oms/Business/Notifier/EventTriggeredNotifier.php
new file mode 100644
index 00000000..bb457486
--- /dev/null
+++ b/src/Spryker/Zed/Oms/Business/Notifier/EventTriggeredNotifier.php
@@ -0,0 +1,56 @@
+
+ */
+ protected array $omsEventTriggeredListenerPlugins;
+
+ /**
+ * @param array<\Spryker\Zed\OmsExtension\Dependency\Plugin\OmsEventTriggeredListenerPluginInterface> $omsEventTriggeredListenerPlugins
+ */
+ public function __construct(array $omsEventTriggeredListenerPlugins)
+ {
+ $this->omsEventTriggeredListenerPlugins = $omsEventTriggeredListenerPlugins;
+ }
+
+ /**
+ * @param string $idEvent
+ * @param array<\Orm\Zed\Sales\Persistence\SpySalesOrderItem> $orderItems
+ * @param \Orm\Zed\Sales\Persistence\SpySalesOrder $orderEntity
+ * @param \Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject $data
+ *
+ * @return void
+ */
+ public function notifyOmsEventTriggeredListeners(string $idEvent, array $orderItems, SpySalesOrder $orderEntity, ReadOnlyArrayObject $data): void
+ {
+ $orderItemIds = array_map(function (SpySalesOrderItem $orderItem) {
+ return $orderItem->getIdSalesOrderItem();
+ }, $orderItems);
+
+ $omsEventTriggeredTransfer = (new OmsEventTriggeredTransfer())
+ ->setIdEvent($idEvent)
+ ->setOrderItemIds($orderItemIds)
+ ->setIdSalesOrder($orderEntity->getIdSalesOrder())
+ ->setEventData($data->getArrayCopy());
+
+ foreach ($this->omsEventTriggeredListenerPlugins as $omsEventTriggeredListener) {
+ if ($omsEventTriggeredListener->isApplicable($omsEventTriggeredTransfer)) {
+ $omsEventTriggeredListener->onEventTriggered($omsEventTriggeredTransfer);
+ }
+ }
+ }
+}
diff --git a/src/Spryker/Zed/Oms/Business/Notifier/EventTriggeredNotifierInterface.php b/src/Spryker/Zed/Oms/Business/Notifier/EventTriggeredNotifierInterface.php
new file mode 100644
index 00000000..31b124e5
--- /dev/null
+++ b/src/Spryker/Zed/Oms/Business/Notifier/EventTriggeredNotifierInterface.php
@@ -0,0 +1,24 @@
+ $orderItems
+ * @param \Orm\Zed\Sales\Persistence\SpySalesOrder $orderEntity
+ * @param \Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject $data
+ *
+ * @return void
+ */
+ public function notifyOmsEventTriggeredListeners(string $idEvent, array $orderItems, SpySalesOrder $orderEntity, ReadOnlyArrayObject $data);
+}
diff --git a/src/Spryker/Zed/Oms/Business/OmsBusinessFactory.php b/src/Spryker/Zed/Oms/Business/OmsBusinessFactory.php
index e12693da..5cd04f6a 100644
--- a/src/Spryker/Zed/Oms/Business/OmsBusinessFactory.php
+++ b/src/Spryker/Zed/Oms/Business/OmsBusinessFactory.php
@@ -20,6 +20,8 @@
use Spryker\Zed\Oms\Business\Expander\StateHistoryExpanderInterface;
use Spryker\Zed\Oms\Business\Lock\TriggerLocker;
use Spryker\Zed\Oms\Business\Mail\MailHandler;
+use Spryker\Zed\Oms\Business\Notifier\EventTriggeredNotifier;
+use Spryker\Zed\Oms\Business\Notifier\EventTriggeredNotifierInterface;
use Spryker\Zed\Oms\Business\OrderStateMachine\Builder;
use Spryker\Zed\Oms\Business\OrderStateMachine\Finder;
use Spryker\Zed\Oms\Business\OrderStateMachine\LockedOrderStateMachine;
@@ -89,9 +91,18 @@ public function createOrderStateMachine(array $logContext = [])
$this->getProvidedDependency(OmsDependencyProvider::COMMAND_PLUGINS),
$this->createUtilReservation(),
$this->getConfig(),
+ $this->createEventTriggeredNotifier(),
);
}
+ /**
+ * @return \Spryker\Zed\Oms\Business\Notifier\EventTriggeredNotifierInterface
+ */
+ public function createEventTriggeredNotifier(): EventTriggeredNotifierInterface
+ {
+ return new EventTriggeredNotifier($this->getOmsEventTriggeredListenerPlugins());
+ }
+
/**
* @param array $logContext
*
@@ -573,4 +584,12 @@ public function createOrderStatusChangedMessageSender(): OrderStatusChangedMessa
{
return new OrderStatusChangedMessageSender($this->getMessageBrokerFacade(), $this->getStoreFacade(), $this->getSalesFacade(), $this->getConfig(), $this->getQueryContainer());
}
+
+ /**
+ * @return array<\Spryker\Zed\OmsExtension\Dependency\Plugin\OmsEventTriggeredListenerPluginInterface>
+ */
+ public function getOmsEventTriggeredListenerPlugins(): array
+ {
+ return $this->getProvidedDependency(OmsDependencyProvider::PLUGINS_OMS_EVENT_TRIGGERED_LISTENER);
+ }
}
diff --git a/src/Spryker/Zed/Oms/Business/OmsFacadeInterface.php b/src/Spryker/Zed/Oms/Business/OmsFacadeInterface.php
index 5342fba9..55390f77 100644
--- a/src/Spryker/Zed/Oms/Business/OmsFacadeInterface.php
+++ b/src/Spryker/Zed/Oms/Business/OmsFacadeInterface.php
@@ -86,6 +86,7 @@ public function isOrderFlaggedExcludeFromCustomer($idOrder);
* - Calls condition plugins
* - Sets timeouts for timeout events
* - Triggers item reservation plugins
+ * - Notified listeners about event handling
* - Unlocks state machine trigger
* - Returns an array with data aggregated from the state machine plugins and an `OmsEventTriggerResponseTransfer` by the key `\Spryker\Zed\Oms\OmsConfig::OMS_EVENT_TRIGGER_RESPONSE`.
* - If command plugins execution ends without issues `OmsEventTriggerResponse.isSuccessful = true`.
@@ -113,6 +114,7 @@ public function triggerEventForOrderItems($eventId, array $orderItemIds, array $
* - Calls condition plugins
* - Sets timeouts for timeout events
* - Triggers item reservation plugins
+ * - Notified listeners about event handling
* - Unlocks state machine trigger
* - Returns an array with data aggregated from the state machine plugins and an `OmsEventTriggerResponseTransfer` by the key `\Spryker\Zed\Oms\OmsConfig::OMS_EVENT_TRIGGER_RESPONSE`.
* - If command plugins execution ends without issues `OmsEventTriggerResponse.isSuccessful = true`.
@@ -138,6 +140,7 @@ public function triggerEventForNewOrderItems(array $orderItemIds, array $data =
* - Calls condition plugins
* - Sets timeouts for timeout events
* - Triggers item reservation plugins
+ * - Notified listeners about event handling
* - Unlocks state machine trigger
* - Returns an array with data aggregated from the state machine plugins and an `OmsEventTriggerResponseTransfer` by the key `\Spryker\Zed\Oms\OmsConfig::OMS_EVENT_TRIGGER_RESPONSE`.
* - If command plugins execution ends without issues `OmsEventTriggerResponse.isSuccessful = true`.
@@ -370,6 +373,7 @@ public function getStateDisplayName(SpySalesOrderItem $orderItem);
* - Calls condition plugins
* - Sets timeouts for timeout events
* - Triggers item reservation plugins
+ * - Notified listeners about event handling
* - Unlocks state machine trigger
* - Returns an array with data aggregated from the state machine plugins and an `OmsEventTriggerResponseTransfer` by the key `\Spryker\Zed\Oms\OmsConfig::OMS_EVENT_TRIGGER_RESPONSE`.
* - If command plugins execution ends without issues `OmsEventTriggerResponse.isSuccessful = true`.
@@ -397,6 +401,7 @@ public function triggerEvent($eventId, ObjectCollection $orderItems, array $logC
* - Calls condition plugins
* - Sets timeouts for timeout events
* - Triggers item reservation plugins
+ * - Notified listeners about event handling
* - Unlocks state machine trigger
* - Returns an array with data aggregated from the state machine plugins and an `OmsEventTriggerResponseTransfer` by the key `\Spryker\Zed\Oms\OmsConfig::OMS_EVENT_TRIGGER_RESPONSE`.
* - If command plugins execution ends without issues `OmsEventTriggerResponse.isSuccessful = true`.
@@ -423,6 +428,7 @@ public function triggerEventForNewItem(ObjectCollection $orderItems, array $logC
* - Calls condition plugins
* - Sets timeouts for timeout events
* - Triggers item reservation plugins
+ * - Notified listeners about event handling
* - Unlocks state machine trigger
* - Returns an array with data aggregated from the state machine plugins and an `OmsEventTriggerResponseTransfer` by the key `\Spryker\Zed\Oms\OmsConfig::OMS_EVENT_TRIGGER_RESPONSE`.
* - If command plugins execution ends without issues `OmsEventTriggerResponse.isSuccessful = true`.
diff --git a/src/Spryker/Zed/Oms/Business/OrderStateMachine/OrderStateMachine.php b/src/Spryker/Zed/Oms/Business/OrderStateMachine/OrderStateMachine.php
index 719ff441..4047f50b 100644
--- a/src/Spryker/Zed/Oms/Business/OrderStateMachine/OrderStateMachine.php
+++ b/src/Spryker/Zed/Oms/Business/OrderStateMachine/OrderStateMachine.php
@@ -18,6 +18,7 @@
use Orm\Zed\Oms\Persistence\SpyOmsOrderItemStateQuery;
use Orm\Zed\Sales\Persistence\SpySalesOrderItem;
use Spryker\Shared\ErrorHandler\ErrorLogger;
+use Spryker\Zed\Oms\Business\Notifier\EventTriggeredNotifierInterface;
use Spryker\Zed\Oms\Business\Process\ProcessInterface;
use Spryker\Zed\Oms\Business\Process\StateInterface;
use Spryker\Zed\Oms\Business\Util\ReadOnlyArrayObject;
@@ -125,6 +126,11 @@ class OrderStateMachine implements OrderStateMachineInterface
*/
protected $omsConfig;
+ /**
+ * @var \Spryker\Zed\Oms\Business\Notifier\EventTriggeredNotifierInterface
+ */
+ protected EventTriggeredNotifierInterface $eventTriggeredNotifier;
+
/**
* @param \Spryker\Zed\Oms\Persistence\OmsQueryContainerInterface $queryContainer
* @param \Spryker\Zed\Oms\Business\OrderStateMachine\BuilderInterface $builder
@@ -135,6 +141,7 @@ class OrderStateMachine implements OrderStateMachineInterface
* @param \Spryker\Zed\Oms\Dependency\Plugin\Command\CommandCollectionInterface|array $commands
* @param \Spryker\Zed\Oms\Business\Util\ReservationInterface $reservation
* @param \Spryker\Zed\Oms\OmsConfig $omsConfig
+ * @param \Spryker\Zed\Oms\Business\Notifier\EventTriggeredNotifierInterface $eventTriggeredNotifier
*/
public function __construct(
OmsQueryContainerInterface $queryContainer,
@@ -145,7 +152,8 @@ public function __construct(
$conditions,
$commands,
ReservationInterface $reservation,
- OmsConfig $omsConfig
+ OmsConfig $omsConfig,
+ EventTriggeredNotifierInterface $eventTriggeredNotifier
) {
$this->queryContainer = $queryContainer;
$this->builder = $builder;
@@ -156,6 +164,7 @@ public function __construct(
$this->setCommands($commands);
$this->reservation = $reservation;
$this->omsConfig = $omsConfig;
+ $this->eventTriggeredNotifier = $eventTriggeredNotifier;
}
/**
@@ -238,6 +247,15 @@ public function triggerEvent($eventId, array $orderItems, $data)
}
$sourceStateBuffer = $this->updateStateByEvent($eventId, $processedOrderItems, $sourceStateBuffer, $log);
$this->saveOrderItems($processedOrderItems, $log, $processes, $sourceStateBuffer);
+
+ $currentOrderItemEntity = current($processedOrderItems);
+
+ if ($currentOrderItemEntity) {
+ $orderEntity = $currentOrderItemEntity->getOrder();
+
+ $this->eventTriggeredNotifier->notifyOmsEventTriggeredListeners($eventId, $processedOrderItems, $orderEntity, $data);
+ }
+
$allProcessedOrderItems = array_merge($allProcessedOrderItems, $processedOrderItems);
}
diff --git a/src/Spryker/Zed/Oms/OmsDependencyProvider.php b/src/Spryker/Zed/Oms/OmsDependencyProvider.php
index 83cb93ce..428b13b5 100644
--- a/src/Spryker/Zed/Oms/OmsDependencyProvider.php
+++ b/src/Spryker/Zed/Oms/OmsDependencyProvider.php
@@ -97,6 +97,11 @@ class OmsDependencyProvider extends AbstractBundleDependencyProvider
*/
public const PLUGINS_TIMEOUT_PROCESSOR = 'PLUGINS_TIMEOUT_PROCESSOR';
+ /**
+ * @var string
+ */
+ public const PLUGINS_OMS_EVENT_TRIGGERED_LISTENER = 'PLUGINS_OMS_EVENT_TRIGGERED_LISTENER';
+
/**
* @var string
*/
@@ -165,6 +170,7 @@ public function provideBusinessLayerDependencies(Container $container)
$container = $this->addOmsReservationWriterStrategyPlugins($container);
$container = $this->addReservationPostSaveTerminationAwareStrategyPlugins($container);
$container = $this->addTimeoutProcessorPlugins($container);
+ $container = $this->addOmsEventTriggeredListenerPlugins($container);
$container = $this->addMessageBrokerFacade($container);
return $container;
@@ -603,6 +609,28 @@ protected function getTimeoutProcessorPlugins(): array
return [];
}
+ /**
+ * @param \Spryker\Zed\Kernel\Container $container
+ *
+ * @return \Spryker\Zed\Kernel\Container
+ */
+ protected function addOmsEventTriggeredListenerPlugins(Container $container): Container
+ {
+ $container->set(static::PLUGINS_OMS_EVENT_TRIGGERED_LISTENER, function () {
+ return $this->getOmsEventTriggeredListenerPlugins();
+ });
+
+ return $container;
+ }
+
+ /**
+ * @return array<\Spryker\Zed\OmsExtension\Dependency\Plugin\OmsEventTriggeredListenerPluginInterface>
+ */
+ protected function getOmsEventTriggeredListenerPlugins(): array
+ {
+ return [];
+ }
+
/**
* @param \Spryker\Zed\Kernel\Container $container
*
diff --git a/tests/SprykerTest/Zed/Oms/Business/OmsFacadeTest.php b/tests/SprykerTest/Zed/Oms/Business/OmsFacadeTest.php
index 834bab64..4eb2bf4e 100644
--- a/tests/SprykerTest/Zed/Oms/Business/OmsFacadeTest.php
+++ b/tests/SprykerTest/Zed/Oms/Business/OmsFacadeTest.php
@@ -130,6 +130,33 @@ public function testIsOrderFlaggedExcludeFromCustomerShouldReturnTrueWhenAllStat
$this->assertTrue($isOrderExcluded);
}
+ /**
+ * @group new
+ *
+ * @return void
+ */
+ public function testEventTriggeredListenersAreNotifiedWhenEventIsTriggered(): void
+ {
+ $testStateMachineProcessName = 'Test01';
+
+ $omsEventTriggeredListener = $this->tester->setupEventTriggeredListenerPluginDependency();
+
+ $omsFacade = $this->createOmsFacadeWithTestStateMachine([$testStateMachineProcessName]);
+
+ $saveOrderTransfer = $this->tester->haveOrder([
+ 'unitPrice' => 100,
+ 'sumPrice' => 100,
+ ], $testStateMachineProcessName);
+
+ $idSalesOrder = $saveOrderTransfer->getIdSalesOrder();
+
+ $salesOrderEntity = SpySalesOrderQuery::create()->filterByIdSalesOrder($idSalesOrder)->findOne();
+
+ $omsFacade->triggerEvent('authorize', $salesOrderEntity->getItems(), []);
+
+ $this->assertTrue($omsEventTriggeredListener->wasTriggered);
+ }
+
/**
* @return void
*/
diff --git a/tests/SprykerTest/Zed/Oms/Business/OrderStateMachine/OrderStateMachineTest.php b/tests/SprykerTest/Zed/Oms/Business/OrderStateMachine/OrderStateMachineTest.php
index a041c187..37c90565 100644
--- a/tests/SprykerTest/Zed/Oms/Business/OrderStateMachine/OrderStateMachineTest.php
+++ b/tests/SprykerTest/Zed/Oms/Business/OrderStateMachine/OrderStateMachineTest.php
@@ -16,6 +16,7 @@
use Orm\Zed\Sales\Persistence\SpySalesOrder as ChildSpySalesOrder;
use Orm\Zed\Sales\Persistence\SpySalesOrderItem;
use ReflectionClass;
+use Spryker\Zed\Oms\Business\Notifier\EventTriggeredNotifier;
use Spryker\Zed\Oms\Business\OmsBusinessFactory;
use Spryker\Zed\Oms\Business\OrderStateMachine\BuilderInterface;
use Spryker\Zed\Oms\Business\OrderStateMachine\OrderStateMachine;
@@ -82,6 +83,7 @@ public function testInstantiationConditionsArrayShouldConvertedToCollection(): v
[],
$this->getReservationMock(),
new OmsConfig(),
+ new EventTriggeredNotifier([]),
);
$reflection = new ReflectionClass(OrderStateMachine::class);
$reflectionProperty = $reflection->getProperty('conditions');
@@ -110,6 +112,7 @@ public function testInstantiationWithConditionCollection(): void
[],
$this->getReservationMock(),
new OmsConfig(),
+ new EventTriggeredNotifier([]),
);
$reflection = new ReflectionClass(OrderStateMachine::class);
$reflectionProperty = $reflection->getProperty('conditions');
@@ -135,6 +138,7 @@ public function testInstantiationCommandsArrayShouldConvertedToCollection(): voi
[static::COMMAND_NAME => $this->getCommandMock()],
$this->getReservationMock(),
new OmsConfig(),
+ new EventTriggeredNotifier([]),
);
$reflection = new ReflectionClass(OrderStateMachine::class);
$reflectionProperty = $reflection->getProperty('commands');
@@ -163,6 +167,7 @@ public function testInstantiationWithCommandCollection(): void
$commandCollection,
$this->getReservationMock(),
new OmsConfig(),
+ new EventTriggeredNotifier([]),
);
$reflection = new ReflectionClass(OrderStateMachine::class);
$reflectionProperty = $reflection->getProperty('commands');
@@ -273,6 +278,7 @@ protected function getOrderStatemachineMockForConditionsWithCriteriaTest(array $
[],
$omsBusinessFactory->createUtilReservation(),
$omsConfigMock,
+ $omsBusinessFactory->createEventTriggeredNotifier(),
])
->onlyMethods($methods);
diff --git a/tests/SprykerTest/Zed/Oms/Business/OrderStateMachine/TimeoutTest.php b/tests/SprykerTest/Zed/Oms/Business/OrderStateMachine/TimeoutTest.php
index 952f6edd..38437575 100644
--- a/tests/SprykerTest/Zed/Oms/Business/OrderStateMachine/TimeoutTest.php
+++ b/tests/SprykerTest/Zed/Oms/Business/OrderStateMachine/TimeoutTest.php
@@ -314,6 +314,7 @@ protected function createOrderStateMachineMock(array $methods): OrderStateMachin
$omsBusinessFactory->getProvidedDependency(OmsDependencyProvider::COMMAND_PLUGINS),
$omsBusinessFactory->createUtilReservation(),
$omsConfigMock,
+ $omsBusinessFactory->createEventTriggeredNotifier(),
])
->onlyMethods($methods)
->getMock();
diff --git a/tests/SprykerTest/Zed/Oms/_support/OmsBusinessTester.php b/tests/SprykerTest/Zed/Oms/_support/OmsBusinessTester.php
index 3c30c928..905632fa 100644
--- a/tests/SprykerTest/Zed/Oms/_support/OmsBusinessTester.php
+++ b/tests/SprykerTest/Zed/Oms/_support/OmsBusinessTester.php
@@ -15,6 +15,7 @@
use Generated\Shared\DataBuilder\ItemMetadataBuilder;
use Generated\Shared\DataBuilder\QuoteBuilder;
use Generated\Shared\Transfer\CustomerTransfer;
+use Generated\Shared\Transfer\OmsEventTriggeredTransfer;
use Generated\Shared\Transfer\OrderTransfer;
use Generated\Shared\Transfer\QuoteTransfer;
use Generated\Shared\Transfer\StoreTransfer;
@@ -35,6 +36,7 @@
use Spryker\Zed\Oms\Dependency\Facade\OmsToSalesInterface;
use Spryker\Zed\Oms\OmsConfig;
use Spryker\Zed\Oms\Persistence\OmsQueryContainer;
+use Spryker\Zed\OmsExtension\Dependency\Plugin\OmsEventTriggeredListenerPluginInterface;
use Spryker\Zed\SalesPayment\SalesPaymentDependencyProvider;
use Spryker\Zed\Store\Communication\Plugin\MessageBroker\CurrentStoreReferenceMessageAttributeProviderPlugin;
use Spryker\Zed\Store\Communication\Plugin\MessageBroker\StoreReferenceMessageValidatorPlugin;
@@ -406,4 +408,41 @@ public function setupMessageBroker(): void
$this->setDependency(MessageBrokerDependencyProvider::PLUGINS_EXTERNAL_VALIDATOR, [new StoreReferenceMessageValidatorPlugin()]);
}
+
+ /**
+ * @return \Spryker\Zed\OmsExtension\Dependency\Plugin\OmsEventTriggeredListenerPluginInterface
+ */
+ public function setupEventTriggeredListenerPluginDependency(): OmsEventTriggeredListenerPluginInterface
+ {
+ $omsEventTriggeredListener = new class implements OmsEventTriggeredListenerPluginInterface {
+ /**
+ * @var bool
+ */
+ public $wasTriggered;
+
+ /**
+ * @param \Generated\Shared\Transfer\OmsEventTriggeredTransfer $omsEventTriggeredTransfer
+ *
+ * @return void
+ */
+ public function onEventTriggered(OmsEventTriggeredTransfer $omsEventTriggeredTransfer): void
+ {
+ $this->wasTriggered = true;
+ }
+
+ /**
+ * @param \Generated\Shared\Transfer\OmsEventTriggeredTransfer $omsEventTriggeredTransfer
+ *
+ * @return bool
+ */
+ public function isApplicable(OmsEventTriggeredTransfer $omsEventTriggeredTransfer): bool
+ {
+ return true;
+ }
+ };
+
+ $this->setDependency('PLUGINS_OMS_EVENT_TRIGGERED_LISTENER', [$omsEventTriggeredListener]);
+
+ return $omsEventTriggeredListener;
+ }
}