spree_core 2.2.14 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/{spree.js.coffee → spree.js.coffee.erb} +11 -2
  3. data/app/controllers/spree/base_controller.rb +1 -0
  4. data/app/helpers/spree/base_helper.rb +5 -6
  5. data/app/helpers/spree/orders_helper.rb +4 -0
  6. data/app/helpers/spree/products_helper.rb +8 -7
  7. data/app/mailers/spree/base_mailer.rb +2 -2
  8. data/app/mailers/spree/order_mailer.rb +2 -2
  9. data/app/mailers/spree/shipment_mailer.rb +1 -1
  10. data/app/mailers/spree/test_mailer.rb +1 -1
  11. data/app/models/spree/ability.rb +15 -16
  12. data/app/models/spree/address.rb +3 -6
  13. data/app/models/spree/adjustment.rb +2 -2
  14. data/app/models/spree/alert.rb +1 -1
  15. data/app/models/spree/app_configuration.rb +17 -20
  16. data/app/models/spree/asset.rb +2 -2
  17. data/app/models/spree/base.rb +9 -0
  18. data/app/models/spree/calculator.rb +1 -1
  19. data/app/models/spree/calculator/flat_rate.rb +1 -1
  20. data/app/models/spree/calculator/flexi_rate.rb +1 -1
  21. data/app/models/spree/calculator/price_sack.rb +1 -3
  22. data/app/models/spree/calculator/shipping/flat_rate.rb +1 -1
  23. data/app/models/spree/calculator/shipping/flexi_rate.rb +1 -1
  24. data/app/models/spree/calculator/shipping/per_item.rb +1 -1
  25. data/app/models/spree/calculator/shipping/price_sack.rb +1 -3
  26. data/app/models/spree/classification.rb +1 -1
  27. data/app/models/spree/configuration.rb +1 -1
  28. data/app/models/spree/country.rb +1 -1
  29. data/app/models/spree/credit_card.rb +8 -12
  30. data/app/models/spree/gateway.rb +0 -3
  31. data/app/models/spree/gateway/bogus.rb +2 -3
  32. data/app/models/spree/image.rb +3 -1
  33. data/app/models/spree/inventory_unit.rb +5 -6
  34. data/app/models/spree/item_adjustments.rb +3 -4
  35. data/app/models/spree/legacy_user.rb +1 -1
  36. data/app/models/spree/line_item.rb +6 -13
  37. data/app/models/spree/log_entry.rb +1 -1
  38. data/app/models/spree/option_type.rb +1 -1
  39. data/app/models/spree/option_value.rb +1 -3
  40. data/app/models/spree/order.rb +52 -70
  41. data/app/models/spree/order/checkout.rb +17 -10
  42. data/app/models/spree/order/currency_updater.rb +1 -1
  43. data/app/models/spree/order_contents.rb +7 -4
  44. data/app/models/spree/order_populator.rb +1 -1
  45. data/app/models/spree/order_updater.rb +8 -21
  46. data/app/models/spree/payment.rb +26 -12
  47. data/app/models/spree/payment/processing.rb +5 -16
  48. data/app/models/spree/payment_capture_event.rb +1 -1
  49. data/app/models/spree/payment_method.rb +2 -2
  50. data/app/models/spree/payment_method/check.rb +0 -2
  51. data/app/models/spree/preference.rb +1 -31
  52. data/app/models/spree/preferences/configuration.rb +2 -6
  53. data/app/models/spree/preferences/preferable.rb +46 -74
  54. data/app/models/spree/preferences/preferable_class_methods.rb +11 -46
  55. data/app/models/spree/preferences/scoped_store.rb +33 -0
  56. data/app/models/spree/preferences/store.rb +8 -7
  57. data/app/models/spree/price.rb +1 -3
  58. data/app/models/spree/product.rb +59 -87
  59. data/app/models/spree/product/scopes.rb +22 -13
  60. data/app/models/spree/product_option_type.rb +1 -1
  61. data/app/models/spree/product_property.rb +1 -3
  62. data/app/models/spree/product_scope/scopes.rb +1 -1
  63. data/app/models/spree/promotion.rb +4 -5
  64. data/app/models/spree/promotion/actions/create_adjustment.rb +11 -2
  65. data/app/models/spree/promotion/actions/create_item_adjustments.rb +19 -2
  66. data/app/models/spree/promotion/actions/create_line_items.rb +2 -12
  67. data/app/models/spree/promotion/rules/user.rb +5 -1
  68. data/app/models/spree/promotion_action.rb +1 -1
  69. data/app/models/spree/promotion_action_line_item.rb +1 -1
  70. data/app/models/spree/promotion_handler/cart.rb +2 -14
  71. data/app/models/spree/promotion_handler/coupon.rb +3 -13
  72. data/app/models/spree/promotion_rule.rb +1 -1
  73. data/app/models/spree/property.rb +1 -3
  74. data/app/models/spree/prototype.rb +1 -1
  75. data/app/models/spree/return_authorization.rb +4 -10
  76. data/app/models/spree/role.rb +1 -1
  77. data/app/models/spree/shipment.rb +1 -9
  78. data/app/models/spree/shipping_category.rb +3 -3
  79. data/app/models/spree/shipping_method.rb +1 -1
  80. data/app/models/spree/shipping_method_category.rb +2 -2
  81. data/app/models/spree/shipping_rate.rb +3 -3
  82. data/app/models/spree/state.rb +1 -1
  83. data/app/models/spree/state_change.rb +1 -1
  84. data/app/models/spree/stock/availability_validator.rb +7 -3
  85. data/app/models/spree/stock/package.rb +0 -23
  86. data/app/models/spree/stock/splitter/backordered.rb +1 -1
  87. data/app/models/spree/stock/splitter/shipping_category.rb +1 -1
  88. data/app/models/spree/stock/splitter/weight.rb +1 -1
  89. data/app/models/spree/stock_item.rb +7 -10
  90. data/app/models/spree/stock_location.rb +2 -6
  91. data/app/models/spree/stock_movement.rb +1 -3
  92. data/app/models/spree/stock_transfer.rb +1 -3
  93. data/app/models/spree/store.rb +33 -0
  94. data/app/models/spree/tax_category.rb +2 -2
  95. data/app/models/spree/tax_rate.rb +21 -52
  96. data/app/models/spree/taxon.rb +9 -8
  97. data/app/models/spree/taxonomy.rb +1 -1
  98. data/app/models/spree/tracker.rb +1 -1
  99. data/app/models/spree/variant.rb +13 -15
  100. data/app/models/spree/variant/scopes.rb +1 -1
  101. data/app/models/spree/zone.rb +22 -22
  102. data/app/models/spree/zone_member.rb +2 -2
  103. data/config/initializers/user_class_extensions.rb +0 -8
  104. data/config/locales/en.yml +7 -42
  105. data/db/default/spree/countries.rb +2 -3
  106. data/db/default/spree/stores.rb +9 -0
  107. data/db/migrate/20130611054351_rename_shipping_methods_zones_to_spree_shipping_methods_zones.rb +0 -5
  108. data/db/migrate/20130807024301_upgrade_adjustments.rb +4 -5
  109. data/db/migrate/20130807024302_rename_adjustment_fields.rb +5 -2
  110. data/db/migrate/20131118183431_add_line_item_id_to_spree_inventory_units.rb +1 -1
  111. data/db/migrate/20140106065820_remove_value_type_from_spree_preferences.rb +8 -0
  112. data/db/migrate/20140227112348_add_preference_store_to_everything.rb +8 -0
  113. data/db/migrate/20140309023735_migrate_old_preferences.rb +23 -0
  114. data/db/migrate/20140309024355_create_spree_stores.rb +25 -0
  115. data/db/migrate/20140309033438_create_store_from_preferences.rb +30 -0
  116. data/db/migrate/20140315053743_add_timestamps_to_spree_assets.rb +6 -0
  117. data/db/migrate/20140331100557_add_additional_store_fields.rb +8 -0
  118. data/db/migrate/20140410141842_add_many_missing_indexes.rb +18 -0
  119. data/db/migrate/20140410150358_correct_some_polymorphic_index_and_add_more_missing.rb +66 -0
  120. data/db/migrate/20140508151342_change_spree_price_amount_precision.rb +1 -1
  121. data/db/migrate/20140518174634_add_token_to_spree_orders.rb +5 -0
  122. data/db/migrate/20140530024945_move_order_token_from_tokenized_permission.rb +29 -0
  123. data/db/migrate/20140601011216_set_shipment_total_for_users_upgrading.rb +5 -3
  124. data/db/migrate/20140604135309_drop_credit_card_first_name_and_last_name.rb +6 -0
  125. data/lib/generators/spree/dummy/dummy_generator.rb +1 -0
  126. data/lib/generators/spree/dummy/templates/initializers/devise.rb +3 -0
  127. data/lib/generators/spree/dummy/templates/rails/routes.rb +0 -1
  128. data/lib/generators/spree/install/install_generator.rb +8 -17
  129. data/lib/generators/spree/install/templates/config/initializers/spree.rb +2 -2
  130. data/lib/spree/core.rb +13 -9
  131. data/lib/spree/core/calculated_adjustments.rb +1 -1
  132. data/lib/spree/core/controller_helpers/auth.rb +27 -18
  133. data/lib/spree/core/controller_helpers/common.rb +2 -2
  134. data/lib/spree/core/controller_helpers/order.rb +15 -24
  135. data/lib/spree/core/controller_helpers/store.rb +19 -0
  136. data/lib/spree/core/delegate_belongs_to.rb +2 -2
  137. data/lib/spree/core/engine.rb +0 -10
  138. data/lib/spree/core/importer.rb +1 -0
  139. data/lib/spree/core/importer/order.rb +16 -44
  140. data/lib/spree/core/importer/product.rb +62 -0
  141. data/lib/spree/core/product_filters.rb +0 -4
  142. data/lib/spree/core/routes.rb +4 -6
  143. data/lib/spree/core/validators/email.rb +23 -1
  144. data/lib/spree/core/version.rb +1 -1
  145. data/lib/spree/money.rb +1 -169
  146. data/lib/spree/permitted_attributes.rb +6 -4
  147. data/lib/spree/testing_support/authorization_helpers.rb +23 -21
  148. data/lib/spree/testing_support/capybara_ext.rb +11 -21
  149. data/lib/spree/testing_support/common_rake.rb +3 -1
  150. data/lib/spree/testing_support/controller_requests.rb +0 -2
  151. data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
  152. data/lib/spree/testing_support/factories/line_item_factory.rb +4 -1
  153. data/lib/spree/testing_support/factories/order_factory.rb +5 -4
  154. data/lib/spree/testing_support/factories/product_factory.rb +0 -4
  155. data/lib/spree/testing_support/factories/promotion_factory.rb +5 -7
  156. data/lib/spree/testing_support/factories/shipment_factory.rb +0 -1
  157. data/lib/spree/testing_support/factories/stock_factory.rb +2 -2
  158. data/lib/spree/testing_support/factories/store_factory.rb +8 -0
  159. data/lib/spree/testing_support/preferences.rb +3 -3
  160. data/lib/tasks/core.rake +2 -2
  161. metadata +48 -39
  162. data/app/models/spree/stock/order_counter.rb +0 -55
  163. data/app/models/spree/tokenized_permission.rb +0 -6
  164. data/app/views/spree/shared/_routes.html.erb +0 -13
  165. data/db/migrate/20140804185157_add_default_to_shipment_cost.rb +0 -10
  166. data/db/migrate/20141021194502_add_state_lock_version_to_order.rb +0 -5
  167. data/lib/spree/core/adjustment_source.rb +0 -26
  168. data/lib/spree/core/mail_interceptor.rb +0 -22
  169. data/lib/spree/core/mail_method.rb +0 -27
  170. data/lib/spree/core/mail_settings.rb +0 -55
  171. data/lib/spree/core/ransackable_attributes.rb +0 -15
  172. data/lib/spree/core/token_resource.rb +0 -27
