Skip to content

Commit

Permalink
Merge pull request #8 from Setono/order-edit-events
Browse files Browse the repository at this point in the history
Order update events
  • Loading branch information
Zales0123 authored Jun 20, 2024
2 parents 62a38d4 + e4fbb72 commit b6fd534
Show file tree
Hide file tree
Showing 27 changed files with 281 additions and 88 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"symfony/form": "^5.4 || ^6.4 || ^7.0",
"symfony/http-foundation": "^5.4 || ^6.4 || ^7.0",
"symfony/http-kernel": "^5.4 || ^6.4 || ^7.0",
"symfony/messenger": "^5.4 || ^6.4 || ^7.0",
"symfony/options-resolver": "^5.4 || ^6.4 || ^7.0",
"symfony/routing": "^5.4 || ^6.4 || ^7.0",
"webmozart/assert": "^1.11"
Expand Down
4 changes: 2 additions & 2 deletions src/Checker/PostUpdateChangesChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

namespace Setono\SyliusOrderEditPlugin\Checker;

use Setono\SyliusOrderEditPlugin\Entity\InitialTotalAwareOrderInterface;
use Setono\SyliusOrderEditPlugin\Entity\EditableOrderInterface;
use Setono\SyliusOrderEditPlugin\Exception\NewOrderWrongTotalException;
use Sylius\Component\Core\Model\OrderInterface;

