solidus_core 2.9.0 → 2.10.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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/base_helper.rb +4 -4
  3. data/app/helpers/spree/products_helper.rb +2 -1
  4. data/app/jobs/spree/promotion_code_batch_job.rb +2 -2
  5. data/app/models/concerns/spree/user_address_book.rb +2 -2
  6. data/app/models/concerns/spree/user_methods.rb +2 -2
  7. data/app/models/spree/address.rb +13 -17
  8. data/app/models/spree/adjustment.rb +20 -9
  9. data/app/models/spree/asset.rb +1 -1
  10. data/app/models/spree/base.rb +0 -2
  11. data/app/models/spree/calculator/price_sack.rb +1 -1
  12. data/app/models/spree/calculator/shipping/flexi_rate.rb +2 -2
  13. data/app/models/spree/calculator/tiered_flat_rate.rb +5 -5
  14. data/app/models/spree/calculator/tiered_percent.rb +6 -6
  15. data/app/models/spree/calculator.rb +1 -1
  16. data/app/models/spree/carton.rb +3 -3
  17. data/app/models/spree/classification.rb +2 -2
  18. data/app/models/spree/credit_card.rb +4 -4
  19. data/app/models/spree/customer_return.rb +1 -1
  20. data/app/models/spree/image/paperclip_attachment.rb +1 -1
  21. data/app/models/spree/inventory_unit.rb +5 -23
  22. data/app/models/spree/line_item.rb +4 -4
  23. data/app/models/spree/line_item_action.rb +2 -2
  24. data/app/models/spree/log_entry.rb +1 -1
  25. data/app/models/spree/option_value.rb +1 -1
  26. data/app/models/spree/option_values_variant.rb +2 -2
  27. data/app/models/spree/order/checkout.rb +1 -1
  28. data/app/models/spree/order/payments.rb +2 -2
  29. data/app/models/spree/order.rb +11 -10
  30. data/app/models/spree/order_cancellations.rb +1 -1
  31. data/app/models/spree/order_capturing.rb +2 -2
  32. data/app/models/spree/order_contents.rb +2 -2
  33. data/app/models/spree/order_mutex.rb +1 -1
  34. data/app/models/spree/order_promotion.rb +3 -3
  35. data/app/models/spree/order_shipping.rb +1 -1
  36. data/app/models/spree/order_taxation.rb +3 -3
  37. data/app/models/spree/payment/processing.rb +3 -3
  38. data/app/models/spree/payment.rb +8 -45
  39. data/app/models/spree/payment_capture_event.rb +1 -1
  40. data/app/models/spree/payment_method/bogus_credit_card.rb +1 -1
  41. data/app/models/spree/payment_method.rb +5 -2
  42. data/app/models/spree/payment_source.rb +1 -1
  43. data/app/models/spree/price.rb +2 -2
  44. data/app/models/spree/product/scopes.rb +218 -210
  45. data/app/models/spree/product.rb +5 -5
  46. data/app/models/spree/product_option_type.rb +2 -2
  47. data/app/models/spree/product_promotion_rule.rb +2 -2
  48. data/app/models/spree/product_property.rb +2 -2
  49. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +1 -1
  50. data/app/models/spree/promotion/actions/free_shipping.rb +1 -1
  51. data/app/models/spree/promotion/rules/option_value.rb +2 -2
  52. data/app/models/spree/promotion/rules/product.rb +3 -3
  53. data/app/models/spree/promotion.rb +28 -13
  54. data/app/models/spree/promotion_action.rb +2 -2
  55. data/app/models/spree/promotion_chooser.rb +2 -2
  56. data/app/models/spree/promotion_code/batch_builder.rb +3 -3
  57. data/app/models/spree/promotion_code.rb +11 -10
  58. data/app/models/spree/promotion_code_batch.rb +1 -1
  59. data/app/models/spree/promotion_rule.rb +2 -2
  60. data/app/models/spree/promotion_rule_role.rb +2 -2
  61. data/app/models/spree/promotion_rule_store.rb +2 -2
  62. data/app/models/spree/promotion_rule_taxon.rb +2 -2
  63. data/app/models/spree/promotion_rule_user.rb +2 -2
  64. data/app/models/spree/refund.rb +5 -5
  65. data/app/models/spree/reimbursement/credit.rb +2 -2
  66. data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -1
  67. data/app/models/spree/reimbursement.rb +5 -13
  68. data/app/models/spree/reimbursement_tax_calculator.rb +1 -1
  69. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +2 -2
  70. data/app/models/spree/return_authorization.rb +4 -10
  71. data/app/models/spree/return_item/eligibility_validator/default.rb +1 -1
  72. data/app/models/spree/return_item.rb +13 -52
  73. data/app/models/spree/role_user.rb +2 -2
  74. data/app/models/spree/shipment.rb +7 -41
  75. data/app/models/spree/shipping_calculator.rb +0 -4
  76. data/app/models/spree/shipping_manifest.rb +3 -3
  77. data/app/models/spree/shipping_method.rb +2 -2
  78. data/app/models/spree/shipping_method_category.rb +2 -2
  79. data/app/models/spree/shipping_method_stock_location.rb +2 -2
  80. data/app/models/spree/shipping_method_zone.rb +2 -2
  81. data/app/models/spree/shipping_rate.rb +2 -2
  82. data/app/models/spree/shipping_rate_tax.rb +2 -2
  83. data/app/models/spree/state.rb +2 -2
  84. data/app/models/spree/state_change.rb +2 -2
  85. data/app/models/spree/stock/differentiator.rb +1 -1
  86. data/app/models/spree/stock/package.rb +1 -1
  87. data/app/models/spree/stock_item.rb +3 -3
  88. data/app/models/spree/stock_location.rb +2 -2
  89. data/app/models/spree/stock_movement.rb +2 -2
  90. data/app/models/spree/stock_quantities.rb +13 -12
  91. data/app/models/spree/store_credit.rb +8 -8
  92. data/app/models/spree/store_credit_event.rb +3 -3
  93. data/app/models/spree/store_payment_method.rb +2 -2
  94. data/app/models/spree/store_shipping_method.rb +2 -2
  95. data/app/models/spree/tax_calculator/default.rb +0 -4
  96. data/app/models/spree/tax_calculator/shipping_rate.rb +0 -3
  97. data/app/models/spree/tax_rate.rb +5 -1
  98. data/app/models/spree/tax_rate_tax_category.rb +2 -2
  99. data/app/models/spree/taxon/paperclip_attachment.rb +13 -0
  100. data/app/models/spree/unit_cancel.rb +5 -2
  101. data/app/models/spree/user_address.rb +2 -2
  102. data/app/models/spree/user_last_url_storer/rules/authentication_rule.rb +36 -0
  103. data/app/models/spree/user_last_url_storer.rb +46 -0
  104. data/app/models/spree/user_stock_location.rb +2 -2
  105. data/app/models/spree/variant/scopes.rb +37 -29
  106. data/app/models/spree/variant.rb +10 -10
  107. data/app/models/spree/variant_property_rule.rb +1 -1
  108. data/app/models/spree/variant_property_rule_condition.rb +2 -2
  109. data/app/models/spree/variant_property_rule_value.rb +2 -2
  110. data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +1 -1
  111. data/app/models/spree/wallet_payment_source.rb +2 -2
  112. data/app/models/spree/zone.rb +1 -1
  113. data/app/models/spree/zone_member.rb +2 -2
  114. data/config/initializers/inflections.rb +5 -0
  115. data/config/initializers/money.rb +2 -0
  116. data/config/locales/en.yml +34 -3
  117. data/lib/generators/spree/dummy/dummy_generator.rb +2 -0
  118. data/lib/generators/spree/install/install_generator.rb +3 -0
  119. data/lib/generators/spree/install/templates/config/initializers/spree.rb.tt +8 -0
  120. data/lib/spree/app_configuration.rb +18 -3
  121. data/lib/spree/core/controller_helpers/auth.rb +1 -13
  122. data/lib/spree/core/engine.rb +2 -2
  123. data/lib/spree/core/environment_extension.rb +9 -0
  124. data/lib/spree/core/importer/order.rb +28 -28
  125. data/lib/spree/core/importer/product.rb +2 -2
  126. data/lib/spree/core/product_filters.rb +15 -15
  127. data/lib/spree/core/role_configuration.rb +2 -2
  128. data/lib/spree/core/search/variant.rb +1 -1
  129. data/lib/spree/core/state_machines/inventory_unit.rb +42 -0
  130. data/lib/spree/core/state_machines/payment.rb +61 -0
  131. data/lib/spree/core/state_machines/reimbursement.rb +33 -0
  132. data/lib/spree/core/state_machines/return_authorization.rb +32 -0
  133. data/lib/spree/core/state_machines/return_item/acceptance_status.rb +51 -0
  134. data/lib/spree/core/state_machines/return_item/reception_status.rb +42 -0
  135. data/lib/spree/core/state_machines/shipment.rb +58 -0
  136. data/lib/spree/core/state_machines.rb +78 -0
  137. data/lib/spree/core/stock_configuration.rb +1 -0
  138. data/lib/spree/core/validators/email.rb +1 -8
  139. data/lib/spree/core/version.rb +1 -1
  140. data/lib/spree/core.rb +12 -0
  141. data/lib/spree/money.rb +2 -2
  142. data/lib/spree/permission_sets/default_customer.rb +1 -1
  143. data/lib/spree/permission_sets/user_management.rb +3 -0
  144. data/lib/spree/permitted_attributes.rb +3 -3
  145. data/lib/spree/preferences/static_model_preferences.rb +2 -2
  146. data/lib/spree/testing_support/dummy_app/rake_tasks.rb +6 -2
  147. data/lib/spree/testing_support/dummy_app.rb +4 -1
  148. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +8 -1
  149. data/lib/spree/testing_support/factories/promotion_factory.rb +7 -0
  150. data/lib/spree/testing_support/factories/stock_package_factory.rb +1 -1
  151. data/lib/spree/testing_support/preferences.rb +54 -15
  152. data/solidus_core.gemspec +6 -6
  153. data/spec/lib/search/base_spec.rb +5 -1
  154. data/spec/lib/search/variant_spec.rb +1 -1
  155. data/spec/lib/spree/core/environment_extension_spec.rb +12 -1
  156. data/spec/lib/spree/core/stock_configuration_spec.rb +36 -0
  157. data/spec/lib/spree/core/validators/email_spec.rb +18 -18
  158. data/spec/lib/spree/event_spec.rb +15 -3
  159. data/spec/models/spree/address_spec.rb +23 -0
  160. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +1 -1
  161. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +1 -1
  162. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +1 -1
  163. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +2 -2
  164. data/spec/models/spree/calculator/shipping/per_item_spec.rb +1 -1
  165. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +24 -15
  166. data/spec/models/spree/carton_spec.rb +10 -2
  167. data/spec/models/spree/classification_spec.rb +21 -9
  168. data/spec/models/spree/concerns/user_address_book_spec.rb +4 -4
  169. data/spec/models/spree/concerns/user_methods_spec.rb +5 -4
  170. data/spec/models/spree/credit_card_spec.rb +2 -2
  171. data/spec/models/spree/customer_return_spec.rb +1 -1
  172. data/spec/models/spree/order/checkout_spec.rb +1 -1
  173. data/spec/models/spree/order/outstanding_balance_integration_spec.rb +5 -5
  174. data/spec/models/spree/order/payment_spec.rb +1 -1
  175. data/spec/models/spree/order_contents_spec.rb +1 -1
  176. data/spec/models/spree/order_inventory_spec.rb +3 -3
  177. data/spec/models/spree/order_merger_spec.rb +3 -3
  178. data/spec/models/spree/order_shipping_spec.rb +1 -1
  179. data/spec/models/spree/order_spec.rb +14 -21
  180. data/spec/models/spree/order_updater_spec.rb +4 -3
  181. data/spec/models/spree/payment_create_spec.rb +6 -16
  182. data/spec/models/spree/payment_spec.rb +12 -12
  183. data/spec/models/spree/permission_sets/user_management_spec.rb +2 -0
  184. data/spec/models/spree/preference_spec.rb +4 -4
  185. data/spec/models/spree/preferences/preferable_spec.rb +3 -3
  186. data/spec/models/spree/preferences/statically_configurable_spec.rb +2 -2
  187. data/spec/models/spree/promotion/rules/first_repeat_purchase_since_spec.rb +2 -2
  188. data/spec/models/spree/promotion/rules/nth_order_spec.rb +2 -2
  189. data/spec/models/spree/promotion_rule_spec.rb +6 -6
  190. data/spec/models/spree/promotion_spec.rb +71 -54
  191. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +3 -3
  192. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +1 -1
  193. data/spec/models/spree/return_item_spec.rb +11 -11
  194. data/spec/models/spree/returns_calculator_spec.rb +2 -2
  195. data/spec/models/spree/shipment_spec.rb +6 -6
  196. data/spec/models/spree/shipping_calculator_spec.rb +1 -13
  197. data/spec/models/spree/shipping_method_spec.rb +32 -0
  198. data/spec/models/spree/stock/availability_validator_spec.rb +2 -2
  199. data/spec/models/spree/stock/differentiator_spec.rb +2 -2
  200. data/spec/models/spree/stock/estimator_spec.rb +3 -3
  201. data/spec/models/spree/stock/inventory_units_finalizer_spec.rb +4 -4
  202. data/spec/models/spree/stock/package_spec.rb +28 -28
  203. data/spec/models/spree/stock/quantifier_spec.rb +3 -3
  204. data/spec/models/spree/stock/simple_coordinator_spec.rb +11 -11
  205. data/spec/models/spree/stock/splitter/base_spec.rb +4 -4
  206. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +7 -7
  207. data/spec/models/spree/stock_quantities_spec.rb +1 -1
  208. data/spec/models/spree/store_credit_spec.rb +8 -8
  209. data/spec/models/spree/tax_category_spec.rb +1 -1
  210. data/spec/models/spree/tax_rate_spec.rb +1 -0
  211. data/spec/models/spree/taxon_spec.rb +2 -2
  212. data/spec/models/spree/taxons/paperclip_attachment_spec.rb +29 -0
  213. data/spec/models/spree/unit_cancel_spec.rb +5 -0
  214. data/spec/models/spree/user_last_url_storer/rules/authentication_rule_spec.rb +31 -0
  215. data/spec/models/spree/user_last_url_storer_spec.rb +60 -0
  216. data/spec/models/spree/user_spec.rb +3 -3
  217. metadata +46 -41
  218. data/spec/migrate/20190106184413_remove_code_from_spree_promotions_spec.rb +0 -148
  219. data/spec/models/spree/order/updating_spec.rb +0 -18
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Spree::ShippingMethodStockLocation < Spree::Base
4
- belongs_to :shipping_method
5
- belongs_to :stock_location
4
+ belongs_to :shipping_method, optional: true
5
+ belongs_to :stock_location, optional: true
6
6
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Spree
4
4
  class ShippingMethodZone < Spree::Base
