Skip to content

Commit

Permalink
Improve the extendability of Rules::ItemTotal
Browse files Browse the repository at this point in the history
- Make operators extendable without reopening the method
- Allow to overwrite/extend the total
- Allow to overwrite/extend the threshold
- Simplify #eligible? making it more readable
- Migrate the OPERATORS constant to an extendible method
- Fix the default preferred operator
  • Loading branch information
elia committed Feb 4, 2020
1 parent 7a0d745 commit 4968e0a
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="row">
<div class="col-6">
<div class="field">
<%= select_tag "#{param_prefix}[preferred_operator]", options_for_select(Spree::Promotion::Rules::ItemTotal::OPERATORS.map{|o| [t(o, scope: 'spree.item_total_rule.operators'),o]}, promotion_rule.preferred_operator), {class: 'custom-select select_item_total fullwidth'} %>
<%= select_tag "#{param_prefix}[preferred_operator]", options_for_select(promotion_rule.class.operator_options, promotion_rule.preferred_operator), {class: 'custom-select select_item_total fullwidth'} %>
</div>
</div>
<div class="col-6">
Expand Down
46 changes: 42 additions & 4 deletions core/app/models/spree/promotion/rules/item_total.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,43 @@ module Rules
# A rule to apply to an order greater than (or greater than or equal to)
# a specific amount
class ItemTotal < PromotionRule
include ActiveSupport::Deprecation::DeprecatedConstantAccessor

preference :amount, :decimal, default: 100.00
preference :currency, :string, default: ->{ Spree::Config[:currency] }
preference :operator, :string, default: 'gt'

OPERATORS = ['gt', 'gte']
# The list of allowed operators names mapped to their symbols.
def self.operators_map
{
gte: :>=,
gt: :>,
}
end

def self.operator_options
operators_map.map do |name, _method|
[I18n.t(name, scope: 'spree.item_total_rule.operators'), name]
end
end

# @deprecated
OPERATORS = operators_map.keys.map(&:to_s)
deprecate_constant(
:OPERATORS,
:operators_map,
message: "OPERATORS is deprecated! Use `operators_map.keys.map(&:to_s)` instead.",
deprecator: Spree::Deprecation,
)

def applicable?(promotable)
promotable.is_a?(Spree::Order)
end

def eligible?(order, _options = {})
return false unless order.currency == preferred_currency
item_total = order.item_total
unless item_total.send(preferred_operator == 'gte' ? :>= : :>, BigDecimal(preferred_amount.to_s))

unless total_for_order(order).send(operator, threshold)
eligibility_errors.add(:base, ineligible_message, error_code: ineligible_error_code)
end

Expand All @@ -28,12 +51,27 @@ def eligible?(order, _options = {})

private

def operator
self.class.operators_map.fetch(
preferred_operator.to_sym,
preferred_operator_default,
)
end

def total_for_order(order)
order.item_total
end

def threshold
BigDecimal(preferred_amount.to_s)
end

def formatted_amount
Spree::Money.new(preferred_amount, currency: preferred_currency).to_s
end

def ineligible_message
if preferred_operator == 'gte'
if preferred_operator.to_s == 'gte'
eligibility_error_message(:item_total_less_than, amount: formatted_amount)
else
eligibility_error_message(:item_total_less_than_or_equal, amount: formatted_amount)
Expand Down

0 comments on commit 4968e0a

Please sign in to comment.