solidus_core 2.11.10 → 3.3.1

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 (252) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +6 -2
  3. data/app/assets/javascripts/spree.js.erb +0 -51
  4. data/app/controllers/spree/base_controller.rb +1 -1
  5. data/app/helpers/spree/base_helper.rb +1 -1
  6. data/app/helpers/spree/products_helper.rb +2 -2
  7. data/app/helpers/spree/store_helper.rb +0 -11
  8. data/app/mailers/spree/carton_mailer.rb +1 -5
  9. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +30 -11
  10. data/app/models/concerns/spree/active_storage_adapter.rb +1 -1
  11. data/app/models/concerns/spree/adjustment_source.rb +0 -15
  12. data/app/models/concerns/spree/calculated_adjustments.rb +0 -18
  13. data/app/models/concerns/spree/default_price.rb +39 -10
  14. data/app/models/concerns/spree/ransackable_attributes.rb +24 -4
  15. data/app/models/concerns/spree/soft_deletable.rb +2 -4
  16. data/app/models/concerns/spree/user_address_book.rb +10 -37
  17. data/app/models/concerns/spree/user_methods.rb +38 -13
  18. data/app/models/spree/ability.rb +0 -37
  19. data/app/models/spree/address/name.rb +2 -20
  20. data/app/models/spree/address.rb +8 -186
  21. data/app/models/spree/adjustment.rb +7 -33
  22. data/app/models/spree/base.rb +0 -53
  23. data/app/models/spree/calculator/flat_fee.rb +21 -0
  24. data/app/models/spree/calculator/flexi_rate.rb +0 -5
  25. data/app/models/spree/calculator.rb +0 -7
  26. data/app/models/spree/carton.rb +1 -1
  27. data/app/models/spree/country.rb +2 -7
  28. data/app/models/spree/credit_card.rb +1 -28
  29. data/app/models/spree/customer_return.rb +5 -7
  30. data/app/models/spree/image/active_storage_attachment.rb +2 -7
  31. data/app/models/spree/image/paperclip_attachment.rb +2 -2
  32. data/app/models/spree/image.rb +0 -7
  33. data/app/models/spree/inventory_unit.rb +0 -21
  34. data/app/models/spree/line_item.rb +6 -49
  35. data/app/models/spree/log_entry.rb +74 -1
  36. data/app/models/spree/option_type.rb +1 -1
  37. data/app/models/spree/option_value.rb +10 -1
  38. data/app/models/spree/order/number_generator.rb +7 -1
  39. data/app/models/spree/order.rb +82 -170
  40. data/app/models/spree/order_cancellations.rb +4 -24
  41. data/app/models/spree/order_contents.rb +2 -1
  42. data/app/models/spree/order_inventory.rb +1 -1
  43. data/app/models/spree/order_merger.rb +2 -2
  44. data/app/models/spree/order_promotion.rb +1 -1
  45. data/app/models/spree/order_shipping.rb +6 -9
  46. data/app/models/spree/order_taxation.rb +6 -4
  47. data/app/models/spree/order_updater.rb +17 -16
  48. data/app/models/spree/payment/cancellation.rb +1 -1
  49. data/app/models/spree/payment/processing.rb +58 -55
  50. data/app/models/spree/payment.rb +0 -3
  51. data/app/models/spree/payment_create.rb +1 -13
  52. data/app/models/spree/payment_method/bogus_credit_card.rb +6 -7
  53. data/app/models/spree/payment_method/credit_card.rb +1 -3
  54. data/app/models/spree/payment_method/simple_bogus_credit_card.rb +8 -0
  55. data/app/models/spree/payment_method.rb +26 -110
  56. data/app/models/spree/price.rb +3 -3
  57. data/app/models/spree/product/scopes.rb +24 -33
  58. data/app/models/spree/product.rb +15 -42
  59. data/app/models/spree/product_property.rb +1 -1
  60. data/app/models/spree/promotion/actions/create_adjustment.rb +4 -3
  61. data/app/models/spree/promotion/actions/create_item_adjustments.rb +5 -9
  62. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +0 -3
  63. data/app/models/spree/promotion/actions/free_shipping.rb +1 -0
  64. data/app/models/spree/promotion/order_adjustments_recalculator.rb +92 -0
  65. data/app/models/spree/promotion/rules/item_total.rb +50 -6
  66. data/app/models/spree/promotion/rules/product.rb +20 -8
  67. data/app/models/spree/promotion/rules/store.rb +4 -0
  68. data/app/models/spree/promotion/rules/taxon.rb +6 -15
  69. data/app/models/spree/promotion/rules/user.rb +4 -0
  70. data/app/models/spree/promotion.rb +39 -32
  71. data/app/models/spree/promotion_action.rb +6 -9
  72. data/app/models/spree/promotion_code/batch_builder.rb +0 -14
  73. data/app/models/spree/promotion_code.rb +11 -7
  74. data/app/models/spree/promotion_handler/cart.rb +26 -6
  75. data/app/models/spree/promotion_rule.rb +5 -0
  76. data/app/models/spree/property.rb +1 -1
  77. data/app/models/spree/refund.rb +8 -52
  78. data/app/models/spree/reimbursement.rb +5 -43
  79. data/app/models/spree/reimbursement_performer.rb +2 -8
  80. data/app/models/spree/reimbursement_type/credit.rb +1 -4
  81. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +1 -2
  82. data/app/models/spree/reimbursement_type/store_credit.rb +1 -4
  83. data/app/models/spree/return_authorization.rb +2 -5
  84. data/app/models/spree/return_item.rb +4 -24
  85. data/app/models/spree/shipment.rb +3 -56
  86. data/app/models/spree/shipping_method.rb +0 -25
  87. data/app/models/spree/shipping_rate.rb +0 -2
  88. data/app/models/spree/shipping_rate_tax.rb +1 -1
  89. data/app/models/spree/state.rb +1 -5
  90. data/app/models/spree/stock/allocator/on_hand_first.rb +2 -2
  91. data/app/models/spree/stock/availability.rb +11 -3
  92. data/app/models/spree/stock/quantifier.rb +12 -8
  93. data/app/models/spree/stock/simple_coordinator.rb +8 -26
  94. data/app/models/spree/stock/splitter/base.rb +2 -7
  95. data/app/models/spree/stock_item.rb +2 -8
  96. data/app/models/spree/stock_location.rb +2 -2
  97. data/app/models/spree/stock_movement.rb +2 -2
  98. data/app/models/spree/store.rb +0 -12
  99. data/app/models/spree/store_credit.rb +14 -1
  100. data/app/models/spree/store_credit_category.rb +0 -32
  101. data/app/models/spree/store_credit_prioritizer.rb +17 -0
  102. data/app/models/spree/tax/item_tax.rb +3 -2
  103. data/app/models/spree/tax/order_tax.rb +3 -1
  104. data/app/models/spree/tax/tax_helpers.rb +2 -2
  105. data/app/models/spree/tax/tax_location.rb +4 -7
  106. data/app/models/spree/tax_calculator/default.rb +31 -0
  107. data/app/models/spree/tax_calculator/shipping_rate.rb +2 -13
  108. data/app/models/spree/tax_rate.rb +9 -27
  109. data/app/models/spree/taxon/active_storage_attachment.rb +2 -7
  110. data/app/models/spree/taxon/paperclip_attachment.rb +3 -8
  111. data/app/models/spree/taxon.rb +1 -12
  112. data/app/models/spree/taxonomy.rb +1 -1
  113. data/app/models/spree/user_address.rb +0 -5
  114. data/app/models/spree/user_last_url_storer/rules/authentication_rule.rb +1 -1
  115. data/app/models/spree/variant/price_selector.rb +34 -4
  116. data/app/models/spree/variant.rb +52 -66
  117. data/app/models/spree/zone.rb +1 -1
  118. data/app/subscribers/spree/mailer_subscriber.rb +4 -0
  119. data/app/subscribers/spree/order_mailer_subscriber.rb +35 -0
  120. data/config/i18n-tasks.yml +134 -0
  121. data/config/locales/en.yml +406 -263
  122. data/db/migrate/20180416083007_add_apply_to_all_to_variant_property_rule.rb +1 -1
  123. data/db/migrate/20201127212108_add_type_before_removal_to_spree_payment_methods.rb +7 -0
  124. data/db/migrate/20210312061050_change_column_null_on_prices.rb +7 -0
  125. data/db/migrate/20220317165036_set_promotions_with_any_policy_to_all_if_possible.rb +20 -0
  126. data/db/migrate/20220805202442_add_level_to_spree_tax_rates.rb +5 -0
  127. data/db/migrate/20221123152807_add_shipping_category_to_spree_variants.rb +5 -0
  128. data/db/seeds.rb +4 -1
  129. data/lib/generators/solidus/install/app_templates/authentication/custom.rb +21 -0
  130. data/lib/generators/solidus/install/app_templates/authentication/devise.rb +16 -0
  131. data/lib/generators/solidus/install/app_templates/authentication/existing.rb +10 -0
  132. data/lib/generators/solidus/install/app_templates/authentication/none.rb +1 -0
  133. data/lib/generators/solidus/install/app_templates/frontend/break_down_solidus_gem.rb +54 -0
  134. data/lib/generators/solidus/install/app_templates/frontend/classic.rb +16 -0
  135. data/lib/generators/solidus/install/app_templates/frontend/none.rb +2 -0
  136. data/lib/generators/solidus/install/app_templates/frontend/starter.rb +3 -0
  137. data/lib/generators/solidus/install/app_templates/payment_method/bolt.rb +13 -0
  138. data/lib/generators/solidus/install/app_templates/payment_method/none.rb +1 -0
  139. data/lib/generators/solidus/install/app_templates/payment_method/paypal.rb +10 -0
  140. data/lib/generators/solidus/install/install_generator.rb +247 -149
  141. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +15 -60
  142. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/backend/all.js +2 -2
  143. data/lib/generators/solidus/update/templates/config/initializers/new_solidus_defaults.rb.tt +30 -0
  144. data/lib/generators/solidus/update/update_generator.rb +112 -0
  145. data/lib/generators/spree/custom_user/custom_user_generator.rb +6 -4
  146. data/lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt +2 -6
  147. data/lib/generators/spree/custom_user/templates/migration.rb.tt +7 -3
  148. data/lib/generators/spree/dummy/dummy_generator.rb +12 -9
  149. data/lib/generators/spree/dummy/templates/rails/application.rb.tt +0 -1
  150. data/lib/generators/spree/dummy/templates/rails/database.yml +81 -39
  151. data/lib/generators/spree/dummy/templates/rails/storage.yml +3 -0
  152. data/lib/generators/spree/dummy/templates/rails/test.rb +2 -0
  153. data/lib/spree/app_configuration.rb +134 -64
  154. data/lib/spree/bus.rb +20 -0
  155. data/lib/spree/core/class_constantizer.rb +2 -0
  156. data/lib/spree/core/controller_helpers/auth.rb +10 -15
  157. data/lib/spree/core/controller_helpers/current_host.rb +5 -3
  158. data/lib/spree/core/controller_helpers/order.rb +12 -32
  159. data/lib/spree/core/controller_helpers/payment_parameters.rb +0 -54
  160. data/lib/spree/core/controller_helpers/pricing.rb +0 -8
  161. data/lib/spree/core/controller_helpers/search.rb +1 -1
  162. data/lib/spree/core/controller_helpers/strong_parameters.rb +0 -4
  163. data/lib/spree/core/engine.rb +54 -50
  164. data/lib/spree/core/environment_extension.rb +0 -9
  165. data/lib/spree/core/product_filters.rb +1 -41
  166. data/lib/spree/core/role_configuration.rb +0 -14
  167. data/lib/spree/core/search/base.rb +18 -35
  168. data/lib/spree/core/state_machines/order.rb +2 -2
  169. data/lib/spree/core/state_machines.rb +2 -11
  170. data/lib/spree/core/stock_configuration.rb +18 -0
  171. data/lib/spree/core/validators/email.rb +5 -3
  172. data/lib/spree/core/version.rb +5 -1
  173. data/lib/spree/core/versioned_value.rb +75 -0
  174. data/lib/spree/core.rb +40 -11
  175. data/lib/spree/deprecation.rb +1 -1
  176. data/lib/spree/event/configuration.rb +0 -5
  177. data/lib/spree/event/subscriber.rb +0 -18
  178. data/lib/spree/event/subscriber_registry.rb +7 -7
  179. data/lib/spree/event.rb +1 -32
  180. data/lib/spree/i18n.rb +0 -22
  181. data/lib/spree/migrations.rb +13 -11
  182. data/lib/spree/money.rb +3 -18
  183. data/lib/spree/permission_sets/default_customer.rb +8 -1
  184. data/lib/spree/permitted_attributes.rb +17 -59
  185. data/lib/spree/preferences/configuration.rb +84 -0
  186. data/lib/spree/preferences/preferable.rb +13 -0
  187. data/lib/spree/preferences/preferable_class_methods.rb +37 -4
  188. data/lib/spree/preferences/preference_differentiator.rb +29 -0
  189. data/lib/spree/preferences/static_model_preferences.rb +25 -10
  190. data/lib/spree/rails_compatibility.rb +106 -0
  191. data/lib/spree/testing_support/blacklist_urls.rb +1 -1
  192. data/lib/spree/testing_support/bus_helpers.rb +101 -0
  193. data/lib/spree/testing_support/capybara_ext.rb +0 -30
  194. data/lib/spree/testing_support/common_rake.rb +71 -23
  195. data/lib/spree/testing_support/controller_requests.rb +0 -82
  196. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/backend/all.js +1 -1
  197. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/frontend/all.js +1 -1
  198. data/lib/spree/testing_support/dummy_app/database.yml +42 -22
  199. data/lib/spree/testing_support/dummy_app/migrations.rb +0 -3
  200. data/lib/spree/testing_support/dummy_app.rb +47 -34
  201. data/lib/spree/testing_support/factories/address_factory.rb +9 -6
  202. data/lib/spree/testing_support/factories/calculator_factory.rb +3 -0
  203. data/lib/spree/testing_support/factories/country_factory.rb +1 -2
  204. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
  205. data/lib/spree/testing_support/factories/order_factory.rb +8 -5
  206. data/lib/spree/testing_support/factories/product_factory.rb +4 -1
  207. data/lib/spree/testing_support/factories/promotion_factory.rb +28 -14
  208. data/lib/spree/testing_support/factories/refund_factory.rb +0 -1
  209. data/lib/spree/testing_support/factories/state_factory.rb +8 -2
  210. data/lib/spree/testing_support/factories/store_credit_factory.rb +4 -4
  211. data/lib/spree/testing_support/factories/user_factory.rb +6 -0
  212. data/lib/spree/testing_support/factory_bot.rb +2 -2
  213. data/lib/spree/testing_support/order_walkthrough.rb +6 -8
  214. data/lib/spree/testing_support/preferences.rb +0 -25
  215. data/lib/spree/testing_support/silence_deprecations.rb +9 -0
  216. data/lib/tasks/colorado_delivery_fee.rake +28 -0
  217. data/lib/tasks/payment_method.rake +29 -0
  218. data/lib/tasks/solidus/check_orders_with_invalid_email.rake +18 -0
  219. data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +8 -0
  220. data/lib/tasks/solidus/split_promotions_with_any_match_policy.rake +33 -0
  221. data/solidus_core.gemspec +14 -7
  222. metadata +127 -78
  223. data/app/mailers/spree/test_mailer.rb +0 -13
  224. data/app/models/concerns/spree/user_payment_source.rb +0 -26
  225. data/app/models/spree/calculator/free_shipping.rb +0 -22
  226. data/app/models/spree/calculator/percent_per_item.rb +0 -51
  227. data/app/models/spree/calculator/price_sack.rb +0 -28
  228. data/app/models/spree/gateway/bogus.rb +0 -13
  229. data/app/models/spree/gateway/bogus_simple.rb +0 -13
  230. data/app/models/spree/gateway.rb +0 -14
  231. data/app/models/spree/order/checkout.rb +0 -244
  232. data/app/models/spree/order_capturing.rb +0 -50
  233. data/app/models/spree/promotion_handler/free_shipping.rb +0 -9
  234. data/app/models/spree/tax/shipping_rate_taxer.rb +0 -24
  235. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -10
  236. data/lib/generators/solidus/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -9
  237. data/lib/generators/spree/install/install_generator.rb +0 -15
  238. data/lib/solidus/migrations/rename_gateways.rb +0 -41
  239. data/lib/spree/core/current_store.rb +0 -24
  240. data/lib/spree/paranoia_deprecations.rb +0 -41
  241. data/lib/spree/promo/environment.rb +0 -12
  242. data/lib/spree/testing_support/bar_ability.rb +0 -19
  243. data/lib/tasks/core.rake +0 -104
  244. data/lib/tasks/email.rake +0 -12
  245. data/lib/tasks/migrations/copy_order_bill_address_to_credit_card.rake +0 -119
  246. data/lib/tasks/migrations/migrate_address_names.rake +0 -158
  247. data/lib/tasks/migrations/migrate_default_billing_addresses_to_address_book.rake +0 -26
  248. data/lib/tasks/migrations/migrate_shipping_rate_taxes.rake +0 -22
  249. data/lib/tasks/migrations/migrate_user_addresses.rake +0 -34
  250. data/lib/tasks/migrations/rename_gateways.rake +0 -23
  251. data/lib/tasks/order_capturing.rake +0 -27
  252. data/lib/tasks/upgrade.rake +0 -13
