Skip to content

Commit

Permalink
Prefer generic calculator handler
Browse files Browse the repository at this point in the history
  • Loading branch information
Sinetheta committed Feb 22, 2018
1 parent 5e2b124 commit 7b837d5
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 35 deletions.
22 changes: 14 additions & 8 deletions core/app/models/spree/calculator/distributed_amount.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@ class Calculator::DistributedAmount < Calculator
preference :currency, :string, default: -> { Spree::Config[:currency] }

def compute_line_item(line_item)
if line_item && preferred_currency.casecmp(line_item.currency).zero?
Spree::DistributedAmountsHandler.new(
line_item,
calculable.promotion,
preferred_amount
).amount
else
0
return 0 unless line_item
return 0 unless preferred_currency.casecmp(line_item.currency).zero?
return 0 unless calculable.promotion.line_item_actionable?(line_item.order, line_item)
Spree::DistributedAmountsHandler.new(
actionable_line_items(line_item.order),
preferred_amount
).amount(line_item)
end

private

def actionable_line_items(order)
order.line_items.select do |line_item|
calculable.promotion.line_item_actionable?(order, line_item)
end
end
end
Expand Down
24 changes: 10 additions & 14 deletions core/app/models/spree/distributed_amounts_handler.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
module Spree
class DistributedAmountsHandler
attr_reader :line_item, :order, :promotion, :total_amount
attr_reader :line_items, :total_amount

def initialize(line_item, promotion, total_amount)
@line_item = line_item
@order = line_item.order
@promotion = promotion
def initialize(line_items, total_amount)
@line_items = line_items
@total_amount = total_amount
end

# @return [BigDecimal] the weighted adjustment for the initialized line item
def amount
distributed_amounts[@line_item.id].to_d
# @param [LineItem] one of the line_items distributed over
# @return [BigDecimal] the weighted adjustment for this line_item
def amount(line_item)
distributed_amounts[line_item.id].to_d
end

private
Expand All @@ -24,14 +23,11 @@ def distributed_amounts
end

def line_item_ids
@order.line_items.map(&:id)
line_items.map(&:id)
end

def elligible_amounts
@order.line_items.map do |line_item|
elligible = promotion.line_item_actionable?(line_item.order, line_item)
elligible ? line_item.amount : 0
end
line_items.map(&:amount)
end

def subtotal
Expand All @@ -43,7 +39,7 @@ def weights
end

def allocated_amounts
@total_amount.to_money.allocate(weights).map(&:to_money)
total_amount.to_money.allocate(weights).map(&:to_money)
end
end
end
27 changes: 14 additions & 13 deletions core/spec/models/spree/distributed_amounts_handler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,20 @@
line_items_attributes: line_items_attributes
)
end
let(:promotion) { FactoryBot.build(:promotion) }

let(:handler) {
described_class.new(order.line_items, total_amount)
}

describe "#amount" do
let(:total_amount) { 15 }

subject { described_class.new(line_item, promotion, total_amount).amount }

context "when there is only one line item" do
let(:line_items_attributes) { [{ price: 100 }] }
let(:line_item) { order.line_items.first }

it "applies the entire amount to the line item" do
expect(subject).to eq(15)
expect(handler.amount(line_item)).to eq(15)
end
end

Expand All @@ -32,9 +33,9 @@
it "evenly distributes the total amount" do
expect(
[
described_class.new(order.line_items[0], promotion, total_amount).amount,
described_class.new(order.line_items[1], promotion, total_amount).amount,
described_class.new(order.line_items[2], promotion, total_amount).amount
handler.amount(order.line_items[0]),
handler.amount(order.line_items[1]),
handler.amount(order.line_items[2])
]
).to eq(
[5, 5, 5]
Expand All @@ -47,9 +48,9 @@
it "applies the remainder of the total amount to the last item" do
expect(
[
described_class.new(order.line_items[0], promotion, total_amount).amount,
described_class.new(order.line_items[1], promotion, total_amount).amount,
described_class.new(order.line_items[2], promotion, total_amount).amount
handler.amount(order.line_items[0]),
handler.amount(order.line_items[1]),
handler.amount(order.line_items[2])
]
).to match_array(
[3.33, 3.33, 3.34]
Expand All @@ -66,9 +67,9 @@
it "distributes the total amount relative to the item's price" do
expect(
[
described_class.new(order.line_items[0], promotion, total_amount).amount,
described_class.new(order.line_items[1], promotion, total_amount).amount,
described_class.new(order.line_items[2], promotion, total_amount).amount
handler.amount(order.line_items[0]),
handler.amount(order.line_items[1]),
handler.amount(order.line_items[2])
]
).to eq(
[7.5, 2.5, 5]
Expand Down

0 comments on commit 7b837d5

Please sign in to comment.