5
- belongs_to :zone
6
- belongs_to :shipping_method
5
+ belongs_to :zone, optional: true
6
+ belongs_to :shipping_method, optional: true
7
7
  end
8
8
  end
@@ -5,8 +5,8 @@ module Spree
5
5
  # method has been selected to deliver the shipment.
6
6
  #
7
7
  class ShippingRate < Spree::Base
8
- belongs_to :shipment, class_name: 'Spree::Shipment', touch: true
9
- belongs_to :shipping_method, -> { with_deleted }, class_name: 'Spree::ShippingMethod', inverse_of: :shipping_rates
8
+ belongs_to :shipment, class_name: 'Spree::Shipment', touch: true, optional: true
9
+ belongs_to :shipping_method, -> { with_deleted }, class_name: 'Spree::ShippingMethod', inverse_of: :shipping_rates, optional: true
10
10
 
11
11
  has_many :taxes,
12
12
  class_name: "Spree::ShippingRateTax",
@@ -7,8 +7,8 @@ module Spree
7
7
  # @since 1.3.0
8
8
  # @see Spree::Tax::ShippingRateTaxer
9
9
  class ShippingRateTax < ActiveRecord::Base
10
- belongs_to :shipping_rate, class_name: "Spree::ShippingRate"
11
- belongs_to :tax_rate, class_name: "Spree::TaxRate"
10
+ belongs_to :shipping_rate, class_name: "Spree::ShippingRate", optional: true
11
+ belongs_to :tax_rate, class_name: "Spree::TaxRate", optional: true
12
12
 
