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_bigger_promotions_than_unit_total(FactoryInterface $adjustmentFactory, FilterInterface $priceRangeFilter, FilterInterface $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'); $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, ['amount' => 1000, 'filters' => ['taxons' => ['testTaxon']]], $promotion); }
function it_does_not_apply_a_discount_if_all_items_have_been_filtered_out(ChannelInterface $channel, FilterInterface $priceRangeFilter, FilterInterface $taxonFilter, FilterInterface $productFilter, OrderInterface $order, OrderItemInterface $orderItem, PromotionInterface $promotion) { $order->getChannel()->willReturn($channel); $channel->getCode()->willReturn('WEB_US'); $order->getItems()->willReturn(new ArrayCollection([$orderItem])); $order->getChannel()->willReturn($channel); $priceRangeFilter->filter([$orderItem], ['percentage' => 0.2, 'channel' => $channel])->willReturn([$orderItem]); $taxonFilter->filter([$orderItem], ['percentage' => 0.2])->willReturn([$orderItem]); $productFilter->filter([$orderItem], ['percentage' => 0.2])->willReturn([]); $this->execute($order, ['WEB_US' => ['percentage' => 0.2]], $promotion)->shouldReturn(false); }
/** * {@inheritdoc} */ public function execute(PromotionSubjectInterface $subject, array $configuration, PromotionInterface $promotion) { if (!$subject instanceof OrderInterface) { throw new UnexpectedTypeException($subject, OrderInterface::class); } $filteredItems = $this->priceRangeFilter->filter($subject->getItems()->toArray(), $configuration); $filteredItems = $this->taxonFilter->filter($filteredItems, $configuration); foreach ($filteredItems as $item) { $promotionAmount = (int) round($item->getUnitPrice() * $configuration['percentage']); $this->setUnitsAdjustments($item, $promotionAmount, $promotion); } }
/** * {@inheritdoc} */ public function execute(PromotionSubjectInterface $subject, array $configuration, PromotionInterface $promotion) { if (!$subject instanceof OrderInterface) { throw new UnexpectedTypeException($subject, OrderInterface::class); } if (0 === $configuration['amount']) { return; } $filteredItems = $this->priceRangeFilter->filter($subject->getItems()->toArray(), $configuration); $filteredItems = $this->taxonFilter->filter($filteredItems, $configuration); $filteredItems = $this->productFilter->filter($filteredItems, $configuration); foreach ($filteredItems as $item) { $this->setUnitsAdjustments($item, $configuration['amount'], $promotion); } }
/** * {@inheritdoc} */ public function execute(PromotionSubjectInterface $subject, array $configuration, PromotionInterface $promotion) { if (!$subject instanceof OrderInterface) { throw new UnexpectedTypeException($subject, OrderInterface::class); } $channelCode = $subject->getChannel()->getCode(); if (!isset($configuration[$channelCode]) || !isset($configuration[$channelCode]['percentage'])) { return false; } $filteredItems = $this->priceRangeFilter->filter($subject->getItems()->toArray(), array_merge(['channel' => $subject->getChannel()], $configuration[$channelCode])); $filteredItems = $this->taxonFilter->filter($filteredItems, $configuration[$channelCode]); $filteredItems = $this->productFilter->filter($filteredItems, $configuration[$channelCode]); if (empty($filteredItems)) { return false; } foreach ($filteredItems as $item) { $promotionAmount = (int) round($item->getUnitPrice() * $configuration[$channelCode]['percentage']); $this->setUnitsAdjustments($item, $promotionAmount, $promotion); } return true; }
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); }