app/Plugin/CustomerClassPrice42/Event.php line 92

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