spree_core 1.3.3 → 1.3.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 (80) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/admin/admin.js.erb +9 -5
  3. data/app/assets/javascripts/store/product.js.coffee +6 -1
  4. data/app/assets/stylesheets/store/screen.css.scss +1 -1
  5. data/app/controllers/spree/admin/images_controller.rb +4 -0
  6. data/app/controllers/spree/admin/resource_controller.rb +6 -2
  7. data/app/controllers/spree/orders_controller.rb +1 -1
  8. data/app/helpers/spree/admin/navigation_helper.rb +3 -1
  9. data/app/models/spree/classification.rb +3 -0
  10. data/app/models/spree/credit_card.rb +13 -0
  11. data/app/models/spree/order.rb +20 -11
  12. data/app/models/spree/payment.rb +1 -1
  13. data/app/models/spree/payment/processing.rb +5 -0
  14. data/app/models/spree/product.rb +1 -1
  15. data/app/models/spree/product/scopes.rb +5 -8
  16. data/app/views/spree/admin/adjustments/index.html.erb +2 -2
  17. data/app/views/spree/admin/payments/_form.html.erb +3 -1
  18. data/app/views/spree/checkout/edit.html.erb +4 -0
  19. data/app/views/spree/orders/_line_item.html.erb +5 -3
  20. data/config/initializers/user_class_extensions.rb +1 -1
  21. data/config/locales/en.yml +6 -0
  22. data/config/routes.rb +1 -1
  23. data/db/migrate/20130626232741_add_cvv_result_code_and_cvv_result_message_to_spree_payments.rb +6 -0
  24. data/db/migrate/20130628021056_add_unique_index_to_permalink_on_spree_products.rb +5 -0
  25. data/db/migrate/20130628022817_add_unique_index_to_orders_shipments_and_stock_transfers.rb +6 -0
  26. data/db/migrate/20130813140619_expand_order_number_size.rb +9 -0
  27. data/lib/generators/spree/dummy/templates/rails/database.yml +0 -3
  28. data/lib/spree/core/permalinks.rb +17 -13
  29. data/lib/spree/core/s3_support.rb +1 -1
  30. data/lib/spree/core/testing_support/factories/variant_factory.rb +1 -1
  31. data/lib/spree/core/version.rb +1 -1
  32. data/vendor/assets/javascripts/jquery.validate/additional-methods.min.js +6 -22
  33. data/vendor/assets/javascripts/jquery.validate/jquery.validate.min.js +6 -45
  34. data/vendor/assets/javascripts/jquery.validate/localization/messages_ar.js +23 -22
  35. data/vendor/assets/javascripts/jquery.validate/localization/messages_bg.js +22 -20
  36. data/vendor/assets/javascripts/jquery.validate/localization/messages_ca.js +22 -20
  37. data/vendor/assets/javascripts/jquery.validate/localization/messages_cs.js +22 -20
  38. data/vendor/assets/javascripts/jquery.validate/localization/messages_da.js +19 -17
  39. data/vendor/assets/javascripts/jquery.validate/localization/messages_de.js +19 -18
  40. data/vendor/assets/javascripts/jquery.validate/localization/messages_el.js +22 -21
  41. data/vendor/assets/javascripts/jquery.validate/localization/messages_es.js +22 -20
  42. data/vendor/assets/javascripts/jquery.validate/localization/messages_et.js +23 -0
  43. data/vendor/assets/javascripts/jquery.validate/localization/messages_eu.js +25 -0
  44. data/vendor/assets/javascripts/jquery.validate/localization/messages_fa.js +22 -20
  45. data/vendor/assets/javascripts/jquery.validate/localization/messages_fi.js +20 -18
  46. data/vendor/assets/javascripts/jquery.validate/localization/messages_fr.js +44 -20
  47. data/vendor/assets/javascripts/jquery.validate/localization/messages_he.js +22 -20
  48. data/vendor/assets/javascripts/jquery.validate/localization/messages_hr.js +25 -0
  49. data/vendor/assets/javascripts/jquery.validate/localization/messages_hu.js +21 -18
  50. data/vendor/assets/javascripts/jquery.validate/localization/messages_it.js +22 -20
  51. data/vendor/assets/javascripts/jquery.validate/localization/messages_ja.js +22 -20
  52. data/vendor/assets/javascripts/jquery.validate/localization/messages_ka.js +25 -0
  53. data/vendor/assets/javascripts/jquery.validate/localization/messages_kk.js +22 -20
  54. data/vendor/assets/javascripts/jquery.validate/localization/messages_ko.js +25 -0
  55. data/vendor/assets/javascripts/jquery.validate/localization/messages_lt.js +23 -21
  56. data/vendor/assets/javascripts/jquery.validate/localization/messages_lv.js +22 -20
  57. data/vendor/assets/javascripts/jquery.validate/localization/messages_my.js +25 -0
  58. data/vendor/assets/javascripts/jquery.validate/localization/messages_nl.js +32 -20
  59. data/vendor/assets/javascripts/jquery.validate/localization/messages_no.js +22 -20
  60. data/vendor/assets/javascripts/jquery.validate/localization/messages_pl.js +22 -20
  61. data/vendor/assets/javascripts/jquery.validate/localization/messages_pt_BR.js +26 -0
  62. data/vendor/assets/javascripts/jquery.validate/localization/messages_pt_PT.js +26 -0
  63. data/vendor/assets/javascripts/jquery.validate/localization/messages_ro.js +22 -20
  64. data/vendor/assets/javascripts/jquery.validate/localization/messages_ru.js +22 -20
  65. data/vendor/assets/javascripts/jquery.validate/localization/messages_si.js +21 -19
  66. data/vendor/assets/javascripts/jquery.validate/localization/messages_sk.js +19 -18
  67. data/vendor/assets/javascripts/jquery.validate/localization/messages_sl.js +25 -0
  68. data/vendor/assets/javascripts/jquery.validate/localization/messages_sr.js +23 -21
  69. data/vendor/assets/javascripts/jquery.validate/localization/messages_sv.js +23 -0
  70. data/vendor/assets/javascripts/jquery.validate/localization/messages_th.js +22 -20
  71. data/vendor/assets/javascripts/jquery.validate/localization/messages_tr.js +22 -21
  72. data/vendor/assets/javascripts/jquery.validate/localization/messages_uk.js +25 -0
  73. data/vendor/assets/javascripts/jquery.validate/localization/messages_vi.js +22 -20
  74. data/vendor/assets/javascripts/jquery.validate/localization/messages_zh.js +25 -0
  75. data/vendor/assets/javascripts/jquery.validate/localization/messages_zh_TW.js +26 -0
  76. data/vendor/assets/javascripts/jquery.validate/localization/methods_de.js +6 -6
  77. data/vendor/assets/javascripts/jquery.validate/localization/methods_nl.js +3 -3
  78. data/vendor/assets/javascripts/jquery.validate/localization/methods_pt.js +3 -3
  79. metadata +30 -14
  80. data/app/views/spree/orders/new.html.erb +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7dcd25bc09eef1fdc85269018277aa954848fb6f
