src/Eccube/Controller/ProductController.php line 528

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.                 $product[] = [
  436.                     'id' => $Product->getId(),
  437.                     'name' => $Product->getName(),
  438.                     'product_class' => $Product->getProductClasses()[0]->getId(),
  439.                     'price_discount' => $price ?? 0,
  440.                     'price' => $reg_price,
  441.                     'discount_rate' => $Product->getProductClasses()[0]->getRegularDiscount() ? $Product->getProductClasses()[0]->getRegularDiscount()->getDiscountRate() : 0,
  442.                     'image' => $Product->getMainListImage() ? $Product->getMainListImage()->getFileName() : null,
  443.                     'star' => round($rate['RecommendAvg'], 1),
  444.                     'reviewCount' => intval($rate['ReviewCntList']),
  445.                     'tagName' => $tagName,
  446.                 ];
  447.             }
  448.         }
  449.         return $this->json($product);
  450.     }
  451.     /**
  452.      * 商品詳細画面.
  453.      * @Route("/products/detail/{id}", name="product_detail_old", methods={"GET"})
  454.      * @Route("/products/{id}/{slug}", name="product_detail", methods={"GET"})
  455.      * @Template("Product/detail.twig")
  456.      * @ParamConverter("Product", options={"repository_method" = "findWithSortedClassCategories"})
  457.      *
  458.      * @param Request $request
  459.      * @param Product $Product
  460.      *
  461.      * @return array
  462.      */
  463.     public function detail(Request $requestProduct $Product,$slug null)
  464.     {
  465.         $ChangeCustomer $this->session->get('PRODUCT_DETAIL_REGULAR') ?? $this->session->get('PRODUCT_DETAIL') ?? 0;
  466.         if ($request->attributes->get('_route') === 'product_detail_old') {
  467.             $slug $Product->getSlug();
  468.             return $this->redirectToRoute('product_detail', ['id' => $Product->getId(), 'slug' => $slug]);
  469.         }
  470.         if(!$Product->getIsVariant() && $slug !== $Product->getSlug()) {
  471.             return $this->redirectToRoute('product_detail', ['id' => $Product->getId(), 'slug' => $Product->getSlug()]);
  472.         }
  473.         $Customer null;
  474.         $LastOrder = [];
  475.         if ($this->isGranted('ROLE_USER')) {
  476.             $Customer $this->getUser();
  477.             $is_favorite $this->customerFavoriteProductRepository->isFavorite($Customer$Product);
  478.          
  479.             $LastOrder $this->productRepository->getCountProductOrder($Product->getId(),$Customer->getId());
  480.         }
  481.         $ProductVariant $this->productRepository->findVariantsByProductId($Product->getId());        
  482.         
  483.         if ($ProductVariant) {
  484.             $url '/products/'.$ProductVariant->getId().'?s='.$Product->getId().'/'.$Product->getSlug();
  485.             return $this->redirect($url);
  486.         }
  487.         if ((!$this->getUser() && !$this->session->get("IS_SUPPLIER")) || ($this->getUser() && !$this->getUser()->getIsSupplier())) {
  488.             if ($this->handlerSupplierProduct($Product)) {
  489.                 return $this->redirectToRoute('salon-suppliers');
  490.             }
  491.         }
  492.         if (!$this->checkVisibility($Product)) {
  493.             throw new NotFoundHttpException();
  494.         }
  495.         if ($this->session->get('PRODUCT_DETAIL')) {
  496.             $this->session->remove('PRODUCT_DETAIL');
  497.         }
  498.         $builder $this->formFactory->createNamedBuilder(
  499.             '',
  500.             AddCartType::class,
  501.             null,
  502.             [
  503.                 'product' => $Product,
  504.                 'id_add_product_id' => false,
  505.             ]
  506.         );
  507.         $event = new EventArgs(
  508.             [
  509.                 'builder' => $builder,
  510.                 'Product' => $Product,
  511.             ],
  512.             $request
  513.         );
  514.         $Customer null;
  515.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_DETAIL_INITIALIZE$event);
  516.         $is_favorite false;
  517.         if ($this->isGranted('ROLE_USER')) {
  518.             $Customer $this->getUser();
  519.             $is_favorite $this->customerFavoriteProductRepository->isFavorite($Customer$Product);
  520.         }
  521.         //お気に入り数の合計を取得 20211127 kikuzawa
  522.         $favorite_total 0;
  523.         $favorite_total $this->customerFavoriteProductRepository->getFavoriteTotal($Product);
  524.         $user_id "";
  525.         $Customer $this->getUser();
  526.         $Customer null;
  527.         
  528.         $productRegularDiscounts null;
  529.         if ($Product) {
  530.             $productRegular $Product->getRegularProduct();
  531.             if ($productRegular){
  532.                 $productRegularDiscount $productRegular->getProductClasses()[0]->getRegularDiscount();
  533.                 if ($productRegularDiscount) {
  534.                     $productRegularDiscounts $this->regularDiscountRepository->findBy([
  535.                         'discount_id' => $productRegularDiscount->getDiscountId()
  536.                     ]);
  537.                     
  538.                 }
  539.             }
  540.         }
  541.         $saleType null;
  542.         if ($this->isGranted('ROLE_USER')) {
  543.             $Customer $this->getUser();
  544.             $StripeCustomerData $this->OnetouchService->getCustomerStripeOnetouch($Customer$Product);
  545.             $productRegularDiscounts $StripeCustomerData['productRegularDiscounts'] ?? null;
  546.             $saleType $Product['ProductClasses'][0]->getSaleType()->getId();
  547.         }
  548.         $ship null;
  549.         $DeliveryFreeAmount $this->BaseInfo->getDeliveryFreeAmount();
  550.         //
  551.         if($Product->getOwnerProductId()){
  552.             // ダイヤモンド会員向けの商品ページは非表示、通常商品ページにリダイレクト
  553.             return $this->redirectToRoute('product_detail', ["id"=>$Product->getOwnerProductId()]);
  554.         }
  555.         $RankProduct null;
  556.         if($Product->getRankPrice()){
  557.             // ダイヤモンド会員向けの商品情報の取得
  558.             $RankProduct $this->productRepository->findOneBy(["owner_product_id"=>$Product->getId()]);
  559.         }
  560.         $s $request->get('s');
  561.         if ($s) {
  562.             $VariantChild explode('/'$s)[0];
  563.         }
  564.         $defaultSelect $VariantChild ?? 0;
  565.         $this->session->remove('PRODUCT_DETAIL');
  566.         $this->session->remove('PRODUCT_DETAIL_REGULAR');
  567.         $Product->setPageViews($Product->getPageViews() + 1);
  568.         $this->entityManager->persist($Product);
  569.         $this->entityManager->flush();
  570.         $faqs $this->productRepository->parseFAQs($Product->getLlmoFaq());
  571.         return [
  572.             'title' => $this->title,
  573.             'subtitle' => $Product->getName(),
  574.             'form' => $builder->getForm()->createView(),
  575.             'Product' => $Product,
  576.             'is_favorite' => $is_favorite,
  577.             'favorite_total' => $favorite_total//お気に入り数の合計を取得 20211127 kikuzawa
  578.             'user_id' => $user_id,
  579.             'Customer' => $Customer,
  580.             'RankProduct' => $RankProduct,
  581.             'productRegularDiscounts' => $productRegularDiscounts,
  582.             'LastOrder' =>$LastOrder,
  583.             'IsLightVersion' => $this->BaseInfo->getIsLightVersion(),
  584.             "defaultSelect"=> $defaultSelect,
  585.             'Sale_type' => $saleType,
  586.             'ChangeCustomer' => $ChangeCustomer,
  587.             'faqs' => $faqs,
  588.         ];
  589.     }
  590.     /**
  591.      * お気に入り追加.
  592.      *
  593.      * @Route("/products/add_favorite/{id}", name="product_add_favorite", requirements={"id" = "\d+"})
  594.      */
  595.     public function addFavorite(Request $requestProduct $Product)
  596.     {
  597.         $this->checkVisibility($Product);
  598.         $event = new EventArgs(
  599.             [
  600.                 'Product' => $Product,
  601.             ],
  602.             $request
  603.         );
  604.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_INITIALIZE$event);
  605.         if ($this->isGranted('ROLE_USER')) {
  606.             $Customer $this->getUser();
  607.             $this->customerFavoriteProductRepository->addFavorite($Customer$Product);
  608.             $this->session->getFlashBag()->set('product_detail.just_added_favorite'$Product->getId());
  609.             $event = new EventArgs(
  610.                 [
  611.                     'Product' => $Product,
  612.                 ],
  613.                 $request
  614.             );
  615.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE$event);
  616.             
  617.             if ($request->get("supplier_page")) {
  618.                 return $this->json(['status' => 'success''message' => '商品はお気に入りに保存されました']);
  619.             }
  620.             return $this->redirectToRoute('product_detail', ['id' => $Product->getId()]);
  621.         } else {
  622.             // 非会員の場合、ログイン画面を表示
  623.             //  ログイン後の画面遷移先を設定
  624.             $this->setLoginTargetPath($this->generateUrl('product_add_favorite', ['id' => $Product->getId()]));
  625.             $this->session->getFlashBag()->set('eccube.add.favorite'true);
  626.             $event = new EventArgs(
  627.                 [
  628.                     'Product' => $Product,
  629.                 ],
  630.                 $request
  631.             );
  632.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE$event);
  633.             return $this->redirectToRoute('mypage_login');
  634.         }
  635.     }
  636.     /**
  637.      * カートに追加.
  638.      *
  639.      * @Route("/products/add_cart/{id}", name="product_add_cart", methods={"POST","GET"}, requirements={"id" = "\d+"})
  640.      */
  641.     //app/Plugin/ProductOption/Controller/AddcartController.phpの内容を移植 20220829 kikuzawa
  642.     public function addCart(Request $requestProduct $Product)
  643.     {
  644.         // エラーメッセージの配列
  645.         $errorMessages = [];
  646.         if (!$this->checkVisibility($Product)) {
  647.             throw new NotFoundHttpException();
  648.         }
  649.         $builder $this->formFactory->createNamedBuilder(
  650.             '',
  651.             AddCartType::class,
  652.             null,
  653.             [
  654.                 'product' => $Product,
  655.                 'id_add_product_id' => false,
  656.             ]
  657.         );
  658.         $event = new EventArgs(
  659.             [
  660.                 'builder' => $builder,
  661.                 'Product' => $Product,
  662.             ],
  663.             $request
  664.         );
  665.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE$event);
  666.         /* @var $form \Symfony\Component\Form\FormInterface */
  667.         $form $builder->getForm();
  668.         $form->handleRequest($request);
  669.         //送り先のメールアドレス(option1)が会員情報に存在するかチェック 20220812 kikuzawa
  670.         if (isset($form->all()['productoption1'])) {
  671.             $recipientEmail $form->get('productoption1')->getData();
  672.             if ($recipientEmail) {
  673.                 $customer $this->customerRepository->findBy(array('email' => $recipientEmail));
  674.                 if (!$customer) {
  675.                     $errorMessages[] = '存在しないメールアドレスです。';
  676.                 }
  677.             }
  678.         }
  679.         if (!$form->isValid()) {
  680.             foreach ($form->all() as $child) {
  681.                 $config $child->getConfig();
  682.                 foreach ($child->getErrors() as $error) {
  683.                     $errorMessages[] = $config->getOption('label') . ':' $error->getMessage();
  684.                 }
  685.             }
  686.         }
  687.         $addCartData $form->getData();
  688.         $ProductClass $this->entityManager->getRepository(ProductClass::class)->find($addCartData['product_class_id']);
  689.         $limit $ProductClass->getSaleLimit();
  690.         if (!$ProductClass->isStockUnlimited()) {
  691.             $stock $ProductClass->getStock();
  692.         }
  693.         if (!is_null($limit) || isset($stock)) {
  694.             $Carts $this->cartService->getCarts();
  695.             $quantity $addCartData['quantity'];
  696.             foreach ($Carts as $Cart) {
  697.                 foreach ($Cart->getCartItems() as $item) {
  698.                     if ($item->getProductClass()->getId() == $ProductClass->getId()) $quantity += $item->getQuantity();
  699.                 }
  700.             }
  701.             $productName $ProductClass->getProduct()->getName();
  702.             if ($ProductClass->hasClassCategory1()) {
  703.                 $productName .= ' - ' $ProductClass->getClassCategory1()->getName();
  704.             }
  705.             if ($ProductClass->hasClassCategory2()) {
  706.                 $productName .= ' - ' $ProductClass->getClassCategory2()->getName();
  707.             }
  708.             if (!is_null($limit) && $limit $quantity) {
  709.                 $errorMessages[] = trans('front.shopping.over_sale_limit', ['%product%' => $productName]);
  710.             }
  711.             if (isset($stock) && $stock $quantity) {
  712.                 $errorMessages[] = trans('front.shopping.out_of_stock', ['%product%' => $productName]);
  713.             }
  714.         }
  715.         if (count($errorMessages) == 0) {
  716.             log_info(
  717.                 'カート追加処理開始',
  718.                 [
  719.                     'product_id' => $Product->getId(),
  720.                     'product_class_id' => $addCartData['product_class_id'],
  721.                     'quantity' => $addCartData['quantity'],
  722.                 ]
  723.             );
  724.             // カートへ追加
  725.             $ProductOptions $Product->getProductOptions();
  726.             $Options = [];
  727.             foreach ($ProductOptions as $ProductOption) {
  728.                 $Option $ProductOption->getOption();
  729.                 $option_key 'productoption' $Option->getId();
  730.                 $value $form->get($option_key)->getData();
  731.                 if ($Option) {
  732.                     $add true;
  733.                     if ($Option->getType() == Option::SELECT_TYPE || $Option->getType() == Option::RADIO_TYPE) {
  734.                         if ($Option->getDisableCategory()) {
  735.                             if ($Option->getDisableCategory() == $value) {
  736.                                 $add false;
  737.                             }
  738.                         }
  739.                         $value $value->getId();
  740.                         if (strlen($value) == 0$add false;
  741.                     } elseif ($Option->getType() == Option::TEXT_TYPE || $Option->getType() == Option::TEXTAREA_TYPE || $Option->getType() == Option::NUMBER_TYPE) {
  742.                         if (strlen($value) == 0$add false;
  743.                     } elseif ($Option->getType() == Option::CHECKBOX_TYPE) {
  744.                         if (count($value) == 0) {
  745.                             $add false;
  746.                         } else {
  747.                             $buff $value;
  748.                             $value = [];
  749.                             foreach ($buff as $categoryoption) {
  750.                                 $value[] = $categoryoption->getId();
  751.                             }
  752.                         }
  753.                     } elseif ($Option->getType() == Option::DATE_TYPE) {
  754.                         if (is_null($value)) $add false;
  755.                     }
  756.                     if ($add) {
  757.                         if (is_array($value)) {
  758.                             $Options[$Option->getId()] = $value;
  759.                         } elseif (is_object($value)) {
  760.                             $Options[$Option->getId()] = $value->format('Y-m-d');
  761.                         } else {
  762.                             $Options[$Option->getId()] = (string)$value;
  763.                         }
  764.                     }
  765.                 }
  766.             }
  767.             $this->cartService->addProductOption($addCartData['product_class_id'], $Options$addCartData['quantity']);
  768.             // 明細の正規化
  769.             $Carts $this->cartService->getCarts();
  770.             foreach ($Carts as $Cart) {
  771.                 $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->getUser()));
  772.                 // 復旧不可のエラーが発生した場合は追加した明細を削除.
  773.                 if ($result->hasError()) {
  774.                     $this->cartService->removeProduct($addCartData['product_class_id']);
  775.                     foreach ($result->getErrors() as $error) {
  776.                         $errorMessages[] = $error->getMessage();
  777.                     }
  778.                 }
  779.                 foreach ($result->getWarning() as $warning) {
  780.                     $errorMessages[] = $warning->getMessage();
  781.                 }
  782.             }
  783.             $this->cartService->save();
  784.             log_info(
  785.                 'カート追加処理完了',
  786.                 [
  787.                     'product_id' => $Product->getId(),
  788.                     'product_class_id' => $addCartData['product_class_id'],
  789.                     'quantity' => $addCartData['quantity'],
  790.                 ]
  791.             );
  792.             $event = new EventArgs(
  793.                 [
  794.                     'form' => $form,
  795.                     'Product' => $Product,
  796.                 ],
  797.                 $request
  798.             );
  799.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE$event);
  800.         }
  801.         if ($event->getResponse() !== null) {
  802.             return $event->getResponse();
  803.         }
  804.         if ($request->isXmlHttpRequest()) {
  805.             // ajaxでのリクエストの場合は結果をjson形式で返す。
  806.             // 初期化
  807.             $done null;
  808.             $messages = [];
  809.             if (empty($errorMessages)) {
  810.                 // エラーが発生していない場合
  811.                 $done true;
  812.                 array_push($messagestrans('front.product.add_cart_complete'));
  813.             } else {
  814.                 // エラーが発生している場合
  815.                 $done false;
  816.                 $messages $errorMessages;
  817.             }
  818.             $Customer $this->getUser();
  819.             $Point $this->getPointCart($Cart$Customer);
  820.             $Cart $this->cartService->getCart();
  821.             $quantity 0;
  822.             $Total 0;
  823.             foreach ($Carts as $Cart) {
  824.                 foreach ($Cart->getCartItems() as $item) {
  825.                     if ($item->getProductClass()->getId() == $ProductClass->getId()){
  826.                         $quantity $item->getQuantity();
  827.                     }
  828.                 }
  829.                 $Total $Total $Cart->getTotalPrice();
  830.                 
  831.             }
  832.             
  833.             return $this->json(['done' => $done'messages' => $messages'total_price' => number_format($Total), 'add_point' => $Point'product_class_id' => $ProductClass->getId(), 'quantity' => $quantity]);
  834.         } else {
  835.             // ajax以外でのリクエストの場合はカート画面へリダイレクト
  836.             if (empty($errorMessages)) {
  837.                 return $this->redirectToRoute('cart');
  838.             } else {
  839.                 foreach ($errorMessages as $errorMessage) {
  840.                     $this->addRequestError($errorMessage);
  841.                 }
  842.                 return $this->redirect($request->headers->get('referer'));
  843.             }
  844.         }
  845.     }
  846.     /**
  847.      * ページタイトルの設定
  848.      *
  849.      * @param  null|array $searchData
  850.      *
  851.      * @return str
  852.      */
  853.     protected function getPageTitle($searchData)
  854.     {
  855.         if (isset($searchData['name']) && !empty($searchData['name'])) {
  856.             return trans('front.product.search_result');
  857.         } elseif (isset($searchData['category_id']) && $searchData['category_id']) {
  858.             return $searchData['category_id']->getName();
  859.         } else {
  860.             return trans('front.product.all_products');
  861.         }
  862.     }
  863.     /**
  864.      * 閲覧可能な商品かどうかを判定
  865.      *
  866.      * @param Product $Product
  867.      *
  868.      * @return boolean 閲覧可能な場合はtrue
  869.      */
  870.     protected function checkVisibility(Product $Product)
  871.     {
  872.         $is_admin $this->session->has('_security_admin');
  873.         // 管理ユーザの場合はステータスやオプションにかかわらず閲覧可能.
  874.         if (!$is_admin) {
  875.             // 在庫なし商品の非表示オプションが有効な場合.
  876.             // if ($this->BaseInfo->isOptionNostockHidden()) {
  877.             //     if (!$Product->getStockFind()) {
  878.             //         return false;
  879.             //     }
  880.             // }
  881.             // 公開ステータスでない商品は表示しない.
  882.             if ($Product->getStatus()->getId() !== ProductStatus::DISPLAY_SHOW) {
  883.                 return false;
  884.             }
  885.         }
  886.         return true;
  887.     }
  888.     /**
  889.      * カートに追加.
  890.      *
  891.      * @Route("/products/one_touch_payment/{id}", name="one_touch_payment", methods={"POST"}, requirements={"id" = "\d+"})
  892.      * @Template("Product/detail.twig")
  893.      */
  894.     public function oneTouchPayment(Request $requestProduct $Product)
  895.     {
  896.         // エラーメッセージの配列
  897.         $errorMessages = [];
  898.         if (!$this->checkVisibility($Product)) {
  899.             throw new NotFoundHttpException();
  900.         }
  901.         $builder $this->formFactory->createNamedBuilder(
  902.             '',
  903.             AddCartType::class,
  904.             null,
  905.             [
  906.                 'product' => $Product,
  907.                 'id_add_product_id' => false,
  908.             ]
  909.         );
  910.         $event = new EventArgs(
  911.             [
  912.                 'builder' => $builder,
  913.                 'Product' => $Product,
  914.             ],
  915.             $request
  916.         );
  917.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE$event);
  918.         /* @var $form \Symfony\Component\Form\FormInterface */
  919.         $form $builder->getForm();
  920.         $form->handleRequest($request);
  921.         //送り先のメールアドレス(option1)が会員情報に存在するかチェック 20220812 kikuzawa
  922.         if (isset($form->all()['productoption1'])) {
  923.             $recipientEmail $form->get('productoption1')->getData();
  924.             if ($recipientEmail) {
  925.                 $customer $this->customerRepository->findBy(array('email' => $recipientEmail));
  926.                 if (!$customer) {
  927.                     $errorMessages[] = '存在しないメールアドレスです。';
  928.                 }
  929.             }
  930.         }
  931.         if (!$form->isValid()) {
  932.             foreach ($form->all() as $child) {
  933.                 $config $child->getConfig();
  934.                 foreach ($child->getErrors() as $error) {
  935.                     $errorMessages[] = $config->getOption('label') . ':' $error->getMessage();
  936.                 }
  937.             }
  938.         }
  939.         $addCartData $form->getData();
  940.         $ProductClass $this->entityManager->getRepository(ProductClass::class)->find($addCartData['product_class_id']);
  941.         $limit $ProductClass->getSaleLimit();
  942.         if (!$ProductClass->isStockUnlimited()) {
  943.             $stock $ProductClass->getStock();
  944.         }
  945.         if (!is_null($limit) || isset($stock)) {
  946.             $Carts $this->cartService->getCarts();
  947.             $quantity $addCartData['quantity'];
  948.             foreach ($Carts as $Cart) {
  949.                 foreach ($Cart->getCartItems() as $item) {
  950.                     if ($item->getProductClass()->getId() == $ProductClass->getId()) $quantity += $item->getQuantity();
  951.                 }
  952.             }
  953.             $productName $ProductClass->getProduct()->getName();
  954.             if ($ProductClass->hasClassCategory1()) {
  955.                 $productName .= ' - ' $ProductClass->getClassCategory1()->getName();
  956.             }
  957.             if ($ProductClass->hasClassCategory2()) {
  958.                 $productName .= ' - ' $ProductClass->getClassCategory2()->getName();
  959.             }
  960.             if (!is_null($limit) && $limit $quantity) {
  961.                 $errorMessages[] = trans('front.shopping.over_sale_limit', ['%product%' => $productName]);
  962.             }
  963.             if (isset($stock) && $stock $quantity) {
  964.                 $errorMessages[] = trans('front.shopping.out_of_stock', ['%product%' => $productName]);
  965.             }
  966.         }
  967.         $oneTouchPaymentCart null;
  968.         if (count($errorMessages) == 0) {
  969.             log_info(
  970.                 'カート追加処理開始',
  971.                 [
  972.                     'product_id' => $Product->getId(),
  973.                     'product_class_id' => $addCartData['product_class_id'],
  974.                     'quantity' => $addCartData['quantity'],
  975.                 ]
  976.             );
  977.             // カートへ追加
  978.             $ProductOptions $Product->getProductOptions();
  979.             $Options = [];
  980.             foreach ($ProductOptions as $ProductOption) {
  981.                 $Option $ProductOption->getOption();
  982.                 $option_key 'productoption' $Option->getId();
  983.                 $value $form->get($option_key)->getData();
  984.                 if ($Option) {
  985.                     $add true;
  986.                     if ($Option->getType() == Option::SELECT_TYPE || $Option->getType() == Option::RADIO_TYPE) {
  987.                         if ($Option->getDisableCategory()) {
  988.                             if ($Option->getDisableCategory() == $value) {
  989.                                 $add false;
  990.                             }
  991.                         }
  992.                         $value $value->getId();
  993.                         if (strlen($value) == 0$add false;
  994.                     } elseif ($Option->getType() == Option::TEXT_TYPE || $Option->getType() == Option::TEXTAREA_TYPE || $Option->getType() == Option::NUMBER_TYPE) {
  995.                         if (strlen($value) == 0$add false;
  996.                     } elseif ($Option->getType() == Option::CHECKBOX_TYPE) {
  997.                         if (count($value) == 0) {
  998.                             $add false;
  999.                         } else {
  1000.                             $buff $value;
  1001.                             $value = [];
  1002.                             foreach ($buff as $categoryoption) {
  1003.                                 $value[] = $categoryoption->getId();
  1004.                             }
  1005.                         }
  1006.                     } elseif ($Option->getType() == Option::DATE_TYPE) {
  1007.                         if (is_null($value)) $add false;
  1008.                     }
  1009.                     if ($add) {
  1010.                         if (is_array($value)) {
  1011.                             $Options[$Option->getId()] = $value;
  1012.                         } elseif (is_object($value)) {
  1013.                             $Options[$Option->getId()] = $value->format('Y-m-d');
  1014.                         } else {
  1015.                             $Options[$Option->getId()] = (string)$value;
  1016.                         }
  1017.                     }
  1018.                 }
  1019.             }
  1020.             $this->cartService->addProductOption($addCartData['product_class_id'], $Options$addCartData['quantity']);
  1021.             // 明細の正規化
  1022.             $Carts $this->cartService->getCarts();
  1023.             foreach ($Carts as $Cart) {
  1024.                 $cartItems $Cart->getCartItems();
  1025.                 $isOneTouchPayment $cartItems[0]->getIsOneTouchPayment();
  1026.                 if ($isOneTouchPayment) {
  1027.                     $oneTouchPaymentCart $cartItems[0]->getCart();
  1028.                 }
  1029.                 $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->getUser()));
  1030.                 // 復旧不可のエラーが発生した場合は追加した明細を削除.
  1031.                 if ($result->hasError()) {
  1032.                     $this->cartService->removeProduct($addCartData['product_class_id']);
  1033.                     foreach ($result->getErrors() as $error) {
  1034.                         $errorMessages[] = $error->getMessage();
  1035.                     }
  1036.                 }
  1037.                 foreach ($result->getWarning() as $warning) {
  1038.                     $errorMessages[] = $warning->getMessage();
  1039.                 }
  1040.             }
  1041.             $this->cartService->save();
  1042.             log_info(
  1043.                 'カート追加処理完了',
  1044.                 [
  1045.                     'product_id' => $Product->getId(),
  1046.                     'product_class_id' => $addCartData['product_class_id'],
  1047.                     'quantity' => $addCartData['quantity'],
  1048.                 ]
  1049.             );
  1050.             $event = new EventArgs(
  1051.                 [
  1052.                     'form' => $form,
  1053.                     'Product' => $Product,
  1054.                 ],
  1055.                 $request
  1056.             );
  1057.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE$event);
  1058.         }
  1059.         if ($event->getResponse() !== null) {
  1060.             return $event->getResponse();
  1061.         }
  1062.             // ajaxでのリクエストの場合は結果をjson形式で返す。
  1063.             // 初期化
  1064.         $done null;
  1065.         $messages = [];
  1066.         $Customer $this->getUser();
  1067.         if (empty($errorMessages) && $oneTouchPaymentCart && $Customer) {
  1068.             // エラーが発生していない場合
  1069.             $done true;
  1070.             try {
  1071.                 $Order $this->orderHelper->initializeOrder($oneTouchPaymentCart$Customer);
  1072.                 $this->executePurchaseFlow($Orderfalse);
  1073.                 if ($Customer->getId()) {
  1074.                     $this->orderHelper->updateCustomerInfo($Order$Customer);
  1075.                     $trial $Customer->getTrialFamilyDate();
  1076.                     if ($trial) {
  1077.                         $date Carbon::parse($trial->format('Y-m-d H:i:s'));
  1078.                         $now Carbon::now();
  1079.                         $diff $date->diffInMonths($now);
  1080.                         if ($diff 1) {
  1081.                             $Order->setPaymentTotal($Order->getPaymentTotal() - $Order->getDeliveryFeeTotal());
  1082.                             $Order->setTotal($Order->getTotal() - $Order->getDeliveryFeeTotal());
  1083.                             $Order->setDeliveryFeeTotal(0);
  1084.                         }
  1085.                     }
  1086.                     $this->entityManager->persist($Order);
  1087.                     $this->entityManager->flush($Order);
  1088.                 }
  1089.                 $Shipping $Order->getShippings()[0];
  1090.                 $ShippingData = [
  1091.                     'id' => $Shipping->getId(),
  1092.                     'name01' => $Shipping->getName01(),
  1093.                     'name02' => $Shipping->getName02(),
  1094.                     'kana01' => $Shipping->getKana01(),
  1095.                     'kana02' => $Shipping->getKana02(),
  1096.                     'postal_code' => $Shipping->getPostalCode(),
  1097.                     'pref' => $Shipping->getPref()->getName(),
  1098.                     'addr01' => $Shipping->getAddr01(),
  1099.                     'addr02' => $Shipping->getAddr02(),
  1100.                     'phone_number' => $Shipping->getPhoneNumber(),
  1101.                 ];
  1102.                 $regularDiscount $Order->getOrderItems()[0]->getProduct()->getProductClasses()[0]->getRegularDiscount();
  1103.                 $discountSecond = array();
  1104.                 if ($regularDiscount) {
  1105.                     $discountFirst $this->regularDiscountRepository->find($Order->getOrderItems()[0]->getProduct()->getProductClasses()[0]->getRegularDiscount()->getId());
  1106.                     $discountSecond $this->regularDiscountRepository->findDiscountById($discountFirst->getDiscountId());
  1107.                 }
  1108.                 $OrderData = [
  1109.                     'payment_total' => $Order->getPaymentTotal(),
  1110.                     'delivery_fee_total' => $Order->getDeliveryFeeTotal(),
  1111.                     'order_id' => $Order->getId(),
  1112.                     'discount' => $Order->getDiscount(),
  1113.                     'shipping' => $ShippingData,
  1114.                     'product_name' => $Order->getOrderItems()[0]->getProduct()->getName() ?? null,
  1115.                     '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'),
  1116.                     'discount_rate' => $Order->getOrderItems()[0]->getProduct()->getProductClasses()[0]->getRegularDiscount() ? $Order->getOrderItems()[0]->getProduct()->getProductClasses()[0]->getRegularDiscount()->getDiscountRate() : 0,
  1117.                     'price' => $Order->getOrderItems()[0]->getProduct()->getPrice02IncTaxMax() ?? null,
  1118.                     'pt' => $this->get_point($Order->getPaymentTotal(), false) ?? null,
  1119.                     'pt_family_benefits' => $this->get_point($Order->getPaymentTotal(), true) ?? null,
  1120.                     'discount_second' => count($discountSecond) > $discountSecond[1]->getDiscountRate() : 0,
  1121.                     'sale_type' => $Order->getOrderItems()[0]->getProduct()->getProductClasses()[0]->getSaletype()->getName() == "定期商品",
  1122.                     'add_point' => number_format($Order->getAddPoint()),
  1123.                     'subtotal' => $Order->getSubtotal(),
  1124.                     'quantity' => $Order->getOrderItems()->first()->getQuantity(),
  1125.                 ];
  1126.                 $this->cartService->removeCart($oneTouchPaymentCart);
  1127.                 return $this->json([
  1128.                     'Order' => $OrderData,
  1129.                     'done' => true,
  1130.                 ]);
  1131.             } catch (\Exception $e) {
  1132.                 if ($oneTouchPaymentCart) {
  1133.                     $this->cartService->removeCart($oneTouchPaymentCart);
  1134.                 }
  1135.                 $this->entityManager->rollback();
  1136.                 $this->addError('front.shopping.system_error');
  1137.                 return $this->json(['done' => false'messages' => $messages]);;
  1138.             }
  1139.         } else {
  1140.             if ($oneTouchPaymentCart) {
  1141.                 $this->cartService->removeCart($oneTouchPaymentCart);
  1142.             }
  1143.             // エラーが発生している場合
  1144.             $done false;
  1145.             $messages $errorMessages;
  1146.             foreach ($messages as $message) {
  1147.                 $this->addError($message);
  1148.             }
  1149.         }
  1150.         return $this->json(['done' => $done'messages' => $messages]);
  1151.     }
  1152.     /**
  1153.      * カートに追加.
  1154.      *
  1155.      * @Route("/products/show_shipping/{id}", name="show_shipping", methods={"POST"}, requirements={"id" = "\d+"})
  1156.      * @Template("Product/detail.twig")
  1157.      */
  1158.     public function showListShipping(Request $requestShipping $Shipping)
  1159.     {
  1160.         $messages = [];
  1161.         $Customer $this->getUser();
  1162.         try {
  1163.             /** @var Customer $Customer */
  1164.             $CustomerAddress = new CustomerAddress();
  1165.             $CustomerAddress->setFromCustomer($Customer);
  1166.             $Addresses array_merge([$CustomerAddress], $Customer->getCustomerAddresses()->toArray());
  1167.             $ShippingDatas = [];
  1168.             foreach ($Addresses as $key => $address) {
  1169.                 $default '';
  1170.                 if ($key == 0) {
  1171.                     $default 'checked';
  1172.                 }
  1173.                 $ShippingDatas[] = [
  1174.                     'id' => $address->getId(),
  1175.                     'name01' => $address->getName01(),
  1176.                     'name02' => $address->getName02(),
  1177.                     'kana01' => $address->getKana01(),
  1178.                     'kana02' => $address->getKana02(),
  1179.                     'postal_code' => $address->getPostalCode(),
  1180.                     'pref' => $address->getPref()->getName(),
  1181.                     'addr01' => $address->getAddr01(),
  1182.                     'addr02' => $address->getAddr02(),
  1183.                     'phone_number' => $address->getPhoneNumber(),
  1184.                     'default' => $default
  1185.                 ];
  1186.             }
  1187.             return $this->json(['done' => false'messages' => $messages,'Shippings' => $ShippingDatas] );
  1188.         } catch (\Exception $e) {
  1189.             $this->entityManager->rollback();
  1190.             $this->addError('front.shopping.system_error');
  1191.             return $this->json(['done' => false'messages' => $messages]);
  1192.         }
  1193.     }
  1194.     /**
  1195.      * カートに追加.
  1196.      *
  1197.      * @Route("/products/show_card/{id}", name="show_card", methods={"POST"}, requirements={"id" = "\d+"})
  1198.      * @Template("Product/detail.twig")
  1199.      */
  1200.     public function showListCard(Request $requestCustomer $Customer)
  1201.     {
  1202.         $messages = [];
  1203.         $dataCards = [];
  1204.         $Customer $this->getUser();
  1205.         $cards = new ArrayCollection();
  1206.         $defaultPayment null;
  1207.         $StripeCustomer=$this->stripeCustomerRepository->findOneBy(array('Customer'=>$Customer));
  1208.         try {
  1209.             if ($StripeCustomer) {
  1210.                 $StripeCustomerId $StripeCustomer->getStripeCustomerId();
  1211.                 $paymentMethod StripeLibCustomer::retrieve($StripeCustomerId);
  1212.                 if ($StripeCustomerId) {
  1213.                     $cards PaymentMethod::all([
  1214.                         'customer' => $StripeCustomerId,
  1215.                         'type' => 'card',
  1216.                     ]);
  1217.                     $cards = new ArrayCollection($cards->data);
  1218.                 };
  1219.                 if ($request->get('stripe_payment_method_id')) {
  1220.                     $defaultPayment $request->get('stripe_payment_method_id');
  1221.                 }
  1222.                 else{
  1223.                     if ($paymentMethod['invoice_settings']['default_payment_method']) {
  1224.                         $defaultPayment $paymentMethod['invoice_settings']['default_payment_method'];
  1225.                     }else{
  1226.                         $defaultPayment $cards[0]['id'];
  1227.                     }
  1228.                 }
  1229.             }
  1230.             foreach ($cards as $key => $card) {
  1231.                 $default "";
  1232.                 if ($defaultPayment == $card['id']) {
  1233.                     $default "checked";
  1234.                 }
  1235.                 $dataCards[] = [
  1236.                     'id' => $card['id'],
  1237.                     'brand' => $card['card']['brand'],
  1238.                     'exp_month' => $card['card']['exp_month'],
  1239.                     'exp_year' => $card['card']['exp_year'],
  1240.                     'last4' => $card['card']['last4'],
  1241.                     'default' => $default
  1242.                 ];
  1243.             }
  1244.             return $this->json(['done' => true'messages' => $messages,'Cards' => $dataCards] );
  1245.         } catch (\Exception $e) {
  1246.             $this->entityManager->rollback();
  1247.             $this->addError('front.shopping.system_error');
  1248.             return $this->json(['done' => false'messages' => $messages]);
  1249.         }
  1250.     }
  1251.     /**
  1252.      * カートに追加.
  1253.      *
  1254.      * @Route("/products/update_card/{id}", name="update_card", methods={"POST"}, requirements={"id" = "\d+"})
  1255.      * @Template("Product/detail.twig")
  1256.      */
  1257.     public function updateCard(Request $request)
  1258.     {
  1259.         $messages = [];
  1260.         $StripeCardId $request->get('radio_card');
  1261.         $paymentMethod PaymentMethod::retrieve($StripeCardId);
  1262.         $dataCard = [
  1263.             'id' => $paymentMethod['id'],
  1264.             'brand' => $paymentMethod['card']['brand'],
  1265.             'exp_month' => $paymentMethod['card']['exp_month'],
  1266.             'exp_year' => $paymentMethod['card']['exp_year'],
  1267.             'last4' => $paymentMethod['card']['last4'],
  1268.         ];
  1269.         return $this->json(['done' => true'messages' => $messages,'Card' => $dataCard] );
  1270.     }
  1271.     /**
  1272.      * カートに追加.
  1273.      *
  1274.      * @Route("/products/create_card_onetouch/{id}", name="create_card_onetouch", methods={"POST"}, requirements={"id" = "\d+"})
  1275.      * @Template("Product/detail.twig")
  1276.      */
  1277.     public function createCardOnetouch(Request $requestCustomer $Customer)
  1278.     {
  1279.         $messages = [];
  1280.         $StripeCustomer $this->stripeCustomerRepository->findOneBy(array('Customer' => $Customer));
  1281.         $cards = new ArrayCollection();
  1282.         if ($StripeCustomer) {
  1283.             $StripeCustomerId $StripeCustomer->getStripeCustomerId();
  1284.             if ($StripeCustomerId) {
  1285.                 $cards PaymentMethod::all([
  1286.                     'customer' => $StripeCustomerId,
  1287.                     'type' => 'card',
  1288.                 ]);
  1289.                 $cards = new ArrayCollection($cards->data);
  1290.             };
  1291.         }else{
  1292.             $customer_id $Customer['id'];
  1293.             $customer_email $Customer['email'];
  1294.             $data = [
  1295.                 'email'=> $customer_email,
  1296.                 'metadata'=> array('customer_id' => $customer_id),
  1297.             ];
  1298.             $StripeCustomerApi StripeLibCustomer::create($data);
  1299.             $StripeCustomer = new StripeCustomer();
  1300.             $StripeCustomer->setCustomer($Customer);
  1301.             $StripeCustomer->setStripeCustomerId($StripeCustomerApi['id']);
  1302.             $StripeCustomer->setIsSaveCardOn(0);
  1303.             $StripeCustomer->setCreatedAt(new \DateTime());
  1304.             $this->entityManager->persist($StripeCustomer);
  1305.             $this->entityManager->flush($StripeCustomer);
  1306.             $StripeCustomerId $StripeCustomer->getStripeCustomerId();
  1307.             if ($StripeCustomerId) {
  1308.                 $cards PaymentMethod::all([
  1309.                     'customer' => $StripeCustomerId,
  1310.                     'type' => 'card',
  1311.                 ]);
  1312.                 $cards = new ArrayCollection($cards->data);
  1313.             };
  1314.         }
  1315.         $fingerprints = [];
  1316.         foreach ($cards as $card) {
  1317.             $fingerprints[] = $card['card']['fingerprint'];
  1318.         }
  1319.         try {
  1320.             $payment_method PaymentMethod::retrieve($request->get("stripe_payment_method_id"));
  1321.             if (in_array($payment_method['card']['fingerprint'], $fingerprints)) {
  1322.                 return $this->redirectToRoute('mypage_card');
  1323.             }
  1324.             $payment_method->attach([
  1325.                 'customer' => $StripeCustomerId
  1326.             ]);
  1327.             $dataCard = [
  1328.                 'id' => $payment_method['id'],
  1329.                 'brand' => $payment_method['card']['brand'],
  1330.                 'exp_month' => $payment_method['card']['exp_month'],
  1331.                 'exp_year' => $payment_method['card']['exp_year'],
  1332.                 'last4' => $payment_method['card']['last4'],
  1333.             ];
  1334.             return $this->json(['done' => true'messages' => $messages,'Card' => $dataCard,'StripeCustomerId' => $StripeCustomerId] );
  1335.         } catch (Exception $e) {
  1336.             return $this->redirectToRoute('mypage_card_new');
  1337.         }
  1338.     }
  1339.     /**
  1340.      * カートに追加.
  1341.      *
  1342.      * @Route("/products/update_shipping/{id}", name="update_shipping", methods={"POST"}, requirements={"id" = "\d+"})
  1343.      * @Template("Product/detail.twig")
  1344.      */
  1345.     public function updateShipping(Request $requestShipping $Shipping)
  1346.     {
  1347.         $messages = [];
  1348.         $Customer $this->getUser();
  1349.         $customerId $Customer->getId();
  1350.         $preOrderId $Shipping->getOrder()->getPreOrderId();
  1351.         $Order $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
  1352.         $idAddress $request->get('radio_address');
  1353.         try {
  1354.             if ($idAddress != 0) {
  1355.                 /** @var CustomerAddress $CustomerAddress */
  1356.                 $CustomerAddress $this->customerAddressRepository->find($idAddress);
  1357.                 $Shipping->setFromCustomerAddress($CustomerAddress);
  1358.             }
  1359.             else{
  1360.                 $CustomerAddress = new CustomerAddress();
  1361.                 $CustomerAddress->setFromCustomer($Customer);
  1362.                 $Shipping->setFromCustomerAddress($CustomerAddress);
  1363.             }
  1364.             // 合計金額の再計算
  1365.             $response $this->executePurchaseFlow($Order);
  1366.             $this->entityManager->flush();
  1367.             $Shipping $Order->getShippings()[0];
  1368.             $ShippingData = [
  1369.                 'id' => $Shipping->getId(),
  1370.                 'name01' => $Shipping->getName01(),
  1371.                 'name02' => $Shipping->getName02(),
  1372.                 'kana01' => $Shipping->getKana01(),
  1373.                 'kana02' => $Shipping->getKana02(),
  1374.                 'postal_code' => $Shipping->getPostalCode(),
  1375.                 'pref' => $Shipping->getPref()->getName(),
  1376.                 'addr01' => $Shipping->getAddr01(),
  1377.                 'addr02' => $Shipping->getAddr02(),
  1378.                 'phone_number' => $Shipping->getPhoneNumber(),
  1379.                 'default_id' => $CustomerAddress->getId(),
  1380.             ];
  1381.             $OrderData = [
  1382.                 'payment_total' => $Order->getPaymentTotal(),
  1383.                 'delivery_fee_total' => $Order->getDeliveryFeeTotal(),
  1384.                 'order_id' => $Order->getId(),
  1385.                 'discount' => $Order['discount'],
  1386.                 'shipping' => $ShippingData
  1387.             ];
  1388.             return $this->json([
  1389.                 'Order' => $OrderData,
  1390.                 'done' => true,
  1391.             ]);
  1392.         } catch (\Exception $e) {
  1393.             $this->entityManager->rollback();
  1394.             $this->addError('front.shopping.system_error');
  1395.             return $this->json(['done' => false'messages' => $messages]);;
  1396.         }
  1397.     }
  1398.     /**
  1399.      * カートに追加.
  1400.      *
  1401.      * @Route("/products/create_shipping/{id}", name="create_shipping", methods={"POST"}, requirements={"id" = "\d+"})
  1402.      * @Template("Product/detail.twig")
  1403.      */
  1404.     public function createShipping(Request $requestShipping $Shipping)
  1405.     {
  1406.         $messages = [];
  1407.         $CustomerAddress = new CustomerAddress();
  1408.         $CustomerAddress->setCustomer($this->getUser());
  1409.         $builder $this->formFactory->createBuilder(CustomerAddressType::class, $CustomerAddress);
  1410.         $form $builder->getForm();
  1411.         $form->handleRequest($request);
  1412.         try {
  1413.             $this->entityManager->persist($CustomerAddress);
  1414.             $this->entityManager->flush();
  1415.             $preOrderId $Shipping->getOrder()->getPreOrderId();
  1416.             $Order $this->orderHelper->getPurchaseProcessingOrder($preOrderId);
  1417.             $Shipping->setFromCustomerAddress($CustomerAddress);
  1418.             $response $this->executePurchaseFlow($Order);
  1419.             $this->entityManager->flush();
  1420.             $Shipping $Order->getShippings()[0];
  1421.             $ShippingData = [
  1422.                 'id' => $Shipping->getId(),
  1423.                 'name01' => $Shipping->getName01(),
  1424.                 'name02' => $Shipping->getName02(),
  1425.                 'kana01' => $Shipping->getKana01(),
  1426.                 'kana02' => $Shipping->getKana02(),
  1427.                 'postal_code' => $Shipping->getPostalCode(),
  1428.                 'pref' => $Shipping->getPref()->getName(),
  1429.                 'addr01' => $Shipping->getAddr01(),
  1430.                 'addr02' => $Shipping->getAddr02(),
  1431.                 'phone_number' => $Shipping->getPhoneNumber(),
  1432.                 'default_id' => $CustomerAddress->getId(),
  1433.             ];
  1434.             $OrderData = [
  1435.                 'payment_total' => $Order->getPaymentTotal(),
  1436.                 'delivery_fee_total' => $Order->getDeliveryFeeTotal(),
  1437.                 'order_id' => $Order->getId(),
  1438.                 'discount' => $Order['discount'],
  1439.                 'shipping' => $ShippingData
  1440.             ];
  1441.             return $this->json([
  1442.                 'Order' => $OrderData,
  1443.                 'done' => true,
  1444.             ]);
  1445.         } catch (\Exception $e) {
  1446.             $this->entityManager->rollback();
  1447.             $this->addError('front.shopping.system_error');
  1448.             return $this->json(['done' => false'messages' => $messages]);;
  1449.         }
  1450.     }
  1451.     /**
  1452.      * @param ItemHolderInterface $itemHolder
  1453.      * @param bool $returnResponse レスポンスを返すかどうか. falseの場合はPurchaseFlowResultを返す.
  1454.      *
  1455.      * @return PurchaseFlowResult|\Symfony\Component\HttpFoundation\RedirectResponse
  1456.      */
  1457.     protected function executePurchaseFlow(ItemHolderInterface $itemHolder$returnResponse true)
  1458.     {
  1459.         /** @var PurchaseFlowResult $flowResult */
  1460.         $flowResult $this->shoppingPurchaseFlow->validate($itemHolder, new PurchaseContext(clone $itemHolder$itemHolder->getCustomer()));
  1461.         foreach ($flowResult->getWarning() as $warning) {
  1462.             $this->addWarning($warning->getMessage());
  1463.         }
  1464.         foreach ($flowResult->getErrors() as $error) {
  1465.             $this->addError($error->getMessage());
  1466.         }
  1467.         if (!$returnResponse) {
  1468.             return $flowResult;
  1469.         }
  1470.         if ($flowResult->hasError()) {
  1471.             log_info('Errorが発生したため購入エラー画面へ遷移します.', [$flowResult->getErrors()]);
  1472.             return $flowResult;
  1473.         }
  1474.         if ($flowResult->hasWarning()) {
  1475.             log_info('Warningが発生したため注文手続き画面へ遷移します.', [$flowResult->getWarning()]);
  1476.             return $flowResult;
  1477.         }
  1478.     }
  1479.     private function get_point($price$prime=false){
  1480.         if($prime){
  1481.             return number_format($price 100);
  1482.         }else{
  1483.             $pointRate 1;
  1484.             if ($this->getUser()) {
  1485.                 $pointRate $this->getUser()->getOwnerRank() + 1;
  1486.             }
  1487.             return number_format($price $pointRate 100);
  1488.         }
  1489.     }
  1490.      /**
  1491.      * 商品一覧画面.
  1492.      * 
  1493.      * @Route("/products/promotion_code", name="promotion_code", methods={"POST"})
  1494.      */
  1495.     public function applyPromotionCode(Request $request)
  1496.     {
  1497.         $Order $this->orderRepository->find($request->get('order_id'));
  1498.         $CouponOrder $this->couponOrderRepository->getCouponOrder($Order->getPreOrderId());
  1499.         $couponCd null;
  1500.         if ($CouponOrder) {
  1501.             $couponCd $CouponOrder->getCouponCd();
  1502.         }
  1503.         $form_c $this->formFactory->createBuilder(CouponUseType::class)->getForm();
  1504.         $service $this->couponService;
  1505.         $formCouponCd $request->get('coupon_cd');
  1506.         $formCouponCancel $request->get('coupon_use');
  1507.         if ($formCouponCancel == 0) {
  1508.             if (!is_null($formCouponCd)) {
  1509.                 $this->couponService->removeCouponOrder($Order);
  1510.                 $Order->setPaymentTotal($Order->getPaymentTotal() + $Order->getDiscount());
  1511.                 $Order->setTotal($Order->getTotal() + $Order->getDiscount());
  1512.                 $Order->setDiscount(0);
  1513.                 $this->entityManager->persist($Order);
  1514.                 $this->entityManager->flush();
  1515.             }
  1516.             return $this->redirectToRoute('shopping');
  1517.         } else {
  1518.             $error false;
  1519.             $Coupon $this->couponRepository->findActiveCoupon($formCouponCd);
  1520.             if (!$Coupon) {
  1521.                 $form_c->get('coupon_cd')->addError(new FormError(trans('plugin_coupon.front.shopping.notexists')));
  1522.                 $error true;
  1523.                 return $this->json([
  1524.                     'success'=> false,
  1525.                 ]);
  1526.             }
  1527.             $Customer $this->getUser();
  1528.             if (!$error && $Coupon) {
  1529.                 $couponProducts $service->existsCouponProduct($Coupon$Order);
  1530.                 $discount $service->recalcOrder($Coupon$couponProducts);
  1531.                 $service->saveCouponOrder($Order$Coupon$formCouponCd$Customer$discount);
  1532.                 if ($discount) {
  1533.                     $Order->setDiscount($discount);
  1534.                     $Order->setPaymentTotal($Order->getPaymentTotal() - $discount);
  1535.                     $Order->setTotal($Order->getTotal() - $discount);
  1536.                     $this->entityManager->persist($Order);
  1537.                     $this->entityManager->flush();
  1538.                 }
  1539.                 return $this->json([
  1540.                     'success'=> true,
  1541.                     'discount' => $discount,
  1542.                     'total' => $Order->getTotal()
  1543.                 ]);
  1544.             }
  1545.         }
  1546.     }
  1547.     private function handlerSupplierProduct($Product)
  1548.     {
  1549.         $categorySupplier $this->productRepository->getSupplierCategories();
  1550.         $is_supplier false;
  1551.         foreach ($Product->getProductCategories() as $category) {
  1552.             if (in_array($category->getCategoryId(), $categorySupplier)) {
  1553.                 $is_supplier true;
  1554.             }
  1555.         }
  1556.         return $is_supplier;
  1557.     }
  1558.      /**
  1559.      * 商品一覧画面.
  1560.      * 
  1561.      * @Route("/products/last_customer/{id}", name="last_customer_order", methods={"GET"}, requirements={"id" = "\d+"})
  1562.      */
  1563.     public function getLastCustomerOrder($id)
  1564.     {
  1565.         $lastOrderCustomers $this->productRepository->getCustomerLastOrder($id);  
  1566.         $Mails = [];
  1567.         if ($lastOrderCustomers) {
  1568.             foreach($lastOrderCustomers as $customer) {
  1569.                 $Mails[] = $customer->getEmail();
  1570.             }
  1571.         }
  1572.         return $this->json([
  1573.             'emails' => $Mails
  1574.         ]);
  1575.     }
  1576.     function getPointCart($Cart$Customer){ 
  1577.         $prime $Customer['prime_member'];
  1578.             $urank $Customer['owner_rank'];
  1579.             $alpha 0;
  1580.             if($prime){
  1581.                 $alpha 3;
  1582.             }
  1583.             if($urank == 0){
  1584.                 $alpha $alpha 1;
  1585.             }elseif($urank == 1){
  1586.                 $alpha $alpha 2;
  1587.             }elseif($urank == 2){
  1588.                 $alpha $alpha 3;
  1589.             }elseif($urank == 3){
  1590.                 $alpha $alpha 4;
  1591.             }
  1592.             return number_formatround(strval($Cart->getTotalPrice() * $alpha 100)));
  1593.     }
  1594.     /**
  1595.      * カートに追加.
  1596.      *
  1597.      * @Route("/products/add_cart_by_email/{id}", name="product_add_cart_by_email", methods={"POST","GET"}, requirements={"id" = "\d+"})
  1598.      */
  1599.     public function addCartByEmail(Request $requestProduct $Product)
  1600.     {
  1601.         // エラーメッセージの配列
  1602.         $errorMessages = [];
  1603.         if (!$this->checkVisibility($Product)) {
  1604.             throw new NotFoundHttpException();
  1605.         }
  1606.         $builder $this->formFactory->createNamedBuilder(
  1607.             '',
  1608.             AddCartByEmailType::class,
  1609.             null,
  1610.             [
  1611.                 'product' => $Product,
  1612.                 'id_add_product_id' => false,
  1613.             ]
  1614.         );
  1615.         $event = new EventArgs(
  1616.             [
  1617.                 'builder' => $builder,
  1618.                 'Product' => $Product,
  1619.             ],
  1620.             $request
  1621.         );
  1622.         $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE$event);
  1623.         /* @var $form \Symfony\Component\Form\FormInterface */
  1624.         $form $builder->getForm();
  1625.         $form->handleRequest($request);
  1626.         if (!$form->isValid()) {
  1627.             foreach ($form->all() as $child) {
  1628.                 $config $child->getConfig();
  1629.                 foreach ($child->getErrors() as $error) {
  1630.                     $errorMessages[] = $config->getOption('label') . ':' $error->getMessage();
  1631.                 }
  1632.             }
  1633.         }
  1634.         $recipientEmail $form->get('email')->getData();
  1635.         if ($recipientEmail) {
  1636.             $customer $this->customerRepository->findBy(array('email' => $recipientEmail));
  1637.             if (count($customer) > 0) {
  1638.                 $customer $customer[0];
  1639.             } else {
  1640.                 $customer null;
  1641.                 $errorMessages[] = '存在しないメールアドレスです。';
  1642.             }
  1643.         }
  1644.         $addCartData $form->getData();
  1645.         $ProductClass $this->entityManager->getRepository(ProductClass::class)->find($addCartData['product_class_id']);
  1646.         $limit $ProductClass->getSaleLimit();
  1647.         if (!$ProductClass->isStockUnlimited()) {
  1648.             $stock $ProductClass->getStock();
  1649.         }
  1650.         if (!is_null($limit) || isset($stock)) {
  1651.             $Carts $this->cartService->getCarts();
  1652.             $quantity $addCartData['quantity'];
  1653.             foreach ($Carts as $Cart) {
  1654.                 foreach ($Cart->getCartItems() as $item) {
  1655.                     if ($item->getProductClass()->getId() == $ProductClass->getId()) $quantity += $item->getQuantity();
  1656.                 }
  1657.             }
  1658.             $productName $ProductClass->getProduct()->getName();
  1659.             if ($ProductClass->hasClassCategory1()) {
  1660.                 $productName .= ' - ' $ProductClass->getClassCategory1()->getName();
  1661.             }
  1662.             if ($ProductClass->hasClassCategory2()) {
  1663.                 $productName .= ' - ' $ProductClass->getClassCategory2()->getName();
  1664.             }
  1665.             if (!is_null($limit) && $limit $quantity) {
  1666.                 $errorMessages[] = trans('front.shopping.over_sale_limit', ['%product%' => $productName]);
  1667.             }
  1668.             if (isset($stock) && $stock $quantity) {
  1669.                 $errorMessages[] = trans('front.shopping.out_of_stock', ['%product%' => $productName]);
  1670.             }
  1671.         }
  1672.         if (count($errorMessages) == 0) {
  1673.             log_info(
  1674.                 'カート追加処理開始',
  1675.                 [
  1676.                     'product_id' => $Product->getId(),
  1677.                     'product_class_id' => $addCartData['product_class_id'],
  1678.                     'quantity' => $addCartData['quantity'],
  1679.                 ]
  1680.             );
  1681.             // カートへ追加
  1682.             $ProductOptions $Product->getProductOptions();
  1683.             $Options = [];
  1684.             foreach ($ProductOptions as $ProductOption) {
  1685.                 $Option $ProductOption->getOption();
  1686.                 $option_key 'productoption' $Option->getId();
  1687.                 $value $form->get($option_key)->getData();
  1688.                 if ($Option) {
  1689.                     $add true;
  1690.                     if ($Option->getType() == Option::SELECT_TYPE || $Option->getType() == Option::RADIO_TYPE) {
  1691.                         if ($Option->getDisableCategory()) {
  1692.                             if ($Option->getDisableCategory() == $value) {
  1693.                                 $add false;
  1694.                             }
  1695.                         }
  1696.                         $value $value->getId();
  1697.                         if (strlen($value) == 0$add false;
  1698.                     } elseif ($Option->getType() == Option::TEXT_TYPE || $Option->getType() == Option::TEXTAREA_TYPE || $Option->getType() == Option::NUMBER_TYPE) {
  1699.                         if (strlen($value) == 0$add false;
  1700.                     } elseif ($Option->getType() == Option::CHECKBOX_TYPE) {
  1701.                         if (count($value) == 0) {
  1702.                             $add false;
  1703.                         } else {
  1704.                             $buff $value;
  1705.                             $value = [];
  1706.                             foreach ($buff as $categoryoption) {
  1707.                                 $value[] = $categoryoption->getId();
  1708.                             }
  1709.                         }
  1710.                     } elseif ($Option->getType() == Option::DATE_TYPE) {
  1711.                         if (is_null($value)) $add false;
  1712.                     }
  1713.                     if ($add) {
  1714.                         if (is_array($value)) {
  1715.                             $Options[$Option->getId()] = $value;
  1716.                         } elseif (is_object($value)) {
  1717.                             $Options[$Option->getId()] = $value->format('Y-m-d');
  1718.                         } else {
  1719.                             $Options[$Option->getId()] = (string)$value;
  1720.                         }
  1721.                     }
  1722.                 }
  1723.             }
  1724.             $this->cartService->addProductOption($addCartData['product_class_id'], $Options$addCartData['quantity']);
  1725.             // 明細の正規化
  1726.             $Carts $this->cartService->getCarts();
  1727.             foreach ($Carts as $Cart) {
  1728.                 $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$customer));
  1729.                 // 復旧不可のエラーが発生した場合は追加した明細を削除.
  1730.                 if ($result->hasError()) {
  1731.                     $this->cartService->removeProduct($addCartData['product_class_id']);
  1732.                     foreach ($result->getErrors() as $error) {
  1733.                         $errorMessages[] = $error->getMessage();
  1734.                     }
  1735.                 }
  1736.                 foreach ($result->getWarning() as $warning) {
  1737.                     $errorMessages[] = $warning->getMessage();
  1738.                 }
  1739.             }
  1740.             $this->cartService->save();
  1741.             log_info(
  1742.                 'カート追加処理完了',
  1743.                 [
  1744.                     'product_id' => $Product->getId(),
  1745.                     'product_class_id' => $addCartData['product_class_id'],
  1746.                     'quantity' => $addCartData['quantity'],
  1747.                 ]
  1748.             );
  1749.             $event = new EventArgs(
  1750.                 [
  1751.                     'form' => $form,
  1752.                     'Product' => $Product,
  1753.                 ],
  1754.                 $request
  1755.             );
  1756.             $this->eventDispatcher->dispatch(EccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE$event);
  1757.         }
  1758.         if ($event->getResponse() !== null) {
  1759.             return $event->getResponse();
  1760.         }
  1761.         $done null;
  1762.         $messages = [];
  1763.         if (empty($errorMessages)) {
  1764.             // エラーが発生していない場合
  1765.             $done true;
  1766.             array_push($messagestrans('front.product.add_cart_complete'));
  1767.         } else {
  1768.             // エラーが発生している場合
  1769.             $done false;
  1770.             $messages $errorMessages;
  1771.         }
  1772.         return $this->json(['done' => $done'messages' => $messages'product_class_id' => $ProductClass->getId()]);
  1773.     }
  1774.     /**
  1775.      * @Route("/update_last_seen_product", name="update_last_seen_product", methods={"POST"})
  1776.      */
  1777.     public function updateLastSeenProduct(Request $request)
  1778.     {
  1779.         try {
  1780.             $productId = (int) $request->request->get('productId');
  1781.             $arr $this->session->get('plugin.check_product.product');
  1782.             $arr[] = $productId;
  1783.             $arr array_unique($arr);
  1784.             $max $this->eccubeConfig['PLG_CHECK_PRODUCT_MAX'];
  1785.             $arr array_slice($arr, (- $max), $max);
  1786.             $this->session->set('plugin.check_product.product'$arr);
  1787.             return $this->json([
  1788.                 'done' => true,
  1789.                 'child_product_id' => $arr
  1790.             ]);
  1791.         } catch (\Throwable $th) {
  1792.             throw $th;
  1793.         }
  1794.     }
  1795. }