@@ -3,7 +3,7 @@
3
3
  module Spree
4
4
  class OrderUpdater
5
5
  attr_reader :order
6
- delegate :payments, :line_items, :adjustments, :all_adjustments, :shipments, :update_hooks, :quantity, to: :order
6
+ delegate :payments, :line_items, :adjustments, :all_adjustments, :shipments, :quantity, to: :order
7
7
 
8
8
  def initialize(order)
9
9
  @order = order
@@ -26,20 +26,11 @@ module Spree
26
26
  update_shipments
27
27
  update_shipment_state
28
28
  end
29
- run_hooks if update_hooks.any?
30
- Spree::Event.fire 'order_recalculated', order: order
29
+ Spree::Bus.publish :order_recalculated, order: order
31
30
  persist_totals
32
31
  end
33
32
  end
34
33
 
35
- def run_hooks
36
- Spree::Deprecation.warn \
37
- "This method is deprecated. Please run your hooks by subscribing " \
38
- "to `order_recalculated` and/or `order_finalized` events instead, depending " \
39
- " on when OrderUpdater#run_hooks was called.", caller(1)
40
- update_hooks.each { |hook| order.send hook }
41
- end
42
-
43
34
  # Updates the +shipment_state+ attribute according to the following logic:
44
35
  #
