Validate the charge types support in a checkout with any given gateway

This commit is contained in:
2024-10-23 14:31:50 +02:00
parent f512754016
commit c7b4ab0fee
3 changed files with 60 additions and 0 deletions
+2
View File
@@ -9,6 +9,7 @@ use App\Entity\Trait\TimestampableUpdationEntity;
use App\Repository\GatewayCheckoutRepository;
use App\State\GatewayCheckoutProcessor;
use App\Validator\GatewayName;
use App\Validator\SupportedChargeTypes;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
@@ -63,6 +64,7 @@ class GatewayCheckout
#[API\ApiProperty(readableLink: true, writableLink: true)]
#[Assert\NotBlank()]
#[Assert\Count(min: 1)]
#[SupportedChargeTypes()]
#[ORM\OneToMany(mappedBy: 'checkout', targetEntity: GatewayCharge::class, cascade: ['persist'])]
private Collection $charges;
+14
View File
@@ -0,0 +1,14 @@
<?php
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
/**
* Validates that a GatewayCheckout has GatewayCharges with charge types supported by the given Gateway.
*/
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
class SupportedChargeTypes extends Constraint
{
public string $message = 'The charge type "{{ value }}" is not supported by the "{{ gateway }}" Gateway.';
}
@@ -0,0 +1,44 @@
<?php
namespace App\Validator;
use App\Library\Economy\Payment\GatewayLocator;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class SupportedChargeTypesValidator extends ConstraintValidator
{
public function __construct(
private GatewayLocator $gatewayLocator
) {}
public function validate(mixed $value, Constraint $constraint): void
{
if ($value === null || $value === '') {
return;
}
if (!$value instanceof Collection) {
return;
}
/** @var Collection<int, \App\Entity\GatewayCharge> */
$charges = $value;
$checkout = $charges->toArray()[0]->getCheckout();
$gateway = $this->gatewayLocator->getGatewayOf($checkout);
foreach ($charges as $charge) {
if (!\in_array(
$charge->getType(),
$gateway->getSupportedChargeTypes()
)) {
$this->context->buildViolation($constraint->message)
->setParameter('{{ value }}', $charge->getType()->value)
->setParameter('{{ gateway }}', $gateway->getName())
->addViolation();
}
}
}
}