@@ -54,28 +54,6 @@ module Spree
54
54
  quantity == 0
55
55
  end
56
56
 
57
- def flattened
58
- flat = []
59
- contents.each do |item|
60
- item.quantity.times do
61
- flat << ContentItem.new(item.line_item, item.variant, 1, item.state)
62
- end
63
- end
64
- flat
65
- end
66
-
67
- def flattened=(flattened)
68
- contents.clear
69
- flattened.each do |item|
70
- current_item = find_item(item.variant, item.state)
71
- if current_item
72
- current_item.quantity += 1
73
- else
74
- add(item.line_item, item.quantity, item.state)
75
- end
76
- end
77
- end
78
-
79
57
  def currency
80
58
  #TODO calculate from first variant?
81
59
  end
@@ -98,7 +76,6 @@ module Spree
98
76
 
99
77
  def to_shipment
100
78
  shipment = Spree::Shipment.new
101
- shipment.address = order.ship_address
102
79
  shipment.order = order
103
80
  shipment.stock_location = stock_location
104
81
  shipment.shipping_rates = shipping_rates
@@ -1,7 +1,7 @@
1
1
  module Spree
2
2
  module Stock
3
3
  module Splitter
4
- class Backordered < Base
4
+ class Backordered < Spree::Stock::Splitter::Base
5
5
 
