/**
  * {@inheritdoc}
  */
 public function isEligible(PromotionSubjectInterface $promotionSubject, PromotionInterface $promotion)
 {
     if (!$promotion->isCouponBased()) {
         throw new UnsupportedPromotionException('Only coupon based promotions can be evaluated by this checker.');
     }
     if (!$promotionSubject instanceof OrderInterface) {
         return false;
     }
     $coupon = $promotionSubject->getPromotionCoupon();
     if (!$coupon instanceof CouponInterface) {
         return false;
     }
     if ($promotion !== $coupon->getPromotion()) {
         return false;
     }
     $couponUsageLimit = $coupon->getPerCustomerUsageLimit();
     if (0 === $couponUsageLimit) {
         return true;
     }
     $customer = $promotionSubject->getCustomer();
     if (null === $customer) {
         return false;
     }
     $placedOrdersNumber = $this->orderRepository->countByCustomerAndCoupon($customer, $coupon);
     // <= because we need to include the cart orders as well
     return $placedOrdersNumber <= $couponUsageLimit;
 }
 private function isCouponEligible(CouponInterface $coupon, PromotionInterface $promotion, CustomerInterface $customer)
 {
     $countPlacedOrders = $this->subjectRepository->countByCustomerAndCoupon($customer, $coupon);
     // <= because we need to include the cart orders as well
     if ($countPlacedOrders <= $coupon->getPerCustomerUsageLimit()) {
         $this->dispatcher->dispatch(SyliusPromotionEvents::COUPON_ELIGIBLE, new GenericEvent($promotion));
         return true;
     }
     return false;
 }
 /**
  * @param CouponInterface $coupon
  * @param CustomerInterface|null $customer
  *
  * @return bool
  */
 private function isCouponEligibleToLimit(CouponInterface $coupon, CustomerInterface $customer = null)
 {
     $couponUsageLimit = $coupon->getPerCustomerUsageLimit();
     if (0 === $couponUsageLimit) {
         return true;
     }
     if (null === $customer) {
         return false;
     }
     $placedOrdersNumber = $this->orderRepository->countByCustomerAndCoupon($customer, $coupon);
     // <= because we need to include the cart orders as well
     return $placedOrdersNumber <= $couponUsageLimit;
 }
 function it_returns_true_if_promotion_coupon_has_not_reached_its_per_customer_usage_limit(OrderRepositoryInterface $orderRepository, OrderInterface $promotionSubject, CorePromotionCouponInterface $promotionCoupon, CustomerInterface $customer)
 {
     $promotionSubject->getCustomer()->willReturn($customer);
     $promotionCoupon->getPerCustomerUsageLimit()->willReturn(42);
     $orderRepository->countByCustomerAndCoupon($customer, $promotionCoupon)->willReturn(41);
     $this->isEligible($promotionSubject, $promotionCoupon)->shouldReturn(true);
 }
 /**
  * {@inheritdoc}
  */
 public function isEligible(PromotionSubjectInterface $promotionSubject, PromotionCouponInterface $promotionCoupon)
 {
     if (!$promotionSubject instanceof OrderInterface) {
         return true;
     }
     if (!$promotionCoupon instanceof CorePromotionCouponInterface) {
         return true;
     }
     $perCustomerUsageLimit = $promotionCoupon->getPerCustomerUsageLimit();
     if ($perCustomerUsageLimit === null) {
         return true;
     }
     $customer = $promotionSubject->getCustomer();
     if ($customer === null) {
         return true;
     }
     $placedOrdersNumber = $this->orderRepository->countByCustomerAndCoupon($customer, $promotionCoupon);
     return $placedOrdersNumber < $perCustomerUsageLimit;
 }
 function it_returns_false_if_subject_coupon_is_eligible_to_promotion_and_number_of_usages_is_bigger_than_coupon_usage_limit(OrderRepositoryInterface $orderRepository, OrderInterface $subject, PromotionInterface $promotion, CouponInterface $coupon, CustomerInterface $customer)
 {
     $subject->getPromotionCoupon()->willReturn($coupon);
     $promotion->isCouponBased()->willReturn(true);
     $subject->getCustomer()->willReturn($customer);
     $coupon->getPromotion()->willReturn($promotion);
     $coupon->getPerCustomerUsageLimit()->willReturn(5);
     $orderRepository->countByCustomerAndCoupon($customer, $coupon)->willReturn(6);
     $this->isEligible($subject, $promotion)->shouldReturn(false);
 }
 function it_dispatches_event_and_returns_false_if_subject_coupon_is_eligible_to_promotion_and_number_of_usages_is_bigger_than_coupon_usage_limit(CouponInterface $coupon, CustomerInterface $customer, EventDispatcherInterface $eventDispatcher, OrderInterface $subject, OrderRepositoryInterface $orderRepository, PromotionInterface $promotion)
 {
     $subject->getPromotionCoupon()->willReturn($coupon);
     $coupon->getPromotion()->willReturn($promotion);
     $subject->getCustomer()->willReturn($customer);
     $coupon->getPerCustomerUsageLimit()->willReturn(5);
     $orderRepository->countByCustomerAndCoupon($customer, $coupon)->willReturn(6);
     $eventDispatcher->dispatch(SyliusPromotionEvents::COUPON_NOT_ELIGIBLE, Argument::type(GenericEvent::class))->shouldBeCalled();
     $this->isEligible($subject, $promotion)->shouldReturn(false);
 }