- <?php
- /**
-  * Copyright(c) 2022 SYSTEM_KD
-  * Date: 2022/09/03
-  */
- namespace Plugin\OrderStatusEx\EventSubscriber;
- use Doctrine\ORM\EntityManagerInterface;
- use Eccube\Entity\Master\OrderStatus;
- use Eccube\Entity\Order;
- use Eccube\Entity\Shipping;
- use Eccube\Event\TemplateEvent;
- use Eccube\Form\Type\Admin\OrderStatusSettingType;
- use Eccube\Repository\Master\OrderStatusRepository;
- use Eccube\Service\OrderStateMachineContext;
- use Eccube\Service\SystemService;
- use Eccube\Util\CacheUtil;
- use Plugin\OrderStatusEx\Controller\Admin\Seggin\Shop\OrderStatusExController;
- use Plugin\OrderStatusEx\Entity\OrderOrderStatus;
- use Plugin\OrderStatusEx\Entity\OrderStatusEvent;
- use Plugin\OrderStatusEx\Entity\OrderStatusEx;
- use Plugin\OrderStatusEx\Service\OrderStatusExConfigService;
- use Plugin\OrderStatusEx\Service\OrderStatusExService;
- use Plugin\OrderStatusEx\Service\TwigRenderService\EventSubscriber\TwigRenderTrait;
- use Symfony\Component\EventDispatcher\EventSubscriberInterface;
- use Symfony\Component\Form\FormFactoryInterface;
- use Symfony\Component\HttpFoundation\Request;
- use Symfony\Component\HttpFoundation\RequestStack;
- use Symfony\Component\HttpFoundation\Session\SessionInterface;
- use Symfony\Component\HttpKernel\Event\ControllerEvent;
- use Symfony\Component\HttpKernel\KernelEvents;
- use Symfony\Component\Routing\RouterInterface;
- use Symfony\Component\Workflow\Event\Event;
- use Symfony\Component\Workflow\Event\TransitionEvent;
- class OrderStatusEventSubscriber implements EventSubscriberInterface
- {
-     use TwigRenderTrait;
-     /** @var RouterInterface */
-     protected $router;
-     /** @var FormFactoryInterface */
-     protected $formFactory;
-     /** @var EntityManagerInterface */
-     protected $entityManager;
-     /** @var OrderStatusExService */
-     protected $orderStatusExService;
-     /** @var OrderStatusExController */
-     protected $orderStatusExController;
-     /** @var CacheUtil */
-     protected $cachUtil;
-     /** @var SessionInterface */
-     protected $session;
-     /** @var SystemService */
-     protected $systemService;
-     /** @var OrderStatusExConfigService */
-     protected $orderStatusExConfigService;
-     /** @var RequestStack */
-     private RequestStack $requestStack;
-     public function __construct(
-         RouterInterface            $router,
-         FormFactoryInterface       $formFactory,
-         EntityManagerInterface     $entityManager,
-         OrderStatusExService       $orderStatusExService,
-         OrderStatusExController    $orderStatusExController,
-         CacheUtil                  $cacheUtil,
-         SystemService              $systemService,
-         OrderStatusExConfigService $orderStatusExConfigService,
-         RequestStack               $requestStack
-     )
-     {
-         $this->router = $router;
-         $this->formFactory = $formFactory;
-         $this->entityManager = $entityManager;
-         $this->orderStatusExService = $orderStatusExService;
-         $this->orderStatusExController = $orderStatusExController;
-         $this->cachUtil = $cacheUtil;
-         $this->systemService = $systemService;
-         $this->orderStatusExConfigService = $orderStatusExConfigService;
-         $this->requestStack = $requestStack;
-     }
-     /**
-      * 受注対応状況設定テンプレート
-      *
-      * @param TemplateEvent $event
-      * @return void
-      */
-     public function onSettingShopOrderStatusTwig(TemplateEvent $event)
-     {
-         // リダイレクトしない場合はキャッシュクリア用フラグOFF
-         $session = $this->requestStack->getSession();
-         $session->set(OrderStatusExService::CACHE_CLEAR_KEY, false);
-         /** @var Request $request */
-         $request = $this->requestStack->getMainRequest();
-         // 新規登録エラー用
-         $builder = $this->formFactory->createBuilder(OrderStatusSettingType::class, null);
-         $form = $builder->getForm();
-         $form->get('color')->setData('#a3a3a3');
-         if ('POST' === $request->getMethod()) {
-             $form->handleRequest($request);
-             if ($form->isSubmitted()) {
-                 $form->isValid();
-             }
-         }
-         $event->setParameter('createForm', $form->createView());
-         $this->initRenderService($event);
-         // 新規登録ブロック追加
-         $this->createInsertBuilder()
-             ->find(".c-contentsArea__primaryCol")
-             ->setTargetId('order_status_ex_block')
-             ->setInsertModePrepend();
-         // テーブル追加
-         $this->createInsertBuilder()
-             ->find('table > thead > tr')
-             ->setTargetId('order_status_ex_table_head')
-             ->setInsertModeAppend();
-         // 削除ボタン
-         $child = $this->twigRenderService
-             ->eachChildBuilder()
-             ->findThis()
-             ->targetFindAndIndexKey("#orderStatusExIndex_", "orderStatusExIndex")
-             ->setInsertModeAppend();
-         $this->twigRenderService
-             ->eachBuilder()
-             ->find("table > tbody > tr")
-             ->setEachIndexKey("orderStatusExIndex")
-             ->each($child->build());
-         // 削除用モーダル
-         $this->createInsertBuilder()
-             ->find("#form")
-             ->setTargetId("OrderStatusDeleteModal")
-             ->setInsertModeAfter();
-         $child = $this->twigRenderService
-             ->eachChildBuilder()
-             ->findThis()
-             ->find('td')
-             ->eq(2)
-             ->targetFindAndIndexKey("#orderStatusExIndex2_", "orderStatusExIndex2")
-             ->setInsertModeAppend();
-         $this->twigRenderService
-             ->eachBuilder()
-             ->find("table > tbody > tr")
-             ->setEachIndexKey("orderStatusExIndex2")
-             ->each($child->build());
-         $this->addTwigRenderSnippet(
-             '@OrderStatusEx/admin/Setting/Shop/order_status_add.twig',
-             '@OrderStatusEx/admin/Setting/Shop/order_status_add_js.twig'
-         );
-     }
-     public function onKernelController(ControllerEvent $event)
-     {
-         $request = $event->getRequest();
-         $route = $request->attributes->get('_route');
-         if ('admin_setting_shop_order_status' === $route) {
-             $session = $this->requestStack->getSession();
-             if ($session->get(OrderStatusExService::CACHE_CLEAR_KEY, false)) {
-                 $this->systemService->switchMaintenance(true);
-                 // Cache Clear
-                 $session->set(OrderStatusExService::CACHE_CLEAR_KEY, false);
-                 $this->cachUtil->clearCache();
-                 $this->systemService->disableMaintenance();
-             }
-             // 新規登録Form
-             $builder = $this->formFactory->createBuilder(OrderStatusSettingType::class, null);
-             $form = $builder->getForm();
-             $form->handleRequest($request);
-             // 新規登録分の登録処理
-             if ($form->isSubmitted()) {
-                 if ($form->isValid()) {
-                     // 登録処理実施
-                     /** @var OrderStatus $orderStatus */
-                     $orderStatus = $form->getData();
-                     // 受注状態追加
-                     $masterResult = $this->orderStatusExService->getMasterNextId(OrderStatus::class);
-                     $orderStatus
-                         ->setId($masterResult->nextId)
-                         ->setSortNo($masterResult->nextSortNo);
-                     $this->entityManager->persist($orderStatus);
-                     $this->entityManager->flush();
-                     // 色登録
-                     $color = $form->get('color')->getData();
-                     $this->orderStatusExService->registerOrderStatusColor($orderStatus, $color);
-                     // マイページ用名称登録
-                     $customerOrderStatusName = $form->get('customer_order_status_name')->getData();
-                     $this->orderStatusExService->registerCustomerOrderStatus($orderStatus, $customerOrderStatusName);
-                     // 移動先・イベント種別情報登録
-                     // 移動先取得
-                     $orderStatuses = $form->get('OrderStatuses')->getData();
-                     // 選択イベント取得
-                     $activeEvent = $form->get('ActiveEvent')->getData();
-                     // 他の受注状況拡張情報取得
-                     $orderStatusExs = $this->entityManager->getRepository(OrderStatusEx::class)->findAll();
-                     $orderStatusEventRepository = $this->entityManager->getRepository(OrderStatusEvent::class);
-                     $selectEvents = [];
-                     /** @var OrderStatusEx $orderStatusEx */
-                     foreach ($orderStatusExs as $orderStatusEx) {
-                         /** @var OrderStatusEvent $selectEventGroup */
-                         $selectEventGroup = $orderStatusEventRepository->find($orderStatusEx->getMoveOrderStatusId());
-                         if ($selectEventGroup) {
-                             $selectEvents[$orderStatusEx->getMoveOrderStatusId()] = $selectEventGroup->getSelectEventGroup();
-                         } else {
-                             $selectEvents[$orderStatusEx->getMoveOrderStatusId()] = OrderStatusEvent::EVENT_GROUP_NONE;
-                         }
-                     }
-                     // 新規追加分のイベント設定
-                     $selectEvents[$orderStatus->getId()] = $activeEvent;
-                     $this->orderStatusExService->updateOrderStatusEx($orderStatus, $orderStatuses, $selectEvents);
-                     $this->entityManager->flush();
-                     // リダイレクト
-                     $event->setController([$this->orderStatusExController, 'success']);
-                 }
-             } else if ($request->getMethod() == 'POST') {
-                 // Cache Clear ON
-                 $session->set(OrderStatusExService::CACHE_CLEAR_KEY, true);
-             }
-         }
-     }
-     /**
-      * 受注状況の発送済み相当変更時
-      *
-      * @param TransitionEvent $event
-      * @return void
-      */
-     public function onShip(TransitionEvent $event)
-     {
-         $tos = $event->getTransition()->getTos();
-         if (in_array(OrderStatus::DELIVERED, $tos)) {
-             return;
-         }
-         /** @var Order $order */
-         $order = $event->getSubject()->getOrder();
-         $order->getShippings()->map(function (Shipping $shipping) {
-             if (!$shipping->isShipped()) {
-                 $shipping->setShippingDate(new \DateTime());
-             }
-         });
-     }
-     public function onCompleted(Event $event)
-     {
-         /** @var $context OrderStateMachineContext */
-         $context = $event->getSubject();
-         $order = $context->getOrder();
-         /** @var OrderStatus $newOrderStatus */
-         $newOrderStatusId = $context->getStatus();
-         /** @var OrderStatusRepository $orderStatusRepository */
-         $orderStatusRepository = $this->entityManager->getRepository(OrderStatus::class);
-         $newOrderStatus = $orderStatusRepository->find($newOrderStatusId);
-         // 拡張情報へ選択したステータスを保持し表示ステータスに標準をセットする
-         $orderOrderStatus = $order->getOrderOrderStatus();
-         if (!$orderOrderStatus) {
-             $orderOrderStatus = new OrderOrderStatus();
-             $orderOrderStatus->setOrder($order);
-         }
-         $orderOrderStatus->setOrderStatus($newOrderStatus);
-         $this->entityManager->persist($orderOrderStatus);
-         // 集約保持モード
-         if (!$this->orderStatusExConfigService->isStrictMode()) {
-             $convertOrderStatus = $this->orderStatusExService->getConvertStatusByEvent($newOrderStatus);
-             $order->setOrderStatus($convertOrderStatus);
-         }
-     }
-     public static function getSubscribedEvents()
-     {
-         return [
-             KernelEvents::CONTROLLER => 'onKernelController',
-             '@admin/Setting/Shop/order_status.twig' => 'onSettingShopOrderStatusTwig',
-             'workflow.order.transition.ship' => 'onShip',
-             'workflow.order.completed' => ['onCompleted', -300],
-         ];
-     }
- }
-