spree_core 2.3.13 → 2.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (232) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/spree.js.coffee.erb +1 -5
  3. data/app/helpers/spree/base_helper.rb +22 -11
  4. data/app/helpers/spree/products_helper.rb +8 -7
  5. data/app/mailers/spree/base_mailer.rb +1 -0
  6. data/app/mailers/spree/reimbursement_mailer.rb +10 -0
  7. data/app/mailers/spree/test_mailer.rb +2 -3
  8. data/app/models/concerns/spree/adjustment_source.rb +24 -0
  9. data/app/models/concerns/spree/calculated_adjustments.rb +33 -0
  10. data/app/models/concerns/spree/named_type.rb +12 -0
  11. data/app/models/concerns/spree/user_address.rb +30 -0
  12. data/app/models/concerns/spree/user_payment_source.rb +19 -0
  13. data/app/models/spree/address.rb +13 -6
  14. data/app/models/spree/adjustment.rb +5 -5
  15. data/app/models/spree/app_configuration.rb +8 -4
  16. data/app/models/spree/asset.rb +1 -1
  17. data/app/models/spree/base.rb +0 -3
  18. data/app/models/spree/calculator/flat_rate.rb +1 -5
  19. data/app/models/spree/calculator/returns/default_refund_amount.rb +36 -0
  20. data/app/models/spree/classification.rb +1 -1
  21. data/app/models/spree/credit_card.rb +18 -22
  22. data/app/models/spree/customer_return.rb +70 -0
  23. data/app/models/spree/exchange.rb +42 -0
  24. data/app/models/spree/gateway/bogus.rb +3 -3
  25. data/app/models/spree/image.rb +1 -1
  26. data/app/models/spree/inventory_unit.rb +32 -8
  27. data/app/models/spree/item_adjustments.rb +7 -11
  28. data/app/models/spree/legacy_user.rb +2 -2
  29. data/app/models/spree/line_item.rb +25 -12
  30. data/app/models/spree/option_type.rb +1 -1
  31. data/app/models/spree/option_value.rb +1 -8
  32. data/app/models/spree/order.rb +163 -145
  33. data/app/models/spree/order/checkout.rb +35 -23
  34. data/app/models/spree/order/payments.rb +66 -0
  35. data/app/models/spree/order_contents.rb +34 -24
  36. data/app/models/spree/order_populator.rb +6 -4
  37. data/app/models/spree/order_updater.rb +10 -1
  38. data/app/models/spree/payment.rb +19 -16
  39. data/app/models/spree/payment/processing.rb +40 -72
  40. data/app/models/spree/payment_method.rb +1 -1
  41. data/app/models/spree/payment_method/check.rb +0 -2
  42. data/app/models/spree/preference.rb +1 -1
  43. data/app/models/spree/preferences/preferable.rb +20 -0
  44. data/app/models/spree/price.rb +13 -3
  45. data/app/models/spree/product.rb +24 -29
  46. data/app/models/spree/product_property.rb +0 -2
  47. data/app/models/spree/promotion.rb +66 -24
  48. data/app/models/spree/promotion/actions/create_adjustment.rb +2 -2
  49. data/app/models/spree/promotion/actions/create_item_adjustments.rb +15 -11
  50. data/app/models/spree/promotion/actions/create_line_items.rb +2 -12
  51. data/app/models/spree/promotion/rules/first_order.rb +6 -2
  52. data/app/models/spree/promotion/rules/item_total.rb +42 -4
  53. data/app/models/spree/promotion/rules/one_use_per_user.rb +24 -0
  54. data/app/models/spree/promotion/rules/product.rb +13 -11
  55. data/app/models/spree/promotion/rules/taxon.rb +61 -0
  56. data/app/models/spree/promotion/rules/user.rb +1 -1
  57. data/app/models/spree/promotion/rules/user_logged_in.rb +4 -1
  58. data/app/models/spree/promotion_category.rb +6 -0
  59. data/app/models/spree/promotion_handler/cart.rb +14 -18
  60. data/app/models/spree/promotion_handler/coupon.rb +25 -16
  61. data/app/models/spree/promotion_rule.rb +13 -0
  62. data/app/models/spree/property.rb +1 -3
  63. data/app/models/spree/refund.rb +91 -0
  64. data/app/models/spree/refund_reason.rb +13 -0
  65. data/app/models/spree/reimbursement.rb +148 -0
  66. data/app/models/spree/reimbursement/credit.rb +25 -0
  67. data/app/models/spree/reimbursement/reimbursement_type_engine.rb +56 -0
  68. data/app/models/spree/reimbursement/reimbursement_type_validator.rb +12 -0
  69. data/app/models/spree/reimbursement_performer.rb +43 -0
  70. data/app/models/spree/reimbursement_tax_calculator.rb +38 -0
  71. data/app/models/spree/reimbursement_type.rb +16 -0
  72. data/app/models/spree/reimbursement_type/credit.rb +13 -0
  73. data/app/models/spree/reimbursement_type/exchange.rb +9 -0
  74. data/app/models/spree/reimbursement_type/original_payment.rb +13 -0
  75. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +50 -0
  76. data/app/models/spree/return_authorization.rb +52 -68
  77. data/app/models/spree/return_authorization_reason.rb +7 -0
  78. data/app/models/spree/return_item.rb +230 -0
  79. data/app/models/spree/return_item/default_eligibility_validator.rb +27 -0
  80. data/app/models/spree/return_item/eligibility_validator/base_validator.rb +24 -0
  81. data/app/models/spree/return_item/eligibility_validator/rma_required.rb +17 -0
  82. data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +16 -0
  83. data/app/models/spree/return_item/exchange_variant_eligibility/same_option_value.rb +34 -0
  84. data/app/models/spree/return_item/exchange_variant_eligibility/same_product.rb +10 -0
  85. data/app/models/spree/returns_calculator.rb +8 -0
  86. data/app/models/spree/shipment.rb +209 -154
  87. data/app/models/spree/shipment_handler.rb +43 -0
  88. data/app/models/spree/shipping_calculator.rb +1 -1
  89. data/app/models/spree/shipping_category.rb +2 -2
  90. data/app/models/spree/shipping_method.rb +1 -1
  91. data/app/models/spree/shipping_method_category.rb +1 -1
  92. data/app/models/spree/shipping_rate.rb +4 -0
  93. data/app/models/spree/stock/adjuster.rb +10 -11
  94. data/app/models/spree/stock/availability_validator.rb +6 -10
  95. data/app/models/spree/stock/content_item.rb +48 -0
  96. data/app/models/spree/stock/coordinator.rb +14 -7
  97. data/app/models/spree/stock/estimator.rb +1 -1
  98. data/app/models/spree/stock/inventory_unit_builder.rb +21 -0
  99. data/app/models/spree/stock/package.rb +38 -51
  100. data/app/models/spree/stock/packer.rb +13 -11
  101. data/app/models/spree/stock/prioritizer.rb +7 -7
  102. data/app/models/spree/stock/splitter/base.rb +2 -2
  103. data/app/models/spree/stock_item.rb +6 -9
  104. data/app/models/spree/stock_location.rb +17 -25
  105. data/app/models/spree/stock_movement.rb +1 -8
  106. data/app/models/spree/stock_transfer.rb +0 -2
  107. data/app/models/spree/store.rb +1 -1
  108. data/app/models/spree/tax_category.rb +2 -2
  109. data/app/models/spree/tax_rate.rb +16 -22
  110. data/app/models/spree/taxon.rb +1 -1
  111. data/app/models/spree/variant.rb +45 -23
  112. data/app/models/spree/zone.rb +17 -17
  113. data/app/models/spree/zone_member.rb +1 -1
  114. data/app/views/layouts/spree/base_mailer.html.erb +784 -0
  115. data/app/views/spree/order_mailer/cancel_email.html.erb +45 -0
  116. data/app/views/spree/order_mailer/cancel_email.text.erb +2 -2
  117. data/app/views/spree/order_mailer/confirm_email.html.erb +84 -0
  118. data/app/views/spree/order_mailer/confirm_email.text.erb +2 -2
  119. data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +22 -0
  120. data/app/views/spree/shared/_base_mailer_footer.html.erb +20 -0
  121. data/app/views/spree/shared/_base_mailer_header.html.erb +31 -0
  122. data/app/views/spree/shipment_mailer/shipped_email.html.erb +34 -0
  123. data/app/views/spree/test_mailer/test_email.html.erb +40 -0
  124. data/app/views/spree/test_mailer/test_email.text.erb +2 -2
  125. data/config/initializers/friendly_id.rb +88 -0
  126. data/config/initializers/premailer_assets.rb +1 -0
  127. data/config/initializers/user_class_extensions.rb +9 -22
  128. data/config/locales/en.yml +180 -12
  129. data/db/default/spree/states.rb +73 -55
  130. data/db/migrate/20130213191427_create_default_stock.rb +1 -0
  131. data/db/migrate/20130807024301_upgrade_adjustments.rb +4 -5
  132. data/db/migrate/20140309033438_create_store_from_preferences.rb +0 -7
  133. data/db/migrate/20140318191500_create_spree_taxons_promotion_rules.rb +8 -0
  134. data/db/migrate/20140530024945_move_order_token_from_tokenized_permission.rb +1 -1
  135. data/db/migrate/20140601011216_set_shipment_total_for_users_upgrading.rb +5 -3
  136. data/db/migrate/20140625214618_create_spree_refunds.rb +12 -0
  137. data/db/migrate/20140702140656_create_spree_return_authorization_inventory_unit.rb +12 -0
  138. data/db/migrate/20140707125621_rename_return_authorization_inventory_unit_to_return_items.rb +5 -0
  139. data/db/migrate/20140709160534_backfill_line_item_pre_tax_amount.rb +10 -0
  140. data/db/migrate/20140710041921_recreate_spree_return_authorizations.rb +55 -0
  141. data/db/migrate/20140710181204_add_amount_fields_to_return_items.rb +7 -0
  142. data/db/migrate/20140710190048_drop_return_authorization_amount.rb +5 -0
  143. data/db/migrate/20140713140455_create_spree_return_authorization_reasons.rb +28 -0
  144. data/db/migrate/20140713140527_create_spree_refund_reasons.rb +14 -0
  145. data/db/migrate/20140713142214_rename_return_authorization_reason.rb +5 -0
  146. data/db/migrate/20140715182625_create_spree_promotion_categories.rb +11 -0
  147. data/db/migrate/20140716204111_drop_received_at_on_return_items.rb +9 -0
  148. data/db/migrate/20140716212330_add_reception_and_acceptance_status_to_return_items.rb +6 -0
  149. data/db/migrate/20140717155155_create_default_refund_reason.rb +9 -0
  150. data/db/migrate/20140717185932_add_default_to_spree_stock_locations.rb +5 -0
  151. data/db/migrate/20140718133010_create_spree_customer_returns.rb +9 -0
  152. data/db/migrate/20140718133349_add_customer_return_id_to_return_item.rb +6 -0
  153. data/db/migrate/20140718195325_create_friendly_id_slugs.rb +15 -0
  154. data/db/migrate/20140723004419_rename_spree_refund_return_authorization_id.rb +5 -0
  155. data/db/migrate/20140723152808_increase_return_item_pre_tax_amount_precision.rb +13 -0
  156. data/db/migrate/20140723214541_copy_product_slugs_to_slug_history.rb +15 -0
  157. data/db/migrate/20140725131539_create_spree_reimbursements.rb +21 -0
  158. data/db/migrate/20140728225422_add_promotionable_to_spree_products.rb +5 -0
  159. data/db/migrate/20140729133613_add_exchange_inventory_unit_foreign_keys.rb +7 -0
  160. data/db/migrate/20140730155938_add_acceptance_status_errors_to_return_item.rb +5 -0
  161. data/db/migrate/20140731150017_create_spree_reimbursement_types.rb +20 -0
  162. data/db/migrate/20140805171035_add_default_to_spree_credit_cards.rb +5 -0
  163. data/db/migrate/20140805171219_make_existing_credit_cards_default.rb +10 -0
  164. data/db/migrate/20140806144901_add_type_to_reimbursement_type.rb +9 -0
  165. data/db/migrate/20140808184039_create_spree_reimbursement_credits.rb +10 -0
  166. data/db/migrate/20140827170513_add_meta_title_to_spree_products.rb +7 -0
  167. data/db/migrate/20140924164824_add_code_to_spree_tax_categories.rb +5 -0
  168. data/db/migrate/20141002191113_add_code_to_spree_shipping_methods.rb +5 -0
  169. data/db/migrate/20141007230328_add_cancel_audit_fields_to_spree_orders.rb +6 -0
  170. data/db/migrate/20141009204607_add_store_id_to_orders.rb +8 -0
  171. data/lib/generators/spree/install/install_generator.rb +7 -3
  172. data/lib/spree/core.rb +11 -10
  173. data/lib/spree/core/controller_helpers/common.rb +3 -10
  174. data/lib/spree/core/controller_helpers/order.rb +15 -12
  175. data/lib/spree/core/controller_helpers/strong_parameters.rb +9 -9
  176. data/lib/spree/core/engine.rb +8 -1
  177. data/lib/spree/core/importer/order.rb +5 -17
  178. data/lib/spree/core/search/base.rb +1 -1
  179. data/lib/spree/core/validators/email.rb +1 -1
  180. data/lib/spree/core/version.rb +1 -1
  181. data/lib/spree/instrumentation.rb +41 -0
  182. data/lib/spree/migrations.rb +3 -7
  183. data/lib/spree/money.rb +2 -2
  184. data/lib/spree/permitted_attributes.rb +10 -9
  185. data/lib/spree/testing_support/ability_helpers.rb +25 -25
  186. data/lib/spree/testing_support/authorization_helpers.rb +3 -5
  187. data/lib/spree/testing_support/capybara_ext.rb +2 -2
  188. data/lib/spree/testing_support/factories/calculator_factory.rb +0 -8
  189. data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
  190. data/lib/spree/testing_support/factories/customer_return_factory.rb +31 -0
  191. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -0
  192. data/lib/spree/testing_support/factories/line_item_factory.rb +2 -1
  193. data/lib/spree/testing_support/factories/order_factory.rb +11 -6
  194. data/lib/spree/testing_support/factories/promotion_category_factory.rb +6 -0
  195. data/lib/spree/testing_support/factories/promotion_factory.rb +9 -7
  196. data/lib/spree/testing_support/factories/refund_factory.rb +14 -0
  197. data/lib/spree/testing_support/factories/reimbursement_factory.rb +16 -0
  198. data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +7 -0
  199. data/lib/spree/testing_support/factories/return_authorization_factory.rb +9 -3
  200. data/lib/spree/testing_support/factories/return_item_factory.rb +10 -0
  201. data/lib/spree/testing_support/factories/shipment_factory.rb +1 -0
  202. data/lib/spree/testing_support/factories/shipping_method_factory.rb +3 -2
  203. data/lib/spree/testing_support/factories/stock_factory.rb +12 -11
  204. data/lib/spree/testing_support/flash.rb +2 -2
  205. data/lib/tasks/email.rake +7 -0
  206. data/lib/tasks/exchanges.rake +70 -0
  207. data/vendor/assets/javascripts/jquery.validate/localization/messages_et.js +23 -0
  208. data/vendor/assets/javascripts/jquery.validate/localization/messages_eu.js +25 -0
  209. data/vendor/assets/javascripts/jquery.validate/localization/messages_hr.js +25 -0
  210. data/vendor/assets/javascripts/jquery.validate/localization/messages_ka.js +25 -0
  211. data/vendor/assets/javascripts/jquery.validate/localization/messages_ko.js +25 -0
  212. data/vendor/assets/javascripts/jquery.validate/localization/messages_my.js +25 -0
  213. data/vendor/assets/javascripts/jquery.validate/localization/messages_pt_BR.js +26 -0
  214. data/vendor/assets/javascripts/jquery.validate/localization/messages_pt_PT.js +26 -0
  215. data/vendor/assets/javascripts/jquery.validate/localization/messages_sl.js +25 -0
  216. data/vendor/assets/javascripts/jquery.validate/localization/messages_sv.js +23 -0
  217. data/vendor/assets/javascripts/jquery.validate/localization/messages_uk.js +25 -0
  218. data/vendor/assets/javascripts/jquery.validate/localization/messages_zh.js +25 -0
  219. data/vendor/assets/javascripts/jquery.validate/localization/messages_zh_TW.js +26 -0
  220. metadata +163 -47
  221. data/app/models/concerns/spree/ransackable_attributes.rb +0 -19
  222. data/db/migrate/20141021194502_add_state_lock_version_to_order.rb +0 -5
  223. data/db/migrate/20141101231208_fix_adjustment_order_presence.rb +0 -13
  224. data/db/migrate/20141105213646_update_classifications_positions.rb +0 -9
  225. data/db/migrate/20141120135441_add_guest_token_index_to_spree_orders.rb +0 -5
  226. data/db/migrate/20150515211137_fix_adjustment_order_id.rb +0 -70
  227. data/lib/spree/core/adjustment_source.rb +0 -26
  228. data/lib/spree/core/calculated_adjustments.rb +0 -35
  229. data/lib/spree/core/controller_helpers.rb +0 -20
  230. data/lib/spree/core/user_address.rb +0 -32
  231. data/lib/spree/core/user_payment_source.rb +0 -20
  232. data/lib/spree/localized_number.rb +0 -20
