New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[CartPromotion][CatalogPromotion] Receiving discount only on non discounted products #13349
[CartPromotion][CatalogPromotion] Receiving discount only on non discounted products #13349
Conversation
GSadee
commented
Dec 1, 2021
Q | A |
---|---|
Branch? | master |
Bug fix? | no |
New feature? | yes |
BC breaks? | no |
Deprecations? | no |
Related tickets | based on #13328 |
License | MIT |
e74c157
to
f3ee1bb
Compare
640d16e
to
9e6efd5
Compare
src/Sylius/Component/Core/Promotion/Action/FixedDiscountPromotionActionCommand.php
Outdated
Show resolved
Hide resolved
…discount only on non discounted products
…iving discount only on non discounted products
…ging the name of field
…ounted products for unit cart promotions
… discounted products for fixed order cart promotions
9e6efd5
to
4227f91
Compare
…nt and minimum prices
4227f91
to
9ce4cb8
Compare
@@ -27,7 +27,7 @@ public function __construct(ProportionalIntegerDistributorInterface $proportiona | |||
$this->proportionalIntegerDistributor = $proportionalIntegerDistributor; | |||
} | |||
|
|||
public function distribute(array $orderItems, int $amount, ChannelInterface $channel): array | |||
public function distribute(array $orderItems, int $amount, ChannelInterface $channel, bool $appliesOnDiscounted): array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it BC break? we shouldn't add an argument without default value to a public function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be a BC Break, but this code is only on master
branch which means it is not used by anyone 💃 We're safe 🚀
@@ -460,4 +460,18 @@ public function setCustomerIp(?string $customerIp): void | |||
{ | |||
$this->customerIp = $customerIp; | |||
} | |||
|
|||
public function getNonDiscountedItemsTotal(): int | |||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure but can we use here array_reduce
instead of foreach?
/** | ||
* @Then /^the product "([^"]+)" should have total price ("[^"]+") in the cart$/ | ||
*/ | ||
public function theProductShouldHaveTotalPriceInTheCart(string $productName, int $totalPrice): void |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use a transformer, we could just call $product->getName()
in line 426 and remove exception from the end of the function
@@ -27,7 +27,7 @@ public function __construct(ProportionalIntegerDistributorInterface $proportiona | |||
$this->proportionalIntegerDistributor = $proportionalIntegerDistributor; | |||
} | |||
|
|||
public function distribute(array $orderItems, int $amount, ChannelInterface $channel): array | |||
public function distribute(array $orderItems, int $amount, ChannelInterface $channel, bool $appliesOnDiscounted): array |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would be a BC Break, but this code is only on master
branch which means it is not used by anyone 💃 We're safe 🚀
private function getTotalPrice(OrderItemInterface $orderItem, bool $appliesOnDiscounted, ChannelInterface $channel): int | ||
{ | ||
$variant = $orderItem->getVariant(); | ||
if ($appliesOnDiscounted === false && !empty($variant->getAppliedPromotionsForChannel($channel))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!$appilesOnDiscounted
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, maybe we could have hasAppliedPromotionsForChannel($channel): bool
on the variant? It would seem more natural this way
$distributedAmounts[] = 0; | ||
} else { | ||
$distributedAmounts[] = (int) round(($element * $amount) / $total, 0, \PHP_ROUND_HALF_DOWN); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would extract it to the private function or make it shorter:
$distributedAmounts[] = ($element === 0) ? 0 : (int) round(($element * $amount) / $total, 0, \PHP_ROUND_HALF_DOWN);
} | ||
} | ||
|
||
if(array_sum($distributedAmounts) === 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing space after if
😱
if ($this->minimumPriceDistributor !== null) { | ||
$splitPromotion = $this->minimumPriceDistributor->distribute($subject->getItems()->toArray(), $promotionAmount, $subject->getChannel()); | ||
$splitPromotion = $this->minimumPriceDistributor->distribute($subject->getItems()->toArray(), $promotionAmount, $subject->getChannel(), $promotion->getAppliesToDiscounted()); | ||
} 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(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My soul hurts, as this part of code is identical to this one 😢
@@ -107,4 +111,23 @@ private function calculate(int $unitTotal, ?int $minimumPrice, int $promotionAmo | |||
|
|||
return $promotionAmount; | |||
} | |||
|
|||
private function canPromotionBeApplied(OrderItemUnitInterface $unit, PromotionInterface $promotion): bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we make it protected
? It's a solid part of logic, that would not be easily replaceable (as is the private function in the extendable class)
Scenario: Distributing discount proportionally between different products when one has minimum price specified and promotion does not apply on discounted products | ||
Given this promotion does not apply on discounted products | ||
And it gives "$27" discount to every order | ||
And there is a catalog promotion "Fixed T-Shirt sale" that reduces price by fixed "$2.50" in the "United States" channel and applies on "PHP Mug" product |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And there is a catalog promotion "Fixed T-Shirt sale" that reduces price by fixed "$2.50" in the "United States" channel and applies on "PHP Mug" product | |
And there is a catalog promotion "Fixed Mug sale" that reduces price by fixed "$2.50" in the "United States" channel and applies on "PHP Mug" product |
Thanks, Grzegorz! 🥇 |