Integrate from Spree fork: Calculators work against LineItems

This commit is contained in:
Rohan Mitchell
2016-05-06 16:42:28 +10:00
parent 04a714426f
commit 9989b76b7d
8 changed files with 117 additions and 0 deletions

View File

@@ -0,0 +1,9 @@
module Spree
Calculator::FlatPercentItemTotal.class_eval do
def compute(object)
item_total = line_items_for(object).map(&:amount).sum
value = item_total * BigDecimal(self.preferred_flat_percent.to_s) / 100.0
(value * 100).round.to_f / 100
end
end
end

View File

@@ -0,0 +1,19 @@
module Spree
Calculator::FlexiRate.class_eval do
def compute(object)
sum = 0
max = self.preferred_max_items.to_i
items_count = line_items_for(object).map(&:quantity).sum
items_count.times do |i|
# check max value to avoid divide by 0 errors
if (max == 0 && i == 0) || (max > 0) && (i % max == 0)
sum += self.preferred_first_item.to_f
else
sum += self.preferred_additional_item.to_f
end
end
sum
end
end
end

View File

@@ -0,0 +1,15 @@
module Spree
Calculator::PerItem.class_eval do
def compute(object=nil)
return 0 if object.nil?
self.preferred_amount * line_items_for(object).reduce(0) do |sum, value|
if matching_products.blank? || matching_products.include?(value.product)
value_to_add = value.quantity
else
value_to_add = 0
end
sum + value_to_add
end
end
end
end

View File

@@ -0,0 +1,18 @@
module Spree
Calculator.class_eval do
private
# Given an object which might be an Order or a LineItem (amongst
# others), return a collection of line items.
def line_items_for(object)
if object.respond_to? :line_items
object.line_items
else
[object]
end
end
end
end

View File

@@ -0,0 +1,10 @@
describe Spree::Calculator::FlatPercentItemTotal do
let(:calculator) { Spree::Calculator::FlatPercentItemTotal.new }
let(:line_item) { mock_model(Spree::LineItem, amount: 10) }
before { calculator.stub :preferred_flat_percent => 10 }
it "should compute amount correctly for a single line item" do
calculator.compute(line_item).should == 1.0
end
end

View File

@@ -0,0 +1,17 @@
require 'spec_helper'
describe Spree::Calculator::FlexiRate do
let(:calculator) { Spree::Calculator::FlexiRate.new }
let(:line_item) { mock_model(Spree::LineItem, amount: 10, quantity: 4) }
describe "computing for a single line item" do
it "returns the first item rate" do
calculator.stub preferred_first_item: 1.0
calculator.compute(line_item).round(2).should == 1.0
end
end
it "allows creation of new object with all the attributes" do
Spree::Calculator::FlexiRate.new(preferred_first_item: 1, preferred_additional_item: 1, preferred_max_items: 1)
end
end

View File

@@ -0,0 +1,12 @@
require 'spec_helper'
describe Spree::Calculator::PerItem do
let(:calculator) { Spree::Calculator::PerItem.new(preferred_amount: 10) }
let(:shipping_calculable) { double(:calculable) }
let(:line_item) { double(:line_item, quantity: 5, product: double(:product)) }
it "correctly calculates on a single line item object" do
calculator.stub(calculable: shipping_calculable)
calculator.compute(line_item).to_f.should == 50 # 5 x 10
end
end

View File

@@ -0,0 +1,17 @@
require 'spec_helper'
describe Spree::Calculator::PriceSack do
let(:calculator) do
calculator = Spree::Calculator::PriceSack.new
calculator.preferred_minimal_amount = 5
calculator.preferred_normal_amount = 10
calculator.preferred_discount_amount = 1
calculator
end
let(:line_item) { stub_model(Spree::LineItem, price: 1, quantity: 2) }
it "computes with a line item object" do
calculator.compute(line_item)
end
end