solidus_core 2.9.5 → 2.10.2

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 (221) 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.rb +1 -1
  12. data/app/models/spree/calculator/price_sack.rb +1 -1
  13. data/app/models/spree/calculator/shipping/flexi_rate.rb +2 -2
  14. data/app/models/spree/calculator/tiered_flat_rate.rb +5 -5
  15. data/app/models/spree/calculator/tiered_percent.rb +6 -6
  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.rb +11 -27
  28. data/app/models/spree/order/checkout.rb +1 -1
  29. data/app/models/spree/order/payments.rb +2 -2
  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.rb +8 -45
  38. data/app/models/spree/payment/processing.rb +3 -3
  39. data/app/models/spree/payment_capture_event.rb +1 -1
  40. data/app/models/spree/payment_method.rb +5 -2
  41. data/app/models/spree/payment_method/bogus_credit_card.rb +1 -1
  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.rb +5 -5
  45. data/app/models/spree/product/scopes.rb +218 -210
  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.rb +28 -13
  50. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +1 -1
  51. data/app/models/spree/promotion/actions/free_shipping.rb +1 -1
  52. data/app/models/spree/promotion/rules/option_value.rb +2 -2
  53. data/app/models/spree/promotion/rules/product.rb +3 -3
  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.rb +11 -10
  57. data/app/models/spree/promotion_code/batch_builder.rb +3 -3
  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.rb +5 -13
  66. data/app/models/spree/reimbursement/credit.rb +2 -2
  67. data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -1
  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.rb +13 -52
  72. data/app/models/spree/return_item/eligibility_validator/default.rb +1 -1
  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.rb +46 -0
  103. data/app/models/spree/user_last_url_storer/rules/authentication_rule.rb +36 -0
  104. data/app/models/spree/user_stock_location.rb +2 -2
  105. data/app/models/spree/variant.rb +10 -10
  106. data/app/models/spree/variant/scopes.rb +37 -29
  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/templates/config/initializers/spree.rb.tt +8 -0
  119. data/lib/spree/app_configuration.rb +18 -3
  120. data/lib/spree/core.rb +12 -0
  121. data/lib/spree/core/controller_helpers/auth.rb +1 -13
  122. data/lib/spree/core/controller_helpers/strong_parameters.rb +21 -7
  123. data/lib/spree/core/engine.rb +2 -2
  124. data/lib/spree/core/importer/order.rb +29 -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.rb +78 -0
  130. data/lib/spree/core/state_machines/inventory_unit.rb +42 -0
  131. data/lib/spree/core/state_machines/payment.rb +61 -0
  132. data/lib/spree/core/state_machines/reimbursement.rb +33 -0
  133. data/lib/spree/core/state_machines/return_authorization.rb +32 -0
  134. data/lib/spree/core/state_machines/return_item/acceptance_status.rb +51 -0
  135. data/lib/spree/core/state_machines/return_item/reception_status.rb +42 -0
  136. data/lib/spree/core/state_machines/shipment.rb +58 -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/money.rb +2 -2
  141. data/lib/spree/permission_sets/default_customer.rb +1 -1
  142. data/lib/spree/permission_sets/user_management.rb +3 -0
  143. data/lib/spree/permitted_attributes.rb +78 -9
  144. data/lib/spree/preferences/static_model_preferences.rb +2 -2
  145. data/lib/spree/testing_support/dummy_app.rb +4 -1
  146. data/lib/spree/testing_support/dummy_app/rake_tasks.rb +6 -2
  147. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +8 -1
  148. data/lib/spree/testing_support/factories/promotion_factory.rb +7 -0
  149. data/lib/spree/testing_support/factories/stock_package_factory.rb +1 -1
  150. data/lib/spree/testing_support/factories/user_factory.rb +4 -1
  151. data/solidus_core.gemspec +6 -6
  152. data/spec/lib/search/base_spec.rb +5 -1
  153. data/spec/lib/search/variant_spec.rb +1 -1
  154. data/spec/lib/spree/core/controller_helpers/strong_parameters_spec.rb +8 -1
  155. data/spec/lib/spree/core/stock_configuration_spec.rb +36 -0
  156. data/spec/lib/spree/core/validators/email_spec.rb +18 -18
  157. data/spec/lib/spree/event_spec.rb +15 -3
  158. data/spec/lib/spree/permitted_attributes_spec.rb +41 -0
  159. data/spec/models/spree/ability_spec.rb +1 -1
  160. data/spec/models/spree/address_spec.rb +23 -0
  161. data/spec/models/spree/calculator/refunds/default_refund_amount_spec.rb +1 -1
  162. data/spec/models/spree/calculator/shipping/flat_percent_item_total_spec.rb +1 -1
  163. data/spec/models/spree/calculator/shipping/flat_rate_spec.rb +1 -1
  164. data/spec/models/spree/calculator/shipping/flexi_rate_spec.rb +2 -2
  165. data/spec/models/spree/calculator/shipping/per_item_spec.rb +1 -1
  166. data/spec/models/spree/calculator/shipping/price_sack_spec.rb +24 -15
  167. data/spec/models/spree/carton_spec.rb +10 -2
  168. data/spec/models/spree/classification_spec.rb +21 -9
  169. data/spec/models/spree/concerns/user_address_book_spec.rb +4 -4
  170. data/spec/models/spree/concerns/user_methods_spec.rb +5 -4
  171. data/spec/models/spree/credit_card_spec.rb +2 -2
  172. data/spec/models/spree/customer_return_spec.rb +1 -1
  173. data/spec/models/spree/order/checkout_spec.rb +1 -1
  174. data/spec/models/spree/order/outstanding_balance_integration_spec.rb +5 -5
  175. data/spec/models/spree/order/payment_spec.rb +1 -1
  176. data/spec/models/spree/order_contents_spec.rb +1 -1
  177. data/spec/models/spree/order_inventory_spec.rb +3 -3
  178. data/spec/models/spree/order_merger_spec.rb +3 -3
  179. data/spec/models/spree/order_shipping_spec.rb +1 -1
  180. data/spec/models/spree/order_spec.rb +14 -21
  181. data/spec/models/spree/order_updater_spec.rb +4 -3
  182. data/spec/models/spree/payment_create_spec.rb +6 -16
  183. data/spec/models/spree/payment_spec.rb +12 -12
  184. data/spec/models/spree/permission_sets/user_management_spec.rb +2 -0
  185. data/spec/models/spree/preference_spec.rb +4 -4
  186. data/spec/models/spree/preferences/preferable_spec.rb +3 -3
  187. data/spec/models/spree/preferences/statically_configurable_spec.rb +2 -2
  188. data/spec/models/spree/promotion/rules/first_repeat_purchase_since_spec.rb +2 -2
  189. data/spec/models/spree/promotion/rules/nth_order_spec.rb +2 -2
  190. data/spec/models/spree/promotion/rules/taxon_spec.rb +1 -0
  191. data/spec/models/spree/promotion_rule_spec.rb +6 -6
  192. data/spec/models/spree/promotion_spec.rb +71 -54
  193. data/spec/models/spree/reimbursement_type/original_payment_spec.rb +3 -3
  194. data/spec/models/spree/return_item/exchange_variant_eligibility/same_product_spec.rb +1 -1
  195. data/spec/models/spree/return_item_spec.rb +11 -11
  196. data/spec/models/spree/returns_calculator_spec.rb +2 -2
  197. data/spec/models/spree/shipment_spec.rb +6 -6
  198. data/spec/models/spree/shipping_calculator_spec.rb +1 -13
  199. data/spec/models/spree/shipping_method_spec.rb +32 -0
  200. data/spec/models/spree/stock/availability_validator_spec.rb +2 -2
  201. data/spec/models/spree/stock/differentiator_spec.rb +2 -2
  202. data/spec/models/spree/stock/estimator_spec.rb +3 -3
  203. data/spec/models/spree/stock/inventory_units_finalizer_spec.rb +4 -4
  204. data/spec/models/spree/stock/package_spec.rb +28 -28
  205. data/spec/models/spree/stock/quantifier_spec.rb +2 -2
  206. data/spec/models/spree/stock/simple_coordinator_spec.rb +11 -11
  207. data/spec/models/spree/stock/splitter/base_spec.rb +4 -4
  208. data/spec/models/spree/stock/splitter/shipping_category_spec.rb +7 -7
  209. data/spec/models/spree/stock_quantities_spec.rb +1 -1
  210. data/spec/models/spree/store_credit_spec.rb +8 -8
  211. data/spec/models/spree/tax_category_spec.rb +1 -1
  212. data/spec/models/spree/tax_rate_spec.rb +1 -0
  213. data/spec/models/spree/taxon_spec.rb +2 -2
  214. data/spec/models/spree/taxons/paperclip_attachment_spec.rb +29 -0
  215. data/spec/models/spree/unit_cancel_spec.rb +5 -0
  216. data/spec/models/spree/user_last_url_storer/rules/authentication_rule_spec.rb +31 -0
  217. data/spec/models/spree/user_last_url_storer_spec.rb +60 -0
  218. data/spec/models/spree/user_spec.rb +3 -3
  219. metadata +46 -39
  220. data/spec/migrate/20190106184413_remove_code_from_spree_promotions_spec.rb +0 -148
  221. data/spec/models/spree/order/updating_spec.rb +0 -18
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Spree
4
4
  class ProductOptionType < Spree::Base
