Class: Spree::Promotion
- Inherits:
-
ActiveRecord::Base
- Object
- ActiveRecord::Base
- Spree::Promotion
- Defined in:
- app/models/spree/promotion.rb,
app/models/spree/promotion/rules/user.rb,
app/models/spree/promotion/rules/product.rb,
app/models/spree/promotion/rules/item_total.rb,
app/models/spree/promotion/rules/first_order.rb,
app/models/spree/promotion/rules/user_logged_in.rb,
app/models/spree/promotion/actions/free_shipping.rb,
app/models/spree/promotion/actions/create_adjustment.rb,
app/models/spree/promotion/actions/create_line_items.rb,
app/models/spree/promotion/actions/create_item_adjustments.rb
Defined Under Namespace
Constant Summary collapse
- MATCH_POLICIES =
%w(all any)
- UNACTIVATABLE_ORDER_STATES =
["complete", "awaiting_return", "returned"]
Class Method Summary collapse
- .active ⇒ Object
- .advertised ⇒ Object
- .order_activatable?(order) ⇒ Boolean
- .with_coupon_code(coupon_code) ⇒ Object
Instance Method Summary collapse
- #activate(payload) ⇒ Object
- #adjusted_credits_count(promotable) ⇒ Object
- #credits ⇒ Object
- #credits_count ⇒ Object
-
#eligible?(promotable) ⇒ Boolean
called anytime order.update! happens.
- #expired? ⇒ Boolean
- #product_ids ⇒ Object
-
#products ⇒ Object
Products assigned to all product rules.
- #rules_are_eligible?(promotable, options = {}) ⇒ Boolean
- #usage_limit_exceeded?(promotable) ⇒ Boolean
Class Method Details
.active ⇒ Object
33 34 35 36 |
# File 'app/models/spree/promotion.rb', line 33 def self.active where('starts_at IS NULL OR starts_at < ?', Time.now). where('expires_at IS NULL OR expires_at > ?', Time.now) end |
.advertised ⇒ Object
25 26 27 |
# File 'app/models/spree/promotion.rb', line 25 def self.advertised where(advertise: true) end |
.order_activatable?(order) ⇒ Boolean
38 39 40 |
# File 'app/models/spree/promotion.rb', line 38 def self.order_activatable?(order) order && !UNACTIVATABLE_ORDER_STATES.include?(order.state) end |
.with_coupon_code(coupon_code) ⇒ Object
29 30 31 |
# File 'app/models/spree/promotion.rb', line 29 def self.with_coupon_code(coupon_code) where("lower(code) = ?", coupon_code.strip.downcase).first end |
Instance Method Details
#activate(payload) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'app/models/spree/promotion.rb', line 46 def activate(payload) order = payload[:order] return unless self.class.order_activatable?(order) # Track results from actions to see if any action has been taken. # Actions should return nil/false if no action has been taken. # If an action returns true, then an action has been taken. results = actions.map do |action| action.perform(payload) end # If an action has been taken, report back to whatever activated this promotion. action_taken = results.include?(true) if action_taken # connect to the order # create the join_table entry. self.orders << order self.save end return action_taken end |
#adjusted_credits_count(promotable) ⇒ Object
107 108 109 |
# File 'app/models/spree/promotion.rb', line 107 def adjusted_credits_count(promotable) credits_count - promotable.adjustments.promotion.where(:source_id => actions.pluck(:id)).count end |
#credits ⇒ Object
111 112 113 |
# File 'app/models/spree/promotion.rb', line 111 def credits Adjustment.eligible.promotion.where(source_id: actions.map(&:id)) end |
#credits_count ⇒ Object
115 116 117 |
# File 'app/models/spree/promotion.rb', line 115 def credits_count credits.count end |
#eligible?(promotable) ⇒ Boolean
called anytime order.update! happens
70 71 72 73 |
# File 'app/models/spree/promotion.rb', line 70 def eligible?(promotable) return false if expired? || usage_limit_exceeded?(promotable) rules_are_eligible?(promotable, {}) end |
#expired? ⇒ Boolean
42 43 44 |
# File 'app/models/spree/promotion.rb', line 42 def expired? !!(starts_at && Time.now < starts_at || expires_at && Time.now > expires_at) end |
#product_ids ⇒ Object
99 100 101 |
# File 'app/models/spree/promotion.rb', line 99 def product_ids products.map(&:id) end |
#products ⇒ Object
Products assigned to all product rules
93 94 95 96 97 |
# File 'app/models/spree/promotion.rb', line 93 def products @products ||= self.rules.to_a.inject([]) do |products, rule| rule.respond_to?(:products) ? products << rule.products : products end.flatten.uniq end |
#rules_are_eligible?(promotable, options = {}) ⇒ Boolean
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'app/models/spree/promotion.rb', line 75 def rules_are_eligible?(promotable, = {}) # Promotions without rules are eligible by default. return true if rules.none? eligible = lambda { |r| r.eligible?(promotable, ) } specific_rules = rules.for(promotable) return true if specific_rules.none? if match_policy == 'all' # If there are rules for this promotion, but no rules for this # particular promotable, then the promotion is ineligible by default. specific_rules.any? && specific_rules.all?(&eligible) else # If there are no rules for this promotable, then this will return false. # If there are rules for this promotable, but they are ineligible, this will return false. specific_rules.any?(&eligible) end end |
#usage_limit_exceeded?(promotable) ⇒ Boolean
103 104 105 |
# File 'app/models/spree/promotion.rb', line 103 def usage_limit_exceeded?(promotable) usage_limit.present? && usage_limit > 0 && adjusted_credits_count(promotable) >= usage_limit end |