13
13
  extend DisplayMoney
14
14
  money_methods :absolute_amount
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Spree
4
4
  class State < Spree::Base
5
- belongs_to :country, class_name: 'Spree::Country'
5
+ belongs_to :country, class_name: 'Spree::Country', optional: true
6
6
  has_many :addresses, dependent: :nullify
7
7
 
8
8
  validates :country, :name, presence: true
@@ -24,7 +24,7 @@ module Spree
24
24
  # table of { country.id => [ state.id , state.name ] }, arrays sorted by name
25
25
  # blank is added elsewhere, if needed
26
26
  def self.states_group_by_country_id
27
- state_info = Hash.new { |h, k| h[k] = [] }
27
+ state_info = Hash.new { |hash, key| hash[key] = [] }
28
28
  order(:name).each { |state|
29
29
  state_info[state.country_id.to_s].push [state.id, state.name]
30
30
  }
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Spree
4
4
  class StateChange < Spree::Base
5
- belongs_to :user
6
- belongs_to :stateful, polymorphic: true
5
+ belongs_to :user, optional: true
6
+ belongs_to :stateful, polymorphic: true, optional: true
7
7
  before_create :assign_user
8
8
 
9
9
  def <=>(other)
@@ -14,7 +14,7 @@ module Spree
14
14
  end