@@ -1,10 +1,10 @@
1
1
  module Spree
2
2
  module Stock
3
3
  class Prioritizer
4
- attr_reader :packages, :order
4
+ attr_reader :packages, :inventory_units
5
5
 
6
- def initialize(order, packages, adjuster_class=Adjuster)
7
- @order = order
6
+ def initialize(inventory_units, packages, adjuster_class=Adjuster)
7
+ @inventory_units = inventory_units
8
8
  @packages = packages
9
9
  @adjuster_class = adjuster_class
10
10
  end
@@ -18,8 +18,8 @@ module Spree
18
18
 
19
19
  private
20
20
  def adjust_packages
21
- order.line_items.each do |line_item|
22
- adjuster = @adjuster_class.new(line_item.variant, line_item.quantity, :on_hand)
21
+ inventory_units.each do |inventory_unit|
22
+ adjuster = @adjuster_class.new(inventory_unit, :on_hand)
23
23
 
24
24
  visit_packages(adjuster)
25
25
 
@@ -30,8 +30,8 @@ module Spree
30
30
 
31
31
  def visit_packages(adjuster)
32
32
  packages.each do |package|
33
- item = package.find_item adjuster.variant, adjuster.status
34
- adjuster.adjust(item) if item
33
+ item = package.find_item adjuster.inventory_unit, adjuster.status
34
+ adjuster.adjust(package) if item
35
35
  end
