Skip to content

Commit

Permalink
Add support for Symfony Workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
coldic3 committed Oct 1, 2024
1 parent d545260 commit 5951f7a
Show file tree
Hide file tree
Showing 6 changed files with 380 additions and 2 deletions.
47 changes: 45 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,10 @@ Show any order on the Sylius backend and click on the top right `History` button

## How does it work?

This plugin is based on the state machine events. It uses the native Winzou state machine callback system to save named
order events when they are triggered.
This plugin is based on the state machine events. It uses both the native Winzou state machine callback system and
Symfony Workflow events to save named order events when they are triggered.

Depending on your `sylius_state_machine_abstraction.default_adapter` configuration:

```yaml
# src/Resources/config/state_machine/checkout.yaml
Expand All @@ -67,6 +69,47 @@ winzou_state_machine:
args: [ 'object', 'constant("MonsieurBiz\\SyliusOrderHistoryPlugin\\Entity\\OrderHistoryEventInterface::TYPE_CHECKOUT")', '"addressed"' ]
```
or
```php
<?php

declare(strict_types=1);

namespace App\EventListener\Workflow;

use MonsieurBiz\SyliusOrderHistoryPlugin\Entity\OrderHistoryEventInterface;
use MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryNotifierInterface;
use MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryWithAddressesDataNotifier;
use Sylius\Component\Core\Model\OrderInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Workflow\Event\CompletedEvent;

final class CheckoutWorkflowEventListener
{
public function __construct(
#[Autowire(service: OrderHistoryWithAddressesDataNotifier::class)]
private OrderHistoryNotifierInterface $orderHistoryWithAddressesDataNotifier,
) {
}

#[AsEventListener(event: 'workflow.sylius_order_checkout.completed.addressed')]
public function addressed(CompletedEvent $event): void
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithAddressesDataNotifier->notifyEvent(
$order,
OrderHistoryEventInterface::TYPE_CHECKOUT,
'addressed',
);
}
}
```

Callback dedicated notifier service / actions who add different details following context:
* `\MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryNotifier` is a basic notifier with no particular details
except the given ones as parameters.
Expand Down
88 changes: 88 additions & 0 deletions src/EventListener/Workflow/CheckoutWorkflowEventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?php

declare(strict_types=1);

namespace MonsieurBiz\SyliusOrderHistoryPlugin\EventListener\Workflow;

use MonsieurBiz\SyliusOrderHistoryPlugin\Entity\OrderHistoryEventInterface;
use MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryNotifierInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Workflow\Event\CompletedEvent;

final class CheckoutWorkflowEventListener
{
public function __construct(
private OrderHistoryNotifierInterface $orderHistoryWithAddressesDataNotifier,
private OrderHistoryNotifierInterface $orderHistoryNotifier,
private OrderHistoryNotifierInterface $orderHistoryWithShipmentDataNotifier,
private OrderHistoryNotifierInterface $orderHistoryWithPaymentDataNotifier,
) {
}

#[AsEventListener(event: 'workflow.sylius_order_checkout.completed.addressed')]
public function addressed(CompletedEvent $event): void
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithAddressesDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_CHECKOUT, 'addressed');
}

#[AsEventListener(event: 'workflow.sylius_order_checkout.completed.skip_shipping')]
public function shippingSkipped(CompletedEvent $event): void
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_CHECKOUT, 'shipping_skipped');
}

#[AsEventListener(event: 'workflow.sylius_order_checkout.completed.select_shipping')]
public function shippingSelected(CompletedEvent $event): void
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithShipmentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_CHECKOUT, 'shipping_selected');
}

#[AsEventListener(event: 'workflow.sylius_order_checkout.completed.skip_payment')]
public function paymentSkipped(CompletedEvent $event): void
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_CHECKOUT, 'payment_skipped');
}

#[AsEventListener(event: 'workflow.sylius_order_checkout.completed.select_payment')]
public function paymentSelected(CompletedEvent $event): void
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithPaymentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_CHECKOUT, 'payment_selected');
}

#[AsEventListener(event: 'workflow.sylius_order_checkout.completed.complete')]
public function completed(CompletedEvent $event): void
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_CHECKOUT, 'completed');
}
}
52 changes: 52 additions & 0 deletions src/EventListener/Workflow/OrderWorkflowEventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace MonsieurBiz\SyliusOrderHistoryPlugin\EventListener\Workflow;

use MonsieurBiz\SyliusOrderHistoryPlugin\Entity\OrderHistoryEventInterface;
use MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryNotifierInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Workflow\Event\CompletedEvent;

final class OrderWorkflowEventListener
{
public function __construct(
private OrderHistoryNotifierInterface $orderHistoryNotifier,
) {
}

#[AsEventListener(event: 'workflow.sylius_order.completed.create')]
public function new(CompletedEvent $event): void
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_ORDER, 'new');
}

