ldc-mesbr-app/src/Domain/Models/ValueObjects/RequestedCoupon/RequestedCoupon.php
2026-10-02 12:48:00 +02:00

80 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Domain\Models\ValueObjects\RequestedCoupon;
use Domain\Models\ValueObjects\Coupon\CouponValidity;
use Domain\Models\ValueObjects\Coupon\CouponValidityInformation;
use Domain\Models\ValueObjects\CouponName;
use Domain\Models\ValueObjects\GS1;
use Domain\Models\ValueObjects\IncoCode;
use Domain\Models\ValueObjects\MoneyAmount;
use Domain\Models\ValueObjects\Period;
use Domain\Models\ValueObjects\PrintRules;
use Domain\Models\ValueObjects\ProcessingCode;
use Domain\Models\ValueObjects\WarningThresholdQuantity;
use Shared\Enums\Country;
final readonly class RequestedCoupon
{
private const int DEFAULT_WARNING_THRESHOLD_QUANTITY = 100;
private const int MIN_FACE_VALUE_IN_CENTS = 1;
private const int MAX_FACE_VALUE_IN_CENTS = 300;
public WarningThresholdQuantity $warningThresholdQuantity;
/**
* @param array<CouponValidityInformation> $couponValidityInformation
* @param array<IncoCode> $products
*/
public function __construct(
public CouponName $name,
public RequestedCouponQuantity $quantity,
public Period $diffusion,
public MoneyAmount $moneyAmount,
public ProcessingCode $processingCode,
public CouponValidity $couponValidity,
public array $couponValidityInformation,
public array $products = [],
public ?PrintRules $printRules = null,
public ?GS1 $gs1 = null,
?WarningThresholdQuantity $warningThresholdQuantity = null,
) {
$money = $this->moneyAmount->value;
foreach ($this->couponValidityInformation as $validityInformation) {
if (!$validityInformation instanceof CouponValidityInformation) {
throw new \DomainException('Coupon validity information must be CouponValidityInformation instances.');
}
}
if ($money->value < self::MIN_FACE_VALUE_IN_CENTS || $money->value > self::MAX_FACE_VALUE_IN_CENTS) {
throw new \DomainException(sprintf(
'Coupon face value must be between 0.01€ and 3.00€, %s given.',
$money,
));
}
if (!$this->hasValidityInformationFor(Country::FRANCE)) {
throw new \DomainException('A coupon requires validity information for France.');
}
if ($this->gs1 instanceof GS1 && !$this->hasValidityInformationFor(Country::BENELUX)) {
throw new \DomainException('A GS1 coupon requires validity information for Benelux.');
}
$this->warningThresholdQuantity = $warningThresholdQuantity ?? new WarningThresholdQuantity(self::DEFAULT_WARNING_THRESHOLD_QUANTITY);
}
private function hasValidityInformationFor(Country $country): bool
{
foreach ($this->couponValidityInformation as $validityInformation) {
if ($validityInformation->forLocale === $country) {
return true;
}
}
return false;
}
}