36
36
  end
37
37
 
@@ -8,7 +8,7 @@ module Spree
8
8
  @packer = packer
9
9
  @next_splitter = next_splitter
10
10
  end
11
- delegate :stock_location, :order, to: :packer
11
+ delegate :stock_location, to: :packer
12
12
 
13
13
  def split(packages)
14
14
  return_next(packages)
@@ -20,7 +20,7 @@ module Spree
20
20
  end
21
21
 
22
22
  def build_package(contents=[])
23
- Spree::Stock::Package.new(stock_location, order, contents)
23
+ Spree::Stock::Package.new(stock_location, contents)
24
24
  end
25
25
  end
26
26
  end
@@ -2,25 +2,19 @@ module Spree
2
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
-
12
- validates_numericality_of :count_on_hand,
13
- greater_than_or_equal_to: 0,
14
- less_than_or_equal_to: 2**31 - 1,
15
- only_integer: true, if: :verify_count_on_hand?
11
+ validates :count_on_hand, numericality: { greater_than_or_equal_to: 0 }, if: :verify_count_on_hand?
16
12
 
17
13
  delegate :weight, :should_track_inventory?, to: :variant
18
14
 
19
15
  after_save :conditional_variant_touch, if: :changed?
20
16
  after_touch { variant.touch }