final class PostUpdateChangesChecker implements PostUpdateChangesCheckerInterface
{
public function check(InitialTotalAwareOrderInterface $previousOrder, OrderInterface $newOrder): void
public function check(EditableOrderInterface $previousOrder, OrderInterface $newOrder): void
{
if ($newOrder->getTotal() > $previousOrder->getInitialTotal()) {
throw new NewOrderWrongTotalException();
Expand Down
7 changes: 2 additions & 5 deletions src/Checker/PostUpdateChangesCheckerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,10 @@

namespace Setono\SyliusOrderEditPlugin\Checker;

use Setono\SyliusOrderEditPlugin\Entity\InitialTotalAwareOrderInterface;
use Setono\SyliusOrderEditPlugin\Entity\EditableOrderInterface;
use Sylius\Component\Core\Model\OrderInterface;

interface PostUpdateChangesCheckerInterface
{
public function check(
InitialTotalAwareOrderInterface $previousOrder,
OrderInterface $newOrder,
): void;
public function check(EditableOrderInterface $previousOrder, OrderInterface $newOrder): void;
}
23 changes: 3 additions & 20 deletions src/Controller/EditOrderAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,8 @@

namespace Setono\SyliusOrderEditPlugin\Controller;

use Doctrine\ORM\EntityManagerInterface;
use Setono\SyliusOrderEditPlugin\Checker\PostUpdateChangesCheckerInterface;
use Setono\SyliusOrderEditPlugin\Entity\InitialTotalAwareOrderInterface;
use Setono\SyliusOrderEditPlugin\Exception\NewOrderWrongTotalException;
use Setono\SyliusOrderEditPlugin\Preparer\OrderPreparerInterface;
use Setono\SyliusOrderEditPlugin\Processor\UpdatedOrderProcessorInterface;
use Setono\SyliusOrderEditPlugin\Provider\UpdatedOrderProviderInterface;
use Setono\SyliusOrderEditPlugin\Updated\OrderUpdaterInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
Expand All @@ -21,28 +16,16 @@
final class EditOrderAction
{
public function __construct(
private readonly OrderPreparerInterface $oldOrderProvider,
private readonly UpdatedOrderProviderInterface $updatedOrderProvider,
private readonly UpdatedOrderProcessorInterface $updatedOrderProcessor,
private readonly PostUpdateChangesCheckerInterface $postUpdateChangesChecker,
private readonly OrderUpdaterInterface $orderUpdater,
private readonly UrlGeneratorInterface $router,
private readonly RequestStack $requestStack,
private readonly EntityManagerInterface $entityManager,
) {
}

public function __invoke(Request $request, int $id): Response
{
$order = $this->oldOrderProvider->prepareToUpdate($id);

/** @var InitialTotalAwareOrderInterface $oldOrder */
$oldOrder = clone $order;

try {
$updatedOrder = $this->updatedOrderProvider->provideFromOldOrderAndRequest($order, $request);
$this->updatedOrderProcessor->process($updatedOrder);
$this->postUpdateChangesChecker->check($oldOrder, $updatedOrder);
$this->entityManager->flush();
$this->orderUpdater->update($request, $id);
} catch (NewOrderWrongTotalException) {
return $this->addFlashAndRedirect(
'error',
Expand Down
8 changes: 8 additions & 0 deletions src/DependencyInjection/SetonoSyliusOrderEditExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ public function prepend(ContainerBuilder $container): void
'templates' => [
'action' => [
'edit_order' => '@SetonoSyliusOrderEditPlugin/admin/order/grid/editOrder.html.twig',
],
],
]);

$container->prependExtensionConfig('framework', [
'messenger' => [
'buses' => [
'setono_sylius_order_edit.event_bus' => null,
],
],
]);
Expand Down
7 changes: 6 additions & 1 deletion src/Entity/EditableOrderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

use Sylius\Component\Core\Model\OrderInterface;

interface EditableOrderInterface extends OrderInterface, InitialTotalAwareOrderInterface
interface EditableOrderInterface extends OrderInterface
{
public function isAlreadyPaid(): bool;

public function getInitialTotal(): int;

public function setInitialTotal(int $initialTotal): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,21 @@
namespace Setono\SyliusOrderEditPlugin\Entity;

use Doctrine\ORM\Mapping as ORM;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\OrderPaymentStates;

trait InitialTotalAwareOrderTrait
/** @mixin OrderInterface */
trait EditableOrderTrait
{
/** @ORM\Column(type="integer") */
#[ORM\Column(type: 'integer')]
private int $initialTotal = 0;

public function isAlreadyPaid(): bool
{
return $this->getPaymentState() === OrderPaymentStates::STATE_PAID;
}

public function getInitialTotal(): int
{
return $this->initialTotal;
Expand Down
12 changes: 0 additions & 12 deletions src/Entity/InitialTotalAwareOrderInterface.php

This file was deleted.

12 changes: 12 additions & 0 deletions src/Event/OrderUpdated.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusOrderEditPlugin\Event;

final class OrderUpdated
{
public function __construct(public int $orderId)
{
}
}
12 changes: 12 additions & 0 deletions src/Event/PaidOrderUpdated.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusOrderEditPlugin\Event;

final class PaidOrderUpdated
{
public function __construct(public int $orderId, public int $oldTotal, public int $newTotal)
{
}
}
8 changes: 4 additions & 4 deletions src/Preparer/OrderPreparer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace Setono\SyliusOrderEditPlugin\Preparer;

use Setono\SyliusOrderEditPlugin\Entity\EditableOrderInterface;
use Sylius\Component\Core\Inventory\Operator\OrderInventoryOperatorInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
use Webmozart\Assert\Assert;

Expand All @@ -17,11 +17,11 @@ public function __construct(
) {
}

public function prepareToUpdate(int $orderId): OrderInterface
public function prepareToUpdate(int $orderId): EditableOrderInterface
{
/** @var OrderInterface|null $order */
/** @var EditableOrderInterface|null $order */
$order = $this->orderRepository->find($orderId);
Assert::isInstanceOf($order, OrderInterface::class);
Assert::isInstanceOf($order, EditableOrderInterface::class);

$this->orderInventoryOperator->cancel($order);

Expand Down
4 changes: 2 additions & 2 deletions src/Preparer/OrderPreparerInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace Setono\SyliusOrderEditPlugin\Preparer;

use Sylius\Component\Core\Model\OrderInterface;
use Setono\SyliusOrderEditPlugin\Entity\EditableOrderInterface;

interface OrderPreparerInterface
{
public function prepareToUpdate(int $orderId): OrderInterface;
public function prepareToUpdate(int $orderId): EditableOrderInterface;
}
4 changes: 1 addition & 3 deletions src/Processor/UpdatedOrderProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,12 @@ public function __construct(
) {
}

public function process(OrderInterface $updatedOrder): OrderInterface
public function process(OrderInterface $updatedOrder): void
{
$updatedOrder->setState(OrderInterface::STATE_CART);
$this->orderProcessor->process($updatedOrder);
$this->afterCheckoutOrderPaymentProcessor->process($updatedOrder);
$updatedOrder->setState(OrderInterface::STATE_NEW);
$this->orderInventoryOperator->hold($updatedOrder);

return $updatedOrder;
}
}
2 changes: 1 addition & 1 deletion src/Processor/UpdatedOrderProcessorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@

interface UpdatedOrderProcessorInterface
{
public function process(OrderInterface $updatedOrder): OrderInterface;
public function process(OrderInterface $updatedOrder): void;
}
5 changes: 3 additions & 2 deletions src/Provider/UpdatedOrderProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Setono\SyliusOrderEditPlugin\Provider;

use Setono\SyliusOrderEditPlugin\Entity\EditableOrderInterface;
use Setono\SyliusOrderEditPlugin\Exception\OrderUpdateException;
use Sylius\Bundle\OrderBundle\Form\Type\OrderType;
use Sylius\Component\Core\Model\OrderInterface;
Expand All @@ -17,7 +18,7 @@ public function __construct(private readonly FormFactoryInterface $formFactory)
{
}

public function provideFromOldOrderAndRequest(OrderInterface $oldOrder, Request $request): OrderInterface
public function provideFromOldOrderAndRequest(OrderInterface $oldOrder, Request $request): EditableOrderInterface
{
$form = $this->formFactory->create(
OrderType::class,
Expand All @@ -33,7 +34,7 @@ public function provideFromOldOrderAndRequest(OrderInterface $oldOrder, Request
}

$data = $form->getData();
Assert::isInstanceOf($data, OrderInterface::class);
Assert::isInstanceOf($data, EditableOrderInterface::class);

return $data;
}
Expand Down
3 changes: 2 additions & 1 deletion src/Provider/UpdatedOrderProviderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

namespace Setono\SyliusOrderEditPlugin\Provider;

use Setono\SyliusOrderEditPlugin\Entity\EditableOrderInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Symfony\Component\HttpFoundation\Request;

interface UpdatedOrderProviderInterface
{
public function provideFromOldOrderAndRequest(OrderInterface $oldOrder, Request $request): OrderInterface;
public function provideFromOldOrderAndRequest(OrderInterface $oldOrder, Request $request): EditableOrderInterface;
}
6 changes: 1 addition & 5 deletions src/Resources/config/services/controller.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@
class="Setono\SyliusOrderEditPlugin\Controller\EditOrderAction"
public="true"
>
<argument type="service" id="setono_sylius_order_edit.preparer.order_preparer" />
<argument type="service" id="setono_sylius_order_edit.provider.updated_order_provider" />
<argument type="service" id="setono_sylius_order_edit.processor.updated_order_processor" />
<argument type="service" id="setono_sylius_order_edit.checker.post_update_changes_checker" />
<argument type="service" id="setono_sylius_order_edit.updated.order_updater" />
<argument type="service" id="router" />
<argument type="service" id="request_stack" />
<argument type="service" id="sylius.manager.order" />
</service>
</services>
</container>
12 changes: 12 additions & 0 deletions src/Resources/config/services/order_processing.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,17 @@
>
<argument type="service" id="sylius.manager.order" />
</service>

<service
id="setono_sylius_order_edit.updated.order_updater"
class="Setono\SyliusOrderEditPlugin\Updated\OrderUpdater"
>
<argument type="service" id="setono_sylius_order_edit.preparer.order_preparer" />
<argument type="service" id="setono_sylius_order_edit.provider.updated_order_provider" />
<argument type="service" id="setono_sylius_order_edit.processor.updated_order_processor" />
<argument type="service" id="setono_sylius_order_edit.checker.post_update_changes_checker" />
<argument type="service" id="doctrine.orm.entity_manager" />
<argument type="service" id="setono_sylius_order_edit.event_bus" />
</service>
</services>
</container>
46 changes: 46 additions & 0 deletions src/Updated/OrderUpdater.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusOrderEditPlugin\Updated;

use Doctrine\ORM\EntityManagerInterface;
use Setono\SyliusOrderEditPlugin\Checker\PostUpdateChangesCheckerInterface;
use Setono\SyliusOrderEditPlugin\Entity\EditableOrderInterface;
use Setono\SyliusOrderEditPlugin\Event\OrderUpdated;
use Setono\SyliusOrderEditPlugin\Event\PaidOrderUpdated;
use Setono\SyliusOrderEditPlugin\Preparer\OrderPreparerInterface;
use Setono\SyliusOrderEditPlugin\Processor\UpdatedOrderProcessorInterface;
use Setono\SyliusOrderEditPlugin\Provider\UpdatedOrderProviderInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Messenger\MessageBusInterface;

final class OrderUpdater implements OrderUpdaterInterface
{
public function __construct(
private readonly OrderPreparerInterface $oldOrderProvider,
private readonly UpdatedOrderProviderInterface $updatedOrderProvider,
private readonly UpdatedOrderProcessorInterface $updatedOrderProcessor,
private readonly PostUpdateChangesCheckerInterface $postUpdateChangesChecker,
private readonly EntityManagerInterface $entityManager,
private readonly MessageBusInterface $eventBus,
) {
}

public function update(Request $request, int $orderId): void
{
$order = $this->oldOrderProvider->prepareToUpdate($orderId);
/** @var EditableOrderInterface $oldOrder */
$oldOrder = clone $order;

$updatedOrder = $this->updatedOrderProvider->provideFromOldOrderAndRequest($order, $request);
$this->updatedOrderProcessor->process($updatedOrder);
$this->postUpdateChangesChecker->check($oldOrder, $updatedOrder);
$this->entityManager->flush();

$this->eventBus->dispatch(new OrderUpdated($orderId));
if ($updatedOrder->isAlreadyPaid()) {
$this->eventBus->dispatch(new PaidOrderUpdated($orderId, $oldOrder->getTotal(), $updatedOrder->getTotal()));
}
}
}
17 changes: 17 additions & 0 deletions src/Updated/OrderUpdaterInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusOrderEditPlugin\Updated;

use Setono\SyliusOrderEditPlugin\Exception\NewOrderWrongTotalException;
use Symfony\Component\HttpFoundation\Request;

interface OrderUpdaterInterface
{
/**
* @throws NewOrderWrongTotalException
* @throws \InvalidArgumentException
*/
public function update(Request $request, int $orderId): void;
}
4 changes: 2 additions & 2 deletions tests/Application/src/Entity/Order.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

use Doctrine\ORM\Mapping as ORM;
use Setono\SyliusOrderEditPlugin\Entity\EditableOrderInterface;
use Setono\SyliusOrderEditPlugin\Entity\InitialTotalAwareOrderTrait;
use Setono\SyliusOrderEditPlugin\Entity\EditableOrderTrait;

#[ORM\Entity]
#[ORM\Table(name: 'sylius_order')]
class Order extends \Sylius\Component\Core\Model\Order implements EditableOrderInterface
{
use InitialTotalAwareOrderTrait;
use EditableOrderTrait;
}
Loading

0 comments on commit b6fd534

Please sign in to comment.