function it_stops_chcecking_at_the_first_failing_eligibility_checker(PromotionEligibilityCheckerInterface $firstPromotionEligibilityChecker, PromotionEligibilityCheckerInterface $secondPromotionEligibilityChecker, PromotionSubjectInterface $promotionSubject, PromotionInterface $promotion)
 {
     $this->beConstructedWith([$firstPromotionEligibilityChecker, $secondPromotionEligibilityChecker]);
     $firstPromotionEligibilityChecker->isEligible($promotionSubject, $promotion)->willReturn(false);
     $secondPromotionEligibilityChecker->isEligible($promotionSubject, $promotion)->shouldNotBeCalled();
     $this->isEligible($promotionSubject, $promotion)->shouldReturn(false);
 }
 function it_reverts_promotions_that_are_not_eligible_anymore(PreQualifiedPromotionsProviderInterface $preQualifiedPromotionsProvider, PromotionEligibilityCheckerInterface $promotionEligibilityChecker, PromotionApplicatorInterface $promotionApplicator, PromotionSubjectInterface $subject, PromotionInterface $promotion)
 {
     $subject->getPromotions()->willReturn([$promotion]);
     $preQualifiedPromotionsProvider->getPromotions($subject)->willReturn([$promotion]);
     $promotionEligibilityChecker->isEligible($subject, $promotion)->willReturn(false);
     $promotionApplicator->apply($subject, $promotion)->shouldNotBeCalled();
     $promotionApplicator->revert($subject, $promotion)->shouldBeCalled();
     $this->process($subject);
 }
 /**
  * {@inheritdoc}
  */
 public function validate($value, Constraint $constraint)
 {
     /** @var PromotionSubjectCoupon $constraint */
     Assert::isInstanceOf($constraint, PromotionSubjectCoupon::class);
     if (!$value instanceof PromotionCouponAwarePromotionSubjectInterface) {
         return;
     }
     $promotionCoupon = $value->getPromotionCoupon();
     if ($promotionCoupon === null) {
         return;
     }
     if ($this->promotionEligibilityChecker->isEligible($value, $promotionCoupon->getPromotion())) {
         return;
     }
     $this->context->buildViolation($constraint->message)->atPath('promotionCoupon')->addViolation();
 }
 /**
  * {@inheritdoc}
  */
 public function process(PromotionSubjectInterface $subject)
 {
     foreach ($subject->getPromotions() as $promotion) {
         $this->promotionApplicator->revert($subject, $promotion);
     }
     $eligiblePromotions = [];
     foreach ($this->preQualifiedPromotionsProvider->getPromotions($subject) as $promotion) {
         if (!$this->promotionEligibilityChecker->isEligible($subject, $promotion)) {
             continue;
         }
         if ($promotion->isExclusive()) {
             $this->promotionApplicator->apply($subject, $promotion);
             return;
         }
         $eligiblePromotions[] = $promotion;
     }
     foreach ($eligiblePromotions as $promotion) {
         $this->promotionApplicator->apply($subject, $promotion);
     }
 }