custom/plugins/MeteorPromotionGift/src/Subscribers/FreeGiftRedemptionUpdater.php line 36

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Meteor\PromotionGift\Subscribers;
  4. use Meteor\PromotionGift\Checker\LineItemIsFreeGiftInterface;
  5. use Meteor\PromotionGift\Core\Checkout\Promotion\Cart\GiftProcessor;
  6. use Meteor\PromotionGift\Dal\FetchCustomerCountsForPromotionsInterface;
  7. use Meteor\PromotionGift\Dal\UpdatePromotionCountInterface;
  8. use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
  9. use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemEntity;
  10. use Shopware\Core\Framework\Uuid\Uuid;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. class FreeGiftRedemptionUpdater implements EventSubscriberInterface
  13. {
  14.     private LineItemIsFreeGiftInterface $lineItemIsFreeGift;
  15.     private FetchCustomerCountsForPromotionsInterface $fetchCustomerCountsForPromotions;
  16.     private UpdatePromotionCountInterface $updatePromotionCount;
  17.     public function __construct(LineItemIsFreeGiftInterface $lineItemIsFreeGiftFetchCustomerCountsForPromotionsInterface $fetchCustomerCountsForPromotionsUpdatePromotionCountInterface $updatePromotionCount)
  18.     {
  19.         $this->lineItemIsFreeGift $lineItemIsFreeGift;
  20.         $this->fetchCustomerCountsForPromotions $fetchCustomerCountsForPromotions;
  21.         $this->updatePromotionCount $updatePromotionCount;
  22.     }
  23.     public static function getSubscribedEvents(): array
  24.     {
  25.         return [
  26.             CheckoutOrderPlacedEvent::class => '__invoke',
  27.         ];
  28.     }
  29.     public function __invoke(CheckoutOrderPlacedEvent $event): void
  30.     {
  31.         $lineItems $event->getOrder()->getLineItems();
  32.         $customer $event->getOrder()->getOrderCustomer();
  33.         if (!$lineItems || !$customer) {
  34.             return;
  35.         }
  36.         $customerId $customer->getCustomerId();
  37.         $promotionIds = [];
  38.         foreach ($lineItems as $lineItem) {
  39.             if (!($this->lineItemIsFreeGift)($lineItem)) {
  40.                 continue;
  41.             }
  42.             $promotionId $this->fetchPromotionId($lineItem);
  43.             if (!$promotionId) {
  44.                 continue;
  45.             }
  46.             $promotionIds[] = $promotionId;
  47.         }
  48.         if (=== count($promotionIds)) {
  49.             return;
  50.         }
  51.         $promotionsUsedByCustomersCount = ($this->fetchCustomerCountsForPromotions)($promotionIds);
  52.         $calculatedPromotionsUsedByCustomer = [];
  53.         foreach ($promotionIds as $promotionId) {
  54.             $calculatedPromotionsUsedByCustomer[$promotionId] = $this->calculatePromotionUsedByCustomer(
  55.                 $promotionsUsedByCustomersCount,
  56.                 $promotionId,
  57.                 $customerId
  58.             );
  59.         }
  60.         ($this->updatePromotionCount)($promotionIds$calculatedPromotionsUsedByCustomer);
  61.     }
  62.     private function calculatePromotionUsedByCustomer(array $allCustomerCounts$promotionId$customerId): array
  63.     {
  64.         $promotionUsedByCustomers $allCustomerCounts[$promotionId] ?? null;
  65.         if (null === $promotionUsedByCustomers) {
  66.             // Prepare array if code isn't used yet
  67.             $allCustomerCounts[$promotionId] = [];
  68.         }
  69.         $promotionUsedByCurrentCustomer $promotionUsedByCustomers[$customerId] ?? null;
  70.         if (null === $promotionUsedByCurrentCustomer) {
  71.             // initiate count if customer hasn't used promotion yet
  72.             $promotionUsedByCustomers[$customerId] = 1;
  73.             return $promotionUsedByCustomers;
  74.         }
  75.         // +1 if customer has used this code before
  76.         $promotionUsedByCustomers[$customerId] = $promotionUsedByCurrentCustomer 1;
  77.         return $promotionUsedByCustomers;
  78.     }
  79.     private function fetchPromotionId(OrderLineItemEntity $lineItem): ?string
  80.     {
  81.         $payload $lineItem->getPayload();
  82.         $payloadPromotionIdKey $payload[GiftProcessor::PAYLOAD_PROMOTION_ID_KEY] ?? null;
  83.         if (null === $payloadPromotionIdKey) {
  84.             return null;
  85.         }
  86.         $promotionId $payload[GiftProcessor::PAYLOAD_PROMOTION_ID_KEY] ?? null;
  87.         if (!Uuid::isValid((string) $promotionId)) {
  88.             return null;
  89.         }
  90.         return (string) $promotionId;
  91.     }
  92. }