15
15
 
16
16
  def missing?
17
- missing.values.any? { |v| v > 0 }
17
+ missing.values.any? { |value| value > 0 }
18
18
  end
19
19
 
20
20
  private
@@ -85,7 +85,7 @@ module Spree
85
85
  # @return [Fixnum] the number of inventory units in the package,
86
86
  # counting only those in the given state if it was specified
87
87
  def quantity(state = nil)
88
- matched_contents = state.nil? ? contents : contents.select { |c| c.state.to_s == state.to_s }
88
+ matched_contents = state.nil? ? contents : contents.select { |content| content.state.to_s == state.to_s }
89
89
  matched_contents.map(&:quantity).sum
90
90
  end
91
91
 
@@ -10,8 +10,8 @@ module Spree
10
10
  include Discard::Model
11
11
  self.discard_column = :deleted_at
12
12
 
13
- belongs_to :stock_location, class_name: 'Spree::StockLocation', inverse_of: :stock_items
14
- belongs_to :variant, -> { with_deleted }, class_name: 'Spree::Variant', inverse_of: :stock_items
13
+ belongs_to :stock_location, class_name: 'Spree::StockLocation', inverse_of: :stock_items, optional: true
14
+ belongs_to :variant, -> { with_deleted }, class_name: 'Spree::Variant', inverse_of: :stock_items, optional: true
15
15
  has_many :stock_movements, inverse_of: :stock_item
16
16
 
17
17
  validates :stock_location, :variant, presence: true
@@ -111,7 +111,7 @@ module Spree
111
111
  def should_touch_variant?
112
112
  # the variant_id changes from nil when a new stock location is added
113
113
  inventory_cache_threshold &&
114
- (saved_change_to_count_on_hand && saved_change_to_count_on_hand.any? { |c| c < inventory_cache_threshold }) ||
114
+ (saved_change_to_count_on_hand&.any? { |cache| cache < inventory_cache_threshold }) ||
115
115
  saved_change_to_variant_id?
116
116
  end
117
117
 
@@ -16,8 +16,8 @@ module Spree
16
16
  has_many :user_stock_locations, dependent: :delete_all
17
17
  has_many :users, through: :user_stock_locations
18
18
 
19
- belongs_to :state, class_name: 'Spree::State'
20
- belongs_to :country, class_name: 'Spree::Country'
19
+ belongs_to :state, class_name: 'Spree::State', optional: true
20
+ belongs_to :country, class_name: 'Spree::Country', optional: true
21
21
 
22
22
  has_many :shipping_method_stock_locations, dependent: :destroy
23
23
  has_many :shipping_methods, through: :shipping_method_stock_locations
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Spree
4
4
  class StockMovement < Spree::Base
5
- belongs_to :stock_item, class_name: 'Spree::StockItem', inverse_of: :stock_movements
6
- belongs_to :originator, polymorphic: true
5
+ belongs_to :stock_item, class_name: 'Spree::StockItem', inverse_of: :stock_movements, optional: true
6
+ belongs_to :originator, polymorphic: true, optional: true
7
7
 
8
8
  after_create :update_stock_item_quantity
9
9
 
@@ -8,8 +8,8 @@ module Spree
8
8
 
9
9
  # @param quantities [Hash<Spree::Variant=>Numeric>]
10
10
  def initialize(quantities = {})
11
- raise ArgumentError unless quantities.keys.all?{ |v| v.is_a?(Spree::Variant) }
12
- raise ArgumentError unless quantities.values.all?{ |v| v.is_a?(Numeric) }
11
+ raise ArgumentError unless quantities.keys.all?{ |value| value.is_a?(Spree::Variant) }
12
+ raise ArgumentError unless quantities.values.all?{ |value| value.is_a?(Numeric) }
13
13
 
