Class: SolidusPromotions::Promotion

Inherits:
Spree::Base
  • Object
show all
Includes:
Spree::SoftDeletable
Defined in:
app/models/solidus_promotions/promotion.rb

Constant Summary collapse

UNACTIVATABLE_ORDER_STATES =
["awaiting_return", "returned", "canceled"]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.human_enum_name(enum_name, enum_value) ⇒ Object



55
56
57
# File 'app/models/solidus_promotions/promotion.rb', line 55

def self.human_enum_name(enum_name, enum_value)
  I18n.t("activerecord.attributes.#{model_name.i18n_key}.#{enum_name.to_s.pluralize}.#{enum_value}")
end

.lane_optionsObject



59
60
61
62
63
# File 'app/models/solidus_promotions/promotion.rb', line 59

def self.lane_options
  ordered_lanes.map do |lane|
    [human_enum_name(:lane, lane), lane]
  end
end

.order_activatable?(order) ⇒ Boolean

Returns:

  • (Boolean)


69
70
71
72
73
74
75
# File 'app/models/solidus_promotions/promotion.rb', line 69

def self.order_activatable?(order)
  return false if UNACTIVATABLE_ORDER_STATES.include?(order.state)
  return false if order.shipped?
  return false if order.complete? && !SolidusPromotions.config.recalculate_complete_orders

  true
end

.ordered_lanesObject



65
66
67
# File 'app/models/solidus_promotions/promotion.rb', line 65

def self.ordered_lanes
  lanes.keys.sort_by { |lane| lanes[lane] }
end

.with_coupon_code(val) ⇒ Object



47
48
49
50
51
52
53
# File 'app/models/solidus_promotions/promotion.rb', line 47

def self.with_coupon_code(val)
  joins(:codes).where(
    SolidusPromotions::PromotionCode.arel_table[:value].eq(
      SolidusPromotions.config.coupon_code_normalizer_class.call(val)
    )
  ).first
end

Instance Method Details

#active?(time = Time.current) ⇒ Boolean

Returns:

  • (Boolean)


136
137
138
# File 'app/models/solidus_promotions/promotion.rb', line 136

def active?(time = Time.current)
  started?(time) && not_expired?(time) && benefits.present?
end

#discounted_ordersObject

All orders that have been discounted using this promotion



82
83
84
85
86
87
88
89
90
91
# File 'app/models/solidus_promotions/promotion.rb', line 82

def discounted_orders
  Spree::Order
    .joins(:all_adjustments)
    .where(
      spree_adjustments: {
        source_type: "SolidusPromotions::Benefit",
        source_id: benefits.map(&:id)
      }
    ).distinct
end

#eligibility_resultsObject



152
153
154
# File 'app/models/solidus_promotions/promotion.rb', line 152

def eligibility_results
  @eligibility_results ||= SolidusPromotions::EligibilityResults.new(self)
end

#expired?(time = Time.current) ⇒ Boolean

Returns:

  • (Boolean)


144
145
146
# File 'app/models/solidus_promotions/promotion.rb', line 144

def expired?(time = Time.current)
  expires_at.present? && expires_at < time
end

#inactive?(time = Time.current) ⇒ Boolean

Returns:

  • (Boolean)


140
141
142
# File 'app/models/solidus_promotions/promotion.rb', line 140

def inactive?(time = Time.current)
  !active?(time)
end

#not_expired?(time = Time.current) ⇒ Boolean

Returns:

  • (Boolean)


124
125
126
# File 'app/models/solidus_promotions/promotion.rb', line 124

def not_expired?(time = Time.current)
  !expired?(time)
end

#not_started?(time = Time.current) ⇒ Boolean

Returns:

  • (Boolean)


128
129
130
# File 'app/models/solidus_promotions/promotion.rb', line 128

def not_started?(time = Time.current)
  !started?(time)
end

#productsObject



148
149
150
# File 'app/models/solidus_promotions/promotion.rb', line 148

def products
  conditions.where(type: "SolidusPromotions::Conditions::Product").flat_map(&:products).uniq
end

#started?(time = Time.current) ⇒ Boolean

Returns:

  • (Boolean)


132
133
134
# File 'app/models/solidus_promotions/promotion.rb', line 132

def started?(time = Time.current)
  starts_at.nil? || starts_at < time
end

#usage_count(excluded_orders: []) ⇒ Integer

Number of times the code has been used overall

Parameters:

  • excluded_orders (Array<Spree::Order>) (defaults to: [])

    Orders to exclude from usage count

Returns:

  • (Integer)

    usage count



97
98
99
100
101
102
103
# File 'app/models/solidus_promotions/promotion.rb', line 97

def usage_count(excluded_orders: [])
  discounted_orders
    .complete
    .where.not(id: [excluded_orders.map(&:id)])
    .where.not(spree_orders: {state: :canceled})
    .count
end

#usage_limit_exceeded?(excluded_orders: []) ⇒ Boolean

Whether the promotion has exceeded its usage restrictions.

Parameters:

  • excluded_orders (Array<Spree::Order>) (defaults to: [])

    Orders to exclude from usage limit

Returns:

  • (Boolean)

    true or false



118
119
120
121
122
# File 'app/models/solidus_promotions/promotion.rb', line 118

def usage_limit_exceeded?(excluded_orders: [])
  return unless usage_limit

  usage_count(excluded_orders: excluded_orders) >= usage_limit
end

#used_by?(user, excluded_orders = []) ⇒ Boolean

Returns:

  • (Boolean)


105
106
107
108
109
110
111
112
# File 'app/models/solidus_promotions/promotion.rb', line 105

def used_by?(user, excluded_orders = [])
  discounted_orders
    .complete
    .where.not(id: excluded_orders.map(&:id))
    .where(user: user)
    .where.not(spree_orders: {state: :canceled})
    .exists?
end