Files
myep/src/Service/VoucherValidator.php
T

132 lines
4.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Service;
use App\BusProNet\ApiClient;
use App\BusProNet\Exception\ApiClientException;
use App\BusProNet\Model\Notification;
use App\BusProNet\Model\PromoVoucherValidationResult;
use App\BusProNet\Model\PurchaseVoucherValidationResult;
use Psr\Log\LoggerInterface;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
class VoucherValidator
{
private const CACHE_TTL = 900; // 15 minutes
public function __construct(
private readonly ApiClient $apiClient,
private readonly CacheInterface $cache,
private readonly LoggerInterface $logger,
) {
}
public function validatePurchaseVoucher(
string $redemptionCode,
): PurchaseVoucherValidationResult {
$cacheKey = sprintf('voucher.purchase.%s', md5($redemptionCode));
try {
return $this->cache->get($cacheKey, function (ItemInterface $item) use ($redemptionCode) {
$item->expiresAfter(self::CACHE_TTL);
try {
$result = $this->apiClient->validatePurchaseVoucher($redemptionCode);
if ($result instanceof Notification) {
return new PurchaseVoucherValidationResult(
isValid: false,
errorMessage: $result->message,
errorCode: $result->code
);
}
return new PurchaseVoucherValidationResult(
isValid: true,
voucher: $result
);
} catch (ApiClientException $e) {
$this->logger->error('Purchase voucher validation failed', [
'redemptionCode' => $redemptionCode,
'error' => $e->getMessage(),
]);
return new PurchaseVoucherValidationResult(
isValid: false,
errorMessage: 'Die Gutschein-Validierung ist fehlgeschlagen.'
);
}
});
} catch (\Exception $e) {
$this->logger->error('Cache error during purchase voucher validation', [
'error' => $e->getMessage(),
]);
return new PurchaseVoucherValidationResult(
isValid: false,
errorMessage: 'Ein technischer Fehler ist aufgetreten.'
);
}
}
public function validatePromoVoucher(
string $promoCode,
int $travelId,
float $participantPrice,
): PromoVoucherValidationResult {
$cacheKey = sprintf(
'voucher.promo.%s.%d.%s',
md5($promoCode),
$travelId,
md5((string) $participantPrice)
);
try {
return $this->cache->get($cacheKey, function (ItemInterface $item) use ($promoCode, $travelId, $participantPrice) {
$item->expiresAfter(self::CACHE_TTL);
try {
$result = $this->apiClient->validatePromoVoucher($promoCode, $travelId, $participantPrice);
if ($result instanceof Notification) {
return new PromoVoucherValidationResult(
isValid: false,
errorMessage: $result->message,
errorCode: $result->code
);
}
return new PromoVoucherValidationResult(
isValid: true,
voucher: $result
);
} catch (ApiClientException $e) {
$this->logger->error('Promo voucher validation failed', [
'promoCode' => $promoCode,
'travelId' => $travelId,
'participantPrice' => $participantPrice,
'error' => $e->getMessage(),
]);
return new PromoVoucherValidationResult(
isValid: false,
errorMessage: 'Die Aktionscode-Validierung ist fehlgeschlagen.'
);
}
});
} catch (\Exception $e) {
$this->logger->error('Cache error during promo voucher validation', [
'error' => $e->getMessage(),
]);
return new PromoVoucherValidationResult(
isValid: false,
errorMessage: 'Ein technischer Fehler ist aufgetreten.'
);
}
}
}