diff --git a/src/ApiResource/Project/RewardClaimApiResource.php b/src/ApiResource/Project/RewardClaimApiResource.php index f9c1d38..6ddfd97 100644 --- a/src/ApiResource/Project/RewardClaimApiResource.php +++ b/src/ApiResource/Project/RewardClaimApiResource.php @@ -4,10 +4,13 @@ namespace App\ApiResource\Project; use ApiPlatform\Doctrine\Orm\State\Options; use ApiPlatform\Metadata as API; +use App\ApiResource\Gateway\ChargeApiResource; use App\ApiResource\User\UserApiResource; use App\Entity\Project\RewardClaim; use App\State\ApiResourceStateProvider; use App\State\Project\RewardClaimStateProcessor; +use App\Validator\AvailableRewardUnits; +use App\Validator\EnoughRewardCharge; use Symfony\Component\Validator\Constraints as Assert; /** @@ -19,20 +22,28 @@ use Symfony\Component\Validator\Constraints as Assert; provider: ApiResourceStateProvider::class, processor: RewardClaimStateProcessor::class )] +#[EnoughRewardCharge()] class RewardClaimApiResource { #[API\ApiProperty(identifier: true, writable: false)] public int $id; - /** - * The ProjectReward being claimed. - */ - #[Assert\NotBlank()] - public RewardApiResource $reward; - /** * The User claiming the ProjectReward. */ #[API\ApiProperty(writable: false)] public UserApiResource $owner; + + /** + * The GatewayCharge granting access to the ProjectReward. + */ + #[Assert\NotBlank()] + public ChargeApiResource $charge; + + /** + * The ProjectReward being claimed. + */ + #[Assert\NotBlank()] + #[AvailableRewardUnits()] + public RewardApiResource $reward; } diff --git a/src/Entity/Project/RewardClaim.php b/src/Entity/Project/RewardClaim.php index feecac3..1707ea5 100644 --- a/src/Entity/Project/RewardClaim.php +++ b/src/Entity/Project/RewardClaim.php @@ -2,6 +2,7 @@ namespace App\Entity\Project; +use App\Entity\Gateway\Charge; use App\Entity\Interface\UserOwnedInterface; use App\Entity\Trait\UserOwnedTrait; use App\Entity\User\User; @@ -22,6 +23,10 @@ class RewardClaim implements UserOwnedInterface #[ORM\Column] private ?int $id = null; + #[ORM\OneToOne(cascade: ['persist', 'remove'])] + #[ORM\JoinColumn(nullable: false)] + private ?Charge $charge = null; + #[ORM\ManyToOne(inversedBy: 'claims')] #[ORM\JoinColumn(nullable: false)] private ?Reward $reward = null; @@ -35,6 +40,18 @@ class RewardClaim implements UserOwnedInterface return $this->id; } + public function getCharge(): ?Charge + { + return $this->charge; + } + + public function setCharge(Charge $charge): static + { + $this->charge = $charge; + + return $this; + } + public function getReward(): ?Reward { return $this->reward; diff --git a/src/Service/Project/RewardService.php b/src/Service/Project/RewardService.php deleted file mode 100644 index 131c1c7..0000000 --- a/src/Service/Project/RewardService.php +++ /dev/null @@ -1,34 +0,0 @@ -getReward(); - - if (!$reward->hasUnits()) { - return $claim; - } - - $available = $reward->getUnitsAvailable(); - - if ($available < 1) { - throw new \Exception('The claimed Reward has no units available'); - } - - $reward->addClaim($claim); - $reward->setUnitsAvailable($available - 1); - - return $claim->setReward($reward); - } -} diff --git a/src/State/Project/RewardClaimStateProcessor.php b/src/State/Project/RewardClaimStateProcessor.php index d3c5a94..ea47d14 100644 --- a/src/State/Project/RewardClaimStateProcessor.php +++ b/src/State/Project/RewardClaimStateProcessor.php @@ -8,7 +8,6 @@ use App\ApiResource\Project\RewardClaimApiResource; use App\Entity\Project\RewardClaim; use App\Mapping\AutoMapper; use App\Service\Auth\AuthService; -use App\Service\Project\RewardService; use App\State\EntityStateProcessor; use Symfony\Component\Security\Core\Exception\AuthenticationException; @@ -18,7 +17,6 @@ class RewardClaimStateProcessor implements ProcessorInterface private EntityStateProcessor $entityStateProcessor, private AutoMapper $autoMapper, private AuthService $authService, - private RewardService $rewardService, ) {} /** @@ -41,7 +39,6 @@ class RewardClaimStateProcessor implements ProcessorInterface $claim->setOwner($owner); } - $claim = $this->rewardService->processClaim($claim); $claim = $this->entityStateProcessor->process($claim, $operation, $uriVariables, $context); return $this->autoMapper->map($claim, $data); diff --git a/src/State/Project/SupportStateProcessor.php b/src/State/Project/SupportStateProcessor.php index ec3002e..9276961 100644 --- a/src/State/Project/SupportStateProcessor.php +++ b/src/State/Project/SupportStateProcessor.php @@ -21,9 +21,13 @@ class SupportStateProcessor implements ProcessorInterface private EntityManagerInterface $entityManager, ) {} + /** + * @param SupportApiResource $data + * + * @return SupportApiResource + */ public function process(mixed $data, Operation $operation, array $uriVariables = [], array $context = []) { - // Verify if the user is authenticated $user = $this->authService->getUser(); if (!$user) { throw new AuthenticationException(); diff --git a/src/Validator/AvailableRewardUnits.php b/src/Validator/AvailableRewardUnits.php new file mode 100644 index 0000000..1414e62 --- /dev/null +++ b/src/Validator/AvailableRewardUnits.php @@ -0,0 +1,11 @@ +hasUnits) { + return; + } + + if ($value->hasUnits && $value->unitsAvailable > 0) { + return; + } + + $this->context->buildViolation($constraint->message) + ->setParameter('{{ id }}', $value->id) + ->addViolation() + ; + } +} diff --git a/src/Validator/EnoughRewardCharge.php b/src/Validator/EnoughRewardCharge.php new file mode 100644 index 0000000..f1bcb3c --- /dev/null +++ b/src/Validator/EnoughRewardCharge.php @@ -0,0 +1,16 @@ +charge->money; + $reward = $value->reward->money; + + if ($this->money->isMoreOrSame($charge, $reward)) { + return; + } + + $this->context->buildViolation($constraint->message) + ->addViolation() + ; + } +}