45
36
  # shipped when all Shipments are in the "shipped" state
@@ -119,8 +110,7 @@ module Spree
119
110
  # http://www.hmrc.gov.uk/vat/managing/charging/discounts-etc.htm#1
120
111
  # It also fits the criteria for sales tax as outlined here:
121
112
  # http://www.boe.ca.gov/formspubs/pub113/
122
- update_item_promotions
123
- update_order_promotions
113
+ update_promotions
124
114
  update_taxes
125
115
  update_cancellations
126
116
  update_item_totals
@@ -166,11 +156,13 @@ module Spree
166
156
  recalculate_adjustments
167
157
 
168
158
  all_items = line_items + shipments
159
+ order_tax_adjustments = adjustments.select(&:eligible?).select(&:tax?)
169
160
 
170
161
  order.adjustment_total = all_items.sum(&:adjustment_total) + adjustments.select(&:eligible?).sum(&:amount)
171
- order.included_tax_total = all_items.sum(&:included_tax_total)
172
- order.additional_tax_total = all_items.sum(&:additional_tax_total)
162
+ order.included_tax_total = all_items.sum(&:included_tax_total) + order_tax_adjustments.select(&:included?).sum(&:amount)
163
+ order.additional_tax_total = all_items.sum(&:additional_tax_total) + order_tax_adjustments.reject(&:included?).sum(&:amount)
173
164
 
