spree 0.6.0 → 0.7.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 +30 -0
- data/CONTRIBUTORS +38 -20
- data/app/controllers/admin/creditcard_payments_controller.rb +10 -3
- data/app/controllers/admin/orders_controller.rb +17 -16
- data/app/controllers/admin/products_controller.rb +12 -14
- data/app/controllers/admin/reports_controller.rb +12 -14
- data/app/controllers/admin/users_controller.rb +10 -5
- data/app/controllers/admin/zones_controller.rb +4 -1
- data/app/controllers/application.rb +0 -1
- data/app/controllers/checkout_controller.rb +96 -0
- data/app/controllers/content_controller.rb +11 -1
- data/app/controllers/orders_controller.rb +12 -33
- data/app/controllers/products_controller.rb +12 -7
- data/app/controllers/spree/base_controller.rb +1 -1
- data/app/controllers/states_controller.rb +14 -2
- data/app/controllers/taxons_controller.rb +6 -2
- data/app/controllers/users_controller.rb +9 -6
- data/app/helpers/application_helper.rb +1 -11
- data/app/helpers/products_helper.rb +3 -1
- data/app/helpers/spree/base_helper.rb +0 -26
- data/app/models/address.rb +3 -3
- data/app/models/app_configuration.rb +1 -0
- data/app/models/country.rb +4 -0
- data/app/models/creditcard.rb +6 -1
- data/app/models/creditcard_payment.rb +1 -1
- data/app/models/inventory_unit.rb +4 -1
- data/app/models/order.rb +37 -21
- data/app/models/product.rb +19 -8
- data/{vendor/extensions/shipping/app → app}/models/shipment.rb +20 -4
- data/{vendor/extensions/shipping/app → app}/models/shipping_category.rb +0 -0
- data/{vendor/extensions/shipping/app → app}/models/shipping_method.rb +6 -4
- data/app/models/state.rb +5 -0
- data/app/models/user.rb +4 -2
- data/app/models/variant.rb +19 -1
- data/app/presenters/checkout_presenter.rb +58 -0
- data/app/views/admin/creditcard_payments/edit.html.erb +1 -1
- data/app/views/admin/option_types/available.html.erb +1 -1
- data/app/views/admin/orders/index.html.erb +28 -18
- data/app/views/admin/orders/show.html.erb +1 -1
- data/app/views/admin/payments/index.html.erb +1 -1
- data/app/views/admin/products/_images.html.erb +1 -1
- data/app/views/admin/products/index.html.erb +17 -13
- data/app/views/admin/users/index.html.erb +8 -8
- data/app/views/admin/zones/index.html.erb +5 -2
- data/app/views/checkout/_form.html.erb +165 -0
- data/app/views/{creditcards → checkout}/cvv.html.erb +1 -1
- data/app/views/checkout/new.html.erb +6 -0
- data/app/views/layouts/admin.html.erb +2 -3
- data/app/views/layouts/application.html.erb +1 -1
- data/app/views/orders/_form.html.erb +6 -4
- data/app/views/orders/_google_order.html.erb +24 -0
- data/app/views/orders/_line_item.html.erb +2 -1
- data/app/views/orders/show.html.erb +4 -1
- data/app/views/products/index.html.erb +2 -1
- data/app/views/products/show.html.erb +4 -4
- data/app/views/shared/_footer.html.erb +12 -1
- data/app/views/shared/_login.html.erb +1 -1
- data/app/views/shared/_order_details.html.erb +8 -9
- data/app/views/shared/_products.html.erb +1 -1
- data/app/views/shared/_report_criteria.html.erb +28 -28
- data/app/views/states/index.js.erb +10 -1
- data/config/environment.rb +10 -4
- data/config/initializers/searchlogic.rb +6 -0
- data/config/locales/de.yml +14 -0
- data/config/locales/en-GB.yml +20 -6
- data/config/locales/en-US.yml +20 -4
- data/config/locales/es.yml +14 -0
- data/config/locales/fr-FR.yml +463 -0
- data/config/locales/fr-FR_rails.yml +115 -0
- data/config/locales/it.yml +14 -0
- data/config/locales/nb-NO.yml +457 -0
- data/config/locales/nb-NO_rails.yml +105 -0
- data/config/locales/pl.yml +14 -0
- data/config/locales/pt-BR.yml +14 -0
- data/config/locales/pt-PT.yml +14 -0
- data/config/locales/ru-RU.yml +458 -0
- data/config/locales/ru-RU_rails.yml +154 -0
- data/config/routes.rb +11 -4
- data/db/migrate/20090204200045_add_order_permalink.rb +13 -0
- data/db/migrate/20090225231119_add_more_needed_keys_items_and_conf.rb +19 -0
- data/db/migrate/20090302221152_give_all_users_user_role.rb +13 -0
- data/db/sample/orders.yml +1 -1
- data/lib/generators/instance/instance_generator.rb +1 -1
- data/lib/spree.rb +1 -1
- data/lib/spree/setup.rb +1 -1
- data/lib/tasks/database.rake +5 -2
- data/lib/tasks/release.rake +1 -1
- data/lib/tasks/upgrade.rake +11 -0
- data/public/assets/products/1009/mini/sean.jpg +0 -0
- data/public/assets/products/1009/original/sean.jpg +0 -0
- data/public/assets/products/1009/product/sean.jpg +0 -0
- data/public/assets/products/1009/small/sean.jpg +0 -0
- data/public/images/ajax_loader.gif +0 -0
- data/public/javascripts/checkout.js +284 -0
- data/public/javascripts/jquery-1.3.2.min.js +19 -0
- data/public/javascripts/jquery.validate.pack.js +15 -0
- data/public/stylesheets/checkout.css +25 -0
- data/public/stylesheets/spree-admin.css +6 -2
- data/public/stylesheets/spree.css +419 -432
- data/spec/controllers/countries_controller_spec.rb +3 -2
- data/spec/controllers/orders_controller_spec.rb +7 -5
- data/spec/controllers/states_controller_spec.rb +4 -2
- data/spec/models/creditcard_payment_spec.rb +6 -2
- data/spec/models/order_spec.rb +164 -157
- data/spec/models/product_spec.rb +2 -2
- data/vendor/extensions/payment_gateway/db/migrate/20090218091936_create_protx_gateway.rb +18 -0
- data/vendor/extensions/payment_gateway/lib/spree/payment_gateway.rb +7 -5
- data/vendor/extensions/shipping/app/controllers/admin/shipments_controller.rb +6 -5
- data/vendor/extensions/shipping/app/views/admin/shipments/index.html.erb +1 -1
- data/vendor/extensions/shipping/config/locales/nb-NO.yml +25 -0
- data/vendor/extensions/shipping/config/locales/ru-RU.yml +25 -0
- data/vendor/extensions/shipping/db/sample/shipping_methods.yml +5 -1
- data/vendor/extensions/shipping/db/sample/zone_members.yml +9 -1
- data/vendor/extensions/shipping/db/sample/zones.yml +4 -1
- data/vendor/extensions/shipping/lib/spree/shipping_calculator.rb +0 -16
- data/vendor/extensions/shipping/shipping_extension.rb +0 -15
- data/vendor/extensions/shipping/spec/models/shipping_method_spec.rb +16 -10
- data/vendor/extensions/shipping/spec/models/shipping_order_spec.rb +3 -17
- data/vendor/extensions/tax_calculator/config/locales/nb-NO.yml +30 -0
- data/vendor/extensions/tax_calculator/spec/models/{order_spec.rb → order_tax_calc_spec.rb} +2 -2
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/.specification +3 -5
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/LICENSE +0 -0
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/README +9 -2
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/Rakefile +0 -0
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/active_presenter.rb +0 -0
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/active_presenter/base.rb +38 -8
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/active_presenter/version.rb +1 -1
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/tasks/doc.rake +0 -0
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/lib/tasks/gem.rake +0 -0
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/test/base_test.rb +66 -30
- data/vendor/gems/{active_presenter-0.0.4 → active_presenter-0.0.6}/test/test_helper.rb +36 -0
- data/vendor/plugins/attribute_fu/lib/attribute_fu/associated_form_helper.rb +12 -4
- data/vendor/plugins/find_by_param/MIT-LICENSE +1 -1
- data/vendor/plugins/find_by_param/{README → README.markdown} +7 -1
- data/vendor/plugins/find_by_param/init.rb +0 -1
- data/vendor/plugins/find_by_param/lib/find_by_param.rb +23 -87
- data/vendor/plugins/find_by_param/test/find_by_param_test.rb +22 -8
- data/vendor/plugins/find_by_param/test/test_helper.rb +0 -1
- metadata +65 -193
- data/app/controllers/creditcards_controller.rb +0 -73
- data/app/models/order_filter.rb +0 -28
- data/app/models/user_filter.rb +0 -6
- data/app/views/creditcards/_form_credit_card.html.erb +0 -30
- data/app/views/creditcards/new.html.erb +0 -25
- data/app/views/shared/_paginate.html.erb +0 -34
- data/lib/plugins/paginating_find/CHANGELOG +0 -120
- data/lib/plugins/paginating_find/README +0 -89
- data/lib/plugins/paginating_find/init.rb +0 -2
- data/lib/plugins/paginating_find/lib/paginating_find.rb +0 -138
- data/lib/plugins/paginating_find/lib/paging_enumerator.rb +0 -158
- data/lib/plugins/paginating_find/lib/paging_helper.rb +0 -47
- data/lib/plugins/paginating_find/test_app/Rakefile +0 -10
- data/lib/plugins/paginating_find/test_app/app/controllers/application.rb +0 -2
- data/lib/plugins/paginating_find/test_app/config/boot.rb +0 -44
- data/lib/plugins/paginating_find/test_app/config/database.yml +0 -6
- data/lib/plugins/paginating_find/test_app/config/environment.rb +0 -53
- data/lib/plugins/paginating_find/test_app/config/environments/test.rb +0 -19
- data/lib/plugins/paginating_find/test_app/config/routes.rb +0 -22
- data/lib/plugins/paginating_find/test_app/script/breakpointer +0 -3
- data/lib/plugins/paginating_find/test_app/script/console +0 -3
- data/lib/plugins/paginating_find/test_app/test/fixtures/articles.yml +0 -19
- data/lib/plugins/paginating_find/test_app/test/fixtures/authors.yml +0 -7
- data/lib/plugins/paginating_find/test_app/test/fixtures/edits.yml +0 -11
- data/lib/plugins/paginating_find/test_app/test/fixtures/models.rb +0 -18
- data/lib/plugins/paginating_find/test_app/test/test_helper.rb +0 -33
- data/lib/plugins/paginating_find/test_app/test/unit/abstract_test.rb +0 -7
- data/lib/plugins/paginating_find/test_app/test/unit/group_test.rb +0 -40
- data/lib/plugins/paginating_find/test_app/test/unit/paginating_find_test.rb +0 -194
- data/lib/plugins/paginating_find/test_app/test/unit/paging_enumerator_test.rb +0 -143
- data/public/assets/products/1012/mini/bt.jpg +0 -0
- data/public/assets/products/1012/original/bt.jpg +0 -0
- data/public/assets/products/1012/product/bt.jpg +0 -0
- data/public/assets/products/1012/small/bt.jpg +0 -0
- data/spec/views/products/index.html.erb_spec.rb +0 -46
- data/spec/views/products/show.html.erb_spec.rb +0 -46
- data/vendor/extensions/shipping/app/controllers/shipments_controller.rb +0 -96
- data/vendor/extensions/shipping/app/helpers/shipments_helper.rb +0 -20
- data/vendor/extensions/shipping/app/views/orders/fatal_shipping.html.erb +0 -6
- data/vendor/extensions/shipping/app/views/shipments/_form.html.erb +0 -46
- data/vendor/extensions/shipping/app/views/shipments/edit.html.erb +0 -57
- data/vendor/extensions/shipping/app/views/shipments/new.html.erb +0 -10
@@ -26,14 +26,19 @@ class ProductsController < Spree::BaseController
|
|
26
26
|
def collection
|
27
27
|
if params[:taxon]
|
28
28
|
@taxon = Taxon.find(params[:taxon])
|
29
|
-
|
30
|
-
@
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
:include => :images)
|
29
|
+
|
30
|
+
@search = Product.active.scoped(:conditions =>
|
31
|
+
["products.id in (select product_id from products_taxons where taxon_id in (" +
|
32
|
+
@taxon.descendents.inject( @taxon.id.to_s) { |clause, t| clause += ', ' + t.id.to_s} + "))"
|
33
|
+
]).new_search(params[:search])
|
35
34
|
else
|
36
|
-
@
|
35
|
+
@search = Product.active.new_search(params[:search])
|
37
36
|
end
|
37
|
+
|
38
|
+
@search.per_page = Spree::Config[:products_per_page]
|
39
|
+
@search.include = :images
|
40
|
+
|
41
|
+
@product_cols = 3
|
42
|
+
@products ||= @search.all
|
38
43
|
end
|
39
44
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Spree::BaseController < ApplicationController
|
2
2
|
|
3
|
-
filter_parameter_logging
|
3
|
+
filter_parameter_logging :password, :creditcard_number, :creditcard_verification_value
|
4
4
|
|
5
5
|
# retrieve the order_id from the session and then load from the database (or return a new order if no
|
6
6
|
# such id exists in the session)
|
@@ -1,10 +1,22 @@
|
|
1
1
|
class StatesController < Spree::BaseController
|
2
2
|
resource_controller
|
3
|
+
|
4
|
+
ssl_allowed :index
|
3
5
|
|
4
6
|
index.response do |wants|
|
5
7
|
wants.html
|
6
8
|
wants.js do
|
7
|
-
@states = end_of_association_chain.find(:all, :conditions => ['lower(name) LIKE ?', "%#{params[:q].downcase}%"], :order => :name)
|
9
|
+
# @states = end_of_association_chain.find(:all, :conditions => ['lower(name) LIKE ?', "%#{params[:q].downcase}%"], :order => :name)
|
10
|
+
|
11
|
+
# table of {country.id => { state.id => state.name }}
|
12
|
+
# blank added elsewhere, if needed
|
13
|
+
usa = {}
|
14
|
+
State.find(:all, :conditions => "country_id = 214",
|
15
|
+
:select => "id, name"
|
16
|
+
).each do |s|
|
17
|
+
usa[s.name] = s.id
|
18
|
+
end
|
19
|
+
@state_info = { "214" => usa } # to be generalised...
|
8
20
|
end
|
9
21
|
end
|
10
|
-
end
|
22
|
+
end
|
@@ -12,12 +12,16 @@ class TaxonsController < Spree::BaseController
|
|
12
12
|
|
13
13
|
private
|
14
14
|
def load_data
|
15
|
-
@
|
15
|
+
@search = object.products.active.new_search(params[:search])
|
16
|
+
@search.per_page = Spree::Config[:products_per_page]
|
17
|
+
@search.include = :images
|
18
|
+
|
16
19
|
@product_cols = 3
|
20
|
+
@products ||= @search.all
|
17
21
|
end
|
18
22
|
|
19
23
|
def object
|
20
|
-
|
24
|
+
@object ||= end_of_association_chain.find_by_permalink(params[:id].join("/") + "/")
|
21
25
|
end
|
22
26
|
|
23
27
|
end
|
@@ -9,13 +9,16 @@ class UsersController < Spree::BaseController
|
|
9
9
|
show.before do
|
10
10
|
@orders = Order.checkout_completed(true).find_all_by_user_id(current_user.id)
|
11
11
|
end
|
12
|
-
|
13
|
-
create
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
create.response do |wants|
|
12
|
+
|
13
|
+
create do
|
14
|
+
flash nil
|
18
15
|
wants.html { redirect_back_or_default(products_path) }
|
19
16
|
end
|
20
17
|
|
18
|
+
create.after do
|
19
|
+
@user.roles << Role.find_by_name("user")
|
20
|
+
@user.save
|
21
|
+
self.current_user = @user
|
22
|
+
end
|
23
|
+
|
21
24
|
end
|
@@ -30,15 +30,5 @@ module ApplicationHelper
|
|
30
30
|
def flag_image(code)
|
31
31
|
"#{code.to_s.split("-").last.downcase}.png"
|
32
32
|
end
|
33
|
-
|
34
|
-
# Takes a filter and converts it into a hash of name/value pairs that can be used in query string
|
35
|
-
def generate_search_options(filter)
|
36
|
-
options = {}
|
37
|
-
filter.attributes.each do |key, value|
|
38
|
-
filter_key = "filter[#{key.to_s}]"
|
39
|
-
options[filter_key] = value
|
40
|
-
end
|
41
|
-
options
|
42
|
-
end
|
43
|
-
|
33
|
+
|
44
34
|
end
|
@@ -22,7 +22,9 @@ module ProductsHelper
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
def format_price(price)
|
25
|
+
def format_price(price)
|
26
|
+
# Don't be fooled - default implementation uses number_to_currency but other extensions may patch into this. It is
|
27
|
+
# suggested that you leave your format_price calls alone.
|
26
28
|
number_to_currency(price)
|
27
29
|
end
|
28
30
|
|
@@ -4,33 +4,7 @@ module Spree::BaseHelper
|
|
4
4
|
return new_order_url if session[:order_id].blank?
|
5
5
|
return edit_order_url(Order.find_or_create_by_id(session[:order_id]))
|
6
6
|
end
|
7
|
-
|
8
|
-
def windowed_pagination_links(pagingEnum, options)
|
9
|
-
link_to_current_page = options[:link_to_current_page]
|
10
|
-
always_show_anchors = options[:always_show_anchors]
|
11
|
-
padding = options[:window_size]
|
12
|
-
|
13
|
-
current_page = pagingEnum.page
|
14
|
-
html = ''
|
15
|
-
|
16
|
-
#Calculate the window start and end pages
|
17
|
-
padding = padding < 0 ? 0 : padding
|
18
|
-
first = pagingEnum.page_exists?(current_page - padding) ? current_page - padding : 1
|
19
|
-
last = pagingEnum.page_exists?(current_page + padding) ? current_page + padding : pagingEnum.last_page
|
20
|
-
|
21
|
-
# Print start page if anchors are enabled
|
22
|
-
html << yield(1) if always_show_anchors and not first == 1
|
23
7
|
|
24
|
-
# Print window pages
|
25
|
-
first.upto(last) do |page|
|
26
|
-
(current_page == page && !link_to_current_page) ? html << page : html << yield(page)
|
27
|
-
end
|
28
|
-
|
29
|
-
# Print end page if anchors are enabled
|
30
|
-
html << yield(pagingEnum.last_page) if always_show_anchors and not last == pagingEnum.last_page
|
31
|
-
html
|
32
|
-
end
|
33
|
-
|
34
8
|
def add_product_link(text, product)
|
35
9
|
link_to_remote text, {:url => {:controller => "cart",
|
36
10
|
:action => "add", :id => product}},
|
data/app/models/address.rb
CHANGED
@@ -12,12 +12,12 @@ class Address < ActiveRecord::Base
|
|
12
12
|
validates_presence_of :zipcode
|
13
13
|
validates_presence_of :country
|
14
14
|
validates_presence_of :phone
|
15
|
-
|
15
|
+
|
16
16
|
def full_name
|
17
17
|
self.firstname + " " + self.lastname
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
def state_text
|
21
|
-
state.nil? ? state_name : (state.abbr
|
21
|
+
state.nil? ? state_name : (state.abbr.blank? ? state.name : state.abbr)
|
22
22
|
end
|
23
23
|
end
|
@@ -31,6 +31,7 @@ class AppConfiguration < Configuration
|
|
31
31
|
preference :admin_interface_logo, :string, :default => "spree/spree.jpg"
|
32
32
|
preference :allow_ssl_in_production, :boolean, :default => true
|
33
33
|
preference :allow_ssl_in_development_and_test, :boolean, :default => false
|
34
|
+
preference :google_analytics_id, :string, :default => '12312312' # Replace with real Google Analytics Id
|
34
35
|
|
35
36
|
validates_presence_of :name
|
36
37
|
validates_uniqueness_of :name
|
data/app/models/country.rb
CHANGED
data/app/models/creditcard.rb
CHANGED
@@ -66,7 +66,12 @@ class Creditcard < ActiveRecord::Base
|
|
66
66
|
def last_digits
|
67
67
|
self.class.last_digits(number)
|
68
68
|
end
|
69
|
-
|
69
|
+
|
70
|
+
# needed for some of the ActiveMerchant gateways (eg. Protx)
|
71
|
+
def brand
|
72
|
+
cc_type
|
73
|
+
end
|
74
|
+
|
70
75
|
def validate
|
71
76
|
validate_essential_attributes
|
72
77
|
validate_card_type
|
@@ -7,7 +7,7 @@ class CreditcardPayment < Payment
|
|
7
7
|
def find_authorization
|
8
8
|
#find the transaction associated with the original authorization/capture
|
9
9
|
txns.find(:first,
|
10
|
-
:conditions => ["txn_type = ?", CreditcardTxn::TxnType::AUTHORIZE],
|
10
|
+
:conditions => ["txn_type = ? AND response_code IS NOT NULL", CreditcardTxn::TxnType::AUTHORIZE],
|
11
11
|
:order => 'created_at DESC')
|
12
12
|
end
|
13
13
|
|
@@ -9,6 +9,9 @@ class InventoryUnit < ActiveRecord::Base
|
|
9
9
|
event :sell do
|
10
10
|
transition :to => 'sold', :from => 'on_hand'
|
11
11
|
end
|
12
|
+
event :fill_backorder do
|
13
|
+
transition :to => 'sold', :from => 'backordered'
|
14
|
+
end
|
12
15
|
event :ship do
|
13
16
|
transition :to => 'shipped', :if => :allow_ship? #, :from => 'sold'
|
14
17
|
end
|
@@ -61,7 +64,7 @@ class InventoryUnit < ActiveRecord::Base
|
|
61
64
|
|
62
65
|
private
|
63
66
|
def allow_ship?
|
64
|
-
state == '
|
67
|
+
state == 'ready_to_ship' || Spree::Config[:allow_backorder_shipping]
|
65
68
|
end
|
66
69
|
|
67
70
|
end
|
data/app/models/order.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class Order < ActiveRecord::Base
|
2
|
-
before_create :generate_order_number
|
2
|
+
# before_create :generate_order_number
|
3
3
|
before_save :update_line_items
|
4
4
|
|
5
5
|
has_many :line_items, :dependent => :destroy, :attributes => true do
|
@@ -7,13 +7,13 @@ class Order < ActiveRecord::Base
|
|
7
7
|
find :first, :conditions => ['variant_id = ?', variant.id]
|
8
8
|
end
|
9
9
|
end
|
10
|
-
has_many :products, :through => :line_items
|
11
10
|
has_many :inventory_units
|
12
11
|
has_many :state_events
|
13
12
|
has_many :payments
|
14
13
|
has_many :creditcard_payments
|
15
14
|
has_many :creditcards
|
16
15
|
belongs_to :user
|
16
|
+
has_many :shipments, :dependent => :destroy
|
17
17
|
|
18
18
|
validates_associated :line_items, :message => "are not valid"
|
19
19
|
validates_numericality_of :tax_amount
|
@@ -31,6 +31,13 @@ class Order < ActiveRecord::Base
|
|
31
31
|
# attr_accessible is a nightmare with attachment_fu, so use attr_protected instead.
|
32
32
|
attr_protected :ship_amount, :tax_amount, :item_total, :total, :user, :number, :ip_address, :checkout_complete, :state
|
33
33
|
|
34
|
+
def to_param
|
35
|
+
self.number if self.number
|
36
|
+
generate_order_number unless self.number
|
37
|
+
self.number.parameterize.to_s.upcase
|
38
|
+
end
|
39
|
+
make_permalink :field => :number
|
40
|
+
|
34
41
|
# order state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
|
35
42
|
state_machine :initial => 'in_progress' do
|
36
43
|
after_transition :to => 'in_progress', :do => lambda {|order| order.update_attribute(:checkout_complete, false)}
|
@@ -38,15 +45,9 @@ class Order < ActiveRecord::Base
|
|
38
45
|
after_transition :to => 'canceled', :do => :cancel_order
|
39
46
|
after_transition :to => 'returned', :do => :restock_inventory
|
40
47
|
after_transition :to => 'resumed', :do => :restore_state
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
event :next do
|
45
|
-
transition :to => 'creditcard', :from => 'in_progress'
|
46
|
-
transition :to => 'new', :from => 'creditcard'
|
47
|
-
end
|
48
|
-
event :edit do
|
49
|
-
transition :to => 'in_progress', :from => %w{creditcard in_progress}
|
48
|
+
|
49
|
+
event :complete do
|
50
|
+
transition :to => 'new', :from => 'in_progress'
|
50
51
|
end
|
51
52
|
event :cancel do
|
52
53
|
transition :to => 'canceled', :if => :allow_cancel?
|
@@ -60,11 +61,9 @@ class Order < ActiveRecord::Base
|
|
60
61
|
event :pay do
|
61
62
|
transition :to => 'paid', :if => :allow_pay?
|
62
63
|
end
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
# normally these types of transitions are recorded by controller
|
67
|
-
state_events.create(:name => I18n.t(:pay), :previous_state => state)
|
64
|
+
event :ship do
|
65
|
+
transition :to => 'shipped', :from => 'paid'
|
66
|
+
end
|
68
67
|
end
|
69
68
|
|
70
69
|
def restore_state
|
@@ -74,7 +73,7 @@ class Order < ActiveRecord::Base
|
|
74
73
|
end
|
75
74
|
|
76
75
|
def allow_cancel?
|
77
|
-
self.
|
76
|
+
self.state != 'canceled'
|
78
77
|
end
|
79
78
|
|
80
79
|
def allow_resume?
|
@@ -112,12 +111,12 @@ class Order < ActiveRecord::Base
|
|
112
111
|
end
|
113
112
|
end
|
114
113
|
|
115
|
-
def generate_order_number
|
114
|
+
def generate_order_number
|
116
115
|
record = true
|
117
116
|
while record
|
118
|
-
random = Array.new(9){rand(9)}.join
|
117
|
+
random = "R#{Array.new(9){rand(9)}.join}"
|
119
118
|
record = Order.find(:first, :conditions => ["number = ?", random])
|
120
|
-
end
|
119
|
+
end
|
121
120
|
self.number = random
|
122
121
|
end
|
123
122
|
|
@@ -142,6 +141,18 @@ class Order < ActiveRecord::Base
|
|
142
141
|
return nil if creditcards.empty?
|
143
142
|
return creditcards.last.address
|
144
143
|
end
|
144
|
+
|
145
|
+
# convenience method since many stores will not allow user to create multiple shipments
|
146
|
+
def shipment
|
147
|
+
shipments.last
|
148
|
+
end
|
149
|
+
|
150
|
+
def ship_address
|
151
|
+
return nil if shipments.empty?
|
152
|
+
return shipment.address
|
153
|
+
end
|
154
|
+
|
155
|
+
include Spree::ShippingCalculator
|
145
156
|
|
146
157
|
private
|
147
158
|
def complete_order
|
@@ -149,7 +160,12 @@ class Order < ActiveRecord::Base
|
|
149
160
|
InventoryUnit.sell_units(self)
|
150
161
|
if user && user.email
|
151
162
|
OrderMailer.deliver_confirm(self)
|
152
|
-
end
|
163
|
+
end
|
164
|
+
# finalize order totals
|
165
|
+
calculator = shipment.shipping_method.shipping_calculator.constantize.new
|
166
|
+
self.ship_amount = calculator.calculate_shipping(shipment)
|
167
|
+
self.tax_amount = calculate_tax
|
168
|
+
save
|
153
169
|
end
|
154
170
|
|
155
171
|
def cancel_order
|
data/app/models/product.rb
CHANGED
@@ -15,19 +15,22 @@ class Product < ActiveRecord::Base
|
|
15
15
|
validates_presence_of :name
|
16
16
|
validates_presence_of :master_price
|
17
17
|
validates_presence_of :description
|
18
|
-
|
19
|
-
make_permalink
|
18
|
+
|
19
|
+
make_permalink
|
20
20
|
|
21
21
|
alias :options :product_option_types
|
22
22
|
|
23
23
|
# default product scope only lists available and non-deleted products
|
24
24
|
named_scope :active, lambda { |*args| { :conditions => ["products.available_on <= ? and products.deleted_at is null", (args.first || Time.zone.now)] } }
|
25
|
+
named_scope :not_deleted, lambda { |*args| { :conditions => ["products.deleted_at is null", (args.first || Time.zone.now)] } }
|
25
26
|
|
26
27
|
named_scope :available, lambda { |*args| { :conditions => ["products.available_on <= ?", (args.first || Time.zone.now)] } }
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
|
29
|
+
def to_param
|
30
|
+
return permalink unless permalink.blank?
|
31
|
+
name.parameterize.to_s
|
32
|
+
end
|
33
|
+
|
31
34
|
# checks is there are any meaningful variants (ie. variants with at least one option value)
|
32
35
|
def variants?
|
33
36
|
self.variants.each do |v|
|
@@ -65,16 +68,24 @@ class Product < ActiveRecord::Base
|
|
65
68
|
def has_stock?
|
66
69
|
variants.inject(false){ |tf, v| tf ||= v.in_stock }
|
67
70
|
end
|
68
|
-
|
71
|
+
|
69
72
|
private
|
70
73
|
|
71
|
-
def adjust_inventory
|
74
|
+
def adjust_inventory
|
72
75
|
return if self.new_record?
|
73
76
|
return unless @quantity && @quantity.is_integer?
|
74
77
|
new_level = @quantity.to_i
|
75
78
|
# don't allow negative on_hand inventory
|
76
79
|
return if new_level < 0
|
77
80
|
variant.save
|
81
|
+
variant.inventory_units.with_state("backordered").each{|iu|
|
82
|
+
if new_level > 0
|
83
|
+
iu.fill_backorder
|
84
|
+
new_level = new_level - 1
|
85
|
+
end
|
86
|
+
break if new_level < 1
|
87
|
+
}
|
88
|
+
|
78
89
|
adjustment = new_level - on_hand
|
79
90
|
if adjustment > 0
|
80
91
|
InventoryUnit.create_on_hand(variant, adjustment)
|
@@ -1,17 +1,28 @@
|
|
1
|
-
class Shipment < ActiveRecord::Base
|
2
|
-
|
1
|
+
class Shipment < ActiveRecord::Base
|
2
|
+
include ActionView::Helpers::NumberHelper # Needed for JS usable rate information
|
3
|
+
|
3
4
|
belongs_to :order
|
4
5
|
belongs_to :shipping_method
|
6
|
+
has_one :address, :as => :addressable, :dependent => :destroy
|
5
7
|
|
8
|
+
before_create :generate_shipment_number
|
9
|
+
after_save :recalculate_tax
|
6
10
|
after_save :transition_order
|
7
|
-
has_one :address, :as => :addressable, :dependent => :destroy
|
8
11
|
|
9
12
|
def shipped?
|
10
13
|
self.shipped_at
|
11
14
|
end
|
12
15
|
|
13
16
|
def shipping_methods
|
14
|
-
ShippingMethod.all.select { |method| method.zone.include?(address) }
|
17
|
+
ShippingMethod.all.select { |method| method.zone.include?(address) && method.available?(order) }
|
18
|
+
end
|
19
|
+
|
20
|
+
def rates
|
21
|
+
quotes = []
|
22
|
+
shipping_methods.each do |method|
|
23
|
+
quotes << {:id => method.id, :name => method.name, :rate => number_to_currency(method.calculate_shipping(self)) }
|
24
|
+
end
|
25
|
+
quotes
|
15
26
|
end
|
16
27
|
|
17
28
|
private
|
@@ -32,4 +43,9 @@ class Shipment < ActiveRecord::Base
|
|
32
43
|
# transition order to shipped if all shipments have been shipped
|
33
44
|
order.ship!
|
34
45
|
end
|
46
|
+
|
47
|
+
def recalculate_tax
|
48
|
+
return unless order && order.respond_to?(:calculate_tax)
|
49
|
+
order.update_attribute("tax_amount", order.calculate_tax)
|
50
|
+
end
|
35
51
|
end
|