5
- belongs_to :product, class_name: 'Spree::Product', inverse_of: :product_option_types, touch: true
6
- belongs_to :option_type, class_name: 'Spree::OptionType', inverse_of: :product_option_types
5
+ belongs_to :product, class_name: 'Spree::Product', inverse_of: :product_option_types, touch: true, optional: true
6
+ belongs_to :option_type, class_name: 'Spree::OptionType', inverse_of: :product_option_types, optional: true
7
7
  acts_as_list scope: :product
8
8
  end
9
9
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Spree
4
4
  class ProductPromotionRule < Spree::Base
5
- belongs_to :product
6
- belongs_to :promotion_rule
5
+ belongs_to :product, optional: true
6
+ belongs_to :promotion_rule, optional: true
7
7
  end
8
8
  end
@@ -6,8 +6,8 @@ module Spree
6
6
 
7
7
  acts_as_list scope: :product
8
8
 
9
- belongs_to :product, touch: true, class_name: 'Spree::Product', inverse_of: :product_properties
10
- belongs_to :property, class_name: 'Spree::Property', inverse_of: :product_properties
9
+ belongs_to :product, touch: true, class_name: 'Spree::Product', inverse_of: :product_properties, optional: true
10
+ belongs_to :property, class_name: 'Spree::Property', inverse_of: :product_properties, optional: true
11
11
 
