spree_core 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. data/app/assets/images/noimage/large.png +0 -0
  2. data/app/assets/javascripts/admin/admin.js.erb +14 -14
  3. data/app/assets/javascripts/admin/checkouts/edit.js +1 -1
  4. data/app/assets/javascripts/admin/spree_core.js +0 -2
  5. data/app/assets/javascripts/store/checkout.js +2 -2
  6. data/app/assets/stylesheets/store/screen.css.scss +1 -1
  7. data/app/controllers/spree/admin/images_controller.rb +5 -13
  8. data/app/controllers/spree/admin/mail_methods_controller.rb +7 -0
  9. data/app/controllers/spree/admin/orders/customer_details_controller.rb +1 -1
  10. data/app/controllers/spree/admin/payment_methods_controller.rb +7 -1
  11. data/app/controllers/spree/admin/products_controller.rb +5 -13
  12. data/app/controllers/spree/admin/prototypes_controller.rb +2 -2
  13. data/app/controllers/spree/checkout_controller.rb +10 -0
  14. data/app/controllers/spree/orders_controller.rb +9 -5
  15. data/app/helpers/spree/base_helper.rb +17 -4
  16. data/app/helpers/spree/checkout_helper.rb +1 -9
  17. data/app/helpers/spree/products_helper.rb +0 -4
  18. data/app/models/spree/address.rb +1 -1
  19. data/app/models/spree/app_configuration.rb +1 -0
  20. data/app/models/spree/calculator/price_sack.rb +5 -3
  21. data/app/models/spree/image.rb +3 -1
  22. data/app/models/spree/inventory_unit.rb +8 -6
  23. data/app/models/spree/line_item.rb +2 -1
  24. data/app/models/spree/order.rb +23 -2
  25. data/app/models/spree/payment/processing.rb +22 -20
  26. data/app/models/spree/preferences/preferable_class_methods.rb +2 -0
  27. data/app/models/spree/preferences/store.rb +20 -2
  28. data/app/models/spree/product.rb +35 -29
  29. data/app/models/spree/product/scopes.rb +21 -6
  30. data/app/models/spree/return_authorization.rb +1 -0
  31. data/app/models/spree/shipping_method.rb +3 -0
  32. data/app/models/spree/variant.rb +19 -9
  33. data/app/views/spree/admin/images/_form.html.erb +4 -8
  34. data/app/views/spree/admin/return_authorizations/_form.html.erb +17 -33
  35. data/app/views/spree/admin/shared/_head.html.erb +2 -15
  36. data/app/views/spree/admin/shared/_order_details.html.erb +1 -1
  37. data/app/views/spree/admin/shared/_routes.html.erb +8 -0
  38. data/app/views/spree/admin/shared/_translations.html.erb +17 -0
  39. data/app/views/spree/admin/tax_rates/index.html.erb +2 -2
  40. data/app/views/spree/admin/variants/_form.html.erb +2 -2
  41. data/app/views/spree/checkout/payment/_gateway.html.erb +1 -1
  42. data/app/views/spree/order_mailer/cancel_email.text.erb +5 -5
  43. data/app/views/spree/order_mailer/confirm_email.text.erb +7 -6
  44. data/app/views/spree/products/_thumbnails.html.erb +1 -1
  45. data/app/views/spree/shared/_google_analytics.html.erb +17 -16
  46. data/app/views/spree/shared/_head.html.erb +0 -3
  47. data/app/views/spree/shared/_order_details.html.erb +2 -3
  48. data/app/views/spree/shipment_mailer/shipped_email.text.erb +7 -7
  49. data/config/initializers/check_for_orphaned_preferences.rb +1 -1
  50. data/config/initializers/rails_5868.rb +8 -0
  51. data/config/locales/en.yml +17 -0
  52. data/config/routes.rb +7 -0
  53. data/db/migrate/20121017010007_remove_not_null_constraint_from_products_on_hand.rb +11 -0
  54. data/lib/generators/spree/dummy/dummy_generator.rb +1 -1
  55. data/lib/generators/spree/dummy/templates/rails/database.yml +1 -1
  56. data/lib/generators/spree/install/templates/app/assets/javascripts/admin/all.js +2 -0
  57. data/lib/spree/core/mail_settings.rb +2 -1
  58. data/lib/spree/core/search/base.rb +5 -2
  59. data/lib/spree/core/testing_support/factories/tax_category_factory.rb +5 -2
  60. data/lib/spree/core/version.rb +1 -1
  61. data/lib/spree/product_filters.rb +1 -1
  62. metadata +41 -42
  63. data/app/helpers/spree/account_helper.rb +0 -4
  64. data/app/helpers/spree/orders_helper.rb +0 -5
  65. data/app/helpers/spree/trackers_helper.rb +0 -4
  66. data/config/initializers/workarounds_for_ruby19.rb +0 -72
  67. data/lib/spree/core/relation_serialization.rb +0 -9
  68. data/lib/spree/core/testing_support/env.rb +0 -2