6
6
  def split(packages)
7
7
  split_packages = []
@@ -1,7 +1,7 @@
1
1
  module Spree
2
2
  module Stock
3
3
  module Splitter
4
- class ShippingCategory < Base
4
+ class ShippingCategory < Spree::Stock::Splitter::Base
5
5
  def split(packages)
6
6
  split_packages = []
7
7
  packages.each do |package|
@@ -1,7 +1,7 @@
1
1
  module Spree
2
2
  module Stock
3
3
  module Splitter
4
- class Weight < Base
4
+ class Weight < Spree::Stock::Splitter::Base
5
5
  attr_reader :packer, :next_splitter
6
6
 
7
7
  cattr_accessor :threshold do
@@ -1,22 +1,19 @@
1
1
  module Spree
2
- class StockItem < ActiveRecord::Base
2
+ class StockItem < Spree::Base
3
3
  acts_as_paranoid
4
4
 
5
- belongs_to :stock_location, class_name: 'Spree::StockLocation', inverse_of: :stock_items
5
+ belongs_to :stock_location, class_name: 'Spree::StockLocation'
6
6
  belongs_to :variant, class_name: 'Spree::Variant', inverse_of: :stock_items
7
7
  has_many :stock_movements, inverse_of: :stock_item
8
8
 
