feat: fold purchase and promo voucher fields into one code field
This commit is contained in:
1 parent
93512b8345
commit
21d756a2e3
21 files changed
+801
-432
No files matched your search
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Enum\VoucherCodeKind;
|
||||
|
||||
/**
|
||||
* Tells promo codes and purchase codes apart, so the booking form needs only one voucher field.
|
||||
*
|
||||
* Promo codes are prefixed "R-". Purchase codes (Kauf and Kulanz) consist of uppercase letters only
|
||||
* and never contain a hyphen, so the prefix cannot collide with them. Promo codes issued before the
|
||||
* prefix was introduced are recognised from `legacy_promo_voucher_codes` until their date has passed.
|
||||
*/
|
||||
class VoucherCodeClassifier
|
||||
{
|
||||
public const PROMO_PREFIX = 'R-';
|
||||
|
||||
private const MAX_LENGTH = 50;
|
||||
|
||||
/** @var array<string, \DateTimeImmutable> Normalised code => last day the code is recognised */
|
||||
private readonly array $legacyPromoCodes;
|
||||
|
||||
/**
|
||||
* @param array<string, string> $legacyPromoCodes Code => last day it is accepted (Y-m-d)
|
||||
*/
|
||||
public function __construct(array $legacyPromoCodes = [])
|
||||
{
|
||||
$codes = [];
|
||||
foreach ($legacyPromoCodes as $code => $lastDay) {
|
||||
$codes[$this->normalize((string) $code)] = new \DateTimeImmutable($lastDay);
|
||||
}
|
||||
|
||||
$this->legacyPromoCodes = $codes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Codes are matched case-insensitively; BusPro receives them in uppercase.
|
||||
*/
|
||||
public function normalize(string $code): string
|
||||
{
|
||||
return mb_strtoupper(trim($code));
|
||||
}
|
||||
|
||||
public function classify(string $code, \DateTimeImmutable $today = new \DateTimeImmutable('today')): VoucherCodeKind
|
||||
{
|
||||
$code = $this->normalize($code);
|
||||
|
||||
if ('' === $code || mb_strlen($code) > self::MAX_LENGTH || 1 !== preg_match('/^[A-Z0-9\-]+$/', $code)) {
|
||||
return VoucherCodeKind::Malformed;
|
||||
}
|
||||
|
||||
if (str_starts_with($code, self::PROMO_PREFIX)) {
|
||||
return VoucherCodeKind::Promo;
|
||||
}
|
||||
|
||||
$lastDay = $this->legacyPromoCodes[$code] ?? null;
|
||||
if (null !== $lastDay && $lastDay >= $today) {
|
||||
return VoucherCodeKind::Promo;
|
||||
}
|
||||
|
||||
if (str_contains($code, '-')) {
|
||||
return VoucherCodeKind::Malformed;
|
||||
}
|
||||
|
||||
return VoucherCodeKind::Purchase;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user