app/Customize/Controller/ProductController.php line 221

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 Customize\Controller;
  13. use Customize\Entity\School;
  14. use Customize\Form\Type\MatomeCartType;
  15. use Eccube\Controller\AbstractController;
  16. use Eccube\Entity\BaseInfo;
  17. use Eccube\Entity\CartItem;
  18. use Eccube\Entity\Master\ProductStatus;
  19. use Eccube\Entity\Product;
  20. use Eccube\Event\EccubeEvents;
  21. use Eccube\Event\EventArgs;
  22. use Eccube\Form\Type\AddCartType;
  23. use Eccube\Form\Type\Master\ProductListMaxType;
  24. use Eccube\Form\Type\Master\ProductListOrderByType;
  25. use Eccube\Form\Type\SearchProductType;
  26. use Eccube\Repository\BaseInfoRepository;
  27. use Eccube\Repository\CustomerFavoriteProductRepository;
  28. use Eccube\Repository\Master\ProductListMaxRepository;
  29. use Eccube\Repository\OrderRepository;
  30. use Customize\Repository\ProductRepository;
  31. use Customize\Repository\SetProductRepository;
  32. use Customize\Repository\RecommendXRepository;
  33. use Customize\Repository\RecommendYRepository;
  34. use Customize\Repository\RecommendSizeRepository;
  35. use Customize\Repository\ProductSchoolRepository;
  36. use Customize\Repository\SchoolRepository;
  37. use Eccube\Repository\ProductClassRepository;
  38. use Customize\Service\CartService;
  39. use Eccube\Service\PurchaseFlow\PurchaseContext;
  40. use Eccube\Service\PurchaseFlow\PurchaseFlow;
  41. use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
  42. use Knp\Component\Pager\PaginatorInterface;
  43. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  44. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  45. use Symfony\Component\HttpFoundation\Request;
  46. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  47. use Symfony\Component\Routing\Annotation\Route;
  48. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  49. use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
  50. use Customize\Repository\BrotherRepository;
  51. use Customize\Service\UserService;
  52. class ProductController extends AbstractController
  53. {
  54.     /**
  55.      * @var PurchaseFlow
  56.      */
  57.     protected $purchaseFlow;
  58.     /**
  59.      * @var CustomerFavoriteProductRepository
  60.      */
  61.     protected $customerFavoriteProductRepository;
  62.     /**
  63.      * @var CartService
  64.      */
  65.     protected $cartService;
  66.     /**
  67.      * @var ProductRepository
  68.      */
  69.     protected $productRepository;
  70.     /**
  71.      * @var SetProductRepository
  72.      */
  73.     protected $setProductRepository;
  74.     /**
  75.      * @var BaseInfo
  76.      */
  77.     protected $BaseInfo;
  78.     /**
  79.      * @var AuthenticationUtils
  80.      */
  81.     protected $helper;
  82.     /**
  83.      * @var ProductListMaxRepository
  84.      */
  85.     protected $productListMaxRepository;
  86.     private $title '';
  87.     /**
  88.      * @var RecommendXRepository
  89.      */
  90.     protected $recommendXRepository;
  91.     /**
  92.      * @var RecommendYRepository
  93.      */
  94.     protected $recommendYRepository;
  95.     /**
  96.      * @var RecommendSizeRepository
  97.      */
  98.     protected $recommendSizeRepository;
  99.     /**
  100.      * @var ProductSchoolRepository
  101.      */
  102.     protected $productSchoolRepository;
  103.     /**
  104.      * @var SchoolRepository
  105.      */
  106.     protected $schoolRepository;
  107.     /**
  108.      * @var ProductClassRepository
  109.      */
  110.     protected $productClassRepository;
  111.     /**
  112.      * @var BrotherRepository
  113.      */
  114.     protected $brotherRepository;
  115.     /**
  116.      * @var UserService
  117.      */
  118.     protected $userService;
  119.     /**
  120.      * @var OrderRepository
  121.      */
  122.     protected $orderRepository;
  123.     /**
  124.      * ProductController constructor.
  125.      *
  126.      * @param PurchaseFlow $cartPurchaseFlow
  127.      * @param CustomerFavoriteProductRepository $customerFavoriteProductRepository
  128.      * @param CartService $cartService
  129.      * @param ProductRepository $productRepository
  130.      * @param SetProductRepository $setProductRepository
  131.      * @param BaseInfoRepository $baseInfoRepository
  132.      * @param AuthenticationUtils $helper
  133.      * @param ProductListMaxRepository $productListMaxRepository
  134.      * @param RecommendXRepository $recommendXRepository
  135.      * @param RecommendYRepository $recommendYRepository
  136.      * @param RecommendSizeRepository $recommendSizeRepository
  137.      * @param ProductSchoolRepository $productSchoolRepository
  138.      * @param SchoolRepository $schoolRepository
  139.      * @param ProductClassRepository $productClassRepository
  140.      * @param UserService $userService
  141.      */
  142.     public function __construct(
  143.         PurchaseFlow $cartPurchaseFlow,
  144.         CustomerFavoriteProductRepository $customerFavoriteProductRepository,
  145.         CartService $cartService,
  146.         ProductRepository $productRepository,
  147.         SetProductRepository $setProductRepository,
  148.         BaseInfoRepository $baseInfoRepository,
  149.         AuthenticationUtils $helper,
  150.         ProductListMaxRepository $productListMaxRepository,
  151.         RecommendXRepository $recommendXRepository,
  152.         RecommendYRepository $recommendYRepository,
  153.         RecommendSizeRepository $recommendSizeRepository,
  154.         ProductSchoolRepository $productSchoolRepository,
  155.         SchoolRepository $schoolRepository,
  156.         ProductClassRepository $productClassRepository,
  157.         BrotherRepository $brotherRepository,
  158.         UserService $userService,
  159.         OrderRepository $orderRepository
  160.     ) {
  161.         $this->purchaseFlow $cartPurchaseFlow;
  162.         $this->customerFavoriteProductRepository $customerFavoriteProductRepository;
  163.         $this->cartService $cartService;
  164.         $this->productRepository $productRepository;
  165.         $this->setProductRepository $setProductRepository;
  166.         $this->BaseInfo $baseInfoRepository->get();
  167.         $this->helper $helper;
  168.         $this->productListMaxRepository $productListMaxRepository;
  169.         $this->recommendXRepository $recommendXRepository;
  170.         $this->recommendYRepository $recommendYRepository;
  171.         $this->recommendSizeRepository $recommendSizeRepository;
  172.         $this->productSchoolRepository $productSchoolRepository;
  173.         $this->schoolRepository  $schoolRepository;
  174.         $this->productClassRepository $productClassRepository;
  175.         $this->brotherRepository $brotherRepository;
  176.         $this->userService $userService;
  177.         $this->orderRepository $orderRepository;
  178.     }
  179.     /**
  180.      * 商品一覧画面.
  181.      *
  182.      * @Route("/products/list", name="product_list", methods={"GET", "POST"})
  183.      * @Template("Product/list.twig")
  184.      */
  185.     public function index(Request $requestPaginatorInterface $paginator)
  186.     {
  187.         // Doctrine SQLFilter
  188.         if ($this->BaseInfo->isOptionNostockHidden()) {
  189.             $this->entityManager->getFilters()->enable('option_nostock_hidden');
  190.         }
  191.         // handleRequestは空のqueryの場合は無視するため
  192.         if ($request->getMethod() === 'GET') {
  193.             $request->query->set('pageno'$request->query->get('pageno'''));
  194.         }
  195.         // searchForm
  196.         /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  197.         $builder $this->formFactory->createNamedBuilder(''SearchProductType::class);
  198.         if ($request->getMethod() === 'GET') {
  199.             $builder->setMethod('GET');
  200.         }
  201.         $event = new EventArgs(
  202.             [
  203.                 'builder' => $builder,
  204.             ],
  205.             $request
  206.         );
  207.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_INDEX_INITIALIZE);
  208.         /* @var $searchForm \Symfony\Component\Form\FormInterface */
  209.         $searchForm $builder->getForm();
  210.         $searchForm->handleRequest($request);
  211.         // paginator
  212.         $searchData $searchForm->getData();
  213.         $Customer $this->userService->getCurrentUser();
  214.         $brother_id $request->get('brother_id''');
  215.         if (!empty($brother_id)) {
  216.             $Brother $this->brotherRepository->find($brother_id);
  217.             if ($Brother) {
  218.                 $Customer $Brother->getCustomer();
  219.             }
  220.         }
  221.         // default sex filtering: only apply when customer's sex id is 1 or 2
  222.         $School $Customer->getSchool();
  223.         
  224.         // 学校がNULLの場合はログイン画面に遷移
  225.         if ($School === null) {
  226.             $this->addWarning('学校情報が設定されていません。ログインしてください。');
  227.             return $this->redirectToRoute('mypage_login');
  228.         }
  229.         $temporaryOrder false;
  230.         if (is_object($Customer) && !$this->session->get('update_temporary_order_id')) {
  231.             if ($School) {
  232.                 $this->session->set('storeMeasuringFlag'$School->getStoreMeasuringFlag());
  233.                 $this->session->set('schoolMeasuringFlag'$School->getSchoolMeasuringFlag());
  234.                 $this->session->set('onlineFlag'$School->getOnlineFlag());
  235.                 if ($School->getOnlineFlag() == 0) {
  236.                     $temporaryOrder true;
  237.                 } else {
  238.                     $temporaryOrder false;
  239.                 }
  240.             }
  241.         }
  242.         $searchData['school_id'] = $request->get('s');
  243.         
  244.         // 絞り込み条件のパラメータを取得
  245.         $genderType $request->get('gender_type');
  246.         $commodityType $request->get('commodity_type');
  247.         $setCommodityType $request->get('set_commodity_type');
  248.         $setGenderType $request->get('set_gender_type');
  249.         
  250.         // すべての絞り込み条件が未選択かどうかをチェック
  251.         $noFilterSelected = empty($genderType) && empty($commodityType) && 
  252.                            empty($setCommodityType) && empty($setGenderType);
  253.         
  254.         // デフォルト性別絞り込みの適用(すべての絞り込み条件が未選択の場合のみ)
  255.         if ($noFilterSelected && $School && $School->getDefaultSexProductsFilteringFlag() == && ($sexObj $Customer->getSex())) {
  256.             $sexId $sexObj->getId();
  257.             // 性別が男子(1)または女子(2)の場合のみ適用(なし(0)と共通(3)は無視)
  258.             if ($sexId === || $sexId === 2) {
  259.                 // デフォルト値を設定(単品・セットの男女別と入学時の必要品すべて)
  260.                 $genderType = [$sexId];
  261.                 $setGenderType = [$sexId];
  262.                 $commodityType = [$sexId];
  263.                 $setCommodityType = [$sexId];
  264.             }
  265.         }
  266.         
  267.         // gender_type の処理(単一値または配列)
  268.         if (is_array($genderType)) {
  269.             $searchData['gender_type'] = $genderType;
  270.         } elseif ($genderType) {
  271.             $searchData['gender_type'] = [$genderType];
  272.         }
  273.         
  274.         // commodity_type の処理(単一値または配列)
  275.         if (is_array($commodityType)) {
  276.             $searchData['commodity_type'] = $commodityType;
  277.         } elseif ($commodityType) {
  278.             $searchData['commodity_type'] = [$commodityType];
  279.         }
  280.         // セット商品用の commodity_type の処理
  281.         if (is_array($setCommodityType)) {
  282.             $searchData['set_commodity_type'] = $setCommodityType;
  283.         } elseif ($setCommodityType) {
  284.             $searchData['set_commodity_type'] = [$setCommodityType];
  285.         }
  286.         // セット商品用の gender_type の処理
  287.         if (is_array($setGenderType)) {
  288.             $searchData['set_gender_type'] = $setGenderType;
  289.         } elseif ($setGenderType) {
  290.             $searchData['set_gender_type'] = [$setGenderType];
  291.         }
  292.         $qb $this->productRepository->getQueryBuilderBySearchData($searchData);
  293.         $event = new EventArgs(
  294.             [
  295.                 'searchData' => $searchData,
  296.                 'qb' => $qb,
  297.             ],
  298.             $request
  299.         );
  300.         // $this->eventDispatcher->dispatch($event, EccubeEvents::FRONT_PRODUCT_INDEX_SEARCH);
  301.         $searchData $event->getArgument('searchData');
  302.         $query $qb->getQuery()
  303.             ->useResultCache(true$this->eccubeConfig['eccube_result_cache_lifetime_short']);
  304.         /** @var SlidingPagination $pagination */
  305.         if ($School && $School->getItemVisibleType() == School::ITEM_VISIBLE_TYPE_MATOME) {
  306.             $limit 1000000;
  307.         } else {
  308.             $limit = !empty($searchData['disp_number']) ? $searchData['disp_number']->getId() : $this->productListMaxRepository->findOneBy([], ['sort_no' => 'ASC'])->getId();
  309.         }
  310.         $pagination $paginator->paginate(
  311.             $query,
  312.             !empty($searchData['pageno']) ? $searchData['pageno'] : 1,
  313.             $limit,
  314.             array('wrap-queries' => true)
  315.         );
  316.         // 絞り込み条件なしの状態でセット商品が存在するかチェック
  317.         $hasSetProductsTotal false;
  318.         $qbTotal $this->productRepository->getQueryBuilderBySearchData(['school_id' => $searchData['school_id']]);
  319.         $qbTotal->select('COUNT(DISTINCT p.id)')
  320.             ->andWhere("p.product_type = 'set'")
  321.             ->setMaxResults(1);
  322.         $setProductCountTotal $qbTotal->getQuery()->getSingleScalarResult();
  323.         if ($setProductCountTotal 0) {
  324.             $hasSetProductsTotal true;
  325.         }
  326.         
  327.         // 検索結果全体でセット商品が存在するかチェック(絞り込み後)
  328.         $hasSetProducts false;
  329.         $qbCheck = clone $qb;
  330.         $qbCheck->select('COUNT(DISTINCT p.id)')
  331.             ->andWhere("p.product_type = 'set'")
  332.             ->setMaxResults(1);
  333.         $setProductCount $qbCheck->getQuery()->getSingleScalarResult();
  334.         if ($setProductCount 0) {
  335.             $hasSetProducts true;
  336.         }
  337.         $ids = [];
  338.         foreach ($pagination as $Product) {
  339.             $ids[] = $Product->getId();
  340.         }
  341.         $ProductsAndClassCategories $this->productRepository->findProductsWithSortedClassCategories($ids'p.id');
  342.         // addCart form
  343.         $forms = [];
  344.         $ProductInSets = [];
  345.         foreach ($pagination as $index => $Product) {
  346.             /* @var $builder \Symfony\Component\Form\FormBuilderInterface */
  347.             $builder $this->formFactory->createNamedBuilder(
  348.                 '',
  349.                 AddCartType::class,
  350.                 null,
  351.                 [
  352.                     'product' => $ProductsAndClassCategories[$Product->getId()],
  353.                     'allow_extra_fields' => true,
  354.                 ]
  355.             );
  356.             $addCartForm $builder->getForm();
  357.             $forms[$Product->getId()] = $addCartForm->createView();
  358.             $product_ids[$index] = $Product->getId();
  359.             if ($Product->getProductType() == 'set') {
  360.                 $ProductInSets[$Product->getId()] = [];
  361.                 $setProduct $Product->getSetProduct();
  362.                 if ($setProduct) {
  363.                     $pis_all $setProduct->getSetProductProduct();
  364.                     foreach ($pis_all as $pis) {
  365.                         if (!in_array($pis->getProduct(), $ProductInSets[$Product->getId()])) {
  366.                             array_push($ProductInSets[$Product->getId()], $pis->getProduct());
  367.                         }
  368.                     }
  369.                 }
  370.             }
  371.         }
  372.         // 表示件数
  373.         $builder $this->formFactory->createNamedBuilder(
  374.             'disp_number',
  375.             ProductListMaxType::class,
  376.             null,
  377.             [
  378.                 'required' => false,
  379.                 'allow_extra_fields' => true,
  380.             ]
  381.         );
  382.         if ($request->getMethod() === 'GET') {
  383.             $builder->setMethod('GET');
  384.         }
  385.         $event = new EventArgs(
  386.             [
  387.                 'builder' => $builder,
  388.             ],
  389.             $request
  390.         );
  391.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_INDEX_DISP);
  392.         $dispNumberForm $builder->getForm();
  393.         $dispNumberForm->handleRequest($request);
  394.         // ソート順
  395.         $builder $this->formFactory->createNamedBuilder(
  396.             'orderby',
  397.             ProductListOrderByType::class,
  398.             null,
  399.             [
  400.                 'required' => false,
  401.                 'allow_extra_fields' => true,
  402.             ]
  403.         );
  404.         if ($request->getMethod() === 'GET') {
  405.             $builder->setMethod('GET');
  406.         }
  407.         $event = new EventArgs(
  408.             [
  409.                 'builder' => $builder,
  410.             ],
  411.             $request
  412.         );
  413.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_INDEX_ORDER);
  414.         $orderByForm $builder->getForm();
  415.         $orderByForm->handleRequest($request);
  416.         $Category $searchForm->get('category_id')->getData();
  417.         //まとめて購入処理 >>>
  418.         $builder $this->formFactory->createNamedBuilder(
  419.             '',
  420.             MatomeCartType::class,
  421.             null,
  422.             [
  423.                 'products' => $pagination,
  424.                 'ProductInSets' => $ProductInSets,
  425.                 'allow_extra_fields' => true,
  426.             ]
  427.         );
  428.         /* @var $searchForm \Symfony\Component\Form\FormInterface */
  429.         $matomeForm $builder->getForm();
  430.         $matomeForm->handleRequest($request);
  431.         $back $request->get('back'false);
  432.         $refresh $this->session->get('refresh'true);
  433.         if ($back && $request->getMethod() == "GET" && !$refresh) {
  434.             $old_matomete_items $this->session->get('matomeItems');
  435.             foreach ($old_matomete_items as $product_class_id => $omi) {
  436.                 $old_product_class $this->productClassRepository->find($product_class_id);
  437.                 if (isset($omi['set_product_class']['class_list'])) {
  438.                     // 兄弟情報を復元(IDからBrotherエンティティを取得)
  439.                     $brother null;
  440.                     if (isset($omi['brother']) && $omi['brother']) {
  441.                         $brother $this->brotherRepository->find($omi['brother']);
  442.                     }
  443.                     $this->cartService->addProduct($old_product_class, -abs($omi['quantity']), $omi['set_product_class']['class_list'], null$brother);
  444.                 }
  445.             }
  446.             $Carts $this->cartService->getCarts();
  447.             foreach ($Carts as $Cart) {
  448.                 $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->userService->getCurrentUser()));
  449.                 // 復旧不可のエラーが発生した場合は追加した明細を削除.
  450.                 if ($result->hasError()) {
  451.                     foreach ($old_matomete_items as $product_class_id => $omi) {
  452.                         if (!empty($omi['quantity'])) {
  453.                             $this->cartService->removeProduct($omi['product_class_id']);
  454.                         }
  455.                     }
  456.                     foreach ($result->getErrors() as $error) {
  457.                         $errorMessages[] = $error->getMessage();
  458.                     }
  459.                 }
  460.                 foreach ($result->getWarning() as $warning) {
  461.                     $errorMessages[] = $warning->getMessage();
  462.                 }
  463.             }
  464.             $this->cartService->save();
  465.             $refresh $this->session->set('refresh'true);
  466.         }
  467.         if ($matomeForm->isSubmitted() && $matomeForm->isValid()) {
  468.             $data $matomeForm->getData();
  469.             
  470.             // デバッグ: データ構造を確認
  471.             log_info('MatomeForm データ構造', [
  472.                 'data_keys' => array_keys($data),
  473.                 'first_item_type' => count($data) > gettype(reset($data)) : 'empty',
  474.             ]);
  475.             
  476.             if (count($data) > 0) {
  477.                 $firstItem reset($data);
  478.                 if (is_array($firstItem) && count($firstItem) > 0) {
  479.                     $firstCartItem reset($firstItem);
  480.                     log_info('First CartItem', [
  481.                         'is_object' => is_object($firstCartItem),
  482.                         'type' => gettype($firstCartItem),
  483.                         'class' => is_object($firstCartItem) ? get_class($firstCartItem) : 'not_object',
  484.                         'has_brother' => is_object($firstCartItem) && method_exists($firstCartItem'getBrother'),
  485.                         'brother_value' => is_object($firstCartItem) && method_exists($firstCartItem'getBrother'
  486.                             ? ($firstCartItem->getBrother() ? get_class($firstCartItem->getBrother()) : 'null')
  487.                             : 'not_accessible',
  488.                     ]);
  489.                 }
  490.             }
  491.             
  492.             $isValid false;
  493.             foreach ($data as $item) {
  494.                 foreach ($item as $cart_item) {
  495.                     // CartItemオブジェクトの場合
  496.                     if (is_object($cart_item) && method_exists($cart_item'getQuantity')) {
  497.                         if (!empty($cart_item->getQuantity())) {
  498.                             $isValid true;
  499.                         }
  500.                     } elseif (!empty($cart_item['quantity'])) {
  501.                         $isValid true;
  502.                     }
  503.                 }
  504.             }
  505.             if ($isValid) {
  506.                 $mData = [];
  507.                 //Go Shopping
  508.                 foreach ($data as $itemKey => $item) {
  509.                     foreach ($item as $cart_index => $cart_item) {
  510.                         $quantity is_object($cart_item) && method_exists($cart_item'getQuantity'
  511.                             ? $cart_item->getQuantity() 
  512.                             : ($cart_item['quantity'] ?? 0);
  513.                         
  514.                         if (!empty($quantity)) {
  515.                             $cartProduct $request->get($itemKey)[$cart_index];
  516.                             $setProductClass = [];
  517.                             foreach ($cartProduct as $attrKey => $attr) {
  518.                                 if (!empty($attr['ProductClass'])) {
  519.                                     $setProductClass[] = $attr['ProductClass'];
  520.                                 }
  521.                             }
  522.                             
  523.                             // 兄弟情報を取得(CartItemオブジェクトから)
  524.                             $brother null;
  525.                             if (is_object($cart_item) && method_exists($cart_item'getBrother')) {
  526.                                 $brother $cart_item->getBrother();
  527.                             } elseif (isset($cart_item['brother'])) {
  528.                                 $brother $cart_item['brother'];
  529.                             }
  530.                             
  531.                             // ProductClassIDを取得
  532.                             $productClassId is_object($cart_item) && method_exists($cart_item'getProductClass')
  533.                                 ? ($cart_item->getProductClass() ? $cart_item->getProductClass()->getId() : null)
  534.                                 : ($cart_item['product_class_id'] ?? null);
  535.                             
  536.                             // 備考を取得
  537.                             $remarks is_object($cart_item) && method_exists($cart_item'getRemarks')
  538.                                 ? $cart_item->getRemarks()
  539.                                 : ($cart_item['remarks'] ?? '');
  540.                             
  541.                             $this->cartService->addProduct($productClassId$quantity$setProductClass$remarks$brother);
  542.                             $mItem = [];
  543.                             $mItem['quantity'] = $quantity;
  544.                             $mItem['set_product_class'] = [];
  545.                             foreach ($setProductClass as $spc) {
  546.                                 $spc_class $this->productClassRepository->find($spc);
  547.                                 $productInSet $spc_class->getProduct();
  548.                                 if ($spc_class && $productInSet) {
  549.                                     $spc_class_category1 $spc_class->getClassCategory1();
  550.                                     $class_cat_tmp = [];
  551.                                     if ($spc_class_category1) {
  552.                                         $class_cat_tmp['class_category1_id'] =  $spc_class_category1->getId();
  553.                                     }
  554.                                     $spc_class_category2 $spc_class->getClassCategory2();
  555.                                     if ($spc_class_category2) {
  556.                                         $class_cat_tmp['class_category2_id'] =  $spc_class_category2->getId();
  557.                                     }
  558.                                     $mItem['set_product_class'][$productInSet->getId()] = $class_cat_tmp;
  559.                                     $class_cat_tmp['product_class_id'] = $spc;
  560.                                     $mItem['set_product_class'][$productInSet->getId()] = $class_cat_tmp;
  561.                                 }
  562.                             }
  563.                             $mItem['set_product_class']['class_list'] = $setProductClass;
  564.                             $mItem['remarks'] = $remarks;
  565.                             // 兄弟情報を保存(Brotherオブジェクトの場合はIDを保存)
  566.                             if ($brother) {
  567.                                 $mItem['brother'] = is_object($brother) ? $brother->getId() : $brother;
  568.                             } else {
  569.                                 $mItem['brother'] = null;
  570.                             }
  571.                             $productClass $this->productClassRepository->find($productClassId);
  572.                             if ($productClass) {
  573.                                 $product_class_category1 $productClass->getClassCategory1();
  574.                                 if ($product_class_category1) {
  575.                                     $mItem['class_category1_id'] =  $product_class_category1->getId();
  576.                                 }
  577.                                 $product_class_category2 $productClass->getClassCategory2();
  578.                                 if ($product_class_category2) {
  579.                                     $mItem['class_category2_id'] =  $product_class_category2->getId();
  580.                                 }
  581.                             }
  582.                             $mData[$productClassId] = $mItem;
  583.                         }
  584.                     }
  585.                 }
  586.                 // 明細の正規化
  587.                 $Carts $this->cartService->getCarts();
  588.                 foreach ($Carts as $Cart) {
  589.                     $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->userService->getCurrentUser()));
  590.                     // 復旧不可のエラーが発生した場合は追加した明細を削除.
  591.                     if ($result->hasError()) {
  592.                         foreach ($data as $item) {
  593.                             foreach ($item as $cart_item) {
  594.                                 $productClassId is_object($cart_item) && method_exists($cart_item'getProductClass')
  595.                                     ? ($cart_item->getProductClass() ? $cart_item->getProductClass()->getId() : null)
  596.                                     : ($cart_item['product_class_id'] ?? null);
  597.                                 $quantity is_object($cart_item) && method_exists($cart_item'getQuantity'
  598.                                     ? $cart_item->getQuantity() 
  599.                                     : ($cart_item['quantity'] ?? 0);
  600.                                     
  601.                                 if (!empty($quantity) && $productClassId) {
  602.                                     $this->cartService->removeProduct($productClassId);
  603.                                 }
  604.                             }
  605.                         }
  606.                         foreach ($result->getErrors() as $error) {
  607.                             $errorMessages[] = $error->getMessage();
  608.                         }
  609.                     }
  610.                     foreach ($result->getWarning() as $warning) {
  611.                         $errorMessages[] = $warning->getMessage();
  612.                     }
  613.                 }
  614.                 $this->cartService->save();
  615.                 if (empty($errorMessages)) {
  616.                     if ($temporaryOrder) {
  617.                         $this->session->set('matomeItems'$mData);
  618.                         $this->session->set('refresh'false);
  619.                         return $this->redirectToRoute('shopping_temporary');
  620.                     } else
  621.                         return $this->redirectToRoute('shopping');
  622.                 }
  623.             }
  624.         }
  625.         //<<<
  626.         return [
  627.             'matomeForm' => $matomeForm->createView(),  //まとめ購入用
  628.             'ProductInSets' => $ProductInSets,          //まとめ購入用
  629.             'subtitle' => $this->getPageTitle($searchData),
  630.             'pagination' => $pagination,
  631.             'search_form' => $searchForm->createView(),
  632.             'disp_number_form' => $dispNumberForm->createView(),
  633.             'order_by_form' => $orderByForm->createView(),
  634.             'forms' => $forms,
  635.             'Category' => $Category,
  636.             'School' => $School,
  637.             'product_type' => isset($searchData['product_type']) ? $searchData['product_type'] : null,
  638.             'matomeItems' => $this->session->get('matomeItems'),
  639.             'back' => $back,
  640.             'FilterSchool' => $request->get('s') ? $this->schoolRepository->findActiveSchool($request->get('s')) : null,
  641.             'hasSetProducts' => $hasSetProducts,
  642.             'hasSetProductsTotal' => $hasSetProductsTotal,
  643.             'searchData' => $searchData
  644.         ];
  645.     }
  646.     /**
  647.      * 商品詳細画面.
  648.      *
  649.      * @Route("/products/detail/{id}", name="product_detail", methods={"GET"}, requirements={"id" = "\d+"})
  650.      * @Template("Product/detail.twig")
  651.      *
  652.      * @param Request $request
  653.      * @param Product $Product
  654.      *
  655.      * @return array
  656.      */
  657.     public function detail(Request $request$id)
  658.     {
  659.         $Product $this->productRepository->findWithSortedClassCategories($id);
  660.         if (!$this->checkVisibility($Product)) {
  661.             throw new NotFoundHttpException();
  662.         }
  663.         $builder $this->formFactory->createNamedBuilder(
  664.             '',
  665.             AddCartType::class,
  666.             null,
  667.             [
  668.                 'product' => $Product,
  669.                 'id_add_product_id' => false,
  670.             ]
  671.         );
  672.         $event = new EventArgs(
  673.             [
  674.                 'builder' => $builder,
  675.                 'Product' => $Product,
  676.             ],
  677.             $request
  678.         );
  679.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_DETAIL_INITIALIZE);
  680.         $Customer $this->userService->getCurrentUser();
  681.         $School $Customer->getSchool();
  682.         
  683.         // 学校がNULLの場合はログイン画面に遷移
  684.         if ($School === null) {
  685.             $this->addWarning('学校情報が設定されていません。ログインしてください。');
  686.             return $this->redirectToRoute('mypage_login');
  687.         }
  688.         $is_favorite false;
  689.         if ($this->isGranted('ROLE_USER')) {
  690.             $is_favorite $this->customerFavoriteProductRepository->isFavorite($Customer$Product);
  691.         }
  692.         $Place = [
  693.             => '肩幅',
  694.             => '袖丈',
  695.             => '裄丈',
  696.             => '総丈',
  697.             => '首回り',
  698.             11 => 'バスト',
  699.             12 => 'ウェスト',
  700.             13 => 'ヒップ',
  701.             21 => '股下',
  702.             22 => 'スカート丈',
  703.             31 => '身長',
  704.             32 => '体重',
  705.         ];
  706.         $RecommendSize = [];
  707.         $xValue 0;
  708.         $yValue 0;
  709.         $Recommend $Product->getRecommend();
  710.         if (!$Recommend) {
  711.             //学校ID->オススメサイズを取得する
  712.             $Recommend $this->productSchoolRepository->getRecommend($Product);
  713.         }
  714.         if ($Recommend) {
  715.             $Recommend->getRecommendXplace();
  716.             $xKey 'getDr' sprintf('%02d'$Recommend->getRecommendXplace());
  717.             $yKey 'getDr' sprintf('%02d'$Recommend->getRecommendYplace());
  718.             $Customer $this->userService->getCurrentUser();
  719.             $xValue 0;
  720.             $yValue 0;
  721.             if (method_exists($Customer$xKey)) $xValue $Customer->$xKey();
  722.             if (method_exists($Customer$yKey)) $yValue $Customer->$yKey();
  723.             $RecommendX $this->recommendXRepository->searchOne($Recommend$xValue);
  724.             $RecommendY $this->recommendYRepository->searchOne($Recommend$yValue);
  725.             if ($RecommendX && $RecommendY)
  726.                 $RecommendSize $this->recommendSizeRepository->searchOne($Recommend$RecommendX[0], $RecommendY[0]);
  727.         }
  728.         $ProductInSet = [];
  729.         if ($Product->isSetProduct()) {
  730.             $pis_all $this->setProductRepository->findOneBy(['set_product_id' => $Product->getSetProductId()])->getSetProductProduct();
  731.             foreach ($pis_all as $pis) {
  732.                 array_push($ProductInSet$this->productRepository->findWithSortedClassCategories($pis->getProduct()->getId()));
  733.             }
  734.         }
  735.         // 販売期間チェック
  736.         $salesPeriodStatus $this->checkSalesPeriod($Product);
  737.         return [
  738.             'title' => $this->title,
  739.             'subtitle' => $Product->getName(),
  740.             'form' => $builder->getForm()->createView(),
  741.             'Product' => $Product,
  742.             'is_favorite' => $is_favorite,
  743.             'RecommendSize' => $RecommendSize,
  744.             'Place' => $Place,
  745.             'x' => $xValue,
  746.             'y' => $yValue,
  747.             'ProductInSet' => $ProductInSet,
  748.             'SetProduct' => $Product->isSetProduct() ? $this->setProductRepository->findOneBy(['set_product_id' => $Product->getSetProductId()]) : null,
  749.             'sales_period_status' => $salesPeriodStatus
  750.         ];
  751.     }
  752.     /**
  753.      * お気に入り追加.
  754.      *
  755.      * @Route("/products/add_favorite/{id}", name="product_add_favorite", requirements={"id" = "\d+"}, methods={"GET", "POST"})
  756.      */
  757.     public function addFavorite(Request $requestProduct $Product)
  758.     {
  759.         $this->checkVisibility($Product);
  760.         $event = new EventArgs(
  761.             [
  762.                 'Product' => $Product,
  763.             ],
  764.             $request
  765.         );
  766.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_INITIALIZE);
  767.         if ($this->isGranted('ROLE_USER')) {
  768.             $Customer $this->userService->getCurrentUser();
  769.             $this->customerFavoriteProductRepository->addFavorite($Customer$Product);
  770.             $this->session->getFlashBag()->set('product_detail.just_added_favorite'$Product->getId());
  771.             $event = new EventArgs(
  772.                 [
  773.                     'Product' => $Product,
  774.                 ],
  775.                 $request
  776.             );
  777.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE);
  778.             return $this->redirectToRoute('product_detail', ['id' => $Product->getId()]);
  779.         } else {
  780.             // 非会員の場合、ログイン画面を表示
  781.             //  ログイン後の画面遷移先を設定
  782.             $this->setLoginTargetPath($this->generateUrl('product_add_favorite', ['id' => $Product->getId()], UrlGeneratorInterface::ABSOLUTE_URL));
  783.             $this->session->getFlashBag()->set('eccube.add.favorite'true);
  784.             $event = new EventArgs(
  785.                 [
  786.                     'Product' => $Product,
  787.                 ],
  788.                 $request
  789.             );
  790.             $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_FAVORITE_ADD_COMPLETE);
  791.             return $this->redirectToRoute('mypage_login');
  792.         }
  793.     }
  794.     /**
  795.      * カートに追加.
  796.      *
  797.      * @Route("/products/add_cart/{id}", name="product_add_cart", methods={"POST"}, requirements={"id" = "\d+"})
  798.      */
  799.     public function addCart(Request $requestProduct $Product)
  800.     {
  801.         // エラーメッセージの配列
  802.         $errorMessages = [];
  803.         if (!$this->checkVisibility($Product)) {
  804.             throw new NotFoundHttpException();
  805.         }
  806.         $builder $this->formFactory->createNamedBuilder(
  807.             '',
  808.             AddCartType::class,
  809.             null,
  810.             [
  811.                 'product' => $Product,
  812.                 'id_add_product_id' => false,
  813.             ]
  814.         );
  815.         $event = new EventArgs(
  816.             [
  817.                 'builder' => $builder,
  818.                 'Product' => $Product,
  819.             ],
  820.             $request
  821.         );
  822.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_CART_ADD_INITIALIZE);
  823.         // 販売期間チェック
  824.         $salesPeriodStatus $this->checkSalesPeriod($Product);
  825.         if ($salesPeriodStatus['is_sales_period_enabled'] && !$salesPeriodStatus['is_within_period']) {
  826.             if ($request->isXmlHttpRequest()) {
  827.                 return $this->json(['done' => false'messages' => [$salesPeriodStatus['message']]]);
  828.             } else {
  829.                 $this->addRequestError($salesPeriodStatus['message']);
  830.                 return $this->redirectToRoute('product_detail', ['id' => $Product->getId()]);
  831.             }
  832.         }
  833.         /* @var $form \Symfony\Component\Form\FormInterface */
  834.         $form $builder->getForm();
  835.         $form->handleRequest($request);
  836.         
  837.         // Brother情報を取得
  838.         $brother null;
  839.         
  840.         // セット商品の場合はフォームバリデーションをスキップ
  841.         if ($Product->getProductType() == 'set') {
  842.             // セット商品の場合は特別な処理
  843.             if ($form->isSubmitted()) {
  844.                 // フォームデータからbrother情報を取得
  845.                 $cartItem $form->getData();
  846.                 if ($cartItem && $cartItem->getBrother()) {
  847.                     $brother $cartItem->getBrother();
  848.                 }
  849.                 
  850.                 // セット商品の場合、フォームバリデーションはスキップして直接データを作成
  851.                 // POSTデータは add_cart という名前ではなく、直接送られてくる
  852.                 $addCartData = [
  853.                     'product_class_id' => $request->get('ProductClass') ?? $Product->getProductClasses()->first()->getId(),
  854.                     'quantity' => (int)$request->get('quantity'1),
  855.                 ];
  856.             } else {
  857.                 throw new NotFoundHttpException();
  858.             }
  859.         } else {
  860.             // 通常商品の場合はフォームバリデーションを実行
  861.             if (!$form->isValid()) {
  862.                 throw new NotFoundHttpException();
  863.             }
  864.             
  865.             if ($form->isSubmitted() && !$form->isValid()) {
  866.                 throw new \Exception('Invalid form data');
  867.             }
  868.             $addCartData $form->getData();
  869.             
  870.             // 通常商品のbrother情報を取得
  871.             if ($addCartData instanceof CartItem && $addCartData->getBrother()) {
  872.                 $brother $addCartData->getBrother();
  873.             }
  874.         }
  875.         
  876.         // 購入点数制限の事前チェック
  877.         $purchaseLimit null;
  878.         $purchaseLimitChecked false;
  879.         $requestQuantity $addCartData['quantity'];
  880.         $allowedQuantity $requestQuantity;
  881.         $partialAddMessage null// 一部追加時のメッセージ
  882.         
  883.         // セット商品の購入制限チェック
  884.         if ($Product->isSetProduct()) {
  885.             $SetProduct $this->setProductRepository->findOneBy(['set_product_id' => $Product->getSetProductId()]);
  886.             $purchaseLimit $SetProduct $SetProduct->getPurchaseLimit() : null;
  887.             $purchaseLimitChecked true;
  888.         } else {
  889.             // 単品商品の購入点数制限のチェック
  890.             $purchaseLimit $Product->getPurchaseLimit();
  891.             $purchaseLimitChecked true;
  892.         }
  893.         
  894.         if ($purchaseLimit && $purchaseLimit 0) {
  895.             // ログインユーザーを取得
  896.             $Customer $this->userService->getCurrentUser();
  897.             
  898.             // 過去の購入数量を取得(ログインユーザーのみ)
  899.             $purchasedQuantity 0;
  900.             if ($Customer) {
  901.                 $purchasedQuantity $this->orderRepository->getPurchasedQuantityByProduct(
  902.                     $Customer,
  903.                     $Product->getId()
  904.                 );
  905.             }
  906.             
  907.             // カート内の既存数量を取得(商品単位で集計)
  908.             $cartQuantity 0;
  909.             $Carts $this->cartService->getCarts();
  910.             foreach ($Carts as $Cart) {
  911.                 foreach ($Cart->getCartItems() as $CartItem) {
  912.                     $ProductClass $CartItem->getProductClass();
  913.                     if ($ProductClass && $ProductClass->getProduct() && 
  914.                         $ProductClass->getProduct()->getId() === $Product->getId()) {
  915.                         $cartQuantity += $CartItem->getQuantity();
  916.                     }
  917.                 }
  918.             }
  919.             
  920.             // 追加可能な数量を計算
  921.             $currentTotal $purchasedQuantity $cartQuantity;
  922.             $allowedQuantity max(0$purchaseLimit $currentTotal);
  923.             
  924.             if ($allowedQuantity <= 0) {
  925.                 // 全く追加できない場合
  926.                 $errorMessages[] = sprintf(
  927.                     'この商品は1人%d点までの購入制限があります。すでに購入制限に達しているため、カートに追加できません。(カート内:%d点、過去購入:%d点)',
  928.                     $purchaseLimit,
  929.                     $cartQuantity,
  930.                     $purchasedQuantity
  931.                 );
  932.                 
  933.                 // カートに追加しない
  934.                 $allowedQuantity 0;
  935.             } elseif ($allowedQuantity $requestQuantity) {
  936.                 // 一部のみ追加できる場合
  937.                 $partialAddMessage sprintf(
  938.                     'この商品は1人%d点までの購入制限があります。%d点のご希望でしたが、%d点のみカートに追加しました。(カート内:%d点、過去購入:%d点)',
  939.                     $purchaseLimit,
  940.                     $requestQuantity,
  941.                     $allowedQuantity,
  942.                     $cartQuantity,
  943.                     $purchasedQuantity
  944.                 );
  945.             }
  946.         }
  947.         
  948.         // カートへ追加(許可された数量のみ)
  949.         $actuallyAdded false;
  950.         if ($allowedQuantity 0) {
  951.             $this->cartService->addProduct($addCartData['product_class_id'], $allowedQuantity$request->get('SetProductClass', []), null$brother);
  952.             $actuallyAdded true;
  953.         }
  954.         // 明細の正規化
  955.         $Carts $this->cartService->getCarts();
  956.         foreach ($Carts as $Cart) {
  957.             $result $this->purchaseFlow->validate($Cart, new PurchaseContext($Cart$this->userService->getCurrentUser()));
  958.             // 復旧不可のエラーが発生した場合は追加した明細を削除(実際に追加した場合のみ)
  959.             if ($result->hasError()) {
  960.                 // 実際にカートに追加した場合のみ、追加分を削除する
  961.                 if ($actuallyAdded) {
  962.                     $this->cartService->removeProduct($addCartData['product_class_id']);
  963.                 }
  964.                 foreach ($result->getErrors() as $error) {
  965.                     $errorMessages[] = $error->getMessage();
  966.                 }
  967.             }
  968.             foreach ($result->getWarning() as $warning) {
  969.                 $errorMessages[] = $warning->getMessage();
  970.             }
  971.         }
  972.         $this->cartService->save();
  973.         $event = new EventArgs(
  974.             [
  975.                 'form' => $form,
  976.                 'Product' => $Product,
  977.             ],
  978.             $request
  979.         );
  980.         $this->eventDispatcher->dispatch($eventEccubeEvents::FRONT_PRODUCT_CART_ADD_COMPLETE);
  981.         if ($event->getResponse() !== null) {
  982.             return $event->getResponse();
  983.         }
  984.         if ($request->isXmlHttpRequest()) {
  985.             // ajaxでのリクエストの場合は結果をjson形式で返す。
  986.             // 初期化
  987.             $done null;
  988.             $messages = [];
  989.             
  990.             if (empty($errorMessages)) {
  991.                 // エラーが発生していない場合
  992.                 $done true;
  993.                 // 一部追加のメッセージがある場合はそれを表示、なければ通常の成功メッセージ
  994.                 if ($partialAddMessage) {
  995.                     array_push($messages$partialAddMessage);
  996.                 } else {
  997.                     array_push($messagestrans('front.product.add_cart_complete'));
  998.                 }
  999.             } else {
  1000.                 // エラーが発生している場合
  1001.                 $done false;
  1002.                 $messages $errorMessages;
  1003.             }
  1004.             return $this->json(['done' => $done'messages' => $messages]);
  1005.         } else {
  1006.             // ajax以外でのリクエストの場合はカート画面へリダイレクト
  1007.             foreach ($errorMessages as $errorMessage) {
  1008.                 $this->addRequestError($errorMessage);
  1009.             }
  1010.             
  1011.             // 一部追加のメッセージがある場合は警告として表示
  1012.             if ($partialAddMessage) {
  1013.                 $this->addWarning($partialAddMessage'front');
  1014.             }
  1015.             return $this->redirectToRoute('cart');
  1016.         }
  1017.     }
  1018.     /**
  1019.      * ページタイトルの設定
  1020.      *
  1021.      * @param  array|null $searchData
  1022.      *
  1023.      * @return str
  1024.      */
  1025.     protected function getPageTitle($searchData)
  1026.     {
  1027.         if (isset($searchData['name']) && !empty($searchData['name'])) {
  1028.             return trans('front.product.search_result');
  1029.         } elseif (isset($searchData['category_id']) && $searchData['category_id']) {
  1030.             return $searchData['category_id']->getName();
  1031.         } else {
  1032.             return trans('front.product.all_products');
  1033.         }
  1034.     }
  1035.     /**
  1036.      * 閲覧可能な商品かどうかを判定
  1037.      *
  1038.      * @param Product $Product
  1039.      *
  1040.      * @return boolean 閲覧可能な場合はtrue
  1041.      */
  1042.     protected function checkVisibility(Product $Product)
  1043.     {
  1044.         $is_admin $this->session->has('_security_admin');
  1045.         // 管理ユーザの場合はステータスやオプションにかかわらず閲覧可能.
  1046.         if (!$is_admin) {
  1047.             // 在庫なし商品の非表示オプションが有効な場合.
  1048.             // if ($this->BaseInfo->isOptionNostockHidden()) {
  1049.             //     if (!$Product->getStockFind()) {
  1050.             //         return false;
  1051.             //     }
  1052.             // }
  1053.             // 公開ステータスでない商品は表示しない.
  1054.             if ($Product->getStatus()->getId() !== ProductStatus::DISPLAY_SHOW) {
  1055.                 return false;
  1056.             }
  1057.         }
  1058.         return true;
  1059.     }
  1060.     /**
  1061.      * 商品の販売期間状態をチェック
  1062.      *
  1063.      * @param Product $Product
  1064.      *
  1065.      * @return array 販売期間の状態情報
  1066.      */
  1067.     protected function checkSalesPeriod(Product $Product)
  1068.     {
  1069.         $currentDate = new \DateTime();
  1070.         $status = [
  1071.             'is_sales_period_enabled' => $Product->getSalesPeriodFlg(),
  1072.             'is_within_period' => true,
  1073.             'message' => '',
  1074.             'start_date' => $Product->getSalesStartDate(),
  1075.             'end_date' => $Product->getSalesEndDate()
  1076.         ];
  1077.         // 販売期間制限が有効な場合のみチェック
  1078.         if ($Product->getSalesPeriodFlg()) {
  1079.             $isWithinPeriod true;
  1080.             $message '';
  1081.             // 公開開始日のチェック
  1082.             if ($Product->getSalesStartDate() && $Product->getSalesStartDate() > $currentDate) {
  1083.                 $isWithinPeriod false;
  1084.                 $message '公開開始日前のため、購入できません。公開開始日: ' $Product->getSalesStartDate()->format('Y年m月d日 H:i');
  1085.             }
  1086.             // 公開終了日のチェック
  1087.             elseif ($Product->getSalesEndDate() && $Product->getSalesEndDate() < $currentDate) {
  1088.                 $isWithinPeriod false;
  1089.                 $message '公開期間が終了しているため、購入できません。公開終了日: ' $Product->getSalesEndDate()->format('Y年m月d日 H:i');
  1090.             }
  1091.             $status['is_within_period'] = $isWithinPeriod;
  1092.             $status['message'] = $message;
  1093.         }
  1094.         return $status;
  1095.     }
  1096.     /**
  1097.      * 価格取得.
  1098.      *
  1099.      * @Route("/products/get_product_price", name="get_product_price", methods={"POST"})
  1100.      */
  1101.     public function getPriceByProductClass(Request $request)
  1102.     {
  1103.         $product_class_id $request->get('product_class_id'null);
  1104.         $done false;
  1105.         if ($product_class_id) {
  1106.             $done true;
  1107.             $ProductClass $this->productClassRepository->find($product_class_id);
  1108.             $Customer $this->userService->getCurrentUser();
  1109.             $school $Customer $Customer->getSchool() : null;
  1110.             if ($school && $school->isOnSale() && !empty($ProductClass->getPrice03IncTax())) {
  1111.                 return $this->json(['done' => $done'price' => $ProductClass->getPrice03IncTax()]);
  1112.             } else {
  1113.                 return $this->json(['done' => $done'price' => $ProductClass->getPrice02IncTax()]);
  1114.             }
  1115.         }
  1116.         return $this->json(['done' => false'price' => null]);
  1117.     }
  1118.     /**
  1119.      * @Route("/products/groupBySeller", name="get_product_group_by_seller", methods={"GET"})
  1120.      */
  1121.     public function getProductsGroupedBySeller()
  1122.     {
  1123.         return $this->json($this->productRepository->getProductsGroupedBySeller());
  1124.     }
  1125. }