9
9
  validates_presence_of :stock_location, :variant
10
10
  validates_uniqueness_of :variant_id, scope: [:stock_location_id, :deleted_at]
11
- validates :count_on_hand, numericality: { greater_than_or_equal_to: 0 }, if: :verify_count_on_hand?
12
11
 
13
12
  delegate :weight, :should_track_inventory?, to: :variant
14
13
 
15
- after_save :conditional_variant_touch, if: :changed?
14
+ after_save :conditional_variant_touch
16
15
  after_touch { variant.touch }
17
16
 
18
- self.whitelisted_ransackable_attributes = ['count_on_hand', 'stock_location_id']
19
-
20
17
  def backordered_inventory_units
21
18
  Spree::InventoryUnit.backordered_for_stock_item(self)
22
19
  end
@@ -54,11 +51,11 @@ module Spree
54
51
  Spree::Variant.unscoped { super }
55
52
  end
56
53
 
57
- private
58
- def verify_count_on_hand?
59
- count_on_hand_changed? && !backorderable? && (count_on_hand < count_on_hand_was) && (count_on_hand < 0)
60
- end
54
+ def reduce_count_on_hand_to_zero
55
+ self.set_count_on_hand(0) if count_on_hand > 0
56
+ end
61
57
 
58
+ private
62
59
  def count_on_hand=(value)
63
60
  write_attribute(:count_on_hand, value)
64
61
  end
@@ -1,7 +1,7 @@
1
1
  module Spree
