Class: Spree::Promotion::Actions::CreateQuantityAdjustments Private

Inherits:
CreateItemAdjustments show all
Defined in:
app/models/spree/promotion/actions/create_quantity_adjustments.rb

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Defined Under Namespace

Classes: PartialLineItem

Instance Method Summary (collapse)

Methods inherited from CreateItemAdjustments

#perform, #remove_from

Methods included from AdjustmentSource

#deals_with_adjustments_for_deleted_source

Methods included from CalculatedAdjustments

#calculator_type, #calculator_type=

Methods inherited from Spree::PromotionAction

#perform, #remove_from

Methods inherited from Base

display_includes, #initialize_preference_defaults, page, preference

Methods included from Spree::Preferences::Preferable

#default_preferences, #defined_preferences, #get_preference, #has_preference!, #has_preference?, #preference_default, #preference_type, #set_preference

Instance Method Details

- (Object) compute_amount(line_item)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Computes the amount for the adjustment based on the line item and any other applicable items in the order. The rules for this specific adjustment are as follows:

Setup

We have a quantity group promotion on t-shirts. If a user orders 3 t-shirts, they get $5 off of each. The shirts come in one size and three colours: red, blue, and white.

Scenario 1

User has 2 red shirts, 1 white shirt, and 1 blue shirt in their order. We want to compute the adjustment amount for the white shirt.

Result: -$5

Reasoning: There are a total of 4 items that are eligible for the promotion. Since that is greater than 3, we can discount the items. The white shirt has a quantity of 1, therefore it will get discounted by adjustment_amount * 1 or $5.

Scenario 1-1

What about the blue shirt? How much does it get discounted?

Result: $0

Reasoning: We have a total quantity of 4. However, we only apply the adjustment to groups of 3. Assuming the white and red shirts have already had their adjustment calculated, that means 3 units have been discounted. Leaving us with a lonely blue shirt that isn't part of a group of 3. Therefore, it does not receive the discount.

Scenario 2

User has 4 red shirts in their order. What is the amount?

Result: -$15

Reasoning: The total quantity of eligible items is 4, so we the adjustment will be non-zero. However, we only apply it to groups of 3, therefore there is one extra item that is not eligible for the adjustment. adjustment_amount * 3 or $15.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'app/models/spree/promotion/actions/create_quantity_adjustments.rb', line 54

def compute_amount(line_item)
  adjustment_amount = calculator.compute(PartialLineItem.new(line_item))
  if !adjustment_amount.is_a?(BigDecimal)
    Spree::Deprecation.warn "#{calculator.class.name}#compute returned #{adjustment_amount.inspect}, it should return a BigDecimal"
  end
  adjustment_amount ||= BigDecimal.new(0)
  adjustment_amount = adjustment_amount.abs

  order = line_item.order
  line_items = actionable_line_items(order)

  actioned_line_items = order.line_item_adjustments.reload.
    select { |a| a.source == self && a.amount < 0 }.
    map(&:adjustable)
  other_line_items = actioned_line_items - [line_item]

  applicable_quantity = total_applicable_quantity(line_items)
  used_quantity = total_used_quantity(other_line_items)
  usable_quantity = [
    applicable_quantity - used_quantity,
    line_item.quantity
  ].min

  persist_quantity(usable_quantity, line_item)

  amount = adjustment_amount * usable_quantity
  [line_item.amount, amount].min * -1
end