- <?php
- /*
- * Plugin Name : ProductOption
- *
- * Copyright (C) BraTech Co., Ltd. All Rights Reserved.
- * http://www.bratech.co.jp/
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Plugin\ProductOption42\Event;
- use Doctrine\ORM\EntityManagerInterface;
- use Eccube\Entity\Master\OrderItemType;
- use Eccube\Entity\OrderItem;
- use Eccube\Entity\Shipping;
- use Eccube\Event\EccubeEvents;
- use Eccube\Event\EventArgs;
- use Eccube\Event\TemplateEvent;
- use Eccube\Form\Type\ShippingMultipleType;
- use Eccube\Repository\Master\OrderItemTypeRepository;
- use Plugin\ProductOption42\Entity\OrderItemOption;
- use Plugin\ProductOption42\Entity\OrderItemOptionCategory;
- use Symfony\Component\EventDispatcher\EventSubscriberInterface;
- use Symfony\Component\Form\Extension\Core\Type\CollectionType;
- class ShoppingEvent implements EventSubscriberInterface
- {
-     private $entityManager;
-     private $orderItemTypeRepository;
-     public function __construct(
-             EntityManagerInterface $entityManager,
-             OrderItemTypeRepository $orderItemTypeRepository
-             )
-     {
-         $this->entityManager = $entityManager;
-         $this->orderItemTypeRepository = $orderItemTypeRepository;
-     }
-     /**
-      * @return array
-      */
-     public static function getSubscribedEvents()
-     {
-         return [
-             'Shopping/index.twig' => 'onTempleteShoppingIndex',
-             'Shopping/confirm.twig' => 'onTempleteShoppingIndex',
-             'Shopping/shipping_multiple.twig' => 'onTempleteShoppingShippingMultiple',
-             EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_INITIALIZE => 'onHookShoppingShippingMultipleInitialize',
-             EccubeEvents::FRONT_SHOPPING_SHIPPING_MULTIPLE_COMPLETE => 'onHookShoppingShippingMultipleComplete',
-         ];
-     }
-     public function onTempleteShoppingIndex(TemplateEvent $event)
-     {
-         $source = $event->getSource();
-         if(preg_match("/\<p\>\{\{\sorderItem\.priceIncTax\|price\s\}\}/",$source, $result)){
-             $search = $result[0];
-             $replace = "{{ include('@ProductOption42/default/Shopping/orderitem_option.twig') }}" . $search;
-             $source = str_replace($search, $replace, $source);
-         }
-         $event->setSource($source);
-     }
-     public function onTempleteShoppingShippingMultiple(TemplateEvent $event)
-     {
-         $source = $event->getSource();
-         if(preg_match("/\{\%\sif\sorderItem\.productClass\.id\s\=\=\skey\s\%\}/",$source, $result)){
-             $search = $result[0];
-             $replace = "{% if orderItem.productClass.id ~ '_' ~ orderItem.option_serial == key %}";
-             $source = str_replace($search, $replace, $source);
-         }
-         if(preg_match("/\<div\sclass\=\"ec\-AddAddress\_\_itemtPrice\"\>/",$source, $result)){
-             $search = $result[0];
-             $replace = $search . "{{ include('@ProductOption42/default/Shopping/shipping_multiple_option.twig') }}";
-             $source = str_replace($search, $replace, $source);
-         }
-         $event->setSource($source);
-         $parameters = $event->getParameters();
-         $OrderItems = $parameters['OrderItems'];
-         $OrderItemsForFormBuilder = [];
-         $ItemQuantitiesByOption = [];
-         $tmpIds = [];
-         $Order = $OrderItems[0]->getOrder();
-         foreach($Order->getProductOrderItems() as $OrderItem){
-             $quantity = $OrderItem->getQuantity();
-             $itemId = $OrderItem->getProductClass()->getId();
-             $serial = $OrderItem->getOptionSerial();
-             $key = $itemId .'_'. $serial;
-             if (!in_array($key, $tmpIds)) {
-                 $OrderItemsForFormBuilder[] = $OrderItem;
-                 $tmpIds[] = $key;
-                 $ItemQuantitiesByOption[$key] = $quantity;
-             }else{
-                 $ItemQuantitiesByOption[$key] += $quantity;
-             }
-         }
-         $parameters['OrderItems'] = $OrderItemsForFormBuilder;
-         $parameters['compItemQuantities'] = $ItemQuantitiesByOption;
-         $event->setParameters($parameters);
-     }
-     public function onHookShoppingShippingMultipleInitialize(EventArgs $event)
-     {
-         $builder = $event->getArgument('builder');
-         $Order = $event->getArgument('Order');
-         $OrderItemsForFormBuilder = [];
-         $tmpIds = [];
-         foreach($Order->getProductOrderItems() as $OrderItem){
-             $itemId = $OrderItem->getProductClass()->getId();
-             $serial = $OrderItem->getOptionSerial();
-             $key = $itemId .'_'. $serial;
-             if (!in_array($key, $tmpIds)) {
-                 $OrderItemsForFormBuilder[] = $OrderItem;
-                 $tmpIds[] = $key;
-             }
-         }
-         $builder->remove('shipping_multiple');
-         $builder
-             ->add('shipping_multiple', CollectionType::class, [
-                 'entry_type' => ShippingMultipleType::class,
-                 'data' => $OrderItemsForFormBuilder,
-                 'allow_add' => true,
-                 'allow_delete' => true,
-             ]);
-     }
-     public function onHookShoppingShippingMultipleComplete(EventArgs $event)
-     {
-         $form = $event->getArgument('form');
-         $Order = $event->getArgument('Order');
-         if ($form->isSubmitted() && $form->isValid()) {
-             $data = $form['shipping_multiple'];
-             // フォームの入力から、送り先ごとに商品の数量を集計する
-             $arrOrderItemTemp = [];
-             foreach ($data as $multiples) {
-                 $OrderItem = $multiples->getData();
-                 foreach ($multiples as $items) {
-                     foreach ($items as $item) {
-                         $CustomerAddress = $item['customer_address']->getData();
-                         $customerAddressName = $CustomerAddress->getShippingMultipleDefaultName();
-                         $itemId = $OrderItem->getProductClass()->getId() . '_' . $OrderItem->getOptionSerial();
-                         $quantity = $item['quantity']->getData();
-                         if (isset($arrOrderItemTemp[$customerAddressName]) && array_key_exists($itemId, $arrOrderItemTemp[$customerAddressName])) {
-                             $arrOrderItemTemp[$customerAddressName][$itemId] = $arrOrderItemTemp[$customerAddressName][$itemId] + $quantity;
-                         } else {
-                             $arrOrderItemTemp[$customerAddressName][$itemId] = $quantity;
-                         }
-                     }
-                 }
-             }
-             // -- ここから先がお届け先を再生成する処理 --
-             // お届け先情報をすべて削除
-             /** @var Shipping $Shipping */
-             foreach ($Order->getShippings() as $Shipping) {
-                 foreach ($Shipping->getOrderItems() as $OrderItem) {
-                     $Shipping->removeOrderItem($OrderItem);
-                     $Order->removeOrderItem($OrderItem);
-                     $this->entityManager->remove($OrderItem);
-                 }
-                 $Order->removeShipping($Shipping);
-                 $this->entityManager->remove($Shipping);
-             }
-             // お届け先のリストを作成する
-             $ShippingList = [];
-             foreach ($data as $multiples) {
-                 $OrderItem = $multiples->getData();
-                 $ProductClass = $OrderItem->getProductClass();
-                 $Delivery = $OrderItem->getShipping()->getDelivery();
-                 $saleTypeId = $ProductClass->getSaleType()->getId();
-                 foreach ($multiples as $items) {
-                     foreach ($items as $item) {
-                         $CustomerAddress = $item['customer_address']->getData();
-                         $customerAddressName = $CustomerAddress->getShippingMultipleDefaultName();
-                         if (isset($ShippingList[$customerAddressName][$saleTypeId])) {
-                             continue;
-                         }
-                         $Shipping = new Shipping();
-                         $Shipping
-                             ->setOrder($Order)
-                             ->setFromCustomerAddress($CustomerAddress)
-                             ->setDelivery($Delivery);
-                         $Order->addShipping($Shipping);
-                         $ShippingList[$customerAddressName][$saleTypeId] = $Shipping;
-                     }
-                 }
-             }
-             // お届け先のリストを保存
-             foreach ($ShippingList as $ShippingListByAddress) {
-                 foreach ($ShippingListByAddress as $Shipping) {
-                     $this->entityManager->persist($Shipping);
-                 }
-             }
-             $ProductOrderType = $this->orderItemTypeRepository->find(OrderItemType::PRODUCT);
-             // お届け先に、配送商品の情報(OrderItem)を関連付ける
-             foreach ($data as $multiples) {
-                 /** @var OrderItem $OrderItem */
-                 $OrderItem = $multiples->getData();
-                 $ProductClass = $OrderItem->getProductClass();
-                 $Product = $OrderItem->getProduct();
-                 $saleTypeId = $ProductClass->getSaleType()->getId();
-                 $itemId = $OrderItem->getProductClass()->getId() . '_' . $OrderItem->getOptionSerial();
-                 $optionSerial = $OrderItem->getOptionSerial();
-                 $OrderItemOptions = $OrderItem->getOrderItemOptions();
-                 $optionPrice = $OrderItem->getOptionPrice();
-                 $optionTax = $OrderItem->getOptionTax();
-                 foreach ($multiples as $items) {
-                     foreach ($items as $item) {
-                         $CustomerAddress = $item['customer_address']->getData();
-                         $customerAddressName = $CustomerAddress->getShippingMultipleDefaultName();
-                         // お届け先から商品の数量を取得
-                         $quantity = 0;
-                         if (isset($arrOrderItemTemp[$customerAddressName]) && array_key_exists($itemId, $arrOrderItemTemp[$customerAddressName])) {
-                             $quantity = $arrOrderItemTemp[$customerAddressName][$itemId];
-                             unset($arrOrderItemTemp[$customerAddressName][$itemId]);
-                         } else {
-                             // この配送先には送る商品がないのでスキップ(通常ありえない)
-                             continue;
-                         }
-                         // 関連付けるお届け先のインスタンスを取得
-                         $Shipping = $ShippingList[$customerAddressName][$saleTypeId];
-                         // インスタンスを生成して保存
-                         $OrderItem = new OrderItem();
-                         $OrderItem->setShipping($Shipping)
-                             ->setOrder($Order)
-                             ->setProductClass($ProductClass)
-                             ->setProduct($Product)
-                             ->setProductName($Product->getName())
-                             ->setProductCode($ProductClass->getCode())
-                             ->setPrice($ProductClass->getPrice02())
-                             ->setQuantity($quantity)
-                             ->setOrderItemType($ProductOrderType)
-                             ->setOptionSerial($optionSerial);
-                         $ClassCategory1 = $ProductClass->getClassCategory1();
-                         if (!is_null($ClassCategory1)) {
-                             $OrderItem->setClasscategoryName1($ClassCategory1->getName());
-                             $OrderItem->setClassName1($ClassCategory1->getClassName()->getName());
-                         }
-                         $ClassCategory2 = $ProductClass->getClassCategory2();
-                         if (!is_null($ClassCategory2)) {
-                             $OrderItem->setClasscategoryName2($ClassCategory2->getName());
-                             $OrderItem->setClassName2($ClassCategory2->getClassName()->getName());
-                         }
-                         foreach($OrderItemOptions as $OrderItemOption){
-                             $newOrderItemOption = new OrderItemOption();
-                             $newOrderItemOption->setOptionId($OrderItemOption->getOptionId())
-                                                ->setOrderItem($OrderItem)
-                                                ->setLabel($OrderItemOption->getLabel())
-                                                ->setSortNo($OrderItemOption->getSortNo());
-                             foreach($OrderItemOption->getOrderItemOptionCategories() as $OrderItemOptionCategory){
-                                 $newOrderItemOptionCategory = new OrderItemOptionCategory();
-                                 $newOrderItemOptionCategory->setOptionCategoryId($OrderItemOptionCategory->getOptionCategoryId())
-                                                            ->setOrderItemOption($newOrderItemOption)
-                                                            ->setValue($OrderItemOptionCategory->getValue())
-                                                            ->setPrice($OrderItemOptionCategory->getPrice())
-                                                            ->setTax($OrderItemOptionCategory->getTax())
-                                                            ->setDeliveryFreeFlg($OrderItemOptionCategory->getDeliveryFreeFlg())
-                                                            ->setSortNo($OrderItemOptionCategory->getSortNo());
-                                 $newOrderItemOption->addOrderItemOptionCategory($newOrderItemOptionCategory);
-                             }
-                             $OrderItem->addOrderItemOption($newOrderItemOption);
-                         }
-                         $OrderItem->setPrice($OrderItem->getPrice() + $optionPrice);
-                         $OrderItem->setTax($OrderItem->getTax() + $optionTax);
-                         $OrderItem->setOptionSetFlg(true);
-                         $Shipping->addOrderItem($OrderItem);
-                         $Order->addOrderItem($OrderItem);
-                         $this->entityManager->persist($OrderItem);
-                     }
-                 }
-             }
-             $this->entityManager->flush();
-         }
-     }
- }
-