4
- data.tar.gz: 6c09d32829e4e87e894c38ce1b14b6b307a97f53
3
+ metadata.gz: 8c5bf35a8b95692aa7ff0d8680f50c4c09fca20c
4
+ data.tar.gz: bb49344e459351d49fd48e2f611efb632c91df74
5
5
  SHA512:
6
- metadata.gz: 4c3732fd647f46c1089fb737409226e8abc5bc0c255523f33815a8d1908fdd6f188d4cadb2bb8914db22b3bac65ea60aa8714aec919cbed2a8f475318cd9b536
7
- data.tar.gz: d09f9087d47758599d36bed4852863a7dd8aadbe6dfa11ce5c279cfd654da291a976c535d0f0b159c0325c9279d6fcca7e44db755c1f70b8a195004d125a7873
6
+ metadata.gz: 0cc6f3c95ba0dce27047501a44aa7434479df796de8e30349d929e24bc1566729d915d53cf5e6c7503c157829784b2070f2e37929009d497f75aeb892b3d2ba7
7
+ data.tar.gz: 357cfcbbe86573ef29d1611cd3260957cb5650827724626b5348d2ef38ea356b30746c317ef4f94b59d448dbfb758b2832c60f3ed5a22e4f29d8d1af45360cae
@@ -157,11 +157,11 @@ $(document).ready(function(){
157
157
  var target = $(this).data("target");
158
158
  var new_table_row = $(target + ' tr:visible:last').clone();
159
159
  var new_id = new Date().getTime();
160
- new_table_row.find("input").each(function () {
160
+ new_table_row.find("input, select").each(function () {
161
161
  var el = $(this);
162
162
  el.val("");
163
- el.attr("id", el.attr("id").replace(/\d+/, new_id))
164
- el.attr("name", el.attr("name").replace(/\d+/, new_id))
163
+ if (typeof el.attr("id") !== 'undefined') el.attr("id", el.attr("id").replace(/\d+/, new_id))
164
+ if (typeof el.attr("name") !== 'undefined') el.attr("name", el.attr("name").replace(/\d+/, new_id))
165
165
  })
166
166
  // When cloning a new row, set the href of all icons to be an empty "#"
167
167
  // This is so that clicking on them does not perform the actions for the
@@ -185,7 +185,9 @@ $(document).ready(function(){
185
185
  },
186
186
  dataType: 'script',
187
187
  success: function(response) {
188
- el.parents("tr").fadeOut('hide');
188
+ el.parents("tr").fadeOut('hide', function() {
189
+ $(this).remove();
190
+ })
189
191
  },
190
192
  error: function(response, textStatus, errorThrown) {
191
193
  show_flash_error(response.responseText);
@@ -199,7 +201,9 @@ $(document).ready(function(){
199
201
  el = $(this);
200
202
  el.prev("input[type=hidden]").val("1");
201
203
  el.closest(".fields").hide();
202
- if (el.attr("href")) {
204
+ if (el.attr("href") == '#') {
205
+ el.parents("tr").fadeOut('hide');
206
+ }else if (el.attr("href")) {
203
207
  $.ajax({
204
208
  type: 'POST',
205
209
  url: el.attr("href"),
@@ -35,8 +35,13 @@ update_variant_price = (variant) ->
35
35
  ($ '.price.selling').text(variant_price) if variant_price
36
36
 
37
37
  $ ->
38
+ radios = ($ '#product-variants input[type="radio"]')
38
39
  add_image_handlers()
39
- show_variant_images ($ '#product-variants input[type="radio"]').eq(0).attr('value') if ($ '#product-variants input[type="radio"]').length > 0
40
+
41
+ if radios.length > 0
42
+ show_variant_images radios.eq(0).attr('value')
43
+ update_variant_price radios.first()
44
+
40
45
  ($ '#product-variants input[type="radio"]').click (event) ->
41
46
  show_variant_images @value
42
47
  update_variant_price ($ this)
@@ -300,7 +300,7 @@ mark {background-color: $link_text_color; color: $layout_background_color; font-
300
300
  &#link-to-cart {
301
301
  float: right;
302
302
  padding-left: 24px;
303
- background: url("cart.png") no-repeat left center;
303
+ background: asset-url("cart.png", image) no-repeat left center;
304
304
 
305
305
  &:hover {
306
306
  border-color: $link_text_color;
@@ -9,6 +9,10 @@ module Spree
9
9
 
10
10
  private
11
11
 
12
+ def location_after_destroy
13
+ admin_product_images_url(@product)
14
+ end
15
+
12
16
  def location_after_save
13
17
  admin_product_images_url(@product)
14
18
  end
@@ -70,13 +70,13 @@ class Spree::Admin::ResourceController < Spree::Admin::BaseController
70
70
  invoke_callbacks(:destroy, :after)
71
71
  flash[:success] = flash_message_for(@object, :successfully_removed)
72
72
  respond_with(@object) do |format|
73
- format.html { redirect_to collection_url }
73
+ format.html { redirect_to location_after_destroy }
74
74
  format.js { render :partial => "spree/admin/shared/destroy" }
75
75
  end
76
76
  else
77
77
  invoke_callbacks(:destroy, :fails)
78
78
  respond_with(@object) do |format|
79
- format.html { redirect_to collection_url }
79
+ format.html { redirect_to location_after_destroy }
80
80
  end
81
81
  end
82
82
  end
@@ -198,6 +198,10 @@ class Spree::Admin::ResourceController < Spree::Admin::BaseController
198
198
  end
199
199
  end
200
200
 
201
+ def location_after_destroy
202
+ collection_url
203
+ end
204
+
201
205
  def location_after_save
202
206
  collection_url
203
207
  end
@@ -26,7 +26,7 @@ module Spree
26
26
  respond_with(@order) do |format|
27
27
  format.html do
28
28
  if params.has_key?(:checkout)
29
- @order.next_transition.run_callbacks
29
+ @order.next_transition.run_callbacks if @order.cart?
30
30
  redirect_to checkout_state_path(@order.checkout_steps.first)
31
31
  else
32
32
  redirect_to cart_path
@@ -143,7 +143,9 @@ module Spree
143
143
  end
144
144
 
145
145
  def configurations_sidebar_menu_item(link_text, url, options = {})
146
- is_active = url.ends_with?(controller.controller_name) || url.ends_with?( "#{controller.controller_name}/edit")
146
+ is_active = url.ends_with?(controller.controller_name) ||
147
+ url.ends_with?("#{controller.controller_name}/edit") ||
148
+ url.ends_with?("#{controller.controller_name.singularize}/edit")
147
149
  options.merge!(:class => is_active ? 'active' : nil)
148
150
  content_tag(:li, options) do
149
151
  link_to(link_text, url)
@@ -3,5 +3,8 @@ module Spree
3
3
  self.table_name = 'spree_products_taxons'
4
4
  belongs_to :product, :class_name => "Spree::Product"
5
5
  belongs_to :taxon, :class_name => "Spree::Taxon"
6
+
7
+ # For #3494
8
+ validates_uniqueness_of :taxon_id, :scope => :product_id, :message => :already_linked
6
9
  end
7
10
  end
@@ -28,6 +28,19 @@ module Spree
28
28
  end
29
29
  end
30
30
 
31
+ # Some payment gateways, such as USA EPay, only support an ActiveMerchant::Billing::CreditCard
32
+ # object, rather than an object *like* that. So we need to convert it.
33
+ def to_active_merchant
34
+ ActiveMerchant::Billing::CreditCard.new(
35
+ :number => number,
36
+ :month => month,
37
+ :year => year,
38
+ :verification_value => verification_value,
39
+ :first_name => first_name,
40
+ :last_name => last_name
41
+ )
42
+ end
43
+
31
44
  # sets self.cc_type while we still have the card number
32
45
  def set_card_type
33
46
  self.cc_type ||= CardDetector.brand?(number)
@@ -17,7 +17,8 @@ module Spree
17
17
  go_to_state :delivery
18
18
  go_to_state :payment, :if => lambda { |order|
19
19
  # Fix for #2191
20
- if order.shipping_method
20
+ # See #3708 also
21
+ if order.total.to_f <= 0 && order.shipping_method
21
22
  order.create_shipment!
22
23
  order.update_totals
23
24
  end
@@ -168,8 +169,13 @@ module Spree
168
169
  end
169
170
 
170
171
  # Used by the checkout state machine to check for unprocessed payments
171
- # The Order should be unable to proceed to complete if there are unprocessed
172
+ # The Order should be only be able to proceed to complete if there are unprocessed
172
173
  # payments and there is payment required.
174
+ #
175
+ # The reason for this is directly before an order transitions to complete, all
176
+ # of the order's payments have `process!` called on it (look in order/checkout.rb).
177
+ # If payment *is* required and there's no payments which haven't already been tried,
178
+ # then the order cannot be paid for and therefore should not be able to become complete.
173
179
  def has_unprocessed_payments?
174
180
  payments.with_state('checkout').reload.exists?
175
181
  end
@@ -340,7 +346,7 @@ module Spree
340
346
  def create_shipment!
341
347
  shipping_method(true)
342
348
  if shipment.present?
343
- shipment.update_attributes!(:shipping_method => shipping_method)
349
+ shipment.update_attributes!({:shipping_method => shipping_method, :inventory_units => self.inventory_units}, :without_protection => true)
344
350
  else
345
351
  self.shipments << Shipment.create!({ :order => self,
346
352
  :shipping_method => shipping_method,
@@ -383,7 +389,7 @@ module Spree
383
389
 
384
390
  # update payment and shipment(s) states, and save
385
391
  updater.update_payment_state
386
- shipments.each { |shipment| shipment.update!(self) }
392
+ shipments.reload.each { |shipment| shipment.update!(self) }
387
393
  updater.update_shipment_state
388
394
  save
389
395
  updater.run_hooks
@@ -491,8 +497,8 @@ module Spree
491
497
  end
492
498
 
493
499
  def empty!
494
- line_items.destroy_all
495
500
  adjustments.destroy_all
501
+ line_items.destroy_all
496
502
  end
497
503
 
498
504
  # destroy any previous adjustments.
@@ -510,12 +516,15 @@ module Spree
510
516
  state = "#{name}_state"
511
517
  if persisted?
512
518
  old_state = self.send("#{state}_was")
513
- self.state_changes.create({
514
- :previous_state => old_state,
515
- :next_state => self.send(state),
516
- :name => name,
517
- :user_id => self.user_id
518
- }, :without_protection => true)
519
+ new_state = self.send(state)
520
+ if old_state != new_state
521
+ self.state_changes.create({
522
+ :previous_state => old_state,
523
+ :next_state => self.send(state),
524
+ :name => name,
525
+ :user_id => self.user_id
526
+ }, :without_protection => true)
527
+ end
519
528
  end
520
529
  end
521
530
 
@@ -8,7 +8,7 @@ module Spree
8
8
  has_many :offsets, :class_name => "Spree::Payment", :foreign_key => :source_id, :conditions => "source_type = 'Spree::Payment' AND amount < 0 AND state = 'completed'"
9
9
  has_many :log_entries, :as => :source
10
10
 
11
- before_save :set_unique_identifier
11
+ before_create :set_unique_identifier
12
12
 
13
13
  after_save :create_payment_profile, :if => :profiles_supported?
14
14
 
@@ -155,6 +155,11 @@ module Spree
155
155
  unless response.authorization.nil?
156
156
  self.response_code = response.authorization
157
157
  self.avs_response = response.avs_result['code']
158
+
159
+ if response.cvv_result
160
+ self.cvv_response_code = response.cvv_result['code']
161
+ self.cvv_response_message = response.cvv_result['message']
162
+ end
158
163
  end
159
164
  self.send("#{success_state}!")
160
165
  else
@@ -290,7 +290,7 @@ module Spree
290
290
  # there's a weird quirk with the delegate stuff that does not automatically save the delegate object
291
291
  # when saving so we force a save using a hook.
292
292
  def save_master
293
- master.save if master && (master.changed? || master.new_record? || (master.default_price && (master.default_price.changed || master.default_price.new_record)))
293
+ master.save if master && (master.changed? || master.new_record? || (master.default_price && (master.default_price.changed? || master.default_price.new_record?)))
294
294
  end
295
295
 
296
296
  def ensure_master
@@ -68,14 +68,11 @@ module Spree
68
68
  #
69
69
  # SELECT COUNT(*) ...
70
70
  add_search_scope :in_taxon do |taxon|
71
- if ActiveRecord::Base.connection.adapter_name == "PostgreSQL"
72
- scope = select("DISTINCT ON (spree_products.id) spree_products.*")
73
- else
74
- scope = select("DISTINCT(spree_products.id), spree_products.*")
75
- end
76
-
77
- scope.joins(:taxons).
78
- where(Taxon.table_name => { :id => taxon.self_and_descendants.map(&:id) })
71
+ select("spree_products.id, spree_products.*").
72
+ where(id: Classification.select('spree_products_taxons.product_id').
73
+ joins(:taxon).
74
+ where(Taxon.table_name => { :id => taxon.self_and_descendants.pluck(:id) })
75
+ )
79
76
  end
80
77
 
81
78
  # This scope selects products in all taxons AND all its descendants
@@ -4,11 +4,11 @@
4
4
  <i class="icon-arrow-right"></i> <%= t(:adjustments) %>
5
5
  <% end %>
6
6
 
7
- <% content_for :page_actions do %>
7
+ <% content_for :page_actions do %>
8
8
  <li><%= button_link_to t(:new_adjustment), new_admin_order_adjustment_url(@order), :icon => 'icon-plus' %></li>
9
9
  <li><%= button_link_to t(:back_to_orders_list), admin_orders_path, :icon => 'icon-arrow-left' %></li>
10
10
  <% end %>
11
11
 
12
12
  <%= render :partial => 'adjustments_table' %>
13
13
 
14
- <%= button_link_to t(:continue), @order.cart? ? new_admin_order_payment_url(@order) : admin_orders_url, :icon => 'icon-arrow-right' %>
14
+ <%= button_link_to t(:continue), @order.payment? ? new_admin_order_payment_url(@order) : admin_orders_url, :icon => 'icon-arrow-right' %>
@@ -20,7 +20,9 @@
20
20
  </ul>
21
21
  <div class="payment-method-settings">
22
22
  <% @payment_methods.each do |method| %>
23
- <%= render :partial => "spree/admin/payments/source_forms/#{method.method_type}", :locals => { :payment_method => method } %>
23
+ <% if method.source_required? %>
24
+ <%= render :partial => "spree/admin/payments/source_forms/#{method.method_type}", :locals => { :payment_method => method } %>
25
+ <% end %>
24
26
  <% end %>
25
27
  </div>
26
28
  </div>
@@ -31,3 +31,7 @@
31
31
  </div>
32
32
 
33
33
  </div>
34
+
35
+ <% if I18n.locale != :en %>
36
+ <script src='/assets/jquery.validate/localization/messages_<%= I18n.locale %>.js'></script>
37
+ <% end %>
@@ -11,10 +11,12 @@
11
11
  <%= variant.options_text %>
12
12
  <% if @order.insufficient_stock_lines.include? line_item %>
13
13
  <span class="out-of-stock">
14
- <%= variant.in_stock? ? t(:insufficient_stock, :on_hand => variant.on_hand) : t(:out_of_stock) %>&nbsp;&nbsp;<br />
15
- </span>
14
+ <%= variant.in_stock? ? t(:insufficient_stock, :on_hand => variant.on_hand) : t(:out_of_stock) %>
15
+ </span><br />
16
16
  <% end %>
17
- <%= line_item_description(variant) %>
17
+ <span class="line-item-description" data-hook="line_item_description">
18
+ <%= line_item_description(variant) %>
19
+ </span>
18
20
  </td>
19
21
  <td class="cart-item-price" data-hook="cart_item_price">
20
22
  <%= line_item.single_money.to_html %>
@@ -18,7 +18,7 @@ Spree::Core::Engine.config.to_prepare do
18
18
  end
19
19
 
20
20
  def last_incomplete_spree_order
21
- spree_orders.incomplete.order('created_at DESC').last
21
+ spree_orders.incomplete.order('created_at DESC').first
22
22
  end
23
23
  end
24
24
  end
@@ -209,6 +209,12 @@ en:
209
209
  spree/zone:
210
210
  one: Zone
211
211
  other: Zones
212
+ errors:
213
+ models:
214
+ spree/classification:
215
+ attributes:
216
+ taxon_id:
217
+ already_linked: "is already linked to this product"
212
218
  add: Add
213
219
  add_category: "Add Category"
214
220
  add_country: "Add Country"
@@ -22,7 +22,7 @@ Spree::Core::Engine.routes.draw do
22
22
  get '/orders/populate', :via => :get, :to => populate_redirect
23
23
  match '/orders/:id/token/:token' => 'orders#show', :via => :get, :as => :token_order
24
24
 
25
- resources :orders do
25
+ resources :orders, :except => [:new, :create] do
26
26
  post :populate, :on => :collection
27
27
  end
28
28
 
@@ -0,0 +1,6 @@
1
+ class AddCvvResultCodeAndCvvResultMessageToSpreePayments < ActiveRecord::Migration
2
+ def change
3
+ add_column :spree_payments, :cvv_response_code, :string
4
+ add_column :spree_payments, :cvv_response_message, :string
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ class AddUniqueIndexToPermalinkOnSpreeProducts < ActiveRecord::Migration
2
+ def change
3
+ add_index "spree_products", ["permalink"], :name => "permalink_idx_unique", :unique => true
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class AddUniqueIndexToOrdersShipmentsAndStockTransfers < ActiveRecord::Migration
2
+ def add
3
+ add_index "spree_orders", ["number"], :name => "number_idx_unique", :unique => true
4
+ add_index "spree_shipments", ["number"], :name => "number_idx_unique", :unique => true
5
+ end
6
+ end
@@ -0,0 +1,9 @@
1
+ class ExpandOrderNumberSize < ActiveRecord::Migration
2
+ def up
3
+ change_column :spree_orders, :number, :string, :limit => 32
4
+ end
5
+
6
+ def down
7
+ change_column :spree_orders, :number, :string, :limit => 15
8
+ end
9
+ end
@@ -16,17 +16,14 @@ production:
16
16
  development:
17
17
  adapter: mysql2
18
18
  database: <%= database_prefix %>spree_development
19
- username:
20
19
  encoding: utf8
21
20
  test:
22
21
  adapter: mysql2
23
22
  database: <%= database_prefix %>spree_test
24
- username:
25
23
  encoding: utf8
26
24
  production:
27
25
  adapter: mysql2
28
26
  database: <%= database_prefix %>spree_production
29
- username:
30
27
  encoding: utf8
31
28
  <% when 'postgres' %>
32
29
  development:
@@ -14,9 +14,9 @@ module Spree
14
14
  options[:field] ||= :permalink
15
15
  self.permalink_options = options
16
16
 
17
- validates permalink_options[:field], :uniqueness => true
18
-
19
- before_validation(:on => :create) { save_permalink }
17
+ if self.table_exists? && self.column_names.include?(permalink_options[:field].to_s)
18
+ before_validation(:on => :create) { save_permalink }
19
+ end
20
20
  end
21
21
 
22
22
  def find_by_param(value, *args)
@@ -38,16 +38,20 @@ module Spree
38
38
  end
39
39
 
40
40
  def save_permalink(permalink_value=self.to_param)
41
- field = self.class.permalink_field
42
- # Do other links exist with this permalink?
43
- other = self.class.where("#{self.class.table_name}.#{field} LIKE ?", "#{permalink_value}%")
44
- if other.any?
45
- # Find the existing permalink with the highest number, and increment that number.
46
- # (If none of the existing permalinks have a number, this will evaluate to 1.)
47
- number = other.map { |o| o.send(field)[/-(\d+)$/, 1].to_i }.max + 1
48
- permalink_value += "-#{number.to_s}"
49
- end
50
- write_attribute(field, permalink_value)
41
+ self.with_lock do
42
+ permalink_value ||= generate_permalink
43
+
44
+ field = self.class.permalink_field
45
+ # Do other links exist with this permalink?
46
+ other = self.class.select(field).where("#{self.class.table_name}.#{field} LIKE ?", "#{permalink_value}%")
47
+ if other.any?
48
+ # Find the existing permalink with the highest number, and increment that number.
49
+ # (If none of the existing permalinks have a number, this will evaluate to 1.)
50
+ number = other.map { |o| o.send(field)[/-(\d+)$/, 1].to_i }.max + 1
51
+ permalink_value += "-#{number.to_s}"
52
+ end
53
+ write_attribute(field, permalink_value)
54
+ end
51
55
  end
52
56
  end
53
57
  end