spree_core 2.0.7 → 2.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/helpers/spree/base_helper.rb +5 -2
- data/app/models/spree/adjustment.rb +2 -2
- data/app/models/spree/gateway.rb +1 -1
- data/app/models/spree/inventory_unit.rb +5 -4
- data/app/models/spree/line_item.rb +2 -3
- data/app/models/spree/option_value.rb +1 -1
- data/app/models/spree/order/checkout.rb +4 -0
- data/app/models/spree/order.rb +22 -17
- data/app/models/spree/order_inventory.rb +1 -1
- data/app/models/spree/payment.rb +2 -2
- data/app/models/spree/price.rb +5 -0
- data/app/models/spree/product/scopes.rb +1 -1
- data/app/models/spree/product.rb +3 -3
- data/app/models/spree/promotion.rb +1 -8
- data/app/models/spree/shipment.rb +9 -14
- data/app/models/spree/shipping_method.rb +2 -1
- data/app/models/spree/shipping_rate.rb +4 -0
- data/app/models/spree/stock/estimator.rb +20 -6
- data/app/models/spree/stock/packer.rb +1 -1
- data/app/models/spree/stock/quantifier.rb +11 -2
- data/app/models/spree/stock_item.rb +1 -1
- data/app/models/spree/stock_location.rb +5 -0
- data/app/models/spree/stock_movement.rb +3 -1
- data/app/models/spree/variant.rb +15 -2
- data/app/models/spree/zone.rb +1 -1
- data/config/locales/en.yml +4 -0
- data/db/migrate/20130417120034_add_index_to_source_columns_on_adjustments.rb +5 -0
- data/db/migrate/20131026154747_add_track_inventory_to_variant.rb +5 -0
- data/db/migrate/20140120160805_add_index_to_variant_id_and_currency_on_prices.rb +5 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +8 -3
- data/lib/generators/spree/dummy/templates/rails/database.yml +10 -0
- data/lib/spree/core/delegate_belongs_to.rb +2 -0
- data/lib/spree/core/engine.rb +5 -1
- data/lib/spree/core/permalinks.rb +5 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/i18n.rb +1 -0
- data/lib/spree/money.rb +171 -1
- data/lib/spree/testing_support/capybara_ext.rb +6 -5
- data/lib/spree/testing_support/factories/product_factory.rb +4 -0
- data/lib/spree/testing_support/factories/variant_factory.rb +15 -0
- metadata +147 -158
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 14ac66f9e7ddcb8372dfead29fd08ba8153910c2
|
4
|
+
data.tar.gz: 08206ae70c25c4689dddd12fbab62c82e360fbd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6aa9dadaa97ec4cd19384d095b92f3bad8e6b0378906c1fa2de65dc3423837a066c09bc602aafe532e0ba11a9cfae36ef8d8887f44f1ebede67d5f922c77fa34
|
7
|
+
data.tar.gz: 4d405953434dafed6a819848cc601c2b718d971cb89ff3e9e4413a7692b1f99902f4502a9d56ee870020fa6f61328ac41980d3087f8f793fc67467137d9119a4
|
@@ -34,7 +34,7 @@ module Spree
|
|
34
34
|
v.options_text
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
37
|
+
def meta_data
|
38
38
|
object = instance_variable_get('@'+controller_name.singularize)
|
39
39
|
meta = {}
|
40
40
|
|
@@ -51,8 +51,11 @@ module Spree
|
|
51
51
|
keywords: Spree::Config[:default_meta_keywords],
|
52
52
|
description: Spree::Config[:default_meta_description]
|
53
53
|
})
|
54
|
+
meta
|
55
|
+
end
|
54
56
|
|
55
|
-
|
57
|
+
def meta_data_tags
|
58
|
+
meta_data.map do |name, content|
|
56
59
|
tag('meta', name: name, content: content)
|
57
60
|
end.join("\n")
|
58
61
|
end
|
@@ -55,8 +55,8 @@ module Spree
|
|
55
55
|
scope :shipping, -> { where(originator_type: 'Spree::ShippingMethod') }
|
56
56
|
scope :optional, -> { where(mandatory: false) }
|
57
57
|
scope :eligible, -> { where(eligible: true) }
|
58
|
-
scope :charge, -> { where(
|
59
|
-
scope :credit, -> { where(
|
58
|
+
scope :charge, -> { where("#{quoted_table_name}.amount >= 0") }
|
59
|
+
scope :credit, -> { where("#{quoted_table_name}.amount < 0") }
|
60
60
|
scope :promotion, -> { where(originator_type: 'Spree::PromotionAction') }
|
61
61
|
scope :return_authorization, -> { where(source_type: "Spree::ReturnAuthorization") }
|
62
62
|
|
data/app/models/spree/gateway.rb
CHANGED
@@ -2,16 +2,17 @@ module Spree
|
|
2
2
|
class InventoryUnit < ActiveRecord::Base
|
3
3
|
belongs_to :variant, class_name: "Spree::Variant"
|
4
4
|
belongs_to :order, class_name: "Spree::Order"
|
5
|
-
belongs_to :shipment, class_name: "Spree::Shipment"
|
5
|
+
belongs_to :shipment, class_name: "Spree::Shipment", touch: true
|
6
6
|
belongs_to :return_authorization, class_name: "Spree::ReturnAuthorization"
|
7
7
|
|
8
8
|
scope :backordered, -> { where state: 'backordered' }
|
9
9
|
scope :shipped, -> { where state: 'shipped' }
|
10
10
|
scope :backordered_per_variant, ->(stock_item) do
|
11
|
-
includes(:shipment)
|
11
|
+
includes(:shipment, :order)
|
12
12
|
.where("spree_shipments.state != 'canceled'")
|
13
13
|
.where(variant_id: stock_item.variant_id)
|
14
|
-
.
|
14
|
+
.where('spree_orders.completed_at is not null')
|
15
|
+
.backordered.order("spree_orders.completed_at ASC")
|
15
16
|
end
|
16
17
|
|
17
18
|
attr_accessible :shipment, :variant_id
|
@@ -36,7 +37,7 @@ module Spree
|
|
36
37
|
# lead to issues once users tried to modify the objects returned. That's due
|
37
38
|
# to ActiveRecord `joins(shipment: :stock_location)` only return readonly
|
38
39
|
# objects
|
39
|
-
#
|
40
|
+
#
|
40
41
|
# Returns an array of backordered inventory units as per a given stock item
|
41
42
|
def self.backordered_for_stock_item(stock_item)
|
42
43
|
backordered_per_variant(stock_item).select do |unit|
|
@@ -22,12 +22,11 @@ module Spree
|
|
22
22
|
|
23
23
|
attr_accessible :quantity, :variant_id
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
after_save :update_inventory
|
27
26
|
after_save :update_order
|
28
27
|
after_destroy :update_order
|
29
28
|
|
30
|
-
delegate :name, :description, to: :variant
|
29
|
+
delegate :name, :description, :should_track_inventory?, to: :variant
|
31
30
|
|
32
31
|
attr_accessor :target_shipment
|
33
32
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Spree
|
2
2
|
class OptionValue < ActiveRecord::Base
|
3
|
-
belongs_to :option_type
|
3
|
+
belongs_to :option_type, :class_name => 'Spree::OptionType', :touch => true
|
4
4
|
acts_as_list scope: :option_type
|
5
5
|
has_and_belongs_to_many :variants, join_table: 'spree_option_values_variants', class_name: "Spree::Variant"
|
6
6
|
|
@@ -145,6 +145,10 @@ module Spree
|
|
145
145
|
@checkout_steps ||= {}
|
146
146
|
end
|
147
147
|
|
148
|
+
def self.checkout_step_names
|
149
|
+
self.checkout_steps.keys
|
150
|
+
end
|
151
|
+
|
148
152
|
def self.add_transition(options)
|
149
153
|
self.next_event_transitions << { options.delete(:from) => options.delete(:to) }.merge(options)
|
150
154
|
end
|
data/app/models/spree/order.rb
CHANGED
@@ -28,7 +28,7 @@ module Spree
|
|
28
28
|
|
29
29
|
attr_accessible :line_items, :bill_address_attributes, :ship_address_attributes,
|
30
30
|
:payments_attributes, :ship_address, :bill_address, :currency,
|
31
|
-
:line_items_attributes, :number, :email, :use_billing,
|
31
|
+
:line_items_attributes, :number, :email, :use_billing,
|
32
32
|
:special_instructions, :shipments_attributes, :coupon_code
|
33
33
|
|
34
34
|
attr_reader :coupon_code
|
@@ -103,7 +103,7 @@ module Spree
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def self.complete
|
106
|
-
where(
|
106
|
+
where("#{quoted_table_name}.completed_at IS NOT NULL")
|
107
107
|
end
|
108
108
|
|
109
109
|
def self.incomplete
|
@@ -172,11 +172,12 @@ module Spree
|
|
172
172
|
|
173
173
|
# If true, causes the confirmation step to happen during the checkout process
|
174
174
|
def confirmation_required?
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
175
|
+
Spree::Config[:always_include_confirm_step] ||
|
176
|
+
payments.valid.map(&:payment_method).compact.any?(&:payment_profiles_supported?) ||
|
177
|
+
# Little hacky fix for #4117
|
178
|
+
# If this wasn't here, order would transition to address state on confirm failure
|
179
|
+
# because there would be no valid payments any more.
|
180
|
+
state == 'confirm'
|
180
181
|
end
|
181
182
|
|
182
183
|
# Indicates the number of items in the order
|
@@ -401,7 +402,7 @@ module Spree
|
|
401
402
|
end
|
402
403
|
|
403
404
|
def available_payment_methods
|
404
|
-
@available_payment_methods ||= PaymentMethod.available(:front_end)
|
405
|
+
@available_payment_methods ||= (PaymentMethod.available(:front_end) + PaymentMethod.available(:both)).uniq
|
405
406
|
end
|
406
407
|
|
407
408
|
def pending_payments
|
@@ -498,12 +499,15 @@ module Spree
|
|
498
499
|
state = "#{name}_state"
|
499
500
|
if persisted?
|
500
501
|
old_state = self.send("#{state}_was")
|
501
|
-
self.
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
502
|
+
new_state = self.send(state)
|
503
|
+
unless old_state == new_state
|
504
|
+
self.state_changes.create({
|
505
|
+
previous_state: old_state,
|
506
|
+
next_state: new_state,
|
507
|
+
name: name,
|
508
|
+
user_id: self.user_id
|
509
|
+
}, :without_protection => true)
|
510
|
+
end
|
507
511
|
end
|
508
512
|
end
|
509
513
|
|
@@ -545,7 +549,7 @@ module Spree
|
|
545
549
|
#
|
546
550
|
# At some point the might need to force the order to transition from address
|
547
551
|
# to delivery again so that proper updated shipments are created.
|
548
|
-
# e.g. customer goes back from payment step and changes order items
|
552
|
+
# e.g. customer goes back from payment step and changes order items
|
549
553
|
def ensure_updated_shipments
|
550
554
|
if shipments.any?
|
551
555
|
self.shipments.destroy_all
|
@@ -565,7 +569,7 @@ module Spree
|
|
565
569
|
|
566
570
|
# Determine if email is required (we don't want validation errors before we hit the checkout)
|
567
571
|
def require_email
|
568
|
-
return true unless new_record? or
|
572
|
+
return true unless new_record? or ['cart', 'address'].include?(state)
|
569
573
|
end
|
570
574
|
|
571
575
|
def ensure_line_items_present
|
@@ -594,9 +598,10 @@ module Spree
|
|
594
598
|
|
595
599
|
def after_cancel
|
596
600
|
shipments.each { |shipment| shipment.cancel! }
|
601
|
+
payments.completed.each { |payment| payment.credit! }
|
597
602
|
|
598
603
|
send_cancel_email
|
599
|
-
self.payment_state
|
604
|
+
self.update_column(:payment_state, 'credit_owed') unless shipped?
|
600
605
|
end
|
601
606
|
|
602
607
|
def send_cancel_email
|
@@ -65,7 +65,7 @@ module Spree
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def add_to_shipment(shipment, variant, quantity)
|
68
|
-
if
|
68
|
+
if variant.should_track_inventory?
|
69
69
|
on_hand, back_order = shipment.stock_location.fill_status(variant, quantity)
|
70
70
|
|
71
71
|
on_hand.times { shipment.set_up_inventory('on_hand', variant, order) }
|
data/app/models/spree/payment.rb
CHANGED
@@ -4,7 +4,7 @@ module Spree
|
|
4
4
|
|
5
5
|
IDENTIFIER_CHARS = (('A'..'Z').to_a + ('0'..'9').to_a - %w(0 1 I O)).freeze
|
6
6
|
|
7
|
-
belongs_to :order, class_name: 'Spree::Order'
|
7
|
+
belongs_to :order, class_name: 'Spree::Order', touch: true
|
8
8
|
belongs_to :source, polymorphic: true
|
9
9
|
belongs_to :payment_method, class_name: 'Spree::PaymentMethod'
|
10
10
|
|
@@ -31,7 +31,7 @@ module Spree
|
|
31
31
|
scope :completed, with_state('completed')
|
32
32
|
scope :pending, with_state('pending')
|
33
33
|
scope :failed, with_state('failed')
|
34
|
-
scope :valid, where(
|
34
|
+
scope :valid, where("#{quoted_table_name}.state NOT IN (?)", %w(failed invalid))
|
35
35
|
|
36
36
|
after_rollback :persist_invalid
|
37
37
|
|
data/app/models/spree/price.rb
CHANGED
@@ -24,6 +24,11 @@ module Spree
|
|
24
24
|
self[:amount] = parse_price(price)
|
25
25
|
end
|
26
26
|
|
27
|
+
# Remove variant default_scope `deleted_at: nil`
|
28
|
+
def variant
|
29
|
+
Spree::Variant.unscoped { super }
|
30
|
+
end
|
31
|
+
|
27
32
|
private
|
28
33
|
def check_price
|
29
34
|
raise "Price must belong to a variant" if variant.nil?
|
@@ -24,7 +24,7 @@ module Spree
|
|
24
24
|
next if name.to_s.include?("master_price")
|
25
25
|
parts = name.to_s.match(/(.*)_by_(.*)/)
|
26
26
|
order_text = "#{Product.quoted_table_name}.#{parts[2]} #{parts[1] == 'ascend' ? "ASC" : "DESC"}"
|
27
|
-
self.scope(name.to_s,
|
27
|
+
self.scope(name.to_s, order(order_text))
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
data/app/models/spree/product.rb
CHANGED
@@ -220,10 +220,10 @@ module Spree
|
|
220
220
|
end
|
221
221
|
|
222
222
|
def total_on_hand
|
223
|
-
if
|
224
|
-
self.stock_items.sum(&:count_on_hand)
|
225
|
-
else
|
223
|
+
if self.variants_including_master.any? { |v| !v.should_track_inventory? }
|
226
224
|
Float::INFINITY
|
225
|
+
else
|
226
|
+
self.stock_items.sum(&:count_on_hand)
|
227
227
|
end
|
228
228
|
end
|
229
229
|
|
@@ -26,13 +26,6 @@ module Spree
|
|
26
26
|
validates :path, presence: true, if: lambda{|r| r.event_name == 'spree.content.visited' }
|
27
27
|
validates :usage_limit, numericality: { greater_than: 0, allow_nil: true }
|
28
28
|
|
29
|
-
# TODO: This shouldn't be necessary with :autosave option but nested attribute updating of actions is broken without it
|
30
|
-
after_save :save_rules_and_actions
|
31
|
-
|
32
|
-
def save_rules_and_actions
|
33
|
-
(rules + actions).each &:save
|
34
|
-
end
|
35
|
-
|
36
29
|
def self.advertised
|
37
30
|
where(advertise: true)
|
38
31
|
end
|
@@ -96,7 +89,7 @@ module Spree
|
|
96
89
|
end
|
97
90
|
|
98
91
|
def credits
|
99
|
-
Adjustment.promotion.where(originator_id: actions.map(&:id))
|
92
|
+
Adjustment.eligible.promotion.where(originator_id: actions.map(&:id))
|
100
93
|
end
|
101
94
|
|
102
95
|
def credits_count
|
@@ -2,7 +2,7 @@ require 'ostruct'
|
|
2
2
|
|
3
3
|
module Spree
|
4
4
|
class Shipment < ActiveRecord::Base
|
5
|
-
belongs_to :order, class_name: 'Spree::Order'
|
5
|
+
belongs_to :order, class_name: 'Spree::Order', touch: true
|
6
6
|
belongs_to :address, class_name: 'Spree::Address'
|
7
7
|
belongs_to :stock_location, class_name: 'Spree::StockLocation'
|
8
8
|
|
@@ -12,7 +12,6 @@ module Spree
|
|
12
12
|
has_many :inventory_units, dependent: :delete_all
|
13
13
|
has_one :adjustment, as: :source, dependent: :destroy
|
14
14
|
|
15
|
-
before_create :generate_shipment_number
|
16
15
|
after_save :ensure_correct_adjustment, :update_order
|
17
16
|
|
18
17
|
attr_accessor :special_instructions
|
@@ -22,7 +21,7 @@ module Spree
|
|
22
21
|
accepts_nested_attributes_for :address
|
23
22
|
accepts_nested_attributes_for :inventory_units
|
24
23
|
|
25
|
-
make_permalink field: :number
|
24
|
+
make_permalink field: :number, length: 11, prefix: 'H'
|
26
25
|
|
27
26
|
scope :shipped, -> { with_state('shipped') }
|
28
27
|
scope :ready, -> { with_state('ready') }
|
@@ -166,8 +165,8 @@ module Spree
|
|
166
165
|
end
|
167
166
|
|
168
167
|
def line_items
|
169
|
-
if order.complete? and Spree::Config
|
170
|
-
order.line_items.select { |li| inventory_units.pluck(:variant_id).include?(li.variant_id) }
|
168
|
+
if order.complete? and Spree::Config.track_inventory_levels
|
169
|
+
order.line_items.select { |li| !li.should_track_inventory? || inventory_units.pluck(:variant_id).include?(li.variant_id) }
|
171
170
|
else
|
172
171
|
order.line_items
|
173
172
|
end
|
@@ -243,17 +242,13 @@ module Spree
|
|
243
242
|
end
|
244
243
|
|
245
244
|
def manifest_restock(item)
|
246
|
-
|
247
|
-
|
245
|
+
if item.states["on_hand"].to_i > 0
|
246
|
+
stock_location.restock item.variant, item.states["on_hand"], self
|
247
|
+
end
|
248
248
|
|
249
|
-
|
250
|
-
|
251
|
-
record = true
|
252
|
-
while record
|
253
|
-
random = "H#{Array.new(11) { rand(9) }.join}"
|
254
|
-
record = self.class.where(number: random).first
|
249
|
+
if item.states["backordered"].to_i > 0
|
250
|
+
stock_location.restock_backordered item.variant, item.states["backordered"]
|
255
251
|
end
|
256
|
-
self.number = random
|
257
252
|
end
|
258
253
|
|
259
254
|
def description_for_shipping_charge
|
@@ -43,7 +43,8 @@ module Spree
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def build_tracking_url(tracking)
|
46
|
-
|
46
|
+
return if tracking.blank? || tracking_url.blank?
|
47
|
+
tracking_url.gsub(/:tracking/, ERB::Util.url_encode(tracking)) # :url_encode exists in 1.8.7 through 2.1.0
|
47
48
|
end
|
48
49
|
|
49
50
|
def self.calculators
|
@@ -15,7 +15,8 @@ module Spree
|
|
15
15
|
|
16
16
|
shipping_methods.each do |shipping_method|
|
17
17
|
cost = calculate_cost(shipping_method, package)
|
18
|
-
|
18
|
+
rate = shipping_method.shipping_rates.new(:cost => cost) unless cost.nil?
|
19
|
+
shipping_rates << rate unless rate.nil?
|
19
20
|
end
|
20
21
|
|
21
22
|
shipping_rates.sort_by! { |r| r.cost || 0 }
|
@@ -34,17 +35,30 @@ module Spree
|
|
34
35
|
end
|
35
36
|
|
36
37
|
private
|
38
|
+
|
37
39
|
def shipping_methods(package)
|
38
|
-
shipping_methods
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
package.shipping_methods.select do |ship_method|
|
41
|
+
calculator = ship_method.calculator
|
42
|
+
begin
|
43
|
+
calculator.available?(package) &&
|
44
|
+
ship_method.include?(order.ship_address) &&
|
45
|
+
(calculator.preferences[:currency].nil? ||
|
46
|
+
calculator.preferences[:currency] == currency)
|
47
|
+
rescue Exception => exception
|
48
|
+
log_calculator_exception(ship_method, exception)
|
49
|
+
end
|
50
|
+
end
|
43
51
|
end
|
44
52
|
|
45
53
|
def calculate_cost(shipping_method, package)
|
46
54
|
shipping_method.calculator.compute(package)
|
47
55
|
end
|
56
|
+
|
57
|
+
def log_calculator_exception(ship_method, exception)
|
58
|
+
Rails.logger.error("Something went wrong calculating rates with the #{ship_method.name} (ID=#{ship_method.id}) shipping method.")
|
59
|
+
Rails.logger.error("*" * 50)
|
60
|
+
Rails.logger.error(exception.backtrace.join("\n"))
|
61
|
+
end
|
48
62
|
end
|
49
63
|
end
|
50
64
|
end
|
@@ -20,7 +20,7 @@ module Spree
|
|
20
20
|
def default_package
|
21
21
|
package = Package.new(stock_location, order)
|
22
22
|
order.line_items.each do |line_item|
|
23
|
-
if
|
23
|
+
if line_item.should_track_inventory?
|
24
24
|
next unless stock_location.stock_item(line_item.variant)
|
25
25
|
|
26
26
|
on_hand, backordered = stock_location.fill_status(line_item.variant, line_item.quantity)
|
@@ -4,12 +4,12 @@ module Spree
|
|
4
4
|
attr_reader :stock_items
|
5
5
|
|
6
6
|
def initialize(variant)
|
7
|
-
@variant = variant
|
7
|
+
@variant = resolve_variant_id(variant)
|
8
8
|
@stock_items = Spree::StockItem.joins(:stock_location).where(:variant_id => @variant, Spree::StockLocation.table_name =>{ :active => true})
|
9
9
|
end
|
10
10
|
|
11
11
|
def total_on_hand
|
12
|
-
if
|
12
|
+
if @variant.should_track_inventory?
|
13
13
|
stock_items.sum(:count_on_hand)
|
14
14
|
else
|
15
15
|
Float::INFINITY
|
@@ -23,6 +23,15 @@ module Spree
|
|
23
23
|
def can_supply?(required)
|
24
24
|
total_on_hand >= required || backorderable?
|
25
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# return variant when passed either variant object or variant id
|
30
|
+
def resolve_variant_id(variant)
|
31
|
+
variant = Spree::Variant.find_by_id(variant) unless variant.respond_to?(:should_track_inventory?)
|
32
|
+
variant
|
33
|
+
end
|
34
|
+
|
26
35
|
end
|
27
36
|
end
|
28
37
|
end
|
@@ -11,7 +11,7 @@ module Spree
|
|
11
11
|
|
12
12
|
attr_accessible :count_on_hand, :variant, :stock_location, :backorderable, :variant_id
|
13
13
|
|
14
|
-
delegate :weight, to: :variant
|
14
|
+
delegate :weight, :should_track_inventory?, to: :variant
|
15
15
|
|
16
16
|
def backordered_inventory_units
|
17
17
|
Spree::InventoryUnit.backordered_for_stock_item(self)
|
@@ -48,6 +48,11 @@ module Spree
|
|
48
48
|
move(variant, quantity, originator)
|
49
49
|
end
|
50
50
|
|
51
|
+
def restock_backordered(variant, quantity, originator = nil)
|
52
|
+
item = stock_item_or_create(variant)
|
53
|
+
item.update_column(:count_on_hand, item.count_on_hand + quantity)
|
54
|
+
end
|
55
|
+
|
51
56
|
def unstock(variant, quantity, originator = nil)
|
52
57
|
move(variant, -quantity, originator)
|
53
58
|
end
|
@@ -17,10 +17,12 @@ module Spree
|
|
17
17
|
end
|
18
18
|
|
19
19
|
private
|
20
|
+
|
20
21
|
def update_stock_item_quantity
|
21
|
-
return unless
|
22
|
+
return unless self.stock_item.should_track_inventory?
|
22
23
|
stock_item.adjust_count_on_hand quantity
|
23
24
|
end
|
25
|
+
|
24
26
|
end
|
25
27
|
end
|
26
28
|
|
data/app/models/spree/variant.rb
CHANGED
@@ -11,7 +11,8 @@ module Spree
|
|
11
11
|
attr_accessible :name, :presentation, :cost_price, :lock_version,
|
12
12
|
:position, :option_value_ids,
|
13
13
|
:product_id, :option_values_attributes, :price,
|
14
|
-
:weight, :height, :width, :depth, :sku, :cost_currency
|
14
|
+
:weight, :height, :width, :depth, :sku, :cost_currency,
|
15
|
+
:track_inventory, :options
|
15
16
|
|
16
17
|
has_many :inventory_units
|
17
18
|
has_many :line_items
|
@@ -44,7 +45,7 @@ module Spree
|
|
44
45
|
after_create :set_position
|
45
46
|
|
46
47
|
# default variant scope only lists non-deleted variants
|
47
|
-
scope :deleted, lambda { where(
|
48
|
+
scope :deleted, lambda { where("#{quoted_table_name}.deleted_at IS NOT NULL") }
|
48
49
|
|
49
50
|
def self.active(currency = nil)
|
50
51
|
joins(:prices).where(deleted_at: nil).where('spree_prices.currency' => currency || Spree::Config[:currency]).where('spree_prices.amount IS NOT NULL')
|
@@ -80,6 +81,12 @@ module Spree
|
|
80
81
|
deleted_at
|
81
82
|
end
|
82
83
|
|
84
|
+
def options=(options = {})
|
85
|
+
options.each do |option|
|
86
|
+
set_option_value(option[:name], option[:value])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
83
90
|
def set_option_value(opt_name, opt_value)
|
84
91
|
# no option values on master
|
85
92
|
return if self.is_master
|
@@ -146,6 +153,12 @@ module Spree
|
|
146
153
|
Spree::Product.unscoped { super }
|
147
154
|
end
|
148
155
|
|
156
|
+
# Shortcut method to determine if inventory tracking is enabled for this variant
|
157
|
+
# This considers both variant tracking flag and site-wide inventory tracking settings
|
158
|
+
def should_track_inventory?
|
159
|
+
self.track_inventory? && Spree::Config.track_inventory_levels
|
160
|
+
end
|
161
|
+
|
149
162
|
private
|
150
163
|
# strips all non-price-like characters from the price, taking into account locale settings
|
151
164
|
def parse_price(price)
|
data/app/models/spree/zone.rb
CHANGED
@@ -133,7 +133,7 @@ module Spree
|
|
133
133
|
|
134
134
|
def remove_defunct_members
|
135
135
|
if zone_members.any?
|
136
|
-
zone_members.where('zoneable_id IS NULL OR zoneable_type != ?', "Spree::#{kind.
|
136
|
+
zone_members.where('zoneable_id IS NULL OR zoneable_type != ?', "Spree::#{kind.classify}").destroy_all
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
data/config/locales/en.yml
CHANGED
@@ -702,6 +702,7 @@ en:
|
|
702
702
|
no_rules_added: No rules added
|
703
703
|
no_resource_found: ! 'No %{resource} found'
|
704
704
|
no_shipping_methods_found: No shipping methods found
|
705
|
+
no_eligible_shipping_methods_found: No eligible shipping methods found
|
705
706
|
no_trackers_found: No Trackers Found
|
706
707
|
no_stock_locations_found: No stock locations found
|
707
708
|
no_tracking_present: No tracking details provided.
|
@@ -954,6 +955,7 @@ en:
|
|
954
955
|
shipment_state: Shipment State
|
955
956
|
shipment_states:
|
956
957
|
backorder: backorder
|
958
|
+
canceled: canceled
|
957
959
|
partial: partial
|
958
960
|
pending: pending
|
959
961
|
ready: ready
|
@@ -1052,6 +1054,8 @@ en:
|
|
1052
1054
|
time: Time
|
1053
1055
|
to_add_variants_you_must_first_define: To add variants, you must first define
|
1054
1056
|
total: Total
|
1057
|
+
total_price: Total price
|
1058
|
+
track_inventory: Track Inventory
|
1055
1059
|
tracking: Tracking
|
1056
1060
|
tracking_number: Tracking Number
|
1057
1061
|
tracking_url: Tracking URL
|
@@ -53,9 +53,9 @@ module Spree
|
|
53
53
|
def test_dummy_inject_extension_requirements
|
54
54
|
if DummyGeneratorHelper.inject_extension_requirements
|
55
55
|
inside dummy_path do
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
inject_require_for('spree_frontend') if Object.const_defined?("Spree::Frontend")
|
57
|
+
inject_require_for('spree_backend') if Object.const_defined?("Spree::Backend")
|
58
|
+
inject_require_for('spree_api') if Object.const_defined?("Spree::Api")
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -82,6 +82,11 @@ module Spree
|
|
82
82
|
attr :database
|
83
83
|
|
84
84
|
protected
|
85
|
+
|
86
|
+
def inject_require_for(requirement)
|
87
|
+
inject_into_file 'config/application.rb', "require '#{requirement}'\n", :before => /require '#{@lib_name}'/, :verbose => true
|
88
|
+
end
|
89
|
+
|
85
90
|
def dummy_path
|
86
91
|
ENV['DUMMY_PATH'] || 'spec/dummy'
|
87
92
|
end
|