12
12
  self.whitelisted_ransackable_attributes = ['value']
13
13
  end
@@ -7,7 +7,7 @@ module Spree
7
7
 
8
8
  attr_reader :eligibility_errors
9
9
 
10
- belongs_to :promotion_category
10
+ belongs_to :promotion_category, optional: true
11
11
 
12
12
  has_many :promotion_rules, autosave: true, dependent: :destroy, inverse_of: :promotion
13
13
  alias_method :rules, :promotion_rules
@@ -126,9 +126,12 @@ module Spree
126
126
  # called anytime order.recalculate happens
127
127
  def eligible?(promotable, promotion_code: nil)
128
128
  return false if inactive?
129
- return false if usage_limit_exceeded?
130
- return false if promotion_code && promotion_code.usage_limit_exceeded?
131
129
  return false if blacklisted?(promotable)
130
+
131
+ excluded_orders = eligibility_excluded_orders(promotable)
132
+ return false if usage_limit_exceeded?(excluded_orders: excluded_orders)
133
+ return false if promotion_code&.usage_limit_exceeded?(excluded_orders: excluded_orders)
134
+
132
135
  !!eligible_rules(promotable, {})
133
136
  end
134
137
 
@@ -138,7 +141,8 @@ module Spree
138
141
  def eligible_rules(promotable, options = {})
139
142
  # Promotions without rules are eligible by default.
140
143
  return [] if rules.none?
141
- eligible = lambda { |r| r.eligible?(promotable, options) }
144
+
145
+ eligible = lambda { |rule| rule.eligible?(promotable, options) }
142
146
  specific_rules = rules.for(promotable)
143
147
  return [] if specific_rules.none?
144
148
 
@@ -165,23 +169,23 @@ module Spree
165
169
 
166
170
  # Whether the promotion has exceeded it's usage restrictions.
167
171
  #
172
+ # @param excluded_orders [Array<Spree::Order>] Orders to exclude from usage limit
168
173
  # @return true or false
169
- def usage_limit_exceeded?
174
+ def usage_limit_exceeded?(excluded_orders: [])
170
175
  if usage_limit
