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



50
51
52
# File 'app/models/solidus_promotions/promotion.rb', line 50

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



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

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)


64
65
66
67
68
69
70
# File 'app/models/solidus_promotions/promotion.rb', line 64

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



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

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

.with_coupon_code(val) ⇒ Object



44
45
46
47
48
# File 'app/models/solidus_promotions/promotion.rb', line 44

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)


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

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

#discounted_ordersObject

All orders that have been discounted using this promotion



77
78
79
80
81
82
83
84
85
86
# File 'app/models/solidus_promotions/promotion.rb', line 77

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

#eligibility_resultsObject



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

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

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

Returns:

  • (Boolean)


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

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

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

Returns:

  • (Boolean)


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

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

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

Returns:

  • (Boolean)


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

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

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

Returns:

  • (Boolean)


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

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

#productsObject



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

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

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

Returns:

  • (Boolean)


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

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



92
93
94
95
96
97
98
# File 'app/models/solidus_promotions/promotion.rb', line 92

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



113
114
115
116
117
# File 'app/models/solidus_promotions/promotion.rb', line 113

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)


100
101
102
103
104
105
106
107
# File 'app/models/solidus_promotions/promotion.rb', line 100

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