2
- class StockLocation < ActiveRecord::Base
2
+ class StockLocation < Spree::Base
3
3
  has_many :shipments
4
- has_many :stock_items, dependent: :delete_all, inverse_of: :stock_location
4
+ has_many :stock_items, dependent: :delete_all
5
5
  has_many :stock_movements, through: :stock_items
6
6
 
7
7
  belongs_to :state, class_name: 'Spree::State'
@@ -13,10 +13,6 @@ module Spree
13
13
 
14
14
  after_create :create_stock_items, :if => "self.propagate_all_variants?"
15
15
 
16
- def state_text
17
- state.try(:abbr) || state.try(:name) || state_name
18
- end
19
-
20
16
  # Wrapper for creating a new stock item respecting the backorderable config
21
17
  def propagate_variant(variant)
22
18
  self.stock_items.create!(variant: variant, backorderable: self.backorderable_default)
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class StockMovement < ActiveRecord::Base
2
+ class StockMovement < Spree::Base
3
3
  belongs_to :stock_item, class_name: 'Spree::StockItem', inverse_of: :stock_movements
4
4
  belongs_to :originator, polymorphic: true
5
5
 
@@ -10,8 +10,6 @@ module Spree
10
10
 
11
11
  scope :recent, -> { order('created_at DESC') }
12
12
 
13
- self.whitelisted_ransackable_attributes = ['quantity']
14
-
15
13
  def readonly?
16
14
  !new_record?
17
15
  end
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class StockTransfer < ActiveRecord::Base
2
+ class StockTransfer < Spree::Base
3
3
  has_many :stock_movements, :as => :originator
4
4
 
5
5
  belongs_to :source_location, :class_name => 'StockLocation'
@@ -7,8 +7,6 @@ module Spree
7
7
 
8
8
  make_permalink field: :number, prefix: 'T'
9
9
 
10
- self.whitelisted_ransackable_attributes = %w[reference source_location_id destination_location_id closed_at created_at number]
11
-
12
10
  def to_param
13
11
  number
14
12
  end
@@ -0,0 +1,33 @@
1
+ module Spree
2
+ class Store < Spree::Base
3
+
4
+ validates :code, presence: true, uniqueness: true
5
+ validates :name, presence: true
6
+ validates :url, presence: true
7
+ validates :mail_from_address, presence: true
8
+
9
+ before_create :ensure_default_exists_and_is_unique
10
+
11
+ scope :by_url, lambda { |url| where("url like ?", "%#{url}%") }
12
+
13
+ def self.current(domain = nil)
14
+ current_store = domain ? Store.by_url(domain).first : nil
15
+ current_store || Store.default
16
+ end
17
+
18
+ def self.default
19
+ where(default: true).first || new
20
+ end
21
+
22
+ private
23
+
24
+ def ensure_default_exists_and_is_unique
25
+ if default
26
+ Store.update_all(default: false)
27
+ else
28
+ self.default = true
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -1,9 +1,9 @@
1
1
  module Spree
2
- class TaxCategory < ActiveRecord::Base
2
+ class TaxCategory < Spree::Base
3
3
  acts_as_paranoid
4
4
  validates :name, presence: true, uniqueness: { scope: :deleted_at }
5
5
 
6
- has_many :tax_rates, dependent: :destroy, inverse_of: :tax_category
6
+ has_many :tax_rates, dependent: :destroy
7
7
 
8
8
  before_save :set_default_category
9
9
 
@@ -9,19 +9,13 @@ module Spree
9
9
  end
10
10
 
11
11
  module Spree
12
- class TaxRate < ActiveRecord::Base
12
+ class TaxRate < Spree::Base
13
13
  acts_as_paranoid
14
-
15
- # Need to deal with adjustments before calculator is destroyed.
16
- before_destroy :deals_with_adjustments_for_deleted_source
17
-
18
14
  include Spree::Core::CalculatedAdjustments
19
- include Spree::Core::AdjustmentSource
20
-
21
- belongs_to :zone, class_name: "Spree::Zone", inverse_of: :tax_rates
22
- belongs_to :tax_category, class_name: "Spree::TaxCategory", inverse_of: :tax_rates
15
+ belongs_to :zone, class_name: "Spree::Zone"
16
+ belongs_to :tax_category, class_name: "Spree::TaxCategory"
23
17
 