21
17
 
22
- self.whitelisted_ransackable_attributes = ['count_on_hand', 'stock_location_id']
23
-
24
18
  def backordered_inventory_units
25
19
  Spree::InventoryUnit.backordered_for_stock_item(self)
26
20
  end
@@ -83,7 +77,10 @@ module Spree
83
77
  end
84
78
 
85
79
  def conditional_variant_touch
86
- if !Spree::Config.binary_inventory_cache || (count_on_hand_changed? && count_on_hand_change.any?(&:zero?))
80
+ # the variant_id changes from nil when a new stock location is added
81
+ stock_changed = (count_on_hand_changed? && count_on_hand_change.any?(&:zero?)) || variant_id_changed?
82
+
83
+ if !Spree::Config.binary_inventory_cache || stock_changed
87
84
  variant.touch
88
85
  end
89
86
  end
@@ -1,7 +1,7 @@
1
1
  module Spree
2
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'
@@ -10,13 +10,15 @@ module Spree
10
10
  validates_presence_of :name
11
11
 
12
12
  scope :active, -> { where(active: true) }
13
+ scope :order_default, -> { order(default: :desc, name: :asc) }
13
14
 
14
15
  after_create :create_stock_items, :if => "self.propagate_all_variants?"
16
+ after_save :ensure_one_default
15
17
 
