spree_core 1.1.0 → 1.1.1
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.
- data/app/assets/javascripts/admin/admin.js.erb +1 -1
- data/app/assets/javascripts/admin/checkouts/edit.js +1 -1
- data/app/assets/javascripts/admin/spree_core.js +3 -0
- data/app/controllers/spree/products_controller.rb +5 -1
- data/app/helpers/spree/base_helper.rb +35 -20
- data/app/models/spree/adjustment.rb +1 -1
- data/app/models/spree/calculator/per_item.rb +7 -1
- data/app/models/spree/gateway.rb +0 -2
- data/app/models/spree/image.rb +1 -1
- data/app/models/spree/inventory_unit.rb +0 -5
- data/app/models/spree/line_item.rb +6 -1
- data/app/models/spree/order.rb +10 -1
- data/app/models/spree/payment/processing.rb +17 -13
- data/app/models/spree/payment_method/check.rb +4 -8
- data/app/models/spree/product.rb +5 -3
- data/app/models/spree/product/scopes.rb +1 -1
- data/app/models/spree/return_authorization.rb +4 -2
- data/app/models/spree/shipment.rb +1 -1
- data/app/models/spree/shipping_method.rb +3 -3
- data/app/models/spree/taxon.rb +2 -1
- data/app/models/spree/variant.rb +35 -0
- data/app/views/spree/admin/shared/_head.html.erb +3 -3
- data/app/views/spree/layouts/admin.html.erb +1 -1
- data/db/migrate/20120507232704_increase_scale_of_tax_rate_amount.rb +9 -0
- data/lib/spree/core/permalinks.rb +6 -17
- data/lib/spree/core/respond_with.rb +1 -1
- data/lib/spree/core/testing_support/factories.rb +1 -2
- data/lib/spree/core/testing_support/factories/adjustment_factory.rb +4 -4
- data/lib/spree/core/testing_support/factories/inventory_unit_factory.rb +4 -4
- data/lib/spree/core/testing_support/factories/order_factory.rb +6 -6
- data/lib/spree/core/testing_support/factories/payment_factory.rb +3 -3
- data/lib/spree/core/testing_support/factories/product_factory.rb +1 -1
- data/lib/spree/core/testing_support/factories/product_option_type_factory.rb +2 -2
- data/lib/spree/core/testing_support/factories/product_property_factory.rb +2 -2
- data/lib/spree/core/testing_support/factories/prototype_factory.rb +1 -1
- data/lib/spree/core/testing_support/factories/return_authorization_factory.rb +2 -2
- data/lib/spree/core/testing_support/factories/shipment_factory.rb +3 -3
- data/lib/spree/core/testing_support/factories/shipping_method_factory.rb +3 -3
- data/lib/spree/core/testing_support/factories/tax_rate_factory.rb +2 -2
- data/lib/spree/core/testing_support/factories/taxon_factory.rb +1 -1
- data/lib/spree/core/testing_support/factories/user_factory.rb +1 -1
- data/lib/spree/core/testing_support/factories/variant_factory.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- metadata +32 -31
@@ -121,7 +121,7 @@ $.fn.product_autocomplete = function(){
|
|
121
121
|
return this.each(function() {
|
122
122
|
$(this).autocomplete({
|
123
123
|
source: function(request, response) {
|
124
|
-
$.get("
|
124
|
+
$.get(ajax_root_prefix() + "admin/products.json?q=" + $('#add_product_name').val() + "&authenticity_token=" + encodeURIComponent($('meta[name=csrf-token]').attr("content")), function(data) {
|
125
125
|
result = prep_product_autocomplete_data(data)
|
126
126
|
response(result);
|
127
127
|
});
|
@@ -46,7 +46,7 @@ $(document).ready(function(){
|
|
46
46
|
minChars: 5,
|
47
47
|
delay: 1500,
|
48
48
|
source: function(request, response) {
|
49
|
-
$.get("
|
49
|
+
$.get(ajax_root_prefix() + "admin/users.json?q=" + $("#customer_search").val() + "&authenticity_token=" + encodeURIComponent($('meta[name=csrf-token]').attr("content")), function(data) {
|
50
50
|
result = prep_user_autocomplete_data(data)
|
51
51
|
response(result);
|
52
52
|
});
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Spree
|
2
2
|
class ProductsController < BaseController
|
3
3
|
HTTP_REFERER_REGEXP = /^https?:\/\/[^\/]+\/t\/([a-z0-9\-\/]+)$/
|
4
|
+
before_filter :load_product, :only => :show
|
4
5
|
rescue_from ActiveRecord::RecordNotFound, :with => :render_404
|
5
6
|
helper 'spree/taxons'
|
6
7
|
|
@@ -13,7 +14,6 @@ module Spree
|
|
13
14
|
end
|
14
15
|
|
15
16
|
def show
|
16
|
-
@product = Product.active.find_by_permalink!(params[:id])
|
17
17
|
return unless @product
|
18
18
|
|
19
19
|
@variants = Variant.active.includes([:option_values, :images]).where(:product_id => @product.id)
|
@@ -32,5 +32,9 @@ module Spree
|
|
32
32
|
def accurate_title
|
33
33
|
@product ? @product.name : super
|
34
34
|
end
|
35
|
+
|
36
|
+
def load_product
|
37
|
+
@product = Product.active.find_by_permalink!(params[:id])
|
38
|
+
end
|
35
39
|
end
|
36
40
|
end
|
@@ -63,24 +63,6 @@ module Spree
|
|
63
63
|
list
|
64
64
|
end
|
65
65
|
|
66
|
-
Spree::Image.attachment_definitions[:attachment][:styles].each do |style, v|
|
67
|
-
# Defines these methods by default:
|
68
|
-
# def mini_image
|
69
|
-
# def small_image
|
70
|
-
# def product_image
|
71
|
-
# def large_image
|
72
|
-
define_method "#{style}_image" do |product, *options|
|
73
|
-
options = options.first || {}
|
74
|
-
if product.images.empty?
|
75
|
-
image_tag "noimage/#{style}.png", options
|
76
|
-
else
|
77
|
-
image = product.images.first
|
78
|
-
options.reverse_merge! :alt => image.alt.blank? ? product.name : image.alt
|
79
|
-
image_tag image.attachment.url(style), options
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
66
|
def meta_data_tags
|
85
67
|
object = instance_variable_get('@'+controller_name.singularize)
|
86
68
|
meta = { :keywords => Spree::Config[:default_meta_keywords], :description => Spree::Config[:default_meta_description] }
|
@@ -141,9 +123,9 @@ module Spree
|
|
141
123
|
|
142
124
|
def available_countries
|
143
125
|
countries = Zone.find_by_name(Spree::Config[:checkout_zone]).try(:country_list) || Country.all
|
144
|
-
countries.collect do |c|
|
126
|
+
countries.collect do |c|
|
145
127
|
c.name = I18n.t(c.iso, :scope => 'countries', :default => c.name)
|
146
|
-
c
|
128
|
+
c
|
147
129
|
end.sort{ |a,b| a.name <=> b.name }
|
148
130
|
end
|
149
131
|
|
@@ -180,5 +162,38 @@ module Spree
|
|
180
162
|
rescue
|
181
163
|
Gem.available?(name)
|
182
164
|
end
|
165
|
+
|
166
|
+
def method_missing(method_name, *args, &block)
|
167
|
+
if image_style = image_style_from_method_name(method_name)
|
168
|
+
define_image_method(image_style)
|
169
|
+
self.send(method_name, *args)
|
170
|
+
else
|
171
|
+
super
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
private
|
176
|
+
|
177
|
+
# Returns style of image or nil
|
178
|
+
def image_style_from_method_name(method_name)
|
179
|
+
if style = method_name.to_s.sub(/_image$/, '')
|
180
|
+
possible_styles = Spree::Image.attachment_definitions[:attachment][:styles]
|
181
|
+
style if style.in? possible_styles.with_indifferent_access
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def define_image_method(style)
|
186
|
+
self.class.send :define_method, "#{style}_image" do |product, *options|
|
187
|
+
options = options.first || {}
|
188
|
+
if product.images.empty?
|
189
|
+
image_tag "noimage/#{style}.png", options
|
190
|
+
else
|
191
|
+
image = product.images.first
|
192
|
+
options.reverse_merge! :alt => image.alt.blank? ? product.name : image.alt
|
193
|
+
image_tag image.attachment.url(style), options
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
183
198
|
end
|
184
199
|
end
|
@@ -33,7 +33,7 @@ module Spree
|
|
33
33
|
|
34
34
|
scope :tax, lambda { where(:originator_type => 'Spree::TaxRate', :adjustable_type => 'Spree::Order') }
|
35
35
|
scope :price, lambda { where(:adjustable_type => 'Spree::LineItem') }
|
36
|
-
scope :shipping, lambda { where(:
|
36
|
+
scope :shipping, lambda { where(:originator_type => 'Spree::ShippingMethod') }
|
37
37
|
scope :optional, where(:mandatory => false)
|
38
38
|
scope :eligible, where(:eligible => true)
|
39
39
|
scope :charge, where("amount >= 0")
|
@@ -11,8 +11,14 @@ module Spree
|
|
11
11
|
def compute(object=nil)
|
12
12
|
return 0 if object.nil?
|
13
13
|
self.preferred_amount * object.line_items.reduce(0) do |sum, value|
|
14
|
-
|
14
|
+
value_to_add = (target_products().include?(value.product) ? value.quantity : 0)
|
15
|
+
sum + value_to_add
|
15
16
|
end
|
16
17
|
end
|
18
|
+
|
19
|
+
def target_products
|
20
|
+
#TODO: product groups?
|
21
|
+
self.calculable.promotion.rules.map(&:products).flatten
|
22
|
+
end
|
17
23
|
end
|
18
24
|
end
|
data/app/models/spree/gateway.rb
CHANGED
data/app/models/spree/image.rb
CHANGED
@@ -3,7 +3,7 @@ module Spree
|
|
3
3
|
validates_attachment_presence :attachment
|
4
4
|
validate :no_attachment_errors
|
5
5
|
|
6
|
-
attr_accessible :alt, :attachment, :position, :viewable_id
|
6
|
+
attr_accessible :alt, :attachment, :position, :viewable_type, :viewable_id
|
7
7
|
|
8
8
|
has_attached_file :attachment,
|
9
9
|
:styles => { :mini => '48x48>', :small => '100x100>', :product => '240x240>', :large => '600x600>' },
|
@@ -62,11 +62,6 @@ module Spree
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
# find the specified quantity of units with the specified status
|
66
|
-
def self.find_by_status(variant, quantity, status)
|
67
|
-
variant.inventory_units.where(:status => status).limit(quantity)
|
68
|
-
end
|
69
|
-
|
70
65
|
private
|
71
66
|
def allow_ship?
|
72
67
|
Spree::Config[:allow_backorder_shipping] || self.sold?
|
@@ -45,7 +45,12 @@ module Spree
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def sufficient_stock?
|
48
|
-
Spree::Config[:allow_backorders]
|
48
|
+
return true if Spree::Config[:allow_backorders]
|
49
|
+
if new_record? || !order.completed?
|
50
|
+
variant.on_hand >= quantity
|
51
|
+
else
|
52
|
+
variant.on_hand >= (quantity - self.changed_attributes['quantity'].to_i)
|
53
|
+
end
|
49
54
|
end
|
50
55
|
|
51
56
|
def insufficient_stock?
|
data/app/models/spree/order.rb
CHANGED
@@ -374,7 +374,7 @@ module Spree
|
|
374
374
|
InventoryUnit.assign_opening_inventory(self)
|
375
375
|
# lock any optional adjustments (coupon promotions, etc.)
|
376
376
|
adjustments.optional.each { |adjustment| adjustment.update_attribute('locked', true) }
|
377
|
-
|
377
|
+
deliver_order_confirmation_email
|
378
378
|
|
379
379
|
self.state_changes.create({
|
380
380
|
:previous_state => 'cart',
|
@@ -384,6 +384,15 @@ module Spree
|
|
384
384
|
}, :without_protection => true)
|
385
385
|
end
|
386
386
|
|
387
|
+
def deliver_order_confirmation_email
|
388
|
+
begin
|
389
|
+
OrderMailer.confirm_email(self).deliver
|
390
|
+
rescue Exception => e
|
391
|
+
logger.error("#{e.class.name}: #{e.message}")
|
392
|
+
logger.error(e.backtrace * "\n")
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
387
396
|
# Helper methods for checkout steps
|
388
397
|
|
389
398
|
def available_shipping_methods(display_on = nil)
|
@@ -97,6 +97,21 @@ module Spree
|
|
97
97
|
credit!(amount)
|
98
98
|
end
|
99
99
|
|
100
|
+
# This needs to be public so that gateway subclasses can use
|
101
|
+
# this to report errors
|
102
|
+
def gateway_error(error)
|
103
|
+
if error.is_a? ActiveMerchant::Billing::Response
|
104
|
+
text = error.params['message'] || error.params['response_reason_text'] || error.message
|
105
|
+
elsif error.is_a? ActiveMerchant::ConnectionError
|
106
|
+
text = I18n.t(:unable_to_connect_to_gateway)
|
107
|
+
else
|
108
|
+
text = error.to_s
|
109
|
+
end
|
110
|
+
logger.error(I18n.t(:gateway_error))
|
111
|
+
logger.error(" #{error.to_yaml}")
|
112
|
+
raise Core::GatewayError.new(text)
|
113
|
+
end
|
114
|
+
|
100
115
|
private
|
101
116
|
|
102
117
|
def gateway_action(source, action, success_state)
|
@@ -136,6 +151,8 @@ module Spree
|
|
136
151
|
options.merge!({ :shipping => order.ship_total * 100,
|
137
152
|
:tax => order.tax_total * 100,
|
138
153
|
:subtotal => order.item_total * 100 })
|
154
|
+
|
155
|
+
options.merge!({ :currency => payment_method.preferences[:currency_code] }) if payment_method && payment_method.preferences[:currency_code]
|
139
156
|
|
140
157
|
options.merge({ :billing_address => order.bill_address.try(:active_merchant_hash),
|
141
158
|
:shipping_address => order.ship_address.try(:active_merchant_hash) })
|
@@ -153,19 +170,6 @@ module Spree
|
|
153
170
|
log_entries.create({:details => response.to_yaml}, :without_protection => true)
|
154
171
|
end
|
155
172
|
|
156
|
-
def gateway_error(error)
|
157
|
-
if error.is_a? ActiveMerchant::Billing::Response
|
158
|
-
text = error.params['message'] || error.params['response_reason_text'] || error.message
|
159
|
-
elsif error.is_a? ActiveMerchant::ConnectionError
|
160
|
-
text = I18n.t(:unable_to_connect_to_gateway)
|
161
|
-
else
|
162
|
-
text = error.to_s
|
163
|
-
end
|
164
|
-
logger.error(I18n.t(:gateway_error))
|
165
|
-
logger.error(" #{error.to_yaml}")
|
166
|
-
raise Core::GatewayError.new(text)
|
167
|
-
end
|
168
|
-
|
169
173
|
# Saftey check to make sure we're not accidentally performing operations on a live gateway.
|
170
174
|
# Ex. When testing in staging environment with a copy of production data.
|
171
175
|
def check_environment
|
@@ -14,16 +14,12 @@ module Spree
|
|
14
14
|
payment.state != 'void'
|
15
15
|
end
|
16
16
|
|
17
|
-
def capture(
|
18
|
-
|
19
|
-
payment.complete
|
20
|
-
true
|
17
|
+
def capture(*args)
|
18
|
+
ActiveMerchant::Billing::Response.new(true, "", {}, {})
|
21
19
|
end
|
22
20
|
|
23
|
-
def void(
|
24
|
-
|
25
|
-
payment.void
|
26
|
-
true
|
21
|
+
def void(*args)
|
22
|
+
ActiveMerchant::Billing::Response.new(true, "", {}, {})
|
27
23
|
end
|
28
24
|
|
29
25
|
def source_required?
|
data/app/models/spree/product.rb
CHANGED
@@ -29,7 +29,7 @@ module Spree
|
|
29
29
|
|
30
30
|
has_one :master,
|
31
31
|
:class_name => 'Spree::Variant',
|
32
|
-
:conditions => ["#{Variant.quoted_table_name}.is_master = ?
|
32
|
+
:conditions => ["#{Variant.quoted_table_name}.is_master = ?", true]
|
33
33
|
|
34
34
|
delegate_belongs_to :master, :sku, :price, :weight, :height, :width, :depth, :is_master
|
35
35
|
delegate_belongs_to :master, :cost_price if Variant.table_exists? && Variant.column_names.include?('cost_price')
|
@@ -59,7 +59,9 @@ module Spree
|
|
59
59
|
accepts_nested_attributes_for :variants, :allow_destroy => true
|
60
60
|
|
61
61
|
def variant_images
|
62
|
-
Image.
|
62
|
+
Image.joins("LEFT JOIN #{Variant.quoted_table_name} ON #{Variant.quoted_table_name}.id = #{Asset.quoted_table_name}.viewable_id").
|
63
|
+
where("#{Variant.quoted_table_name}.product_id = #{self.id}").
|
64
|
+
order("#{Asset.quoted_table_name}.position")
|
63
65
|
end
|
64
66
|
|
65
67
|
alias_method :images, :variant_images
|
@@ -72,7 +74,7 @@ module Spree
|
|
72
74
|
:meta_keywords, :price, :sku, :deleted_at, :prototype_id,
|
73
75
|
:option_values_hash, :on_hand, :weight, :height, :width, :depth,
|
74
76
|
:shipping_category_id, :tax_category_id, :product_properties_attributes,
|
75
|
-
:variants_attributes
|
77
|
+
:variants_attributes, :taxon_ids
|
76
78
|
|
77
79
|
attr_accessible :cost_price if Variant.table_exists? && Variant.column_names.include?('cost_price')
|
78
80
|
|
@@ -185,7 +185,7 @@ module Spree
|
|
185
185
|
end
|
186
186
|
|
187
187
|
def self.available(available_on = nil)
|
188
|
-
where(
|
188
|
+
where("#{Product.quoted_table_name}.available_on <= ?", available_on || Time.now)
|
189
189
|
end
|
190
190
|
|
191
191
|
#RAILS 3 TODO - this scope doesn't match the original 2.3.x version, needs attention (but it works)
|
@@ -67,8 +67,10 @@ module Spree
|
|
67
67
|
|
68
68
|
def process_return
|
69
69
|
inventory_units.each &:return!
|
70
|
-
credit = Adjustment.
|
71
|
-
|
70
|
+
credit = Adjustment.new(:amount => amount.abs * -1, :label => I18n.t(:rma_credit))
|
71
|
+
credit.source = self
|
72
|
+
credit.adjustable = order
|
73
|
+
credit.save
|
72
74
|
end
|
73
75
|
|
74
76
|
def allow_receive?
|
@@ -15,7 +15,7 @@ module Spree
|
|
15
15
|
attr_accessor :special_instructions
|
16
16
|
|
17
17
|
attr_accessible :order, :state, :shipping_method, :special_instructions,
|
18
|
-
:shipping_method_id, :tracking
|
18
|
+
:shipping_method_id, :tracking, :address, :inventory_units
|
19
19
|
|
20
20
|
accepts_nested_attributes_for :address
|
21
21
|
accepts_nested_attributes_for :inventory_units
|
@@ -3,11 +3,11 @@ module Spree
|
|
3
3
|
DISPLAY = [:both, :front_end, :back_end]
|
4
4
|
belongs_to :zone
|
5
5
|
has_many :shipments
|
6
|
-
validates :name, :
|
6
|
+
validates :name, :zone, :presence => true
|
7
7
|
belongs_to :shipping_category
|
8
8
|
|
9
|
-
attr_accessible :name, :zone_id, :display_on, :shipping_category_id,
|
10
|
-
:match_none, :match_one, :match_all
|
9
|
+
attr_accessible :name, :zone_id, :display_on, :shipping_category_id,
|
10
|
+
:match_none, :match_one, :match_all
|
11
11
|
|
12
12
|
calculated_adjustments
|
13
13
|
|
data/app/models/spree/taxon.rb
CHANGED
@@ -6,9 +6,10 @@ module Spree
|
|
6
6
|
has_and_belongs_to_many :products, :join_table => 'spree_products_taxons'
|
7
7
|
before_create :set_permalink
|
8
8
|
|
9
|
-
attr_accessible :name, :parent_id, :position, :icon, :description, :permalink
|
9
|
+
attr_accessible :name, :parent_id, :position, :icon, :description, :permalink, :taxonomy_id
|
10
10
|
|
11
11
|
validates :name, :presence => true
|
12
|
+
|
12
13
|
has_attached_file :icon,
|
13
14
|
:styles => { :mini => '32x32>', :normal => '128x128>' },
|
14
15
|
:default_style => :mini,
|
data/app/models/spree/variant.rb
CHANGED
@@ -112,6 +112,41 @@ module Spree
|
|
112
112
|
deleted_at
|
113
113
|
end
|
114
114
|
|
115
|
+
def set_option_value(opt_name, opt_value)
|
116
|
+
# no option values on master
|
117
|
+
return if self.is_master
|
118
|
+
|
119
|
+
option_type = Spree::OptionType.find_or_initialize_by_name(opt_name) do |o|
|
120
|
+
o.presentation = opt_name
|
121
|
+
o.save!
|
122
|
+
end
|
123
|
+
|
124
|
+
current_value = self.option_values.detect { |o| o.option_type.name == opt_name }
|
125
|
+
|
126
|
+
unless current_value.nil?
|
127
|
+
return if current_value.name == opt_value
|
128
|
+
self.option_values.delete(current_value)
|
129
|
+
else
|
130
|
+
# then we have to check to make sure that the product has the option type
|
131
|
+
unless self.product.option_types.include? option_type
|
132
|
+
self.product.option_types << option_type
|
133
|
+
self.product.save
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
option_value = Spree::OptionValue.find_or_initialize_by_option_type_id_and_name(option_type.id, opt_value) do |o|
|
138
|
+
o.presentation = opt_value
|
139
|
+
o.save!
|
140
|
+
end
|
141
|
+
|
142
|
+
self.option_values << option_value
|
143
|
+
self.save
|
144
|
+
end
|
145
|
+
|
146
|
+
def option_value(opt_name)
|
147
|
+
self.option_values.detect { |o| o.option_type.name == opt_name }.try(:presentation)
|
148
|
+
end
|
149
|
+
|
115
150
|
private
|
116
151
|
# Ensures a new variant takes the product master price when price is not supplied
|
117
152
|
def check_price
|
@@ -4,9 +4,9 @@
|
|
4
4
|
<%= t(controller.controller_name, :default => controller.controller_name.titleize) %></title>
|
5
5
|
<%= javascript_tag do %>
|
6
6
|
ajax_urls = <%== {
|
7
|
-
:product_search_json => spree.
|
8
|
-
:product_search_basic_json => spree.
|
9
|
-
:user_search_basic_json => spree.
|
7
|
+
:product_search_json => spree.admin_products_path(:format => 'json'),
|
8
|
+
:product_search_basic_json => spree.admin_products_path(:format => 'json', :json_format => 'basic', :limit => 10),
|
9
|
+
:user_search_basic_json => spree.admin_users_path(:format => 'json', :json_format => 'basic', :limit => 10)
|
10
10
|
}.to_json %>;
|
11
11
|
|
12
12
|
strings = <%==
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class IncreaseScaleOfTaxRateAmount < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
change_column :spree_tax_rates, :amount, :decimal, { :scale => 5, :precision => 8 }
|
4
|
+
end
|
5
|
+
|
6
|
+
def down
|
7
|
+
change_column :spree_tax_rates, :amount, :decimal, { :scale => 4, :precision => 8 }
|
8
|
+
end
|
9
|
+
end
|
@@ -46,25 +46,14 @@ module Spree
|
|
46
46
|
def save_permalink
|
47
47
|
permalink_value = self.to_param
|
48
48
|
field = self.class.permalink_field
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
if other
|
56
|
-
# Find existence of that permalink or the number of that permalink and add one.
|
57
|
-
if ( permalink_value == other.send(field) || /-(\d+)$/.match(other.send(field)) )
|
58
|
-
if $1
|
59
|
-
number = $1.to_i + 1
|
60
|
-
# Otherwise default to suffixing it with a 1.
|
61
|
-
else
|
62
|
-
number = 1
|
63
|
-
end
|
64
|
-
|
49
|
+
# Do other links exist with this permalink?
|
50
|
+
other = self.class.all(:conditions => "#{field} LIKE '#{permalink_value}%'")
|
51
|
+
unless other.empty?
|
52
|
+
# Find the existing permalink with the highest number, and increment that number.
|
53
|
+
# (If none of the existing permalinks have a number, this will evaluate to 1.)
|
54
|
+
number = other.map { |o| o.send(field)[/-(\d+)$/, 1].to_i }.max + 1
|
65
55
|
permalink_value += "-#{number.to_s}"
|
66
56
|
end
|
67
|
-
end
|
68
57
|
write_attribute(field, permalink_value)
|
69
58
|
end
|
70
59
|
end
|
@@ -7,7 +7,7 @@ module ActionController
|
|
7
7
|
if collector = retrieve_collector_from_mimes(&block)
|
8
8
|
options = resources.size == 1 ? {} : resources.extract_options!
|
9
9
|
|
10
|
-
if defined_response = collector.response and Spree::BaseController.spree_responders.
|
10
|
+
if defined_response = collector.response and !Spree::BaseController.spree_responders.keys.include?(self.class.to_s.to_sym)
|
11
11
|
if action = options.delete(:action)
|
12
12
|
render :action => action
|
13
13
|
else
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Spree::Zone.class_eval do
|
2
2
|
def self.global
|
3
|
-
find_by_name("GlobalZone") ||
|
3
|
+
find_by_name("GlobalZone") || create(:global_zone)
|
4
4
|
end
|
5
5
|
end
|
6
6
|
|
@@ -9,4 +9,3 @@ require 'factory_girl'
|
|
9
9
|
Dir["#{File.dirname(__FILE__)}/factories/**"].each do |f|
|
10
10
|
require File.expand_path(f)
|
11
11
|
end
|
12
|
-
|
@@ -1,16 +1,16 @@
|
|
1
1
|
FactoryGirl.define do
|
2
2
|
factory :adjustment, :class => Spree::Adjustment do
|
3
|
-
adjustable {
|
3
|
+
adjustable { FactoryGirl.create(:order) }
|
4
4
|
amount '100.0'
|
5
5
|
label 'Shipping'
|
6
|
-
source {
|
6
|
+
source { FactoryGirl.create(:shipment) }
|
7
7
|
eligible true
|
8
8
|
end
|
9
9
|
factory :line_item_adjustment, :class => Spree::Adjustment do
|
10
|
-
adjustable {
|
10
|
+
adjustable { FactoryGirl.create(:line_item) }
|
11
11
|
amount '10.0'
|
12
12
|
label 'VAT 5%'
|
13
|
-
source {
|
13
|
+
source { FactoryGirl.create(:tax_rate) }
|
14
14
|
eligible true
|
15
15
|
end
|
16
16
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
FactoryGirl.define do
|
2
2
|
factory :inventory_unit, :class => Spree::InventoryUnit do
|
3
|
-
variant {
|
4
|
-
order {
|
3
|
+
variant { FactoryGirl.create(:variant) }
|
4
|
+
order { FactoryGirl.create(:order) }
|
5
5
|
state 'sold'
|
6
|
-
shipment {
|
7
|
-
#return_authorization {
|
6
|
+
shipment { FactoryGirl.create(:shipment, :state => 'pending') }
|
7
|
+
#return_authorization { FactoryGirl.create(:return_authorization) }
|
8
8
|
end
|
9
9
|
end
|
@@ -10,21 +10,21 @@ FactoryGirl.define do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
factory :order_with_totals, :parent => :order do
|
13
|
-
after_create { |order|
|
13
|
+
after_create { |order| FactoryGirl.create(:line_item, :order => order) }
|
14
14
|
end
|
15
15
|
|
16
16
|
factory :order_with_inventory_unit_shipped, :parent => :order do
|
17
17
|
after_create do |order|
|
18
|
-
|
19
|
-
|
18
|
+
FactoryGirl.create(:line_item, :order => order)
|
19
|
+
FactoryGirl.create(:inventory_unit, :order => order, :state => 'shipped')
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
23
|
factory :completed_order_with_totals, :parent => :order_with_totals do
|
24
|
-
bill_address {
|
25
|
-
ship_address {
|
24
|
+
bill_address { FactoryGirl.create(:address) }
|
25
|
+
ship_address { FactoryGirl.create(:address) }
|
26
26
|
after_create do |order|
|
27
|
-
|
27
|
+
FactoryGirl.create(:inventory_unit, :order => order, :state => 'shipped')
|
28
28
|
end
|
29
29
|
state 'complete'
|
30
30
|
completed_at Time.now
|
@@ -1,9 +1,9 @@
|
|
1
1
|
FactoryGirl.define do
|
2
2
|
factory :payment, :class => Spree::Payment do
|
3
3
|
amount 45.75
|
4
|
-
payment_method {
|
5
|
-
source {
|
6
|
-
order {
|
4
|
+
payment_method { FactoryGirl.create(:bogus_payment_method) }
|
5
|
+
source { FactoryGirl.build(:creditcard) }
|
6
|
+
order { FactoryGirl.create(:order) }
|
7
7
|
state 'pending'
|
8
8
|
response_code '12345'
|
9
9
|
|
@@ -17,7 +17,7 @@ FactoryGirl.define do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
factory :product_with_option_types, :parent => :product do
|
20
|
-
after_create { |product|
|
20
|
+
after_create { |product| FactoryGirl.create(:product_option_type, :product => product) }
|
21
21
|
end
|
22
22
|
|
23
23
|
factory :custom_product, :class => Spree::Product do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
FactoryGirl.define do
|
2
2
|
factory :product_option_type, :class => Spree::ProductOptionType do
|
3
|
-
product {
|
4
|
-
option_type {
|
3
|
+
product { FactoryGirl.create(:product) }
|
4
|
+
option_type { FactoryGirl.create(:option_type) }
|
5
5
|
end
|
6
6
|
end
|
@@ -2,8 +2,8 @@ FactoryGirl.define do
|
|
2
2
|
factory :return_authorization, :class => Spree::ReturnAuthorization do
|
3
3
|
number '100'
|
4
4
|
amount 100.00
|
5
|
-
#order {
|
6
|
-
order {
|
5
|
+
#order { FactoryGirl.create(:order) }
|
6
|
+
order { FactoryGirl.create(:order_with_inventory_unit_shipped) }
|
7
7
|
reason 'no particular reason'
|
8
8
|
state 'received'
|
9
9
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
FactoryGirl.define do
|
2
2
|
factory :shipment, :class => Spree::Shipment do
|
3
|
-
order {
|
4
|
-
shipping_method {
|
3
|
+
order { FactoryGirl.create(:order) }
|
4
|
+
shipping_method { FactoryGirl.create(:shipping_method) }
|
5
5
|
tracking 'U10000'
|
6
6
|
number '100'
|
7
7
|
cost 100.00
|
8
|
-
address {
|
8
|
+
address { FactoryGirl.create(:address) }
|
9
9
|
state 'pending'
|
10
10
|
end
|
11
11
|
end
|
@@ -2,13 +2,13 @@ FactoryGirl.define do
|
|
2
2
|
factory :shipping_method, :class => Spree::ShippingMethod do
|
3
3
|
zone { |a| Spree::Zone.find_by_name('GlobalZone') || a.association(:global_zone) }
|
4
4
|
name 'UPS Ground'
|
5
|
-
calculator {
|
5
|
+
calculator { FactoryGirl.build(:calculator) }
|
6
6
|
end
|
7
7
|
|
8
8
|
factory :free_shipping_method, :class => Spree::ShippingMethod do
|
9
9
|
zone { |a| Spree::Zone.find_by_name('GlobalZone') || a.association(:global_zone) }
|
10
10
|
name 'UPS Ground'
|
11
|
-
calculator {
|
11
|
+
calculator { FactoryGirl.build(:no_amount_calculator) }
|
12
12
|
end
|
13
13
|
|
14
14
|
factory :shipping_method_with_category, :class => Spree::ShippingMethod do
|
@@ -18,6 +18,6 @@ FactoryGirl.define do
|
|
18
18
|
match_one nil
|
19
19
|
match_all nil
|
20
20
|
association(:shipping_category, :factory => :shipping_category)
|
21
|
-
calculator {
|
21
|
+
calculator { FactoryGirl.build(:calculator) }
|
22
22
|
end
|
23
23
|
end
|
@@ -12,6 +12,6 @@ FactoryGirl.define do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
factory :admin_user, :parent => :user do
|
15
|
-
roles { [Spree::Role.find_by_name('admin') ||
|
15
|
+
roles { [Spree::Role.find_by_name('admin') || FactoryGirl.create(:role, :name => 'admin')]}
|
16
16
|
end
|
17
17
|
end
|
data/lib/spree/core/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spree_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-05-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: acts_as_list
|
16
|
-
requirement: &
|
16
|
+
requirement: &70318236789620 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - =
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: 0.1.4
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70318236789620
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: nested_set
|
27
|
-
requirement: &
|
27
|
+
requirement: &70318236802480 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - =
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: 1.7.0
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70318236802480
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: jquery-rails
|
38
|
-
requirement: &
|
38
|
+
requirement: &70318236799920 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: 2.0.0
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70318236799920
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: highline
|
49
|
-
requirement: &
|
49
|
+
requirement: &70318236798400 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - =
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: 1.6.11
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70318236798400
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: state_machine
|
60
|
-
requirement: &
|
60
|
+
requirement: &70318236810320 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - =
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: 1.1.2
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70318236810320
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: ffaker
|
71
|
-
requirement: &
|
71
|
+
requirement: &70318236825880 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: 1.12.0
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70318236825880
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: paperclip
|
82
|
-
requirement: &
|
82
|
+
requirement: &70318236822420 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ~>
|
@@ -87,10 +87,10 @@ dependencies:
|
|
87
87
|
version: '2.7'
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *70318236822420
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: aws-sdk
|
93
|
-
requirement: &
|
93
|
+
requirement: &70318236844440 !ruby/object:Gem::Requirement
|
94
94
|
none: false
|
95
95
|
requirements:
|
96
96
|
- - ~>
|
@@ -98,10 +98,10 @@ dependencies:
|
|
98
98
|
version: 1.3.4
|
99
99
|
type: :runtime
|
100
100
|
prerelease: false
|
101
|
-
version_requirements: *
|
101
|
+
version_requirements: *70318236844440
|
102
102
|
- !ruby/object:Gem::Dependency
|
103
103
|
name: ransack
|
104
|
-
requirement: &
|
104
|
+
requirement: &70318236839880 !ruby/object:Gem::Requirement
|
105
105
|
none: false
|
106
106
|
requirements:
|
107
107
|
- - ~>
|
@@ -109,10 +109,10 @@ dependencies:
|
|
109
109
|
version: 0.6.0
|
110
110
|
type: :runtime
|
111
111
|
prerelease: false
|
112
|
-
version_requirements: *
|
112
|
+
version_requirements: *70318236839880
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
114
|
name: activemerchant
|
115
|
-
requirement: &
|
115
|
+
requirement: &70318236853080 !ruby/object:Gem::Requirement
|
116
116
|
none: false
|
117
117
|
requirements:
|
118
118
|
- - =
|
@@ -120,10 +120,10 @@ dependencies:
|
|
120
120
|
version: 1.20.4
|
121
121
|
type: :runtime
|
122
122
|
prerelease: false
|
123
|
-
version_requirements: *
|
123
|
+
version_requirements: *70318236853080
|
124
124
|
- !ruby/object:Gem::Dependency
|
125
125
|
name: rails
|
126
|
-
requirement: &
|
126
|
+
requirement: &70318236860820 !ruby/object:Gem::Requirement
|
127
127
|
none: false
|
128
128
|
requirements:
|
129
129
|
- - ! '>='
|
@@ -134,10 +134,10 @@ dependencies:
|
|
134
134
|
version: 3.2.3
|
135
135
|
type: :runtime
|
136
136
|
prerelease: false
|
137
|
-
version_requirements: *
|
137
|
+
version_requirements: *70318236860820
|
138
138
|
- !ruby/object:Gem::Dependency
|
139
139
|
name: kaminari
|
140
|
-
requirement: &
|
140
|
+
requirement: &70318236885120 !ruby/object:Gem::Requirement
|
141
141
|
none: false
|
142
142
|
requirements:
|
143
143
|
- - ! '>='
|
@@ -145,10 +145,10 @@ dependencies:
|
|
145
145
|
version: 0.13.0
|
146
146
|
type: :runtime
|
147
147
|
prerelease: false
|
148
|
-
version_requirements: *
|
148
|
+
version_requirements: *70318236885120
|
149
149
|
- !ruby/object:Gem::Dependency
|
150
150
|
name: deface
|
151
|
-
requirement: &
|
151
|
+
requirement: &70318236881940 !ruby/object:Gem::Requirement
|
152
152
|
none: false
|
153
153
|
requirements:
|
154
154
|
- - ! '>='
|
@@ -156,10 +156,10 @@ dependencies:
|
|
156
156
|
version: 0.8.0
|
157
157
|
type: :runtime
|
158
158
|
prerelease: false
|
159
|
-
version_requirements: *
|
159
|
+
version_requirements: *70318236881940
|
160
160
|
- !ruby/object:Gem::Dependency
|
161
161
|
name: stringex
|
162
|
-
requirement: &
|
162
|
+
requirement: &70318236902600 !ruby/object:Gem::Requirement
|
163
163
|
none: false
|
164
164
|
requirements:
|
165
165
|
- - ~>
|
@@ -167,7 +167,7 @@ dependencies:
|
|
167
167
|
version: 1.3.2
|
168
168
|
type: :runtime
|
169
169
|
prerelease: false
|
170
|
-
version_requirements: *
|
170
|
+
version_requirements: *70318236902600
|
171
171
|
description: Required dependency for Spree
|
172
172
|
email: sean@spreecommerce.com
|
173
173
|
executables: []
|
@@ -868,6 +868,7 @@ files:
|
|
868
868
|
- db/migrate/20120203153759_add_deleted_at_to_tax_category.rb
|
869
869
|
- db/migrate/20120315064358_migrate_images_from_products_to_variants.rb
|
870
870
|
- db/migrate/20120416233427_rename_attachment_size_to_attachment_file_size.rb
|
871
|
+
- db/migrate/20120507232704_increase_scale_of_tax_rate_amount.rb
|
871
872
|
- db/sample/users.rb
|
872
873
|
- db/seeds.rb
|
873
874
|
- vendor/assets/images/datepicker/cal.gif
|
@@ -968,7 +969,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
968
969
|
version: '0'
|
969
970
|
segments:
|
970
971
|
- 0
|
971
|
-
hash: -
|
972
|
+
hash: -3177419443841864347
|
972
973
|
requirements:
|
973
974
|
- none
|
974
975
|
rubyforge_project: spree_core
|