14
14
  @quantities = quantities
15
15
  end
@@ -33,16 +33,16 @@ module Spree
33
33
  # Adds two StockQuantities together
34
34
  # @return [Spree::StockQuantities]
35
35
  def +(other)
36
- combine_with(other) do |_variant, a, b|
37
- (a || 0) + (b || 0)
36
+ combine_with(other) do |_variant, first, second|
37
+ (first || 0) + (second || 0)
38
38
  end
39
39
  end
40
40
 
41
41
  # Subtracts another StockQuantities from this one
42
42
  # @return [Spree::StockQuantities]
43
43
  def -(other)
44
- combine_with(other) do |_variant, a, b|
45
- (a || 0) - (b || 0)
44
+ combine_with(other) do |_variant, first, second|
45
+ (first || 0) - (second || 0)
46
46
  end
47
47
  end
48
48
 
@@ -50,9 +50,10 @@ module Spree
50
50
  # stock which exists in both StockQuantities.
51
51
  # @return [Spree::StockQuantities]
52
52
  def &(other)
53
- combine_with(other) do |_variant, a, b|
54
- next unless a && b
55
- [a, b].min
53
+ combine_with(other) do |_variant, first, second|
54
+ next unless first && second
55
+
56
+ [first, second].min
56
57
  end
57
58
  end
58
59
 
@@ -72,9 +73,9 @@ module Spree
72
73
  def combine_with(other)
73
74
  self.class.new(
74
75
  (variants | other.variants).map do |variant|
75
- a = self[variant]
76
- b = other[variant]
77
- value = yield variant, a, b
76
+ self_v = self[variant]
77
+ other_v = other[variant]
78
+ value = yield variant, self_v, other_v
78
79
  [variant, value]
79
80
  end.to_h.compact
80
81
  )
@@ -18,10 +18,10 @@ class Spree::StoreCredit < Spree::PaymentSource
18
18
  ADJUSTMENT_ACTION = 'adjustment'
19
19
  INVALIDATE_ACTION = 'invalidate'
20
20
 
21
- belongs_to :user, class_name: Spree::UserClassHandle.new
22
- belongs_to :created_by, class_name: Spree::UserClassHandle.new
23
- belongs_to :category, class_name: "Spree::StoreCreditCategory"
24
- belongs_to :credit_type, class_name: 'Spree::StoreCreditType', foreign_key: 'type_id'
21
+ belongs_to :user, class_name: Spree::UserClassHandle.new, optional: true
22
+ belongs_to :created_by, class_name: Spree::UserClassHandle.new, optional: true
23
+ belongs_to :category, class_name: "Spree::StoreCreditCategory", optional: true
24
+ belongs_to :credit_type, class_name: 'Spree::StoreCreditType', foreign_key: 'type_id', optional: true
25
25
  has_many :store_credit_events
26
26
 
27
27
  validates_presence_of :user_id, :category_id, :type_id, :created_by_id, :currency
@@ -63,7 +63,7 @@ class Spree::StoreCredit < Spree::PaymentSource
63
63
  end
64
64
 
65
65
  if validate_authorization(amount, order_currency)
