promotionConfig->isCampaignActive() || !$this->promotionConfig->isRegistrationNewsletterCouponPromotion() || $this->hasAlreadyBeenGranted($customerId) ) { return false; } $ruleId = $this->config->getRegistrationSubscriptionRuleId($storeId ?: null); if ($ruleId <= 0) { return false; } /** @var Rule $rule */ $rule = $this->ruleFactory->create()->load($ruleId); $scope = $storeId > 0 ? $this->storeManager->getStore($storeId) : $this->storeManager->getStore(); if (!$rule->getId() || !$rule->getIsActive() || ((int)$rule->getCouponType() !== Rule::COUPON_TYPE_AUTO && !$rule->getUseAutoGeneration()) || !in_array($websiteId, array_map('intval', $rule->getWebsiteIds()), true) || !in_array($customerGroupId, array_map('intval', $rule->getCustomerGroupIds()), true) || !$this->timezone->isScopeDateInInterval($scope, $rule->getFromDate(), $rule->getToDate()) ) { throw new LocalizedException( __('The configured registration subscription coupon rule is not eligible for this customer.') ); } /** @var CouponGenerationSpecInterface $specification */ $specification = $this->generationSpecFactory->create(); $specification->setRuleId($ruleId) ->setQuantity(1) ->setLength(12) ->setFormat(CouponGenerationSpecInterface::COUPON_FORMAT_ALPHANUMERIC) ->setPrefix('WELCOME-') ->setDelimiterAtEvery(0); $codes = $this->couponManagement->generate($specification); if (count($codes) !== 1) { if ($codes) { $this->couponManagement->deleteByCodes($codes); } throw new LocalizedException(__('The registration subscription coupon could not be generated.')); } try { $this->assignmentService->assignCodes( $codes, [$customerId], $ruleId, self::ASSIGNMENT_SOURCE ); } catch (\Throwable $exception) { $this->couponManagement->deleteByCodes($codes); if ($this->hasAlreadyBeenGranted($customerId)) { return true; } throw $exception; } return true; } private function hasAlreadyBeenGranted(int $customerId): bool { $connection = $this->assignmentResource->getConnection(); $select = $connection->select() ->from($this->assignmentResource->getMainTable(), ['entity_id']) ->where('customer_id = ?', $customerId) ->where('source = ?', self::ASSIGNMENT_SOURCE) ->limit(1); return (bool)$connection->fetchOne($select); } }