165
+ # TODO: Delete this line in Solidus 4.0, when it is run in `update_promotions`.
174
166
  order.promo_total = all_items.sum(&:promo_total) + adjustments.select(&:eligible?).select(&:promotion?).sum(&:amount)
175
167
 
176
168
  update_order_total
@@ -186,7 +178,7 @@ module Spree
186
178
  end
187
179
 
188
180
  def persist_totals
189
- order.save!(validate: Spree::Config.run_order_validations_on_order_updater)
181
+ order.save!
190
182
  end
191
183
 
192
184
  def log_state_change(name)
@@ -204,6 +196,11 @@ module Spree
204
196
  end
205
197
  end
206
198
 
199
+ def update_promotions
200
+ Spree::Config.promotion_adjuster_class.new(order).call
201
+ end
202
+
203
+ # DEPRECATED; this functionality is handled in #update_promotions
207
204
  def update_item_promotions
208
205
  [*line_items, *shipments].each do |item|
209
206
  promotion_adjustments = item.adjustments.select(&:promotion?)
@@ -214,16 +211,20 @@ module Spree
214
211
  item.promo_total = promotion_adjustments.select(&:eligible?).sum(&:amount)
215
212
  end
216
213
  end
214
+ deprecate update_item_promotions: :update_promotions, deprecator: Spree::Deprecation
217
215
 
218
216
  # Update and select the best promotion adjustment for the order.
219
217
  # We don't update the order.promo_total yet. Order totals are updated later
220
218
  # in #update_adjustment_total since they include the totals from the order's
221
219
  # line items and/or shipments.
220
+ #
221
+ # DEPRECATED; this functionality is handled in #update_promotions
222
222
  def update_order_promotions
223
223
  promotion_adjustments = order.adjustments.select(&:promotion?)
224
224
  promotion_adjustments.each(&:recalculate)
225
225
  Spree::Config.promotion_chooser_class.new(promotion_adjustments).update
226
226
  end
227
+ deprecate update_order_promotions: :update_promotions, deprecator: Spree::Deprecation
227
228
 
228
229
  def update_taxes
229
230
  Spree::Config.tax_adjuster_class.new(order).adjust!
@@ -29,7 +29,7 @@ module Spree
29
29
  if response = payment.payment_method.try_void(payment)
30
30
  payment.handle_void_response(response)
31
31
  else
32
- payment.refunds.create!(amount: payment.credit_allowed, reason: refund_reason, perform_after_create: false).perform!
32
+ payment.refunds.create!(amount: payment.credit_allowed, reason: refund_reason).perform!
33
33
  end
34
34
  end
35
35
 
@@ -35,12 +35,36 @@ module Spree
35
35
  end
