src/Eccube/Service/OrderStateMachine.php line 167

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Eccube\Service;
  13. use Customize\Service\AmbassadorPointLogService;
  14. use Eccube\Entity\Master\OrderStatus;
  15. use Eccube\Entity\Order;
  16. use Eccube\Repository\CustomerRepository;
  17. use Eccube\Repository\Master\OrderStatusRepository;
  18. use Eccube\Service\PurchaseFlow\Processor\PointProcessor;
  19. use Eccube\Service\PurchaseFlow\Processor\StockReduceProcessor;
  20. use Eccube\Service\PurchaseFlow\PurchaseContext;
  21. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  22. use Symfony\Component\Workflow\Event\Event;
  23. use Symfony\Component\Workflow\StateMachine;
  24. class OrderStateMachine implements EventSubscriberInterface
  25. {
  26.     /**
  27.      * @var StateMachine
  28.      */
  29.     private $machine;
  30.     /**
  31.      * @var OrderStatusRepository
  32.      */
  33.     private $orderStatusRepository;
  34.     /**
  35.      * @var PointProcessor
  36.      */
  37.     private $pointProcessor;
  38.     /**
  39.      * @var StockReduceProcessor
  40.      */
  41.     private $stockReduceProcessor;
  42.     private $ambassadorPointLogService;
  43.     public function __construct(StateMachine $_orderStateMachineOrderStatusRepository $orderStatusRepositoryPointProcessor $pointProcessorStockReduceProcessor $stockReduceProcessorAmbassadorPointLogService $ambassadorPointLogService)
  44.     {
  45.         $this->machine $_orderStateMachine;
  46.         $this->orderStatusRepository $orderStatusRepository;
  47.         $this->pointProcessor $pointProcessor;
  48.         $this->stockReduceProcessor $stockReduceProcessor;
  49.         $this->ambassadorPointLogService $ambassadorPointLogService;
  50.     }
  51.     /**
  52.      * 指定ステータスに遷移.
  53.      *
  54.      * @param Order $Order 受注
  55.      * @param OrderStatus $OrderStatus 遷移先ステータス
  56.      */
  57.     public function apply(Order $OrderOrderStatus $OrderStatus)
  58.     {
  59.         $context $this->newContext($Order);
  60.         $transition $this->getTransition($context$OrderStatus);
  61.         if ($transition) {
  62.             $this->machine->apply($context$transition->getName());
  63.         } else {
  64.             throw new \InvalidArgumentException();
  65.         }
  66.     }
  67.     /**
  68.      * 指定ステータスに遷移できるかどうかを判定.
  69.      *
  70.      * @param Order $Order 受注
  71.      * @param OrderStatus $OrderStatus 遷移先ステータス
  72.      *
  73.      * @return boolean 指定ステータスに遷移できる場合はtrue
  74.      */
  75.     public function can(Order $OrderOrderStatus $OrderStatus)
  76.     {
  77.         return !is_null($this->getTransition($this->newContext($Order), $OrderStatus));
  78.     }
  79.     private function getTransition(OrderStateMachineContext $contextOrderStatus $OrderStatus)
  80.     {
  81.         $transitions $this->machine->getEnabledTransitions($context);
  82.         foreach ($transitions as $t) {
  83.             if (in_array($OrderStatus->getId(), $t->getTos())) {
  84.                 return $t;
  85.             }
  86.         }
  87.         return null;
  88.     }
  89.     /**
  90.      * {@inheritdoc}
  91.      */
  92.     public static function getSubscribedEvents()
  93.     {
  94.         return [
  95.             'workflow.order.completed' => ['onCompleted'],
  96.             'workflow.order.transition.pay' => ['updatePaymentDate'],
  97.             'workflow.order.transition.cancel' => [['rollbackStock'], ['rollbackUsePoint']],
  98.             'workflow.order.transition.back_to_in_progress' => [['commitStock'], ['commitUsePoint']],
  99.             'workflow.order.transition.ship' => [['commitAddPoint']],
  100.             'workflow.order.transition.return' => [['rollbackUsePoint'], ['rollbackAddPoint']],
  101.             'workflow.order.transition.cancel_return' => [['commitUsePoint'], ['commitAddPoint']],
  102.         ];
  103.     }
  104.     /*
  105.      * Event handlers.
  106.      */
  107.     /**
  108.      * 入金日を更新する.
  109.      *
  110.      * @param Event $event
  111.      */
  112.     public function updatePaymentDate(Event $event)
  113.     {
  114.         /* @var Order $Order */
  115.         $Order $event->getSubject()->getOrder();
  116.         $Order->setPaymentDate(new \DateTime());
  117.     }
  118.     /**
  119.      * 会員の保有ポイントを減らす.
  120.      *
  121.      * @param Event $event
  122.      *
  123.      * @throws PurchaseFlow\PurchaseException
  124.      */
  125.     public function commitUsePoint(Event $event)
  126.     {
  127.         /* @var Order $Order */
  128.         $Order $event->getSubject()->getOrder();
  129.         $this->pointProcessor->prepare($Order, new PurchaseContext());
  130.     }
  131.     /**
  132.      * 利用ポイントを会員に戻す.
  133.      *
  134.      * @param Event $event
  135.      */
  136.     public function rollbackUsePoint(Event $event)
  137.     {
  138.         /* @var Order $Order */
  139.         $Order $event->getSubject()->getOrder();
  140.         $this->pointProcessor->rollback($Order, new PurchaseContext());
  141.     }
  142.     /**
  143.      * 在庫を減らす.
  144.      *
  145.      * @param Event $event
  146.      *
  147.      * @throws PurchaseFlow\PurchaseException
  148.      */
  149.     public function commitStock(Event $event)
  150.     {
  151.         /* @var Order $Order */
  152.         $Order $event->getSubject()->getOrder();
  153.         $this->stockReduceProcessor->prepare($Order, new PurchaseContext());
  154.     }
  155.     /**
  156.      * 在庫を戻す.
  157.      *
  158.      * @param Event $event
  159.      */
  160.     public function rollbackStock(Event $event)
  161.     {
  162.         /* @var Order $Order */
  163.         $Order $event->getSubject()->getOrder();
  164.         $this->stockReduceProcessor->rollback($Order, new PurchaseContext());
  165.     }
  166.     /**
  167.      * 会員に加算ポイントを付与する.
  168.      *
  169.      * @param Event $event
  170.      */
  171.     public function commitAddPoint(Event $event)
  172.     {
  173.         /* @var Order $Order */
  174.         $Order $event->getSubject()->getOrder();
  175.         $Customer $Order->getCustomer();
  176.         if ($Customer) {
  177.             $Customer->setPoint(intval($Customer->getPoint()) + intval($Order->getAddPoint()),$Order->getId());
  178.         }        
  179.     }
  180.     /**
  181.      * 会員に付与した加算ポイントを取り消す.
  182.      *
  183.      * @param Event $event
  184.      */
  185.     public function rollbackAddPoint(Event $event)
  186.     {
  187.         /* @var Order $Order */
  188.         $Order $event->getSubject()->getOrder();
  189.         $Customer $Order->getCustomer();
  190.         if ($Customer) {
  191.             $Customer->setPoint(intval($Customer->getPoint()) - intval($Order->getAddPoint()));
  192.         }
  193.     }
  194.     /**
  195.      * 受注ステータスを再設定.
  196.      * {@link StateMachine}によって遷移が終了したときには{@link Order#OrderStatus}のidが変更されるだけなのでOrderStatusを設定し直す.
  197.      *
  198.      * @param Event $event
  199.      */
  200.     public function onCompleted(Event $event)
  201.     {
  202.         /** @var $context OrderStateMachineContext */
  203.         $context $event->getSubject();
  204.         $Order $context->getOrder();
  205.         $CompletedOrderStatus $this->orderStatusRepository->find($context->getStatus());
  206.         $Order->setOrderStatus($CompletedOrderStatus);
  207.     }
  208.     private function newContext(Order $Order)
  209.     {
  210.         return new OrderStateMachineContext((string) $Order->getOrderStatus()->getId(), $Order);
  211.     }
  212. }
  213. class OrderStateMachineContext
  214. {
  215.     /** @var string */
  216.     private $status;
  217.     /** @var Order */
  218.     private $Order;
  219.     /**
  220.      * OrderStateMachineContext constructor.
  221.      *
  222.      * @param string $status
  223.      * @param Order $Order
  224.      */
  225.     public function __construct($statusOrder $Order)
  226.     {
  227.         $this->status $status;
  228.         $this->Order $Order;
  229.     }
  230.     /**
  231.      * @return string
  232.      */
  233.     public function getStatus()
  234.     {
  235.         return $this->status;
  236.     }
  237.     /**
  238.      * @param string $status
  239.      */
  240.     public function setStatus($status)
  241.     {
  242.         $this->status $status;
  243.     }
  244.     /**
  245.      * @return Order
  246.      */
  247.     public function getOrder()
  248.     {
  249.         return $this->Order;
  250.     }
  251. }