Class: SolidusPromotions::Calculators::TieredPercent
- Inherits:
-
Spree::Calculator
- Object
- Spree::Calculator
- SolidusPromotions::Calculators::TieredPercent
- Includes:
- PromotionCalculator
- Defined in:
- app/models/solidus_promotions/calculators/tiered_percent.rb
Overview
A calculator that applies tiered percentage-based discounts based on order item total thresholds.
This calculator allows defining multiple discount tiers where each tier specifies a minimum order item total threshold and the corresponding percentage discount to apply to the individual item. The calculator selects the highest tier that the order qualifies for based on its item total.
Unlike TieredFlatRate which applies a fixed amount, this calculator applies a percentage of the item’s amount. The tier thresholds are evaluated against the entire order’s item total, but the percentage discount is applied to the individual item (line item or shipment).
If the order doesn’t meet any tier threshold, the base percentage is used. The discount is only applied if the currency matches the preferred currency.
Instance Method Summary collapse
-
#compute_item(object) ⇒ BigDecimal
(also: #compute_shipment, #compute_line_item)
Computes the tiered percentage discount for an item based on the order’s item total.
Methods included from PromotionCalculator
Instance Method Details
#compute_item(object) ⇒ BigDecimal Also known as: compute_shipment, compute_line_item
Computes the tiered percentage discount for an item based on the order’s item total.
Evaluates the order’s item total against all defined tiers and selects the highest tier threshold that the order meets or exceeds. Returns a percentage of the item’s amount based on the matching tier, or the base percentage if no tier threshold is met. Returns 0 if the currency doesn’t match.
94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'app/models/solidus_promotions/calculators/tiered_percent.rb', line 94 def compute_item(object) order = object.order _base, percent = preferred_tiers.sort.reverse.detect do |value, _| order.item_total >= value end if preferred_currency.casecmp(order.currency).zero? round_to_currency(object.amount * (percent || preferred_base_percent) / 100, preferred_currency) else Spree::ZERO end end |