171
- usage_count >= usage_limit
176
+ usage_count(excluded_orders: excluded_orders) >= usage_limit
172
177
  end
173
178
  end
174
179
 
175
180
  # Number of times the code has been used overall
176
181
  #
182
+ # @param excluded_orders [Array<Spree::Order>] Orders to exclude from usage count
177
183
  # @return [Integer] usage count
178
- def usage_count
179
- Spree::Adjustment.eligible.
180
- promotion.
181
- where(source_id: actions.map(&:id)).
182
- joins(:order).
183
- merge(Spree::Order.complete).
184
- distinct.
184
+ def usage_count(excluded_orders: [])
185
+ Spree::Adjustment.promotion.
186
+ eligible.
187
+ in_completed_orders(excluded_orders: excluded_orders).
188
+ where(source_id: actions).
185
189
  count(:order_id)
186
190
  end
187
191
 
@@ -255,8 +259,19 @@ module Spree
255
259
 
256
260
  def apply_automatically_disallowed_with_codes_or_paths
257
261
  return unless apply_automatically
262
+
258
263
  errors.add(:apply_automatically, :disallowed_with_code) if codes.any?
259
264
  errors.add(:apply_automatically, :disallowed_with_path) if path.present?
260
265
  end
266
+
267
+ def eligibility_excluded_orders(promotable)
268
+ if promotable.is_a?(Spree::Order)
269
+ [promotable]
270
+ elsif promotable.respond_to?(:order)
271
+ [promotable.order]
272
+ else
273
+ []
274
+ end
275
+ end
261
276
  end
262
277
  end
@@ -67,7 +67,7 @@ module Spree
67
67
  line_items = actionable_line_items(order)
68
68
 
69
69
  actioned_line_items = order.line_item_adjustments.reload.
70
- select { |a| a.source == self && a.amount < 0 }.
70
+ select { |adjustment| adjustment.source == self && adjustment.amount < 0 }.
71
71
  map(&:adjustable)
72
72
  other_line_items = actioned_line_items - [line_item]
73
73
 
@@ -21,7 +21,7 @@ module Spree
21
21
  end
22
22
  # Did we actually end up applying any adjustments?
23
23
  # If so, then this action should be classed as 'successful'
24
- results.any? { |r| r == true }
24
+ results.any? { |result| result == true }
25
25
  end
26
26
 
27
27
  def label
@@ -29,8 +29,8 @@ module Spree
29
29
  def preferred_eligible_values
30
30
  values = preferences[:eligible_values] || {}
31
31
  Hash[values.keys.map(&:to_i).zip(
32
- values.values.map do |v|
33
- (v.is_a?(Array) ? v : v.split(",")).map(&:to_i)
32
+ values.values.map do |value|
33
+ (value.is_a?(Array) ? value : value.split(",")).map(&:to_i)
34
34
  end
35
35
  )]
36
36
  end
@@ -32,15 +32,15 @@ module Spree
32
32
 
33
33
  case preferred_match_policy
34
34
  when 'all'
35
- unless eligible_products.all? { |p| order.products.include?(p) }
35
+ unless eligible_products.all? { |product| order.products.include?(product) }
36
36
  eligibility_errors.add(:base, eligibility_error_message(:missing_product), error_code: :missing_product)
37
37
  end
38
38
  when 'any'
39
- unless order.products.any? { |p| eligible_products.include?(p) }
39
+ unless order.products.any? { |product| eligible_products.include?(product) }
40
40
  eligibility_errors.add(:base, eligibility_error_message(:no_applicable_products), error_code: :no_applicable_products)
41
41
  end
42
42
  when 'none'
43
- unless order.products.none? { |p| eligible_products.include?(p) }
43
+ unless order.products.none? { |product| eligible_products.include?(product) }
44
44
  eligibility_errors.add(:base, eligibility_error_message(:has_excluded_product), error_code: :has_excluded_product)
45
45
  end
46
46
  else
@@ -14,9 +14,9 @@ module Spree
14
14
  include Discard::Model
15
15
  self.discard_column = :deleted_at
16
16
 
17
- belongs_to :promotion, class_name: 'Spree::Promotion', inverse_of: :promotion_actions
17
+ belongs_to :promotion, class_name: 'Spree::Promotion', inverse_of: :promotion_actions, optional: true
18
18
 