24
- has_many :adjustments, as: :source
18
+ has_many :adjustments, as: :source, dependent: :destroy
25
19
 
26
20
  validates :amount, presence: true, numericality: true
27
21
  validates :tax_category_id, presence: true
@@ -30,13 +24,12 @@ module Spree
30
24
  scope :by_zone, ->(zone) { where(zone_id: zone) }
31
25
 
32
26
  # Gets the array of TaxRates appropriate for the specified order
33
- def self.match(order)
34
- order_zone = order.tax_zone
35
- return [] unless order_zone
27
+ def self.match(order_tax_zone)
28
+ return [] unless order_tax_zone
36
29
  rates = includes(zone: { zone_members: :zoneable }).load.select do |rate|
37
30
  # Why "potentially"?
38
31
  # Go see the documentation for that method.
39
- rate.potentially_applicable?(order)
32
+ rate.potentially_applicable?(order_tax_zone)
40
33
  end
41
34
 
42
35
  # Imagine with me this scenario:
@@ -75,41 +68,20 @@ module Spree
75
68
  end
76
69
 
77
70
  # This method is best described by the documentation on #potentially_applicable?
78
- def self.adjust(order, items)
79
- rates = self.match(order)
71
+ def self.adjust(order_tax_zone, items)
72
+ rates = self.match(order_tax_zone)
80
73
  tax_categories = rates.map(&:tax_category)
81
- relevant_items, non_relevant_items = items.partition { |item| tax_categories.include?(item.tax_category) }
74
+ relevant_items = items.select { |item| tax_categories.include?(item.tax_category) }
82
75
  relevant_items.each do |item|
83
76
  item.adjustments.tax.delete_all
84
77
  relevant_rates = rates.select { |rate| rate.tax_category == item.tax_category }
85
78
  store_pre_tax_amount(item, relevant_rates)
86
79
  relevant_rates.each do |rate|
87
- rate.adjust(order, item)
88
- end
89
- end
90
- non_relevant_items.each do |item|
91
- if item.adjustments.tax.present?
92
- item.adjustments.tax.delete_all
93
- item.update_column(:pre_tax_amount, nil)
94
- Spree::ItemAdjustments.new(item).update
80
+ rate.adjust(order_tax_zone, item)
95
81
  end
96
82
  end
97
83
  end
98
84
 
99
- # For Vat the default rate is the rate that is configured for the default category
100
- # It is needed for every price calculation (as all customer facing prices include vat )
101
- # The function returns the actual amount, which may be 0 in case of wrong setup, but is never nil
102
- def self.default
103
- category = TaxCategory.includes(:tax_rates).where(is_default: true).first
104
- return 0 unless category
105
-
106
- address ||= Address.new(country_id: Spree::Config[:default_country_id])
107
- rate = category.tax_rates.detect { |rate| rate.zone.include? address }.try(:amount)
108
-
109
- rate || 0
110
- end
111
-
112
-
113
85
  # Tax rates can *potentially* be applicable to an order.
114
86
  # We do not know if they are/aren't until we attempt to apply these rates to
115
87
  # the items contained within the Order itself.
@@ -150,21 +122,21 @@ module Spree
150
122
  # Under no circumstances should negative adjustments be applied for the Spanish tax rates.
151
123
  #
152
124
  # Those rates should never come into play at all and only the French rates should apply.
153
- def potentially_applicable?(order)
125
+ def potentially_applicable?(order_tax_zone)
154
126
  # If the rate's zone matches the order's tax zone, then it's applicable.
155
- self.zone == order.tax_zone ||
127
+ self.zone == order_tax_zone ||
156
128
  # If the rate's zone *contains* the order's tax zone, then it's applicable.
157
- self.zone.contains?(order.tax_zone) ||
129
+ self.zone.contains?(order_tax_zone) ||
158
130
  # 1) The rate's zone is the default zone, then it's always applicable.
