custom/plugins/CogiLicenseManager/src/Service/LicenseManagerService.php line 547

Open in your IDE?
  1. <?php
  2. namespace Cogi\CogiLicenseManager\Service;
  3. use Cogi\CogiLicenseManager\CogiLicenseManager;
  4. use Cogi\CogiLicenseManager\Core\LicenseEmail\LicenseEmailEntity;
  5. use Cogi\CogiLicenseManager\Core\LicenseKey\LicenseKeyCollection;
  6. use Cogi\CogiLicenseManager\Core\LicenseKey\LicenseKeyEntity;
  7. use Cogi\CogiLicenseManager\Core\LicenseMultiKeyLog\LicenseMultiKeyLogEntity;
  8. use Cogi\CogiLicenseManager\Core\LicensePool\LicensePoolEntity;
  9. use Cogi\CogiLicenseManager\Core\LicenseProduct\LicenseProductEntity;
  10. use Doctrine\DBAL\Connection;
  11. use Exception;
  12. use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryEntity;
  13. use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
  14. use Shopware\Core\Checkout\Order\Aggregate\OrderTransaction\OrderTransactionEntity;
  15. use Shopware\Core\Checkout\Order\OrderEntity;
  16. use Shopware\Core\Content\Mail\Service\AbstractMailService;
  17. use Shopware\Core\Content\MailTemplate\MailTemplateEntity;
  18. use Shopware\Core\Content\Media\MediaService;
  19. use Shopware\Core\Framework\Api\Context\SystemSource;
  20. use Shopware\Core\Framework\Context;
  21. use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
  22. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  23. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  24. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  25. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  26. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  27. use Shopware\Core\Framework\Uuid\Uuid;
  28. use Shopware\Core\Framework\Validation\DataBag\DataBag;
  29. use Shopware\Core\System\Salutation\SalutationEntity;
  30. use Shopware\Core\System\SystemConfig\SystemConfigService;
  31. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  32. class LicenseManagerService extends AbstractController {
  33.     /**
  34.      * @var AbstractMailService $mailService
  35.      */
  36.     private AbstractMailService $mailService;
  37.     /**
  38.      * @var EntityRepository $mailTemplateRepository
  39.      */
  40.     private EntityRepository $mailTemplateRepository;
  41.     /**
  42.      * @var EntityRepository $salutationRepository
  43.      */
  44.     private EntityRepository $salutationRepository;
  45.     /**
  46.      * @var SystemConfigService $systemConfigService
  47.      */
  48.     private SystemConfigService $systemConfigService;
  49.     /**
  50.      * @var EntityRepository
  51.      */
  52.     protected EntityRepository $licenseProductRepository;
  53.     /**
  54.      * @var EntityRepository
  55.      */
  56.     protected EntityRepository $licenseRepository;
  57.     /**
  58.      * @var EntityRepository
  59.      */
  60.     protected EntityRepository $licensePoolRepository;
  61.     /**
  62.      * @var EntityRepository $orderRepository
  63.      */
  64.     private EntityRepository $orderRepository;
  65.     /**
  66.      * @var EntityRepository $orderTransactionRepository
  67.      */
  68.     private EntityRepository $orderTransactionRepository;
  69.     /**
  70.      * @var EntityRepository $orderDeliveryRepository
  71.      */
  72.     private EntityRepository $orderDeliveryRepository;
  73.     /**
  74.      * @var EntityRepository
  75.      */
  76.     protected EntityRepository $licenseUrlRepository;
  77.     /**
  78.      * @var EntityRepository
  79.      */
  80.     protected EntityRepository $licenseMultiKeyLogRepository;
  81.     /**
  82.      * @var EntityRepository
  83.      */
  84.     protected EntityRepository $productRepository;
  85.     /**
  86.      * @var array
  87.      */
  88.     protected array $config;
  89.     /**
  90.      * @var MediaService
  91.      */
  92.     private MediaService $mediaService;
  93.     /**
  94.      * @param MediaService $mediaService
  95.      * @param AbstractMailService $mailService
  96.      * @param EntityRepository $mailTemplateRepository
  97.      * @param EntityRepository $salutationRepository
  98.      * @param SystemConfigService $systemConfigService
  99.      * @param EntityRepository $licenseProductRepository
  100.      * @param EntityRepository $licenseRepository
  101.      * @param EntityRepository $licensePoolRepository
  102.      * @param EntityRepository $orderRepository
  103.      * @param EntityRepository $orderTransactionRepository
  104.      * @param EntityRepository $orderDeliveryRepository
  105.      * @param EntityRepository $licenseUrlRepository
  106.      * @param EntityRepository $productRepository
  107.      * @param EntityRepository $licenseMultiKeyLogRepository
  108.      */
  109.     public function __construct(MediaService $mediaServiceAbstractMailService $mailServiceEntityRepository $mailTemplateRepositoryEntityRepository $salutationRepositorySystemConfigService $systemConfigServiceEntityRepository $licenseProductRepositoryEntityRepository $licenseRepositoryEntityRepository $licensePoolRepositoryEntityRepository $orderRepositoryEntityRepository $orderTransactionRepositoryEntityRepository $orderDeliveryRepositoryEntityRepository $licenseUrlRepositoryEntityRepository $productRepositoryEntityRepository $licenseMultiKeyLogRepository) {
  110.         $this->mailService $mailService;
  111.         $this->mailTemplateRepository $mailTemplateRepository;
  112.         $this->salutationRepository $salutationRepository;
  113.         $this->systemConfigService $systemConfigService;
  114.         $this->licenseProductRepository $licenseProductRepository;
  115.         $this->licenseRepository $licenseRepository;
  116.         $this->licensePoolRepository $licensePoolRepository;
  117.         $this->orderRepository $orderRepository;
  118.         $this->orderTransactionRepository $orderTransactionRepository;
  119.         $this->orderDeliveryRepository $orderDeliveryRepository;
  120.         $this->licenseUrlRepository $licenseUrlRepository;
  121.         $this->productRepository $productRepository;
  122.         $this->licenseMultiKeyLogRepository $licenseMultiKeyLogRepository;
  123.         $this->mediaService $mediaService;
  124.         $this->config $systemConfigService->getDomain('CogiLicenseManager.config');
  125.     }
  126.     /**
  127.      * @param OrderEntity $order
  128.      * @param OrderLineItemEntity $lineItem
  129.      * @param Context $context
  130.      */
  131.     public function processLicenseOrder(OrderEntity $orderOrderLineItemEntity $lineItemContext $context) {
  132.         $criteria = new Criteria();
  133.         $criteria->addAssociation('pool');
  134.         $criteria->addAssociation('product');
  135.         $criteria->setLimit(1);
  136.         $criteria->addFilter(new EqualsFilter('productId'$lineItem->getReferencedId()));
  137.         /** @var LicenseProductEntity $result */
  138.         $result $this->licenseProductRepository->search($criteria$context)->getEntities()->first();
  139.         $multiKey $this->getMultiKey($result->getPool()->getId(), $context$result->getCount() * $lineItem->getQuantity());
  140.         if ($multiKey->count() <= 0) {
  141.             $licenseList $this->getFreeLicenses($result->getPool()->getId(), $context$result->getCount() * $lineItem->getQuantity(), true);
  142.         } else {
  143.             $licenseList $multiKey;
  144.         }
  145.         if (count($licenseList) < $result->getCount() && $multiKey === null) {
  146.             try {
  147.                 $mailTemplate $this->getMailTemplate(CogiLicenseManager::MAIL_TEMPLATE_ADMIN_EMPTY_POOL);
  148.                 $licenseEmail = new LicenseEmailEntity();
  149.                 $licenseEmail->setCustomer($order->getOrderCustomer());
  150.                 $licenseEmail->setOrder($order);
  151.                 $licenseEmail->setPool($result->getPool());
  152.                 $licenseEmail->setLicenseProduct($result);
  153.                 $this->sendEmptyPoolMail($licenseEmail$mailTemplate);
  154.             } catch (InconsistentCriteriaIdsException $e) {
  155.                 return;
  156.             }
  157.         } else if (count($licenseList) <= 0) {
  158.             try {
  159.                 $mailTemplate $this->getMailTemplate(CogiLicenseManager::MAIL_TEMPLATE_ADMIN_EMPTY_POOL);
  160.                 $licenseEmail = new LicenseEmailEntity();
  161.                 $licenseEmail->setCustomer($order->getOrderCustomer());
  162.                 $licenseEmail->setOrder($order);
  163.                 $licenseEmail->setPool($result->getPool());
  164.                 $licenseEmail->setLicenseProduct($result);
  165.                 $this->sendEmptyPoolMail($licenseEmail$mailTemplate);
  166.             } catch (InconsistentCriteriaIdsException $e) {
  167.                 return;
  168.             }
  169.         } else {
  170.             $this->reserveLicense($licenseList$order$lineItem$result->getPool()->getId(), $result->getCount() * $lineItem->getQuantity());
  171.             $orderCustomFields $order->getCustomFields() ?: [];
  172.             $licenseKeys = [];
  173.             if (isset($orderCustomFields['licenseKeys'])) $licenseKeys $orderCustomFields['licenseKeys'] ?: [];
  174.             /** @var LicenseKeyEntity $license */
  175.             foreach ($licenseList->getElements() as $license) {
  176.                 array_push($licenseKeys$license->getLicense());
  177.             }
  178.             $orderCustomFields['licenseKeys'] = $licenseKeys;
  179.             $order->setCustomFields($orderCustomFields);
  180.             $this->orderRepository->update([
  181.                 [
  182.                     'id' => $order->getId(),
  183.                     'customFields' => $orderCustomFields
  184.                 ]
  185.             ], $context);
  186.             try {
  187.                 $mailTemplate $this->getMailTemplate(CogiLicenseManager::MAIL_TEMPLATE_ADMIN);
  188.                 if (isset($mailTemplate)) {
  189.                     $licenseEmail = new LicenseEmailEntity();
  190.                     $licenseEmail->setCustomer($order->getOrderCustomer());
  191.                     $licenseEmail->setOrder($order);
  192.                     $licenseEmail->setLicenseKeys($licenseList->getElements());
  193.                     $licenseEmail->setPool($result->getPool());
  194.                     $licenseEmail->setLicenseList($licenseList);
  195.                     $licenseEmail->setLicenseProduct($result);
  196.                     $this->sendAdminMail($licenseEmail$mailTemplate);
  197.                 }
  198.             } catch (InconsistentCriteriaIdsException $e) {
  199.                 return;
  200.             }
  201.         }
  202.     }
  203.     /**
  204.      * @param EntityCollection $licenseList
  205.      * @param OrderEntity $order
  206.      * @param OrderLineItemEntity $lineItem
  207.      * @param string $poolId
  208.      * @param int $count
  209.      */
  210.     private function reserveLicense(EntityCollection $licenseListOrderEntity $orderOrderLineItemEntity $lineItemstring $poolIdint $count) {
  211.         /** @var LicenseKeyEntity $license */
  212.         foreach ($licenseList as $license) {
  213.             if (!$license->isMultiKey()) {
  214.                 $this->licenseRepository->update([
  215.                     [
  216.                         'id' => $license->getId(),
  217.                         'sold' => false,
  218.                         'delivered' => false,
  219.                         'reserved' => true,
  220.                         'orderId' => $order->getId(),
  221.                         'customerId' => $order->getOrderCustomer()->getCustomer()->getId(),
  222.                         'productId' => $lineItem->getProductId(),
  223.                     ]
  224.                 ], Context::createDefaultContext());
  225.             } else {
  226.                 $this->licenseMultiKeyLogRepository->create([
  227.                     [
  228.                         'id' => Uuid::randomHex(),
  229.                         'keyId' => $license->getId(),
  230.                         'count' => $count,
  231.                         'sold' => false,
  232.                         'deliverd' => false,
  233.                         'reserved' => true,
  234.                         'orderId' => $order->getId(),
  235.                         'customerId' => $order->getOrderCustomer()->getCustomer()->getId(),
  236.                         'productId' => $lineItem->getProductId(),
  237.                     ]
  238.                 ], Context::createDefaultContext());
  239.             }
  240.         }
  241.     }
  242.     /**
  243.      * @param OrderEntity $order
  244.      * @param Context $context
  245.      * @param bool $isResend
  246.      */
  247.     public function processSendKeys(OrderEntity $orderContext $contextbool $isResend false) {
  248.         $keys $this->getKeysToBeSent($order$context$isResend);
  249.         if (count($keys) <= && !isset($order->getCustomFields()["licenseHasSendSuccess"])) {
  250.             $criteria = new Criteria([$order->getId()]);
  251.             $criteria->addAssociation("orderCustomer");
  252.             $criteria->addAssociation("orderCustomer.customer");
  253.             $criteria->addAssociation("salesChannel");
  254.             $criteria->addAssociation("currency");
  255.             $criteria->addAssociation("billingAddress");
  256.             $criteria->addAssociation("deliveries");
  257.             $criteria->addAssociation("lineItems");
  258.             $criteria->addAssociation("transactions");
  259.             $order $this->orderRepository->search($criteria$context)->first();
  260.             foreach ($order->getLineItems() as $lineItem) {
  261.                 if (isset($lineItem->getPayload()['isLicense'])) {
  262.                     if ($lineItem->getPayload()['isLicense'] !== null) {
  263.                         if ($lineItem->getPayload()['isLicense']) {
  264.                             $this->processLicenseOrder($order$lineItem$context);
  265.                         }
  266.                     }
  267.                 }
  268.             }
  269.             $keys $this->getKeysToBeSent($order$context$isResend);
  270.         }
  271.         if (!$isResend) {
  272.             $this->updateOrderState($order$context);
  273.             foreach ($keys as $key) {
  274.                 if (!isset($key->keyId)) {
  275.                     $this->licenseRepository->update([
  276.                         [
  277.                             'id' => $key->getId(),
  278.                             'sold' => true,
  279.                             'delivered' => true,
  280.                         ]
  281.                     ], Context::createDefaultContext());
  282.                 } else {
  283.                     $this->licenseMultiKeyLogRepository->update([
  284.                         [
  285.                             'id' => $key->getId(),
  286.                             'sold' => true,
  287.                             'deliverd' => true,
  288.                             'reserved' => true
  289.                         ]
  290.                     ], Context::createDefaultContext());
  291.                     $this->licenseRepository->update([
  292.                         [
  293.                             'id' => $key->getKey()->getId(),
  294.                             'multiKeyUsed' => ($key->getKey()->getMultiKeyUsed() + $key->getCount()),
  295.                         ]
  296.                     ], Context::createDefaultContext());
  297.                 }
  298.             }
  299.         }
  300.         $keyPoolArr = array();
  301.         $keyCounts = [];
  302.         foreach ($keys as $key) {
  303.             if (!isset($key->keyId)) {
  304.                 $keyPoolArr[$key->getPool()->getId()][] = $key;
  305.             } else {
  306.                 $keyCounts[$key->keyId] = $key->count;
  307.                 $multiKey $key->getKey();
  308.                 $multiKey->setCustomer($key->getCustomer());
  309.                 $multiKey->setOrder($key->getOrder());
  310.                 $multiKey->setProduct($key->getProduct());
  311.                 $keyPoolArr[$key->getKey()->getPool()->getId()][] = $multiKey;
  312.             }
  313.         }
  314.         foreach ($keyPoolArr as $poolItems) {
  315.             $pool $poolItems[0]->getPool();
  316.             $licenseList = new LicenseKeyCollection();
  317.             foreach ($poolItems as $license) {
  318.                 $licenseList->add($license);
  319.             }
  320.             $licenseEmail = new LicenseEmailEntity();
  321.             $licenseEmail->setCustomer($order->getOrderCustomer());
  322.             $licenseEmail->setOrder($order);
  323.             $licenseEmail->setLicenseKeys($poolItems);
  324.             $licenseEmail->setPool($pool);
  325.             $licenseEmail->setLicenseList($licenseList);
  326.             $licenseEmail->setCount($keyCounts[$poolItems[0]->id] ?? 1);
  327.             $licenseEmail->setHidenMailUrl($this->config['CogiLicenseManager.config.openKeyUrl'] ?? null);
  328.             if (isset($pool)) $licenseEmail->setUrlList($this->getUrls($pool$context) ?: null);
  329.             if (isset($pool)) $licenseEmail->setMediaList($pool->getMedialist() ?: null);
  330.             if (isset($pool)) $licenseEmail->setEmailContent($pool->getEmailcontent() ?: null);
  331.             try {
  332.                 $mailTemplate $this->getMailTemplate(CogiLicenseManager::MAIL_TEMPLATE_CUSTOMER);
  333.             } catch (InconsistentCriteriaIdsException $e) {
  334.                 return;
  335.             }
  336.             if (!$isResend) {
  337.                 try {
  338.                     $orderCustomFields $order->getCustomFields() ?: [];
  339. //                    $orderCustomFields['licenseEmail'] = json_decode(json_encode($licenseEmail));
  340.                     $orderCustomFields['licenseHasSendSuccess'] = true;
  341.                     $order->setCustomFields($orderCustomFields);
  342.                     $this->orderRepository->update([
  343.                         [
  344.                             'id' => $order->getId(),
  345.                             'customFields' => $orderCustomFields
  346.                         ]
  347.                     ], $context);
  348.                 } catch (Exeption $e) {
  349.                 }
  350.             }
  351.             $this->sendEmail($licenseEmail$mailTemplate);
  352.         }
  353.     }
  354.     /**
  355.      * @param OrderEntity $order
  356.      * @param Context $context
  357.      */
  358.     public function checkState(OrderEntity $orderContext $context) {
  359.         $transaction $this->getTransaction($order);
  360.         $paymentState $transaction->getStateMachineState()->getId();
  361.         $hasLicense false;
  362.         foreach ($order->getLineItems() as $lineItem){
  363.             if(isset($lineItem->getPayload()['isLicense'])) {
  364.                 if ($lineItem->getPayload()['isLicense'] !== null) {
  365.                     if ($lineItem->getPayload()['isLicense']) {
  366.                         $hasLicense true;
  367.                         break;
  368.                     }
  369.                 }
  370.             }
  371.         }
  372.         if (!$this->checkForPaymentCanceled($order$context$paymentState) && $hasLicense) {
  373.             if (isset($this->config['CogiLicenseManager.config.transactionStatus'])) {
  374.                 if ($this->config['CogiLicenseManager.config.transactionStatus'] === $paymentState) {
  375.                     $this->processSendKeys($order$context);
  376.                 }
  377.             }
  378.         }
  379.     }
  380.     /**
  381.      * @param OrderEntity $order
  382.      * @param Context $context
  383.      * @param $paymentState
  384.      * @return bool
  385.      */
  386.     private function checkForPaymentCanceled(OrderEntity $orderContext $context$paymentState): bool {
  387.         if (is_array($this->config['CogiLicenseManager.config.transactionAbordStatus'])) {
  388.             if (in_array($paymentState$this->config['CogiLicenseManager.config.transactionAbordStatus'])) {
  389.                 $this->cancelLicense($order$context);
  390.                 return true;
  391.             }
  392.         } else if ($this->config['CogiLicenseManager.config.transactionAbordStatus'] === $paymentState) {
  393.             $this->cancelLicense($order$context);
  394.             return true;
  395.         }
  396.         return false;
  397.     }
  398.     /**
  399.      * @param OrderEntity $order
  400.      * @param Context $context
  401.      */
  402.     private function cancelLicense(OrderEntity $orderContext $context) {
  403.         $keys $this->getKeysToBeSent($order$context);
  404.         $poolId null;
  405.         $productId null;
  406.         foreach ($keys as $key) {
  407.             if (!isset($key->keyId)) {
  408.                 $this->licenseRepository->update([
  409.                     [
  410.                         'id' => $key->getId(),
  411.                         'sold' => false,
  412.                         'delivered' => false,
  413.                         'reserved' => false,
  414.                         'orderId' => null,
  415.                         'customerId' => null,
  416.                         'productId' => null,
  417.                     ]
  418.                 ], Context::createDefaultContext());
  419.                 if ($productId === null) {
  420.                     $productId $key->getProduct()->getId();
  421.                 }
  422.                 if ($poolId === null) {
  423.                     $poolId $key->getPool();
  424.                 }
  425.                 if ($poolId !== $key->getPool() || $productId !== $key->getProduct()->getId()) $this->updateProductStock($productId$poolId);
  426.             } else {
  427.                 $this->licenseMultiKeyLogRepository->update([
  428.                     [
  429.                         'id' => $key->getId(),
  430.                         'sold' => false,
  431.                         'deliverd' => false,
  432.                         'reserved' => false
  433.                     ]
  434.                 ], Context::createDefaultContext());
  435.             }
  436.         }
  437.     }
  438.     /**
  439.      * @param $salutationId
  440.      * @return SalutationEntity|null
  441.      */
  442.     private function getSalutation($salutationId): ?SalutationEntity {
  443.         $context = new Context(new SystemSource());
  444.         $criteria = new Criteria();
  445.         $criteria->addFilter(new EqualsFilter('id'$salutationId));
  446.         $criteria->setLimit(1);
  447.         /** @var SalutationEntity|null $salutation */
  448.         $salutation $this->salutationRepository->search($criteria$context)->first();
  449.         return $salutation;
  450.     }
  451.     /**
  452.      * Gibt das bennötigte EMail Template wieder
  453.      * @param string $technicalName
  454.      * @return MailTemplateEntity|null
  455.      */
  456.     private function getMailTemplate(string $technicalName): ?MailTemplateEntity {
  457.         $context = new Context(new SystemSource());
  458.         $criteria = new Criteria();
  459.         $criteria->addFilter(new EqualsFilter('mailTemplateType.technicalName'$technicalName));
  460.         $criteria->setLimit(1);
  461.         /** @var MailTemplateEntity|null $mailTemplate */
  462.         $mailTemplate $this->mailTemplateRepository->search($criteria$context)->first();
  463.         return $mailTemplate;
  464.     }
  465.     /**
  466.      * @param string $poolId
  467.      * @param Context $context
  468.      * @param int $count
  469.      * @param bool $noMultiKey
  470.      * @return EntityCollection
  471.      */
  472.     public function getFreeLicenses(string $poolIdContext $contextint $countbool $noMultiKey false): EntityCollection {
  473.         $criteria = new Criteria();
  474.         $criteria->addAssociation('pool');
  475.         if ($count 0) {
  476.             $criteria->setLimit($count);
  477.         } else {
  478.             $criteria->setLimit(500);
  479.         }
  480.         $criteria->addFilter(new EqualsFilter('poolId'$poolId));
  481.         $criteria->addFilter(new EqualsFilter('active'true));
  482.         $criteria->addFilter(new EqualsFilter('delivered'false));
  483.         $criteria->addFilter(new EqualsFilter('sold'false));
  484.         $criteria->addFilter(new EqualsFilter('reserved'false));
  485.         if ($noMultiKey$criteria->addFilter(new EqualsFilter('isMultiKey'false));
  486.         return $this->licenseRepository->search($criteria$context)->getEntities();
  487.     }
  488.     /**
  489.      * @param string $poolId
  490.      * @param Context $context
  491.      * @param int $count
  492.      * @return LicenseKeyCollection
  493.      */
  494.     public function getMultiKey(string $poolIdContext $contextint $count): LicenseKeyCollection {
  495.         $criteria = new Criteria();
  496.         $criteria->addAssociation('pool');
  497.         $criteria->setLimit(500);
  498.         $criteria->addFilter(new EqualsFilter('poolId'$poolId));
  499.         $criteria->addFilter(new EqualsFilter('active'true));
  500.         $criteria->addFilter(new EqualsFilter('delivered'false));
  501.         $criteria->addFilter(new EqualsFilter('sold'false));
  502.         $criteria->addFilter(new EqualsFilter('reserved'false));
  503.         $criteria->addFilter(new EqualsFilter('isMultiKey'true));
  504.         $keys $this->licenseRepository->search($criteria$context)->getEntities();
  505.         $list = new LicenseKeyCollection ();
  506.         /** @var LicenseKeyEntity $key */
  507.         foreach ($keys as $key) {
  508.             if ($key->isMultiKey()) {
  509.                 $criteria = new Criteria();
  510.                 $criteria->setLimit(500);
  511.                 $criteria->addFilter(new EqualsFilter('reserved'true));
  512.                 $criteria->addFilter(new EqualsFilter('sold'false));
  513.                 $criteria->addFilter(new EqualsFilter('deliverd'false));
  514.                 $criteria->addFilter(new EqualsFilter('keyId'$key->id));
  515.                 $reserved $this->licenseMultiKeyLogRepository->search($criteria$context)->getEntities()->count();
  516.                 if (($key->getMultiKeyLimit() - $key->getMultiKeyUsed() - $reserved) < $count) {
  517.                     continue;
  518.                 } else if (($key->getMultiKeyLimit() - $key->getMultiKeyUsed() - $reserved) >= $count) {
  519.                     $list->add($key);
  520.                     return $list;
  521.                 }
  522.             }
  523.         }
  524.         return $list;
  525.     }
  526.     /**
  527.      * @param string $id
  528.      * @param Context $context
  529.      * @return int
  530.      */
  531.     public function getReservedCountMultiKey(string $idContext $context): int {
  532.         $count 0;
  533.         $criteria = new Criteria();
  534.         $criteria->setLimit(500);
  535.         $criteria->addFilter(new EqualsFilter('reserved'true));
  536.         $criteria->addFilter(new EqualsFilter('sold'false));
  537.         $criteria->addFilter(new EqualsFilter('deliverd'false));
  538.         $criteria->addFilter(new EqualsFilter('keyId'$id));
  539.         /** @var LicenseMultiKeyLogEntity $key */
  540.         foreach ($this->licenseMultiKeyLogRepository->search($criteria$context)->getEntities() as $key) {
  541.             $count += $key->getCount();
  542.         }
  543.         return $count;
  544.     }
  545.     /**
  546.      * @param OrderEntity $order
  547.      * @param Context $context
  548.      * @param bool $isResend
  549.      * @return EntityCollection
  550.      */
  551.     private function getKeysToBeSent(OrderEntity $orderContext $contextbool $isResend false): EntityCollection {
  552.         $criteria = new Criteria();
  553.         $criteria->setLimit(500);
  554.         $criteria->addAssociation('pool.medialist');
  555.         $criteria->addAssociation('product');
  556.         $criteria->addAssociation('order');
  557.         $criteria->addAssociation('order.billingAddress');
  558.         $criteria->addAssociation('order.deliveries');
  559.         $criteria->addAssociation('order.lineItems');
  560.         $criteria->addAssociation('order.transactions');
  561.         $criteria->addAssociation('order.currency');
  562.         $criteria->addAssociation('order.language');
  563.         $criteria->addAssociation('order.addresses');
  564.         $criteria->addAssociation('customer');
  565.         $criteria->addAssociation('customer.salutation');
  566.         $criteria->addAssociation('customer.addresses');
  567.         $criteria->addAssociation('customer.language');
  568.         $criteria->addFilter(new EqualsFilter('orderId'$order->getId()));
  569.         $criteria->addFilter(new EqualsFilter('active'true));
  570.         if (!$isResend) {
  571.             $criteria->addFilter(new EqualsFilter('delivered'false));
  572.         }
  573.         $criteria->addFilter(new EqualsFilter('reserved'true));
  574.         $criteria->addSorting(new FieldSorting("createdAt""ASC"));
  575.         $list $this->licenseRepository->search($criteria$context)->getEntities();
  576.         if ($list->count() <= 0) {
  577.             $criteria = new Criteria();
  578.             $criteria->setLimit(500);
  579.             $criteria->addAssociation('key');
  580.             $criteria->addAssociation('key.pool');
  581.             $criteria->addAssociation('key.pool.medialist');
  582.             $criteria->addAssociation('product');
  583.             $criteria->addAssociation('order');
  584.             $criteria->addAssociation('order.billingAddress');
  585.             $criteria->addAssociation('order.deliveries');
  586.             $criteria->addAssociation('order.lineItems');
  587.             $criteria->addAssociation('order.transactions');
  588.             $criteria->addAssociation('order.currency');
  589.             $criteria->addAssociation('order.language');
  590.             $criteria->addAssociation('order.addresses');
  591.             $criteria->addAssociation('customer');
  592.             $criteria->addAssociation('customer.salutation');
  593.             $criteria->addAssociation('customer.addresses');
  594.             $criteria->addAssociation('customer.language');
  595.             $criteria->addFilter(new EqualsFilter('orderId'$order->getId()));
  596.             if (!$isResend) {
  597.                 $criteria->addFilter(new EqualsFilter('deliverd'false));
  598.             }
  599.             $criteria->addFilter(new EqualsFilter('reserved'true));
  600.             $criteria->addSorting(new FieldSorting("createdAt""ASC"));
  601.             $list $this->licenseMultiKeyLogRepository->search($criteria$context)->getEntities();
  602.         }
  603.         return $list;
  604.     }
  605.     /**
  606.      * @param LicensePoolEntity $pool
  607.      * @param Context $context
  608.      * @return EntityCollection
  609.      */
  610.     private function getUrls(LicensePoolEntity $poolContext $context): EntityCollection {
  611.         $criteria = new Criteria();
  612.         $criteria->setLimit(500);
  613.         $criteria->addFilter(new EqualsFilter('poolId'$pool->getId()));
  614.         return $this->licenseUrlRepository->search($criteria$context)->getEntities();
  615.     }
  616.     /**
  617.      * @param OrderEntity $order
  618.      * @param Context $context
  619.      */
  620.     private function updateOrderState(OrderEntity $orderContext $context) {
  621.         $containsNoDigitalProduct false;
  622.         /** @var OrderLineItemEntity $lineItem */
  623.         foreach ($order->getLineItems() as $lineItem) {
  624.             if ($lineItem->getType() === "product") {
  625.                 if (isset($lineItem->getPayload()['isLicense'])) {
  626.                     if ($lineItem->getPayload()['isLicense'] !== null) {
  627.                         if (!$lineItem->getPayload()['isLicense']) {
  628.                             $containsNoDigitalProduct true;
  629.                         }
  630.                     } else {
  631.                         $containsNoDigitalProduct true;
  632.                     }
  633.                 } else {
  634.                     $containsNoDigitalProduct true;
  635.                 }
  636.             }
  637.         }
  638.         try {
  639.             if ($this->config['CogiLicenseManager.config.deliveryStatus'] != null && !$containsNoDigitalProduct) {
  640.                 $criteria = new Criteria();
  641.                 $criteria->setLimit(1);
  642.                 $criteria->addFilter(new EqualsFilter('orderId'$order->getId()));
  643.                 /** @var OrderDeliveryEntity $result */
  644.                 $result $this->orderDeliveryRepository->search($criteria$context)->getEntities()->first();
  645.                 if (isset($result)) {
  646.                     $this->orderDeliveryRepository->update([
  647.                         [
  648.                             'id' => $result->getId(),
  649.                             'stateId' => $this->config['CogiLicenseManager.config.deliveryStatus'],
  650.                         ]
  651.                     ], Context::createDefaultContext());
  652.                 }
  653.                 if ($this->config['CogiLicenseManager.config.orderStatus'] != null) {
  654.                     $this->orderRepository->update([
  655.                         [
  656.                             'id' => $order->getId(),
  657.                             'stateId' => $this->config['CogiLicenseManager.config.orderStatus'],
  658.                         ]
  659.                     ], Context::createDefaultContext());
  660.                 }
  661.             } else if ($this->config['CogiLicenseManager.config.deliveryStatusPartial'] != null && $containsNoDigitalProduct) {
  662.                 $criteria = new Criteria();
  663.                 $criteria->setLimit(1);
  664.                 $criteria->addFilter(new EqualsFilter('orderId'$order->getId()));
  665.                 /** @var OrderDeliveryEntity $result */
  666.                 $result $this->orderDeliveryRepository->search($criteria$context)->getEntities()->first();
  667.                 if (isset($result)) {
  668.                     $this->orderDeliveryRepository->update([
  669.                         [
  670.                             'id' => $result->getId(),
  671.                             'stateId' => $this->config['CogiLicenseManager.config.deliveryStatusPartial'],
  672.                         ]
  673.                     ], Context::createDefaultContext());
  674.                 }
  675.             }
  676.         } catch (Exception $e) {
  677.         }
  678.     }
  679.     /**
  680.      * Returns transaction.
  681.      *
  682.      * @param OrderEntity $order
  683.      *
  684.      * @return OrderTransactionEntity|null
  685.      *
  686.      * @throws InconsistentCriteriaIdsException
  687.      */
  688.     private function getTransaction(OrderEntity $order): ?OrderTransactionEntity {
  689.         $context = new Context(new SystemSource());
  690.         $criteria = new Criteria();
  691.         $criteria->setLimit(500);
  692.         $criteria->addFilter(new EqualsFilter('orderId'$order->getId()));
  693.         return $this->orderTransactionRepository->search($criteria$context)->first();
  694.     }
  695.     /**
  696.      * @param string $productId
  697.      * @param string $poolId
  698.      * @return float|int
  699.      * @throws \Doctrine\DBAL\Exception
  700.      */
  701.     public function updateProductStock(string $productIdstring $poolId) {
  702. //        if(!$this->config['CogiLicenseManager.config.stockupdate']) {
  703. //            return -1;
  704. //        }
  705.         $context = new Context(new SystemSource());
  706.         $criteria = new Criteria();
  707.         $criteria->addFilter(new EqualsFilter('poolId'$poolId));
  708.         $criteria->addFilter(new EqualsFilter('active'true));
  709.         $criteria->addFilter(new EqualsFilter('delivered'false));
  710.         $criteria->addFilter(new EqualsFilter('sold'false));
  711.         $criteria->addFilter(new EqualsFilter('reserved'false));
  712.         /** @var LicenseKeyCollection $licenses */
  713.         $licenses $this->licenseRepository->search($criteria$context)->getEntities();
  714.         $criteria = new Criteria();
  715.         $criteria->addFilter(new EqualsFilter('productId'$productId));
  716.         /** @var LicenseProductEntity $product */
  717.         $product $this->licenseProductRepository->search($criteria$context)->getEntities()->first();
  718.         $count $product->getCount();
  719.         $stock 0;
  720.         /** @var LicenseKeyEntity $license */
  721.         foreach ($licenses as $license) {
  722.             if ($license->isMultiKey()) {
  723.                 $i $license->getMultiKeyLimit() - $license->getMultiKeyUsed();
  724.                 if ($i 0) {
  725.                     $stock += $i;
  726.                 }
  727.             } else {
  728.                 $stock++;
  729.             }
  730.         }
  731.         if ($stock 1) {
  732.             if (($stock $count) < 1) {
  733.                 $stock 0;
  734.             } else {
  735.                 $i = ($stock $count);
  736.                 $stock round($i0PHP_ROUND_HALF_DOWN);
  737.                 if ($stock 1$stock 1;
  738.             }
  739.         }
  740. //        $this->productRepository->update([
  741. //            [
  742. //                'id' => $productId,
  743. //                'stock' => intval($stock),
  744. //                'availableStock' => intval($stock),
  745. //                'max_purchase' => intval($stock),
  746. //            ]
  747. //        ], Context::createDefaultContext());
  748.         /** @var Connection $connection */
  749.         $connection $this->container->get(Connection::class);
  750.         $connection->executeStatement("UPDATE `product` SET `stock` = :stock, `available_stock` = :stock, `max_purchase` = :stock WHERE `id` = UNHEX(:id);", [
  751.             'id' => $productId,
  752.             'stock' => intval($stock)
  753.         ]);
  754.         return $stock;
  755.     }
  756.     /**
  757.      * Email an den Kunden senden
  758.      * @param LicenseEmailEntity $licenseEmail
  759.      * @param MailTemplateEntity $mailTemplate
  760.      */
  761.     private function sendEmail(LicenseEmailEntity $licenseEmailMailTemplateEntity $mailTemplate) {
  762.         $recipients = [
  763.             $licenseEmail->getCustomer()->getEmail() => $licenseEmail->getCustomer()->getFirstName() . ' ' $licenseEmail->getCustomer()->getLastName()
  764.         ];
  765.         $context = new Context(new SystemSource());
  766.         $attachments = [];
  767.         $data = new DataBag();
  768.         $data->set('recipients'$recipients);
  769.         $data->set('senderName'$mailTemplate->getSenderName());
  770.         $data->set('salesChannelId'$licenseEmail->getOrder()->getSalesChannelId());
  771.         $data->set('contentHtml'$mailTemplate->getContentHtml());
  772.         $data->set('contentPlain'$mailTemplate->getContentPlain());
  773.         $data->set('subject'$mailTemplate->getSubject());
  774.         if ($licenseEmail->getMediaList() !== null) {
  775.             foreach ($licenseEmail->getMediaList()->getElements() as $mailTemplateMedia) {
  776.                 $attachments[] = $this->mediaService->getAttachment($mailTemplateMedia$context);
  777.             }
  778.         }
  779.         $data->set('binAttachments'$attachments);
  780.         $this->mailService->send($data->all(), $context, [
  781.             'licenseEmail' => $licenseEmail,
  782.         ]);
  783.     }
  784.     /**
  785.      * @param LicenseEmailEntity $licenseEmail
  786.      * @param MailTemplateEntity $mailTemplate
  787.      */
  788.     private function sendAdminMail(LicenseEmailEntity $licenseEmailMailTemplateEntity $mailTemplate) {
  789.         if (isset($this->config['CogiLicenseManager.config.storeMail'])) {
  790.             if (isset($this->config['CogiLicenseManager.config.sendAdminMail'])) {
  791.                 if ($this->config['CogiLicenseManager.config.sendAdminMail']) {
  792.                     $recipients = [
  793.                         $this->config['CogiLicenseManager.config.storeMail'] => 'SHOP'
  794.                     ];
  795.                     $context = new Context(new SystemSource());
  796.                     $attachments = [];
  797.                     $data = new DataBag();
  798.                     $data->set('recipients'$recipients);
  799.                     $data->set('senderName'$mailTemplate->getSenderName());
  800.                     $data->set('salesChannelId'$licenseEmail->getOrder()->getSalesChannelId());
  801.                     $data->set('contentHtml'$mailTemplate->getContentHtml());
  802.                     $data->set('contentPlain'$mailTemplate->getContentPlain());
  803.                     $data->set('subject'$mailTemplate->getSubject());
  804.                     if ($licenseEmail->getMediaList() !== null) {
  805.                         foreach ($licenseEmail->getMediaList()->getElements() as $mailTemplateMedia) {
  806.                             $attachments[] = $this->mediaService->getAttachment($mailTemplateMedia$context);
  807.                         }
  808.                     }
  809.                     $data->set('binAttachments'$attachments);
  810.                     $this->mailService->send($data->all(), $context, [
  811.                         'licenseEmail' => $licenseEmail
  812.                     ]);
  813.                 }
  814.             }
  815.         }
  816.     }
  817.     /**
  818.      * @param LicenseEmailEntity $licenseEmail
  819.      * @param MailTemplateEntity $mailTemplate
  820.      */
  821.     private function sendEmptyPoolMail(LicenseEmailEntity $licenseEmailMailTemplateEntity $mailTemplate) {
  822.         if (isset($this->config['CogiLicenseManager.config.storeMail'])) {
  823.             if (isset($this->config['CogiLicenseManager.config.sendMailKeyEmpty'])) {
  824.                 if ($this->config['CogiLicenseManager.config.sendMailKeyEmpty']) {
  825.                     $recipients = [
  826.                         $this->config['CogiLicenseManager.config.storeMail'] => 'SHOP'
  827.                     ];
  828.                     $context = new Context(new SystemSource());
  829.                     $attachments = [];
  830.                     $data = new DataBag();
  831.                     $data->set('recipients'$recipients);
  832.                     $data->set('senderName'$mailTemplate->getSenderName());
  833.                     $data->set('salesChannelId'$licenseEmail->getOrder()->getSalesChannelId());
  834.                     $data->set('contentHtml'$mailTemplate->getContentHtml());
  835.                     $data->set('contentPlain'$mailTemplate->getContentPlain());
  836.                     $data->set('subject'$mailTemplate->getSubject());
  837.                     if ($licenseEmail->getMediaList() !== null) {
  838.                         foreach ($licenseEmail->getMediaList()->getElements() as $mailTemplateMedia) {
  839.                             $attachments[] = $this->mediaService->getAttachment($mailTemplateMedia$context);
  840.                         }
  841.                     }
  842.                     $data->set('binAttachments'$attachments);
  843.                     $this->mailService->send($data->all(), $context, [
  844.                         'licenseEmail' => $licenseEmail
  845.                     ]);
  846.                 }
  847.             }
  848.         }
  849.     }
  850. }