19
- scope :of_type, ->(t) { where(type: Array.wrap(t).map(&:to_s)) }
19
+ scope :of_type, ->(type) { where(type: Array.wrap(type).map(&:to_s)) }
20
20
  scope :shipping, -> { of_type(Spree::Config.environment.promotions.shipping_actions.to_a) }
21
21
 
22
22
  # Updates the state of the order or performs some other action depending on
@@ -26,8 +26,8 @@ module Spree
26
26
 
27
27
  # @return The best promotion from this set of adjustments.
28
28
  def best_promotion_adjustment
29
- @best_promotion_adjustment ||= @adjustments.select(&:eligible?).min_by do |a|
30
- [a.amount, -a.id]
29
+ @best_promotion_adjustment ||= @adjustments.select(&:eligible?).min_by do |adjustment|
30
+ [adjustment.amount, -adjustment.id]
31
31
  end
32
32
  end
33
33
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Spree::PromotionCode < Spree::Base
4
- belongs_to :promotion, inverse_of: :codes
5
- belongs_to :promotion_code_batch, class_name: "Spree::PromotionCodeBatch"
4
+ belongs_to :promotion, inverse_of: :codes, optional: true
5
+ belongs_to :promotion_code_batch, class_name: "Spree::PromotionCodeBatch", optional: true
6
6
  has_many :adjustments
7
7
 
8
8
  validates :value, presence: true, uniqueness: { allow_blank: true }
@@ -14,22 +14,23 @@ class Spree::PromotionCode < Spree::Base
14
14
 
15
15
  # Whether the promotion code has exceeded its usage restrictions
16
16
  #
17
+ # @param excluded_orders [Array<Spree::Order>] Orders to exclude from usage limit
17
18
  # @return true or false
18
- def usage_limit_exceeded?
19
+ def usage_limit_exceeded?(excluded_orders: [])
19
20
  if usage_limit
20
- usage_count >= usage_limit
21
+ usage_count(excluded_orders: excluded_orders) >= usage_limit
21
22
  end
22
23
  end
23
24
 
24
25
  # Number of times the code has been used overall
25
26
  #
27
+ # @param excluded_orders [Array<Spree::Order>] Orders to exclude from usage count
26
28
  # @return [Integer] usage count
27
- def usage_count
28
- adjustments.eligible.
29
- joins(:order).
30
- merge(Spree::Order.complete).
31
- distinct.
32
- count(:order_id)
29
+ def usage_count(excluded_orders: [])
30
+ adjustments.
31
+ eligible.
32
+ in_completed_orders(excluded_orders: excluded_orders).
33
+ count(:order_id)
33
34
  end
34
35
 
35
36
  def usage_limit
@@ -33,12 +33,12 @@ class ::Spree::PromotionCode::BatchBuilder
33
33
  def build_promotion_codes
34
34
  generate_random_codes
35
35
  promotion_code_batch.update!(state: "completed")
36
- rescue StandardError => e
36
+ rescue StandardError => error
37
37
  promotion_code_batch.update!(
38
- error: e.inspect,
38
+ error: error.inspect,
39
39
  state: "failed"
40
40
  )
41
- raise e
41
+ raise error
42
42
  end
43
43
 
44
44
  private
@@ -5,7 +5,7 @@ module Spree
5
5
  class CantProcessStartedBatch < StandardError
6
6
  end
7
7
 
8
- belongs_to :promotion, class_name: "Spree::Promotion"
8
+ belongs_to :promotion, class_name: "Spree::Promotion", optional: true
9
9
  has_many :promotion_codes, class_name: "Spree::PromotionCode", dependent: :destroy
10
10
 
11
11
  validates :number_of_codes, numericality: { greater_than: 0 }
@@ -3,9 +3,9 @@
3
3
  module Spree
4
4
  # Base class for all promotion rules
5
5
  class PromotionRule < Spree::Base
6
- belongs_to :promotion, class_name: 'Spree::Promotion', inverse_of: :promotion_rules
6
+ belongs_to :promotion, class_name: 'Spree::Promotion', inverse_of: :promotion_rules, optional: true
7
7
 
8
- scope :of_type, ->(t) { where(type: t) }
8
+ scope :of_type, ->(type) { where(type: type) }
9
9
 
10
10
  validates :promotion, presence: true
11
11
  validate :unique_per_promotion, on: :create
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Spree
4
4
  class PromotionRuleRole < ActiveRecord::Base
