function it_does_not_apply_bigger_promotions_than_unit_total($adjustmentFactory, $originator, $priceRangeFilter, $taxonFilter, AdjustmentInterface $promotionAdjustment1, AdjustmentInterface $promotionAdjustment2, Collection $originalItems, Collection $units, OrderInterface $order, OrderItemInterface $orderItem1, OrderItemInterface $orderItem2, OrderItemInterface $orderItem3, OrderItemUnitInterface $unit1, OrderItemUnitInterface $unit2, PromotionInterface $promotion)
 {
     $order->getItems()->willReturn($originalItems);
     $originalItems->toArray()->willReturn([$orderItem1, $orderItem2, $orderItem3]);
     $priceRangeFilter->filter([$orderItem1, $orderItem2, $orderItem3], ['amount' => 1000, 'filters' => ['taxons' => ['testTaxon']]])->willReturn([$orderItem1, $orderItem3]);
     $taxonFilter->filter([$orderItem1, $orderItem3], ['amount' => 1000, 'filters' => ['taxons' => ['testTaxon']]])->willReturn([$orderItem1]);
     $orderItem1->getQuantity()->willReturn(2);
     $orderItem1->getUnits()->willReturn($units);
     $units->getIterator()->willReturn(new \ArrayIterator([$unit1->getWrappedObject(), $unit2->getWrappedObject()]));
     $promotion->getName()->willReturn('Test promotion');
     $adjustmentFactory->createNew()->willReturn($promotionAdjustment1, $promotionAdjustment2);
     $unit1->getTotal()->willReturn(300);
     $promotionAdjustment1->setType(AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT)->shouldBeCalled();
     $promotionAdjustment1->setLabel('Test promotion')->shouldBeCalled();
     $promotionAdjustment1->setAmount(-300)->shouldBeCalled();
     $originator->setOrigin($promotionAdjustment1, $promotion)->shouldBeCalled();
     $unit2->getTotal()->willReturn(200);
     $promotionAdjustment2->setType(AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT)->shouldBeCalled();
     $promotionAdjustment2->setLabel('Test promotion')->shouldBeCalled();
     $promotionAdjustment2->setAmount(-200)->shouldBeCalled();
     $originator->setOrigin($promotionAdjustment2, $promotion)->shouldBeCalled();
     $unit1->addAdjustment($promotionAdjustment1)->shouldBeCalled();
     $unit2->addAdjustment($promotionAdjustment2)->shouldBeCalled();
     $this->execute($order, ['amount' => 1000, 'filters' => ['taxons' => ['testTaxon']]], $promotion);
 }
 function it_applies_percentage_discount_on_every_unit_in_order(FactoryInterface $adjustmentFactory, FilterInterface $priceRangeFilter, FilterInterface $taxonFilter, FilterInterface $productFilter, AdjustmentInterface $promotionAdjustment1, AdjustmentInterface $promotionAdjustment2, Collection $originalItems, Collection $units, OrderInterface $order, OrderItemInterface $orderItem1, OrderItemUnitInterface $unit1, OrderItemUnitInterface $unit2, PromotionInterface $promotion)
 {
     $order->getItems()->willReturn($originalItems);
     $originalItems->toArray()->willReturn([$orderItem1]);
     $priceRangeFilter->filter([$orderItem1], ['percentage' => 0.2])->willReturn([$orderItem1]);
     $taxonFilter->filter([$orderItem1], ['percentage' => 0.2])->willReturn([$orderItem1]);
     $productFilter->filter([$orderItem1], ['percentage' => 0.2])->willReturn([$orderItem1]);
     $orderItem1->getQuantity()->willReturn(2);
     $orderItem1->getUnits()->willReturn($units);
     $units->getIterator()->willReturn(new \ArrayIterator([$unit1->getWrappedObject(), $unit2->getWrappedObject()]));
     $orderItem1->getUnitPrice()->willReturn(500);
     $promotion->getName()->willReturn('Test promotion');
     $promotion->getCode()->willReturn('TEST_PROMOTION');
     $adjustmentFactory->createNew()->willReturn($promotionAdjustment1, $promotionAdjustment2);
     $promotionAdjustment1->setType(AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT)->shouldBeCalled();
     $promotionAdjustment1->setLabel('Test promotion')->shouldBeCalled();
     $promotionAdjustment1->setAmount(-100)->shouldBeCalled();
     $promotionAdjustment1->setOriginCode('TEST_PROMOTION')->shouldBeCalled();
     $promotionAdjustment2->setType(AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT)->shouldBeCalled();
     $promotionAdjustment2->setLabel('Test promotion')->shouldBeCalled();
     $promotionAdjustment2->setAmount(-100)->shouldBeCalled();
     $promotionAdjustment2->setOriginCode('TEST_PROMOTION')->shouldBeCalled();
     $unit1->addAdjustment($promotionAdjustment1)->shouldBeCalled();
     $unit2->addAdjustment($promotionAdjustment2)->shouldBeCalled();
     $this->execute($order, ['percentage' => 0.2], $promotion);
 }
 function it_does_not_apply_promotions_with_amount_0($adjustmentFactory, $distributor, $originator, $priceRangeFilter, $taxonFilter, AdjustmentInterface $promotionAdjustment1, Collection $originalItems, Collection $units, OrderInterface $order, OrderItemInterface $orderItem1, OrderItemInterface $orderItem2, OrderItemInterface $orderItem3, OrderItemUnitInterface $unit1, OrderItemUnitInterface $unit2, PromotionInterface $promotion)
 {
     $order->getItems()->willReturn($originalItems);
     $originalItems->toArray()->willReturn([$orderItem1, $orderItem2, $orderItem3]);
     $priceRangeFilter->filter([$orderItem1, $orderItem2, $orderItem3], ['percentage' => 0.2, 'filters' => ['taxons' => ['testTaxon']]])->willReturn([$orderItem1, $orderItem2]);
     $taxonFilter->filter([$orderItem1, $orderItem2], ['percentage' => 0.2, 'filters' => ['taxons' => ['testTaxon']]])->willReturn([$orderItem1]);
     $orderItem1->getQuantity()->willReturn(2);
     $orderItem1->getUnits()->willReturn($units);
     $units->getIterator()->willReturn(new \ArrayIterator([$unit1->getWrappedObject(), $unit2->getWrappedObject()]));
     $orderItem1->getTotal()->willReturn(5);
     $distributor->distribute(1, 2)->willReturn([1, 0]);
     $promotion->getName()->willReturn('Test promotion');
     $adjustmentFactory->createNew()->willReturn($promotionAdjustment1);
     $promotionAdjustment1->setType(AdjustmentInterface::ORDER_ITEM_PROMOTION_ADJUSTMENT)->shouldBeCalled();
     $promotionAdjustment1->setLabel('Test promotion')->shouldBeCalled();
     $promotionAdjustment1->setAmount(-1)->shouldBeCalled();
     $originator->setOrigin($promotionAdjustment1, $promotion)->shouldBeCalled();
     $unit1->addAdjustment($promotionAdjustment1)->shouldBeCalled();
     $unit2->addAdjustment(Argument::any())->shouldNotBeCalled();
     $this->execute($order, ['percentage' => 0.2, 'filters' => ['taxons' => ['testTaxon']]], $promotion);
 }
 function it_does_not_apply_bigger_discount_than_unit_total(ChannelInterface $channel, FactoryInterface $adjustmentFactory, FilterInterface $priceRangeFilter, FilterInterface $taxonFilter, FilterInterface $productFilter, AdjustmentInterface $promotionAdjustment1, AdjustmentInterface $promotionAdjustment2, OrderInterface $order, OrderItemInterface $orderItem, OrderItemUnitInterface $unit1, OrderItemUnitInterface $unit2, PromotionInterface $promotion)
 {
     $order->getChannel()->willReturn($channel);
     $channel->getCode()->willReturn('WEB_US');
     $order->getItems()->willReturn(new ArrayCollection([$orderItem]));
     $order->getChannel()->willReturn($channel);
     $priceRangeFilter->filter([$orderItem], ['amount' => 1000, 'channel' => $channel])->willReturn([$orderItem]);
     $taxonFilter->filter([$orderItem], ['amount' => 1000])->willReturn([$orderItem]);
     $productFilter->filter([$orderItem], ['amount' => 1000])->willReturn([$orderItem]);
     $orderItem->getQuantity()->willReturn(2);
     $orderItem->getUnits()->willReturn(new ArrayCollection([$unit1->getWrappedObject(), $unit2->getWrappedObject()]));
     $promotion->getName()->willReturn('Test promotion');
     $promotion->getCode()->willReturn('TEST_PROMOTION');
     $adjustmentFactory->createNew()->willReturn($promotionAdjustment1, $promotionAdjustment2);
     $unit1->getTotal()->willReturn(300);
     $promotionAdjustment1->setType(AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT)->shouldBeCalled();
     $promotionAdjustment1->setLabel('Test promotion')->shouldBeCalled();
     $promotionAdjustment1->setAmount(-300)->shouldBeCalled();
     $promotionAdjustment1->setOriginCode('TEST_PROMOTION')->shouldBeCalled();
     $unit2->getTotal()->willReturn(200);
     $promotionAdjustment2->setType(AdjustmentInterface::ORDER_UNIT_PROMOTION_ADJUSTMENT)->shouldBeCalled();
     $promotionAdjustment2->setLabel('Test promotion')->shouldBeCalled();
     $promotionAdjustment2->setAmount(-200)->shouldBeCalled();
     $promotionAdjustment2->setOriginCode('TEST_PROMOTION')->shouldBeCalled();
     $unit1->addAdjustment($promotionAdjustment1)->shouldBeCalled();
     $unit2->addAdjustment($promotionAdjustment2)->shouldBeCalled();
     $this->execute($order, ['WEB_US' => ['amount' => 1000]], $promotion)->shouldReturn(true);
 }