Class: Coupon::Calculator::AdjustableAmount

Inherits:
Base
  • Object
show all
Defined in:
app/services/coupon/calculator/adjustable_amount.rb

Overview

Essentially a flat amount off but the discount vlaue is used

Instance Method Summary collapse

Instance Method Details

#calculate(discount) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'app/services/coupon/calculator/adjustable_amount.rb', line 3

def calculate(discount)
  amount = discount.user_amount
  calculation_method = @options[:method]
  # Credit order reverse coupon polarity if specified, maybe?
  if discount.itemizable.try(:order_type) == 'CO'
    if calculation_method == :subtract
      calculation_method = :add
    elsif calculation_method == :add
      calculation_method = :subtract
    end
  end
  calculation_method ||= amount.negative? ? :subtract : :add
  case calculation_method
  when :add
    amount = amount.abs
  when :subtract
    # Cap against the currently-discounted balance (not MSRP) to prevent line items
    # from going below $0 when a prior pricing-program discount is already applied.
    # Example: $12 item with -$4.20 Gold-level discount → remaining balance = $7.80.
    # A rep entering -$12.00 should be capped at -$7.80, not -$12.00 (which would
    # produce a negative discounted_total and eventually a negative delivery total).
    # [0] floor ensures we never "discount" a line that is already at $0 or negative.
    remaining_balance = [@line_item_extractor.get_base_amount_discounted, 0].max
    amount = -[amount.abs, remaining_balance].min
  end
  @allocator ||= Coupon::MsrpAllocator
  @allocator.new(@line_item_extractor).allocate(discount, amount)
end