159
131
  (self.included_in_price? && self.zone.default_tax)
160
132
  end
161
133
 
162
134
  # Creates necessary tax adjustments for the order.
163
- def adjust(order, item)
135
+ def adjust(order_tax_zone, item)
164
136
  amount = compute_amount(item)
165
137
  return if amount == 0
166
138
 
167
- included = included_in_price && default_zone_or_zone_match?(item)
139
+ included = included_in_price && default_zone_or_zone_match?(order_tax_zone)
168
140
 
169
141
  if amount < 0
170
142
  label = Spree.t(:refund) + ' ' + create_label
@@ -173,7 +145,7 @@ module Spree
173
145
  self.adjustments.create!({
174
146
  :adjustable => item,
175
147
  :amount => amount,
176
- :order => order,
148
+ :order_id => item.order_id,
177
149
  :label => label || create_label,
178
150
  :included => included
179
151
  })
@@ -182,7 +154,7 @@ module Spree
182
154
  # This method is used by Adjustment#update to recalculate the cost.
183
155
  def compute_amount(item)
184
156
  if included_in_price
185
- if default_zone_or_zone_match?(item)
157
+ if default_zone_or_zone_match?(item.order.tax_zone)
186
158
  calculator.compute(item)
187
159
  else
188
160
  # In this case, it's a refund.
@@ -193,9 +165,9 @@ module Spree
193
165
  end
194
166
  end
195
167
 
196
- def default_zone_or_zone_match?(item)
197
- Zone.default_tax.contains?(item.order.tax_zone) ||
198
- item.order.tax_zone == self.zone
168
+ def default_zone_or_zone_match?(order_tax_zone)
169
+ default_tax = Zone.default_tax
170
+ (default_tax && default_tax.contains?(order_tax_zone)) || order_tax_zone == self.zone
199
171
  end
200
172
 
201
173
  private
@@ -204,9 +176,6 @@ module Spree
204
176
  label = ""
205
177
  label << (name.present? ? name : tax_category.name) + " "
206
178
  label << (show_rate_in_label? ? "#{amount * 100}%" : "")
207
- label << " (#{Spree.t(:included_in_price)})" if included_in_price?
208
- label
209
179
  end
210
-
211
180
  end
212
181
  end
@@ -1,8 +1,8 @@
1
1
  module Spree
2
- class Taxon < ActiveRecord::Base
2
+ class Taxon < Spree::Base
3
3
  acts_as_nested_set dependent: :destroy
4
4
 
5
- belongs_to :taxonomy, class_name: 'Spree::Taxonomy', touch: true, inverse_of: :taxons
5
+ belongs_to :taxonomy, class_name: 'Spree::Taxonomy', inverse_of: :taxons
6
6
  has_many :classifications, -> { order(:position) }, dependent: :delete_all, inverse_of: :taxon
7
7
  has_many :products, through: :classifications
8
8
 
@@ -10,7 +10,7 @@ module Spree
10
10
 
11
11
  validates :name, presence: true
12
12
 
13
- after_touch :touch_parent
13
+ after_touch :touch_ancestors_and_taxonomy
14
14
 
15
15
  has_attached_file :icon,
16
16
  styles: { mini: '32x32>', normal: '128x128>' },
@@ -20,9 +20,7 @@ module Spree
20
20
  default_url: '/assets/default_taxon.png'
21
21
 
22
22
  validates_attachment :icon,
23
- content_type: { content_type: ["image/jpg", "image/jpeg", "image/png", "image/gif"] }
24
-
25
- include Spree::Core::ProductFilters # for detailed defs of filters
23
+ content_type: { content_type: ["image/jpg", "image/jpeg", "image/png"] }
26
24
 
27
25
  # indicate which filters should be used for a taxon
28
26
  # this method should be customized to your own site
@@ -83,8 +81,11 @@ module Spree
83
81
 
84
82
  private
85
83
 
