app/Plugin/CustomerGroupPrice/EventListener/ProductOptionListener.php line 102

Open in your IDE?
  1. <?php
  2. /**
  3.  * This file is part of CustomerGroupPrice
  4.  *
  5.  * Copyright(c) Akira Kurozumi <info@a-zumi.net>
  6.  *
  7.  * https://a-zumi.net
  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 Plugin\CustomerGroupPrice\EventListener;
  13. use Doctrine\ORM\EntityManagerInterface;
  14. use Eccube\Common\EccubeConfig;
  15. use Eccube\Entity\Customer;
  16. use Eccube\Entity\Master\OrderItemType;
  17. use Eccube\Entity\OrderItem;
  18. use Eccube\Entity\ProductClass;
  19. use Eccube\Entity\Shipping;
  20. use Eccube\Event\EccubeEvents;
  21. use Eccube\Event\EventArgs;
  22. use Eccube\Repository\Master\OrderItemTypeRepository;
  23. use Eccube\Repository\OrderItemRepository;
  24. use Plugin\CustomerGroup\Security\Authorization\Voter\ProductVoter;
  25. use Plugin\CustomerGroupPrice\Service\Pricing\PriceHelper;
  26. use Plugin\CustomerGroupPrice\Utils\Pricing;
  27. use Plugin\ProductOption\Entity\OrderItemOption;
  28. use Plugin\ProductOption\Entity\OrderItemOptionCategory;
  29. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  30. use Symfony\Component\Security\Core\Security;
  31. /**
  32.  * Class ProductOptionListener
  33.  * @package Plugin\CustomerGroupPrice\EventListener
  34.  *
  35.  * 商品オプションプラグインのためどうしようもなく対応。
  36.  * お届け先を追加すると会員グループ価格がもとの価格に戻ってしまう。
  37.  * なぜかイベント内でDoctrineのイベントが発火しない。
  38.  *
  39.  */
  40. class ProductOptionListener implements EventSubscriberInterface
  41. {
  42.     use PriceHelper;
  43.     /**
  44.      * @var EccubeConfig
  45.      */
  46.     protected $eccubeConfig;
  47.     /**
  48.      * @var EntityManagerInterface
  49.      */
  50.     protected $entityManager;
  51.     /**
  52.      * @var Security
  53.      */
  54.     protected $security;
  55.     /**
  56.      * @var OrderItemRepository
  57.      */
  58.     protected $orderItemRepository;
  59.     /**
  60.      * @var OrderItemTypeRepository
  61.      */
  62.     protected $orderItemTypeRepository;
  63.     /**
  64.      * @var Pricing
  65.      */
  66.     private $pricing;
  67.     public function __construct(
  68.         EccubeConfig $eccubeConfig,
  69.         EntityManagerInterface $entityManager,
  70.         Security $security,
  71.         OrderItemRepository $orderItemRepository,
  72.         OrderItemTypeRepository $orderItemTypeRepository,
  73.         Pricing $pricing
  74.     )
  75.     {
  76.         $this->eccubeConfig $eccubeConfig;
  77.         $this->entityManager $entityManager;
  78.         $this->security $security;
  79.         $this->orderItemRepository $orderItemRepository;
  80.         $this->orderItemTypeRepository $orderItemTypeRepository;
  81.         $this->pricing $pricing;
  82.     }
  83.     public static function getSubscribedEvents()
  84.     {
  85.         return [
  86.             EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_COMPLETE => [['onHookShoppingShippingMultipleComplete', -99999]]
  87.         ];
  88.     }
  89.     public function onHookShoppingShippingMultipleComplete(EventArgs $event): void
  90.     {
  91.         $enabled $this->eccubeConfig->get('eccube.plugins.enabled');
  92.         if (false === in_array('ProductOption'$enabledtrue)) {
  93.             return;
  94.         }
  95.         $form $event->getArgument('form');
  96.         $Order $event->getArgument('Order');
  97.         if ($form->isSubmitted() && $form->isValid()) {
  98.             $data $form['shipping_multiple'];
  99.             // フォームの入力から、送り先ごとに商品の数量を集計する
  100.             $arrOrderItemTemp = [];
  101.             foreach ($data as $multiples) {
  102.                 $OrderItem $multiples->getData();
  103.                 foreach ($multiples as $items) {
  104.                     foreach ($items as $item) {
  105.                         $CustomerAddress $item['customer_address']->getData();
  106.                         $customerAddressName $CustomerAddress->getShippingMultipleDefaultName();
  107.                         $itemId $OrderItem->getProductClass()->getId() . '_' $OrderItem->getOptionSerial();
  108.                         $quantity $item['quantity']->getData();
  109.                         if (isset($arrOrderItemTemp[$customerAddressName]) && array_key_exists($itemId$arrOrderItemTemp[$customerAddressName])) {
  110.                             $arrOrderItemTemp[$customerAddressName][$itemId] = $arrOrderItemTemp[$customerAddressName][$itemId] + $quantity;
  111.                         } else {
  112.                             $arrOrderItemTemp[$customerAddressName][$itemId] = $quantity;
  113.                         }
  114.                     }
  115.                 }
  116.             }
  117.             // -- ここから先がお届け先を再生成する処理 --
  118.             // お届け先情報をすべて削除
  119.             /** @var Shipping $Shipping */
  120.             foreach ($Order->getShippings() as $Shipping) {
  121.                 foreach ($Shipping->getOrderItems() as $OrderItem) {
  122.                     $Shipping->removeOrderItem($OrderItem);
  123.                     $Order->removeOrderItem($OrderItem);
  124.                     $this->entityManager->remove($OrderItem);
  125.                 }
  126.                 $Order->removeShipping($Shipping);
  127.                 $this->entityManager->remove($Shipping);
  128.             }
  129.             // お届け先のリストを作成する
  130.             $ShippingList = [];
  131.             foreach ($data as $multiples) {
  132.                 $OrderItem $multiples->getData();
  133.                 $ProductClass $OrderItem->getProductClass();
  134.                 $Delivery $OrderItem->getShipping()->getDelivery();
  135.                 $saleTypeId $ProductClass->getSaleType()->getId();
  136.                 foreach ($multiples as $items) {
  137.                     foreach ($items as $item) {
  138.                         $CustomerAddress $item['customer_address']->getData();
  139.                         $customerAddressName $CustomerAddress->getShippingMultipleDefaultName();
  140.                         if (isset($ShippingList[$customerAddressName][$saleTypeId])) {
  141.                             continue;
  142.                         }
  143.                         $Shipping = new Shipping();
  144.                         $Shipping
  145.                             ->setOrder($Order)
  146.                             ->setFromCustomerAddress($CustomerAddress)
  147.                             ->setDelivery($Delivery);
  148.                         $Order->addShipping($Shipping);
  149.                         $ShippingList[$customerAddressName][$saleTypeId] = $Shipping;
  150.                     }
  151.                 }
  152.             }
  153.             // お届け先のリストを保存
  154.             foreach ($ShippingList as $ShippingListByAddress) {
  155.                 foreach ($ShippingListByAddress as $Shipping) {
  156.                     $this->entityManager->persist($Shipping);
  157.                 }
  158.             }
  159.             $ProductOrderType $this->orderItemTypeRepository->find(OrderItemType::PRODUCT);
  160.             // お届け先に、配送商品の情報(OrderItem)を関連付ける
  161.             foreach ($data as $multiples) {
  162.                 /** @var OrderItem $OrderItem */
  163.                 $OrderItem $multiples->getData();
  164.                 $ProductClass $OrderItem->getProductClass();
  165.                 $Product $OrderItem->getProduct();
  166.                 $saleTypeId $ProductClass->getSaleType()->getId();
  167.                 $itemId $OrderItem->getProductClass()->getId() . '_' $OrderItem->getOptionSerial();
  168.                 $optionSerial $OrderItem->getOptionSerial();
  169.                 $OrderItemOptions $OrderItem->getOrderItemOptions();
  170.                 $optionPrice $OrderItem->getOptionPrice();
  171.                 $optionTax $OrderItem->getOptionTax();
  172.                 foreach ($multiples as $items) {
  173.                     foreach ($items as $item) {
  174.                         $CustomerAddress $item['customer_address']->getData();
  175.                         $customerAddressName $CustomerAddress->getShippingMultipleDefaultName();
  176.                         // お届け先から商品の数量を取得
  177.                         $quantity 0;
  178.                         if (isset($arrOrderItemTemp[$customerAddressName]) && array_key_exists($itemId$arrOrderItemTemp[$customerAddressName])) {
  179.                             $quantity $arrOrderItemTemp[$customerAddressName][$itemId];
  180.                             unset($arrOrderItemTemp[$customerAddressName][$itemId]);
  181.                         } else {
  182.                             // この配送先には送る商品がないのでスキップ(通常ありえない)
  183.                             continue;
  184.                         }
  185.                         // 関連付けるお届け先のインスタンスを取得
  186.                         $Shipping $ShippingList[$customerAddressName][$saleTypeId];
  187.                         $price02 $ProductClass->getPrice02();
  188.                         if ($this->supports($ProductClass)) {
  189.                             $price02 $this->pricing->getPrice($this->security->getToken(), $ProductClass);
  190.                         }
  191.                         // インスタンスを生成して保存
  192.                         $OrderItem = new OrderItem();
  193.                         $OrderItem->setShipping($Shipping)
  194.                             ->setOrder($Order)
  195.                             ->setProductClass($ProductClass)
  196.                             ->setProduct($Product)
  197.                             ->setProductName($Product->getName())
  198.                             ->setProductCode($ProductClass->getCode())
  199.                             ->setPrice($price02)
  200.                             ->setQuantity($quantity)
  201.                             ->setOrderItemType($ProductOrderType)
  202.                             ->setOptionSerial($optionSerial);
  203.                         $ClassCategory1 $ProductClass->getClassCategory1();
  204.                         if (!is_null($ClassCategory1)) {
  205.                             $OrderItem->setClasscategoryName1($ClassCategory1->getName());
  206.                             $OrderItem->setClassName1($ClassCategory1->getClassName()->getName());
  207.                         }
  208.                         $ClassCategory2 $ProductClass->getClassCategory2();
  209.                         if (!is_null($ClassCategory2)) {
  210.                             $OrderItem->setClasscategoryName2($ClassCategory2->getName());
  211.                             $OrderItem->setClassName2($ClassCategory2->getClassName()->getName());
  212.                         }
  213.                         foreach ($OrderItemOptions as $OrderItemOption) {
  214.                             $newOrderItemOption = new OrderItemOption();
  215.                             $newOrderItemOption->setOptionId($OrderItemOption->getOptionId())
  216.                                 ->setOrderItem($OrderItem)
  217.                                 ->setLabel($OrderItemOption->getLabel())
  218.                                 ->setSortNo($OrderItemOption->getSortNo());
  219.                             foreach ($OrderItemOption->getOrderItemOptionCategories() as $OrderItemOptionCategory) {
  220.                                 $newOrderItemOptionCategory = new OrderItemOptionCategory();
  221.                                 $newOrderItemOptionCategory->setOptionCategoryId($OrderItemOptionCategory->getOptionCategoryId())
  222.                                     ->setOrderItemOption($newOrderItemOption)
  223.                                     ->setValue($OrderItemOptionCategory->getValue())
  224.                                     ->setPrice($OrderItemOptionCategory->getPrice())
  225.                                     ->setTax($OrderItemOptionCategory->getTax())
  226.                                     ->setDeliveryFreeFlg($OrderItemOptionCategory->getDeliveryFreeFlg())
  227.                                     ->setSortNo($OrderItemOptionCategory->getSortNo());
  228.                                 $newOrderItemOption->addOrderItemOptionCategory($newOrderItemOptionCategory);
  229.                             }
  230.                             $OrderItem->addOrderItemOption($newOrderItemOption);
  231.                         }
  232.                         $OrderItem->setPrice($OrderItem->getPrice() + $optionPrice);
  233.                         $OrderItem->setTax($OrderItem->getTax() + $optionTax);
  234.                         $Shipping->addOrderItem($OrderItem);
  235.                         $Order->addOrderItem($OrderItem);
  236.                         $this->entityManager->persist($OrderItem);
  237.                     }
  238.                 }
  239.             }
  240.             $this->entityManager->flush();
  241.         }
  242.     }
  243.     public function supports(ProductClass $entity)
  244.     {
  245.         if (!$this->security->getUser() instanceof Customer) {
  246.             return false;
  247.         }
  248.         return $this->security->isGranted(ProductVoter::VIEW$entity->getProduct());
  249.     }
  250. }