<?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],
];
}
}