vendor/shopware/core/Checkout/Promotion/Subscriber/PromotionIndividualCodeRedeemer.php line 48

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Shopware\Core\Checkout\Promotion\Subscriber;
  4. use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
  5. use Shopware\Core\Checkout\Order\Aggregate\OrderCustomer\OrderCustomerEntity;
  6. use Shopware\Core\Checkout\Promotion\Aggregate\PromotionIndividualCode\PromotionIndividualCodeCollection;
  7. use Shopware\Core\Checkout\Promotion\Aggregate\PromotionIndividualCode\PromotionIndividualCodeEntity;
  8. use Shopware\Core\Checkout\Promotion\Cart\PromotionProcessor;
  9. use Shopware\Core\Checkout\Promotion\Exception\CodeAlreadyRedeemedException;
  10. use Shopware\Core\Checkout\Promotion\Exception\PromotionCodeNotFoundException;
  11. use Shopware\Core\Framework\Context;
  12. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  16. use Shopware\Core\Framework\Log\Package;
  17. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18. /**
  19. * @deprecated tag:v6.5.0 - reason:becomes-internal - EventSubscribers will become internal in v6.5.0
  20. */
  21. #[Package('checkout')]
  22. class PromotionIndividualCodeRedeemer implements EventSubscriberInterface
  23. {
  24. private EntityRepositoryInterface $codesRepository;
  25. /**
  26. * @internal
  27. */
  28. public function __construct(EntityRepositoryInterface $codesRepository)
  29. {
  30. $this->codesRepository = $codesRepository;
  31. }
  32. public static function getSubscribedEvents(): array
  33. {
  34. return [
  35. CheckoutOrderPlacedEvent::class => 'onOrderPlaced',
  36. ];
  37. }
  38. /**
  39. * @throws CodeAlreadyRedeemedException
  40. * @throws InconsistentCriteriaIdsException
  41. */
  42. public function onOrderPlaced(CheckoutOrderPlacedEvent $event): void
  43. {
  44. foreach ($event->getOrder()->getLineItems() ?? [] as $item) {
  45. // only update promotions in here
  46. if ($item->getType() !== PromotionProcessor::LINE_ITEM_TYPE) {
  47. continue;
  48. }
  49. /** @var string $code */
  50. $code = $item->getPayload()['code'] ?? '';
  51. try {
  52. // first try if its an individual
  53. // if not, then it might be a global promotion
  54. $individualCode = $this->getIndividualCode($code, $event->getContext());
  55. } catch (PromotionCodeNotFoundException $ex) {
  56. $individualCode = null;
  57. }
  58. // if we did not use an individual code we might have
  59. // just used a global one or anything else, so just quit in this case.
  60. if (!($individualCode instanceof PromotionIndividualCodeEntity)) {
  61. return;
  62. }
  63. /** @var OrderCustomerEntity $customer */
  64. $customer = $event->getOrder()->getOrderCustomer();
  65. // set the code to be redeemed
  66. // and assign all required meta data
  67. // for later needs
  68. $individualCode->setRedeemed(
  69. $item->getOrderId(),
  70. $customer->getCustomerId() ?? '',
  71. $customer->getFirstName() . ' ' . $customer->getLastName()
  72. );
  73. // save in database
  74. $this->codesRepository->update(
  75. [
  76. [
  77. 'id' => $individualCode->getId(),
  78. 'payload' => $individualCode->getPayload(),
  79. ],
  80. ],
  81. $event->getContext()
  82. );
  83. }
  84. }
  85. /**
  86. * Gets all individual code entities for the provided code value.
  87. *
  88. * @throws PromotionCodeNotFoundException
  89. * @throws InconsistentCriteriaIdsException
  90. */
  91. private function getIndividualCode(string $code, Context $context): PromotionIndividualCodeEntity
  92. {
  93. $criteria = new Criteria();
  94. $criteria->addFilter(
  95. new EqualsFilter('code', $code)
  96. );
  97. /** @var PromotionIndividualCodeCollection $result */
  98. $result = $this->codesRepository->search($criteria, $context)->getEntities();
  99. if (\count($result->getElements()) <= 0) {
  100. throw new PromotionCodeNotFoundException($code);
  101. }
  102. // return first element
  103. return $result->first();
  104. }
  105. }