36
36
 
37
37
  def authorize!
38
- handle_payment_preconditions { process_authorization }
38
+ return unless check_payment_preconditions!
39
+
40
+ started_processing!
41
+
42
+ protect_from_connection_error do
43
+ response = payment_method.authorize(
44
+ money.money.cents,
45
+ source,
46
+ gateway_options,
47
+ )
48
+ pend! if handle_response(response)
49
+ end
39
50
  end
40
51
 
41
52
  # Captures the entire amount of a payment.
42
53
  def purchase!
43
- handle_payment_preconditions { process_purchase }
54
+ return unless check_payment_preconditions!
55
+
56
+ started_processing!
57
+
58
+ protect_from_connection_error do
59
+ response = payment_method.purchase(
60
+ money.money.cents,
61
+ source,
62
+ gateway_options,
63
+ )
64
+ complete! if handle_response(response)
65
+ end
66
+
67
+ capture_events.create!(amount: amount)
44
68
  end
45
69
 
46
70
  # Takes the amount in cents to capture.
@@ -62,7 +86,7 @@ module Spree
62
86
  money = ::Money.new(capture_amount, currency)
63
87
  capture_events.create!(amount: money.to_d)
64
88
  update!(amount: captured_amount)
65
- handle_response(response, :complete, :failure)
89
+ complete! if handle_response(response)
66
90
  end
67
91
  end
68
92
 
@@ -139,67 +163,46 @@ module Spree
139
163
 
140
164
  private
141
165
 
142
- def process_authorization
143
- started_processing!
144
- gateway_action(source, :authorize, :pend)
145
- end
166
+ # @raises Spree::Core::GatewayError
167
+ def check_payment_preconditions!
168
+ return if processing?
169
+ return unless payment_method
170
+ return unless payment_method.source_required?
146
171
 
147
- def process_purchase
148
- started_processing!
149
- gateway_action(source, :purchase, :complete)
150
- # This won't be called if gateway_action raises a GatewayError
151
- capture_events.create!(amount: amount)
152
- end
153
-
154
- def handle_payment_preconditions(&_block)
155
- unless block_given?
156
- raise ArgumentError.new("handle_payment_preconditions must be called with a block")
172
+ unless source
173
+ gateway_error(I18n.t('spree.payment_processing_failed'))
157
174
  end
158
175
 
159
- return if payment_method.nil?
160
- return if !payment_method.source_required?
161
-
162
- if source
163
- if !processing?
164
- if payment_method.supports?(source)
165
- yield
166
- else
167
- invalidate!
168
- raise Core::GatewayError.new(I18n.t('spree.payment_method_not_supported'))
169
- end
170
- end
171
- else
172
- raise Core::GatewayError.new(I18n.t('spree.payment_processing_failed'))
176
+ unless payment_method.supports?(source)
177
+ invalidate!
178
+ gateway_error(I18n.t('spree.payment_method_not_supported'))
173
179
  end
174
- end
175
180
 
176
- def gateway_action(source, action, success_state)
177
- protect_from_connection_error do
178
- response = payment_method.send(action, money.money.cents,
179
- source,
180
- gateway_options)
181
- handle_response(response, success_state, :failure)
182
- end
181
+ true
183
182
  end
184
183
 
185
- def handle_response(response, success_state, failure_state)
184
+ # @returns true if the response is successful
185
+ # @returns false (and calls #failure) if the response is not successful
186
+ def handle_response(response)
186
187
  record_response(response)
187
188
 
188
- if response.success?
189
- unless response.authorization.nil?
190
- self.response_code = response.authorization
191
- self.avs_response = response.avs_result['code']
192
-
193
- if response.cvv_result
194
- self.cvv_response_code = response.cvv_result['code']
195
- self.cvv_response_message = response.cvv_result['message']
196
- end
197
- end
198
- send("#{success_state}!")
199
- else
200
- send(failure_state)
189
+ unless response.success?
190
+ failure
201
191
  gateway_error(response)
192
+ return false
193
+ end
194
+
195
+ unless response.authorization.nil?
196
+ self.response_code = response.authorization
197
+ self.avs_response = response.avs_result['code']
198
+
199
+ if response.cvv_result
200
+ self.cvv_response_code = response.cvv_result['code']
201
+ self.cvv_response_message = response.cvv_result['message']
202
+ end
202
203
  end
204
+
205
+ true
203
206
  end
204
207
 
205
208
  def record_response(response)
@@ -207,9 +210,9 @@ module Spree
207
210
  end
208
211
 
209
212
  def protect_from_connection_error
210
- yield
213
+ yield
211
214
  rescue ActiveMerchant::ConnectionError => error
212
- gateway_error(error)
215
+ gateway_error(error)
213
216
  end
214
217
 
215
218
  def gateway_error(error)
@@ -8,9 +8,6 @@ module Spree
8
8
  class Payment < Spree::Base
9
9
  include Spree::Payment::Processing
10
10
 
11
- alias_attribute :identifier, :number
12
- deprecate :identifier, :identifier=, deprecator: Spree::Deprecation
13
-
14
11
  IDENTIFIER_CHARS = (('A'..'Z').to_a + ('0'..'9').to_a - %w(0 1 I O)).freeze
15
12
  NON_RISKY_AVS_CODES = ['B', 'D', 'H', 'J', 'M', 'Q', 'T', 'V', 'X', 'Y'].freeze
16
13
  RISKY_AVS_CODES = ['A', 'C', 'E', 'F', 'G', 'I', 'K', 'L', 'N', 'O', 'P', 'R', 'S', 'U', 'W', 'Z'].freeze
@@ -7,7 +7,6 @@ module Spree
7
7
  # @param attributes [Hash,ActionController::Parameters] attributes which are assigned to the new payment
8
8
  # * :payment_method_id Id of payment method used for this payment
