feat: add validation for charges targetting projects not in campaign

This commit is contained in:
2026-08-26 11:52:03 +02:00
parent 4d4de0fc7b
commit 40ff4b5ca4
4 changed files with 61 additions and 0 deletions
@@ -17,6 +17,7 @@ use App\Gateway\Tracking;
use App\Mapping\Transformer\GatewayIdMapTransformer;
use App\State\ApiResourceStateProvider;
use App\State\Gateway\CheckoutStateProcessor;
use App\Validator\ChargeToProjectInCampaign;
use AutoMapper\Attribute\MapFrom;
use AutoMapper\Attribute\MapTo;
use Symfony\Component\Validator\Constraints as Assert;
@@ -70,6 +71,7 @@ class CheckoutApiResource
#[API\ApiProperty(readableLink: true, writableLink: true)]
#[Assert\NotBlank()]
#[Assert\Count(min: 1)]
#[Assert\All([new ChargeToProjectInCampaign()])]
public array $charges = [];
/**
+2
View File
@@ -8,6 +8,7 @@ use App\ApiResource\Gateway\GatewayApiResource;
use App\Entity\Gateway\Checkout;
use App\Gateway\RefundStrategy;
use App\Mapping\Transformer\GatewayIdMapTransformer;
use App\Validator\ChargeToProjectInCampaign;
use AutoMapper\Attribute\MapFrom;
use AutoMapper\Attribute\MapTo;
use Symfony\Component\Validator\Constraints as Assert;
@@ -37,6 +38,7 @@ class CheckoutCreationDto
#[API\ApiProperty(readableLink: true, writableLink: true)]
#[Assert\NotBlank()]
#[Assert\Count(min: 1)]
#[Assert\All([new ChargeToProjectInCampaign()])]
public array $charges = [];
/**
@@ -0,0 +1,11 @@
<?php
namespace App\Validator;
use Symfony\Component\Validator\Constraint;
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
final class ChargeToProjectInCampaign extends Constraint
{
public string $message = 'The targeted Project {{ project }} behind Accounting {{ target }} is not in a status where it can receive Charges.';
}
@@ -0,0 +1,46 @@
<?php
namespace App\Validator;
use App\ApiResource\Gateway\ChargeApiResource;
use App\Dto\Gateway\ChargeCreationDto;
use App\Entity\Accounting\Accounting;
use App\Entity\Project\ProjectStatus;
use App\Mapping\AutoMapper;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
final class ChargeToProjectInCampaignValidator extends ConstraintValidator
{
public function __construct(
private AutoMapper $mapper,
) {}
/**
* @param ChargeApiResource|ChargeCreationDto $value
* @param ChargeToProjectInCampaign $constraint
*/
public function validate(mixed $value, Constraint $constraint): void
{
if ($value === null || $value === '') {
return;
}
/** @var Accounting */
$target = $this->mapper->map($value->target, Accounting::class);
if ($target->getProject() === null) {
return;
}
if ($target->getProject()->getStatus() === ProjectStatus::InCampaign) {
return;
}
$this->context->buildViolation($constraint->message)
->setParameter('{{ target }}', $value->target->id)
->setParameter('{{ project }}', $target->getProject()->getId())
->addViolation()
;
}
}