diff --git a/core/app/models/spree/calculator/distributed_amount.rb b/core/app/models/spree/calculator/distributed_amount.rb index f1214955c5a..c42ef3bb7df 100644 --- a/core/app/models/spree/calculator/distributed_amount.rb +++ b/core/app/models/spree/calculator/distributed_amount.rb @@ -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 diff --git a/core/app/models/spree/distributed_amounts_handler.rb b/core/app/models/spree/distributed_amounts_handler.rb index f548796c0cd..9a5c774b409 100644 --- a/core/app/models/spree/distributed_amounts_handler.rb +++ b/core/app/models/spree/distributed_amounts_handler.rb @@ -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 @@ -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 @@ -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 diff --git a/core/spec/models/spree/distributed_amounts_handler_spec.rb b/core/spec/models/spree/distributed_amounts_handler_spec.rb index a6913f37566..2bda51537a8 100644 --- a/core/spec/models/spree/distributed_amounts_handler_spec.rb +++ b/core/spec/models/spree/distributed_amounts_handler_spec.rb @@ -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 @@ -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] @@ -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] @@ -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]