16
18
  def state_text
17
19
  state.try(:abbr) || state.try(:name) || state_name
18
20
  end
19
-
21
+
20
22
  # Wrapper for creating a new stock item respecting the backorderable config
21
23
  def propagate_variant(variant)
22
24
  self.stock_items.create!(variant: variant, backorderable: self.backorderable_default)
@@ -29,31 +31,12 @@ module Spree
29
31
  self.stock_item(variant) || propagate_variant(variant)
30
32
  end
31
33
 
32
- # Returns an instance of StockItem for the variant id.
33
- #
34
- # @param variant_id [String] The id of a variant.
35
- #
36
- # @return [StockItem] Corresponding StockItem for the StockLocation's variant.
37
- def stock_item(variant_id)
38
- stock_items.where(variant_id: variant_id).order(:id).first
34
+ def stock_item(variant)
35
+ stock_items.where(variant_id: variant).order(:id).first
39
36
  end
40
37
 
41
- # Attempts to look up StockItem for the variant, and creates one if not found.
42
- # This method accepts an id or instance of the variant since it is used in
43
- # multiple ways. Other methods in this model attempt to pass a variant,
44
- # but controller actions can pass just the variant id as a parameter.
45
- #
46
- # @param variant_or_id [Variant|String] Variant instance or string id of a variant.
47
- #
48
- # @return [StockItem] Corresponding StockItem for the StockLocation's variant.
49
- def stock_item_or_create(variant_or_id)
50
- vid = if variant_or_id.is_a?(Variant)
51
- variant_or_id.id
52
- else
53
- ActiveSupport::Deprecation.warn "Passing a Variant ID is deprecated, and will be removed in Spree 3. Please pass a variant instance instead.", caller
54
- variant_or_id
55
- end
56
- stock_item(vid) || stock_items.create(variant_id: vid)
38
+ def stock_item_or_create(variant)
39
+ stock_item(variant) || stock_items.create(variant: variant)
57
40
  end
