Skip to content

Commit

Permalink
[CartPromotion] handle fixed and percentage order discount
Browse files Browse the repository at this point in the history
  • Loading branch information
SirDomin committed Dec 8, 2021
1 parent 372365b commit e735927
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ Feature: Receiving fixed discount from cart promotions only on non discounted pr
And the product "Mug" should have discounted unit price "$30.00" in the cart
And the cart total should be "$45.00"

@ui @api
@api
Scenario: Receiving order discount from cart promotions distributed only on non discounted products
Given there is a promotion "Christmas sale" that does not apply to discounted products
And this promotion gives "$10.00" discount to every order
When the customer adds "T-Shirt" product to the cart
And the customer adds "Mug" product to the cart
And the customer adds "Cap" product to the cart
Then the product "T-Shirt" should have discounted unit price "$15.00" in the cart
And the product "Mug" should have discounted unit price "$32.00" in the cart
And the product "Cap" should have discounted unit price "$8.00" in the cart
And the product "Mug" should have total price "$32.00" in the cart
And the product "Cap" should have total price "$8.00" in the cart
And the cart total should be "$55.00"
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,14 @@ Feature: Receiving percentage discount from cart promotions only on non discount
And the product "Mug" should have discounted unit price "$20.00" in the cart
And the cart total should be "$35.00"

@todo @ui @api
@api
Scenario: Receiving order discount from cart promotions distributed only on non discounted products
Given there is a promotion "Christmas sale" that does not apply to discounted products
And this promotion gives "50%" discount to every order
When the customer adds "T-Shirt" product to the cart
And the customer adds "Mug" product to the cart
And the customer adds "Cap" product to the cart
Then the product "T-Shirt" should have discounted unit price "$15.00" in the cart
And the product "Mug" should have discounted unit price "$20.00" in the cart
And the product "Cap" should have discounted unit price "$5.00" in the cart
And the product "Mug" should have total price "$20.00" in the cart
And the product "Cap" should have total price "$5.00" in the cart
And the cart total should be "$40.00"
18 changes: 18 additions & 0 deletions src/Sylius/Behat/Context/Api/Shop/CartContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,24 @@ public function iShouldSeeProductWithDiscountedUnitPriceInMyCart(string $product
throw new \InvalidArgumentException(sprintf('The product %s does not exist', $productName));
}

/**
* @Then /^the product "([^"]+)" should have total price ("[^"]+") in the cart$/
*/
public function theProductShouldHaveTotalPriceInTheCart(string $productName, int $totalPrice): void
{
$response = $this->cartsClient->getLastResponse();

foreach ($this->responseChecker->getValue($response, 'items') as $item) {
if ($item['productName'] === $productName) {
Assert::same($item['total'], $totalPrice);

return;
}
}

throw new \InvalidArgumentException(sprintf('The product %s does not exist', $productName));
}

/**
* @Then there should be one item in my cart
*/
Expand Down
8 changes: 8 additions & 0 deletions src/Sylius/Behat/Context/Ui/Shop/CartContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,14 @@ public function iShouldSeeProductWithUnitPriceInMyCart(string $productName, int
Assert::same($this->summaryPage->getItemUnitPrice($productName), $unitPrice);
}

/**
* @Then /^the product "([^"]+)" should have total price ("[^"]+") in the cart$/
*/
public function theProductShouldHaveTotalPrice(string $productName, int $totalPrice): void
{
Assert::same($this->summaryPage->getItemTotal($productName), $totalPrice);
}

/**
* @Then /^I should see "([^"]+)" with original price ("[^"]+") in my cart$/
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ public function execute(PromotionSubjectInterface $subject, array $configuration
return false;
}

$promotionAmount = $this->calculateAdjustmentAmount($subject->getPromotionSubjectTotal(), $configuration['percentage']);
$subjectTotal = $promotion->getAppliesToDiscounted() ? $subject->getPromotionSubjectTotal() : $subject->getNonDiscountedItemsTotal();
$promotionAmount = $this->calculateAdjustmentAmount($subjectTotal, $configuration['percentage']);

if (0 === $promotionAmount) {
return false;
}
Expand All @@ -67,6 +69,19 @@ public function execute(PromotionSubjectInterface $subject, array $configuration
} else {
$itemsTotal = [];
foreach ($subject->getItems() as $orderItem) {
if ($promotion->getAppliesToDiscounted()) {
$itemsTotal[] = $orderItem->getTotal();

continue;
}

$variant = $orderItem->getVariant();
if (!empty($variant->getAppliedPromotionsForChannel($subject->getChannel()))) {
$itemsTotal[] = 0;

continue;
}

$itemsTotal[] = $orderItem->getTotal();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ function it_distributes_promotion_using_regular_distributor_if_minimum_price_dis
$channelPricingOne->getMinimumPrice()->willReturn(0);
$channelPricingTwo->getMinimumPrice()->willReturn(0);

$promotion->getAppliesToDiscounted()->willReturn(true);

$order->getPromotionSubjectTotal()->willReturn(10000);

$minimumPriceDistributor->distribute([$firstItem, $secondItem], -1000, $channel)->shouldNotBeCalled();
Expand All @@ -140,7 +142,8 @@ function it_distributes_promotion_amount_taking_minimum_price_into_account(
ChannelPricingInterface $channelPricingOne,
ChannelPricingInterface $channelPricingTwo,
ChannelInterface $channel
): void {
): void
{
$order->countItems()->willReturn(2);
$order->getChannel()->willReturn($channel);

Expand All @@ -164,6 +167,38 @@ function it_distributes_promotion_amount_taking_minimum_price_into_account(
$minimumPriceDistributor->distribute([$firstItem, $secondItem], -1000, $channel)->willReturn([-100, -800]);

$unitsPromotionAdjustmentsApplicator->apply($order, $promotion, [-100, -800])->shouldBeCalled();
}

function it_uses_a_distributor_and_applicator_to_execute_promotion_action_only_for_non_discounted_items(
ChannelInterface $channel,
OrderInterface $order,
OrderItemInterface $firstItem,
OrderItemInterface $secondItem,
ProductVariantInterface $firstVariant,
ProductVariantInterface $secondVariant,
PromotionInterface $promotion,
ProportionalIntegerDistributorInterface $distributor,
UnitsPromotionAdjustmentsApplicatorInterface $unitsPromotionAdjustmentsApplicator
): void {
$order->countItems()->willReturn(2);
$order->getItems()->willReturn(new ArrayCollection([$firstItem->getWrappedObject(), $secondItem->getWrappedObject()]));
$order->getChannel()->willReturn($channel);

$firstItem->getTotal()->willReturn(200);
$firstItem->getVariant()->willReturn($firstVariant);
$secondItem->getTotal()->willReturn(800);
$secondItem->getVariant()->willReturn($secondVariant);

$firstVariant->getAppliedPromotionsForChannel($channel)->willReturn([]);
$secondVariant->getAppliedPromotionsForChannel($channel)->willReturn(['winter_sale' => ['name' => 'Winter sale']]);

$order->getNonDiscountedItemsTotal()->willReturn(200);
$promotion->getAppliesToDiscounted()->willReturn(false);

$order->getPromotionSubjectTotal()->willReturn(10000);

$distributor->distribute([200, 0], -20)->willReturn([-20, 0]);
$unitsPromotionAdjustmentsApplicator->apply($order, $promotion, [-20, 0])->shouldBeCalled();

$this->execute($order, ['percentage' => 0.1], $promotion)->shouldReturn(true);
}
Expand Down

0 comments on commit e735927

Please sign in to comment.