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



53
54
55
# File 'app/models/solidus_promotions/promotion.rb', line 53

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



57
58
59
60
61
# File 'app/models/solidus_promotions/promotion.rb', line 57

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

.order_activatable?(order) ⇒ Boolean

Returns:

  • (Boolean)


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

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



63
64
65
# File 'app/models/solidus_promotions/promotion.rb', line 63

def self.ordered_lanes
  lanes.sort_by(&:last).to_h
end

.with_coupon_code(val) ⇒ Object



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

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

Instance Method Details

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

Returns:

  • (Boolean)


134
135
136
# File 'app/models/solidus_promotions/promotion.rb', line 134

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

#discounted_ordersObject

All orders that have been discounted using this promotion



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

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

#eligibility_resultsObject



150
151
152
# File 'app/models/solidus_promotions/promotion.rb', line 150

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

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

Returns:

  • (Boolean)


142
143
144
# File 'app/models/solidus_promotions/promotion.rb', line 142

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

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

Returns:

  • (Boolean)


138
139
140
# File 'app/models/solidus_promotions/promotion.rb', line 138

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

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

Returns:

  • (Boolean)


122
123
124
# File 'app/models/solidus_promotions/promotion.rb', line 122

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

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

Returns:

  • (Boolean)


126
127
128
# File 'app/models/solidus_promotions/promotion.rb', line 126

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

#productsObject



146
147
148
# File 'app/models/solidus_promotions/promotion.rb', line 146

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

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

Returns:

  • (Boolean)


130
131
132
# File 'app/models/solidus_promotions/promotion.rb', line 130

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



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

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



116
117
118
119
120
# File 'app/models/solidus_promotions/promotion.rb', line 116

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)


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

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