5
- belongs_to :promotion_rule, class_name: 'Spree::PromotionRule'
6
- belongs_to :role, class_name: 'Spree::Role'
5
+ belongs_to :promotion_rule, class_name: 'Spree::PromotionRule', optional: true
6
+ belongs_to :role, class_name: 'Spree::Role', optional: true
7
7
  end
8
8
  end
@@ -4,7 +4,7 @@ module Spree
4
4
  class PromotionRuleStore < Spree::Base
5
5
  self.table_name = "spree_promotion_rules_stores"
6
6
 
7
- belongs_to :promotion_rule, class_name: "Spree::PromotionRule"
8
- belongs_to :store, class_name: "Spree::Store"
7
+ belongs_to :promotion_rule, class_name: "Spree::PromotionRule", optional: true
8
+ belongs_to :store, class_name: "Spree::Store", optional: true
9
9
  end
10
10
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Spree
4
4
  class PromotionRuleTaxon < Spree::Base
5
- belongs_to :promotion_rule
6
- belongs_to :taxon
5
+ belongs_to :promotion_rule, optional: true
6
+ belongs_to :taxon, optional: true
7
7
  end
8
8
  end
@@ -4,7 +4,7 @@ module Spree
4
4
  class PromotionRuleUser < Spree::Base
5
5
  self.table_name = 'spree_promotion_rules_users'
6
6
 
7
- belongs_to :promotion_rule, class_name: 'Spree::PromotionRule'
8
- belongs_to :user, class_name: Spree::UserClassHandle.new
7
+ belongs_to :promotion_rule, class_name: 'Spree::PromotionRule', optional: true
8
+ belongs_to :user, class_name: Spree::UserClassHandle.new, optional: true
9
9
  end
10
10
  end
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Spree
4
4
  class Refund < Spree::Base
5
- belongs_to :payment, inverse_of: :refunds
6
- belongs_to :reason, class_name: 'Spree::RefundReason', foreign_key: :refund_reason_id
7
- belongs_to :reimbursement, inverse_of: :refunds
5
+ belongs_to :payment, inverse_of: :refunds, optional: true
6
+ belongs_to :reason, class_name: 'Spree::RefundReason', foreign_key: :refund_reason_id, optional: true
7
+ belongs_to :reimbursement, inverse_of: :refunds, optional: true
8
8
 
9
9
  has_many :log_entries, as: :source
10
10
 
@@ -68,8 +68,8 @@ module Spree
68
68
  end
69
69
 
70
70
  response
71
- rescue ActiveMerchant::ConnectionError => e
72
- logger.error(I18n.t('spree.gateway_error') + " #{e.inspect}")
71
+ rescue ActiveMerchant::ConnectionError => error
72
+ logger.error(I18n.t('spree.gateway_error') + " #{error.inspect}")
73
73
  raise Core::GatewayError.new(I18n.t('spree.unable_to_connect_to_gateway'))
74
74
  end
75
75
 
@@ -4,8 +4,8 @@ module Spree
4
4
  class Reimbursement < Spree::Base
5
5
  class IncompleteReimbursementError < StandardError; end
6
6
 
7
- belongs_to :order, inverse_of: :reimbursements
8
- belongs_to :customer_return, inverse_of: :reimbursements, touch: true
7
+ belongs_to :order, inverse_of: :reimbursements, optional: true
8
+ belongs_to :customer_return, inverse_of: :reimbursements, touch: true, optional: true
9
9
 
10
10
  has_many :refunds, inverse_of: :reimbursement
11
11
  has_many :credits, inverse_of: :reimbursement, class_name: 'Spree::Reimbursement::Credit'
@@ -59,15 +59,7 @@ module Spree
59
59
  class_attribute :reimbursement_failure_hooks
60
60
  self.reimbursement_failure_hooks = []
61
61
 
62
- state_machine :reimbursement_status, initial: :pending do
63
- event :errored do
64
- transition to: :errored, from: [:pending, :errored]
65
- end
66
-
67
- event :reimbursed do
68
- transition to: :reimbursed, from: [:pending, :errored]
69
- end
70
- end
62
+ include ::Spree::Config.state_machines.reimbursement
71
63
 
72
64
  class << self
73
65
  def build_from_customer_return(customer_return)
@@ -112,11 +104,11 @@ module Spree
112
104
  if unpaid_amount_within_tolerance?