9
9
  # * :source_attributes Attributes used to build the source of this payment. Usually a {CreditCard}
10
- # * :existing_card_id (Integer) Deprecated: The id of an existing {CreditCard} object to use
11
10
  # * :wallet_payment_source_id (Integer): The id of a {WalletPaymentSource} to use
12
11
  # @param request_env [Hash] rack env of user creating the payment
13
12
  # @param payment [Payment] Internal use only. Instead of making a new payment, change the attributes for an existing one.
@@ -29,13 +28,7 @@ module Spree
29
28
  @payment.request_env = @request_env if @request_env
30
29
  @payment.attributes = @attributes
31
30
 
32
- if source_attributes[:existing_card_id].present?
33
- Spree::Deprecation.warn(
34
- "Passing existing_card_id to PaymentCreate is deprecated. Use wallet_payment_source_id instead.",
35
- caller,
36
- )
37
- build_existing_card
38
- elsif source_attributes[:wallet_payment_source_id].present?
31
+ if source_attributes[:wallet_payment_source_id].present?
39
32
  build_from_wallet_payment_source
40
33
  else
41
34
  build_source
@@ -67,11 +60,6 @@ module Spree
67
60
  build_from_payment_source(wallet_payment_source.payment_source)
68
61
  end
69
62
 
70
- def build_existing_card
71
- credit_card = available_cards.find(source_attributes[:existing_card_id])
72
- build_from_payment_source(credit_card)
73
- end
74
-
75
63
  def build_from_payment_source(payment_source)
76
64
  # FIXME: does this work?
77
65
  if source_attributes[:verification_value]
@@ -57,13 +57,12 @@ module Spree
57
57
  end
58
58
  end
59
59
 
60
- def void(_response_code, _credit_card, _options = {})
61
- ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
62
- end
63
-
64
- # @see Spree::PaymentMethod#try_void
65
- def try_void(_payment)
66
- ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
60
+ def void(_response_code, _credit_card, options = {})
61
+ if options[:originator].completed?
62
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
63
+ else
64
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
65
+ end
67
66
  end
68
67
 
69
68
  def test?
@@ -14,7 +14,7 @@ module Spree
14
14
  end
15
15
 
16
16
  def partial_name
17
- deprecated_method_type_override || 'gateway'
17
+ 'gateway'
18
18
  end
19
19
 
20
20
  def supports?(source)
@@ -27,8 +27,6 @@ module Spree
27
27
  source_ids = order.payments.where(payment_method_id: id).pluck(:source_id).uniq
28
28
  payment_source_class.where(id: source_ids).select(&:reusable?)
29
29
  end
30
- alias_method :sources_by_order, :reusable_sources_by_order
31
- deprecate sources_by_order: :reusable_sources_by_order, deprecator: Spree::Deprecation
32
30
 
33
31
  def reusable_sources(order)
34
32
  if order.completed?
@@ -22,5 +22,13 @@ module Spree
22
22
  ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, message: FAILURE_MESSAGE, test: true)
23
23
  end
24
24
  end
25
+
26
+ def void(_response_code, options = {})
27
+ if options[:originator].completed?
28
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
29
+ else
30
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
31
+ end
32
+ end
25
33
  end
26
34
  end
@@ -13,6 +13,7 @@ module Spree
13
13
  #
14
14
  class PaymentMethod < Spree::Base
15
15
  include Spree::Preferences::Persistable
16
+ class UnsupportedPaymentMethod < StandardError; end
16
17
 
17
18
  preference :server, :string, default: 'test'
18
19
  preference :test_mode, :boolean, default: true
@@ -21,19 +22,6 @@ module Spree
21
22
 
22
23
  acts_as_list
23
24
 
24
- # @private
25
- def self.const_missing(name)
26
- if name == :DISPLAY
27
- Spree::Deprecation.warn(
28
- "#{self}::DISPLAY has been deprecated and will be removed in Solidus v3.",
29
- caller
30
- )
31
- const_set(:DISPLAY, [:both, :front_end, :back_end])
32
- else
33
- super
34
- end
35
- end
36
-
37
25
  validates :name, :type, presence: true
38
26
 
39
27
  has_many :payments, class_name: "Spree::Payment", inverse_of: :payment_method
@@ -70,50 +58,18 @@ module Spree
70
58
  end
71
59
 
72
60
  class << self
73
- # @deprecated Use Spree::Config.environment.payment_methods instead
74
- def providers
75
- Spree::Deprecation.warn 'Spree::PaymentMethod.providers is deprecated and will be deleted in Solidus 3.0. ' \
76
- 'Please use Rails.application.config.spree.payment_methods instead'
77
- Spree::Config.environment.payment_methods
78
- end
79
-
80
- # @deprecated Use {.active}, {.available_to_users}, and {.available_to_admin} scopes instead.
81
- def available(display_on = nil, store: nil)
82
- Spree::Deprecation.warn "Spree::PaymentMethod.available is deprecated."\
83
- "Please use .active, .available_to_users, and .available_to_admin scopes instead."\
84
- "For payment methods associated with a specific store, use Spree::PaymentMethod.available_to_store(your_store)"\
85
- " as the base applying any further filtering"
86
-
87
- display_on = display_on.to_s
88
-
89
- available_payment_methods =
90
- case display_on
91
- when 'front_end'
92
- active.available_to_users
93
- when 'back_end'
94
- active.available_to_admin
95
- else
96
- active.available_to_users.available_to_admin
97
- end
98
- available_payment_methods.select do |payment|
99
- store.nil? || store.payment_methods.empty? || store.payment_methods.include?(payment)
100
- end
101
- end
102
-
103
61
  def model_name
104
62
  ModelName.new(self, Spree)
105
63
  end
106
64
 
