spree_core 1.1.3 → 1.1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/app/assets/images/noimage/large.png +0 -0
- data/app/assets/javascripts/admin/admin.js.erb +14 -14
- data/app/assets/javascripts/admin/checkouts/edit.js +1 -1
- data/app/assets/javascripts/admin/spree_core.js +0 -2
- data/app/assets/javascripts/store/checkout.js +2 -2
- data/app/assets/stylesheets/store/screen.css.scss +1 -1
- data/app/controllers/spree/admin/images_controller.rb +5 -13
- data/app/controllers/spree/admin/mail_methods_controller.rb +7 -0
- data/app/controllers/spree/admin/orders/customer_details_controller.rb +1 -1
- data/app/controllers/spree/admin/payment_methods_controller.rb +7 -1
- data/app/controllers/spree/admin/products_controller.rb +5 -13
- data/app/controllers/spree/admin/prototypes_controller.rb +2 -2
- data/app/controllers/spree/checkout_controller.rb +10 -0
- data/app/controllers/spree/orders_controller.rb +9 -5
- data/app/helpers/spree/base_helper.rb +17 -4
- data/app/helpers/spree/checkout_helper.rb +1 -9
- data/app/helpers/spree/products_helper.rb +0 -4
- data/app/models/spree/address.rb +1 -1
- data/app/models/spree/app_configuration.rb +1 -0
- data/app/models/spree/calculator/price_sack.rb +5 -3
- data/app/models/spree/image.rb +3 -1
- data/app/models/spree/inventory_unit.rb +8 -6
- data/app/models/spree/line_item.rb +2 -1
- data/app/models/spree/order.rb +23 -2
- data/app/models/spree/payment/processing.rb +22 -20
- data/app/models/spree/preferences/preferable_class_methods.rb +2 -0
- data/app/models/spree/preferences/store.rb +20 -2
- data/app/models/spree/product.rb +35 -29
- data/app/models/spree/product/scopes.rb +21 -6
- data/app/models/spree/return_authorization.rb +1 -0
- data/app/models/spree/shipping_method.rb +3 -0
- data/app/models/spree/variant.rb +19 -9
- data/app/views/spree/admin/images/_form.html.erb +4 -8
- data/app/views/spree/admin/return_authorizations/_form.html.erb +17 -33
- data/app/views/spree/admin/shared/_head.html.erb +2 -15
- data/app/views/spree/admin/shared/_order_details.html.erb +1 -1
- data/app/views/spree/admin/shared/_routes.html.erb +8 -0
- data/app/views/spree/admin/shared/_translations.html.erb +17 -0
- data/app/views/spree/admin/tax_rates/index.html.erb +2 -2
- data/app/views/spree/admin/variants/_form.html.erb +2 -2
- data/app/views/spree/checkout/payment/_gateway.html.erb +1 -1
- data/app/views/spree/order_mailer/cancel_email.text.erb +5 -5
- data/app/views/spree/order_mailer/confirm_email.text.erb +7 -6
- data/app/views/spree/products/_thumbnails.html.erb +1 -1
- data/app/views/spree/shared/_google_analytics.html.erb +17 -16
- data/app/views/spree/shared/_head.html.erb +0 -3
- data/app/views/spree/shared/_order_details.html.erb +2 -3
- data/app/views/spree/shipment_mailer/shipped_email.text.erb +7 -7
- data/config/initializers/check_for_orphaned_preferences.rb +1 -1
- data/config/initializers/rails_5868.rb +8 -0
- data/config/locales/en.yml +17 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20121017010007_remove_not_null_constraint_from_products_on_hand.rb +11 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +1 -1
- data/lib/generators/spree/dummy/templates/rails/database.yml +1 -1
- data/lib/generators/spree/install/templates/app/assets/javascripts/admin/all.js +2 -0
- data/lib/spree/core/mail_settings.rb +2 -1
- data/lib/spree/core/search/base.rb +5 -2
- data/lib/spree/core/testing_support/factories/tax_category_factory.rb +5 -2
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/product_filters.rb +1 -1
- metadata +41 -42
- data/app/helpers/spree/account_helper.rb +0 -4
- data/app/helpers/spree/orders_helper.rb +0 -5
- data/app/helpers/spree/trackers_helper.rb +0 -4
- data/config/initializers/workarounds_for_ruby19.rb +0 -72
- data/lib/spree/core/relation_serialization.rb +0 -9
- data/lib/spree/core/testing_support/env.rb +0 -2
@@ -80,6 +80,7 @@ module Spree
|
|
80
80
|
|
81
81
|
def update_order
|
82
82
|
# update the order totals, etc.
|
83
|
+
order.create_tax_charge!
|
83
84
|
order.update!
|
84
85
|
end
|
85
86
|
|
@@ -97,7 +98,7 @@ module Spree
|
|
97
98
|
end
|
98
99
|
|
99
100
|
def quantity_no_less_than_shipped
|
100
|
-
already_shipped = order.shipments.reduce(0) { |acc,s| acc + s.inventory_units.
|
101
|
+
already_shipped = order.shipments.reduce(0) { |acc,s| acc + s.inventory_units.select { |i| i.variant == variant }.count }
|
101
102
|
unless quantity >= already_shipped
|
102
103
|
errors.add(:quantity, I18n.t('validation.cannot_be_less_than_shipped_units'))
|
103
104
|
end
|
data/app/models/spree/order.rb
CHANGED
@@ -19,7 +19,7 @@ module Spree
|
|
19
19
|
belongs_to :shipping_method, :class_name => "Spree::ShippingMethod"
|
20
20
|
|
21
21
|
has_many :state_changes, :as => :stateful
|
22
|
-
has_many :line_items, :dependent => :destroy
|
22
|
+
has_many :line_items, :dependent => :destroy, :order => "created_at ASC"
|
23
23
|
has_many :inventory_units
|
24
24
|
has_many :payments, :dependent => :destroy
|
25
25
|
has_many :shipments, :dependent => :destroy
|
@@ -69,7 +69,7 @@ module Spree
|
|
69
69
|
transition :to => 'canceled', :if => :allow_cancel?
|
70
70
|
end
|
71
71
|
event :return do
|
72
|
-
transition :to => 'returned', :from => 'awaiting_return'
|
72
|
+
transition :to => 'returned', :from => 'awaiting_return', :unless=>:awaiting_returns?
|
73
73
|
end
|
74
74
|
event :resume do
|
75
75
|
transition :to => 'resumed', :from => 'canceled', :if => :allow_resume?
|
@@ -127,6 +127,14 @@ module Spree
|
|
127
127
|
self.update_hooks.add(hook)
|
128
128
|
end
|
129
129
|
|
130
|
+
def checkout_steps
|
131
|
+
if payment and payment.payment_method.payment_profiles_supported?
|
132
|
+
%w(address delivery payment confirm complete)
|
133
|
+
else
|
134
|
+
%w(address delivery payment complete)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
130
138
|
# For compatiblity with Calculator::PriceSack
|
131
139
|
def amount
|
132
140
|
line_items.map(&:amount).sum
|
@@ -271,6 +279,10 @@ module Spree
|
|
271
279
|
true
|
272
280
|
end
|
273
281
|
|
282
|
+
def awaiting_returns?
|
283
|
+
return_authorizations.any? { |return_authorization| return_authorization.authorized? }
|
284
|
+
end
|
285
|
+
|
274
286
|
def add_variant(variant, quantity = 1)
|
275
287
|
current_item = contains?(variant)
|
276
288
|
if current_item
|
@@ -466,6 +478,11 @@ module Spree
|
|
466
478
|
order.destroy
|
467
479
|
end
|
468
480
|
|
481
|
+
def empty!
|
482
|
+
line_items.destroy_all
|
483
|
+
adjustments.destroy_all
|
484
|
+
end
|
485
|
+
|
469
486
|
private
|
470
487
|
def create_user
|
471
488
|
self.email = user.email if self.user and not user.anonymous?
|
@@ -581,6 +598,10 @@ module Spree
|
|
581
598
|
end
|
582
599
|
|
583
600
|
def after_cancel
|
601
|
+
if shipment_state == 'pending'
|
602
|
+
self.update_attribute(:payment_state, 'credit_owed')
|
603
|
+
end
|
604
|
+
|
584
605
|
restock_items!
|
585
606
|
|
586
607
|
#TODO: make_shipments_pending
|
@@ -47,6 +47,7 @@ module Spree
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def void_transaction!
|
50
|
+
return true if void?
|
50
51
|
protect_from_connection_error do
|
51
52
|
check_environment
|
52
53
|
|
@@ -104,8 +105,27 @@ module Spree
|
|
104
105
|
credit!(amount)
|
105
106
|
end
|
106
107
|
|
107
|
-
|
108
|
-
|
108
|
+
def gateway_options
|
109
|
+
options = { :email => order.email,
|
110
|
+
:customer => order.email,
|
111
|
+
:ip => '192.168.1.100', # TODO: Use an actual IP
|
112
|
+
:order_id => order.number }
|
113
|
+
|
114
|
+
options.merge!({ :shipping => order.ship_total * 100,
|
115
|
+
:tax => order.tax_total * 100,
|
116
|
+
:subtotal => order.item_total * 100 })
|
117
|
+
|
118
|
+
options.merge!({ :currency => payment_method.preferences[:currency_code] }) if payment_method && payment_method.preferences[:currency_code]
|
119
|
+
|
120
|
+
options.merge!({ :billing_address => order.bill_address.try(:active_merchant_hash),
|
121
|
+
:shipping_address => order.ship_address.try(:active_merchant_hash) })
|
122
|
+
|
123
|
+
options.merge!(:discount => promo_total) if respond_to?(:promo_total)
|
124
|
+
options
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
109
129
|
def gateway_error(error)
|
110
130
|
if error.is_a? ActiveMerchant::Billing::Response
|
111
131
|
text = error.params['message'] || error.params['response_reason_text'] || error.message
|
@@ -119,8 +139,6 @@ module Spree
|
|
119
139
|
raise Core::GatewayError.new(text)
|
120
140
|
end
|
121
141
|
|
122
|
-
private
|
123
|
-
|
124
142
|
def gateway_action(source, action, success_state)
|
125
143
|
protect_from_connection_error do
|
126
144
|
check_environment
|
@@ -151,22 +169,6 @@ module Spree
|
|
151
169
|
log_entries.create({:details => response.to_yaml}, :without_protection => true)
|
152
170
|
end
|
153
171
|
|
154
|
-
def gateway_options
|
155
|
-
options = { :email => order.email,
|
156
|
-
:customer => order.email,
|
157
|
-
:ip => '192.168.1.100', # TODO: Use real IP address
|
158
|
-
:order_id => order.number }
|
159
|
-
|
160
|
-
options.merge!({ :shipping => order.ship_total * 100,
|
161
|
-
:tax => order.tax_total * 100,
|
162
|
-
:subtotal => order.item_total * 100 })
|
163
|
-
|
164
|
-
options.merge!({ :currency => payment_method.preferences[:currency_code] }) if payment_method && payment_method.preferences[:currency_code]
|
165
|
-
|
166
|
-
options.merge({ :billing_address => order.bill_address.try(:active_merchant_hash),
|
167
|
-
:shipping_address => order.ship_address.try(:active_merchant_hash) })
|
168
|
-
end
|
169
|
-
|
170
172
|
def protect_from_connection_error
|
171
173
|
begin
|
172
174
|
yield
|
@@ -15,6 +15,8 @@ module Spree::Preferences
|
|
15
15
|
else
|
16
16
|
if get_pending_preference(name)
|
17
17
|
get_pending_preference(name)
|
18
|
+
elsif Spree::Preference.table_exists? && preference = Spree::Preference.find_by_name(name)
|
19
|
+
preference.value
|
18
20
|
else
|
19
21
|
send self.class.preference_default_getter_method(name)
|
20
22
|
end
|
@@ -23,11 +23,29 @@ module Spree::Preferences
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def exist?(key)
|
26
|
-
@cache.exist?
|
26
|
+
@cache.exist?(key) ||
|
27
|
+
should_persist? && Spree::Preference.where(:key => key).exists?
|
27
28
|
end
|
28
29
|
|
29
30
|
def get(key)
|
30
|
-
|
31
|
+
# return the retrieved value, if it's in the cache
|
32
|
+
if (val = @cache.read(key)).present?
|
33
|
+
return val
|
34
|
+
end
|
35
|
+
|
36
|
+
return nil unless should_persist?
|
37
|
+
|
38
|
+
# If it's not in the cache, maybe it's in the database, but
|
39
|
+
# has been cleared from the cache
|
40
|
+
|
41
|
+
# does it exist in the database?
|
42
|
+
if preference = Spree::Preference.find_by_key(key)
|
43
|
+
# it does exist, so let's put it back into the cache
|
44
|
+
@cache.write(preference.key, preference.value)
|
45
|
+
|
46
|
+
# and return the value
|
47
|
+
preference.value
|
48
|
+
end
|
31
49
|
end
|
32
50
|
|
33
51
|
def delete(key)
|
data/app/models/spree/product.rb
CHANGED
@@ -23,13 +23,26 @@ module Spree
|
|
23
23
|
has_many :option_types, :through => :product_option_types
|
24
24
|
has_many :product_properties, :dependent => :destroy
|
25
25
|
has_many :properties, :through => :product_properties
|
26
|
-
|
26
|
+
|
27
27
|
has_and_belongs_to_many :taxons, :join_table => 'spree_products_taxons'
|
28
|
-
|
28
|
+
|
29
|
+
belongs_to :tax_category
|
30
|
+
belongs_to :shipping_category
|
29
31
|
|
30
32
|
has_one :master,
|
31
33
|
:class_name => 'Spree::Variant',
|
32
|
-
:conditions =>
|
34
|
+
:conditions => { :is_master => true },
|
35
|
+
:dependent => :destroy
|
36
|
+
|
37
|
+
has_many :variants,
|
38
|
+
:class_name => 'Spree::Variant',
|
39
|
+
:conditions => { :is_master => false, :deleted_at => nil },
|
40
|
+
:order => :position
|
41
|
+
|
42
|
+
has_many :variants_including_master,
|
43
|
+
:class_name => 'Spree::Variant',
|
44
|
+
:conditions => { :deleted_at => nil },
|
45
|
+
:dependent => :destroy
|
33
46
|
|
34
47
|
delegate_belongs_to :master, :sku, :price, :weight, :height, :width, :depth, :is_master
|
35
48
|
delegate_belongs_to :master, :cost_price if Variant.table_exists? && Variant.column_names.include?('cost_price')
|
@@ -41,33 +54,13 @@ module Spree
|
|
41
54
|
after_save :save_master
|
42
55
|
after_save :set_master_on_hand_to_zero_when_product_has_variants
|
43
56
|
|
44
|
-
|
45
|
-
|
46
|
-
:conditions => ["#{::Spree::Variant.quoted_table_name}.is_master = ? AND #{::Spree::Variant.quoted_table_name}.deleted_at IS NULL", false],
|
47
|
-
:order => "#{::Spree::Variant.quoted_table_name}.position ASC"
|
48
|
-
|
49
|
-
has_many :variants_including_master,
|
50
|
-
:class_name => 'Spree::Variant',
|
51
|
-
:conditions => ["#{::Spree::Variant.quoted_table_name}.deleted_at IS NULL"],
|
52
|
-
:dependent => :destroy
|
57
|
+
delegate :images, :to => :master, :prefix => true
|
58
|
+
alias_method :images, :master_images
|
53
59
|
|
54
|
-
has_many :
|
55
|
-
:class_name => 'Spree::Variant',
|
56
|
-
:conditions => ["#{::Spree::Variant.quoted_table_name}.deleted_at IS NULL AND #{::Spree::Variant.quoted_table_name}.is_master = ?", true],
|
57
|
-
:dependent => :destroy
|
60
|
+
has_many :variant_images, :source => :images, :through => :variants_including_master, :order => :position
|
58
61
|
|
59
62
|
accepts_nested_attributes_for :variants, :allow_destroy => true
|
60
63
|
|
61
|
-
def variant_images
|
62
|
-
Image.joins("LEFT JOIN #{Variant.quoted_table_name} ON #{Variant.quoted_table_name}.id = #{Asset.quoted_table_name}.viewable_id").
|
63
|
-
where("(#{Asset.quoted_table_name}.viewable_type = ? AND #{Asset.quoted_table_name}.viewable_id = ?) OR
|
64
|
-
(#{Asset.quoted_table_name}.viewable_type = ? AND #{Asset.quoted_table_name}.viewable_id = ?)", Variant.name, self.master.id, Product.name, self.id).
|
65
|
-
order("#{Asset.quoted_table_name}.position").
|
66
|
-
extend(Spree::Core::RelationSerialization)
|
67
|
-
end
|
68
|
-
|
69
|
-
alias_method :images, :variant_images
|
70
|
-
|
71
64
|
validates :name, :price, :permalink, :presence => true
|
72
65
|
|
73
66
|
attr_accessor :option_values_hash
|
@@ -89,11 +82,12 @@ module Spree
|
|
89
82
|
|
90
83
|
after_initialize :ensure_master
|
91
84
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
85
|
+
def variants_with_only_master
|
86
|
+
ActiveSupport::Deprecation.warn("[SPREE] Spree::Product#variants_with_only_master will be deprecated in Spree 1.3. Please use Spree::Product#master instead.")
|
87
|
+
master
|
95
88
|
end
|
96
89
|
|
90
|
+
|
97
91
|
def to_param
|
98
92
|
permalink.present? ? permalink : (permalink_was || name.to_s.to_url)
|
99
93
|
end
|
@@ -127,6 +121,13 @@ module Spree
|
|
127
121
|
end
|
128
122
|
end
|
129
123
|
|
124
|
+
# override the delete method to set deleted_at value
|
125
|
+
# instead of actually deleting the product.
|
126
|
+
def delete
|
127
|
+
self.update_column(:deleted_at, Time.now)
|
128
|
+
variants_including_master.update_all(:deleted_at => Time.now)
|
129
|
+
end
|
130
|
+
|
130
131
|
# Adding properties and option types on creation based on a chosen prototype
|
131
132
|
attr_reader :prototype_id
|
132
133
|
def prototype_id=(value)
|
@@ -256,6 +257,11 @@ module Spree
|
|
256
257
|
def save_master
|
257
258
|
master.save if master && (master.changed? || master.new_record?)
|
258
259
|
end
|
260
|
+
|
261
|
+
def ensure_master
|
262
|
+
return unless new_record?
|
263
|
+
self.master ||= Variant.new
|
264
|
+
end
|
259
265
|
end
|
260
266
|
end
|
261
267
|
|
@@ -27,11 +27,11 @@ module Spree
|
|
27
27
|
end
|
28
28
|
|
29
29
|
add_search_scope :ascend_by_master_price do
|
30
|
-
joins(:
|
30
|
+
joins(:master).order("#{variant_table_name}.price ASC")
|
31
31
|
end
|
32
32
|
|
33
33
|
add_search_scope :descend_by_master_price do
|
34
|
-
joins(:
|
34
|
+
joins(:master).order("#{variant_table_name}.price DESC")
|
35
35
|
end
|
36
36
|
|
37
37
|
add_search_scope :price_between do |low, high|
|
@@ -50,8 +50,23 @@ module Spree
|
|
50
50
|
# If you need products only within one taxon use
|
51
51
|
#
|
52
52
|
# Spree::Product.taxons_id_eq(x)
|
53
|
+
#
|
54
|
+
# If you're using count on the result of this scope, you must use the
|
55
|
+
# `:distinct` option as well:
|
56
|
+
#
|
57
|
+
# Spree::Product.in_taxon(taxon).count(:distinct => true)
|
58
|
+
#
|
59
|
+
# This is so that the count query is distinct'd:
|
60
|
+
#
|
61
|
+
# SELECT COUNT(DISTINCT "spree_products"."id") ...
|
62
|
+
#
|
63
|
+
# vs.
|
64
|
+
#
|
65
|
+
# SELECT COUNT(*) ...
|
53
66
|
add_search_scope :in_taxon do |taxon|
|
54
|
-
|
67
|
+
select("DISTINCT(spree_products.id), spree_products.*").
|
68
|
+
joins(:taxons).
|
69
|
+
where(Taxon.table_name => { :id => taxon.self_and_descendants.map(&:id) })
|
55
70
|
end
|
56
71
|
|
57
72
|
# This scope selects products in all taxons AND all its descendants
|
@@ -113,7 +128,7 @@ module Spree
|
|
113
128
|
end
|
114
129
|
|
115
130
|
conditions = "#{option_values}.name = ? AND #{option_values}.option_type_id = ?", value, option_type_id
|
116
|
-
joins(:variants_including_master => :option_values).where(conditions)
|
131
|
+
group("spree_products.id").joins(:variants_including_master => :option_values).where(conditions)
|
117
132
|
end
|
118
133
|
|
119
134
|
# Finds all products which have either:
|
@@ -188,11 +203,11 @@ module Spree
|
|
188
203
|
|
189
204
|
add_search_scope :on_hand do
|
190
205
|
variants_table = Variant.table_name
|
191
|
-
where("#{table_name}.id in (select product_id from #{variants_table} where product_id = #{table_name}.id group by product_id having sum(count_on_hand) > 0)")
|
206
|
+
where("#{table_name}.id in (select product_id from #{variants_table} where product_id = #{table_name}.id and #{variants_table}.deleted_at IS NULL group by product_id having sum(count_on_hand) > 0)")
|
192
207
|
end
|
193
208
|
|
194
209
|
add_search_scope :taxons_name_eq do |name|
|
195
|
-
joins(:taxons).where(Taxon.arel_table[:name].eq(name))
|
210
|
+
group("spree_products.id").joins(:taxons).where(Taxon.arel_table[:name].eq(name))
|
196
211
|
end
|
197
212
|
|
198
213
|
if (ActiveRecord::Base.connection.adapter_name == 'PostgreSQL')
|
data/app/models/spree/variant.rb
CHANGED
@@ -58,18 +58,12 @@ module Spree
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
# strips all non-price-like characters from the price.
|
62
61
|
def price=(price)
|
63
|
-
if price.present?
|
64
|
-
self[:price] = price.to_s.gsub(/[^0-9\.-]/, '').to_f
|
65
|
-
end
|
62
|
+
self[:price] = parse_price(price) if price.present?
|
66
63
|
end
|
67
64
|
|
68
|
-
# and cost_price
|
69
65
|
def cost_price=(price)
|
70
|
-
if price.present?
|
71
|
-
self[:cost_price] = price.to_s.gsub(/[^0-9\.-]/, '').to_f
|
72
|
-
end
|
66
|
+
self[:cost_price] = parse_price(price) if price.present?
|
73
67
|
end
|
74
68
|
|
75
69
|
# returns number of units currently on backorder for this variant.
|
@@ -156,6 +150,19 @@ module Spree
|
|
156
150
|
end
|
157
151
|
|
158
152
|
private
|
153
|
+
|
154
|
+
# strips all non-price-like characters from the price, taking into account locale settings
|
155
|
+
def parse_price(price)
|
156
|
+
return price unless price.is_a?(String)
|
157
|
+
|
158
|
+
separator, delimiter = I18n.t([:'number.currency.format.separator', :'number.currency.format.delimiter'])
|
159
|
+
non_price_characters = /[^0-9\-#{separator}]/
|
160
|
+
price.gsub!(non_price_characters, '') # strip everything else first
|
161
|
+
price.gsub!(separator, '.') unless separator == '.' # then replace the locale-specific decimal separator with the standard separator if necessary
|
162
|
+
|
163
|
+
price.to_d
|
164
|
+
end
|
165
|
+
|
159
166
|
# Ensures a new variant takes the product master price when price is not supplied
|
160
167
|
def check_price
|
161
168
|
if price.nil?
|
@@ -169,7 +176,10 @@ module Spree
|
|
169
176
|
end
|
170
177
|
|
171
178
|
def recalculate_product_on_hand
|
172
|
-
|
179
|
+
on_hand = product.on_hand
|
180
|
+
if Spree::Config[:track_inventory_levels] && on_hand != (1.0 / 0) # Infinity
|
181
|
+
product.update_column(:count_on_hand, on_hand)
|
182
|
+
end
|
173
183
|
end
|
174
184
|
end
|
175
185
|
end
|
@@ -3,14 +3,10 @@
|
|
3
3
|
<td><%= t(:filename) %>:</td>
|
4
4
|
<td><%= f.file_field :attachment %></td>
|
5
5
|
</tr>
|
6
|
-
|
7
|
-
<
|
8
|
-
|
9
|
-
|
10
|
-
</tr>
|
11
|
-
<% else %>
|
12
|
-
<%= hidden_field_tag :product_id, @product.id %>
|
13
|
-
<% end %>
|
6
|
+
<tr data-hook="variant">
|
7
|
+
<td><%= Spree::Variant.model_name.human %>:</td>
|
8
|
+
<td><%= f.select :viewable_id, @variants %></td>
|
9
|
+
</tr>
|
14
10
|
<tr data-hook="alt_text">
|
15
11
|
<td><%= t(:alt_text) %>:</td>
|
16
12
|
<td><%= f.text_area :alt %></td>
|