Add new Shipping Calculator (Weight Rate) #1007

Closed
wants to merge 3 commits into
from
@@ -0,0 +1,28 @@
+module Spree
+ class Calculator::WeightScale < Calculator
+ preference :rule, :string
+ preference :default_weight, :decimal, :default => 1
+ preference :default_price, :decimal, :default => 0
+
+ def self.description
+ I18n.t(:weight_scale)
+ end
+
+ # as object we always get line items, as calculable we have Coupon, ShippingMethod
+ def compute(object)
+ line_items = object.is_a?(Order) ? object.line_items : object
+
+ if self.preferred_rule =~ /^(\d*\:\d*\;)*$|^(\d*\:\d*\;)*(\d*\:\d*)$/
+
+ total_weight = line_items.sum do |li|
+ (li.variant.weight || self.preferred_default_weight) * li.quantity
+ end
+ self.preferred_rule.split(";").each do |rule|
+ weight, price = rule.split(":")
+ return price.to_f if total_weight.to_f < weight.to_f
+ end
+ end
+ return self.preferred_default_price.to_f
+ end
+ end
+end
@@ -1030,6 +1030,7 @@ en:
void: Void
website: Website
weight: Weight
+ weight_scale: "Weight Scale"
welcome_to_sample_store: "Welcome to the sample store"
what_is_a_cvv: "What is a (CVV) Credit Card Code?"
what_is_this: "What's This?"
@@ -50,7 +50,8 @@ def self.activate
Spree::Calculator::FlatRate,
Spree::Calculator::FlexiRate,
Spree::Calculator::PerItem,
- Spree::Calculator::PriceBucket]
+ Spree::Calculator::PriceBucket,
+ Spree::Calculator::WeightScale]
app.config.spree.calculators.tax_rates = [
Spree::Calculator::DefaultTax]
@@ -0,0 +1,63 @@
+require 'spec_helper'
+
+describe Spree::Calculator::WeightScale do
+ let(:calculator) { Spree::Calculator::WeightScale.new }
+ let(:order) { mock_model Spree::Order, :line_items => [mock_model(Spree::LineItem, :amount => 10, :quantity => 4), mock_model(Spree::LineItem, :amount => 20, :quantity => 6)] }
+
+ context "compute" do
+ it "should show correct defaut price" do
+ calculator.stub :preferred_default_price => 10.0
+ calculator.compute(order).round(2).should == 10.0
+ end
+
+ it "should show correct amount with rule and defaut weight #1" do
+ calculator.stub :preferred_rule => "1:4;2:5;3:10;4:14;10:30;20:70;40:120;100:150"
+ calculator.stub :preferred_default_weight => 1
+
+ variant1 = mock_model(Spree::Variant, :product => "product1")
+ variant2 = mock_model(Spree::Variant, :product => "product2")
+ line_items = [mock_model(Spree::LineItem, :variant => variant1, :quantity => 4), mock_model(Spree::LineItem, :variant => variant2, :quantity => 2)]
+ order.stub(:line_items => line_items)
+
+ calculator.compute(order).round(2).should == 30.0
+ end
+
+ it "should show correct amount with rule and defaut weight #2" do
+ calculator.stub :preferred_rule => "1:4;2:5;3:10;4:14;10:30;20:70;40:120;100:150"
+ calculator.stub :preferred_default_weight => 1.9
+
+ variant1 = mock_model(Spree::Variant, :product => "product1")
+ variant2 = mock_model(Spree::Variant, :product => "product2")
+ line_items = [mock_model(Spree::LineItem, :variant => variant1, :quantity => 4), mock_model(Spree::LineItem, :variant => variant2, :quantity => 2)]
+ order.stub(:line_items => line_items)
+
+ calculator.compute(order).round(2).should == 70.0
+ end
+
+ it "should show correct amount with rule and variant weight" do
+ calculator.stub :preferred_rule => "1:4;2:5;3:10;4:14;10:30;20:70;40:120;100:150"
+
+ variant1 = mock_model(Spree::Variant, :product => "product1", :weight => 0.4)
+ variant2 = mock_model(Spree::Variant, :product => "product2", :weight => 1.1)
+ line_items = [mock_model(Spree::LineItem, :variant => variant1, :quantity => 4), mock_model(Spree::LineItem, :variant => variant2, :quantity => 2)]
+ order.stub(:line_items => line_items)
+
+ calculator.compute(order).round(2).should == 14.0
+ end
+
+ it "should show correct amount with rule and variant weight and default weight" do
+ calculator.stub :preferred_rule => "1:4;2:5;3:10;4:14;10:30;20:70;40:120;100:150"
+ calculator.stub :preferred_default_weight => 1
+
+ variant1 = mock_model(Spree::Variant, :product => "product1", :weight => 0.2)
+ variant2 = mock_model(Spree::Variant, :product => "product2")
+ line_items = [mock_model(Spree::LineItem, :variant => variant1, :quantity => 4), mock_model(Spree::LineItem, :variant => variant2, :quantity => 2)]
+ order.stub(:line_items => line_items)
+
+ calculator.compute(order).round(2).should == 10.0
+ end
+
+ end
+
+
+end