$packages =
$this->
enrichPackagesWithCartData($packages,
$calculatedCart,
$context);
// if we have any graduation settings, make sure to reduce the items
// that are eligible for our discount by executing our graduation resolver.
$packages =
$this->advancedFilter->
filterPackages($discount,
$packages,
$originalPackageCount);
$packages =
$this->
enrichPackagesWithCartData($packages,
$calculatedCart,
$context);
$calculator =
match ($discount->
getType()) { PromotionDiscountEntity::TYPE_ABSOLUTE =>
new DiscountAbsoluteCalculator($this->absolutePriceCalculator
),
PromotionDiscountEntity::TYPE_PERCENTAGE =>
new DiscountPercentageCalculator($this->absolutePriceCalculator,
$this->percentagePriceCalculator
),
PromotionDiscountEntity::TYPE_FIXED =>
new DiscountFixedPriceCalculator($this->absolutePriceCalculator
),
PromotionDiscountEntity::TYPE_FIXED_UNIT =>
new DiscountFixedUnitPriceCalculator($this->absolutePriceCalculator
),
default =>
throw new DiscountCalculatorNotFoundException($discount->
getType()),
};
$result =
$calculator->
calculate($discount,
$packages,
$context);
// now aggregate any composition items
// which might be duplicated due to separate packages
$aggregatedCompositionItems =
$this->discountCompositionBuilder->
aggregateCompositionItems($result->
getCompositionItems());
$result =
new DiscountCalculatorResult($result->
getPrice(),
$aggregatedCompositionItems);
// get the cart total price => discount may never be higher than this value