113
105
  reimbursed!
114
106
  Spree::Event.fire 'reimbursement_reimbursed', reimbursement: self
115
- reimbursement_success_hooks.each { |h| h.call self }
107
+ reimbursement_success_hooks.each { |hook| hook.call self }
116
108
  else
117
109
  errored!
118
110
  Spree::Event.fire 'reimbursement_errored', reimbursement: self
119
- reimbursement_failure_hooks.each { |h| h.call self }
111
+ reimbursement_failure_hooks.each { |hook| hook.call self }
120
112
  end
121
113
 
122
114
  if errored?
@@ -6,8 +6,8 @@ module Spree
6
6
  class_attribute :default_creditable_class
7
7
  self.default_creditable_class = Spree::StoreCredit
8
8
 
9
- belongs_to :reimbursement, inverse_of: :credits
10
- belongs_to :creditable, polymorphic: true
9
+ belongs_to :reimbursement, inverse_of: :credits, optional: true
10
+ belongs_to :creditable, polymorphic: true, optional: true
11
11
 
12
12
  validates :creditable, presence: true
13
13
 
@@ -18,7 +18,7 @@ module Spree
18
18
 
19
19
  def initialize(return_items)
20
20
  @return_items = return_items
21
- @reimbursement_type_hash = Hash.new { |h, k| h[k] = [] }
21
+ @reimbursement_type_hash = Hash.new { |hash, key| hash[key] = [] }
22
22
  end
23
23
 
24
24
  def calculate_reimbursement_types
@@ -25,7 +25,7 @@ module Spree
25
25
  additional_tax_total = percent_of_tax * return_item.inventory_unit.additional_tax_total
26
26
  included_tax_total = percent_of_tax * return_item.inventory_unit.included_tax_total
27
27
 
28
- return_item.update_attributes!({
28
+ return_item.update!({
29
29
  additional_tax_total: additional_tax_total,
30
30
  included_tax_total: included_tax_total
31
31
  })
@@ -63,8 +63,8 @@ module Spree
63
63
 
64
64
  def sorted_eligible_refund_payments(payments)
65
65
  if eligible_refund_methods = self.eligible_refund_methods
66
- payments = payments.select { |p| eligible_refund_methods.include? p.payment_method.class }
67
- payments = payments.sort_by { |p| eligible_refund_methods.index(p.payment_method.class) }
66
+ payments = payments.select { |payment| eligible_refund_methods.include? payment.payment_method.class }
67
+ payments = payments.sort_by { |payment| eligible_refund_methods.index(payment.payment_method.class) }
68
68
  end
69
69
  payments
70
70
  end
@@ -4,14 +4,14 @@ module Spree
4
4
  # Models the return of Inventory Units to a Stock Location for an Order.
5
5
  #
6
6
  class ReturnAuthorization < Spree::Base
7
- belongs_to :order, class_name: 'Spree::Order', inverse_of: :return_authorizations
7
+ belongs_to :order, class_name: 'Spree::Order', inverse_of: :return_authorizations, optional: true
8
8
 
9
9
  has_many :return_items, inverse_of: :return_authorization, dependent: :destroy
10
10
  has_many :inventory_units, through: :return_items, dependent: :nullify
11
11
  has_many :customer_returns, through: :return_items
12
12
 
13
- belongs_to :stock_location
14
- belongs_to :reason, class_name: 'Spree::ReturnReason', foreign_key: :return_reason_id
13
+ belongs_to :stock_location, optional: true
14
+ belongs_to :reason, class_name: 'Spree::ReturnReason', foreign_key: :return_reason_id, optional: true
15
15
 
16
16
  before_create :generate_number
17
17
 
@@ -22,13 +22,7 @@ module Spree
22
22
  validate :must_have_shipped_units, on: :create
23
23
  validate :no_previously_exchanged_inventory_units, on: :create
24
24
 
25
- state_machine initial: :authorized do
26
- before_transition to: :canceled, do: :cancel_return_items
27
-
28
- event :cancel do
29
- transition to: :canceled, from: :authorized, if: lambda { |return_authorization| return_authorization.can_cancel_return_items? }
30
- end
31
- end
25
+ include ::Spree::Config.state_machines.return_authorization
32
26
 
33
27
  extend DisplayMoney
34
28
  money_methods :pre_tax_total, :amount, :total_excluding_vat