Class: SolidusPromotions::Calculators::TieredFlatRate

Inherits:
Spree::Calculator
  • Object
show all
Includes:
PromotionCalculator
Defined in:
app/models/solidus_promotions/calculators/tiered_flat_rate.rb

Overview

A calculator that applies tiered flat-rate discounts based on discountable amount thresholds.

This calculator allows defining multiple discount tiers where each tier specifies a minimum discountable amount threshold and the corresponding discount amount to apply. The calculator selects the highest tier that the item qualifies for based on its discountable amount.

If the item doesn’t meet any tier threshold, the base amount is used. The discount is only applied if the currency matches the preferred currency.

Examples:

Use case: Volume-based shipping discounts

# Free shipping on orders over $100, $5 off on orders over $50
calculator = TieredFlatRate.new(
  preferred_base_amount: 0,
  preferred_tiers: {
    50 => 5,   # $5 discount when amount >= $50
    100 => 15  # $15 discount when amount >= $100
  },
  preferred_currency: 'USD'
)

Use case: Bulk purchase incentives

# Tiered discounts for line items based on total line value
calculator = TieredFlatRate.new(
  preferred_base_amount: 2,
  preferred_tiers: {
    25 => 5,    # $5 off when line total >= $25
    50 => 12,   # $12 off when line total >= $50
    100 => 30   # $30 off when line total >= $100
  },
  preferred_currency: 'USD'
)

Instance Method Summary collapse

Methods included from PromotionCalculator

#description

Instance Method Details

#compute_item(object) ⇒ BigDecimal Also known as: compute_shipment, compute_line_item

Computes the tiered flat-rate discount for an item.

Evaluates the item’s discountable amount against all defined tiers and selects the highest tier threshold that the item meets or exceeds. Returns the discount amount associated with that tier, or the base amount if no tier threshold is met. Returns 0 if the currency doesn’t match.

Examples:

Computing discount with tier matching

calculator = TieredFlatRate.new(
  preferred_base_amount: 2,
  preferred_tiers: { 25 => 5, 50 => 10, 100 => 20 }
)
line_item.discountable_amount # => 75.00
calculator.compute_item(line_item) # => 10.00 (matches $50 tier)

Computing discount below all tiers

calculator = TieredFlatRate.new(
  preferred_base_amount: 2,
  preferred_tiers: { 25 => 5, 50 => 10 }
)
line_item.discountable_amount # => 15.00
calculator.compute_item(line_item) # => 2.00 (base amount)

Computing discount with currency mismatch

calculator = TieredFlatRate.new(
  preferred_currency: 'USD',
  preferred_tiers: { 50 => 10 }
)
line_item.currency # => 'EUR'
calculator.compute_item(line_item) # => 0

Parameters:

  • object (Object)

    The object to calculate the discount for (e.g., LineItem, Shipment)

Returns:

  • (BigDecimal)

    The discount amount from the matching tier, base amount, or 0



83
84
85
86
87
88
89
90
91
92
93
# File 'app/models/solidus_promotions/calculators/tiered_flat_rate.rb', line 83

def compute_item(object)
  _base, amount = preferred_tiers.sort.reverse.detect do |value, _|
    object.discountable_amount >= value
  end

  if preferred_currency.casecmp(object.currency).zero?
    amount || preferred_base_amount
  else
    Spree::ZERO
  end
end