<?php
/*
* Copyright(c) 2020 RACCOON HOLDINGS, Inc. All rights reserved.
* https://paid.jp/
*/
namespace Plugin\Paid4\EventSubscriber;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\EntityManagerInterface;
use Eccube\Common\EccubeConfig;
use Eccube\Entity\Customer;
use Eccube\Entity\Master\OrderStatus;
use Eccube\Entity\Order;
use Eccube\Entity\Shipping;
use Eccube\Event\EccubeEvents;
use Eccube\Event\EventArgs;
use Eccube\Event\TemplateEvent;
use Eccube\Repository\Master\OrderStatusRepository;
use Eccube\Service\OrderStateMachine;
use Plugin\Paid4\Entity\PaidCustomer;
use Plugin\Paid4\Entity\PaidOrder;
use Plugin\Paid4\Service\CancelMailService;
use Plugin\Paid4\Service\PaidApi\PaidHelperOrder;
use Plugin\Paid4\Service\Payment\Method\PaidMethod;
use Plugin\Paid4\Util\PaidUtil;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
class ShoppingEventSubscriber implements EventSubscriberInterface
{
/**
* @var EccubeConfig
*/
protected $eccubeConfig;
/**
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* @var CancelMailService
*/
protected $cancelMailService;
/**
* @var OrderStatusRepository
*/
protected $orderStatusRepository;
/**
* @var OrderStateMachine
*/
protected $orderStateMachine;
/**
* @var PaidHelperOrder
*/
private $paidHelperOrder;
/**
* @var TokenStorageInterface
*/
private $tokenStorage;
/**
* @var mixed
*/
private $unregistered;
/**
* @var mixed
*/
private $notAvailable;
/**
* OrderEditIndexCompleteListener constructor.
*
* @param EccubeConfig $eccubeConfig
* @param EntityManagerInterface $entityManager
* @param CancelMailService $cancelMailService
* @param OrderStatusRepository $orderStatusRepository
* @param OrderStateMachine $orderStateMachine
* @param PaidHelperOrder $paidHelperOrder
* @param TokenStorageInterface $tokenStorage
*/
public function __construct(
EccubeConfig $eccubeConfig,
EntityManagerInterface $entityManager,
CancelMailService $cancelMailService,
OrderStatusRepository $orderStatusRepository,
OrderStateMachine $orderStateMachine,
PaidHelperOrder $paidHelperOrder,
TokenStorageInterface $tokenStorage
)
{
$this->tokenStorage = $tokenStorage;
$this->eccubeConfig = $eccubeConfig;
$this->entityManager = $entityManager;
$this->cancelMailService = $cancelMailService;
$this->orderStatusRepository = $orderStatusRepository;
$this->orderStateMachine = $orderStateMachine;
$this->paidHelperOrder = $paidHelperOrder;
$this->unregistered = $eccubeConfig['paid4.register.unregistered'];
$this->notAvailable = $eccubeConfig['paid4.use.not_available'];
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
'Shopping/index.twig' => 'onDefaultShoppingTwig',
EccubeEvents::FRONT_SHOPPING_COMPLETE_INITIALIZE => 'onFrontShoppingCompleteInitialize',
];
}
/**
* フロント -> ご注文手続き
*/
public function onDefaultShoppingTwig(TemplateEvent $event)
{
$PaidUse = true;
$token = $this->tokenStorage->getToken();
if ($token && $token->getUser() !== "anon.") {
if ($token->getProviderKey() === "customer") {
/** @var Customer $Customer */
$Customer = $token->getUser();
/** @var PaidCustomer $PaidCustomer */
$PaidCustomer = $Customer->getPaidCustomer();
// Paid未登録
if (empty($PaidCustomer)
|| $PaidCustomer->getPaidRegister() == $this->unregistered
|| is_null($PaidCustomer->getPaidRegister())) {
$PaidUse = false;
}
// Paid利用不可の場合はラベルを出さない
if (!empty($PaidCustomer) &&
$PaidCustomer->getPaidUse() == $this->notAvailable) {
$PaidUse = true;
}
}
// ゲスト購入
} else {
$PaidUse = false;
}
$event->setParameter('isNotPaidCustomer', $PaidUse);
$event->addSnippet('@Paid4/default/Shopping/PaidLabel.twig');
}
/**
* @param EventArgs $event
* @throws \Exception
*/
public function onFrontShoppingCompleteInitialize(EventArgs $event)
{
$request = $event->getRequest();
/** @var Order $Order */
$Order = $event->getArgument("Order");
$Payment = $Order->getPayment();
if ($Payment->getMethodClass() == PaidMethod::class) {
$this->serLogMessage('FRONT_SHOPPING_COMPLETE_INITIALIZE - Paid受注情報のステータス更新開始');
$now = new \DateTime("now");
$PaidOrder = new PaidOrder();
$PaidOrder->setOrder($Order)
->setPaymentTotal($Order->getPaymentTotal())
->setPaidSettlementStatus($this->eccubeConfig['paid4.settlement.unsettled'])
->setSettlementDate($now)
->setCreateDate($now)
->setUpdateDate($now);
$this->entityManager->persist($PaidOrder);
$this->entityManager->flush();
$this->serLogMessage('FRONT_SHOPPING_COMPLETE_INITIALIZE - Paid受注情報のステータス更新終了');
$this->serLogMessage('FRONT_SHOPPING_COMPLETE_INITIALIZE - 受注登録API開始');
$result = $this->paidHelperOrder->registerOrder($Order);
$this->serLogMessage('FRONT_SHOPPING_COMPLETE_INITIALIZE - 受注登録API終了');
$now = new \DateTime("now");
if (!$result) {
// 決済キャンセル
$PaidOrder
->setPaidSettlementStatus($this->eccubeConfig['paid4.settlement.cancel'])
->setSettlementDate($now);
// 受注情報のステータスをキャンセルに変更する
$this->serLogMessage('FRONT_SHOPPING_COMPLETE_INITIALIZE - 受注情報のステータスをキャンセルに変更開始');
$this->changeOrderStatus($Order);
$this->serLogMessage('FRONT_SHOPPING_COMPLETE_INITIALIZE - 受注情報のステータスをキャンセルに変更終了');
// キャンセルメール送信
$this->cancelMailService->sendOrderCancelMail($Order);
$this->serLogMessage('FRONT_SHOPPING_COMPLETE_INITIALIZE - Paid受注情報のステータス更新開始');
$this->entityManager->persist($PaidOrder);
$this->entityManager->flush();
$this->serLogMessage('FRONT_SHOPPING_COMPLETE_INITIALIZE - Paid受注情報のステータス更新終了');
}
}
}
/**
* @param Order $Order
*/
public function changeOrderStatus(Order $Order)
{
// 編集前の受注情報を保持
$OriginOrder = clone $Order;
$OriginItems = new ArrayCollection();
foreach ($Order->getOrderItems() as $Item) {
$OriginItems->add($Item);
}
// 受注ステータスを注文取消しに変更
$OrderStatus =
$this->orderStatusRepository->find(OrderStatus::CANCEL);
$Order->setOrderStatus($OrderStatus);
$OldStatus = $OriginOrder->getOrderStatus();
$NewStatus = $Order->getOrderStatus();
// ステータスが変更されている場合はステートマシンを実行.
if ($Order->getId() && $OldStatus->getId() != $NewStatus->getId()) {
// 発送済に変更された場合は, 発送日をセットする.
if ($NewStatus->getId() == OrderStatus::DELIVERED) {
$Order->getShippings()->map(function (Shipping $Shipping) {
if (!$Shipping->isShipped()) {
$Shipping->setShippingDate(new \DateTime());
}
});
}
// ステートマシンでステータスは更新されるので, 古いステータスに戻す.
$Order->setOrderStatus($OldStatus);
// FormTypeでステータスの遷移チェックは行っているのでapplyのみ実行.
$this->orderStateMachine->apply($Order, $NewStatus);
}
$this->entityManager->persist($Order);
$this->entityManager->flush();
}
/**
* @param string $Message
*/
private function serLogMessage($Message = '')
{
PaidUtil::logInfo(__NAMESPACE__ . get_class($this) .' - '. $Message);
}
}