spree_core 1.3.1 → 1.3.2
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/LICENSE +1 -1
- data/app/assets/javascripts/admin/admin.js.erb +1 -1
- data/app/assets/javascripts/admin/shipping_methods.js.coffee +1 -1
- data/app/assets/javascripts/admin/spree_core.js +1 -0
- data/app/assets/javascripts/admin/variant_autocomplete.js.erb +1 -1
- data/app/assets/stylesheets/admin/globals/_variables.scss +7 -7
- data/app/assets/stylesheets/admin/plugins/font-awesome.scss +2 -2
- data/app/assets/stylesheets/admin/shared/_forms.scss +19 -16
- data/app/assets/stylesheets/admin/shared/_layout.scss +1 -1
- data/app/assets/stylesheets/admin/shared/_typography.scss +10 -10
- data/app/assets/stylesheets/store/screen.css.scss +50 -50
- data/app/controllers/spree/admin/base_controller.rb +0 -1
- data/app/controllers/spree/admin/images_controller.rb +1 -1
- data/app/controllers/spree/admin/line_items_controller.rb +1 -0
- data/app/controllers/spree/admin/orders_controller.rb +5 -1
- data/app/controllers/spree/admin/payments_controller.rb +2 -1
- data/app/controllers/spree/admin/products_controller.rb +3 -1
- data/app/controllers/spree/admin/resource_controller.rb +15 -4
- data/app/controllers/spree/admin/shipments_controller.rb +6 -1
- data/app/controllers/spree/admin/taxons_controller.rb +0 -6
- data/app/controllers/spree/checkout_controller.rb +0 -4
- data/app/controllers/spree/locale_controller.rb +2 -2
- data/app/controllers/spree/orders_controller.rb +1 -1
- data/app/helpers/spree/admin/base_helper.rb +9 -1
- data/app/helpers/spree/admin/images_helper.rb +14 -0
- data/app/helpers/spree/admin/products_helper.rb +1 -1
- data/app/helpers/spree/base_helper.rb +3 -3
- data/app/models/spree/ability.rb +2 -6
- data/app/models/spree/address.rb +6 -1
- data/app/models/spree/legacy_user.rb +11 -0
- data/app/models/spree/log_entry.rb +11 -0
- data/app/models/spree/order.rb +11 -5
- data/app/models/spree/order_populator.rb +2 -2
- data/app/models/spree/order_updater.rb +11 -11
- data/app/models/spree/payment/processing.rb +2 -2
- data/app/models/spree/payment.rb +20 -1
- data/app/models/spree/payment_method.rb +10 -3
- data/app/models/spree/preference.rb +0 -29
- data/app/models/spree/preferences/store.rb +4 -10
- data/app/models/spree/product/scopes.rb +2 -2
- data/app/models/spree/product.rb +2 -5
- data/app/models/spree/product_property.rb +3 -1
- data/app/models/spree/property.rb +0 -2
- data/app/models/spree/return_authorization.rb +1 -1
- data/app/models/spree/shipment.rb +1 -1
- data/app/models/spree/variant.rb +1 -1
- data/app/views/spree/admin/general_settings/edit.html.erb +2 -2
- data/app/views/spree/admin/images/index.html.erb +6 -33
- data/app/views/spree/admin/orders/_form.html.erb +1 -1
- data/app/views/spree/admin/payment_methods/_form.html.erb +4 -0
- data/app/views/spree/admin/payment_methods/index.html.erb +3 -1
- data/app/views/spree/admin/product_properties/_product_property_fields.html.erb +5 -1
- data/app/views/spree/admin/product_properties/index.html.erb +2 -2
- data/app/views/spree/admin/products/_form.html.erb +1 -6
- data/app/views/spree/admin/products/edit.html.erb +4 -1
- data/app/views/spree/admin/prototypes/_form.html.erb +1 -1
- data/app/views/spree/admin/prototypes/select.js.erb +2 -2
- data/app/views/spree/admin/return_authorizations/index.html.erb +1 -1
- data/app/views/spree/admin/shared/_tabs.html.erb +1 -1
- data/app/views/spree/admin/shared/_translations.html.erb +1 -1
- data/app/views/spree/admin/shipments/_form.html.erb +1 -1
- data/app/views/spree/admin/shipping_methods/_form.html.erb +3 -3
- data/app/views/spree/admin/taxonomies/get_children.json.erb +1 -1
- data/app/views/spree/admin/variants/_autocomplete.js.erb +1 -1
- data/app/views/spree/shared/_order_details.html.erb +1 -1
- data/config/routes.rb +5 -1
- data/db/migrate/20121031162139_split_prices_from_variants.rb +1 -1
- data/db/migrate/20130114053446_add_display_on_to_spree_payment_methods.rb +9 -0
- data/db/migrate/20130120201805_add_position_to_product_properties.spree.rb +6 -0
- data/db/migrate/20130203232234_add_identifier_to_spree_payments.rb +5 -0
- data/lib/generators/spree/install/install_generator.rb +4 -1
- data/lib/spree/core/controller_helpers/common.rb +3 -3
- data/lib/spree/core/controller_helpers.rb +13 -0
- data/lib/spree/core/engine.rb +7 -4
- data/lib/spree/core/permalinks.rb +1 -1
- data/lib/spree/core/ssl_requirement.rb +1 -1
- data/lib/spree/core/testing_support/authorization_helpers.rb +5 -2
- data/lib/spree/core/testing_support/bar_ability.rb +17 -0
- data/lib/spree/core/testing_support/factories/product_factory.rb +4 -2
- data/lib/spree/core/testing_support/factories/variant_factory.rb +9 -3
- data/lib/spree/core/testing_support/preferences.rb +12 -6
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +1 -1
- data/lib/spree/scopes/dynamic.rb +1 -1
- data/lib/tasks/core.rake +3 -3
- data/vendor/assets/javascripts/jquery-migrate-1.0.0.js +498 -0
- metadata +14 -7
|
@@ -77,7 +77,7 @@ module Spree
|
|
|
77
77
|
|
|
78
78
|
def load_data
|
|
79
79
|
@amount = params[:amount] || load_order.total
|
|
80
|
-
@payment_methods = PaymentMethod.available
|
|
80
|
+
@payment_methods = PaymentMethod.available(:back_end)
|
|
81
81
|
if @payment and @payment.payment_method
|
|
82
82
|
@payment_method = @payment.payment_method
|
|
83
83
|
else
|
|
@@ -88,6 +88,7 @@ module Spree
|
|
|
88
88
|
|
|
89
89
|
def load_order
|
|
90
90
|
@order = Order.find_by_number!(params[:order_id])
|
|
91
|
+
authorize! params[:action], @order
|
|
91
92
|
end
|
|
92
93
|
|
|
93
94
|
def load_payment
|
|
@@ -9,10 +9,12 @@ module Spree
|
|
|
9
9
|
update.before :update_before
|
|
10
10
|
|
|
11
11
|
def show
|
|
12
|
+
session[:return_to] ||= request.referer
|
|
12
13
|
redirect_to( :action => :edit )
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
def index
|
|
17
|
+
session[:return_to] = request.url
|
|
16
18
|
respond_with(@collection)
|
|
17
19
|
end
|
|
18
20
|
|
|
@@ -33,7 +35,7 @@ module Spree
|
|
|
33
35
|
end
|
|
34
36
|
|
|
35
37
|
def destroy
|
|
36
|
-
@product = Product.
|
|
38
|
+
@product = Product.find_by_permalink!(params[:id])
|
|
37
39
|
@product.delete
|
|
38
40
|
|
|
39
41
|
flash.notice = I18n.t('notice_messages.product_deleted')
|
|
@@ -40,6 +40,7 @@ class Spree::Admin::ResourceController < Spree::Admin::BaseController
|
|
|
40
40
|
|
|
41
41
|
def create
|
|
42
42
|
invoke_callbacks(:create, :before)
|
|
43
|
+
@object.attributes = params[object_name]
|
|
43
44
|
if @object.save
|
|
44
45
|
invoke_callbacks(:create, :after)
|
|
45
46
|
flash[:success] = flash_message_for(@object, :successfully_created)
|
|
@@ -134,9 +135,19 @@ class Spree::Admin::ResourceController < Spree::Admin::BaseController
|
|
|
134
135
|
def load_resource
|
|
135
136
|
if member_action?
|
|
136
137
|
@object ||= load_resource_instance
|
|
138
|
+
|
|
139
|
+
# call authorize! a third time (called twice already in Admin::BaseController)
|
|
140
|
+
# this time we pass the actual instance so fine-grained abilities can control
|
|
141
|
+
# access to individual records, not just entire models.
|
|
142
|
+
authorize! params[:action], @object
|
|
143
|
+
|
|
137
144
|
instance_variable_set("@#{object_name}", @object)
|
|
138
145
|
else
|
|
139
146
|
@collection ||= collection
|
|
147
|
+
|
|
148
|
+
# note: we don't call authorize here as the collection method should use
|
|
149
|
+
# CanCan's accessible_by method to restrict the actual records returned
|
|
150
|
+
|
|
140
151
|
instance_variable_set("@#{controller_name}", @collection)
|
|
141
152
|
end
|
|
142
153
|
end
|
|
@@ -155,7 +166,7 @@ class Spree::Admin::ResourceController < Spree::Admin::BaseController
|
|
|
155
166
|
|
|
156
167
|
def parent
|
|
157
168
|
if parent_data.present?
|
|
158
|
-
@parent ||= parent_data[:model_class].
|
|
169
|
+
@parent ||= parent_data[:model_class].send("find_by_#{parent_data[:find_by]}", params["#{model_name}_id"])
|
|
159
170
|
instance_variable_set("@#{model_name}", @parent)
|
|
160
171
|
else
|
|
161
172
|
nil
|
|
@@ -172,16 +183,16 @@ class Spree::Admin::ResourceController < Spree::Admin::BaseController
|
|
|
172
183
|
|
|
173
184
|
def build_resource
|
|
174
185
|
if parent_data.present?
|
|
175
|
-
parent.send(controller_name).build
|
|
186
|
+
parent.send(controller_name).build
|
|
176
187
|
else
|
|
177
|
-
model_class.new
|
|
188
|
+
model_class.new
|
|
178
189
|
end
|
|
179
190
|
end
|
|
180
191
|
|
|
181
192
|
def collection
|
|
182
193
|
return parent.send(controller_name) if parent_data.present?
|
|
183
194
|
if model_class.respond_to?(:accessible_by) && !current_ability.has_block?(params[:action], model_class)
|
|
184
|
-
model_class.accessible_by(current_ability)
|
|
195
|
+
model_class.accessible_by(current_ability, params[:action])
|
|
185
196
|
else
|
|
186
197
|
model_class.scoped
|
|
187
198
|
end
|
|
@@ -79,10 +79,11 @@ module Spree
|
|
|
79
79
|
|
|
80
80
|
def order
|
|
81
81
|
@order ||= Order.find_by_number(params[:order_id])
|
|
82
|
+
authorize! params[:action], @order
|
|
82
83
|
end
|
|
83
84
|
|
|
84
85
|
def shipment
|
|
85
|
-
@shipment ||=
|
|
86
|
+
@shipment ||= order.shipments.find_by_number(params[:id])
|
|
86
87
|
end
|
|
87
88
|
|
|
88
89
|
def build_shipment
|
|
@@ -92,6 +93,10 @@ module Spree
|
|
|
92
93
|
@shipment.shipping_method ||= order.shipping_method
|
|
93
94
|
@shipment.attributes = params[:shipment]
|
|
94
95
|
end
|
|
96
|
+
|
|
97
|
+
def model_class
|
|
98
|
+
Spree::Shipment
|
|
99
|
+
end
|
|
95
100
|
end
|
|
96
101
|
end
|
|
97
102
|
end
|
|
@@ -107,10 +107,6 @@ module Spree
|
|
|
107
107
|
@order.shipping_method ||= (@order.rate_hash.first && @order.rate_hash.first[:shipping_method])
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
-
def before_payment
|
|
111
|
-
current_order.payments.destroy_all if request.put?
|
|
112
|
-
end
|
|
113
|
-
|
|
114
110
|
def after_complete
|
|
115
111
|
session[:order_id] = nil
|
|
116
112
|
end
|
|
@@ -4,8 +4,8 @@ module Spree
|
|
|
4
4
|
if request.referer && request.referer.starts_with?('http://' + request.host)
|
|
5
5
|
session['user_return_to'] = request.referer
|
|
6
6
|
end
|
|
7
|
-
if params[:locale] && I18n.available_locales.include?(params[:locale]
|
|
8
|
-
session[:locale] = I18n.locale = params[:locale]
|
|
7
|
+
if params[:locale] && I18n.available_locales.map(&:to_s).include?(params[:locale])
|
|
8
|
+
session[:locale] = I18n.locale = params[:locale]
|
|
9
9
|
flash.notice = t(:locale_changed)
|
|
10
10
|
else
|
|
11
11
|
flash[:error] = t(:locale_not_changed)
|
|
@@ -40,7 +40,7 @@ module Spree
|
|
|
40
40
|
|
|
41
41
|
# Adds a new item to the order (creating a new order if none already exists)
|
|
42
42
|
def populate
|
|
43
|
-
populator = OrderPopulator.new(current_order(true), current_currency)
|
|
43
|
+
populator = Spree::OrderPopulator.new(current_order(true), current_currency)
|
|
44
44
|
if populator.populate(params.slice(:products, :variants, :quantity))
|
|
45
45
|
fire_event('spree.cart.add')
|
|
46
46
|
fire_event('spree.order.contents_changed')
|
|
@@ -22,6 +22,14 @@ module Spree
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def datepicker_field_value(date)
|
|
26
|
+
unless date.blank?
|
|
27
|
+
l(date, :format => t('spree.date_picker.format'))
|
|
28
|
+
else
|
|
29
|
+
nil
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
25
33
|
# This method demonstrates the use of the :child_index option to render a
|
|
26
34
|
# form partial for, for instance, client side addition of new nested
|
|
27
35
|
# records.
|
|
@@ -54,7 +62,7 @@ module Spree
|
|
|
54
62
|
def remove_nested(fields)
|
|
55
63
|
out = ''
|
|
56
64
|
out << fields.hidden_field(:_destroy) unless fields.object.new_record?
|
|
57
|
-
out << (link_to icon('
|
|
65
|
+
out << (link_to icon('icon-remove'), "#", :class => 'remove')
|
|
58
66
|
out.html_safe
|
|
59
67
|
end
|
|
60
68
|
|
|
@@ -13,7 +13,7 @@ module Spree
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def link_to_cart(text = nil)
|
|
16
|
-
return "" if current_spree_page?(cart_path)
|
|
16
|
+
return "" if current_spree_page?(spree.cart_path)
|
|
17
17
|
|
|
18
18
|
text = text ? h(text) : t('cart')
|
|
19
19
|
css_class = nil
|
|
@@ -26,7 +26,7 @@ module Spree
|
|
|
26
26
|
css_class = 'full'
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
link_to text, cart_path, :class => css_class
|
|
29
|
+
link_to text, spree.cart_path, :class => css_class
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
# human readable list of variant options
|
|
@@ -127,7 +127,7 @@ module Spree
|
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
countries.collect do |country|
|
|
130
|
-
country.name = I18n.t(country.iso, :scope => '
|
|
130
|
+
country.name = I18n.t(country.iso, :scope => 'country_names', :default => country.name)
|
|
131
131
|
country
|
|
132
132
|
end.sort { |a, b| a.name <=> b.name }
|
|
133
133
|
end
|
data/app/models/spree/ability.rb
CHANGED
|
@@ -30,18 +30,14 @@ module Spree
|
|
|
30
30
|
alias_action :new, :to => :create
|
|
31
31
|
alias_action :new_action, :to => :create
|
|
32
32
|
alias_action :show, :to => :read
|
|
33
|
+
alias_action :delete, :to => :destroy
|
|
33
34
|
|
|
34
35
|
user ||= Spree.user_class.new
|
|
35
36
|
if user.respond_to?(:has_spree_role?) && user.has_spree_role?('admin')
|
|
36
37
|
can :manage, :all
|
|
37
38
|
else
|
|
38
39
|
#############################
|
|
39
|
-
can :read, Spree.user_class
|
|
40
|
-
resource == user
|
|
41
|
-
end
|
|
42
|
-
can :update, Spree.user_class do |resource|
|
|
43
|
-
resource == user
|
|
44
|
-
end
|
|
40
|
+
can [:read,:update,:destroy], Spree.user_class, :id => user.id
|
|
45
41
|
can :create, Spree.user_class
|
|
46
42
|
#############################
|
|
47
43
|
can :read, Order do |order, token|
|
data/app/models/spree/address.rb
CHANGED
|
@@ -5,7 +5,8 @@ module Spree
|
|
|
5
5
|
|
|
6
6
|
has_many :shipments
|
|
7
7
|
|
|
8
|
-
validates :firstname, :lastname, :address1, :city, :zipcode, :country, :
|
|
8
|
+
validates :firstname, :lastname, :address1, :city, :zipcode, :country, :presence => true
|
|
9
|
+
validates :phone, :presence => true, :if => :require_phone?
|
|
9
10
|
validate :state_validate
|
|
10
11
|
|
|
11
12
|
attr_accessible :firstname, :lastname, :address1, :address2,
|
|
@@ -83,6 +84,10 @@ module Spree
|
|
|
83
84
|
|
|
84
85
|
private
|
|
85
86
|
|
|
87
|
+
def require_phone?
|
|
88
|
+
true
|
|
89
|
+
end
|
|
90
|
+
|
|
86
91
|
def state_validate
|
|
87
92
|
# Skip state validation without country (also required)
|
|
88
93
|
# or when disabled by preference
|
|
@@ -4,11 +4,16 @@ module Spree
|
|
|
4
4
|
self.table_name = 'spree_users'
|
|
5
5
|
attr_accessible :email, :password, :password_confirmation
|
|
6
6
|
|
|
7
|
+
has_many :orders, :foreign_key => :user_id
|
|
7
8
|
belongs_to :ship_address, :class_name => 'Spree::Address'
|
|
8
9
|
belongs_to :bill_address, :class_name => 'Spree::Address'
|
|
9
10
|
|
|
10
11
|
scope :registered
|
|
11
12
|
|
|
13
|
+
before_destroy :check_completed_orders
|
|
14
|
+
|
|
15
|
+
class DestroyWithOrdersError < StandardError; end
|
|
16
|
+
|
|
12
17
|
def anonymous?
|
|
13
18
|
false
|
|
14
19
|
end
|
|
@@ -24,5 +29,11 @@ module Spree
|
|
|
24
29
|
|
|
25
30
|
attr_accessor :password
|
|
26
31
|
attr_accessor :password_confirmation
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def check_completed_orders
|
|
36
|
+
raise DestroyWithOrdersError if orders.complete.present?
|
|
37
|
+
end
|
|
27
38
|
end
|
|
28
39
|
end
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
class LogEntry < ActiveRecord::Base
|
|
3
3
|
belongs_to :source, :polymorphic => true
|
|
4
|
+
|
|
5
|
+
# Fix for #1767
|
|
6
|
+
# If a payment fails, we want to make sure we keep the record of it failing
|
|
7
|
+
after_rollback :save_anyway
|
|
8
|
+
|
|
9
|
+
def save_anyway
|
|
10
|
+
log = Spree::LogEntry.new
|
|
11
|
+
log.source = source
|
|
12
|
+
log.details = details
|
|
13
|
+
log.save!
|
|
14
|
+
end
|
|
4
15
|
end
|
|
5
16
|
end
|
data/app/models/spree/order.rb
CHANGED
|
@@ -31,7 +31,7 @@ module Spree
|
|
|
31
31
|
token_resource
|
|
32
32
|
|
|
33
33
|
attr_accessible :line_items, :bill_address_attributes, :ship_address_attributes, :payments_attributes,
|
|
34
|
-
:ship_address, :bill_address, :line_items_attributes, :number,
|
|
34
|
+
:ship_address, :bill_address, :payments_attributes, :line_items_attributes, :number,
|
|
35
35
|
:shipping_method_id, :email, :use_billing, :special_instructions, :currency
|
|
36
36
|
|
|
37
37
|
if Spree.user_class
|
|
@@ -52,7 +52,13 @@ module Spree
|
|
|
52
52
|
has_many :line_items, :dependent => :destroy, :order => "created_at ASC"
|
|
53
53
|
has_many :inventory_units
|
|
54
54
|
has_many :payments, :dependent => :destroy
|
|
55
|
-
|
|
55
|
+
|
|
56
|
+
has_many :shipments, :dependent => :destroy do
|
|
57
|
+
def states
|
|
58
|
+
pluck(:state).uniq
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
56
62
|
has_many :return_authorizations, :dependent => :destroy
|
|
57
63
|
has_many :adjustments, :as => :adjustable, :dependent => :destroy, :order => "created_at ASC"
|
|
58
64
|
|
|
@@ -351,11 +357,11 @@ module Spree
|
|
|
351
357
|
end
|
|
352
358
|
|
|
353
359
|
def can_ship?
|
|
354
|
-
self.complete? || self.resumed?
|
|
360
|
+
self.complete? || self.resumed? || self.awaiting_return? || self.returned?
|
|
355
361
|
end
|
|
356
362
|
|
|
357
363
|
def credit_cards
|
|
358
|
-
credit_card_ids = payments.from_credit_card.
|
|
364
|
+
credit_card_ids = payments.from_credit_card.pluck(:source_id).uniq
|
|
359
365
|
CreditCard.scoped(:conditions => { :id => credit_card_ids })
|
|
360
366
|
end
|
|
361
367
|
|
|
@@ -436,7 +442,7 @@ module Spree
|
|
|
436
442
|
end
|
|
437
443
|
|
|
438
444
|
def available_payment_methods
|
|
439
|
-
@available_payment_methods ||= PaymentMethod.available
|
|
445
|
+
@available_payment_methods ||= PaymentMethod.available(:front_end)
|
|
440
446
|
end
|
|
441
447
|
|
|
442
448
|
def payment_method
|
|
@@ -50,9 +50,9 @@ module Spree
|
|
|
50
50
|
display_name = %Q{#{variant.name}}
|
|
51
51
|
display_name += %Q{ (#{variant.options_text})} unless variant.options_text.blank?
|
|
52
52
|
|
|
53
|
-
if variant.
|
|
53
|
+
if variant.available?
|
|
54
54
|
on_hand = variant.on_hand
|
|
55
|
-
if on_hand >= quantity
|
|
55
|
+
if on_hand >= quantity || Spree::Config[:allow_backorders]
|
|
56
56
|
return true
|
|
57
57
|
else
|
|
58
58
|
errors.add(:base, %Q{There are only #{on_hand} of #{display_name.inspect} remaining.} +
|
|
@@ -69,18 +69,18 @@ module Spree
|
|
|
69
69
|
if order.backordered?
|
|
70
70
|
order.shipment_state = 'backorder'
|
|
71
71
|
else
|
|
72
|
-
order
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
'shipped'
|
|
78
|
-
when shipments.ready.count
|
|
79
|
-
'ready'
|
|
80
|
-
when shipments.pending.count
|
|
81
|
-
'pending'
|
|
72
|
+
# get all the shipment states for this order
|
|
73
|
+
shipment_states = shipments.states
|
|
74
|
+
if shipment_states.size > 1
|
|
75
|
+
# multiple shiment states means it's most likely partially shipped
|
|
76
|
+
order.shipment_state = 'partial'
|
|
82
77
|
else
|
|
83
|
-
|
|
78
|
+
# will return nil if no shipments are found
|
|
79
|
+
order.shipment_state = shipment_states.first
|
|
80
|
+
if order.shipment_state && order.inventory_units.where(:shipment_id => nil).exists?
|
|
81
|
+
# shipments exist but there are unassigned inventory units
|
|
82
|
+
order.shipment_state = 'partial'
|
|
83
|
+
end
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
|
|
@@ -5,7 +5,7 @@ module Spree
|
|
|
5
5
|
if payment_method && payment_method.source_required?
|
|
6
6
|
if source
|
|
7
7
|
if !processing?
|
|
8
|
-
if
|
|
8
|
+
if payment_method.auto_capture?
|
|
9
9
|
purchase!
|
|
10
10
|
else
|
|
11
11
|
authorize!
|
|
@@ -111,7 +111,7 @@ module Spree
|
|
|
111
111
|
options = { :email => order.email,
|
|
112
112
|
:customer => order.email,
|
|
113
113
|
:ip => order.last_ip_address,
|
|
114
|
-
:order_id => order.number }
|
|
114
|
+
:order_id => "#{order.number}-#{self.identifier}" }
|
|
115
115
|
|
|
116
116
|
options.merge!({ :shipping => order.ship_total * 100,
|
|
117
117
|
:tax => order.tax_total * 100,
|
data/app/models/spree/payment.rb
CHANGED
|
@@ -8,6 +8,8 @@ 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
|
|
12
|
+
|
|
11
13
|
after_save :create_payment_profile, :if => :profiles_supported?
|
|
12
14
|
|
|
13
15
|
# update the order totals, etc.
|
|
@@ -56,7 +58,7 @@ module Spree
|
|
|
56
58
|
end
|
|
57
59
|
|
|
58
60
|
def offsets_total
|
|
59
|
-
offsets.
|
|
61
|
+
offsets.pluck(:amount).sum
|
|
60
62
|
end
|
|
61
63
|
|
|
62
64
|
def credit_allowed
|
|
@@ -108,5 +110,22 @@ module Spree
|
|
|
108
110
|
order.payments.reload
|
|
109
111
|
order.update!
|
|
110
112
|
end
|
|
113
|
+
|
|
114
|
+
# Necessary because some payment gateways will refuse payments with
|
|
115
|
+
# duplicate IDs. We *were* using the Order number, but that's set once and
|
|
116
|
+
# is unchanging. What we need is a unique identifier on a per-payment basis,
|
|
117
|
+
# and this is it. Related to #1998.
|
|
118
|
+
# See https://github.com/spree/spree/issues/1998#issuecomment-12869105
|
|
119
|
+
def set_unique_identifier
|
|
120
|
+
chars = [('A'..'Z').to_a, ('0'..'9').to_a].flatten - %w(0 1 I O)
|
|
121
|
+
identifier = ''
|
|
122
|
+
8.times { identifier << chars[rand(chars.length)] }
|
|
123
|
+
if Spree::Payment.exists?(:identifier => identifier)
|
|
124
|
+
# Call it again, we've got a duplicate ID.
|
|
125
|
+
set_unique_identifier
|
|
126
|
+
else
|
|
127
|
+
self.identifier = identifier
|
|
128
|
+
end
|
|
129
|
+
end
|
|
111
130
|
end
|
|
112
131
|
end
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
class PaymentMethod < ActiveRecord::Base
|
|
3
|
+
DISPLAY = [:both, :front_end, :back_end]
|
|
3
4
|
default_scope where(:deleted_at => nil)
|
|
4
5
|
|
|
5
6
|
scope :production, lambda { where(:environment => 'production') }
|
|
6
7
|
|
|
7
|
-
attr_accessible :name, :description, :environment, :active
|
|
8
|
+
attr_accessible :name, :description, :environment, :display_on, :active
|
|
8
9
|
validates :name, :presence => true
|
|
9
10
|
|
|
10
11
|
def self.providers
|
|
@@ -22,9 +23,11 @@ module Spree
|
|
|
22
23
|
raise 'You must implement payment_source_class method for this gateway.'
|
|
23
24
|
end
|
|
24
25
|
|
|
25
|
-
def self.available
|
|
26
|
+
def self.available(display_on = 'both')
|
|
26
27
|
all.select do |p|
|
|
27
|
-
p.active &&
|
|
28
|
+
p.active &&
|
|
29
|
+
(p.display_on == display_on.to_s || p.display_on.blank?) &&
|
|
30
|
+
(p.environment == Rails.env || p.environment.blank?)
|
|
28
31
|
end
|
|
29
32
|
end
|
|
30
33
|
|
|
@@ -51,5 +54,9 @@ module Spree
|
|
|
51
54
|
def source_required?
|
|
52
55
|
true
|
|
53
56
|
end
|
|
57
|
+
|
|
58
|
+
def auto_capture?
|
|
59
|
+
Spree::Config[:auto_capture]
|
|
60
|
+
end
|
|
54
61
|
end
|
|
55
62
|
end
|
|
@@ -33,33 +33,4 @@ class Spree::Preference < ActiveRecord::Base
|
|
|
33
33
|
self[:value]
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
# For the rc releases of 1.0, we stored the object class names, this converts
|
|
37
|
-
# to preferences definition types. This code should eventually be removed.
|
|
38
|
-
# it is called during the load_preferences of the Preferences::Store
|
|
39
|
-
def self.convert_old_value_types(preference)
|
|
40
|
-
classes = [Symbol.to_s, Fixnum.to_s, Bignum.to_s,
|
|
41
|
-
Float.to_s, TrueClass.to_s, FalseClass.to_s]
|
|
42
|
-
return unless classes.map(&:downcase).include? preference.value_type.downcase
|
|
43
|
-
|
|
44
|
-
case preference.value_type.downcase
|
|
45
|
-
when "symbol"
|
|
46
|
-
preference.value_type = 'string'
|
|
47
|
-
when "fixnum"
|
|
48
|
-
preference.value_type = 'integer'
|
|
49
|
-
when "bignum"
|
|
50
|
-
preference.value_type = 'integer'
|
|
51
|
-
preference.value = preference.value.to_f.to_i
|
|
52
|
-
when "float"
|
|
53
|
-
preference.value_type = 'decimal'
|
|
54
|
-
when "trueclass"
|
|
55
|
-
preference.value_type = 'boolean'
|
|
56
|
-
preference.value = "true"
|
|
57
|
-
when "falseclass"
|
|
58
|
-
preference.value_type = 'boolean'
|
|
59
|
-
preference.value = "false"
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
preference.save
|
|
63
|
-
end
|
|
64
|
-
|
|
65
36
|
end
|
|
@@ -14,7 +14,6 @@ module Spree::Preferences
|
|
|
14
14
|
def initialize
|
|
15
15
|
@cache = Rails.cache
|
|
16
16
|
@persistence = true
|
|
17
|
-
load_preferences
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
def set(key, value, type)
|
|
@@ -64,6 +63,10 @@ module Spree::Preferences
|
|
|
64
63
|
destroy(key)
|
|
65
64
|
end
|
|
66
65
|
|
|
66
|
+
def clear_cache
|
|
67
|
+
@cache.clear
|
|
68
|
+
end
|
|
69
|
+
|
|
67
70
|
private
|
|
68
71
|
|
|
69
72
|
def persist(cache_key, value, type)
|
|
@@ -82,15 +85,6 @@ module Spree::Preferences
|
|
|
82
85
|
preference.destroy if preference
|
|
83
86
|
end
|
|
84
87
|
|
|
85
|
-
def load_preferences
|
|
86
|
-
return unless should_persist?
|
|
87
|
-
|
|
88
|
-
Spree::Preference.valid.each do |p|
|
|
89
|
-
Spree::Preference.convert_old_value_types(p) # see comment
|
|
90
|
-
@cache.write(p.key, p.value)
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
88
|
def should_persist?
|
|
95
89
|
@persistence and Spree::Preference.table_exists?
|
|
96
90
|
end
|
|
@@ -66,7 +66,7 @@ module Spree
|
|
|
66
66
|
add_search_scope :in_taxon do |taxon|
|
|
67
67
|
select("DISTINCT(spree_products.id), spree_products.*").
|
|
68
68
|
joins(:taxons).
|
|
69
|
-
where(Taxon.table_name => { :id => taxon.self_and_descendants.
|
|
69
|
+
where(Taxon.table_name => { :id => taxon.self_and_descendants.pluck(:id) })
|
|
70
70
|
end
|
|
71
71
|
|
|
72
72
|
# This scope selects products in all taxons AND all its descendants
|
|
@@ -228,7 +228,7 @@ module Spree
|
|
|
228
228
|
|
|
229
229
|
# specifically avoid having an order for taxon search (conflicts with main order)
|
|
230
230
|
def self.prepare_taxon_conditions(taxons)
|
|
231
|
-
ids = taxons.map { |taxon| taxon.self_and_descendants.
|
|
231
|
+
ids = taxons.map { |taxon| taxon.self_and_descendants.pluck(:id) }.flatten.uniq
|
|
232
232
|
joins(:taxons).where("#{Taxon.table_name}.id" => ids)
|
|
233
233
|
end
|
|
234
234
|
|
data/app/models/spree/product.rb
CHANGED
|
@@ -162,7 +162,7 @@ module Spree
|
|
|
162
162
|
return if option_values_hash.nil?
|
|
163
163
|
option_values_hash.keys.map(&:to_i).each do |id|
|
|
164
164
|
self.option_type_ids << id unless option_type_ids.include?(id)
|
|
165
|
-
product_option_types.create({:option_type_id => id}, :without_protection => true) unless product_option_types.
|
|
165
|
+
product_option_types.create({:option_type_id => id}, :without_protection => true) unless product_option_types.pluck(:option_type_id).include?(id)
|
|
166
166
|
end
|
|
167
167
|
end
|
|
168
168
|
|
|
@@ -232,10 +232,7 @@ module Spree
|
|
|
232
232
|
|
|
233
233
|
def set_property(property_name, property_value)
|
|
234
234
|
ActiveRecord::Base.transaction do
|
|
235
|
-
property = Property.where(:name => property_name).
|
|
236
|
-
property.presentation = property_name
|
|
237
|
-
property.save!
|
|
238
|
-
|
|
235
|
+
property = Property.where(:name => property_name).first_or_create!(:presentation => property_name)
|
|
239
236
|
product_property = ProductProperty.where(:product_id => id, :property_id => property.id).first_or_initialize
|
|
240
237
|
product_property.value = property_value
|
|
241
238
|
product_property.save!
|
|
@@ -6,7 +6,9 @@ module Spree
|
|
|
6
6
|
validates :property, :presence => true
|
|
7
7
|
validates :value, :length => { :maximum => 255 }
|
|
8
8
|
|
|
9
|
-
attr_accessible :property_name, :value
|
|
9
|
+
attr_accessible :property_name, :value, :position
|
|
10
|
+
|
|
11
|
+
default_scope :order => "#{self.table_name}.position"
|
|
10
12
|
|
|
11
13
|
# virtual attributes for use with AJAX completion stuff
|
|
12
14
|
def property_name
|