Binary file
@@ -1,4 +1,4 @@
1
- <%# encoding: utf-8 %>
1
+ //<%#encoding: UTF-8%>
2
2
  //= require_self
3
3
 
4
4
  /**
@@ -61,9 +61,9 @@ format_product_autocomplete = function(item){
61
61
 
62
62
  html += "<div><h4>" + product['name'] + "</h4>";
63
63
  if (product['master']) {
64
- html += "<span><strong><%= ::I18n.t(:sku) %>: </strong>" + product['master']['sku'] + "</span>";
64
+ html += "<span><strong>" + Spree.translations.sku + ":</strong>" + product['master']['sku'] + "</span>";
65
65
  }
66
- html += "<span><strong><%= ::I18n.t(:on_hand) %>: </strong>" + product['count_on_hand'] + "</span></div>";
66
+ html += "<span><strong>" + Spree.translations.on_hand + ":</strong>" + product['count_on_hand'] + "</span></div>";
67
67
  }else{
68
68
  // variant
69
69
  var variant = item.data['variant'];
@@ -82,8 +82,8 @@ format_product_autocomplete = function(item){
82
82
  }).join(", ")
83
83
 
84
84
  html += "<div><h4>" + name + "</h4>";
85
- html += "<span><strong><%= ::I18n.t(:sku) %>: </strong>" + variant['sku'] + "</span>";
86
- html += "<span><strong><%= ::I18n.t(:on_hand) %>: </strong>" + variant['count_on_hand'] + "</span></div>";
85
+ html += "<span><strong>" + Spree.translations.sku + ":</strong>" + variant['sku'] + "</span>";
86
+ html += "<span><strong>" + Spree.translations.on_hand + ":</strong>" + variant['count_on_hand'] + "</span></div>";
87
87
  }
88
88
 
89
89
  return html
@@ -164,9 +164,9 @@ $.fn.product_autocomplete = function(){
164
164
  $.fn.objectPicker = function(url){
165
165
  $(this).tokenInput(url + "&authenticity_token=" + escape(AUTH_TOKEN), {
166
166
  searchDelay : 600,
167
- hintText : Spree.strings.type_to_search,
168
- noResultsText : Spree.strings.no_results,
169
- searchingText : Spree.strings.searching,
167
+ hintText : Spree.translations.type_to_search,
168
+ noResultsText : Spree.translations.no_results,
169
+ searchingText : Spree.translations.searching,
170
170
  prePopulateFromInput : true
171
171
  });
172
172
  };
@@ -181,12 +181,12 @@ $.fn.userPicker = function(){
181
181
 
182
182
  handle_date_picker_fields = function(){
183
183
  $('.datepicker').datepicker({
184
- dateFormat: "<%= ::I18n.t(:format, :scope => 'spree.date_picker', :default => 'yy/mm/dd') %>",
185
- dayNames: <%= ::I18n.t(:day_names, :scope => :date).to_json %>,
186
- dayNamesMin: <%= ::I18n.t(:abbr_day_names, :scope => :date).to_json %>,
187
- monthNames: <%= (::I18n.t(:month_names, :scope => :date).delete_if(&:blank?)).to_json %>,
188
- prevText: '<%= ::I18n.t(:previous) %>',
189
- nextText: '<%= ::I18n.t(:next) %>',
184
+ dateFormat: Spree.translations.date_picker,
185
+ dayNames: Spree.translations.abbr_day_names,
186
+ dayNamesMin: Spree.translations.abbr_day_names,
187
+ monthNames: Spree.translations.month_names,
188
+ prevText: Spree.translations.previous,
189
+ nextText: Spree.translations.next,
190
190
  showOn: "button",
191
191
  buttonImage: "<%= asset_path 'datepicker/cal.gif' %>",
192
192
  buttonImageOnly: true
@@ -80,7 +80,7 @@ $(document).ready(function(){
80
80
  $('#user_id').val(ui.item.data['id']);
81
81
  $('#guest_checkout_true').prop("checked", false);
82
82
  $('#guest_checkout_false').prop("checked", true);
83
- $('#guest_checkout_false').prob("disabled", false);
83
+ $('#guest_checkout_false').prop("disabled", false);
84
84
  return true;
85
85
  }
86
86
  }).data("autocomplete")._renderItem = function(ul, item) {
@@ -1,5 +1,3 @@
1
- //= require jquery
2
- //= require jquery_ujs
3
1
  //= require jquery-ui
4
2
  //= require jquery.cookie
5
3
  //= require jquery.tokeninput
@@ -16,7 +16,7 @@
16
16
  state_input = $('p#' + region + 'state input');
17
17
 
18
18
  if(states) {
19
- selected = state_select.val();
19
+ selected = parseInt(state_select.val());
20
20
  state_select.html('');
21
21
  states_with_blank = [["",""]].concat(states);
22
22
  $.each(states_with_blank, function(pos,id_nm) {
@@ -72,7 +72,7 @@
72
72
  })(jQuery);
73
73
 
74
74
  function disableSaveOnClick() {
75
- $('form.edit_spree_order').submit(function() {
75
+ $('form.edit_order').submit(function() {
76
76
  $(this).find(':submit, :image').attr('disabled', true).removeClass('primary').addClass('disabled');
77
77
  });
78
78
  }
@@ -1,4 +1,4 @@
1
- @import "store/variables";
1
+ @import "./variables.css.scss";
2
2
 
3
3
  /*--------------------------------------*/