107
- # @deprecated Use .active.any? instead
108
- def active?
109
- Spree::Deprecation.warn "#{self}.active? is deprecated. Use #{self}.active.any? instead"
110
- where(type: to_s, active: true).count > 0
111
- end
112
-
113
- # @deprecated Use .with_discarded.find instead
114
- def find_with_destroyed(*args)
115
- Spree::Deprecation.warn "#{self}.find_with_destroyed is deprecated. Use #{self}.with_discarded.find instead"
116
- unscoped { find(*args) }
65
+ def find_sti_class(type_name)
66
+ super(type_name)
67
+ rescue ActiveRecord::SubclassNotFound
68
+ raise UnsupportedPaymentMethod, "Found invalid payment type '#{type_name}'.\n"\
69
+ "This may happen after switching payment service provider, when payment methods "\
70
+ "reference old types that are not supported any more.\n"\
71
+ "If that is the case, consider running 'rake payment_method:deprecate_unsupported_payment_methods' "\
72
+ "to fix the issue."
117
73
  end
118
74
  end
119
75
 
@@ -141,8 +97,6 @@ module Spree
141
97
 
142
98
  @gateway ||= gateway_class.new(gateway_options)
143
99
  end
144
- alias_method :provider, :gateway
145
- deprecate provider: :gateway, deprecator: Spree::Deprecation
146
100
 
147
101
  # Represents all preferences as a Hash
148
102
  #
@@ -162,29 +116,6 @@ module Spree
162
116
  raise ::NotImplementedError, "You must implement payment_source_class method for #{self.class}."
163
117
  end
164
118
 
165
- # @deprecated Use {Spree::PaymentMethod#available_to_users=} and {Spree::PaymentMethod#available_to_admin=} instead
166
- def display_on=(value)
167
- Spree::Deprecation.warn "Spree::PaymentMethod#display_on= is deprecated."\
168
- "Please use #available_to_users= and #available_to_admin= instead."
169
- self.available_to_users = value.blank? || value == 'front_end'
170
- self.available_to_admin = value.blank? || value == 'back_end'
171
- end
172
-
173
- # @deprecated Use {Spree::PaymentMethod#available_to_users} and {Spree::PaymentMethod#available_to_admin} instead
174
- def display_on
175
- Spree::Deprecation.warn "Spree::PaymentMethod#display_on is deprecated."\
176
- "Please use #available_to_users and #available_to_admin instead."
177
- if available_to_users? && available_to_admin?
178
- ''
179
- elsif available_to_users?
180
- 'front_end'
181
- elsif available_to_admin?
182
- 'back_end'
183
- else
184
- 'none'
185
- end
186
- end
187
-
188
119
  # Used as partial name for your payment method
189
120
  #
190
121
  # Currently your payment method needs to provide these partials:
@@ -205,21 +136,7 @@ module Spree
205
136
  # The view that represents your payment method on orders through the api
206
137
  #
207
138
  def partial_name
208
- deprecated_method_type_override || type.demodulize.underscore
209
- end
210
-
211
- # :nodoc:
212
- # If method_type has been overridden, call it and return the value, otherwise return nil
213
- def deprecated_method_type_override
214
- if method(:method_type).owner != Spree::PaymentMethod
215
- Spree::Deprecation.warn "#{method(:method_type).owner} is overriding PaymentMethod#method_type. This is deprecated and will be removed from Solidus 3.0 (override partial_name instead).", caller[1..-1]
216
- method_type
217
- end
218
- end
219
-
220
- def method_type
221
- Spree::Deprecation.warn "method_type is deprecated and will be removed from Solidus 3.0 (use partial_name instead)", caller
222
- partial_name
139
+ type.demodulize.underscore
223
140
  end
224
141
 
225
142
  def payment_profiles_supported?
@@ -256,16 +173,22 @@ module Spree
256
173
  # Return +false+ or +nil+ if the void is not possible anymore - because it was already processed by the bank.
257
174
  # Solidus will refund the amount of the payment in this case.
258
175
  #
259
- # @return [ActiveMerchant::Billing::Response] with +true+ if the void succeeded
260
- # @return [ActiveMerchant::Billing::Response] with +false+ if the void failed
261
- # @return [false] if it can't be voided at this time
176
+ # This default implementation will void the payment if void succeeds,
177
+ # otherwise it returns false.
262
178
  #
263
- def try_void(_payment)
264
- raise ::NotImplementedError,
265
- "You need to implement `try_void` for #{self.class.name}. In that " \
266
- 'return a ActiveMerchant::Billing::Response object if the void succeeds '\
267
- 'or `false|nil` if the void is not possible anymore. ' \
268
- 'Solidus will refund the amount of the payment then.'
179
+ # @api public
180
+ # @param payment [Spree::Payment] the payment to void
181
+ # @return [ActiveMerchant::Billing::Response|FalseClass]
182
+ def try_void(payment)
183
+ void_attempt = if payment.payment_method.payment_profiles_supported?
184
+ void(payment.transaction_id, payment.source, { originator: payment })
185
+ else
186
+ void(payment.transaction_id, { originator: payment })
187
+ end
188
+
189
+ return void_attempt if void_attempt.success?
190
+
191
+ false
269
192
  end
270
193
 
271
194
  def store_credit?
@@ -277,14 +200,7 @@ module Spree
277
200
  # Represents the gateway class of this payment method
278
201
  #
279
202
  def gateway_class
280
- if respond_to? :provider_class
281
- Spree::Deprecation.warn \
282
- "provider_class is deprecated and will be removed from Solidus 3.0 " \
283
- "(use gateway_class instead)"
284
- public_send :provider_class
285
- else
286
- raise ::NotImplementedError, "You must implement gateway_class method for #{self.class}."
287
- end
203
+ raise ::NotImplementedError, "You must implement gateway_class method for #{self.class}."
288
204
  end
