Class: Workarea::Pricing::Discount::ApplicationGroup

Inherits:
Object
  • Object
show all
Defined in:
app/models/workarea/pricing/discount/application_group.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(discounts, order, shippings) ⇒ ApplicationGroup

Returns a new instance of ApplicationGroup.



82
83
84
85
86
# File 'app/models/workarea/pricing/discount/application_group.rb', line 82

def initialize(discounts, order, shippings)
  @discounts = discounts.sort
  @order = order
  @shippings = shippings
end

Instance Attribute Details

#discountsObject (readonly)

Returns the value of attribute discounts.



5
6
7
# File 'app/models/workarea/pricing/discount/application_group.rb', line 5

def discounts
  @discounts
end

#orderObject (readonly)

Returns the value of attribute order.



5
6
7
# File 'app/models/workarea/pricing/discount/application_group.rb', line 5

def order
  @order
end

#shippingsObject (readonly)

Returns the value of attribute shippings.



5
6
7
# File 'app/models/workarea/pricing/discount/application_group.rb', line 5

def shippings
  @shippings
end

Class Method Details

.calculate(discounts, order, shippings) ⇒ Object



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'app/models/workarea/pricing/discount/application_group.rb', line 8

def calculate(discounts, order, shippings)
  expiration = Workarea.config.cache_expirations.discount_application_groups
  groups = Rails.cache.fetch(current_cache_key, expires_in: expiration, race_condition_ttl: 10) do
    # Ensure an undirected graph of compatibility on discounts
    discounts.each do |discount|
      discount.compatible_discount_ids.each do |id|
        compatible_discount = discounts.detect { |d| d.id.to_s == id }
        next unless compatible_discount.present?

        # compatible_discounts should be the open neighborhood of the
        # discount i.e. it shouldn't include itself
        unless compatible_discount == discount
          discount.compatible_discounts << compatible_discount
          compatible_discount.compatible_discounts << discount
        end
      end
    end

    results = []
    build_groups(remaining: discounts.to_set, results: results)
    results
  end

  groups.map { |set| new(set.to_a, order, shippings) }
end

.current_cache_keyObject



34
35
36
37
38
39
40
# File 'app/models/workarea/pricing/discount/application_group.rb', line 34

def current_cache_key
  [
    'discount_application_groups',
    Release.current&.id,
    *Segment.current.map(&:id).sort
  ].compact.join('/')
end

Instance Method Details

#applyObject



88
89
90
91
92
93
94
95
# File 'app/models/workarea/pricing/discount/application_group.rb', line 88

def apply
  discounts.each do |discount|
    discount_order = Discount::Order.new(order, shippings, discount)
    next unless discount.qualifies?(discount_order)

    discount.apply(discount_order)
  end
end

#valueObject



97
98
99
100
101
102
103
104
105
# File 'app/models/workarea/pricing/discount/application_group.rb', line 97

def value
  @value ||=
    begin
      apply
      result = calculate_applied_value
      remove_discounts
      result
    end.to_m
end