scopeConfig->isSetFlag( self::XML_PATH_ENABLED, ScopeInterface::SCOPE_STORE, $storeId ); } public function getGiftSku(?int $storeId = null): string { return trim((string)$this->scopeConfig->getValue( self::XML_PATH_GIFT_SKU, ScopeInterface::SCOPE_STORE, $storeId )); } public function isGiftSku(string $sku, ?int $storeId = null): bool { $giftSku = $this->getGiftSku($storeId); return $giftSku !== '' && strcasecmp($giftSku, trim($sku)) === 0; } public function isActive(?int $storeId = null): bool { if (!$this->isEnabled($storeId) || $this->getGiftSku($storeId) === '') { return false; } $today = $this->timezone->scopeDate($storeId)->format('Y-m-d'); $startDate = $this->normalizeDate($this->getValue(self::XML_PATH_START_DATE, $storeId)); $endDate = $this->normalizeDate($this->getValue(self::XML_PATH_END_DATE, $storeId)); return ($startDate === '' || $today >= $startDate) && ($endDate === '' || $today <= $endDate); } public function getTargetQuantity(float $eligibleBaseSubtotal, ?int $storeId = null): int { if (!$this->isActive($storeId)) { return 0; } $targetQuantity = 0; $subtotal = round(max(0.0, $eligibleBaseSubtotal), 2); foreach ($this->getTiers($storeId) as $tier) { if ($subtotal + 0.0001 >= $tier['amount']) { $targetQuantity = $tier['qty']; } } return $targetQuantity; } /** @return array */ public function getTiers(?int $storeId = null): array { $configuredTiers = $this->getConfiguredTiers($storeId); if ($configuredTiers !== []) { return $configuredTiers; } $tiers = []; for ($index = 1; $index <= 3; $index++) { $amount = max(0.0, (float)$this->getValue(sprintf(self::XML_PATH_TIER_AMOUNT, $index), $storeId)); $quantity = max(0, (int)$this->getValue(sprintf(self::XML_PATH_TIER_QTY, $index), $storeId)); if ($quantity > 0) { $tiers[] = ['amount' => $amount, 'qty' => $quantity]; } } usort( $tiers, static fn (array $left, array $right): int => $left['amount'] <=> $right['amount'] ); return $tiers; } /** @return array */ private function getConfiguredTiers(?int $storeId): array { $value = $this->scopeConfig->getValue( self::XML_PATH_TIER_ITEMS, ScopeInterface::SCOPE_STORE, $storeId ); try { $items = is_array($value) ? $value : (trim((string)$value) === '' ? [] : $this->serializer->unserialize((string)$value)); } catch (\InvalidArgumentException) { return []; } if (!is_array($items)) { return []; } $tiers = []; foreach ($items as $item) { if (!is_array($item)) { continue; } $quantity = max(0, (int)($item['qty'] ?? 0)); if ($quantity <= 0) { continue; } $tiers[] = [ 'amount' => max(0.0, (float)($item['amount'] ?? 0)), 'qty' => $quantity, ]; } usort($tiers, static fn (array $left, array $right): int => $left['amount'] <=> $right['amount']); return $tiers; } private function getValue(string $path, ?int $storeId = null): string { return trim((string)$this->scopeConfig->getValue( $path, ScopeInterface::SCOPE_STORE, $storeId )); } private function normalizeDate(string $value): string { if ($value === '') { return ''; } $timestamp = strtotime($value); return $timestamp === false ? '' : date('Y-m-d', $timestamp); } }