58
41
 
59
42
  def count_on_hand(variant)
@@ -107,5 +90,14 @@ module Spree
107
90
  def create_stock_items
108
91
  Variant.find_each { |variant| self.propagate_variant(variant) }
109
92
  end
93
+
94
+ def ensure_one_default
95
+ if self.default
96
+ StockLocation.where(default: true).where.not(id: self.id).each do |stock_location|
97
+ stock_location.default = false
98
+ stock_location.save!
99
+ end
100
+ end
101
+ end
110
102
  end
111
103
  end
@@ -6,17 +6,10 @@ module Spree
6
6
  after_create :update_stock_item_quantity
7
7
 
8
8
  validates :stock_item, presence: true
9
- validates :quantity, presence: true, numericality: {
10
- greater_than_or_equal_to: -2**31,
11
- less_than_or_equal_to: 2**31-1,
12
- only_integer: true,
13
- allow_nil: true
14
- }
9
+ validates :quantity, presence: true
15
10
 
16
11
  scope :recent, -> { order('created_at DESC') }
17
12
 
18
- self.whitelisted_ransackable_attributes = ['quantity']
19
-
20
13
  def readonly?
21
14
  !new_record?
22
15
  end
@@ -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
@@ -1,7 +1,7 @@
1
1
  module Spree
2
2
  class Store < Spree::Base
3
3
 
4
- validates :code, presence: true, uniqueness: { allow_blank: true }
4
+ validates :code, presence: true, uniqueness: true
5
5
  validates :name, presence: true
6
6
  validates :url, presence: true
7
7
  validates :mail_from_address, presence: true
@@ -1,9 +1,9 @@
1
1
  module Spree
2
2
  class TaxCategory < Spree::Base
3
3
  acts_as_paranoid
4
- validates :name, presence: true, uniqueness: { scope: :deleted_at, allow_blank: true }
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
 
@@ -11,15 +11,10 @@ end
11
11
  module Spree
12
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
- 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
14
+ include Spree::CalculatedAdjustments
15
+ include Spree::AdjustmentSource
16
+ belongs_to :zone, class_name: "Spree::Zone"
17
+ belongs_to :tax_category, class_name: "Spree::TaxCategory"
23
18
 
24
19
  has_many :adjustments, as: :source
25
20
 
@@ -27,6 +22,8 @@ module Spree
27
22
  validates :tax_category_id, presence: true
28
23
  validates_with DefaultTaxZoneValidator
29
24
 
25
+ before_destroy :deals_with_adjustments_for_deleted_source
26
+
30
27
  scope :by_zone, ->(zone) { where(zone_id: zone) }
31
28
 
32
29
  # Gets the array of TaxRates appropriate for the specified order
@@ -61,16 +58,17 @@ module Spree
61
58
  # correct rate amounts in the future. For example:
62
59
  # https://github.com/spree/spree/issues/4318#issuecomment-34723428
63
60
  def self.store_pre_tax_amount(item, rates)
64
- if rates.any? { |r| r.included_in_price }
65
- case item
66
- when Spree::LineItem
67
- item_amount = item.discounted_amount
68
- when Spree::Shipment
69
- item_amount = item.discounted_cost
61
+ pre_tax_amount = case item
62
+ when Spree::LineItem then item.discounted_amount
63
+ when Spree::Shipment then item.discounted_cost
70
64
  end
71
- pre_tax_amount = item_amount / (1 + rates.map(&:amount).sum)
72
- item.update_column(:pre_tax_amount, pre_tax_amount)
65
+
66
+ included_rates = rates.select(&:included_in_price)
67
+ if included_rates.any?
68
+ pre_tax_amount /= (1 + included_rates.map(&:amount).sum)
73
69
  end