289
205
  end
290
206
  end
@@ -13,7 +13,7 @@ module Spree
13
13
  delegate :tax_rates, to: :variant
14
14
 
15
15
  validate :check_price
16
- validates :amount, allow_nil: true, numericality: {
16
+ validates :amount, numericality: {
17
17
  greater_than_or_equal_to: 0,
18
18
  less_than_or_equal_to: MAXIMUM_AMOUNT
19
19
  }
@@ -30,7 +30,7 @@ module Spree
30
30
  money_methods :amount, :price
31
31
  alias_method :money, :display_amount
32
32
 
33
- self.whitelisted_ransackable_attributes = %w(amount variant_id currency country_iso)
33
+ self.allowed_ransackable_attributes = %w(amount variant_id currency country_iso)
34
34
 
35
35
  # An alias for #amount
36
36
  def price
@@ -55,7 +55,7 @@ module Spree
55
55
 
56
56
  def display_country
57
57
  if country_iso
58
- "#{country_iso} (#{country.name})"
58
+ "#{country_iso} (#{I18n.t(country_iso, scope: [:spree, :country_names])})"
59
59
  else
60
60
  I18n.t(:any_country, scope: [:spree, :admin, :prices])
61
61
  end
@@ -29,25 +29,25 @@ module Spree
29
29
  scope :descend_by_name, -> { order(name: :desc) }
30
30
 
31
31
  add_search_scope :ascend_by_master_price do
32
- joins(master: :default_price).select('spree_products.* , spree_prices.amount')
32
+ joins(master: :prices).select('spree_products.* , spree_prices.amount')
33
33
  .order(Spree::Price.arel_table[:amount].asc)
34
34
  end
35
35
 
36
36
  add_search_scope :descend_by_master_price do
37
- joins(master: :default_price).select('spree_products.* , spree_prices.amount')
37
+ joins(master: :prices).select('spree_products.* , spree_prices.amount')
38
38
  .order(Spree::Price.arel_table[:amount].desc)
39
39
  end
40
40
 
41
41
  add_search_scope :price_between do |low, high|
42
- joins(master: :default_price).where(Price.table_name => { amount: low..high })
42
+ joins(master: :prices).where(Price.table_name => { amount: low..high })
43
43
  end
44
44
 
45
45
  add_search_scope :master_price_lte do |price|
46
- joins(master: :default_price).where("#{price_table_name}.amount <= ?", price)
46
+ joins(master: :prices).where("#{price_table_name}.amount <= ?", price)
47
47
  end
48
48
 
49
49
  add_search_scope :master_price_gte do |price|
50
- joins(master: :default_price).where("#{price_table_name}.amount >= ?", price)
50
+ joins(master: :prices).where("#{price_table_name}.amount >= ?", price)
51
51
  end
52
52
 
53
53
  # This scope selects products in taxon AND all its descendants
@@ -194,38 +194,29 @@ module Spree
194
194
  group("spree_products.id").joins(:taxons).where(Spree::Taxon.arel_table[:name].eq(name))
195
195
  end
196
196
 
197
- def self.with_variant_sku_cont(sku)
198
- sku_match = "%#{sku}%"
197
+ def self.with_all_variant_sku_cont(sku)
199
198
  variant_table = Spree::Variant.arel_table
200
- subquery = Spree::Variant.where(variant_table[:sku].matches(sku_match).and(variant_table[:product_id].eq(arel_table[:id])))
199
+ subquery = Spree::Variant.with_discarded.where(
200
+ variant_table[:sku].matches("%#{sku}%").and(
201
+ variant_table[:product_id].eq(arel_table[:id])
202
+ )
203
+ )
201
204
  where(subquery.arel.exists)
202
205
  end
203
206
 
204
- def self.distinct_by_product_ids(sort_order = nil)
205
- Spree::Deprecation.warn "Product.distinct_by_product_ids is deprecated and should not be used"
206
-
207
- sort_column = sort_order.split(" ").first
208
-
209
- # Postgres will complain when using ordering by expressions not present in
210
- # SELECT DISTINCT. e.g.
211
- #
212
- # PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY
213
- # expressions must appear in select list. e.g.
214
- #
215
- # SELECT DISTINCT "spree_products".* FROM "spree_products" LEFT OUTER JOIN
216
- # "spree_variants" ON "spree_variants"."product_id" = "spree_products"."id" AND "spree_variants"."is_master" = 't'
217
- # AND "spree_variants"."deleted_at" IS NULL LEFT OUTER JOIN "spree_prices" ON
218
- # "spree_prices"."variant_id" = "spree_variants"."id" AND "spree_prices"."currency" = 'USD'
219
- # AND "spree_prices"."deleted_at" IS NULL WHERE "spree_products"."deleted_at" IS NULL AND ('t'='t')
220
- # ORDER BY "spree_prices"."amount" ASC LIMIT 10 OFFSET 0
221
- #
222
- # Don't allow sort_column, a variable coming from params,
223
- # to be anything but a column in the database
224
- if ActiveRecord::Base.connection.adapter_name == 'PostgreSQL' && !column_names.include?(sort_column)
225
- all
226
- else
227
- distinct
228
- end
207
+ def self.with_kept_variant_sku_cont(sku)
208
+ variant_table = Spree::Variant.arel_table
209
+ subquery = Spree::Variant.where(
210
+ variant_table[:sku].matches("%#{sku}%").and(
211
+ variant_table[:product_id].eq(arel_table[:id])
212
+ )
213
+ )
214
+ where(subquery.arel.exists)
215
+ end
216
+
217
+ def self.with_variant_sku_cont(sku)
218
+ Spree::Deprecation.warn("use .with_kept_variant_sku_cont instead")
219
+ with_kept_variant_sku_cont(sku)
229
220
  end
230
221
 
231
222
  class << self