<?php
/*
* Copyright(c) 2020 RACCOON HOLDINGS, Inc. All rights reserved.
* https://paid.jp/
*/
namespace Plugin\Paid4\EventSubscriber;
use Doctrine\ORM\EntityManagerInterface;
use Eccube\Common\EccubeConfig;
use Eccube\Entity\Order;
use \Exception;
use Plugin\Paid4\Entity\PaidOrder;
use Plugin\Paid4\Service\PaidApi\PaidHelperOrder;
use Plugin\Paid4\Service\Payment\Method\PaidMethod;
use Plugin\Paid4\Util\PaidUtil;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Workflow\Event\Event;
class AdminOrderStateEventSubscriber implements EventSubscriberInterface
{
/**
* 未決済ステータス
* @var mixed
*/
protected $unsettled;
/**
* 決済完了ステータス
* @var mixed
*/
protected $complete;
/**
* キャンセルステータス
* @var mixed
*/
protected $cancel;
/**
* @var EntityManagerInterface
*/
protected $entityManager;
/**
* @var PaidHelperOrder
*/
protected $paidHelperOrder;
/**
* @var mixed
*/
protected $routeName;
/**
* 管理画面->受注管理->出荷CSV登録のルート名
*/
const ADMIN_SHIPPING_CSV_IMPORT_ROUTE_NAME = 'admin_shipping_csv_import';
/**
* 管理画面->受注管理->受注一覧のルート名
*/
const ADMIN_SHIPPING_UPDATE_ORDER_STATUS_ROUTE_NAME = 'admin_shipping_update_order_status';
/**
* 管理画面->受注管理->PAID決済出荷CSV登録のルート名
*/
const ADMIN_SHIPPING_PAID_CSV_IMPORT_ROUTE_NAME = 'admin_shipping_paid_csv_import';
/**
* フロント->購入完了のルート名
*/
const FRONT_SHOPPING_COMPLETE_ROUTE_NAME = 'shopping_complete';
/**
* AdminOrderStateEventSubscriber constructor.
* @param EccubeConfig $eccubeConfig
* @param ContainerInterface $container
* @param EntityManagerInterface $entityManager
* @param PaidHelperOrder $paidHelperOrder
*/
public function __construct(
EccubeConfig $eccubeConfig,
ContainerInterface $container,
EntityManagerInterface $entityManager,
PaidHelperOrder $paidHelperOrder
)
{
// 未決済
$this->unsettled = $eccubeConfig['paid4.settlement.unsettled'];
// 決済完了
$this->complete = $eccubeConfig['paid4.settlement.complete'];
// キャンセル
$this->cancel = $eccubeConfig['paid4.settlement.cancel'];
$this->entityManager = $entityManager;
$request = $container->get('request_stack')->getCurrentRequest();
$this->routeName = $request->attributes->get('_route');
$this->paidHelperOrder = $paidHelperOrder;
}
/**
* @inheritDoc
*/
public static function getSubscribedEvents()
{
return [
'workflow.order.transition.pay' => ['onChangeOrder'],
'workflow.order.transition.packing' => ['onChangeOrder'],
'workflow.order.transition.ship' => ['onOrderShip'],
'workflow.order.transition.cancel' => ['onOrderCancel'],
];
}
/**
* @param Event $event
* @throws \Exception
*/
public function onChangeOrder(Event $event)
{
/** @var Order $Order */
$Order = $event->getSubject()->getOrder();
$this->changeOrder($Order);
}
/**
* @param Event $event
* @throws \Exception
*/
public function onOrderShip(Event $event)
{
/** @var Order $Order */
$Order = $event->getSubject()->getOrder();
$this->changeOrder($Order);
$this->statusValidate($Order, $this->complete);
}
/**
* @param Event $event
* @throws \Exception
*/
public function onOrderCancel(Event $event)
{
if ($this->routeName === self::FRONT_SHOPPING_COMPLETE_ROUTE_NAME) {
return;
}
// 既存出荷CSV登録処理は弾く
/** @var Order $Order */
$Order = $event->getSubject()->getOrder();
$this->changeOrder($Order);
$this->statusValidate($Order, $this->cancel);
}
/**
* @param Order $Order
* @param string $nextStatus
* @throws \Exception
*/
protected function changeOrder($Order)
{
// 既存の出荷CSV登録処理は弾く
if ($this->routeName === self::ADMIN_SHIPPING_CSV_IMPORT_ROUTE_NAME) {
return;
}
// 決済方法がPaid決済か確認
$Payment = $Order->getPayment();
if ($Payment->getMethodClass() !== PaidMethod::class) {
return;
}
$PaidOrder = $Order->getPaidOrder();
if (!is_null($PaidOrder)
&& $PaidOrder->getPaidSettlementStatus() === strval($this->unsettled)
&& $Order->getPaymentTotal() != $PaidOrder->getPaymentTotal()) {
$this->serLogMessage('workflow.order.transition - paid注文内容変更API開始');
$error = $this->paidHelperOrder->changeOrder($Order);
// 受注のステータスを戻すために強制終了
if (!$error) {
$this->serLogMessage('workflow.order.transition - paid注文内容変更API失敗');
if ($this->routeName === self::ADMIN_SHIPPING_PAID_CSV_IMPORT_ROUTE_NAME) {
// paidCSVインポート処理の場合はreturn
return;
}
throw new \Exception();
}
if ($error) {
$this->serLogMessage('workflow.order.transition - paid注文内容変更API完了');
$PaidOrder->setPaymentTotal($Order->getPaymentTotal());
$Order->setPaidOrder($PaidOrder);
}
}
}
/**
* @param Order $Order
* @param string $nextStatus
* @throws \Exception
*/
protected function statusValidate($Order, $nextStatus)
{
// 既存の出荷CSV登録処理は弾く
if ($this->routeName === self::ADMIN_SHIPPING_CSV_IMPORT_ROUTE_NAME) {
return;
}
// 決済方法がPaid決済か確認
$Payment = $Order->getPayment();
if ($Payment->getMethodClass() !== PaidMethod::class) {
return;
}
/** @var PaidOrder $PaidOrder */
$PaidOrder = $Order->getPaidOrder();
// ステータスが未決済のみ処理
if (!is_null($PaidOrder) &&
$PaidOrder->getPaidSettlementStatus() === strval($this->unsettled)) {
$result = false;
try {
if ($nextStatus == $this->complete) {
$this->serLogMessage('workflow.order.transition.ship - paid決済完了API開始');
$result = $this->paidHelperOrder->fixOrder($Order);
$this->serLogMessage('workflow.order.transition.ship - paid決済完了API終了');
} elseif ($nextStatus == $this->cancel) {
$this->serLogMessage('workflow.order.transition.cancel - paid決済キャンセルAPI開始');
$result = $this->paidHelperOrder->cancelOrder($Order);
$this->serLogMessage('workflow.order.transition.cancel - paid決済キャンセルAPI終了');
}
// Paid受注のステータス変更
} catch (Exception $e) {
// ログ出力
$this->serLogMessage('workflow.order.transition - PaidAPI失敗');
$result = false;
}
// 受注のステータスを戻すために強制終了
if (!$result) {
if ($this->routeName === self::ADMIN_SHIPPING_PAID_CSV_IMPORT_ROUTE_NAME) {
// paidCSVインポート処理の場合はreturn
return;
}
throw new \Exception();
}
if ($result) {
$this->serLogMessage('workflow.order.transition - paid受注ステータス更新開始');
$PaidOrder->setPaidSettlementStatus($nextStatus);
$PaidOrder->setSettlementDate(new \DateTime("now"));
$Order->setPaidOrder($PaidOrder);
if ($this->routeName === self::ADMIN_SHIPPING_UPDATE_ORDER_STATUS_ROUTE_NAME) {
$this->entityManager->flush($PaidOrder);
}
$this->serLogMessage('workflow.order.transition - paid受注ステータス更新終了');
}
}
}
/**
* @param string $Message
*/
private function serLogMessage($Message = '')
{
PaidUtil::logInfo(__NAMESPACE__ . get_class($this) .' - '. $Message);
}
}