70
+
71
+ item.update_column(:pre_tax_amount, pre_tax_amount)
74
72
  end
75
73
 
76
74
  # This method is best described by the documentation on #potentially_applicable?
@@ -78,11 +76,7 @@ module Spree
78
76
  rates = self.match(order_tax_zone)
79
77
  tax_categories = rates.map(&:tax_category)
80
78
  relevant_items, non_relevant_items = items.partition { |item| tax_categories.include?(item.tax_category) }
81
-
82
- if relevant_items.present?
83
- Spree::Adjustment.where(adjustable: relevant_items).tax.destroy_all # using destroy_all to ensure adjustment destroy callback fires.
84
- end
85
-
79
+ Spree::Adjustment.where(adjustable: relevant_items).tax.destroy_all # using destroy_all to ensure adjustment destroy callback fires.
86
80
  relevant_items.each do |item|
87
81
  relevant_rates = rates.select { |rate| rate.tax_category == item.tax_category }
88
82
  store_pre_tax_amount(item, relevant_rates)
@@ -20,7 +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"] }
23
+ content_type: { content_type: ["image/jpg", "image/jpeg", "image/png"] }
24
24
 
25
25
  # indicate which filters should be used for a taxon
26
26
  # this method should be customized to your own site
@@ -9,7 +9,7 @@ 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
  has_many :orders, through: :line_items
15
15
 
@@ -23,8 +23,7 @@ module Spree
23
23
  has_one :default_price,
24
24
  -> { where currency: Spree::Config[:currency] },
25
25
  class_name: 'Spree::Price',
26
- dependent: :destroy,
27
- inverse_of: :variant
26
+ dependent: :destroy
28
27
 
29
28
  delegate_belongs_to :default_price, :display_price, :display_amount, :price, :price=, :currency
30
29
 
@@ -33,25 +32,19 @@ module Spree
33
32
  dependent: :destroy,
34
33
  inverse_of: :variant
35
34
 
36
- before_validation :set_cost_currency
37
-
38
35
  validate :check_price
39
-
40
36
  validates :cost_price, numericality: { greater_than_or_equal_to: 0, allow_nil: true }
41
- validates :price, numericality: { greater_than_or_equal_to: 0, allow_nil: true }
37
+ validates :price, numericality: { greater_than_or_equal_to: 0 }
42
38
  validates_uniqueness_of :sku, allow_blank: true, conditions: -> { where(deleted_at: nil) }
43
39
 
40
+ before_validation :set_cost_currency
44
41
  after_save :save_default_price
45
-
46
42
  after_create :create_stock_items
47
43
  after_create :set_position
48
- after_create :set_master_out_of_stock, unless: :is_master?
44
+ after_create :set_master_out_of_stock, :unless => :is_master?
49
45
 
50
46
  after_touch :clear_in_stock_cache
51
47
 
52
- self.whitelisted_ransackable_associations = %w[option_values product prices default_price]
53
- self.whitelisted_ransackable_attributes = %w[weight sku]
54
-
55
48
  def self.active(currency = nil)
56
49
  joins(:prices).where(deleted_at: nil).where('spree_prices.currency' => currency || Spree::Config[:currency]).where('spree_prices.amount IS NOT NULL')
57
50
  end
@@ -65,11 +58,7 @@ module Spree
65
58
  end
66
59
 
67
60
  def cost_price=(price)
68
- self[:cost_price] = Spree::LocalizedNumber.parse(price) if price.present?
69
- end
70
-
71
- def weight=(weight)
72
- self[:weight] = Spree::LocalizedNumber.parse(weight) if weight.present?
61
+ self[:cost_price] = parse_price(price) if price.present?
73
62
  end
74
63
 
75
64
  # returns number of units currently on backorder for this variant.
@@ -77,10 +66,6 @@ module Spree
77
66
  inventory_units.with_state('backordered').size
78
67
  end
79
68
 
80
- def is_backorderable?
81
- Spree::Stock::Quantifier.new(self).backorderable?
82
- end
83
-
84
69
  def options_text
85
70
  values = self.option_values.sort do |a, b|
86
71
  a.option_type.position <=> b.option_type.position
@@ -163,6 +148,32 @@ module Spree
163
148
  price_in(currency).try(:amount)
164
149
  end
165
150
 