86
- def touch_parent
87
- parent.touch if parent
84
+ def touch_ancestors_and_taxonomy
85
+ # Touches all ancestors at once to avoid recursive taxonomy touch, and reduce queries.
86
+ self.class.where(id: ancestors.pluck(:id)).update_all(updated_at: Time.now)
87
+ # Have taxonomy touch happen in #touch_ancestors_and_taxonomy rather than association option in order for imports to override.
88
+ taxonomy.touch
88
89
  end
89
90
  end
90
91
  end
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class Taxonomy < ActiveRecord::Base
2
+ class Taxonomy < Spree::Base
3
3
  validates :name, presence: true
4
4
 
5
5
  has_many :taxons, inverse_of: :taxonomy
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class Tracker < ActiveRecord::Base
2
+ class Tracker < Spree::Base
3
3
  def self.current
4
4
  tracker = where(active: true, environment: Rails.env).first
5
5
  tracker.analytics_id.present? ? tracker : nil if tracker
@@ -1,5 +1,5 @@
1
1
  module Spree
2
- class Variant < ActiveRecord::Base
2
+ class Variant < Spree::Base
3
3
  acts_as_paranoid
4
4
 
5
5
  belongs_to :product, touch: true, class_name: 'Spree::Product', inverse_of: :variants
@@ -9,12 +9,12 @@ module Spree
9
9
  :shipping_category_id, :meta_description, :meta_keywords,
10
10
  :shipping_category
11
11
 
12
- has_many :inventory_units, inverse_of: :variant
12
+ has_many :inventory_units
13
13
  has_many :line_items, inverse_of: :variant
14
14
 
15
15
  has_many :stock_items, dependent: :destroy, inverse_of: :variant
16
16
  has_many :stock_locations, through: :stock_items
17
- has_many :stock_movements
17
+ has_many :stock_movements, through: :stock_items
18
18
 
19
19
  has_and_belongs_to_many :option_values, join_table: :spree_option_values_variants
20
20
  has_many :images, -> { order(:position) }, as: :viewable, dependent: :destroy, class_name: "Spree::Image"
@@ -40,15 +40,10 @@ module Spree
40
40
  after_save :save_default_price
41
41
  after_create :create_stock_items
42
42
  after_create :set_position
43
+ after_create :set_master_out_of_stock, :unless => :is_master?
43
44
 
44
45
  after_touch :clear_in_stock_cache
45
46
 
46
- # default variant scope only lists non-deleted variants
47
- scope :deleted, lambda { where.not(deleted_at: nil) }
48
-
49
- self.whitelisted_ransackable_associations = %w[option_values product prices default_price]
50
- self.whitelisted_ransackable_attributes = %w[weight sku]
51
-
52
47
  def self.active(currency = nil)
53
48
  joins(:prices).where(deleted_at: nil).where('spree_prices.currency' => currency || Spree::Config[:currency]).where('spree_prices.amount IS NOT NULL')
54
49
  end
@@ -75,7 +70,7 @@ module Spree
75
70
  a.option_type.position <=> b.option_type.position
76
71
  end
77
72
 
78
- values.map! do |ov|
73
+ values.to_a.map! do |ov|
79
74
  "#{ov.option_type.presentation}: #{ov.presentation}"
80
75
  end
81
76
 
@@ -193,6 +188,13 @@ module Spree
193
188
  price.to_d
194
189
  end
195
190
 
191
+ def set_master_out_of_stock
192
+ if product.master && product.master.in_stock?
193
+ product.master.stock_items.update_all(:backorderable => false)
194
+ product.master.stock_items.each { |item| item.reduce_count_on_hand_to_zero }
195
+ end
196
+ end
197
+
196
198
  # Ensures a new variant takes the product master price when price is not supplied
197
199
  def check_price
198
200
  if price.nil? && Spree::Config[:require_master_price]
@@ -205,12 +207,8 @@ module Spree
205
207
  end
206
208
  end
207
209
 
208
- def default_price_changed?
209
- default_price && (default_price.changed? || default_price.new_record?)
210
- end
211
-
212
210
  def save_default_price
213
- default_price.save if default_price_changed?
211
+ default_price.save if default_price && (default_price.changed? || default_price.new_record?)
214
212
  end
215
213
 
216
214
  def set_cost_currency