<?php
namespace App\Controller;
use App\Component\Cart;
use App\Component\CartService;
use App\Component\RefererTrait;
use App\Entity\CartItem;
use App\Entity\Invoice;
use App\Entity\InvoiceDetail;
use App\Entity\Menu;
use App\Entity\Order;
use App\Entity\OrderMenu;
use App\Entity\Payment;
use App\Entity\PaymentMethod;
use App\Entity\User;
use App\Form\Type\CartAddItemType;
use App\Form\Type\CartUpdateQuantityType;
use App\GmoPg\Exception\HasErrorException;
use App\GmoPg\Exception\RequestException;
use App\GmoPg\Form\Type\CreditCardType;
use App\GmoPg\GmoPgCreditCard;
use Doctrine\ORM\EntityManagerInterface;
use Http\Discovery\Exception\NotFoundException;
use PascalDeVink\ShortUuid\ShortUuid;
use Ramsey\Uuid\Uuid;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
class CartController extends AbstractController
{
use RefererTrait;
/**
* @Route("/cart", name="cart_index")
*
* @param EntityManagerInterface $em
* @return Response
*/
public function index(Request $request, EntityManagerInterface $em, Security $security, CartService $cartService, GmoPgCreditCard $gmoPgCreditCard)
{
$user = $security->getToken()->getUser();
$form = $this->createForm(FormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// 支払処理
/* @var User $user */
if (! $user->getPrimaryPaymentMethod()) {
$this->addFlash('user-warning', 'お支払方法が設定されていません。');
return $this->redirectToRoute('cart_index');
}
$em->beginTransaction();
$result = $cartService->checkout($user);
if (! ($result instanceof Order)) {
$this->addFlash('user-warning', $result);
return $this->redirectToRoute('cart_index');
}
$em->commit();
return $this->redirectToRoute('cart_checkout', ['order' => $result->getId()]);
}
$user = $this->getUser();
$cart = $em->getRepository('App:Cart')->getAvailableCartByUser($user);
return $this->render('index/cart/index.html.twig', [
'user' => $user,
'cart' => $cart,
'form' => $form->createView(),
]);
}
/**
* @Route("/cart/checkout/{order}", name="cart_checkout")
*
*/
public function cartDone(Request $request, EntityManagerInterface $em, Order $order)
{
$user = $this->getUser();
if ($order->getUser()->getId() != $user->getId()) {
throw $this->createAccessDeniedException();
}
return $this->render('index/cart/checkout.html.twig', [
'user' => $user,
'order' => $order,
]);
}
/**
* @Route("/cart/add/{menu}", name="cart_add")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param Security $security
* @param Menu $menu
* @param CartService $cartService
* @return \Symfony\Component\HttpFoundation\RedirectResponse
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function add(Request $request, EntityManagerInterface $em, Security $security, Menu $menu, CartService $cartService)
{
$form = $this->createForm(CartAddItemType::class);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($this->isCsrfTokenValid('add-item', $request->request->get('token'))) {
$data = $form->getData();
$quantity = 1;
if ($data['quantity']) {
$quantity = $data['quantity'];
}
// $this->cartFactory->addItem($menu, $quantity);
// $this->addFlash('success', 'カートに'. $menu->getName(). 'を追加しました。');
$user = $this->getUser();
$toCart = false;
if ($user) {
$token = $security->getToken();
$_user = $token->getUser();
if ($_user instanceof User) {
$toCart = true;
}
}
if (! $toCart) {
// 未ログインなのでログイン画面にリダイレクト
// 戻りURL情報をリファラから取得
$params = $this->getRefererParams();
// 登録後にカートに商品を追加するためセッションに保存
$this->container->get('session')->set('auth_adding_item', [
'params' => $params,
'menuId' => $menu->getId(),
'quantity' => $quantity,
]);
return $this->redirectToRoute('user_register');
} else {
$cartService->addCartItem($user, $menu, $quantity);
$em->flush();
$this->addFlash('user-success', 'カートに'. $menu->getName(). 'を追加しました。');
$this->container->get('session')->remove('auth_adding_item');
}
}
}
return $this->redirectToRoute('shop', [
'id' => $menu->getShop()->getId(),
]);
}
/**
* @Route("/cart/update-quantity", name="cart_update_quantity")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param Security $security
* @param Menu $menu
* @param CartService $cartService
* @return JsonResponse
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function updateQuantity(Request $request, EntityManagerInterface $em, Security $security, CartService $cartService)
{
$form = $this->createForm(CartUpdateQuantityType::class);
$form->handleRequest($request);
$cartItem = null;
if ($form->isSubmitted()) {
if ($this->isCsrfTokenValid('cart_update_quantity', $request->request->get('token'))) {
$data = $form->getData();
$user = $security->getToken()->getUser();
$cartItem = $em->getRepository('App:CartItem')->find($data['cartItem']);
$cartService->updateQuantity($user, $cartItem->getMenu(), $data['quantity']);
$em->flush();
}
}
return new JsonResponse();
}
/**
* @Route("/cart/payment-method", name="cart_payment_method")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param Security $security
* @param Menu $menu
* @param CartService $cartService
* @return Response
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function paymentMethod(Request $request, EntityManagerInterface $em, Security $security, CartService $cartService)
{
$user = $this->getUser();
return $this->render('index/cart/payment_method/index.html.twig', [
'user' => $user,
]);
}
/**
* @Route("/cart/payment-method/add", name="cart_payment_method_add")
*
* @param Request $request
* @param EntityManagerInterface $em
* @param Security $security
* @param Menu $menu
* @param CartService $cartService
* @return Response
* @throws \Psr\Container\ContainerExceptionInterface
* @throws \Psr\Container\NotFoundExceptionInterface
*/
public function paymentMethodAdd(Request $request, EntityManagerInterface $em, Security $security, CartService $cartService, GmoPgCreditCard $gmoPgCreditCard)
{
$user = $this->getUser();
$form = $this->createForm(CreditCardType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$em->beginTransaction();
// 既存の支払方法を優先ではなくす
foreach ($user->getPaymentMethods() as $paymentMethod) {
$paymentMethod->setIsPrimary(false);
$em->persist($paymentMethod);
}
try {
$gmoPgCreditCard->saveMember($user);
// カード登録
$paymentMethod = new PaymentMethod();
$paymentMethod->setUser($user);
$paymentMethod->setIsPrimary(true);
$paymentMethod->setType(PaymentMethod::TYPE_CREDIT_CARD);
$em->persist($paymentMethod);
$creditCard = $gmoPgCreditCard->saveCard($paymentMethod, $data['credit_card_token']);
$em->persist($creditCard);
$paymentMethod->setCreditCard($creditCard);
$em->persist($paymentMethod);
} catch (HasErrorException $e) {
$messages = $gmoPgCreditCard->convertErrorCodeToMessage($e->getErrors());
$this->addFlash('user-danger', "クレジットカードの登録に失敗しました。" . implode("", $messages) . '(エラーコード:' . implode(',', $e->getErrors()) . ')');
return $this->redirectToRoute('cart_payment_method_add');
} catch (RequestException $e) {
$this->addFlash('user-danger', 'クレジットカード会社との通信に失敗しました。恐れ入りますが、しばらく待ってから再度入力をお願いいたします。(エラーコード:' .$e->getCode(). ')');
return $this->redirectToRoute('cart_payment_method_add');
} catch (\Exception $e) {
$this->addFlash('user-danger', 'クレジットカードの登録に失敗しました。恐れ入りますが、しばらく待ってから再度入力をお願いいたします。(エラーコード:' .$e->getCode(). ')');
return $this->redirectToRoute('cart_payment_method_add');
}
$em->persist($user);
$em->flush();
$em->commit();
$this->addFlash('user-success', 'お支払い情報を保存しました');
return $this->redirectToRoute('cart_index');
}
return $this->render('index/cart/payment_method/add.html.twig', [
'form' => $form->createView(),
'user' => $user,
]);
}
}