<?php
/*
* Copyright (c) 2018 VeriTrans Inc., a Digital Garage company. All rights reserved.
* http://www.veritrans.co.jp/
*/
namespace Plugin\VeriTrans4G2\Service\Shopping;
use Eccube\Common\Constant;
use Eccube\Event\TemplateEvent;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Plugin\VeriTrans4G2\Entity\Vt4gPaymentMethod;
use Plugin\VeriTrans4G2\Entity\Master\Vt4gSubscSaleType;
use Symfony\Component\Form\FormError;
/**
* ご注文手続き画面 拡張用クラス
*/
class IndexExtensionService
{
/**
* コンテナ
*/
protected $container;
/**
* エンティティーマネージャー
*/
protected $em;
/**
* 汎用処理用サービス
*/
protected $util;
/**
* VT用固定値配列
*/
protected $vt4gConst;
/**
* コンストラクタ
*
* @param ContainerInterface $container
* @return void
*/
public function __construct(ContainerInterface $container)
{
$this->container = $container;
$this->em = $container->get('doctrine.orm.entity_manager');
$this->util = $container->get('vt4g_plugin.service.util');
$this->vt4gConst = $container->getParameter('vt4g_plugin.const');
}
/**
* ご注文手続き画面 レンダリング時のイベントリスナ
* @param TemplateEvent $event イベントデータ
* @return void
*/
public function onRenderBefore(TemplateEvent $event)
{
$excludePaymentIdList = [];
//plg_vt4g_payment_methodを取得
$vt4gPaymentMethods = $this->em->getRepository(Vt4gPaymentMethod::class)->findAll();
//ご注文手続き画面のリクエストが存在する場合は削除する
if ($this->container->get('session')->has('vt4g_shopping_request')) {
$this->container->get('session')->remove('vt4g_shopping_request');
}
//支払情報の有無を確認する。
$paymentId = '';
if (!empty($event->getParameter('Order')->getPayment())) {
$paymentId = $event->getParameter('Order')->getPayment()->getId();
}
$paymentInfo = null;
foreach ($vt4gPaymentMethods as $vt4gPaymentMethod) {
if ($vt4gPaymentMethod->getPaymentId() == $paymentId) {
$paymentInfo = $vt4gPaymentMethod;
break;
}
}
// 注文商品の販売種別を取得
$orderSaleTypes = $event->getParameter('Order')->getSaleTypes();
$curSaleTypeId = isset($orderSaleTypes[0]) ? $orderSaleTypes[0]->getId() : null;
// $subscSaleTypeがnullでなかったら継続課金商品
$subscSaleType = $this->em->getRepository(Vt4gSubscSaleType::class)->findOneBy(['sale_type_id' => $curSaleTypeId]);
//plg_vt4g_pluginのサブデータから有効になっている決済内部IDを取得
$enablePayIdList = $this->util->getEnablePayIdList();
// 継続課金対象の注文
if (isset($subscSaleType)) {
// 注文の顧客マスタ情報を取得
$customer = $event->getParameter('Order')->getCustomer();
// 顧客マスタあり(ベリトランス会員)、かつ、決済内部IDにクレジットカード決済が含まれていたらクレジットカード決済のみ有効
if (in_array($this->vt4gConst['VT4G_PAYTYPEID_CREDIT'], $enablePayIdList) && isset($customer)) {
$paymethodCredits = $this->em->getRepository(Vt4gPaymentMethod::class)->findBy(['memo03' => $this->vt4gConst['VT4G_PAYTYPEID_CREDIT']]);
$enablePayIdList = [$this->vt4gConst['VT4G_PAYTYPEID_CREDIT']];
foreach ($paymethodCredits as $paymethodCredit) {
$memo5Array = !is_null($paymethodCredit->getMemo05()) ? unserialize($paymethodCredit->getMemo05()) : [];
$oneClickFlg = !empty($memo5Array['one_click_flg']) ? $memo5Array['one_click_flg'] : null;
if (is_null($oneClickFlg) || $oneClickFlg != $this->vt4gConst['VT4G_CREDIT_ONE_CLICK']['VERITRANS_ID']) {
$excludePaymentIdList[] = $paymethodCredit->getPaymentId();
}
}
} else {
// 決済手段なし
$enablePayIdList = [];
}
}
//有効な決済内部IDリストに存在しないplg_vt4g_payment_methodのpayment_idを対象外リストに追加
foreach ($vt4gPaymentMethods as $vt4gPaymentMethod) {
if (!in_array($vt4gPaymentMethod->getMemo03(), $enablePayIdList)) {
$excludePaymentIdList[] = $vt4gPaymentMethod->getPaymentId();
}
}
// 継続課金注文の場合
if (isset($subscSaleType)) {
// plg_vt4g_payment_methodに含まれないdtb_paymentの支払方法も対象外リストに追加
$notExistsVt4gPaymentMethodList = $this->em->getRepository(Vt4gPaymentMethod::class)->getNotExistsVt4gPaymentMethodList();
foreach ($notExistsVt4gPaymentMethodList as $notExistsVt4gPaymentMethod) {
$excludePaymentIdList[] = $notExistsVt4gPaymentMethod['id'];
}
}
//お支払方法のFormViewから対象外リストにあるpayment_idを削除
$form = $event->getParameter('form');
$paymentFormViews = $form['Payment'];
foreach ($paymentFormViews as $key => $paymentFormView){
if (in_array($paymentFormView->vars['value'], $excludePaymentIdList)) {
$paymentFormViews->offsetUnset($key);
}
}
// 有効な支払い方法がない場合
if ($paymentFormViews->count() == 0) {
// 「支払い情報を選択」する旨のエラーとなるのでそのメッセージを除去
$form['Payment']->vars['errors'] = [];
$form['Payment']->vars['errors'] = [new FormError(trans('front.shopping.payment_method_not_fount'))];
$paymentInfo = null;
} else {
// お支払方法一覧にdtb_orderで指定中のpaymentIDが存在しない場合は、有効な支払方法の中から1件目の項目を選択済みとする
$formViesChildren = $paymentFormViews->children;
if (!array_key_exists($paymentId,$formViesChildren)) {
foreach ($paymentFormViews as $paymentId => $paymentFormView){
$paymentFormView->vars['checked'] = true;
$paymentInfo = $this->util->getPaymentMethod($paymentId);
break;
}
}
}
$event->setParameter('form', $form);
//お支払方法に1件も表示する支払方法がない、ポイント利用によりベリトランス決済以外が選択された場合は処理を終了する
if(empty($paymentInfo)){
return;
}
$payTypeId = $paymentInfo->getMemo03();
$pluginSetting = $this->util->getPluginSetting();
if (empty($pluginSetting['use_recaptcha'])) {
$recaptchaAipUrl = '';
$useRecaptcha = false;
} else if ($pluginSetting['use_recaptcha'] === $this->vt4gConst['VT4G_RECAPTCHA_EXECUTE']['ONLY_CREDIT']) {
$recaptchaAipUrl = $payTypeId == $this->vt4gConst['VT4G_PAYTYPEID_CREDIT']
? $this->vt4gConst['VT4G_RECAPTCHA_URL'].$pluginSetting['recaptcha_site_key']
: '';
$useRecaptcha = empty($recaptchaAipUrl) ? false : true;
} else {
$recaptchaAipUrl = $this->vt4gConst['VT4G_RECAPTCHA_URL'].$pluginSetting['recaptcha_site_key'];
$useRecaptcha = true;
}
// 支払方法に応じたフォームの表示処理
switch ($paymentInfo->getMemo03()) {
case $this->vt4gConst['VT4G_PAYTYPEID_CREDIT']:
//クレジットカードを選択した場合の処理
$credit = $this->container->get('vt4g_plugin.service.payment_credit');
$customer = $event->getParameter('Order')->getCustomer();
$paymentInfo = $this->util->getPaymentMethodInfo($paymentId);
// クレジットカード情報入力フォーム
$cardForm = $credit->createCreditForm($paymentInfo);
// ベリトランス会員ID決済入力フォーム
$accountForm = $credit->createAccountForm($paymentInfo);
// 再取引入力フォーム
$oneClickForm = $credit->createOneClickForm($paymentInfo);
//バリデーションチェックエラーが存在したときのチェックを行う
if ($this->container->get('session')->has('vt4g_shopping_error')) {
$vt4gShoppingError = $this->container->get('session')->get('vt4g_shopping_error');
switch ($vt4gShoppingError['mode']) {
case 'token':
$cardForm = $this->addFormError($cardForm);
break;
case 'account':
$accountForm = $this->addFormError($accountForm);
break;
case 'retrade':
$oneClickForm = $this->addFormError($oneClickForm);
break;
default:
break;
}
}
$paymentInfo['one_click_flg'] = $paymentInfo['one_click_flg'] ?? $this->vt4gConst['VT4G_CREDIT_ONE_CLICK']['DISABLED'];
// ベリトランス会員ID決済の利用可否
$useAccountPayment = $paymentInfo['one_click_flg'] === $this->vt4gConst['VT4G_CREDIT_ONE_CLICK']['VERITRANS_ID'];
// 登録済みカード情報を取得
$isGranted = $this->container->get('security.authorization_checker')->isGranted('IS_AUTHENTICATED_FULLY');
$accountCards = $useAccountPayment && $isGranted && !empty($customer->vt4g_account_id)
? $this->container->get('vt4g_plugin.service.vt4g_account_id')->getAccountCards($customer->vt4g_account_id)
: [];
// 登録済みカード情報が存在しない場合
if (empty($accountCards)) {
$useAccountPayment = false;
}
$cardsMax = $paymentInfo['cardinfo_regist_max'] ?? $this->vt4gConst['VT4G_FORM']['DEFAULT']['CARDINFO_REGIST_MAX'];
// 再取引の利用可否
$useReTradePayment = $paymentInfo['one_click_flg'] === $this->vt4gConst['VT4G_CREDIT_ONE_CLICK']['RETRADE'];
// 再取引用の注文情報を取得
$retrade = $this->container->get('vt4g_plugin.service.vt4g_retrade');
$reTradeCards = $useReTradePayment
? $retrade->getReTradeCards($customer)
: [];
// 再取引に使用可能なカード情報が存在しない場合
if (empty($reTradeCards)) {
$useReTradePayment = false;
}
// 継続課金商品の注文か判定
$subscOrderFlg = $this->em->getRepository(Vt4gSubscSaleType::class)->judgmentSubscSaleTypeByOrderId($event->getParameter('Order')->getId());
$event->addSnippet(
$this->container->get('twig')->render(
"VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment_credit_setting.twig",
[
'form' => $cardForm->createView(),
'accountForm' => $accountForm->createView(),
'oneClickForm' => $oneClickForm->createView(),
'paymentInfo' => $paymentInfo,
'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_10'],
'useAccountPayment' => $useAccountPayment,
'accountCards' => $accountCards,
'useReTradePayment' => $useReTradePayment,
'reTradeCards' => $reTradeCards,
'cardRegistFlg' => $customer != null && $paymentInfo['one_click_flg'] === $this->vt4gConst['VT4G_CREDIT_ONE_CLICK']['VERITRANS_ID'],
'cardRetradeFlg' => $customer != null && $paymentInfo['one_click_flg'] === $this->vt4gConst['VT4G_CREDIT_ONE_CLICK']['RETRADE'],
'isCardMaxOver' => count($accountCards) >= $cardsMax,
'subscOrderFlg' => $subscOrderFlg,
'tokenApiUrl' => $this->vt4gConst['VT4G_PLUGIN_TOKEN_API_ENDPOINT'],
'tokenApiKey' => $pluginSetting['token_api_key'],
'tokenJsPath' => $this->util->getTokenJsPath(),
'useRecaptcha' => $useRecaptcha,
'recaptchaSiteKey' => $pluginSetting['recaptcha_site_key'],
],
'text/html'
),
false
);
break;
case $this->vt4gConst['VT4G_PAYTYPEID_CVS']:
//コンビニを選択した場合の処理
$cvs = $this->container->get('vt4g_plugin.service.payment_cvs');
$form = $cvs->createCVSForm($this->util->getPaymentMethodInfo($paymentId));
$form = $this->addFormError($form);
//ご注文手続きにコンビニ設定用のFormを追加する。
$event->addSnippet(
$this->container->get('twig')->render(
"VeriTrans4G2/Resource/template/default/Shopping/vt4g_payment_cvs_setting.twig",
[
'title' => $this->vt4gConst['VT4G_PAYNAME_PAYTYPEID_20'],
'form' => $form->createView(),
],
'text/html'
),
false
);
break;
default:
break;
}
$useThrottling = Constant::VERSION >= $this->vt4gConst['VT4G_ECCUBE_VERSION_THROTTLING']
? !empty($pluginSetting['vt4g_shopping_index_rate_limit'])
: false;
$customer = $event->getParameter('Order')->getCustomer();
$event->addSnippet(
$this->container->get('twig')->render(
"VeriTrans4G2/Resource/template/default/js/vt4g_js.twig",
[
'useThrottling' => $useThrottling,
'url' => $this->util->generateUrl('vt4g_shopping_index_rate_limiter'),
'customerId' => is_null($customer) ? null : $customer->getId(),
'orderId' => $event->getParameter('Order')->getId(),
'payTypeId' => $payTypeId,
'useRecaptcha' => $useRecaptcha,
'recaptchaAipUrl' => $recaptchaAipUrl,
'recaptchaSiteKey' => $pluginSetting['recaptcha_site_key'],
],
'text/html'
),
false
);
}
/**
* ご注文手続き画面 拡張formにエラーを付与する
* @param Form $form formデータ
* @return Form $form formデータ
*/
private function addFormError($form) {
//sessionよりエラーの内容を取得し、formに付与する
if ($this->container->get('session')->has('vt4g_shopping_error')) {
$vt4gShoppingError = $this->container->get('session')->get('vt4g_shopping_error');
$this->container->get('session')->remove('vt4g_shopping_error');
foreach($vt4gShoppingError as $name => $errorMsg){
if($name === 'mode'){
continue;
}
$form[$name]->addError(new FormError($errorMsg));
}
}
return $form;
}
}