4
4
  /* Basic styles
@@ -19,30 +19,22 @@ module Spree
19
19
 
20
20
 
21
21
  private
22
-
22
+
23
23
  def location_after_save
24
24
  admin_product_images_url(@product)
25
25
  end
26
26
 
27
27
  def load_data
28
- @product = Product.find_by_permalink(params[:product_id])
28
+ @product = Product.where(:permalink => params[:product_id]).first
29
29
  @variants = @product.variants.collect do |variant|
30
30
  [variant.options_text, variant.id]
31
31
  end
32
- @variants.insert(0, [I18n.t(:all), 'All'])
32
+ @variants.insert(0, [I18n.t(:all), @product.master.id])
33
33
  end
34
34
 
35
35
  def set_viewable
36
- if params[:image].has_key? :viewable_id
37
- if params[:image][:viewable_id] == 'All'
38
- @image.viewable = @product.master
39
- else
40
- @image.viewable_type = 'Spree::Variant'
41
- @image.viewable_id = params[:image][:viewable_id]
42
- end
43
- else
44
- @image.viewable = @product.master
45
- end
36
+ @image.viewable_type = 'Spree::Variant'
37
+ @image.viewable_id = params[:image][:viewable_id]
46
38
  end
47
39
 
48
40
  def destroy_before
@@ -3,6 +3,13 @@ module Spree
3
3
  class MailMethodsController < ResourceController
4
4
  after_filter :initialize_mail_settings
5
5
 
6
+ def update
7
+ if params[:mail_method][:preferred_smtp_password].blank?
8
+ params[:mail_method].delete(:preferred_smtp_password)
9
+ end
10
+ super
11
+ end
12
+
6
13
  def testmail
7
14
  @mail_method = Spree::MailMethod.find(params[:id])
8
15
  if TestMailer.test_email(@mail_method, respond_to?(:current_user) ? current_user : nil).deliver
@@ -10,7 +10,7 @@ module Spree
10
10
  end
11
11
 
12
12
  def edit
13
- country_id = Address.default.country
13
+ country_id = Address.default.country.id
14
14
  @order.build_bill_address(:country_id => country_id) if @order.bill_address.nil?
15
15
  @order.build_ship_address(:country_id => country_id) if @order.ship_address.nil?
16
16
  end
@@ -27,7 +27,13 @@ module Spree
27
27
  end
28
28
 
29
29
  payment_method_params = params[ActiveModel::Naming.param_key(@payment_method)] || {}
30
- if @payment_method.update_attributes(params[:payment_method].merge(payment_method_params))
30
+ attributes = params[:payment_method].merge(payment_method_params)
31
+ attributes.each do |k,v|
32
+ if k.include?("password") && attributes[k].blank?
33
+ attributes.delete(k)
34
+ end
35
+ end
36
+ if @payment_method.update_attributes(attributes)
31
37
  invoke_callbacks(:update, :after)
32
38
  flash.notice = I18n.t(:successfully_updated, :resource => I18n.t(:payment_method))
33
39
  respond_with(@payment_method, :location => edit_admin_payment_method_path(@payment_method))
@@ -19,13 +19,9 @@ module Spree
19
19
  end
20
20
  end
21
21
 
22
- # override the destory method to set deleted_at value
23
- # instead of actually deleting the product.
24
22
  def destroy
25
- @product = Product.find_by_permalink!(params[:id])
26
- @product.update_column(:deleted_at, Time.now)
27
-
28
- @product.variants_including_master.update_all(:deleted_at => Time.now)
23
+ @product = Product.where(:permalink => params[:id]).first!
24
+ @product.delete
29
25
 
30
26
  flash.notice = I18n.t('notice_messages.product_deleted')
31
27
 
@@ -90,13 +86,9 @@ module Spree
90
86
  includes([:master, {:variants => [:images, :option_values]}]).
91
87
  page(params[:page]).
92
88
  per(Spree::Config[:admin_products_per_page])
93
-
94
- if params[:q][:s].include?("master_price")
95
- # By applying the group in the main query we get an undefined method gsub for Arel::Nodes::Descending
96
- # It seems to only work when the price is actually being sorted in the query
97
- # To be investigated later.
98
- @collection = @collection.group("spree_variants.price")
99
- end
89
+ if params[:q][:s].include?("master_price")
90
+ @collection = @collection.group("spree_variants.price")
91
+ end
100
92
  else
101
93
  includes = [{:variants => [:images, {:option_values => :option_type}]}, {:master => :images}]
102
94
 
@@ -29,8 +29,8 @@ module Spree
29
29
  private
30
30
 
31
31
  def set_habtm_associations
32
- @prototype.property_ids = params[:property][:id] if params[:property]
33
- @prototype.option_type_ids = params[:option_type][:id] if params[:option_type]
32
+ @prototype.property_ids = params[:option_type].blank? ? [] : params[:property][:id]
33
+ @prototype.option_type_ids = params[:option_type].blank? ? [] : params[:option_type][:id]
34
34
  end
35
35
  end
36
36
  end
@@ -6,6 +6,8 @@ module Spree
6
6
  ssl_required
7
7
 
8
8
  before_filter :load_order
9
+ before_filter :ensure_valid_state
10
+
9
11
  rescue_from Spree::Core::GatewayError, :with => :rescue_from_spree_gateway_error
10
12
 
11
13
  respond_to :html
@@ -36,6 +38,14 @@ module Spree
36
38
  end
37
39
 
38
40
  private
41
+ def ensure_valid_state
42
+ if params[:state] && params[:state] != 'cart' &&
43
+ !@order.checkout_steps.include?(params[:state])
44
+ @order.state = 'cart'
45
+ redirect_to checkout_path
46
+ end
47
+ end
48
+
39
49
  # Provides a route to redirect after order completion
40
50
  def completion_route
41
51
  order_path(@order)
@@ -1,5 +1,7 @@
1
1
  module Spree
2
2
  class OrdersController < BaseController
3
+ ssl_required :show
4
+
3
5
  rescue_from ActiveRecord::RecordNotFound, :with => :render_404
4
6
  helper 'spree/products'
5
7
 
@@ -13,7 +15,7 @@ module Spree
13
15
  def update
14
16
  @order = current_order
15
17
  if @order.update_attributes(params[:order])
16
- @order.line_items = @order.line_items.select {|li| li.quantity > 0 }
18
+ @order.line_items = @order.line_items.select { |li| li.quantity > 0 }
17
19
  fire_event('spree.order.contents_changed')
18
20
  respond_with(@order) { |format| format.html { redirect_to cart_path } }
19
21
  else
@@ -57,14 +59,16 @@ module Spree
57
59
 
58
60
  def empty
59
61
  if @order = current_order
60
- @order.line_items.destroy_all
62
+ @order.empty!
61
63
  end
62
64
 
63
65
  redirect_to spree.cart_path
64
66
  end
65
67
 
66
- def accurate_titles
67
- @order && @order.completed? ? "#{Order.model_name.human} #{@order.number}" : t(:shopping_cart)
68
- end
68
+ private
69
+
70
+ def accurate_title
71
+ @order && @order.completed? ? "#{Order.model_name.human} #{@order.number}" : t(:shopping_cart)
72
+ end
69
73
  end
70
74
  end
@@ -65,13 +65,22 @@ module Spree
65
65
 
66
66
  def meta_data_tags
67
67
  object = instance_variable_get('@'+controller_name.singularize)
68
- meta = { :keywords => Spree::Config[:default_meta_keywords], :description => Spree::Config[:default_meta_description] }
68
+ meta = {}
69
69
 
70
- if object.kind_of?(ActiveRecord::Base)
70
+ if object.kind_of? ActiveRecord::Base
71
71
  meta[:keywords] = object.meta_keywords if object[:meta_keywords].present?
72
72
  meta[:description] = object.meta_description if object[:meta_description].present?
73
73
  end
74
74
 
75
+ if meta[:description].blank? && object.kind_of?(Spree::Product)
76
+ meta[:description] = strip_tags(object.description)
77
+ end
78
+
79
+ meta.reverse_merge!({
80
+ :keywords => Spree::Config[:default_meta_keywords],
81
+ :description => Spree::Config[:default_meta_description]
82
+ })
83
+
75
84
  meta.map do |name, content|
76
85
  tag('meta', :name => name, :content => content)
77
86
  end.join("\n")
@@ -86,9 +95,13 @@ module Spree
86
95
  link_to image_tag(image_path), root_path
87
96
  end
88
97
 
89
- def flash_messages
98
+ def flash_messages(opts = {})
99
+ opts[:ignore_types] = [:commerce_tracking].concat(opts[:ignore_types] || [])
100
+
90
101
  flash.each do |msg_type, text|
91
- concat(content_tag :div, text, :class => "flash #{msg_type}") unless msg_type == :commerce_tracking
102
+ unless opts[:ignore_types].include?(msg_type)
103
+ concat(content_tag :div, text, :class => "flash #{msg_type}")
104
+ end
92
105
  end
93
106
  nil
94
107
  end
@@ -1,15 +1,7 @@
1
1
  module Spree
2
2
  module CheckoutHelper
3
- def checkout_states
4
- if @order.payment and @order.payment.payment_method.payment_profiles_supported?
5
- %w(address delivery payment confirm complete)
6
- else
7
- %w(address delivery payment complete)
8
- end
9
- end
10
-
11
3
  def checkout_progress
12
- states = checkout_states
4
+ states = @order.checkout_steps
13
5
  items = states.map do |state|
14
6
  text = t("order_state.#{state}").titleize
15
7
 
@@ -17,10 +17,6 @@ module Spree
17
17
  raw(product.description.gsub(/(.*?)\r?\n\r?\n/m, '<p>\1</p>'))
18
18
  end
19
19
 
20
- def variant_images_hash(product)
21
- product.variant_images.inject({}) { |h, img| (h[img.viewable_id] ||= []) << img; h }
22
- end
23
-
24
20
  def line_item_description(variant)
25
21
  description = variant.product.description
26
22
  if description.present?
@@ -36,7 +36,7 @@ module Spree
36
36
  end
37
37
 
38
38
  def state_text
39
- state.nil? ? state_name : (state.abbr.blank? ? state.name : state.abbr)
39
+ state.try(:abbr) || state.try(:name) || state_name
40
40
  end
41
41
 
42
42
  def zone
@@ -77,6 +77,7 @@ module Spree
77
77
  preference :s3_headers, :string, :default => "{\"Cache-Control\":\"max-age=31557600\"}"
78
78
  preference :use_s3, :boolean, :default => false # Use S3 for images rather than the file system
79
79
  preference :s3_protocol, :string
80
+ preference :s3_host_alias, :string
80
81
 
81
82
  # searcher_class allows spree extension writers to provide their own Search class
82
83
  def searcher_class
@@ -1,4 +1,6 @@
1
1
  require_dependency 'spree/calculator'
2
+ # For #to_d method on Ruby 1.8
3
+ require 'bigdecimal/util'
2
4
 
3
5
  module Spree
4
6
  class Calculator::PriceSack < Calculator
@@ -17,12 +19,12 @@ module Spree
17
19
  # as object we always get line items, as calculable we have Coupon, ShippingMethod
18
20
  def compute(object)
19
21
  if object.is_a?(Array)
20
- base = object.map { |o| o.respond_to?(:amount) ? o.amount : o.to_d }.sum
22
+ base = object.map { |o| o.respond_to?(:amount) ? o.amount : BigDecimal(o.to_s) }.sum
21
23
  else
22
- base = object.respond_to?(:amount) ? object.amount : object.to_d
24
+ base = object.respond_to?(:amount) ? object.amount : BigDecimal(object.to_s)
23
25
  end
24
26
 
25
- if base >= self.preferred_minimal_amount
27
+ if base < self.preferred_minimal_amount
26
28
  self.preferred_normal_amount
27
29
  else
28
30
  self.preferred_discount_amount
@@ -9,7 +9,8 @@ module Spree
9
9
  :styles => { :mini => '48x48>', :small => '100x100>', :product => '240x240>', :large => '600x600>' },
10
10
  :default_style => :product,
11
11
  :url => '/spree/products/:id/:style/:basename.:extension',
12
- :path => ':rails_root/public/spree/products/:id/:style/:basename.:extension'
12
+ :path => ':rails_root/public/spree/products/:id/:style/:basename.:extension',
13
+ :convert_options => { :all => '-strip' }
13
14
  # save the w,h of the original image (from which others can be calculated)
14
15
  # we need to look at the write-queue for images which have not been saved yet
15
16
  after_post_process :find_dimensions
@@ -22,6 +23,7 @@ module Spree
22
23
  Spree::Image.attachment_definitions[:attachment][:s3_headers] = ActiveSupport::JSON.decode(Spree::Config[:s3_headers])
23
24
  Spree::Image.attachment_definitions[:attachment][:bucket] = Spree::Config[:s3_bucket]
24
25
  Spree::Image.attachment_definitions[:attachment][:s3_protocol] = Spree::Config[:s3_protocol] unless Spree::Config[:s3_protocol].blank?
26
+ Spree::Image.attachment_definitions[:attachment][:s3_host_alias] = Spree::Config[:s3_host_alias] unless Spree::Config[:s3_host_alias].blank?
25
27
  end
26
28
 
27
29
  Spree::Image.attachment_definitions[:attachment][:styles] = ActiveSupport::JSON.decode(Spree::Config[:attachment_styles])
@@ -1,9 +1,9 @@
1
1
  module Spree
2
2
  class InventoryUnit < ActiveRecord::Base
3
- belongs_to :variant, :class_name => "Spree::Variant"
4
- belongs_to :order, :class_name => "Spree::Order"
5
- belongs_to :shipment, :class_name => "Spree::Shipment"
6
- belongs_to :return_authorization, :class_name => "Spree::ReturnAuthorization"
3
+ belongs_to :variant
4
+ belongs_to :order
5
+ belongs_to :shipment
6
+ belongs_to :return_authorization
7
7
 
8
8
  scope :backorder, where(:state => 'backordered')
9
9
 
@@ -107,8 +107,10 @@ module Spree
107
107
  end
108
108
 
109
109
  def restock_variant
110
- variant.on_hand = (variant.on_hand + 1)
111
- variant.save
110
+ if Spree::Config[:track_inventory_levels]
111
+ variant.on_hand += 1
112
+ variant.save
113
+ end
112
114
  end
113
115
  end
114
116
  end