spree 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of spree might be problematic. Click here for more details.
- data/CHANGELOG +35 -0
- data/CONTRIBUTORS +2 -1
- data/README.markdown +8 -52
- data/app/controllers/account_controller.rb +1 -1
- data/app/controllers/addresses_controller.rb +5 -1
- data/app/controllers/admin/inventory_settings_controller.rb +13 -0
- data/app/controllers/admin/option_types_controller.rb +1 -1
- data/app/controllers/admin/orders_controller.rb +14 -8
- data/app/controllers/admin/products_controller.rb +2 -0
- data/app/controllers/admin/variants_controller.rb +7 -0
- data/app/controllers/content_controller.rb +5 -0
- data/app/controllers/creditcard_payments_controller.rb +2 -2
- data/app/controllers/orders_controller.rb +18 -2
- data/app/helpers/admin/inventory_settings_helper.rb +5 -0
- data/app/helpers/admin/product_properties_helper.rb +10 -2
- data/app/helpers/products_helper.rb +2 -2
- data/app/models/address.rb +2 -2
- data/app/models/app_configuration.rb +1 -0
- data/app/models/creditcard_payment.rb +6 -14
- data/app/models/order.rb +6 -12
- data/app/models/order_filter.rb +1 -0
- data/app/models/product.rb +9 -0
- data/app/models/product_property.rb +1 -0
- data/app/models/property.rb +0 -1
- data/app/models/zone.rb +17 -3
- data/app/views/account/login.html.erb +2 -14
- data/app/views/admin/configurations/index.html.erb +4 -0
- data/app/views/admin/inventory_settings/edit.html.erb +18 -0
- data/app/views/admin/inventory_settings/show.html.erb +11 -0
- data/app/views/admin/orders/_address.html.erb +1 -1
- data/app/views/admin/orders/index.html.erb +5 -1
- data/app/views/admin/orders/show.html.erb +3 -3
- data/app/views/admin/product_properties/_product_property.html.erb +6 -3
- data/app/views/admin/products/_form.html.erb +9 -1
- data/app/views/admin/prototypes/select.rjs +3 -1
- data/app/views/admin/variants/_form.html.erb +6 -0
- data/app/views/admin/variants/index.html.erb +7 -1
- data/app/views/creditcard_payments/_form_credit_card.html.erb +1 -1
- data/app/views/creditcard_payments/new.html.erb +7 -2
- data/app/views/products/show.html.erb +8 -2
- data/app/views/shared/_login.html.erb +17 -0
- data/app/views/shared/_products.html.erb +1 -1
- data/app/views/users/_form.html.erb +1 -1
- data/app/views/users/new.html.erb +19 -8
- data/config/boot.rb +1 -1
- data/config/database.yml +7 -3
- data/config/environment.rb +16 -2
- data/config/routes.rb +4 -0
- data/db/migrate/20081016002224_remove_defunct_order_fields.rb +10 -0
- data/db/migrate/20081016162924_drop_category_id_from_products.rb +9 -0
- data/db/sample/addresses.yml +14 -0
- data/db/sample/orders.yml +0 -1
- data/lang/ui/de-DE.yml +2 -1
- data/lang/ui/en-US.yml +50 -25
- data/lang/ui/es-ES.yml +2 -1
- data/lang/ui/it-IT.yml +2 -1
- data/lang/ui/pl-PL.yml +1 -0
- data/lang/ui/pt-BR.yml +5 -2
- data/lib/authenticated_system.rb +1 -1
- data/lib/generators/extension/extension_generator.rb +1 -0
- data/lib/generators/extension/templates/extension.rb +4 -5
- data/lib/generators/extension/templates/tasks.rake +12 -0
- data/lib/generators/extension_migration/extension_migration_generator.rb +32 -0
- data/lib/generators/extension_migration/templates/migration.rb +7 -0
- data/lib/spree.rb +2 -2
- data/lib/spree/extension.rb +0 -7
- data/lib/spree/extension_loader.rb +0 -8
- data/lib/tasks/extensions.rake +47 -0
- data/public/javascripts/application.js +34 -0
- data/public/javascripts/spree-yui.js +2 -2
- data/public/stylesheets/spree.css +11 -1
- data/spec/fixtures/preferences.yml +14 -6
- data/spec/models/address_spec.rb +78 -0
- data/spec/models/country_spec.rb +29 -0
- data/spec/models/option_type_spec.rb +36 -0
- data/spec/models/option_value_spec.rb +39 -0
- data/spec/models/product_option_type_spec.rb +38 -0
- data/spec/models/product_property_spec.rb +36 -0
- data/spec/models/product_spec.rb +109 -32
- data/spec/models/property_spec.rb +38 -0
- data/spec/models/prototype_spec.rb +35 -0
- data/spec/models/state_spec.rb +28 -0
- data/spec/models/taxon_spec.rb +38 -0
- data/spec/models/taxonomy_spec.rb +37 -0
- data/spec/models/variant_spec.rb +73 -12
- data/spec/models/zone_spec.rb +35 -15
- data/spec/spec_helper.rb +15 -0
- data/spec/views/admin/configurations/index.html.erb_spec.rb +29 -0
- data/spec/views/admin/mail_settings/show.html.erb_spec.rb +3 -3
- data/spec/views/products/index.html.erb_spec.rb +46 -0
- data/spec/views/products/show.html.erb_spec.rb +46 -0
- data/vendor/extensions/flat_rate_shipping/README.markdown +3 -0
- data/vendor/extensions/flat_rate_shipping/Rakefile +120 -0
- data/vendor/extensions/flat_rate_shipping/flat_rate_shipping_extension.rb +17 -0
- data/vendor/extensions/flat_rate_shipping/lib/flat_rate_shipping_configuration.rb +7 -0
- data/vendor/extensions/flat_rate_shipping/lib/spree/flat_rate_shipping/calculator.rb +9 -0
- data/vendor/extensions/flat_rate_shipping/lib/spree/flat_rate_shipping/config.rb +22 -0
- data/vendor/extensions/flat_rate_shipping/lib/tasks/flat_rate_shipping_extension_tasks.rake +29 -0
- data/vendor/extensions/flat_rate_shipping/spec/spec.opts +6 -0
- data/vendor/extensions/flat_rate_shipping/spec/spec_helper.rb +37 -0
- data/vendor/extensions/localization/localization_extension.rb +1 -6
- data/vendor/extensions/payment_gateway/lib/gateway_config.rb +7 -0
- data/vendor/extensions/payment_gateway/lib/spree/gateway/config.rb +22 -0
- data/vendor/extensions/payment_gateway/lib/spree/payment_gateway.rb +27 -3
- data/vendor/extensions/payment_gateway/payment_gateway_extension.rb +0 -4
- data/vendor/extensions/shipping/README.markdown +3 -0
- data/vendor/extensions/shipping/Rakefile +120 -0
- data/vendor/extensions/shipping/app/controllers/admin/shipping_categories_controller.rb +17 -0
- data/vendor/extensions/shipping/app/controllers/admin/shipping_methods_controller.rb +21 -0
- data/vendor/extensions/shipping/app/controllers/shipments_controller.rb +84 -0
- data/vendor/extensions/shipping/app/helpers/admin/shipping_categories_helper.rb +2 -0
- data/vendor/extensions/shipping/app/helpers/admin/shipping_methods_helper.rb +2 -0
- data/vendor/extensions/shipping/app/helpers/shipments_helper.rb +20 -0
- data/vendor/extensions/shipping/app/models/shipment.rb +11 -0
- data/vendor/extensions/shipping/app/models/shipping_category.rb +3 -0
- data/vendor/extensions/shipping/app/models/shipping_method.rb +12 -0
- data/vendor/extensions/shipping/app/views/admin/shipping_categories/_form.html.erb +6 -0
- data/vendor/extensions/shipping/app/views/admin/shipping_categories/edit.html.erb +8 -0
- data/vendor/extensions/shipping/app/views/admin/shipping_categories/index.html.erb +24 -0
- data/vendor/extensions/shipping/app/views/admin/shipping_categories/new.html.erb +10 -0
- data/vendor/extensions/shipping/app/views/admin/shipping_methods/_form.html.erb +14 -0
- data/vendor/extensions/shipping/app/views/admin/shipping_methods/edit.html.erb +8 -0
- data/vendor/extensions/shipping/app/views/admin/shipping_methods/index.html.erb +28 -0
- data/vendor/extensions/shipping/app/views/admin/shipping_methods/new.html.erb +10 -0
- data/vendor/extensions/shipping/app/views/orders/fatal_shipping.html.erb +6 -0
- data/vendor/extensions/shipping/app/views/shipments/_form.html.erb +46 -0
- data/vendor/extensions/shipping/app/views/shipments/edit.html.erb +8 -0
- data/vendor/extensions/shipping/app/views/shipments/new.html.erb +8 -0
- data/vendor/extensions/shipping/db/migrate/20081003211336_create_shipping_methods.rb +14 -0
- data/vendor/extensions/shipping/db/migrate/20081003233427_create_shipping_categories.rb +15 -0
- data/vendor/extensions/shipping/db/migrate/20081015001711_create_shipments.rb +14 -0
- data/vendor/extensions/shipping/db/migrate/20081023134446_add_product_dimensions.rb +19 -0
- data/vendor/extensions/shipping/db/sample/shipping_categories.yml +2 -0
- data/vendor/extensions/shipping/db/sample/shipping_methods.yml +12 -0
- data/vendor/extensions/shipping/db/sample/zone_members.yml +8 -0
- data/vendor/extensions/shipping/db/sample/zones.yml +3 -0
- data/vendor/extensions/shipping/lang/en-US.yml +9 -0
- data/vendor/extensions/shipping/lib/spree/shipping_calculator.rb +37 -0
- data/vendor/extensions/shipping/lib/spree/shipping_error.rb +3 -0
- data/vendor/extensions/shipping/lib/tasks/shipping_extension_tasks.rake +29 -0
- data/vendor/extensions/shipping/shipping_extension.rb +39 -0
- data/vendor/extensions/shipping/spec/controllers/admin/shipping_categories_controller_spec.rb +10 -0
- data/vendor/extensions/shipping/spec/controllers/admin/shipping_methods_controller_spec.rb +10 -0
- data/vendor/extensions/shipping/spec/models/order_spec.rb +98 -0
- data/vendor/extensions/shipping/spec/models/shipment_spec.rb +26 -0
- data/vendor/extensions/shipping/spec/models/shipping_category_spec.rb +8 -0
- data/vendor/extensions/shipping/spec/models/shipping_method_spec.rb +53 -0
- data/vendor/extensions/shipping/spec/spec.opts +6 -0
- data/vendor/extensions/shipping/spec/spec_helper.rb +37 -0
- data/vendor/extensions/tax_calculator/lib/spree/sales_tax_calculator.rb +12 -4
- data/vendor/extensions/tax_calculator/spec/controllers/tax_calculator_spec.rb +0 -4
- data/vendor/extensions/tax_calculator/spec/models/sales_tax_calculator_spec.rb +14 -14
- data/vendor/extensions/tax_calculator/tax_calculator_extension.rb +0 -4
- data/vendor/plugins/resource_controller/README.rdoc +38 -6
- data/vendor/plugins/resource_controller/Rakefile +7 -20
- data/vendor/plugins/resource_controller/TODO +0 -1
- data/vendor/plugins/resource_controller/lib/resource_controller/helpers/current_objects.rb +71 -69
- data/vendor/plugins/resource_controller/lib/resource_controller/helpers/internal.rb +69 -65
- data/vendor/plugins/resource_controller/lib/resource_controller/helpers/nested.rb +62 -57
- data/vendor/plugins/resource_controller/lib/resource_controller/helpers/singleton_customizations.rb +50 -46
- data/vendor/plugins/resource_controller/lib/resource_controller/helpers/urls.rb +73 -69
- data/vendor/plugins/resource_controller/resource_controller.gemspec +4 -3
- data/vendor/plugins/resource_controller/test/app/controllers/cms/personnel_controller.rb +2 -0
- data/vendor/plugins/resource_controller/test/app/controllers/cms/photos_controller.rb +6 -0
- data/vendor/plugins/resource_controller/test/app/models/personnel.rb +3 -0
- data/vendor/plugins/resource_controller/test/app/models/photo.rb +1 -0
- data/vendor/plugins/resource_controller/test/app/views/cms/photos/edit.rhtml +17 -0
- data/vendor/plugins/resource_controller/test/app/views/cms/photos/index.rhtml +20 -0
- data/vendor/plugins/resource_controller/test/app/views/cms/photos/new.rhtml +16 -0
- data/vendor/plugins/resource_controller/test/app/views/cms/photos/show.rhtml +8 -0
- data/vendor/plugins/resource_controller/test/config/database.yml +9 -0
- data/vendor/plugins/resource_controller/test/config/environment.rb +1 -18
- data/vendor/plugins/resource_controller/test/config/initializers/inflections.rb +14 -0
- data/vendor/plugins/resource_controller/test/config/routes.rb +3 -0
- data/vendor/plugins/resource_controller/test/db/migrate/013_create_personnel.rb +11 -0
- data/vendor/plugins/resource_controller/test/db/migrate/014_add_personnel_id_to_photos.rb +9 -0
- data/vendor/plugins/resource_controller/test/test/fixtures/personnel.yml +5 -0
- data/vendor/plugins/resource_controller/test/test/functional/cms/photos_controller_test.rb +43 -0
- metadata +136 -6
- data/app/models/spree/extension_meta.rb +0 -5
- data/app/models/variants.rb +0 -2
- data/vendor/plugins/resource_controller/lib/resource_controller/version.rb +0 -9
@@ -0,0 +1,39 @@
|
|
1
|
+
# Uncomment this if you reference any of your controllers in activate
|
2
|
+
require_dependency 'application'
|
3
|
+
|
4
|
+
class ShippingExtension < Spree::Extension
|
5
|
+
version "1.0"
|
6
|
+
description "Describe your extension here"
|
7
|
+
url "http://yourwebsite.com/shipping"
|
8
|
+
|
9
|
+
define_routes do |map|
|
10
|
+
map.namespace :admin do |admin|
|
11
|
+
admin.resources :shipping_methods
|
12
|
+
admin.resources :shipping_categories
|
13
|
+
end
|
14
|
+
map.resources :shipments
|
15
|
+
map.resources :orders, :has_many => :shipments, :member => {:fatal_shipping => :get}
|
16
|
+
end
|
17
|
+
|
18
|
+
def activate
|
19
|
+
|
20
|
+
Order.class_eval do
|
21
|
+
has_many :shipments, :dependent => :destroy
|
22
|
+
include Spree::ShippingCalculator
|
23
|
+
end
|
24
|
+
AddressesController.class_eval do
|
25
|
+
# limit the countries to the ones that are possible to ship to
|
26
|
+
def load_countries
|
27
|
+
@countries = @order.shipping_countries
|
28
|
+
@countries = [Country.find(Spree::Config[:default_country_id])] if @countries.empty?
|
29
|
+
end
|
30
|
+
end
|
31
|
+
Admin::ConfigurationsController.class_eval do
|
32
|
+
before_filter :add_shipping_links, :only => :index
|
33
|
+
def add_shipping_links
|
34
|
+
@extension_links << {:link => admin_shipping_methods_path, :link_text => Globalite.localize(:ext_shipping_shipping_methods), :description => Globalite.localize(:ext_shipping_shipping_methods_description)}
|
35
|
+
@extension_links << {:link => admin_shipping_categories_path, :link_text => Globalite.localize(:ext_shipping_shipping_categories), :description => Globalite.localize(:ext_shipping_shipping_categories_description)}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Admin::ShippingCategoriesController do
|
4
|
+
|
5
|
+
#Delete this example and add some real ones
|
6
|
+
it "should use Admin::ShippingCategoriesController" do
|
7
|
+
controller.should be_an_instance_of(Admin::ShippingCategoriesController)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe Admin::ShippingMethodsController do
|
4
|
+
|
5
|
+
#Delete this example and add some real ones
|
6
|
+
it "should use Admin::ShippingMethodsController" do
|
7
|
+
controller.should be_an_instance_of(Admin::ShippingMethodsController)
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
|
3
|
+
describe Order do
|
4
|
+
before(:each) do
|
5
|
+
@order = Order.new(:address => @address = mock_model(Address, :null_object => true))
|
6
|
+
#add_stubs(@order, :save => true)
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "shipping_countries" do
|
10
|
+
it "should return an empty array if there are no shipping methods configured" do
|
11
|
+
ShippingMethod.stub!(:all).and_return([])
|
12
|
+
@order.shipping_countries.should == []
|
13
|
+
end
|
14
|
+
it "should contain only a single country even if multiple shipping methods are configured with that same country" do
|
15
|
+
country = mock_model(Country)
|
16
|
+
method1 = mock_model(ShippingMethod, :zone => mock_model(Zone, :country_list => [country]))
|
17
|
+
method2 = mock_model(ShippingMethod, :zone => mock_model(Zone, :country_list => [country]))
|
18
|
+
ShippingMethod.stub!(:all).and_return([method1, method2])
|
19
|
+
@order.shipping_countries.should == [country]
|
20
|
+
end
|
21
|
+
it "should contain the unique list of countries that fall within at least one shipping method's zone" do
|
22
|
+
country1 = mock_model(Country)
|
23
|
+
country2 = mock_model(Country)
|
24
|
+
method1 = mock_model(ShippingMethod, :zone => mock_model(Zone, :country_list => [country1]))
|
25
|
+
method2 = mock_model(ShippingMethod, :zone => mock_model(Zone, :country_list => [country2]))
|
26
|
+
ShippingMethod.stub!(:all).and_return([method1, method2])
|
27
|
+
@order.shipping_countries.should == [country1, country2]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "shipping_methods" do
|
32
|
+
it "should return empty array if there are no shipping methods configured" do
|
33
|
+
ShippingMethod.stub!(:all).and_return([])
|
34
|
+
@order.shipping_methods.should == []
|
35
|
+
end
|
36
|
+
it "should check the shipping address against the shipping method's zone" do
|
37
|
+
zone = mock_model(Zone)
|
38
|
+
method = mock_model(ShippingMethod, :zone => zone)
|
39
|
+
ShippingMethod.stub!(:all).and_return([method])
|
40
|
+
zone.should_receive(:include?).with(@address)
|
41
|
+
@order.shipping_methods
|
42
|
+
end
|
43
|
+
it "should return empty array if none of the configured shipping methods cover the shipping address" do
|
44
|
+
method = mock_model(ShippingMethod, :zone => mock_model(Zone, :include? => false))
|
45
|
+
ShippingMethod.stub!(:all).and_return([method])
|
46
|
+
@order.shipping_methods.should == []
|
47
|
+
end
|
48
|
+
it "should return all shipping methiods that cover the shipping address" do
|
49
|
+
method1 = mock_model(ShippingMethod, :zone => mock_model(Zone, :include? => true))
|
50
|
+
method2 = mock_model(ShippingMethod, :zone => mock_model(Zone, :include? => true))
|
51
|
+
method3 = mock_model(ShippingMethod, :zone => mock_model(Zone, :include? => false))
|
52
|
+
ShippingMethod.stub!(:all).and_return([method1, method2, method3])
|
53
|
+
@order.shipping_methods.should == [method1, method2]
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "state_machine in 'address' state" do
|
58
|
+
before :each do
|
59
|
+
@order.state = 'address'
|
60
|
+
end
|
61
|
+
describe "when there are no shipping methods" do
|
62
|
+
it "next! should transition to 'creditcard_payment'" do
|
63
|
+
@order.stub!(:shipping_methods).and_return([])
|
64
|
+
@order.next!
|
65
|
+
@order.state.should == "creditcard_payment"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
describe "when there is only one shipping method" do
|
69
|
+
before :each do
|
70
|
+
@shipping_method = ShippingMethod.new
|
71
|
+
@order.stub!(:shipping_methods).and_return([@shipping_method])
|
72
|
+
end
|
73
|
+
it "next! should transition to 'creditcard_payment'" do
|
74
|
+
@order.next!
|
75
|
+
@order.state.should == "creditcard_payment"
|
76
|
+
end
|
77
|
+
it "should automatically calculate the shipping cost using the single shipping method" do
|
78
|
+
@order.next!
|
79
|
+
@order.shipments.first.shipping_method.should == @shipping_method
|
80
|
+
end
|
81
|
+
end
|
82
|
+
describe "when there is only one shipping method" do
|
83
|
+
it "next! should transition to 'shipment'" do
|
84
|
+
@order.stub!(:shipping_methods).and_return([ShippingMethod.new, ShippingMethod.new])
|
85
|
+
@order.next!
|
86
|
+
@order.state.should == "shipment"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
describe "state_machine in 'shipment' state" do
|
92
|
+
it "next! should transition to 'creditcard_payment'" do
|
93
|
+
@order.state = 'shipment'
|
94
|
+
@order.next!
|
95
|
+
@order.state.should == "creditcard_payment"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
class MockCalculator
|
4
|
+
end
|
5
|
+
|
6
|
+
describe Shipment do
|
7
|
+
before :each do
|
8
|
+
@order = Order.new
|
9
|
+
@shipping_method = ShippingMethod.new(:shipping_calculator => "MockCalculator")
|
10
|
+
@shipment = Shipment.new(:order => @order, :shipping_method => @shipping_method)
|
11
|
+
@calculator = MockCalculator.new
|
12
|
+
MockCalculator.stub!(:new).and_return(@calculator)
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "update" do
|
16
|
+
it "should calculate the shipping cost using the specified calculator" do
|
17
|
+
@calculator.should_receive(:calculate_shipping).with(@order)
|
18
|
+
@shipment.save
|
19
|
+
end
|
20
|
+
it "should assign the calculated cost to the order" do
|
21
|
+
@calculator.stub!(:calculate_shipping).with(@order).and_return(8.95)
|
22
|
+
@order.should_receive(:update_attribute).with(:ship_amount, 8.95)
|
23
|
+
@shipment.save
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
class MockCalculator
|
4
|
+
def calculate_shipping(order)
|
5
|
+
2.5
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe ShippingMethod do
|
10
|
+
before(:each) do
|
11
|
+
@zone = mock_model(Zone)
|
12
|
+
@address = mock_model(Address)
|
13
|
+
@shipping_method = ShippingMethod.new(:zone => @zone, :shipping_calculator => "MockCalculator")
|
14
|
+
@order = mock_model(Order, :address => @address)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "available?" do
|
18
|
+
it "should check the shipping address against the zone" do
|
19
|
+
@zone.should_receive(:include?).with(@address)
|
20
|
+
@shipping_method.available?(@order)
|
21
|
+
end
|
22
|
+
it "should be true if the shipping address is located within the method's zone" do
|
23
|
+
@zone.stub!(:include?).with(@address).and_return(true)
|
24
|
+
@shipping_method.available?(@order).should be_true
|
25
|
+
end
|
26
|
+
it "should be false if the shipping address is located outside of the method's zone" do
|
27
|
+
@zone.stub!(:include?).with(@address).and_return(false)
|
28
|
+
@shipping_method.available?(@order).should be_false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "calculate_shipping" do
|
33
|
+
it "should be 0 if the shipping address does not fall within the method's zone" do
|
34
|
+
@zone.stub!(:include?).with(@address).and_return(false)
|
35
|
+
@shipping_method.calculate_shipping(@order).should == 0
|
36
|
+
end
|
37
|
+
describe "when the shipping address is included within the method's zone" do
|
38
|
+
before :each do
|
39
|
+
@zone.stub!(:include?).with(@address).and_return(true)
|
40
|
+
# TODO - stub out instatiation code
|
41
|
+
end
|
42
|
+
it "should use the calculate_shipping method of the specified calculator" do
|
43
|
+
@calculator = MockCalculator.new
|
44
|
+
MockCalculator.stub!(:new).and_return(@calculator)
|
45
|
+
@calculator.should_receive(:calculate_shipping).with(@order)
|
46
|
+
@shipping_method.calculate_shipping(@order)
|
47
|
+
end
|
48
|
+
it "should return the correct amount" do
|
49
|
+
@shipping_method.calculate_shipping(@order).should == 2.5
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
unless defined? SPREE_ROOT
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
3
|
+
case
|
4
|
+
when ENV["SPREE_ENV_FILE"]
|
5
|
+
require ENV["SPREE_ENV_FILE"]
|
6
|
+
when File.dirname(__FILE__) =~ %r{vendor/SPREE/vendor/extensions}
|
7
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment"
|
8
|
+
else
|
9
|
+
require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
require "#{SPREE_ROOT}/spec/spec_helper"
|
13
|
+
|
14
|
+
if File.directory?(File.dirname(__FILE__) + "/scenarios")
|
15
|
+
Scenario.load_paths.unshift File.dirname(__FILE__) + "/scenarios"
|
16
|
+
end
|
17
|
+
if File.directory?(File.dirname(__FILE__) + "/matchers")
|
18
|
+
Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
|
19
|
+
end
|
20
|
+
|
21
|
+
Spec::Runner.configure do |config|
|
22
|
+
# config.use_transactional_fixtures = true
|
23
|
+
# config.use_instantiated_fixtures = false
|
24
|
+
# config.fixture_path = RAILS_ROOT + '/spec/fixtures'
|
25
|
+
|
26
|
+
# You can declare fixtures for each behaviour like this:
|
27
|
+
# describe "...." do
|
28
|
+
# fixtures :table_a, :table_b
|
29
|
+
#
|
30
|
+
# Alternatively, if you prefer to declare them only once, you can
|
31
|
+
# do so here, like so ...
|
32
|
+
#
|
33
|
+
# config.global_fixtures = :table_a, :table_b
|
34
|
+
#
|
35
|
+
# If you declare global fixtures, be aware that they will be declared
|
36
|
+
# for all of your examples, even those that don't use them.
|
37
|
+
end
|
@@ -3,18 +3,26 @@ module Spree #:nodoc:
|
|
3
3
|
|
4
4
|
def self.calculate_tax(order, rates)
|
5
5
|
return 0 if rates.empty?
|
6
|
+
# note: there is a bug with associations in rails 2.1 model caching so we're using this hack
|
7
|
+
# (see http://rails.lighthouseapp.com/projects/8994/tickets/785-caching-models-fails-in-development)
|
8
|
+
cache_hack = rates.first.respond_to?(:tax_category_id)
|
9
|
+
|
6
10
|
taxable_totals = {}
|
7
11
|
order.line_items.each do |line_item|
|
8
12
|
next unless tax_category = line_item.variant.product.tax_category
|
9
|
-
next unless rate = rates
|
10
|
-
|
13
|
+
next unless rate = rates.find { | sales_rate | sales_rate.tax_category_id == tax_category.id } if cache_hack
|
14
|
+
next unless rate = rates.find { | sales_rate | sales_rate.tax_category == tax_category } unless cache_hack
|
15
|
+
|
16
|
+
taxable_totals[tax_category] ||= 0
|
11
17
|
taxable_totals[tax_category] += line_item.total
|
12
18
|
end
|
13
19
|
|
14
20
|
return 0 if taxable_totals.empty?
|
15
21
|
tax = 0
|
16
|
-
rates.each do |
|
17
|
-
|
22
|
+
rates.each do |rate|
|
23
|
+
tax_category = rate.tax_category unless cache_hack
|
24
|
+
tax_category = TaxCategory.find(rate.tax_category_id) if cache_hack
|
25
|
+
next unless taxable_total = taxable_totals[tax_category]
|
18
26
|
tax += taxable_total * rate.amount
|
19
27
|
end
|
20
28
|
tax
|
@@ -3,10 +3,6 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
3
3
|
describe ApplicationController do
|
4
4
|
|
5
5
|
before(:each) do
|
6
|
-
@new_york = mock_model State, :name => "New York"
|
7
|
-
@ship_address = mock_model Address, {:state => @new_york}
|
8
|
-
@order = mock_model Order, {:item_total => 100, :ship_address => @ship_address}
|
9
|
-
@tax_rate = mock_model TaxRate, {:state => @new_york, :rate => 0.075}
|
10
6
|
end
|
11
7
|
|
12
8
|
it "should map :controller => 'admin/tax_rates', :action => 'index') to /admin/tax_rates" do
|
@@ -14,40 +14,40 @@ describe Spree::SalesTaxCalculator do
|
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should calc zero tax if no rates provided" do
|
17
|
-
Spree::SalesTaxCalculator.calculate_tax(@order,
|
17
|
+
Spree::SalesTaxCalculator.calculate_tax(@order, []).should == 0
|
18
18
|
end
|
19
19
|
|
20
20
|
it "should calc zero tax if none of the line items contains a taxable product" do
|
21
|
-
tax_category =
|
21
|
+
tax_category = TaxCategory.create(:name => "foo")
|
22
22
|
tax_rate = mock_model(TaxRate, :amount => 0.05, :category => tax_category)
|
23
23
|
@product1.should_receive(:tax_category).and_return(nil)
|
24
24
|
@product2.should_receive(:tax_category).and_return(nil)
|
25
|
-
Spree::SalesTaxCalculator.calculate_tax(@order,
|
25
|
+
Spree::SalesTaxCalculator.calculate_tax(@order, [tax_rate]).should == 0
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should calc tax only on the items that are taxable" do
|
29
|
-
tax_category =
|
30
|
-
tax_rate =
|
29
|
+
tax_category = TaxCategory.create(:name => "foo")
|
30
|
+
tax_rate = TaxRate.new(:amount => 0.05, :tax_category => tax_category)
|
31
31
|
@product1.should_receive(:tax_category).and_return(nil)
|
32
32
|
@product2.should_receive(:tax_category).and_return(tax_category)
|
33
|
-
Spree::SalesTaxCalculator.calculate_tax(@order,
|
33
|
+
Spree::SalesTaxCalculator.calculate_tax(@order, [tax_rate]).should == 5
|
34
34
|
end
|
35
35
|
|
36
36
|
it "should apply tax to the total of all taxable line items" do
|
37
|
-
tax_category =
|
38
|
-
tax_rate =
|
37
|
+
tax_category = TaxCategory.create(:name => "foo")
|
38
|
+
tax_rate = TaxRate.new(:amount => 0.10, :tax_category => tax_category)
|
39
39
|
@product1.stub!(:tax_category).and_return(tax_category)
|
40
40
|
@product2.stub!(:tax_category).and_return(tax_category)
|
41
|
-
Spree::SalesTaxCalculator.calculate_tax(@order,
|
41
|
+
Spree::SalesTaxCalculator.calculate_tax(@order, [tax_rate]).should == 20
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should apply the correct tax rates based on tax category" do
|
45
|
-
tax_category1 =
|
46
|
-
tax_category2 =
|
47
|
-
tax_rate1 =
|
48
|
-
tax_rate2 =
|
45
|
+
tax_category1 = TaxCategory.create(:name => "foo")
|
46
|
+
tax_category2 = TaxCategory.create(:name => "bar")
|
47
|
+
tax_rate1 = TaxRate.create(:amount => 0.10, :tax_category => tax_category1)
|
48
|
+
tax_rate2 = TaxRate.create(:amount => 0.05, :tax_category => tax_category2)
|
49
49
|
@product1.stub!(:tax_category).and_return(tax_category1)
|
50
50
|
@product2.stub!(:tax_category).and_return(tax_category2)
|
51
|
-
Spree::SalesTaxCalculator.calculate_tax(@order,
|
51
|
+
Spree::SalesTaxCalculator.calculate_tax(@order, [tax_rate1, tax_rate2]).should == 15
|
52
52
|
end
|
53
53
|
end
|
@@ -4,13 +4,9 @@ resource_controller makes RESTful controllers easier, more maintainable, and sup
|
|
4
4
|
|
5
5
|
== Get It
|
6
6
|
|
7
|
-
|
7
|
+
Install it as a plugin:
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
Or install it as a gem manually
|
12
|
-
|
13
|
-
sudo gem install giraffesoft-resource_controller
|
9
|
+
script/plugin install git://github.com/giraffesoft/resource_controller.git
|
14
10
|
|
15
11
|
Or grab the source
|
16
12
|
|
@@ -102,6 +98,42 @@ With actions that can fail, the scoping defaults to success. That means that cr
|
|
102
98
|
end
|
103
99
|
|
104
100
|
end
|
101
|
+
|
102
|
+
== Singleton Resource
|
103
|
+
|
104
|
+
If you want to create a singleton RESTful controller inherit from ResourceController::Singleton.
|
105
|
+
|
106
|
+
class AccountsController < ResourceController::Singleton
|
107
|
+
end
|
108
|
+
|
109
|
+
*Note:* This type of controllers handle a single resource only so the index action and all the collection helpers (collection_url, collection_path...) are not available for them.
|
110
|
+
|
111
|
+
Loading objects in singletons is similar to plural controllers with one exception. For non-nested singleton controllers you should override the object method as it defaults to nil for them.
|
112
|
+
|
113
|
+
class AccountsController < ResourceController::Singleton
|
114
|
+
private
|
115
|
+
def object
|
116
|
+
@object ||= Account.find(session[:account_id])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
In other cases you can use the default logic and override it only if you use permalinks or anything special.
|
121
|
+
|
122
|
+
Singleton nesting with both :has_many and :has_one associations is provided...
|
123
|
+
|
124
|
+
map.resource :account, :has_many => :options # /account/options, account is a singleton parent
|
125
|
+
map.resources :users, :has_one => :image # /users/1/image, image is a singleton child
|
126
|
+
|
127
|
+
If you have the :has_many association with a singleton parent remember to override parent_object for your :has_many controller as it returns nil by default in this case.
|
128
|
+
|
129
|
+
class OptionsController < ResourceController::Base
|
130
|
+
belongs_to :account
|
131
|
+
|
132
|
+
protected
|
133
|
+
def parent_object
|
134
|
+
Account.find(session[:account_id])
|
135
|
+
end
|
136
|
+
end
|
105
137
|
|
106
138
|
== Helpers (ResourceController::Helpers)
|
107
139
|
|