custom/plugins/TwigelBonusProgram/src/Subscriber/OnOrderWritten.php line 67

Open in your IDE?
  1. <?php
  2. namespace Twigel\BonusProgram\Subscriber;
  3. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  4. use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
  5. use Shopware\Core\Checkout\Order\OrderEntity;
  6. use Shopware\Core\Checkout\Order\OrderEvents;
  7. use Shopware\Core\Framework\Context;
  8. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  13. use Shopware\Core\Framework\Uuid\Uuid;
  14. use Shopware\Core\System\SystemConfig\SystemConfigService;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. use Twigel\BonusProgram\Service\TwigelCustomerOrderService;
  17. class OnOrderWritten implements EventSubscriberInterface
  18. {
  19.     /** @var EntityRepository */
  20.     private $orderRepository;
  21.     /** @var SystemConfigService */
  22.     private $config;
  23.     /** @var EntityRepository */
  24.     private $twigelOrderStatusRepository;
  25.     /** @var EntityRepository */
  26.     private $orderCustomerRepository;
  27.     /** @var EntityRepository */
  28.     private $customerRepository;
  29.     /** @var EntityRepository */
  30.     private $twigelCustomerAccountRepository;
  31.     /** @var EntityRepository */
  32.     private $twigelStatusRepository;
  33.     public function __construct(
  34.         EntityRepository $orderRepository,
  35.         SystemConfigService $config,
  36.         EntityRepository $twigelOrderStatusRepository,
  37.         EntityRepository $orderCustomerRepository,
  38.         EntityRepository $customerRepository,
  39.         EntityRepository $twigelCustomerAccountRepository,
  40.         EntityRepository $twigelStatusRepository
  41.     )
  42.     {
  43.         $this->orderRepository $orderRepository;
  44.         $this->config $config;
  45.         $this->twigelOrderStatusRepository $twigelOrderStatusRepository;
  46.         $this->orderCustomerRepository $orderCustomerRepository;
  47.         $this->customerRepository $customerRepository;
  48.         $this->twigelCustomerAccountRepository $twigelCustomerAccountRepository;
  49.         $this->twigelStatusRepository $twigelStatusRepository;
  50.     }
  51.     /**
  52.      * @inheritDoc
  53.      */
  54.     public static function getSubscribedEvents()
  55.     {
  56.         return [
  57.             OrderEvents::ORDER_WRITTEN_EVENT => 'onOrderWritten'
  58.         ];
  59.     }
  60.     public function onOrderWritten(EntityWrittenEvent $event)
  61.     {
  62.         if ($event->getName() !== OrderEvents::ORDER_WRITTEN_EVENT) {
  63.             return;
  64.         }
  65.         if (!$this->config->get("TwigelBonusProgram")) {
  66.             return;
  67.         }
  68.         $results $event->getWriteResults();
  69.         $customerId '';
  70.         $orderUpdate = [];
  71.         foreach ($results as $result) {
  72.             $criteria = new Criteria([$result->getPrimaryKey()]);
  73.             $criteria->addAssociations(['lineItems']);
  74.             /** @var OrderEntity $order */
  75.             $order $this->orderRepository->search($criteria$event->getContext())->first();
  76.             $customerId $order->getOrderCustomer()->getCustomerId();
  77.             $customer self::getCustomer($customerId$event->getContext());
  78.             $bonusAmount 0;
  79.             $bonusSell 0;
  80.             /** @var OrderLineItemEntity $lineItem */
  81.             foreach ($order->getLineItems() as $lineItem){
  82.                 if ($lineItem->getType() !== "promotion"){
  83.                     $bonusAmount += round($lineItem->getTotalPrice() * $this->config->get("TwigelBonusProgram.config.bonusToEuro"));
  84.                 }
  85.                 if (array_key_exists('productBonusSell'$lineItem->getPayload())){
  86.                     $bonusSell += $lineItem->getPayload()['productBonusSell'];
  87.                 }elseif(array_key_exists("promotionId"$lineItem->getPayload()) && $lineItem->getPayload()["promotionId"] == $this->config->get("TwigelBonusProgram")["config"]["discountByBonus"]){
  88.                     $bonusSell += +($lineItem->getPayload()["value"]) * $this->config->get("TwigelBonusProgram")["config"]["euroToBonus"];
  89.                 }
  90.             }
  91.             if($bonusSell){
  92.                 $orderUpdate[] = [
  93.                     'id' => $order->getId(),
  94.                     'customFields' => [
  95.                         'bonusOrder' => $bonusAmount,
  96.                         'bonusSell' => $bonusSell
  97.                     ]
  98.                 ];
  99.             }else{
  100.                 $orderUpdate[] = [
  101.                     'id' => $order->getId(),
  102.                     'customFields' => [
  103.                         'bonusOrder' => $bonusAmount
  104.                     ]
  105.                 ];
  106.             }
  107.             $bonusAmount $bonusAmount $bonusSell;
  108.             $orderStatus = [
  109.                 'id' => Uuid::randomHex(),
  110.                 'orderId' => $order->getId(),
  111.                 'customerId' => $order->getOrderCustomer()->getCustomerId(),
  112.                 'bonusAmount' => (int)$bonusAmount
  113.             ];
  114.             $criteria = new Criteria();
  115.             $criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_AND, [
  116.                 new EqualsFilter('orderId'$order->getId()),
  117.                 new EqualsFilter('customerId'$order->getOrderCustomer()->getCustomerId())
  118.             ]));
  119.             $orderStatusDb $this->twigelOrderStatusRepository->search($criteria$event->getContext())->first();
  120.             if ($orderStatusDb) {
  121.                 $this->twigelOrderStatusRepository->update([[
  122.                     'id' => $orderStatusDb->getId(),
  123.                     'bonusAmount' => (int)$bonusAmount,
  124.                 ]], $event->getContext());
  125.             } else {
  126.                 $this->twigelOrderStatusRepository->create([$orderStatus], $event->getContext());
  127.             }
  128.             $customerAccountCriteria = new Criteria();
  129.             $customerAccountCriteria->addFilter(new EqualsFilter('customerId'$customerId));
  130.             $customerAccount $this->twigelCustomerAccountRepository->search($customerAccountCriteria$event->getContext())->first();
  131.             if (!$customerAccount) {
  132.                 $status self::getCustomerStatusId($customerId$event->getContext());
  133.                 $customerAccount = [
  134.                     'id' => Uuid::randomHex(),
  135.                     'customerId' => $customerId,
  136.                     'bonusAmount' => (int)$bonusAmount
  137.                 ];
  138.                 if ($status){
  139.                     $customerAccount['statusId'] = $status->getId();
  140.                 }
  141.                 $this->twigelCustomerAccountRepository->create([$customerAccount], $event->getContext());
  142.             } else {
  143.                 $status self::getCustomerStatusId($customerId$event->getContext());
  144.                 if ($status && $customerAccount->getStatusId() !== $status->getId()){
  145.                     $this->twigelCustomerAccountRepository->update([
  146.                         [
  147.                             'id' => $customerAccount->getId(),
  148.                             'statusId' => $status->getId(),
  149.                             'bonusAmount' => $customerAccount->getBonusAmount() + (int)$bonusAmount
  150.                         ]
  151.                     ], $event->getContext());
  152.                 }else{
  153.                     $this->twigelCustomerAccountRepository->update([
  154.                         [
  155.                             'id' => $customerAccount->getId(),
  156.                             'bonusAmount' => $customerAccount->getBonusAmount() + (int)$bonusAmount
  157.                         ]
  158.                     ], $event->getContext());
  159.                 }
  160.             }
  161.             if (!$order->getCustomFields()){
  162.                 self::orderUpdate($orderUpdate$event->getContext());
  163.             }
  164.         }
  165.         self::getCustomerTurnOver($customerId$event->getContext());
  166.     }
  167.     private function orderUpdate(array $updateContext $context){
  168.         if (!$update){
  169.             return;
  170.         }
  171.         $this->orderRepository->update($update$context);
  172.     }
  173.     private function getCustomerStatusId($customerIdContext $context){
  174.         $status self::getCustomerStatus($customerId);
  175.         if ($status['turnOver']){
  176.             $customerGroupId $this->config->get('TwigelBonusProgram')['config'][TwigelCustomerOrderService::CONFIG_CUSTOMER_GROUPS[$status['turnOver']]];
  177.             $statusCriteria = new Criteria();
  178.             $statusCriteria->addFilter(new EqualsFilter('customerGroupId'$customerGroupId));
  179.             return $this->twigelStatusRepository->search($statusCriteria$context)->first();
  180.         }else{
  181.             return null;
  182.         }
  183.     }
  184.     private function getCustomerStatus($customerId){
  185.         $service = new TwigelCustomerOrderService($this->orderCustomerRepository);
  186.         return [
  187.             'turnOver' => $service->countTurnOver($customerId),
  188.             'amountOfOrders' => $service->countOrdersOfCustomer($customerId)
  189.         ];
  190.     }
  191.     private function getCustomerTurnOver($customerIdContext $context)
  192.     {
  193.         $status self::getCustomerStatus($customerId);
  194.         if (($status['turnOver'] !== || $status['amountOfOrders'] !== 0) && $status['turnOver'] !== $status['amountOfOrders']) {
  195.             self::setCustomerStatus($status['turnOver'], $customerId$context);
  196.         } elseif (($status['turnOver'] !== || $status['amountOfOrders'] !== 0) && $status['turnOver'] === $status['amountOfOrders']) {
  197.             self::setCustomerStatus($status['amountOfOrders'], $customerId$context);
  198.         }
  199.     }
  200.     private function setCustomerStatus($status$customerIdContext $context)
  201.     {
  202.         if ($status === "0") {
  203.             return;
  204.         }
  205.         $customerGroupId $this->config->get('TwigelBonusProgram')['config'][TwigelCustomerOrderService::CONFIG_CUSTOMER_GROUPS[$status]];
  206.         $criteria = new Criteria([$customerId]);
  207.         $criteria->addFilter(new EqualsFilter('groupId'$customerGroupId));
  208.         $customer $this->customerRepository->search($criteria$context)->first();
  209.         if (!$customer) {
  210.             $this->customerRepository->update([
  211.                 [
  212.                     'id' => $customerId,
  213.                     'groupId' => $customerGroupId
  214.                 ]
  215.             ], $context);
  216.         }
  217.     }
  218.     private function getCustomer($customerIdContext $context)
  219.     {
  220.         if (!$customerId){
  221.             return null;
  222.         }
  223.         $criteria = new Criteria([$customerId]);
  224.         return $this->customerRepository->search($criteria$context)->first();
  225.     }
  226. }