151
+ def price_modifier_amount_in(currency, options = {})
152
+ return 0 unless options.present?
153
+
154
+ options.keys.map { |key|
155
+ m = "#{key}_price_modifier_amount_in".to_sym
156
+ if self.respond_to? m
157
+ self.send(m, currency, options[key])
158
+ else
159
+ 0
160
+ end
161
+ }.sum
162
+ end
163
+
164
+ def price_modifier_amount(options = {})
165
+ return 0 unless options.present?
166
+
167
+ options.keys.map { |key|
168
+ m = "#{options[key]}_price_modifier_amount".to_sym
169
+ if self.respond_to? m
170
+ self.send(m, options[key])
171
+ else
172
+ 0
173
+ end
174
+ }.sum
175
+ end
176
+
166
177
  def name_and_sku
167
178
  "#{name} - #{sku}"
168
179
  end
@@ -192,6 +203,17 @@ module Spree
192
203
  end
193
204
 
194
205
  private
206
+ # strips all non-price-like characters from the price, taking into account locale settings
207
+ def parse_price(price)
208
+ return price unless price.is_a?(String)
209
+
210
+ separator, delimiter = I18n.t([:'number.currency.format.separator', :'number.currency.format.delimiter'])
211
+ non_price_characters = /[^0-9\-#{separator}]/
212
+ price.gsub!(non_price_characters, '') # strip everything else first
213
+ price.gsub!(separator, '.') unless separator == '.' # then replace the locale-specific decimal separator with the standard separator if necessary
214
+
215
+ price.to_d
216
+ end
195
217
 
196
218
  def set_master_out_of_stock
197
219
  if product.master && product.master.in_stock?
@@ -225,8 +247,8 @@ module Spree
225
247
  end
226
248
 
227
249
  def create_stock_items
228
- StockLocation.all.each do |stock_location|
229
- stock_location.propagate_variant(self) if stock_location.propagate_all_variants?
250
+ StockLocation.where(propagate_all_variants: true).each do |stock_location|
251
+ stock_location.propagate_variant(self)
230
252
  end
231
253
  end
232
254
 
@@ -1,18 +1,16 @@
1
1
  module Spree
2
2
  class Zone < Spree::Base
3
- has_many :zone_members, dependent: :destroy, class_name: "Spree::ZoneMember", inverse_of: :zone
4
- has_many :tax_rates, dependent: :destroy, inverse_of: :zone
3
+ has_many :zone_members, dependent: :destroy, class_name: "Spree::ZoneMember"
4
+ has_many :tax_rates, dependent: :destroy
5
5
  has_and_belongs_to_many :shipping_methods, :join_table => 'spree_shipping_methods_zones'
6
6
 
7
- validates :name, presence: true, uniqueness: { allow_blank: true }
7
+ validates :name, presence: true, uniqueness: true
8
8
  after_save :remove_defunct_members
9
9
  after_save :remove_previous_default
10
10
 
11
11
  alias :members :zone_members
12
12
  accepts_nested_attributes_for :zone_members, allow_destroy: true, reject_if: proc { |a| a['zoneable_id'].blank? }
13
13
 
14
- self.whitelisted_ransackable_attributes = ['description']
15
-
16
14
  def self.default_tax
17
15
  where(default_tax: true).first
18
16
  end
@@ -94,11 +92,23 @@ module Spree
94
92
  end
95
93
 
96
94
  def country_ids=(ids)
97
- set_zone_members(ids, 'Spree::Country')
95
+ zone_members.destroy_all
96
+ ids.reject{ |id| id.blank? }.map do |id|
97
+ member = ZoneMember.new
98
+ member.zoneable_type = 'Spree::Country'
99
+ member.zoneable_id = id
100
+ members << member
101
+ end
98
102
  end
99
103
 
100
104
  def state_ids=(ids)
101
- set_zone_members(ids, 'Spree::State')
105
+ zone_members.destroy_all
106
+ ids.reject{ |id| id.blank? }.map do |id|
107
+ member = ZoneMember.new
108
+ member.zoneable_type = 'Spree::State'
109
+ member.zoneable_id = id
110
+ members << member
111
+ end
102
112
  end
103
113
 
104
114
  # Indicates whether the specified zone falls entirely within the zone performing
@@ -126,15 +136,5 @@ module Spree
126
136
  def remove_previous_default
127
137
  Spree::Zone.where('id != ?', self.id).update_all(default_tax: false) if default_tax
128
138
  end
129
-
130
- def set_zone_members(ids, type)
131
- zone_members.destroy_all
132
- ids.reject{ |id| id.blank? }.map do |id|
133
- member = ZoneMember.new
134
- member.zoneable_type = type
135
- member.zoneable_id = id
136
- members << member
137
- end
138
- end
139
139
  end
140
140
  end