src/Eccube/Controller/ProductController.php line 471

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of EC-CUBE
  4.  *
  5.  * Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
  6.  *
  7.  * http://www.ec-cube.co.jp/
  8.  *
  9.  * For the full copyright and license information, please view the LICENSE
  10.  * file that was distributed with this source code.
  11.  */
  12. namespace Eccube\Controller;
  13. use Carbon\Carbon;
  14. use Doctrine\Common\Collections\ArrayCollection;
  15. use Eccube\Entity\BaseInfo;
  16. use Eccube\Entity\Category;
  17. use Eccube\Entity\Customer;
  18. use Eccube\Entity\CustomerAddress;
  19. use Eccube\Entity\ItemHolderInterface;
  20. use Eccube\Entity\Master\ProductStatus;
  21. use Eccube\Entity\Order;
  22. use Eccube\Entity\Product;
  23. use Eccube\Event\EccubeEvents;
  24. use Eccube\Event\EventArgs;
  25. use Eccube\Form\Type\AddCartType;
  26. use Eccube\Form\Type\Master\ProductListMaxType;
  27. use Eccube\Form\Type\Master\ProductListOrderByType;
  28. use Eccube\Form\Type\SearchProductType;
  29. use Eccube\Repository\BaseInfoRepository;
  30. use Eccube\Repository\CategoryRepository;
  31. use Eccube\Repository\CustomerFavoriteProductRepository;
  32. use Eccube\Repository\Master\ProductListMaxRepository;
  33. use Eccube\Repository\ProductRepository;
  34. use Eccube\Service\CartService;
  35. use Eccube\Repository\DeliveryFeeRepository;
  36. use Eccube\Repository\DeliveryRepository;
  37. use Eccube\Service\PurchaseFlow\PurchaseContext;
  38. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  39. use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
  40. use Knp\Component\Pager\Paginator;
  41. use Plugin\Coupon4\Form\Type\CouponUseType;
  42. use Plugin\Coupon4\Repository\CouponOrderRepository;
  43. use Plugin\Coupon4\Repository\CouponRepository;
  44. use Plugin\Coupon4\Service\CouponService;
  45. use Plugin\EccubePaymentLite4\Repository\RegularDiscountRepository;
  46. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  47. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  48. use Symfony\Component\Form\FormError;
  49. use Symfony\Component\HttpFoundation\Request;
  50. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  51. use Symfony\Component\Routing\Annotation\Route;
  52. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  53. use Plugin\StripePaymentGateway\Repository\StripeConfigRepository;
  54. use Eccube\Entity\ProductClass//20220829 kikuzawa
  55. use Eccube\Entity\Shipping;
  56. use Eccube\Exception\ShoppingException;
  57. use Eccube\Form\Type\AddCartByEmailType;
  58. use Eccube\Form\Type\Front\CustomerAddressType;
  59. use Eccube\Form\Type\Front\MyCardType;
  60. use Eccube\Form\Type\Front\ShoppingShippingType;
  61. use Eccube\Form\Type\Shopping\CustomerAddressOneTouchType;
  62. use Eccube\Repository\CartRepository;
  63. use Eccube\Repository\OrderRepository;
  64. use Plugin\ProductOption\Entity\Option//20220829 kikuzawa
  65. use Plugin\ProductOption\Service\ProductOptionCartService//20220829 kikuzawa
  66. use Eccube\Repository\CustomerRepository//20220812 kikuzawa
  67. use Eccube\Repository\CustomerAddressRepository//20220812 kikuzawa
  68. use Eccube\Service\MailService;
  69. use Eccube\Service\OneTouchService;
  70. use Eccube\Service\OrderHelper;
  71. use Eccube\Service\Payment\PaymentDispatcher;
  72. use Eccube\Service\Payment\PaymentMethodInterface;
  73. use Eccube\Service\ProductReviewService;
  74. use Exception;
  75. use Plugin\ProductReview4\Entity\ProductReview;
  76. use Plugin\ProductReview4\Repository\ProductReviewRepository;
  77. use Plugin\StripePaymentGateway\Entity\StripeCustomer;
  78. use Plugin\StripePaymentGateway\StripeClient;
  79. use Plugin\StripeRec\Service\Method\StripeRecurringNagMethod;
  80. use Psr\Container\ContainerInterface;
  81. use Stripe\PaymentMethod;
  82. use Stripe\Customer as StripeLibCustomer;
  83. use Symfony\Component\Asset\Packages;
  84. use Symfony\Component\Asset\VersionStrategy\EmptyVersionStrategy;
  85. use Symfony\Component\Form\Test\FormInterface;
  86. use Symfony\Component\Validator\Constraints\Length;
  87. use function Plugin\get;
  88. class ProductController extends AbstractController
  89. {
  90.     /**
  91.      * @var PurchaseFlow
  92.      */
  93.     protected $purchaseFlow;
  94.     /**
  95.      * @var PurchaseFlow
  96.      */
  97.     protected $shoppingPurchaseFlow;
  98.     /**
  99.      * @var MailService
  100.      */
  101.     protected $mailService;
  102.     /**
  103.      * @var CustomerFavoriteProductRepository
  104.      */
  105.     protected $customerFavoriteProductRepository;
  106.     /**
  107.      * @var CartService
  108.      */
  109.     protected $cartService;
  110.     /**
  111.      * @var ProductRepository
  112.      */
  113.     protected $productRepository;
  114.     /**
  115.      * @var BaseInfo
  116.      */
  117.     protected $BaseInfo;
  118.     /**
  119.      * @var AuthenticationUtils
  120.      */
  121.     protected $helper;
  122.     /**
  123.      * @var ProductListMaxRepository
  124.      */
  125.     protected $productListMaxRepository;
  126.     /**
  127.      * @var OrderHelper
  128.      */
  129.     protected $orderHelper;
  130.     /**
  131.      * @var DeliveryFeeRepository
  132.      */
  133.     protected $deliveryFeeRepository;
  134.     /**
  135.      * @var DeliveryRepository
  136.      */
  137.     protected $deliveryRepository;
  138.     /**
  139.      * @var CartRepository
  140.      */
  141.     protected $cartRepository;
  142.     /**
  143.      * @var OrderRepository
  144.      */
  145.     protected $orderRepository;
  146.     private $title '';
  147.     protected $stripeConfigRepository;
  148.     //20220812 kikuzawa
  149.     protected $customerRepository;
  150.     protected $customerAddressRepository;
  151.     protected $container;
  152.     private $em;
  153.     protected $stripeCustomerRepository;
  154.     /**
  155.      * @var CategoryRepository
  156.      */
  157.     protected $categoryRepository;
  158.     
  159.     /**
  160.      * @var RegularDiscountRepository
  161.      */
  162.     protected $regularDiscountRepository;
  163.     /**
  164.      * @var CouponService
  165.      */
  166.     protected $couponService;
  167.     /**
  168.      * @var CouponRepository
  169.      */
  170.     protected $couponRepository;
  171.     /**
  172.      * @var CouponOrderRepository
  173.      */
  174.     protected $couponOrderRepository;
  175.     protected $packages;
  176.     protected $productReviewRepository;
  177.     protected $productReviewService;
  178.     protected $OnetouchService;
  179.     /**
  180.      * ProductController constructor.
  181.      *
  182.      * @param PurchaseFlow $cartPurchaseFlow
  183.      * @param CustomerFavoriteProductRepository $customerFavoriteProductRepository
  184.      * @param CartService $cartService
  185.      * @param ProductRepository $productRepository
  186.      * @param BaseInfoRepository $baseInfoRepository
  187.      * @param AuthenticationUtils $helper
  188.      * @param ProductListMaxRepository $productListMaxRepository
  189.      */
  190.     public function __construct(
  191.         PurchaseFlow $cartPurchaseFlow,
  192.         CustomerFavoriteProductRepository $customerFavoriteProductRepository,
  193.         // CartService $cartService,
  194.         ProductRepository $productRepository,
  195.         BaseInfoRepository $baseInfoRepository,
  196.         AuthenticationUtils $helper,
  197.         CustomerRepository $customerRepository//20220812 kikuzawa
  198.         CustomerAddressRepository $customerAddressRepository,
  199.         ProductOptionCartService $cartService//20220812 kikuzawa
  200.         ProductListMaxRepository $productListMaxRepository,
  201.         ContainerInterface $container,
  202.         OrderHelper $orderHelper,
  203.         MailService $mailService,
  204.         StripeConfigRepository $stripeConfigRepository,
  205.         DeliveryFeeRepository $deliveryFeeRepository,
  206.         DeliveryRepository $deliveryRepository,
  207.         CartRepository $cartRepository,
  208.         OrderRepository $orderRepository,
  209.         PurchaseFlow $shoppingPurchaseFlow,
  210.         CategoryRepository $categoryRepository,
  211.         RegularDiscountRepository $regularDiscountRepository,
  212.         CouponService $couponService,
  213.         CouponRepository $couponRepository,
  214.         CouponOrderRepository $couponOrderRepository,
  215.         Packages $packages,
  216.         ProductReviewRepository $productReviewRepository,
  217.         ProductReviewService $productReviewService,
  218.         OneTouchService $OnetouchService
  219.     ) {
  220.         $this->purchaseFlow $cartPurchaseFlow;
  221.         $this->customerFavoriteProductRepository $customerFavoriteProductRepository;
  222.         $this->cartService $cartService;
  223.         $this->mailService $mailService;
  224.         $this->productRepository $productRepository;
  225.         $this->BaseInfo $baseInfoRepository->get();
  226.         $this->helper $helper;
  227.         $this->productListMaxRepository $productListMaxRepository;
  228.         $this->container $container;
  229.         $this->em $container->get('doctrine.orm.entity_manager');
  230.         $this->stripeCustomerRepository $this->em->getRepository(StripeCustomer::class);
  231.         $this->deliveryFeeRepository $deliveryFeeRepository;
  232.         $this->deliveryRepository $deliveryRepository;
  233.         $this->orderHelper $orderHelper;
  234.         $this->cartRepository $cartRepository;
  235.         $this->orderRepository $orderRepository;
  236.         $this->stripeConfigRepository $stripeConfigRepository;
  237.         $this->customerRepository $customerRepository//20220812 kikuzawa
  238.         $this->customerAddressRepository $customerAddressRepository//20220812 kikuzawa
  239.         $this->shoppingPurchaseFlow $shoppingPurchaseFlow;
  240.         $this->categoryRepository $categoryRepository;
  241.         $this->regularDiscountRepository $regularDiscountRepository;
  242.         $this->couponService $couponService;
  243.         $this->couponRepository $couponRepository;
  244.         $this->couponOrderRepository $couponOrderRepository;
  245.         $this->packages $packages;
  246.         $this->productReviewRepository $productReviewRepository;
  247.         $this->productReviewService $productReviewService;
  248.         $this->OnetouchService $OnetouchService;
  249.     }
  250.     /**
  251.      * 商品一覧画面.
  252.      *
  253.      * @Route("/products/list", name="product_list")
  254.      * @Template("Product/list.twig")
  255.      */
  256.     public function index(Request $requestPaginator $paginator)
  257.     {
  258.         $Customer $this->getUser();
  259.         // Doctrine SQLFilter
  260.         if ($this->BaseInfo->isOptionNostockHidden()) {
  261.             $this->entityManager->getFilters()->enable('option_nostock_hidden');
  262.         }
  263.         // handleRequestは空のqueryの場合は無視するため
  264.         if ($request->getMethod() === 'GET') {
  265.             $request->query->set('pageno'$request->query->get('pageno'''));
  266.         }
  267.         // searchForm
  268.         /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  269.         $builder $this->formFactory->createNamedBuilder(''SearchProductType::class);
  270.         if ($request->getMethod() === 'GET') {
  271.             $builder->setMethod('GET');
  272.         }
  273.         $event = new EventArgs(
  274.             [
  275.                 'builder' => $builder,
  276.             ],
  277.             $request
  278.         );
  279.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE$event);
  280.         /* @var $searchForm \Symfony\Component\Form\FormInterface */
  281.         $searchForm $builder->getForm();
  282.         $searchForm->handleRequest($request);
  283.         // paginator
  284.         $searchData $searchForm->getData();
  285.         if($Customer){
  286.             if ($Customer->getIsSupplier() === true) {
  287.                 $qb $this->productRepository->getQueryBuilderBySearchData($searchData$Customer->getOwnerRank(), true);
  288.             } else {
  289.                 $qb $this->productRepository->getQueryBuilderBySearchData($searchData$Customer->getOwnerRank());
  290.             }
  291.         }else{
  292.             $qb $this->productRepository->getQueryBuilderBySearchData($searchData);
  293.         }
  294.         $event = new EventArgs(
  295.             [
  296.                 'searchData' => $searchData,
  297.                 'qb' => $qb,
  298.             ],
  299.             $request
  300.         );
  301.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_SEARCH$event);
  302.         $searchData $event->getArgument('searchData');
  303.         $query $qb->getQuery()
  304.             ->useResultCache(true$this->eccubeConfig['eccube_result_cache_lifetime_short']);
  305.         /** @var SlidingPagination $pagination */
  306.         $pagination $paginator->paginate(
  307.             $query,
  308.             !empty($searchData['pageno']) ? $searchData['pageno'] : 1,
  309.             !empty($searchData['disp_number']) ? $searchData['disp_number']->getId() : $this->productListMaxRepository->findOneBy([], ['sort_no' => 'ASC'])->getId()
  310.         );
  311.         // if (isset($searchData['category_id']) && $searchData['category_id']) {
  312.         //     // カテゴリ表示時は全て表示
  313.         //     $pagination = $paginator->paginate($query,1,99);
  314.         // } else {
  315.         //     // BEST OF BEST表示時は4件のみ
  316.         //     $pagination = $paginator->paginate($query,1,4);
  317.         // }
  318.         $ids = [];
  319.         $ReviewAveList = array();
  320.         $ReviewCntList = array();
  321.         foreach ($pagination as $Product) {
  322.             $ids[] = $Product->getId();
  323.             $rate $this->entityManager->getRepository('Plugin\ProductReview4\Entity\ProductReview')->getAvgAll($Product);
  324.             $ReviewAveList[$Product->getId()] = round($rate['recommend_avg']);
  325.             $ReviewCntList[$Product->getId()] = intval($rate['review_count']);
  326.         }
  327.         $ProductsAndClassCategories $this->productRepository->findProductsWithSortedClassCategories($ids'p.id');
  328.         // addCart form
  329.         $forms = [];
  330.         foreach ($pagination as $Product) {
  331.             /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  332.             $builder $this->formFactory->createNamedBuilder(
  333.                 '',
  334.                 AddCartType::class,
  335.                 null,
  336.                 [
  337.                     'product' => $ProductsAndClassCategories[$Product->getId()],
  338.                     'allow_extra_fields' => true,
  339.                 ]
  340.             );
  341.             $addCartForm $builder->getForm();
  342.             $forms[$Product->getId()] = $addCartForm->createView();
  343.         }
  344.         // 表示件数
  345.         $builder $this->formFactory->createNamedBuilder(
  346.             'disp_number',
  347.             ProductListMaxType::class,
  348.             null,
  349.             [
  350.                 'required' => false,
  351.                 'allow_extra_fields' => true,
  352.             ]
  353.         );
  354.         if ($request->getMethod() === 'GET') {
  355.             $builder->setMethod('GET');
  356.         }
  357.         $event = new EventArgs(
  358.             [
  359.                 'builder' => $builder,
  360.             ],
  361.             $request
  362.         );
  363.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_DISP$event);
  364.         $dispNumberForm $builder->getForm();
  365.         $dispNumberForm->handleRequest($request);
  366.         // ソート順
  367.         $builder $this->formFactory->createNamedBuilder(
  368.             'orderby',
  369.             ProductListOrderByType::class,
  370.             null,
  371.             [
  372.                 'required' => false,
  373.                 'allow_extra_fields' => true,
  374.             ]
  375.         );
  376.         if ($request->getMethod() === 'GET') {
  377.             $builder->setMethod('GET');
  378.         }
  379.         $event = new EventArgs(
  380.             [
  381.                 'builder' => $builder,
  382.             ],
  383.             $request
  384.         );
  385.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_INDEX_ORDER$event);
  386.         $orderByForm $builder->getForm();
  387.         $orderByForm->handleRequest($request);
  388.         $Category $searchForm->get('category_id')->getData();
  389.         if (!isset($searchForm->getData()['name'])) {
  390.             $items $pagination->getItems();
  391.             $filteredItems array_filter($items, function ($product) {
  392.                 return $product['id'] !== 1543;
  393.             });
  394.         
  395.             $pagination->setItems($filteredItems);
  396.         }
  397.         return [
  398.             'subtitle' => $this->getPageTitle($searchData),
  399.             'pagination' => $pagination,
  400.             'search_form' => $searchForm->createView(),
  401.             'disp_number_form' => $dispNumberForm->createView(),
  402.             'order_by_form' => $orderByForm->createView(),
  403.             'forms' => $forms,
  404.             'Category' => $Category,
  405.             'ReviewAveList' => $ReviewAveList,
  406.             'ReviewCntList' => $ReviewCntList,
  407.         ];
  408.     }
  409.     /**
  410.      * 商品一覧画面.
  411.      *
  412.      * @Route("/products/category/{id}", name="product_category")
  413.      */
  414.     public function listCategory(Request $requestCategory $category)
  415.     {
  416.         $searchData = [
  417.             'category_id' => $category
  418.         ];
  419.         $productCategoriesQuery $this->productRepository->getQueryBuilderBySearchData($searchData);
  420.         $productCategories $productCategoriesQuery->getQuery()->getResult();
  421.         if ($productCategories !== null && count($productCategories) > 0) {
  422.             foreach ($productCategories as $Product) {
  423.                 $rate $this->productReviewService->getReview($Product);
  424.                 $reg_price 0;
  425.                 if($Product->hasProductClass()) {
  426.                     $reg_price $Product->getPrice02IncTaxMin();
  427.                 } else {
  428.                     $reg_price $Product->getPrice02IncTaxMin();
  429.                 }
  430.                 if ($Product->getProductClasses()[0]->getRegularDiscount() && $Product->getProductClasses()[0]->getRegularDiscount()->getDiscountRate() > 0) {
  431.                     $price $reg_price $reg_price $Product->getProductClasses()[0]->getRegularDiscount()->getDiscountRate() / 100;
  432.                 }
  433.                 $tags $this->productRepository->getProductTags($Product->getId());
  434.                 $tagName = !empty($tags) ? $tags[0]['name'] : null;
  435.                 $parentVariant $this->productRepository->findVariantsByProductId($Product->getId());
  436.                 $parentVariantId $parentVariant $parentVariant->getId() : null;
  437.                 $product[] = [
  438.                     'id' => $Product->getId(),
  439.                     'name' => $Product->getName(),
  440.                     'slug' => $Product->getSlug(),
  441.                     'parent_variant_id' => $parentVariantId,
  442.                     'product_class' => $Product->getProductClasses()[0]->getId(),
  443.                     'price_discount' => $price ?? 0,
  444.                     'price' => $reg_price,
  445.                     'discount_rate' => $Product->getProductClasses()[0]->getRegularDiscount() ? $Product->getProductClasses()[0]->getRegularDiscount()->getDiscountRate() : 0,
  446.                     'image' => $Product->getMainListImage() ? $Product->getMainListImage()->getFileName() : null,
  447.                     'star' => round($rate['RecommendAvg'], 1),
  448.                     'reviewCount' => intval($rate['ReviewCntList']),
  449.                     'tagName' => $tagName,
  450.                 ];
  451.             }
  452.         }
  453.         return $this->json($product);
  454.     }
  455.     /**
  456.      * 商品詳細画面.
  457.      * @Route("/products/detail/{id}", name="product_detail_old", methods={"GET"})
  458.      * @Route("/products/{id}/{slug}", name="product_detail", methods={"GET"}, requirements={"id"="\d+", "slug"=".+"})
  459.      * @Template("Product/detail.twig")
  460.      * @ParamConverter("Product", options={"repository_method" = "findWithSortedClassCategories"})
  461.      *
  462.      * @param Request $request
  463.      * @param Product $Product
  464.      *
  465.      * @return array
  466.      */
  467.     public function detail(Request $requestProduct $Product,$slug null)
  468.     {
  469.         $ChangeCustomer $this->session->get('PRODUCT_DETAIL_REGULAR') ?? $this->session->get('PRODUCT_DETAIL') ?? 0;
  470.         if ($request->attributes->get('_route') === 'product_detail_old') {
  471.             $slug $Product->getSlug();
  472.             return $this->redirectToRoute('product_detail', ['id' => $Product->getId(), 'slug' => $slug]);
  473.         }
  474.         if(!$Product->getIsVariant() && $slug !== $Product->getSlug()) {
  475.             return $this->redirectToRoute('product_detail', ['id' => $Product->getId(), 'slug' => $Product->getSlug()]);
  476.         }
  477.         $Customer null;
  478.         $LastOrder = [];
  479.         if ($this->isGranted('ROLE_USER')) {
  480.             $Customer $this->getUser();
  481.             $is_favorite $this->customerFavoriteProductRepository->isFavorite($Customer$Product);
  482.          
  483.             $LastOrder $this->productRepository->getCountProductOrder($Product->getId(),$Customer->getId());
  484.         }
  485.         $ProductVariant $this->productRepository->findVariantsByProductId($Product->getId());        
  486.         
  487.         if ($ProductVariant) {
  488.             $url '/products/'.$ProductVariant->getId().'?s='.$Product->getId().'/'.$Product->getSlug();
  489.             return $this->redirect($url);
  490.         }
  491.         if ((!$this->getUser() && !$this->session->get("IS_SUPPLIER")) || ($this->getUser() && !$this->getUser()->getIsSupplier())) {
  492.             if ($this->handlerSupplierProduct($Product)) {
  493.                 return $this->redirectToRoute('salon-suppliers');
  494.             }
  495.         }
  496.         if (!$this->checkVisibility($Product)) {
  497.             throw new NotFoundHttpException();
  498.         }
  499.         if ($this->session->get('PRODUCT_DETAIL')) {
  500.             $this->session->remove('PRODUCT_DETAIL');
  501.         }
  502.         $builder $this->formFactory->createNamedBuilder(
  503.             '',
  504.             AddCartType::class,
  505.             null,
  506.             [
  507.                 'product' => $Product,
  508.                 'id_add_product_id' => false,
  509.             ]
  510.         );
  511.         $event = new EventArgs(
  512.             [
  513.                 'builder' => $builder,
  514.                 'Product' => $Product,
  515.             ],
  516.             $request
  517.         );
  518.         $Customer null;
  519.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_DETAIL_INITIALIZE$event);
  520.         $is_favorite false;
  521.         if ($this->isGranted('ROLE_USER')) {
  522.             $Customer $this->getUser();
  523.             $is_favorite $this->customerFavoriteProductRepository->isFavorite($Customer$Product);
  524.         }
  525.         //お気に入り数の合計を取得 20211127 kikuzawa
  526.         $favorite_total 0;
  527.         $favorite_total $this->customerFavoriteProductRepository->getFavoriteTotal($Product);
  528.         $user_id "";
  529.         $Customer $this->getUser();
  530.         $Customer null;
  531.         
  532.         $productRegularDiscounts null;
  533.         if ($Product) {
  534.             $productRegular $Product->getRegularProduct();
  535.             if ($productRegular){
  536.                 $productRegularDiscount $productRegular->getProductClasses()[0]->getRegularDiscount();
  537.                 if ($productRegularDiscount) {
  538.                     $productRegularDiscounts $this->regularDiscountRepository->findBy([
  539.                         'discount_id' => $productRegularDiscount->getDiscountId()
  540.                     ]);
  541.                     
  542.                 }
  543.             }
  544.         }
  545.         $saleType null;
  546.         if ($this->isGranted('ROLE_USER')) {
  547.             $Customer $this->getUser();
  548.             $StripeCustomerData $this->OnetouchService->getCustomerStripeOnetouch($Customer$Product);
  549.             $productRegularDiscounts $StripeCustomerData['productRegularDiscounts'] ?? null;
  550.             $saleType $Product['ProductClasses'][0]->getSaleType()->getId();
  551.         }
  552.         $ship null;
  553.         $DeliveryFreeAmount $this->BaseInfo->getDeliveryFreeAmount();
  554.         //
  555.         if($Product->getOwnerProductId()){
  556.             // ダイヤモンド会員向けの商品ページは非表示、通常商品ページにリダイレクト
  557.             $OwnerProduct $this->productRepository->find($Product->getOwnerProductId());
  558.             if ($OwnerProduct) {
  559.                 return $this->redirectToRoute('product_detail', ["id"=>$OwnerProduct->getId(), "slug"=>$OwnerProduct->getSlug()]);
  560.             }
  561.         }
  562.         $RankProduct null;
  563.         if($Product->getRankPrice()){
  564.             // ダイヤモンド会員向けの商品情報の取得
  565.             $RankProduct $this->productRepository->findOneBy(["owner_product_id"=>$Product->getId()]);
  566.         }
  567.         $s $request->get('s');
  568.         if ($s) {
  569.             $VariantChild explode('/'$s)[0];
  570.         }
  571.         $defaultSelect $VariantChild ?? 0;
  572.         $this->session->remove('PRODUCT_DETAIL');
  573.         $this->session->remove('PRODUCT_DETAIL_REGULAR');
  574.         $Product->setPageViews($Product->getPageViews() + 1);
  575.         $this->entityManager->persist($Product);
  576.         $this->entityManager->flush();
  577.         $faqs $this->productRepository->parseFAQs($Product->getLlmoFaq());
  578.         return [
  579.             'title' => $this->title,
  580.             'subtitle' => $Product->getName(),
  581.             'form' => $builder->getForm()->createView(),
  582.             'Product' => $Product,
  583.             'is_favorite' => $is_favorite,
  584.             'favorite_total' => $favorite_total//お気に入り数の合計を取得 20211127 kikuzawa
  585.             'user_id' => $user_id,
  586.             'Customer' => $Customer,
  587.             'RankProduct' => $RankProduct,
  588.             'productRegularDiscounts' => $productRegularDiscounts,
  589.             'LastOrder' =>$LastOrder,
  590.             'IsLightVersion' => $this->BaseInfo->getIsLightVersion(),
  591.             "defaultSelect"=> $defaultSelect,
  592.             'Sale_type' => $saleType,
  593.             'ChangeCustomer' => $ChangeCustomer,
  594.             'faqs' => $faqs,
  595.         ];
  596.     }
  597.     /**
  598.      * お気に入り追加.
  599.      *
  600.      * @Route("/products/add_favorite/{id}", name="product_add_favorite", requirements={"id" = "\d+"})
  601.      */
  602.     public function addFavorite(Request $requestProduct $Product)
  603.     {
  604.         $this->checkVisibility($Product);
  605.         $event = new EventArgs(
  606.             [
  607.                 'Product' => $Product,
  608.             ],
  609.             $request
  610.         );
  611.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_INITIALIZE$event);
  612.         if ($this->isGranted('ROLE_USER')) {
  613.             $Customer $this->getUser();
  614.             $this->customerFavoriteProductRepository->addFavorite($Customer$Product);
  615.             $this->session->getFlashBag()->set('product_detail.just_added_favorite'$Product->getId());
  616.             $event = new EventArgs(
  617.                 [
  618.                     'Product' => $Product,
  619.                 ],
  620.                 $request
  621.             );
  622.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE$event);
  623.             
  624.             if ($request->get("supplier_page")) {
  625.                 return $this->json(['status' => 'success''message' => '商品はお気に入りに保存されました']);
  626.             }
  627.             return $this->redirectToRoute('product_detail', ['id' => $Product->getId()]);
  628.         } else {
  629.             // 非会員の場合、ログイン画面を表示
  630.             //  ログイン後の画面遷移先を設定
  631.             $this->setLoginTargetPath($this->generateUrl('product_add_favorite', ['id' => $Product->getId()]));
  632.             $this->session->getFlashBag()->set('eccube.add.favorite'true);
  633.             $event = new EventArgs(
  634.                 [
  635.                     'Product' => $Product,
  636.                 ],
  637.                 $request
  638.             );
  639.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE$event);
  640.             return $this->redirectToRoute('mypage_login');
  641.         }
  642.     }
  643.     /**
  644.      * カートに追加.
  645.      *
  646.      * @Route("/products/add_cart/{id}", name="product_add_cart", methods={"POST","GET"}, requirements={"id" = "\d+"})
  647.      */
  648.     //app/Plugin/ProductOption/Controller/AddcartController.phpの内容を移植 20220829 kikuzawa
  649.     public function addCart(Request $requestProduct $Product)
  650.     {
  651.         // エラーメッセージの配列
  652.         $errorMessages = [];
  653.         if (!$this->checkVisibility($Product)) {
  654.             throw new NotFoundHttpException();
  655.         }
  656.         $builder $this->formFactory->createNamedBuilder(
  657.             '',
  658.             AddCartType::class,
  659.             null,
  660.             [
  661.                 'product' => $Product,
  662.                 'id_add_product_id' => false,
  663.             ]
  664.         );
  665.         $event = new EventArgs(
  666.             [
  667.                 'builder' => $builder,
  668.                 'Product' => $Product,
  669.             ],
  670.             $request
  671.         );
  672.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE$event);
  673.         /* @var $form \Symfony\Component\Form\FormInterface */
  674.         $form $builder->getForm();
  675.         $form->handleRequest($request);
  676.         //送り先のメールアドレス(option1)が会員情報に存在するかチェック 20220812 kikuzawa
  677.         if (isset($form->all()['productoption1'])) {
  678.             $recipientEmail $form->get('productoption1')->getData();
  679.             if ($recipientEmail) {
  680.                 $customer $this->customerRepository->findBy(array('email' => $recipientEmail));
  681.                 if (!$customer) {
  682.                     $errorMessages[] = '存在しないメールアドレスです。';
  683.                 }
  684.             }
  685.         }
  686.         if (!$form->isValid()) {
  687.             foreach ($form->all() as $child) {
  688.                 $config $child->getConfig();
  689.                 foreach ($child->getErrors() as $error) {
  690.                     $errorMessages[] = $config->getOption('label') . ':' $error->getMessage();
  691.                 }
  692.             }
  693.         }
  694.         $addCartData $form->getData();
  695.         $ProductClass $this->entityManager->getRepository(ProductClass::class)->find($addCartData['product_class_id']);
  696.         $limit $ProductClass->getSaleLimit();
  697.         if (!$ProductClass->isStockUnlimited()) {
  698.             $stock $ProductClass->getStock();
  699.         }
  700.         if (!is_null($limit) || isset($stock)) {
  701.             $Carts $this->cartService->getCarts();
  702.             $quantity $addCartData['quantity'];
  703.             foreach ($Carts as $Cart) {
  704.                 foreach ($Cart->getCartItems() as $item) {
  705.                     if ($item->getProductClass()->getId() == $ProductClass->getId()) $quantity += $item->getQuantity();
  706.                 }
  707.             }
  708.             $productName $ProductClass->getProduct()->getName();
  709.             if ($ProductClass->hasClassCategory1()) {
  710.                 $productName .= ' - ' $ProductClass->getClassCategory1()->getName();
  711.             }
  712.             if ($ProductClass->hasClassCategory2()) {
  713.                 $productName .= ' - ' $ProductClass->getClassCategory2()->getName();
  714.             }
  715.             if (!is_null($limit) && $limit $quantity) {
  716.                 $errorMessages[] = trans('front.shopping.over_sale_limit', ['%product%' => $productName]);
  717.             }
  718.             if (isset($stock) && $stock $quantity) {
  719.                 $errorMessages[] = trans('front.shopping.out_of_stock', ['%product%' => $productName]);
  720.             }
  721.         }
  722.         if (count($errorMessages) == 0) {
  723.             log_info(
  724.                 'カート追加処理開始',
  725.                 [
  726.                     'product_id' => $Product->getId(),
  727.                     'product_class_id' => $addCartData['product_class_id'],
  728.                     'quantity' => $addCartData['quantity'],
  729.                 ]
  730.             );
  731.             // カートへ追加
  732.             $ProductOptions $Product->getProductOptions();
  733.             $Options = [];
  734.             foreach ($ProductOptions as $ProductOption) {
  735.                 $Option $ProductOption->getOption();
  736.                 $option_key 'productoption' $Option->getId();
  737.                 $value $form->get($option_key)->getData();
  738.                 if ($Option) {
  739.                     $add true;
  740.                     if ($Option->getType() == Option::SELECT_TYPE || $Option->getType() == Option::RADIO_TYPE) {
  741.                         if ($Option->getDisableCategory()) {
  742.                             if ($Option->getDisableCategory() == $value) {
  743.                                 $add false;
  744.                             }
  745.                         }
  746.                         $value $value->getId();
  747.                         if (strlen($value) == 0$add false;
  748.                     } elseif ($Option->getType() == Option::TEXT_TYPE || $Option->getType() == Option::TEXTAREA_TYPE || $Option->getType() == Option::NUMBER_TYPE) {
  749.                         if (strlen($value) == 0$add false;
  750.                     } elseif ($Option->getType() == Option::CHECKBOX_TYPE) {
  751.                         if (count($value) == 0) {
  752.                             $add false;
  753.                         } else {
  754.                             $buff $value;
  755.                             $value = [];
  756.                             foreach ($buff as $categoryoption) {
  757.                                 $value[] = $categoryoption->getId();
  758.                             }
  759.                         }
  760.                     } elseif ($Option->getType() == Option::DATE_TYPE) {
  761.                         if (is_null($value)) $add false;
  762.                     }
  763.                     if ($add) {
  764.                         if (is_array($value)) {
  765.                             $Options[$Option->getId()] = $value;
  766.                         } elseif (is_object($value)) {
  767.                             $Options[$Option->getId()] = $value->format('Y-m-d');
  768.                         } else {
  769.                             $Options[$Option->getId()] = (string)$value;
  770.                         }
  771.                     }
  772.                 }
  773.             }
  774.             $this->cartService->addProductOption($addCartData['product_class_id'], $Options$addCartData['quantity']);
  775.             // 明細の正規化
  776.             $Carts $this->cartService->getCarts();
  777.             foreach ($Carts as $Cart) {
  778.                 $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->getUser()));
  779.                 // 復旧不可のエラーが発生した場合は追加した明細を削除.
  780.                 if ($result->hasError()) {
  781.                     $this->cartService->removeProduct($addCartData['product_class_id']);
  782.                     foreach ($result->getErrors() as $error) {
  783.                         $errorMessages[] = $error->getMessage();
  784.                     }
  785.                 }
  786.                 foreach ($result->getWarning() as $warning) {
  787.                     $errorMessages[] = $warning->getMessage();
  788.                 }
  789.             }
  790.             $this->cartService->save();
  791.             log_info(
  792.                 'カート追加処理完了',
  793.                 [
  794.                     'product_id' => $Product->getId(),
  795.                     'product_class_id' => $addCartData['product_class_id'],
  796.                     'quantity' => $addCartData['quantity'],
  797.                 ]
  798.             );
  799.             $event = new EventArgs(
  800.                 [
  801.                     'form' => $form,
  802.                     'Product' => $Product,
  803.                 ],
  804.                 $request
  805.             );
  806.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE$event);
  807.         }
  808.         if ($event->getResponse() !== null) {
  809.             return $event->getResponse();
  810.         }
  811.         if ($request->isXmlHttpRequest()) {
  812.             // ajaxでのリクエストの場合は結果をjson形式で返す。
  813.             // 初期化
  814.             $done null;
  815.             $messages = [];
  816.             if (empty($errorMessages)) {
  817.                 // エラーが発生していない場合
  818.                 $done true;
  819.                 array_push($messagestrans('front.product.add_cart_complete'));
  820.             } else {
  821.                 // エラーが発生している場合
  822.                 $done false;
  823.                 $messages $errorMessages;
  824.             }
  825.             $Customer $this->getUser();
  826.             $Point $this->getPointCart($Cart$Customer);
  827.             $Cart $this->cartService->getCart();
  828.             $quantity 0;
  829.             $Total 0;
  830.             foreach ($Carts as $Cart) {
  831.                 foreach ($Cart->getCartItems() as $item) {
  832.                     if ($item->getProductClass()->getId() == $ProductClass->getId()){
  833.                         $quantity $item->getQuantity();
  834.                     }
  835.                 }
  836.                 $Total $Total $Cart->getTotalPrice();
  837.                 
  838.             }
  839.             
  840.             return $this->json(['done' => $done'messages' => $messages'total_price' => number_format($Total), 'add_point' => $Point'product_class_id' => $ProductClass->getId(), 'quantity' => $quantity]);
  841.         } else {
  842.             // ajax以外でのリクエストの場合はカート画面へリダイレクト
  843.             if (empty($errorMessages)) {
  844.                 return $this->redirectToRoute('cart');
  845.             } else {
  846.                 foreach ($errorMessages as $errorMessage) {
  847.                     $this->addRequestError($errorMessage);
  848.                 }
  849.                 return $this->redirect($request->headers->get('referer'));
  850.             }
  851.         }
  852.     }
  853.     /**
  854.      * ページタイトルの設定
  855.      *
  856.      * @param  null|array $searchData
  857.      *
  858.      * @return str
  859.      */
  860.     protected function getPageTitle($searchData)
  861.     {
  862.         if (isset($searchData['name']) && !empty($searchData['name'])) {
  863.             return trans('front.product.search_result');
  864.         } elseif (isset($searchData['category_id']) && $searchData['category_id']) {
  865.             return $searchData['category_id']->getName();
  866.         } else {
  867.             return trans('front.product.all_products');
  868.         }
  869.     }
  870.     /**
  871.      * 閲覧可能な商品かどうかを判定
  872.      *
  873.      * @param Product $Product
  874.      *
  875.      * @return boolean 閲覧可能な場合はtrue
  876.      */
  877.     protected function checkVisibility(Product $Product)
  878.     {
  879.         $is_admin $this->session->has('_security_admin');
  880.         // 管理ユーザの場合はステータスやオプションにかかわらず閲覧可能.
  881.         if (!$is_admin) {
  882.             // 在庫なし商品の非表示オプションが有効な場合.
  883.             // if ($this->BaseInfo->isOptionNostockHidden()) {
  884.             //     if (!$Product->getStockFind()) {
  885.             //         return false;
  886.             //     }
  887.             // }
  888.             // 公開ステータスでない商品は表示しない.
  889.             if ($Product->getStatus()->getId() !== ProductStatus::DISPLAY_SHOW) {
  890.                 return false;
  891.             }
  892.         }
  893.         return true;
  894.     }
  895.     /**
  896.      * カートに追加.
  897.      *
  898.      * @Route("/products/one_touch_payment/{id}", name="one_touch_payment", methods={"POST"}, requirements={"id" = "\d+"})
  899.      * @Template("Product/detail.twig")
  900.      */
  901.     public function oneTouchPayment(Request $requestProduct $Product)
  902.     {
  903.         // エラーメッセージの配列
  904.         $errorMessages = [];
  905.         if (!$this->checkVisibility($Product)) {
  906.             throw new NotFoundHttpException();
  907.         }
  908.         $builder $this->formFactory->createNamedBuilder(
  909.             '',
  910.             AddCartType::class,
  911.             null,
  912.             [
  913.                 'product' => $Product,
  914.                 'id_add_product_id' => false,
  915.             ]
  916.         );
  917.         $event = new EventArgs(
  918.             [
  919.                 'builder' => $builder,
  920.                 'Product' => $Product,
  921.             ],
  922.             $request
  923.         );
  924.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE$event);
  925.         /* @var $form \Symfony\Component\Form\FormInterface */
  926.         $form $builder->getForm();
  927.         $form->handleRequest($request);
  928.         //送り先のメールアドレス(option1)が会員情報に存在するかチェック 20220812 kikuzawa
  929.         if (isset($form->all()['productoption1'])) {
  930.             $recipientEmail $form->get('productoption1')->getData();
  931.             if ($recipientEmail) {
  932.                 $customer $this->customerRepository->findBy(array('email' => $recipientEmail));
  933.                 if (!$customer) {
  934.                     $errorMessages[] = '存在しないメールアドレスです。';
  935.                 }
  936.             }
  937.         }
  938.         if (!$form->isValid()) {
  939.             foreach ($form->all() as $child) {
  940.                 $config $child->getConfig();
  941.                 foreach ($child->getErrors() as $error) {
  942.                     $errorMessages[] = $config->getOption('label') . ':' $error->getMessage();
  943.                 }
  944.             }
  945.         }
  946.         $addCartData $form->getData();
  947.         $ProductClass $this->entityManager->getRepository(ProductClass::class)->find($addCartData['product_class_id']);
  948.         $limit $ProductClass->getSaleLimit();
  949.         if (!$ProductClass->isStockUnlimited()) {
  950.             $stock $ProductClass->getStock();
  951.         }
  952.         if (!is_null($limit) || isset($stock)) {
  953.             $Carts $this->cartService->getCarts();
  954.             $quantity $addCartData['quantity'];
  955.             foreach ($Carts as $Cart) {
  956.                 foreach ($Cart->getCartItems() as $item) {
  957.                     if ($item->getProductClass()->getId() == $ProductClass->getId()) $quantity += $item->getQuantity();
  958.                 }
  959.             }
  960.             $productName $ProductClass->getProduct()->getName();
  961.             if ($ProductClass->hasClassCategory1()) {
  962.                 $productName .= ' - ' $ProductClass->getClassCategory1()->getName();
  963.             }
  964.             if ($ProductClass->hasClassCategory2()) {
  965.                 $productName .= ' - ' $ProductClass->getClassCategory2()->getName();
  966.             }
  967.             if (!is_null($limit) && $limit $quantity) {
  968.                 $errorMessages[] = trans('front.shopping.over_sale_limit', ['%product%' => $productName]);
  969.             }
  970.             if (isset($stock) && $stock $quantity) {
  971.                 $errorMessages[] = trans('front.shopping.out_of_stock', ['%product%' => $productName]);
  972.             }
  973.         }
  974.         $oneTouchPaymentCart null;
  975.         if (count($errorMessages) == 0) {
  976.             log_info(
  977.                 'カート追加処理開始',
  978.                 [
  979.                     'product_id' => $Product->getId(),
  980.                     'product_class_id' => $addCartData['product_class_id'],
  981.                     'quantity' => $addCartData['quantity'],
  982.                 ]
  983.             );
  984.             // カートへ追加
  985.             $ProductOptions $Product->getProductOptions();
  986.             $Options = [];
  987.             foreach ($ProductOptions as $ProductOption) {
  988.                 $Option $ProductOption->getOption();
  989.                 $option_key 'productoption' $Option->getId();
  990.                 $value $form->get($option_key)->getData();
  991.                 if ($Option) {
  992.                     $add true;
  993.                     if ($Option->getType() == Option::SELECT_TYPE || $Option->getType() == Option::RADIO_TYPE) {
  994.                         if ($Option->getDisableCategory()) {
  995.                             if ($Option->getDisableCategory() == $value) {
  996.                                 $add false;
  997.                             }
  998.                         }
  999.                         $value $value->getId();
  1000.                         if (strlen($value) == 0$add false;
  1001.                     } elseif ($Option->getType() == Option::TEXT_TYPE || $Option->getType() == Option::TEXTAREA_TYPE || $Option->getType() == Option::NUMBER_TYPE) {
  1002.                         if (strlen($value) == 0$add false;
  1003.                     } elseif ($Option->getType() == Option::CHECKBOX_TYPE) {
  1004.                         if (count($value) == 0) {
  1005.                             $add false;
  1006.                         } else {
  1007.                             $buff $value;
  1008.                             $value = [];
  1009.                             foreach ($buff as $categoryoption) {
  1010.                                 $value[] = $categoryoption->getId();
  1011.                             }
  1012.                         }
  1013.                     } elseif ($Option->getType() == Option::DATE_TYPE) {
  1014.                         if (is_null($value)) $add false;
  1015.                     }
  1016.                     if ($add) {
  1017.                         if (is_array($value)) {
  1018.                             $Options[$Option->getId()] = $value;
  1019.                         } elseif (is_object($value)) {
  1020.                             $Options[$Option->getId()] = $value->format('Y-m-d');
  1021.                         } else {
  1022.                             $Options[$Option->getId()] = (string)$value;
  1023.                         }
  1024.                     }
  1025.                 }
  1026.             }
  1027.             $this->cartService->addProductOption($addCartData['product_class_id'], $Options$addCartData['quantity']);
  1028.             // 明細の正規化
  1029.             $Carts $this->cartService->getCarts();
  1030.             foreach ($Carts as $Cart) {
  1031.                 $cartItems $Cart->getCartItems();
  1032.                 $isOneTouchPayment $cartItems[0]->getIsOneTouchPayment();
  1033.                 if ($isOneTouchPayment) {
  1034.                     $oneTouchPaymentCart $cartItems[0]->getCart();
  1035.                 }
  1036.                 $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->getUser()));
  1037.                 // 復旧不可のエラーが発生した場合は追加した明細を削除.
  1038.                 if ($result->hasError()) {
  1039.                     $this->cartService->removeProduct($addCartData['product_class_id']);
  1040.                     foreach ($result->getErrors() as $error) {
  1041.                         $errorMessages[] = $error->getMessage();
  1042.                     }
  1043.                 }
  1044.                 foreach ($result->getWarning() as $warning) {
  1045.                     $errorMessages[] = $warning->getMessage();
  1046.                 }
  1047.             }
  1048.             $this->cartService->save();
  1049.             log_info(
  1050.                 'カート追加処理完了',
  1051.                 [
  1052.                     'product_id' => $Product->getId(),
  1053.                     'product_class_id' => $addCartData['product_class_id'],
  1054.                     'quantity' => $addCartData['quantity'],
  1055.                 ]
  1056.             );
  1057.             $event = new EventArgs(
  1058.                 [
  1059.                     'form' => $form,
  1060.                     'Product' => $Product,
  1061.                 ],
  1062.                 $request
  1063.             );
  1064.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE$event);
  1065.         }
  1066.         if ($event->getResponse() !== null) {
  1067.             return $event->getResponse();
  1068.         }
  1069.             // ajaxでのリクエストの場合は結果をjson形式で返す。
  1070.             // 初期化
  1071.         $done null;
  1072.         $messages = [];
  1073.         $Customer $this->getUser();
  1074.         if (empty($errorMessages) && $oneTouchPaymentCart && $Customer) {
  1075.             // エラーが発生していない場合
  1076.             $done true;
  1077.             try {
  1078.                 $Order $this->orderHelper->initializeOrder($oneTouchPaymentCart$Customer);
  1079.                 $this->executePurchaseFlow($Orderfalse);
  1080.                 if ($Customer->getId()) {
  1081.                     $this->orderHelper->updateCustomerInfo($Order$Customer);
  1082.                     $trial $Customer->getTrialFamilyDate();
  1083.                     if ($trial) {
  1084.                         $date Carbon::parse($trial->format('Y-m-d H:i:s'));
  1085.                         $now Carbon::now();
  1086.                         $diff $date->diffInMonths($now);
  1087.                         if ($diff 1) {
  1088.                             $Order->setPaymentTotal($Order->getPaymentTotal() - $Order->getDeliveryFeeTotal());
  1089.                             $Order->setTotal($Order->getTotal() - $Order->getDeliveryFeeTotal());
  1090.                             $Order->setDeliveryFeeTotal(0);
  1091.                         }
  1092.                     }
  1093.                     $this->entityManager->persist($Order);
  1094.                     $this->entityManager->flush($Order);
  1095.                 }
  1096.                 $Shipping $Order->getShippings()[0];
  1097.                 $ShippingData = [
  1098.                     'id' => $Shipping->getId(),
  1099.                     'name01' => $Shipping->getName01(),
  1100.                     'name02' => $Shipping->getName02(),
  1101.                     'kana01' => $Shipping->getKana01(),
  1102.                     'kana02' => $Shipping->getKana02(),
  1103.                     'postal_code' => $Shipping->getPostalCode(),
  1104.                     'pref' => $Shipping->getPref()->getName(),
  1105.                     'addr01' => $Shipping->getAddr01(),
  1106.                     'addr02' => $Shipping->getAddr02(),
  1107.                     'phone_number' => $Shipping->getPhoneNumber(),
  1108.                 ];
  1109.                 $regularDiscount $Order->getOrderItems()[0]->getProduct()->getProductClasses()[0]->getRegularDiscount();
  1110.                 $discountSecond = array();
  1111.                 if ($regularDiscount) {
  1112.                     $discountFirst $this->regularDiscountRepository->find($Order->getOrderItems()[0]->getProduct()->getProductClasses()[0]->getRegularDiscount()->getId());
  1113.                     $discountSecond $this->regularDiscountRepository->findDiscountById($discountFirst->getDiscountId());
  1114.                 }
  1115.                 $OrderData = [
  1116.                     'payment_total' => $Order->getPaymentTotal(),
  1117.                     'delivery_fee_total' => $Order->getDeliveryFeeTotal(),
  1118.                     'order_id' => $Order->getId(),
  1119.                     'discount' => $Order->getDiscount(),
  1120.                     'shipping' => $ShippingData,
  1121.                     'product_name' => $Order->getOrderItems()[0]->getProduct()->getName() ?? null,
  1122.                     'main_image' => $Order->getOrderItems()[0]->getProduct()->getMainFileName() ? $this->packages->getUrl($Order->getOrderItems()[0]->getProduct()->getMainListImage(),'save_image') : $this->packages->getUrl('no_image_product.png','save_image'),
  1123.                     'discount_rate' => $Order->getOrderItems()[0]->getProduct()->getProductClasses()[0]->getRegularDiscount() ? $Order->getOrderItems()[0]->getProduct()->getProductClasses()[0]->getRegularDiscount()->getDiscountRate() : 0,
  1124.                     'price' => $Order->getOrderItems()[0]->getProduct()->getPrice02IncTaxMax() ?? null,
  1125.                     'pt' => $this->get_point($Order->getPaymentTotal(), false) ?? null,
  1126.                     'pt_family_benefits' => $this->get_point($Order->getPaymentTotal(), true) ?? null,
  1127.                     'discount_second' => count($discountSecond) > $discountSecond[1]->getDiscountRate() : 0,
  1128.                     'sale_type' => $Order->getOrderItems()[0]->getProduct()->getProductClasses()[0]->getSaletype()->getName() == "定期商品",
  1129.                     'add_point' => number_format($Order->getAddPoint()),
  1130.                     'subtotal' => $Order->getSubtotal(),
  1131.                     'quantity' => $Order->getOrderItems()->first()->getQuantity(),
  1132.                 ];
  1133.                 $this->cartService->removeCart($oneTouchPaymentCart);
  1134.                 return $this->json([
  1135.                     'Order' => $OrderData,
  1136.                     'done' => true,
  1137.                 ]);
  1138.             } catch (\Exception $e) {
  1139.                 if ($oneTouchPaymentCart) {
  1140.                     $this->cartService->removeCart($oneTouchPaymentCart);
  1141.                 }
  1142.                 $this->entityManager->rollback();
  1143.                 $this->addError('front.shopping.system_error');
  1144.                 return $this->json(['done' => false'messages' => $messages]);;
  1145.             }
  1146.         } else {
  1147.             if ($oneTouchPaymentCart) {
  1148.                 $this->cartService->removeCart($oneTouchPaymentCart);
  1149.             }
  1150.             // エラーが発生している場合
  1151.             $done false;
  1152.             $messages $errorMessages;
  1153.             foreach ($messages as $message) {
  1154.                 $this->addError($message);
  1155.             }
  1156.         }
  1157.         return $this->json(['done' => $done'messages' => $messages]);
  1158.     }
  1159.     /**
  1160.      * カートに追加.
  1161.      *
  1162.      * @Route("/products/show_shipping/{id}", name="show_shipping", methods={"POST"}, requirements={"id" = "\d+"})
  1163.      * @Template("Product/detail.twig")
  1164.      */
  1165.     public function showListShipping(Request $requestShipping $Shipping)
  1166.     {
  1167.         $messages = [];
  1168.         $Customer $this->getUser();
  1169.         try {
  1170.             /** @var Customer $Customer */
  1171.             $CustomerAddress = new CustomerAddress();
  1172.             $CustomerAddress->setFromCustomer($Customer);
  1173.             $Addresses array_merge([$CustomerAddress], $Customer->getCustomerAddresses()->toArray());
  1174.             $ShippingDatas = [];
  1175.             foreach ($Addresses as $key => $address) {
  1176.                 $default '';
  1177.                 if ($key == 0) {
  1178.                     $default 'checked';
  1179.                 }
  1180.                 $ShippingDatas[] = [
  1181.                     'id' => $address->getId(),
  1182.                     'name01' => $address->getName01(),
  1183.                     'name02' => $address->getName02(),
  1184.                     'kana01' => $address->getKana01(),
  1185.                     'kana02' => $address->getKana02(),
  1186.                     'postal_code' => $address->getPostalCode(),
  1187.                     'pref' => $address->getPref()->getName(),
  1188.                     'addr01' => $address->getAddr01(),
  1189.                     'addr02' => $address->getAddr02(),
  1190.                     'phone_number' => $address->getPhoneNumber(),
  1191.                     'default' => $default
  1192.                 ];
  1193.             }
  1194.             return $this->json(['done' => false'messages' => $messages,'Shippings' => $ShippingDatas] );
  1195.         } catch (\Exception $e) {
  1196.             $this->entityManager->rollback();
  1197.             $this->addError('front.shopping.system_error');
  1198.             return $this->json(['done' => false'messages' => $messages]);
  1199.         }
  1200.     }
  1201.     /**
  1202.      * カートに追加.
  1203.      *
  1204.      * @Route("/products/show_card/{id}", name="show_card", methods={"POST"}, requirements={"id" = "\d+"})
  1205.      * @Template("Product/detail.twig")
  1206.      */
  1207.     public function showListCard(Request $requestCustomer $Customer)
  1208.     {
  1209.         $messages = [];
  1210.         $dataCards = [];
  1211.         $Customer $this->getUser();
  1212.         $cards = new ArrayCollection();
  1213.         $defaultPayment null;
  1214.         $StripeCustomer=$this->stripeCustomerRepository->findOneBy(array('Customer'=>$Customer));
  1215.         try {
  1216.             if ($StripeCustomer) {
  1217.                 $StripeCustomerId $StripeCustomer->getStripeCustomerId();
  1218.                 $paymentMethod StripeLibCustomer::retrieve($StripeCustomerId);
  1219.                 if ($StripeCustomerId) {
  1220.                     $cards PaymentMethod::all([
  1221.                         'customer' => $StripeCustomerId,
  1222.                         'type' => 'card',
  1223.                     ]);
  1224.                     $cards = new ArrayCollection($cards->data);
  1225.                 };
  1226.                 if ($request->get('stripe_payment_method_id')) {
  1227.                     $defaultPayment $request->get('stripe_payment_method_id');
  1228.                 }
  1229.                 else{
  1230.                     if ($paymentMethod['invoice_settings']['default_payment_method']) {
  1231.                         $defaultPayment $paymentMethod['invoice_settings']['default_payment_method'];
  1232.                     }else{
  1233.                         $defaultPayment $cards[0]['id'];
  1234.                     }
  1235.                 }
  1236.             }
  1237.             foreach ($cards as $key => $card) {
  1238.                 $default "";
  1239.                 if ($defaultPayment == $card['id']) {
  1240.                     $default "checked";
  1241.                 }
  1242.                 $dataCards[] = [
  1243.                     'id' => $card['id'],
  1244.                     'brand' => $card['card']['brand'],
  1245.                     'exp_month' => $card['card']['exp_month'],
  1246.                     'exp_year' => $card['card']['exp_year'],
  1247.                     'last4' => $card['card']['last4'],
  1248.                     'default' => $default
  1249.                 ];
  1250.             }
  1251.             return $this->json(['done' => true'messages' => $messages,'Cards' => $dataCards] );
  1252.         } catch (\Exception $e) {
  1253.             $this->entityManager->rollback();
  1254.             $this->addError('front.shopping.system_error');
  1255.             return $this->json(['done' => false'messages' => $messages]);
  1256.         }
  1257.     }
  1258.     /**
  1259.      * カートに追加.
  1260.      *
  1261.      * @Route("/products/update_card/{id}", name="update_card", methods={"POST"}, requirements={"id" = "\d+"})
  1262.      * @Template("Product/detail.twig")
  1263.      */
  1264.     public function updateCard(Request $request)
  1265.     {
  1266.         $messages = [];
  1267.         $StripeCardId $request->get('radio_card');
  1268.         $paymentMethod PaymentMethod::retrieve($StripeCardId);
  1269.         $dataCard = [
  1270.             'id' => $paymentMethod['id'],
  1271.             'brand' => $paymentMethod['card']['brand'],
  1272.             'exp_month' => $paymentMethod['card']['exp_month'],
  1273.             'exp_year' => $paymentMethod['card']['exp_year'],
  1274.             'last4' => $paymentMethod['card']['last4'],
  1275.         ];
  1276.         return $this->json(['done' => true'messages' => $messages,'Card' => $dataCard] );
  1277.     }
  1278.     /**
  1279.      * カートに追加.
  1280.      *
  1281.      * @Route("/products/create_card_onetouch/{id}", name="create_card_onetouch", methods={"POST"}, requirements={"id" = "\d+"})
  1282.      * @Template("Product/detail.twig")
  1283.      */
  1284.     public function createCardOnetouch(Request $requestCustomer $Customer)
  1285.     {
  1286.         $messages = [];
  1287.         $StripeCustomer $this->stripeCustomerRepository->findOneBy(array('Customer' => $Customer));
  1288.         $cards = new ArrayCollection();
  1289.         if ($StripeCustomer) {
  1290.             $StripeCustomerId $StripeCustomer->getStripeCustomerId();
  1291.             if ($StripeCustomerId) {
  1292.                 $cards PaymentMethod::all([
  1293.                     'customer' => $StripeCustomerId,
  1294.                     'type' => 'card',
  1295.                 ]);
  1296.                 $cards = new ArrayCollection($cards->data);
  1297.             };
  1298.         }else{
  1299.             $customer_id $Customer['id'];
  1300.             $customer_email $Customer['email'];
  1301.             $data = [
  1302.                 'email'=> $customer_email,
  1303.                 'metadata'=> array('customer_id' => $customer_id),
  1304.             ];
  1305.             $StripeCustomerApi StripeLibCustomer::create($data);
  1306.             $StripeCustomer = new StripeCustomer();
  1307.             $StripeCustomer->setCustomer($Customer);
  1308.             $StripeCustomer->setStripeCustomerId($StripeCustomerApi['id']);
  1309.             $StripeCustomer->setIsSaveCardOn(0);
  1310.             $StripeCustomer->setCreatedAt(new \DateTime());
  1311.             $this->entityManager->persist($StripeCustomer);
  1312.             $this->entityManager->flush($StripeCustomer);
  1313.             $StripeCustomerId $StripeCustomer->getStripeCustomerId();
  1314.             if ($StripeCustomerId) {
  1315.                 $cards PaymentMethod::all([
  1316.                     'customer' => $StripeCustomerId,
  1317.                     'type' => 'card',
  1318.                 ]);
  1319.                 $cards = new ArrayCollection($cards->data);
  1320.             };
  1321.         }
  1322.         $fingerprints = [];
  1323.         foreach ($cards as $card) {
  1324.             $fingerprints[] = $card['card']['fingerprint'];
  1325.         }
  1326.         try {
  1327.             $payment_method PaymentMethod::retrieve($request->get("stripe_payment_method_id"));
  1328.             if (in_array($payment_method['card']['fingerprint'], $fingerprints)) {
  1329.                 return $this->redirectToRoute('mypage_card');
  1330.             }
  1331.             $payment_method->attach([
  1332.                 'customer' => $StripeCustomerId
  1333.             ]);
  1334.             $dataCard = [
  1335.                 'id' => $payment_method['id'],
  1336.                 'brand' => $payment_method['card']['brand'],
  1337.                 'exp_month' => $payment_method['card']['exp_month'],
  1338.                 'exp_year' => $payment_method['card']['exp_year'],
  1339.                 'last4' => $payment_method['card']['last4'],
  1340.             ];
  1341.             return $this->json(['done' => true'messages' => $messages,'Card' => $dataCard,'StripeCustomerId' => $StripeCustomerId] );
  1342.         } catch (Exception $e) {
  1343.             return $this->redirectToRoute('mypage_card_new');
  1344.         }
  1345.     }
  1346.     /**
  1347.      * カートに追加.
  1348.      *
  1349.      * @Route("/products/update_shipping/{id}", name="update_shipping", methods={"POST"}, requirements={"id" = "\d+"})
  1350.      * @Template("Product/detail.twig")
  1351.      */
  1352.     public function updateShipping(Request $requestShipping $Shipping)
  1353.     {
  1354.         $messages = [];
  1355.         $Customer $this->getUser();
  1356.         $customerId $Customer->getId();
  1357.         $preOrderId $Shipping->getOrder()->getPreOrderId();
  1358.         $Order $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
  1359.         $idAddress $request->get('radio_address');
  1360.         try {
  1361.             if ($idAddress != 0) {
  1362.                 /** @var CustomerAddress $CustomerAddress */
  1363.                 $CustomerAddress $this->customerAddressRepository->find($idAddress);
  1364.                 $Shipping->setFromCustomerAddress($CustomerAddress);
  1365.             }
  1366.             else{
  1367.                 $CustomerAddress = new CustomerAddress();
  1368.                 $CustomerAddress->setFromCustomer($Customer);
  1369.                 $Shipping->setFromCustomerAddress($CustomerAddress);
  1370.             }
  1371.             // 合計金額の再計算
  1372.             $response $this->executePurchaseFlow($Order);
  1373.             $this->entityManager->flush();
  1374.             $Shipping $Order->getShippings()[0];
  1375.             $ShippingData = [
  1376.                 'id' => $Shipping->getId(),
  1377.                 'name01' => $Shipping->getName01(),
  1378.                 'name02' => $Shipping->getName02(),
  1379.                 'kana01' => $Shipping->getKana01(),
  1380.                 'kana02' => $Shipping->getKana02(),
  1381.                 'postal_code' => $Shipping->getPostalCode(),
  1382.                 'pref' => $Shipping->getPref()->getName(),
  1383.                 'addr01' => $Shipping->getAddr01(),
  1384.                 'addr02' => $Shipping->getAddr02(),
  1385.                 'phone_number' => $Shipping->getPhoneNumber(),
  1386.                 'default_id' => $CustomerAddress->getId(),
  1387.             ];
  1388.             $OrderData = [
  1389.                 'payment_total' => $Order->getPaymentTotal(),
  1390.                 'delivery_fee_total' => $Order->getDeliveryFeeTotal(),
  1391.                 'order_id' => $Order->getId(),
  1392.                 'discount' => $Order['discount'],
  1393.                 'shipping' => $ShippingData
  1394.             ];
  1395.             return $this->json([
  1396.                 'Order' => $OrderData,
  1397.                 'done' => true,
  1398.             ]);
  1399.         } catch (\Exception $e) {
  1400.             $this->entityManager->rollback();
  1401.             $this->addError('front.shopping.system_error');
  1402.             return $this->json(['done' => false'messages' => $messages]);;
  1403.         }
  1404.     }
  1405.     /**
  1406.      * カートに追加.
  1407.      *
  1408.      * @Route("/products/create_shipping/{id}", name="create_shipping", methods={"POST"}, requirements={"id" = "\d+"})
  1409.      * @Template("Product/detail.twig")
  1410.      */
  1411.     public function createShipping(Request $requestShipping $Shipping)
  1412.     {
  1413.         $messages = [];
  1414.         $CustomerAddress = new CustomerAddress();
  1415.         $CustomerAddress->setCustomer($this->getUser());
  1416.         $builder $this->formFactory->createBuilder(CustomerAddressType::class, $CustomerAddress);
  1417.         $form $builder->getForm();
  1418.         $form->handleRequest($request);
  1419.         try {
  1420.             $this->entityManager->persist($CustomerAddress);
  1421.             $this->entityManager->flush();
  1422.             $preOrderId $Shipping->getOrder()->getPreOrderId();
  1423.             $Order $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
  1424.             $Shipping->setFromCustomerAddress($CustomerAddress);
  1425.             $response $this->executePurchaseFlow($Order);
  1426.             $this->entityManager->flush();
  1427.             $Shipping $Order->getShippings()[0];
  1428.             $ShippingData = [
  1429.                 'id' => $Shipping->getId(),
  1430.                 'name01' => $Shipping->getName01(),
  1431.                 'name02' => $Shipping->getName02(),
  1432.                 'kana01' => $Shipping->getKana01(),
  1433.                 'kana02' => $Shipping->getKana02(),
  1434.                 'postal_code' => $Shipping->getPostalCode(),
  1435.                 'pref' => $Shipping->getPref()->getName(),
  1436.                 'addr01' => $Shipping->getAddr01(),
  1437.                 'addr02' => $Shipping->getAddr02(),
  1438.                 'phone_number' => $Shipping->getPhoneNumber(),
  1439.                 'default_id' => $CustomerAddress->getId(),
  1440.             ];
  1441.             $OrderData = [
  1442.                 'payment_total' => $Order->getPaymentTotal(),
  1443.                 'delivery_fee_total' => $Order->getDeliveryFeeTotal(),
  1444.                 'order_id' => $Order->getId(),
  1445.                 'discount' => $Order['discount'],
  1446.                 'shipping' => $ShippingData
  1447.             ];
  1448.             return $this->json([
  1449.                 'Order' => $OrderData,
  1450.                 'done' => true,
  1451.             ]);
  1452.         } catch (\Exception $e) {
  1453.             $this->entityManager->rollback();
  1454.             $this->addError('front.shopping.system_error');
  1455.             return $this->json(['done' => false'messages' => $messages]);;
  1456.         }
  1457.     }
  1458.     /**
  1459.      * @param ItemHolderInterface $itemHolder
  1460.      * @param bool $returnResponse レスポンスを返すかどうか. falseの場合はPurchaseFlowResultを返す.
  1461.      *
  1462.      * @return PurchaseFlowResult|\Symfony\Component\HttpFoundation\RedirectResponse
  1463.      */
  1464.     protected function executePurchaseFlow(ItemHolderInterface $itemHolder$returnResponse true)
  1465.     {
  1466.         /** @var PurchaseFlowResult $flowResult */
  1467.         $flowResult $this->shoppingPurchaseFlow->validate($itemHolder, new PurchaseContext(clone $itemHolder$itemHolder->getCustomer()));
  1468.         foreach ($flowResult->getWarning() as $warning) {
  1469.             $this->addWarning($warning->getMessage());
  1470.         }
  1471.         foreach ($flowResult->getErrors() as $error) {
  1472.             $this->addError($error->getMessage());
  1473.         }
  1474.         if (!$returnResponse) {
  1475.             return $flowResult;
  1476.         }
  1477.         if ($flowResult->hasError()) {
  1478.             log_info('Errorが発生したため購入エラー画面へ遷移します.', [$flowResult->getErrors()]);
  1479.             return $flowResult;
  1480.         }
  1481.         if ($flowResult->hasWarning()) {
  1482.             log_info('Warningが発生したため注文手続き画面へ遷移します.', [$flowResult->getWarning()]);
  1483.             return $flowResult;
  1484.         }
  1485.     }
  1486.     private function get_point($price$prime=false){
  1487.         if($prime){
  1488.             return number_format($price 100);
  1489.         }else{
  1490.             $pointRate 1;
  1491.             if ($this->getUser()) {
  1492.                 $pointRate $this->getUser()->getOwnerRank() + 1;
  1493.             }
  1494.             return number_format($price $pointRate 100);
  1495.         }
  1496.     }
  1497.      /**
  1498.      * 商品一覧画面.
  1499.      * 
  1500.      * @Route("/products/promotion_code", name="promotion_code", methods={"POST"})
  1501.      */
  1502.     public function applyPromotionCode(Request $request)
  1503.     {
  1504.         $Order $this->orderRepository->find($request->get('order_id'));
  1505.         $CouponOrder $this->couponOrderRepository->getCouponOrder($Order->getPreOrderId());
  1506.         $couponCd null;
  1507.         if ($CouponOrder) {
  1508.             $couponCd $CouponOrder->getCouponCd();
  1509.         }
  1510.         $form_c $this->formFactory->createBuilder(CouponUseType::class)->getForm();
  1511.         $service $this->couponService;
  1512.         $formCouponCd $request->get('coupon_cd');
  1513.         $formCouponCancel $request->get('coupon_use');
  1514.         if ($formCouponCancel == 0) {
  1515.             if (!is_null($formCouponCd)) {
  1516.                 $this->couponService->removeCouponOrder($Order);
  1517.                 $Order->setPaymentTotal($Order->getPaymentTotal() + $Order->getDiscount());
  1518.                 $Order->setTotal($Order->getTotal() + $Order->getDiscount());
  1519.                 $Order->setDiscount(0);
  1520.                 $this->entityManager->persist($Order);
  1521.                 $this->entityManager->flush();
  1522.             }
  1523.             return $this->redirectToRoute('shopping');
  1524.         } else {
  1525.             $error false;
  1526.             $Coupon $this->couponRepository->findActiveCoupon($formCouponCd);
  1527.             if (!$Coupon) {
  1528.                 $form_c->get('coupon_cd')->addError(new FormError(trans('plugin_coupon.front.shopping.notexists')));
  1529.                 $error true;
  1530.                 return $this->json([
  1531.                     'success'=> false,
  1532.                 ]);
  1533.             }
  1534.             $Customer $this->getUser();
  1535.             if (!$error && $Coupon) {
  1536.                 $couponProducts $service->existsCouponProduct($Coupon$Order);
  1537.                 $discount $service->recalcOrder($Coupon$couponProducts);
  1538.                 $service->saveCouponOrder($Order$Coupon$formCouponCd$Customer$discount);
  1539.                 if ($discount) {
  1540.                     $Order->setDiscount($discount);
  1541.                     $Order->setPaymentTotal($Order->getPaymentTotal() - $discount);
  1542.                     $Order->setTotal($Order->getTotal() - $discount);
  1543.                     $this->entityManager->persist($Order);
  1544.                     $this->entityManager->flush();
  1545.                 }
  1546.                 return $this->json([
  1547.                     'success'=> true,
  1548.                     'discount' => $discount,
  1549.                     'total' => $Order->getTotal()
  1550.                 ]);
  1551.             }
  1552.         }
  1553.     }
  1554.     private function handlerSupplierProduct($Product)
  1555.     {
  1556.         $categorySupplier $this->productRepository->getSupplierCategories();
  1557.         $is_supplier false;
  1558.         foreach ($Product->getProductCategories() as $category) {
  1559.             if (in_array($category->getCategoryId(), $categorySupplier)) {
  1560.                 $is_supplier true;
  1561.             }
  1562.         }
  1563.         return $is_supplier;
  1564.     }
  1565.      /**
  1566.      * 商品一覧画面.
  1567.      * 
  1568.      * @Route("/products/last_customer/{id}", name="last_customer_order", methods={"GET"}, requirements={"id" = "\d+"})
  1569.      */
  1570.     public function getLastCustomerOrder($id)
  1571.     {
  1572.         $lastOrderCustomers $this->productRepository->getCustomerLastOrder($id);  
  1573.         $Mails = [];
  1574.         if ($lastOrderCustomers) {
  1575.             foreach($lastOrderCustomers as $customer) {
  1576.                 $Mails[] = $customer->getEmail();
  1577.             }
  1578.         }
  1579.         return $this->json([
  1580.             'emails' => $Mails
  1581.         ]);
  1582.     }
  1583.     function getPointCart($Cart$Customer){ 
  1584.         $prime $Customer['prime_member'];
  1585.             $urank $Customer['owner_rank'];
  1586.             $alpha 0;
  1587.             if($prime){
  1588.                 $alpha 3;
  1589.             }
  1590.             if($urank == 0){
  1591.                 $alpha $alpha 1;
  1592.             }elseif($urank == 1){
  1593.                 $alpha $alpha 2;
  1594.             }elseif($urank == 2){
  1595.                 $alpha $alpha 3;
  1596.             }elseif($urank == 3){
  1597.                 $alpha $alpha 4;
  1598.             }
  1599.             return number_formatround(strval($Cart->getTotalPrice() * $alpha 100)));
  1600.     }
  1601.     /**
  1602.      * カートに追加.
  1603.      *
  1604.      * @Route("/products/add_cart_by_email/{id}", name="product_add_cart_by_email", methods={"POST","GET"}, requirements={"id" = "\d+"})
  1605.      */
  1606.     public function addCartByEmail(Request $requestProduct $Product)
  1607.     {
  1608.         // エラーメッセージの配列
  1609.         $errorMessages = [];
  1610.         if (!$this->checkVisibility($Product)) {
  1611.             throw new NotFoundHttpException();
  1612.         }
  1613.         $builder $this->formFactory->createNamedBuilder(
  1614.             '',
  1615.             AddCartByEmailType::class,
  1616.             null,
  1617.             [
  1618.                 'product' => $Product,
  1619.                 'id_add_product_id' => false,
  1620.             ]
  1621.         );
  1622.         $event = new EventArgs(
  1623.             [
  1624.                 'builder' => $builder,
  1625.                 'Product' => $Product,
  1626.             ],
  1627.             $request
  1628.         );
  1629.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE$event);
  1630.         /* @var $form \Symfony\Component\Form\FormInterface */
  1631.         $form $builder->getForm();
  1632.         $form->handleRequest($request);
  1633.         if (!$form->isValid()) {
  1634.             foreach ($form->all() as $child) {
  1635.                 $config $child->getConfig();
  1636.                 foreach ($child->getErrors() as $error) {
  1637.                     $errorMessages[] = $config->getOption('label') . ':' $error->getMessage();
  1638.                 }
  1639.             }
  1640.         }
  1641.         $recipientEmail $form->get('email')->getData();
  1642.         if ($recipientEmail) {
  1643.             $customer $this->customerRepository->findBy(array('email' => $recipientEmail));
  1644.             if (count($customer) > 0) {
  1645.                 $customer $customer[0];
  1646.             } else {
  1647.                 $customer null;
  1648.                 $errorMessages[] = '存在しないメールアドレスです。';
  1649.             }
  1650.         }
  1651.         $addCartData $form->getData();
  1652.         $ProductClass $this->entityManager->getRepository(ProductClass::class)->find($addCartData['product_class_id']);
  1653.         $limit $ProductClass->getSaleLimit();
  1654.         if (!$ProductClass->isStockUnlimited()) {
  1655.             $stock $ProductClass->getStock();
  1656.         }
  1657.         if (!is_null($limit) || isset($stock)) {
  1658.             $Carts $this->cartService->getCarts();
  1659.             $quantity $addCartData['quantity'];
  1660.             foreach ($Carts as $Cart) {
  1661.                 foreach ($Cart->getCartItems() as $item) {
  1662.                     if ($item->getProductClass()->getId() == $ProductClass->getId()) $quantity += $item->getQuantity();
  1663.                 }
  1664.             }
  1665.             $productName $ProductClass->getProduct()->getName();
  1666.             if ($ProductClass->hasClassCategory1()) {
  1667.                 $productName .= ' - ' $ProductClass->getClassCategory1()->getName();
  1668.             }
  1669.             if ($ProductClass->hasClassCategory2()) {
  1670.                 $productName .= ' - ' $ProductClass->getClassCategory2()->getName();
  1671.             }
  1672.             if (!is_null($limit) && $limit $quantity) {
  1673.                 $errorMessages[] = trans('front.shopping.over_sale_limit', ['%product%' => $productName]);
  1674.             }
  1675.             if (isset($stock) && $stock $quantity) {
  1676.                 $errorMessages[] = trans('front.shopping.out_of_stock', ['%product%' => $productName]);
  1677.             }
  1678.         }
  1679.         if (count($errorMessages) == 0) {
  1680.             log_info(
  1681.                 'カート追加処理開始',
  1682.                 [
  1683.                     'product_id' => $Product->getId(),
  1684.                     'product_class_id' => $addCartData['product_class_id'],
  1685.                     'quantity' => $addCartData['quantity'],
  1686.                 ]
  1687.             );
  1688.             // カートへ追加
  1689.             $ProductOptions $Product->getProductOptions();
  1690.             $Options = [];
  1691.             foreach ($ProductOptions as $ProductOption) {
  1692.                 $Option $ProductOption->getOption();
  1693.                 $option_key 'productoption' $Option->getId();
  1694.                 $value $form->get($option_key)->getData();
  1695.                 if ($Option) {
  1696.                     $add true;
  1697.                     if ($Option->getType() == Option::SELECT_TYPE || $Option->getType() == Option::RADIO_TYPE) {
  1698.                         if ($Option->getDisableCategory()) {
  1699.                             if ($Option->getDisableCategory() == $value) {
  1700.                                 $add false;
  1701.                             }
  1702.                         }
  1703.                         $value $value->getId();
  1704.                         if (strlen($value) == 0$add false;
  1705.                     } elseif ($Option->getType() == Option::TEXT_TYPE || $Option->getType() == Option::TEXTAREA_TYPE || $Option->getType() == Option::NUMBER_TYPE) {
  1706.                         if (strlen($value) == 0$add false;
  1707.                     } elseif ($Option->getType() == Option::CHECKBOX_TYPE) {
  1708.                         if (count($value) == 0) {
  1709.                             $add false;
  1710.                         } else {
  1711.                             $buff $value;
  1712.                             $value = [];
  1713.                             foreach ($buff as $categoryoption) {
  1714.                                 $value[] = $categoryoption->getId();
  1715.                             }
  1716.                         }
  1717.                     } elseif ($Option->getType() == Option::DATE_TYPE) {
  1718.                         if (is_null($value)) $add false;
  1719.                     }
  1720.                     if ($add) {
  1721.                         if (is_array($value)) {
  1722.                             $Options[$Option->getId()] = $value;
  1723.                         } elseif (is_object($value)) {
  1724.                             $Options[$Option->getId()] = $value->format('Y-m-d');
  1725.                         } else {
  1726.                             $Options[$Option->getId()] = (string)$value;
  1727.                         }
  1728.                     }
  1729.                 }
  1730.             }
  1731.             $this->cartService->addProductOption($addCartData['product_class_id'], $Options$addCartData['quantity']);
  1732.             // 明細の正規化
  1733.             $Carts $this->cartService->getCarts();
  1734.             foreach ($Carts as $Cart) {
  1735.                 $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$customer));
  1736.                 // 復旧不可のエラーが発生した場合は追加した明細を削除.
  1737.                 if ($result->hasError()) {
  1738.                     $this->cartService->removeProduct($addCartData['product_class_id']);
  1739.                     foreach ($result->getErrors() as $error) {
  1740.                         $errorMessages[] = $error->getMessage();
  1741.                     }
  1742.                 }
  1743.                 foreach ($result->getWarning() as $warning) {
  1744.                     $errorMessages[] = $warning->getMessage();
  1745.                 }
  1746.             }
  1747.             $this->cartService->save();
  1748.             log_info(
  1749.                 'カート追加処理完了',
  1750.                 [
  1751.                     'product_id' => $Product->getId(),
  1752.                     'product_class_id' => $addCartData['product_class_id'],
  1753.                     'quantity' => $addCartData['quantity'],
  1754.                 ]
  1755.             );
  1756.             $event = new EventArgs(
  1757.                 [
  1758.                     'form' => $form,
  1759.                     'Product' => $Product,
  1760.                 ],
  1761.                 $request
  1762.             );
  1763.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE$event);
  1764.         }
  1765.         if ($event->getResponse() !== null) {
  1766.             return $event->getResponse();
  1767.         }
  1768.         $done null;
  1769.         $messages = [];
  1770.         if (empty($errorMessages)) {
  1771.             // エラーが発生していない場合
  1772.             $done true;
  1773.             array_push($messagestrans('front.product.add_cart_complete'));
  1774.         } else {
  1775.             // エラーが発生している場合
  1776.             $done false;
  1777.             $messages $errorMessages;
  1778.         }
  1779.         return $this->json(['done' => $done'messages' => $messages'product_class_id' => $ProductClass->getId()]);
  1780.     }
  1781.     /**
  1782.      * @Route("/update_last_seen_product", name="update_last_seen_product", methods={"POST"})
  1783.      */
  1784.     public function updateLastSeenProduct(Request $request)
  1785.     {
  1786.         try {
  1787.             $productId = (int) $request->request->get('productId');
  1788.             $arr $this->session->get('plugin.check_product.product');
  1789.             $arr[] = $productId;
  1790.             $arr array_unique($arr);
  1791.             $max $this->eccubeConfig['PLG_CHECK_PRODUCT_MAX'];
  1792.             $arr array_slice($arr, (- $max), $max);
  1793.             $this->session->set('plugin.check_product.product'$arr);
  1794.             return $this->json([
  1795.                 'done' => true,
  1796.                 'child_product_id' => $arr
  1797.             ]);
  1798.         } catch (\Throwable $th) {
  1799.             throw $th;
  1800.         }
  1801.     }
  1802. }