#[AsEventListener(event: 'workflow.sylius_order.completed.cancel')]
public function cancelled(CompletedEvent $event): void
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_ORDER, 'cancelled');
}

#[AsEventListener(event: 'workflow.sylius_order.completed.fulfill')]
public function fulfilled(CompletedEvent $event): void
{
$order = $event->getSubject();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_ORDER, 'fulfilled');
}
}
125 changes: 125 additions & 0 deletions src/EventListener/Workflow/PaymentWorkflowEventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
<?php

declare(strict_types=1);

namespace MonsieurBiz\SyliusOrderHistoryPlugin\EventListener\Workflow;

use MonsieurBiz\SyliusOrderHistoryPlugin\Entity\OrderHistoryEventInterface;
use MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryNotifierInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\PaymentInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Workflow\Event\CompletedEvent;

final class PaymentWorkflowEventListener
{
public function __construct(
private OrderHistoryNotifierInterface $orderHistoryWithPaymentDataNotifier,
) {
}

#[AsEventListener(event: 'workflow.sylius_payment.completed.create')]
public function new(CompletedEvent $event): void
{
$payment = $event->getSubject();
if (!$payment instanceof PaymentInterface) {
return;
}
$order = $payment->getOrder();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithPaymentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_PAYMENT, 'new');
}

#[AsEventListener(event: 'workflow.sylius_payment.completed.process')]
public function processing(CompletedEvent $event): void
{
$payment = $event->getSubject();
if (!$payment instanceof PaymentInterface) {
return;
}
$order = $payment->getOrder();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithPaymentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_PAYMENT, 'processing');
}

#[AsEventListener(event: 'workflow.sylius_payment.completed.authorize')]
public function authorized(CompletedEvent $event): void
{
$payment = $event->getSubject();
if (!$payment instanceof PaymentInterface) {
return;
}
$order = $payment->getOrder();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithPaymentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_PAYMENT, 'authorized');
}

#[AsEventListener(event: 'workflow.sylius_payment.completed.complete')]
public function completed(CompletedEvent $event): void
{
$payment = $event->getSubject();
if (!$payment instanceof PaymentInterface) {
return;
}
$order = $payment->getOrder();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithPaymentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_PAYMENT, 'completed');
}

#[AsEventListener(event: 'workflow.sylius_payment.completed.fail')]
public function failed(CompletedEvent $event): void
{
$payment = $event->getSubject();
if (!$payment instanceof PaymentInterface) {
return;
}
$order = $payment->getOrder();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithPaymentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_PAYMENT, 'failed');
}

#[AsEventListener(event: 'workflow.sylius_payment.completed.cancel')]
public function cancelled(CompletedEvent $event): void
{
$payment = $event->getSubject();
if (!$payment instanceof PaymentInterface) {
return;
}
$order = $payment->getOrder();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithPaymentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_PAYMENT, 'cancelled');
}

#[AsEventListener(event: 'workflow.sylius_payment.completed.refund')]
public function refunded(CompletedEvent $event): void
{
$payment = $event->getSubject();
if (!$payment instanceof PaymentInterface) {
return;
}
$order = $payment->getOrder();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithPaymentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_PAYMENT, 'refunded');
}
}
65 changes: 65 additions & 0 deletions src/EventListener/Workflow/ShipmentWorkflowEventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace MonsieurBiz\SyliusOrderHistoryPlugin\EventListener\Workflow;

use MonsieurBiz\SyliusOrderHistoryPlugin\Entity\OrderHistoryEventInterface;
use MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryNotifierInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\ShipmentInterface;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Symfony\Component\Workflow\Event\CompletedEvent;

final class ShipmentWorkflowEventListener
{
public function __construct(
private OrderHistoryNotifierInterface $orderHistoryWithShipmentDataNotifier,
) {
}

#[AsEventListener(event: 'workflow.sylius_shipment.completed.create')]
public function new(CompletedEvent $event): void
{
$shipment = $event->getSubject();
if (!$shipment instanceof ShipmentInterface) {
return;
}
$order = $shipment->getOrder();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithShipmentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_SHIPMENT, 'new');
}

#[AsEventListener(event: 'workflow.sylius_shipment.completed.cancel')]
public function cancelled(CompletedEvent $event): void
{
$shipment = $event->getSubject();
if (!$shipment instanceof ShipmentInterface) {
return;
}
$order = $shipment->getOrder();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithShipmentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_SHIPMENT, 'cancelled');
}

#[AsEventListener(event: 'workflow.sylius_shipment.completed.ship')]
public function shipped(CompletedEvent $event): void
{
$shipment = $event->getSubject();
if (!$shipment instanceof ShipmentInterface) {
return;
}
$order = $shipment->getOrder();
if (!$order instanceof OrderInterface) {
return;
}

$this->orderHistoryWithShipmentDataNotifier->notifyEvent($order, OrderHistoryEventInterface::TYPE_SHIPMENT, 'shipped');
}
}
Loading

0 comments on commit 5951f7a

Please sign in to comment.