66
- update_attributes!({
66
+ update!({
67
67
  action: AUTHORIZE_ACTION,
68
68
  action_amount: amount,
69
69
  action_originator: options[:action_originator],
@@ -95,7 +95,7 @@ class Spree::StoreCredit < Spree::PaymentSource
95
95
  errors.add(:base, I18n.t('spree.store_credit.currency_mismatch'))
96
96
  false
97
97
  else
98
- update_attributes!({
98
+ update!({
99
99
  action: CAPTURE_ACTION,
100
100
  action_amount: amount,
101
101
  action_originator: options[:action_originator],
@@ -114,7 +114,7 @@ class Spree::StoreCredit < Spree::PaymentSource
114
114
 
115
115
  def void(authorization_code, options = {})
116
116
  if auth_event = store_credit_events.find_by(action: AUTHORIZE_ACTION, authorization_code: authorization_code)
117
- update_attributes!({
117
+ update!({
118
118
  action: VOID_ACTION,
119
119
  action_amount: auth_event.amount,
120
120
  action_authorization_code: authorization_code,
@@ -235,7 +235,7 @@ class Spree::StoreCredit < Spree::PaymentSource
235
235
  store_credit_events.where(action: ALLOCATION_ACTION).first_or_initialize
236
236
  end
237
237
 
238
- event.update_attributes!({
238
+ event.update!({
239
239
  amount: action_amount || amount,
240
240
  authorization_code: action_authorization_code || event.authorization_code || generate_authorization_code,
241
241
  amount_remaining: amount_remaining,
@@ -10,9 +10,9 @@ module Spree
10
10
  include Discard::Model
11
11
  self.discard_column = :deleted_at
12
12
 
13
- belongs_to :store_credit
14
- belongs_to :originator, polymorphic: true
15
- belongs_to :store_credit_reason, class_name: 'Spree::StoreCreditReason', inverse_of: :store_credit_events
13
+ belongs_to :store_credit, optional: true
14
+ belongs_to :originator, polymorphic: true, optional: true
15
+ belongs_to :store_credit_reason, class_name: 'Spree::StoreCreditReason', inverse_of: :store_credit_events, optional: true
16
16
 
17
17
  validates_presence_of :store_credit_reason, if: :action_requires_reason?
18
18
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Spree
4
4
  class StorePaymentMethod < Spree::Base
5
- belongs_to :store, inverse_of: :store_payment_methods
6
- belongs_to :payment_method, inverse_of: :store_payment_methods
5
+ belongs_to :store, inverse_of: :store_payment_methods, optional: true
6
+ belongs_to :payment_method, inverse_of: :store_payment_methods, optional: true
7
7
  end
8
8
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Spree
4
4
  class StoreShippingMethod < Spree::Base
5
- belongs_to :store, inverse_of: :store_shipping_methods
6
- belongs_to :shipping_method, inverse_of: :store_shipping_methods
5
+ belongs_to :store, inverse_of: :store_shipping_methods, optional: true
6
+ belongs_to :shipping_method, inverse_of: :store_shipping_methods, optional: true
7
7
  end
8
8
  end
@@ -8,10 +8,6 @@ module Spree
8
8
  # The class used for tax calculation is configurable, so that the
9
9
  # calculation can easily be pushed to third-party services. Users looking
10
10
  # to provide their own calculator should adhere to the API of this class.
11
- #
12
- # @api experimental
13
- # @note This API is currently in development and likely to change.
14
- # Specifically, the input format is not yet finalized.
15
11
  class Default
16
12
  include Spree::Tax::TaxHelpers
17
13
 
@@ -10,9 +10,6 @@ module Spree
10
10
  # class.
11
11
  #
12
12
  # @see Spree::Tax::ShippingRateTaxer
13
- # @api experimental
14
- # @note This API is currently in development and likely to change.
15
- # Specifically, the input format is not yet finalized.
16
13
  class ShippingRate
17
14
  include Spree::Tax::TaxHelpers
18
15
 
@@ -17,7 +17,7 @@ module Spree
17
17
  include Spree::CalculatedAdjustments
18
18
  include Spree::AdjustmentSource
19
19
 
20
- belongs_to :zone, class_name: "Spree::Zone", inverse_of: :tax_rates
20
+ belongs_to :zone, class_name: "Spree::Zone", inverse_of: :tax_rates, optional: true
21
21
 
22
22
  has_many :tax_rate_tax_categories,
23
23
  class_name: 'Spree::TaxRateTaxCategory',
@@ -88,7 +88,11 @@ module Spree
88
88
  scope :included_in_price, -> { where(included_in_price: true) }
89
89
 
90
90
  # Creates necessary tax adjustments for the order.
91
+ #
92
+ # @deprecated Please use `Spree::Tax::OrderAdjuster#adjust!` instead
91
93
  def adjust(_order_tax_zone, item)
94
+ Spree::Deprecation.warn("`Spree::TaxRate#adjust` is deprecated. Please use `Spree::Tax::OrderAdjuster#adjust!` instead.", caller)
95
+
92
96
  amount = compute_amount(item)
93
97
 
94
98
  item.adjustments.create!(
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Spree
4
4
  class TaxRateTaxCategory < Spree::Base
5
- belongs_to :tax_rate, class_name: 'Spree::TaxRate', inverse_of: :tax_rate_tax_categories
6
- belongs_to :tax_category, class_name: 'Spree::TaxCategory', inverse_of: :tax_rate_tax_categories
5
+ belongs_to :tax_rate, class_name: 'Spree::TaxRate', inverse_of: :tax_rate_tax_categories, optional: true
6
+ belongs_to :tax_category, class_name: 'Spree::TaxCategory', inverse_of: :tax_rate_tax_categories, optional: true
7
7
  end
8
8
  end
@@ -18,4 +18,17 @@ module Spree::Taxon::PaperclipAttachment
18
18
  def icon_present?
19
19
  icon.present?
20
20
  end
21
+
22
+ def attachment_partial_name
23
+ 'paperclip'
24
+ end
25
+
26
+ def destroy_attachment(definition)
27
+ return false unless respond_to?(definition)
28
+
29
+ attached_file = send(definition)
30
+ return false unless attached_file.exists?
31
+
32
+ attached_file.destroy
33
+ end
21
34
  end
@@ -7,7 +7,7 @@ class Spree::UnitCancel < Spree::Base
7
7
  SHORT_SHIP = 'Short Ship'
8
8
  DEFAULT_REASON = 'Cancel'
9
9
 
10
- belongs_to :inventory_unit
10
+ belongs_to :inventory_unit, optional: true
11
11
  has_one :adjustment, as: :source, dependent: :destroy
12
12
 
13
13
  validates :inventory_unit, presence: true
@@ -41,7 +41,10 @@ class Spree::UnitCancel < Spree::Base
41
41
  private
42
42
 
43
43
  def weighted_line_item_amount(line_item)
44
- line_item.total_before_tax / quantity_of_line_item(line_item)
44
+ quantity_of_line_item = quantity_of_line_item(line_item)
45
+ raise ZeroDivisionError, "Line Item does not have any inventory units available to cancel" if quantity_of_line_item.zero?
46
+
47
+ line_item.total_before_tax / quantity_of_line_item
45
48
  end
46
49
 
47
50
  def quantity_of_line_item(line_item)
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Spree
4
4
  class UserAddress < Spree::Base
5
- belongs_to :user, class_name: UserClassHandle.new, foreign_key: "user_id"
6
- belongs_to :address, class_name: "Spree::Address"
5
+ belongs_to :user, class_name: UserClassHandle.new, foreign_key: "user_id", optional: true
6
+ belongs_to :address, class_name: "Spree::Address", optional: true
7
7
 
8
8
  validates_uniqueness_of :address_id, scope: :user_id
9
9
  validates_uniqueness_of :user_id, conditions: -> { active.default }, message: :default_address_exists, if: :default?
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ class UserLastUrlStorer
5
+ module Rules
6
+ # This is the basic rule that ships with Solidus that avoids storing in
7
+ # session the current path for login/loout/signup routes, avoiding possibly
8
+ # infinte redirects.
9
+ module AuthenticationRule
10
+ AUTHENTICATION_ROUTES = %w[spree_signup_path spree_login_path spree_logout_path]
11
+
12
+ extend self
13
+
14
+ def match?(controller)
15
+ full_path = controller.request.fullpath
16
+ disallowed_urls(controller).include?(full_path)
17
+ end
18
+
19
+ private
20
+
21
+ def disallowed_urls(controller)
22
+ @disallowed_urls ||= {}
23
+ @disallowed_urls[controller.controller_name] ||= begin
24
+ [].tap do |disallowed_urls|
25
+ AUTHENTICATION_ROUTES.each do |route|
26
+ if controller.respond_to?(route)
27
+ disallowed_urls << controller.send(route)
28
+ end
29
+ end
30
+ end.map! { |url| url[/\/\w+$/] }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ # This service object is responsible for storing the current path into
5
+ # into `session[:spree_user_return_to]` for redirects after successful
6
+ # user/admin authentication.
7
+ class UserLastUrlStorer
8
+ # Lists all the rules that will be evaluated before storing the
9
+ # current path value into the session.
10
+ #
11
+ # @return [Spree::Core::ClassConstantizer::Set] a set of rules
12
+ # that, when matched, will prevent session[:spree_user_return_to]
13
+ # to be set
14
+ #
15
+ # @example This method can be used also to add more rules
16
+ # Spree::UserLastUrlStorer.rules << 'CustomRule'
17
+ #
18
+ # @example it can be used also for removing unwanted rules
19
+ # Spree::UserLastUrlStorer.rules.delete('CustomRule')
20
+ #
21
+ def self.rules
22
+ Spree::Config.user_last_url_storer_rules
23
+ end
24
+
25
+ # @param controller [ApplicationController] an instance of ApplicationController
26
+ # or its subclasses. The controller will be passed to each rule for matching.
27
+ def initialize(controller)
28
+ @controller = controller
29
+ end
30
+
31
+ # Stores into session[:spree_user_return_to] the request full path for
32
+ # future redirects (to be used after successful authentication). When
33
+ # there is a rule match then the request full path is not stored.
34
+ def store_location
35
+ return if self.class.rules.any? { |rule| rule.match? controller }
36
+
37
+ session[:spree_user_return_to] = request.fullpath.gsub('//', '/')
38
+ end
39
+
40
+ private
41
+
42
+ attr_reader :controller
43
+
44
+ delegate :session, :request, to: :controller
45
+ end
46
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Spree
4
4
  class UserStockLocation < Spree::Base
5
- belongs_to :user, class_name: Spree::UserClassHandle.new, inverse_of: :user_stock_locations
6
- belongs_to :stock_location, class_name: "Spree::StockLocation", inverse_of: :user_stock_locations
5
+ belongs_to :user, class_name: Spree::UserClassHandle.new, inverse_of: :user_stock_locations, optional: true
6
+ belongs_to :stock_location, class_name: "Spree::StockLocation", inverse_of: :user_stock_locations, optional: true
7
7
  end
8
8
  end
@@ -2,41 +2,49 @@
2
2
 
3
3
  module Spree
4
4
  class Variant < Spree::Base
5
- # FIXME: WARNING tested only under sqlite and postgresql
6
- scope :descend_by_popularity, -> {
7
- order(Arel.sql("COALESCE((SELECT COUNT(*) FROM #{Spree::LineItem.quoted_table_name} GROUP BY #{Spree::LineItem.quoted_table_name}.variant_id HAVING #{Spree::LineItem.quoted_table_name}.variant_id = #{Spree::Variant.quoted_table_name}.id), 0) DESC"))
8
- }
9
-
10
- class << self
11
- # Returns variants that match a given option value
12
- #
13
- # Example:
14
- #
15
- # product.variants_including_master.has_option(OptionType.find_by(name: 'shoe-size'), OptionValue.find_by(name: '8'))
16
- def has_option(option_type, *option_values)
17
- option_types = Spree::OptionType.table_name
18
-
19
- option_type_conditions = case option_type
20
- when OptionType then { "#{option_types}.name" => option_type.name }
21
- when String then { "#{option_types}.name" => option_type }
22
- else { "#{option_types}.id" => option_type }
23
- end
5
+ module Scopes
6
+ def self.prepended(base)
7
+ base.class_eval do
8
+ # FIXME: WARNING tested only under sqlite and postgresql
9
+ scope :descend_by_popularity, -> {
10
+ order(Arel.sql("COALESCE((SELECT COUNT(*) FROM #{Spree::LineItem.quoted_table_name} GROUP BY #{Spree::LineItem.quoted_table_name}.variant_id HAVING #{Spree::LineItem.quoted_table_name}.variant_id = #{Spree::Variant.quoted_table_name}.id), 0) DESC"))
11
+ }
12
+
13
+ class << self
14
+ # Returns variants that match a given option value
15
+ #
16
+ # Example:
17
+ #
18
+ # product.variants_including_master.has_option(OptionType.find_by(name: 'shoe-size'), OptionValue.find_by(name: '8'))
19
+ def has_option(option_type, *option_values)
20
+ option_types = Spree::OptionType.table_name
21
+
22
+ option_type_conditions = case option_type
23
+ when OptionType then { "#{option_types}.name" => option_type.name }
24
+ when String then { "#{option_types}.name" => option_type }
25
+ else { "#{option_types}.id" => option_type }
26
+ end
24
27
 
25
- relation = joins(option_values: :option_type).where(option_type_conditions)
28
+ relation = joins(option_values: :option_type).where(option_type_conditions)
26
29
 
27
- option_values.each do |option_value|
28
- option_value_conditions = case option_value
29
- when OptionValue then { "#{Spree::OptionValue.table_name}.name" => option_value.name }
30
- when String then { "#{Spree::OptionValue.table_name}.name" => option_value }
31
- else { "#{Spree::OptionValue.table_name}.id" => option_value }
30
+ option_values.each do |option_value|
31
+ option_value_conditions = case option_value
32
+ when OptionValue then { "#{Spree::OptionValue.table_name}.name" => option_value.name }
33
+ when String then { "#{Spree::OptionValue.table_name}.name" => option_value }
34
+ else { "#{Spree::OptionValue.table_name}.id" => option_value }
35
+ end
36
+ relation = relation.where(option_value_conditions)
37
+ end
38
+
39
+ relation
40
+ end
41
+
42
+ alias_method :has_options, :has_option
32
43
  end
33
- relation = relation.where(option_value_conditions)
34
44
  end
35
-
36
- relation
37
45
  end
38
46
 
39
- alias_method :has_options, :has_option
47
+ ::Spree::Variant.prepend self
40
48
  end
41
49
  end
42
50
  end
@@ -37,7 +37,7 @@ module Spree
37
37
  include Spree::DefaultPrice
38
38
 
39
39
  belongs_to :product, -> { with_deleted }, touch: true, class_name: 'Spree::Product', inverse_of: :variants, optional: false
40
- belongs_to :tax_category, class_name: 'Spree::TaxCategory'
40
+ belongs_to :tax_category, class_name: 'Spree::TaxCategory', optional: true
41
41
 
42
42
  delegate :name, :description, :slug, :available_on, :shipping_category_id,
43
43
  :meta_description, :meta_keywords, :shipping_category,
@@ -250,12 +250,12 @@ module Spree
250
250
  # no option values on master
251
251
  return if is_master
252
252
 
253
- option_type = Spree::OptionType.where(name: opt_name).first_or_initialize do |o|
254
- o.presentation = opt_name
255
- o.save!
253
+ option_type = Spree::OptionType.where(name: opt_name).first_or_initialize do |option|
254
+ option.presentation = opt_name
255
+ option.save!
256
256
  end
257
257
 
258
- current_value = option_values.detect { |o| o.option_type.name == opt_name }
258
+ current_value = option_values.detect { |option| option.option_type.name == opt_name }
259
259
 
260
260
  if current_value
261
261
  return if current_value.name == opt_value
@@ -267,9 +267,9 @@ module Spree
267
267
  end
268
268
  end
269
269
 
270
- option_value = Spree::OptionValue.where(option_type_id: option_type.id, name: opt_value).first_or_initialize do |o|
271
- o.presentation = opt_value
272
- o.save!
270
+ option_value = Spree::OptionValue.where(option_type_id: option_type.id, name: opt_value).first_or_initialize do |option|
271
+ option.presentation = opt_value
272
+ option.save!
273
273
  end
274
274
 
275
275
  option_values << option_value
@@ -281,7 +281,7 @@ module Spree
281
281
  # @param opt_name [String] the name of the option whose value you want
282
282
  # @return [String] the option value
283
283
  def option_value(opt_name)
284
- option_values.detect { |o| o.option_type.name == opt_name }.try(:presentation)
284
+ option_values.detect { |option| option.option_type.name == opt_name }.try(:presentation)
285
285
  end
286
286
 
287
287
  # Returns an instance of the globally configured variant price selector class for this variant.
@@ -439,7 +439,7 @@ module Spree
439
439
  end
440
440
 
441
441
  def build_vat_prices
442
- VatPriceGenerator.new(self).run
442
+ Spree::Config.variant_vat_prices_generator_class.new(self).run
443
443
  end
444
444
 
445
445
  def set_position
@@ -13,7 +13,7 @@
13
13
  # targeted by the rule, the properties will automatically apply to the variant.
14
14
  module Spree
15
15
  class VariantPropertyRule < Spree::Base
16
- belongs_to :product, touch: true
16
+ belongs_to :product, touch: true, optional: true
17
17
 
18
18
  has_many :values, class_name: 'Spree::VariantPropertyRuleValue', dependent: :destroy
19
19
  has_many :properties, through: :values
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Spree
4
4
  class VariantPropertyRuleCondition < Spree::Base
5
- belongs_to :option_value
6
- belongs_to :variant_property_rule, touch: true
5
+ belongs_to :option_value, optional: true
6
+ belongs_to :variant_property_rule, touch: true, optional: true
7
7
 
8
8
  validates_uniqueness_of :option_value_id, scope: :variant_property_rule_id
9
9
  end