solidus_core 3.0.0 → 4.5.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 (444) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -2
  3. data/Rakefile +7 -2
  4. data/app/assets/images/logo/solidus.svg +18 -1
  5. data/app/assets/images/logo/solidus_logo.png +0 -0
  6. data/app/controllers/spree/base_controller.rb +1 -3
  7. data/app/helpers/spree/base_helper.rb +3 -3
  8. data/app/helpers/spree/core/controller_helpers/auth.rb +66 -0
  9. data/app/helpers/spree/core/controller_helpers/common.rb +82 -0
  10. data/app/helpers/spree/core/controller_helpers/order.rb +86 -0
  11. data/app/helpers/spree/core/controller_helpers/payment_parameters.rb +165 -0
  12. data/{lib/spree/core/controller_helpers/current_host.rb → app/helpers/spree/core/controller_helpers/pricing.rb} +6 -4
  13. data/app/helpers/spree/core/controller_helpers/search.rb +16 -0
  14. data/app/helpers/spree/core/controller_helpers/store.rb +19 -0
  15. data/app/helpers/spree/core/controller_helpers/strong_parameters.rb +74 -0
  16. data/app/helpers/spree/products_helper.rb +2 -2
  17. data/app/mailers/spree/base_mailer.rb +1 -1
  18. data/app/mailers/spree/carton_mailer.rb +1 -1
  19. data/app/mailers/spree/order_mailer.rb +3 -3
  20. data/app/mailers/spree/reimbursement_mailer.rb +1 -1
  21. data/app/models/concerns/spree/active_storage_adapter/attachment.rb +30 -11
  22. data/app/models/concerns/spree/active_storage_adapter/normalization.rb +1 -1
  23. data/app/models/concerns/spree/active_storage_adapter.rb +1 -18
  24. data/app/models/concerns/spree/default_price.rb +30 -10
  25. data/app/models/concerns/spree/display_money.rb +1 -1
  26. data/app/models/concerns/spree/metadata.rb +64 -0
  27. data/app/models/concerns/spree/named_type.rb +2 -0
  28. data/app/models/concerns/spree/ordered_property_value_list.rb +2 -2
  29. data/app/models/concerns/spree/ransackable_attributes.rb +9 -5
  30. data/app/models/concerns/spree/user_address_book.rb +19 -10
  31. data/app/models/concerns/spree/user_methods.rb +40 -6
  32. data/app/models/spree/address.rb +11 -9
  33. data/app/models/spree/adjustment.rb +15 -76
  34. data/app/models/spree/adjustment_reason.rb +2 -0
  35. data/app/models/spree/calculator/flat_fee.rb +21 -0
  36. data/app/models/spree/calculator/returns/default_refund_amount.rb +1 -1
  37. data/app/models/spree/carton.rb +3 -3
  38. data/app/models/spree/core/state_machines/inventory_unit.rb +42 -0
  39. data/app/models/spree/core/state_machines/order/class_methods.rb +217 -0
  40. data/app/models/spree/core/state_machines/order.rb +42 -0
  41. data/app/models/spree/core/state_machines/payment.rb +61 -0
  42. data/app/models/spree/core/state_machines/reimbursement.rb +33 -0
  43. data/app/models/spree/core/state_machines/return_authorization.rb +32 -0
  44. data/app/models/spree/core/state_machines/return_item/acceptance_status.rb +51 -0
  45. data/app/models/spree/core/state_machines/return_item/reception_status.rb +42 -0
  46. data/app/models/spree/core/state_machines/shipment.rb +58 -0
  47. data/app/models/spree/country.rb +1 -1
  48. data/app/models/spree/credit_card.rb +13 -10
  49. data/app/models/spree/customer_return.rb +6 -3
  50. data/app/models/spree/deprecated_configurable_class.rb +40 -0
  51. data/app/models/spree/fulfilment_changer.rb +56 -29
  52. data/app/models/spree/image/active_storage_attachment.rb +2 -7
  53. data/app/models/spree/image/paperclip_attachment.rb +2 -2
  54. data/app/models/spree/inventory_unit.rb +2 -2
  55. data/app/models/spree/item_total.rb +28 -0
  56. data/app/models/spree/legacy_user.rb +1 -0
  57. data/app/models/spree/line_item.rb +26 -8
  58. data/app/models/spree/log_entry.rb +98 -1
  59. data/app/models/spree/money.rb +120 -0
  60. data/app/models/spree/null_promotion_adjuster.rb +13 -0
  61. data/app/models/spree/null_promotion_advertiser.rb +9 -0
  62. data/app/models/spree/null_promotion_finder.rb +9 -0
  63. data/app/models/spree/null_promotion_handler.rb +44 -0
  64. data/app/models/spree/option_type.rb +1 -1
  65. data/app/models/spree/option_value.rb +4 -3
  66. data/app/models/spree/order/number_generator.rb +7 -1
  67. data/app/models/spree/order.rb +143 -96
  68. data/app/models/spree/order_cancellations.rb +8 -8
  69. data/app/models/spree/order_inventory.rb +7 -5
  70. data/app/models/spree/order_merger.rb +5 -7
  71. data/app/models/spree/order_mutex.rb +2 -2
  72. data/app/models/spree/order_shipping.rb +15 -19
  73. data/app/models/spree/order_taxation.rb +7 -4
  74. data/app/models/spree/order_update_attributes.rb +3 -1
  75. data/app/models/spree/order_updater.rb +25 -63
  76. data/app/models/spree/payment/processing.rb +60 -57
  77. data/app/models/spree/payment.rb +14 -27
  78. data/app/models/spree/payment_create.rb +1 -1
  79. data/app/models/spree/payment_method/bogus_credit_card.rb +18 -14
  80. data/app/models/spree/payment_method/credit_card.rb +0 -4
  81. data/app/models/spree/payment_method/simple_bogus_credit_card.rb +18 -4
  82. data/app/models/spree/payment_method/store_credit.rb +1 -1
  83. data/app/models/spree/payment_method.rb +29 -10
  84. data/app/models/spree/payment_source.rb +5 -1
  85. data/app/models/spree/permission_set.rb +11 -0
  86. data/app/models/spree/permission_sets/base.rb +45 -0
  87. data/app/models/spree/permission_sets/configuration_display.rb +53 -0
  88. data/app/models/spree/permission_sets/configuration_management.rb +52 -0
  89. data/app/models/spree/permission_sets/dashboard_display.rb +28 -0
  90. data/app/models/spree/permission_sets/default_customer.rb +83 -0
  91. data/app/models/spree/permission_sets/order_display.rb +50 -0
  92. data/app/models/spree/permission_sets/order_management.rb +50 -0
  93. data/app/models/spree/permission_sets/product_display.rb +43 -0
  94. data/app/models/spree/permission_sets/product_management.rb +47 -0
  95. data/app/models/spree/permission_sets/restricted_stock_display.rb +33 -0
  96. data/app/models/spree/permission_sets/restricted_stock_management.rb +33 -0
  97. data/app/models/spree/permission_sets/stock_display.rb +26 -0
  98. data/app/models/spree/permission_sets/stock_management.rb +26 -0
  99. data/app/models/spree/permission_sets/super_user.rb +26 -0
  100. data/app/models/spree/permission_sets/user_display.rb +27 -0
  101. data/app/models/spree/permission_sets/user_management.rb +44 -0
  102. data/app/models/spree/preference.rb +1 -1
  103. data/app/models/spree/price.rb +3 -3
  104. data/app/models/spree/product/scopes.rb +23 -10
  105. data/app/models/spree/product.rb +30 -23
  106. data/app/models/spree/product_property.rb +1 -1
  107. data/app/models/spree/property.rb +1 -1
  108. data/app/models/spree/refund.rb +13 -3
  109. data/app/models/spree/refund_reason.rb +6 -1
  110. data/app/models/spree/reimbursement.rb +6 -6
  111. data/app/models/spree/reimbursement_performer.rb +3 -3
  112. data/app/models/spree/reimbursement_tax_calculator.rb +3 -3
  113. data/app/models/spree/reimbursement_type/credit.rb +1 -1
  114. data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +6 -6
  115. data/app/models/spree/reimbursement_type/store_credit.rb +1 -1
  116. data/app/models/spree/reimbursement_type.rb +6 -1
  117. data/app/models/spree/return_authorization.rb +3 -1
  118. data/app/models/spree/return_item.rb +13 -15
  119. data/app/models/spree/return_reason.rb +6 -1
  120. data/app/models/spree/role.rb +3 -1
  121. data/app/models/spree/role_permission.rb +8 -0
  122. data/app/models/spree/shipment.rb +12 -10
  123. data/app/models/spree/shipping_category.rb +2 -0
  124. data/app/models/spree/shipping_rate.rb +2 -3
  125. data/app/models/spree/shipping_rate_tax.rb +1 -1
  126. data/app/models/spree/{order_contents.rb → simple_order_contents.rb} +10 -13
  127. data/app/models/spree/state.rb +1 -1
  128. data/app/models/spree/stock/allocator/on_hand_first.rb +2 -2
  129. data/app/models/spree/stock/availability.rb +11 -3
  130. data/app/models/spree/stock/estimator.rb +1 -1
  131. data/app/models/spree/stock/inventory_unit_builder.rb +1 -1
  132. data/app/models/spree/stock/package.rb +2 -2
  133. data/app/models/spree/stock/quantifier.rb +12 -8
  134. data/app/models/spree/stock/simple_coordinator.rb +38 -28
  135. data/app/models/spree/stock/splitter/shipping_category.rb +1 -1
  136. data/app/models/spree/stock_item.rb +2 -1
  137. data/app/models/spree/stock_location.rb +7 -7
  138. data/app/models/spree/stock_movement.rb +2 -2
  139. data/app/models/spree/store.rb +3 -1
  140. data/app/models/spree/store_credit.rb +31 -16
  141. data/app/models/spree/store_credit_event.rb +4 -3
  142. data/app/models/spree/store_credit_prioritizer.rb +17 -0
  143. data/app/models/spree/store_credit_reason.rb +6 -1
  144. data/app/models/spree/store_selector/by_server_name.rb +1 -1
  145. data/app/models/spree/tax/item_tax.rb +3 -2
  146. data/app/models/spree/tax/order_tax.rb +3 -1
  147. data/app/models/spree/tax/tax_helpers.rb +14 -3
  148. data/app/models/spree/tax/tax_location.rb +4 -7
  149. data/app/models/spree/tax_calculator/default.rb +32 -1
  150. data/app/models/spree/tax_calculator/shipping_rate.rb +2 -2
  151. data/app/models/spree/tax_category.rb +3 -1
  152. data/app/models/spree/tax_rate.rb +14 -1
  153. data/app/models/spree/taxon/active_storage_attachment.rb +2 -2
  154. data/app/models/spree/taxon/paperclip_attachment.rb +4 -4
  155. data/app/models/spree/taxon.rb +25 -3
  156. data/app/models/spree/taxon_brand_selector.rb +22 -0
  157. data/app/models/spree/taxonomy.rb +4 -3
  158. data/app/models/spree/unauthorized_redirect_handler.rb +24 -0
  159. data/app/models/spree/unit_cancel.rb +1 -2
  160. data/app/models/spree/user_address.rb +9 -3
  161. data/app/models/spree/user_last_url_storer/rules/authentication_rule.rb +1 -1
  162. data/app/models/spree/variant/price_selector.rb +25 -8
  163. data/app/models/spree/variant/scopes.rb +4 -0
  164. data/app/models/spree/variant/vat_price_generator.rb +1 -1
  165. data/app/models/spree/variant.rb +64 -37
  166. data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +4 -4
  167. data/app/models/spree/wallet.rb +2 -2
  168. data/app/models/spree/zone.rb +1 -1
  169. data/app/subscribers/spree/order_mailer_subscriber.rb +35 -0
  170. data/app/views/layouts/spree/base_mailer.html.erb +2 -2
  171. data/app/views/spree/order_mailer/cancel_email.html.erb +1 -1
  172. data/app/views/spree/order_mailer/cancel_email.text.erb +1 -1
  173. data/app/views/spree/order_mailer/confirm_email.html.erb +5 -5
  174. data/app/views/spree/order_mailer/confirm_email.text.erb +5 -5
  175. data/app/views/spree/order_mailer/inventory_cancellation_email.html.erb +0 -1
  176. data/config/i18n-tasks.yml +134 -0
  177. data/config/locales/en.yml +439 -338
  178. data/db/default/spree/permission_sets.rb +10 -0
  179. data/db/default/spree/return_reasons.rb +3 -1
  180. data/db/default/spree/states.rb +2 -2
  181. data/db/migrate/20160101010000_solidus_one_four.rb +0 -127
  182. data/db/migrate/20180710170104_create_spree_store_credit_reasons_table.rb +2 -2
  183. data/db/migrate/20201127212108_add_type_before_removal_to_spree_payment_methods.rb +7 -0
  184. data/db/migrate/20210312061050_change_column_null_on_prices.rb +7 -0
  185. data/db/migrate/20210815004823_add_unique_index_to_option_values_variants.rb +16 -0
  186. data/db/migrate/20220419170826_remove_archived_user_addresses.rb +12 -0
  187. data/db/migrate/20220805202442_add_level_to_spree_tax_rates.rb +5 -0
  188. data/db/migrate/20221123152807_add_shipping_category_to_spree_variants.rb +5 -0
  189. data/db/migrate/20230321161854_change_column_null_option_values_option_type_id.rb +5 -0
  190. data/db/migrate/20230425103509_remove_taxon_position.rb +5 -0
  191. data/db/migrate/20230427095534_drop_deprecated_address_id_from_shipments.rb +11 -0
  192. data/db/migrate/20240821173254_create_spree_permission_sets_in_core.rb +9 -0
  193. data/db/migrate/20240821173341_create_spree_roles_permissions_in_core.rb +9 -0
  194. data/db/migrate/20240821173641_add_description_to_spree_roles.rb +5 -0
  195. data/db/migrate/20240904152041_add_privilege_and_category_to_spree_permission_sets.rb +6 -0
  196. data/db/migrate/20250129061658_add_metadata_to_spree_resources.rb +28 -0
  197. data/db/migrate/20250201172950_add_gtin_and_condition_to_spree_variant.rb +6 -0
  198. data/db/migrate/20250207104016_add_primary_taxon_to_products.rb +7 -0
  199. data/db/migrate/20250221152004_add_metadata_to_users.rb +13 -0
  200. data/db/seeds.rb +5 -1
  201. data/lib/generators/solidus/install/app_templates/authentication/custom.rb +16 -0
  202. data/lib/generators/solidus/install/app_templates/authentication/devise.rb +16 -0
  203. data/lib/generators/solidus/install/app_templates/authentication/existing.rb +10 -0
  204. data/lib/generators/solidus/install/app_templates/authentication/none.rb +1 -0
  205. data/lib/generators/solidus/install/app_templates/frontend/none.rb +1 -0
  206. data/lib/generators/solidus/install/app_templates/frontend/starter.rb +1 -0
  207. data/lib/generators/solidus/install/app_templates/payment_method/braintree.rb +5 -0
  208. data/lib/generators/solidus/install/app_templates/payment_method/none.rb +1 -0
  209. data/lib/generators/solidus/install/app_templates/payment_method/paypal.rb +5 -0
  210. data/lib/generators/solidus/install/app_templates/payment_method/stripe.rb +5 -0
  211. data/lib/generators/solidus/install/install_generator.rb +210 -156
  212. data/lib/generators/solidus/install/templates/config/initializers/spree.rb.tt +27 -33
  213. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/backend/all.js +2 -2
  214. data/lib/generators/solidus/update/templates/config/initializers/new_solidus_defaults.rb.tt +30 -0
  215. data/lib/generators/solidus/update/update_generator.rb +124 -0
  216. data/lib/generators/spree/custom_user/custom_user_generator.rb +6 -4
  217. data/lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt +2 -6
  218. data/lib/generators/spree/custom_user/templates/migration.rb.tt +7 -3
  219. data/lib/generators/spree/dummy/dummy_generator.rb +12 -9
  220. data/lib/generators/spree/dummy/templates/rails/application.rb.tt +1 -2
  221. data/lib/generators/spree/dummy/templates/rails/database.yml +48 -63
  222. data/lib/generators/spree/dummy/templates/rails/manifest.js +3 -0
  223. data/lib/generators/spree/dummy/templates/rails/test.rb +7 -2
  224. data/lib/spree/app_configuration.rb +220 -71
  225. data/lib/spree/bus.rb +11 -0
  226. data/lib/spree/core/class_constantizer.rb +2 -2
  227. data/lib/spree/core/controller_helpers/auth.rb +5 -69
  228. data/lib/spree/core/controller_helpers/common.rb +5 -80
  229. data/lib/spree/core/controller_helpers/order.rb +5 -86
  230. data/lib/spree/core/controller_helpers/payment_parameters.rb +5 -165
  231. data/lib/spree/core/controller_helpers/pricing.rb +5 -17
  232. data/lib/spree/core/controller_helpers/search.rb +5 -14
  233. data/lib/spree/core/controller_helpers/store.rb +5 -17
  234. data/lib/spree/core/controller_helpers/strong_parameters.rb +5 -71
  235. data/lib/spree/core/engine.rb +49 -16
  236. data/lib/spree/core/environment/calculators.rb +35 -3
  237. data/lib/spree/core/environment/promotions.rb +25 -4
  238. data/lib/spree/core/environment_extension.rb +16 -2
  239. data/lib/spree/core/importer/order.rb +6 -6
  240. data/lib/spree/core/importer/product.rb +3 -3
  241. data/lib/spree/core/nested_class_set.rb +28 -0
  242. data/lib/spree/core/null_promotion_configuration.rb +84 -0
  243. data/lib/spree/core/product_duplicator.rb +1 -1
  244. data/lib/spree/core/product_filters.rb +2 -2
  245. data/lib/spree/core/search/base.rb +18 -9
  246. data/lib/spree/core/search/variant.rb +2 -2
  247. data/lib/spree/core/state_machines/inventory_unit.rb +5 -40
  248. data/lib/spree/core/state_machines/order.rb +5 -247
  249. data/lib/spree/core/state_machines/payment.rb +5 -59
  250. data/lib/spree/core/state_machines/reimbursement.rb +5 -31
  251. data/lib/spree/core/state_machines/return_authorization.rb +5 -30
  252. data/lib/spree/core/state_machines/return_item/acceptance_status.rb +5 -49
  253. data/lib/spree/core/state_machines/return_item/reception_status.rb +5 -40
  254. data/lib/spree/core/state_machines/shipment.rb +5 -56
  255. data/lib/spree/core/state_machines.rb +48 -81
  256. data/lib/spree/core/stock_configuration.rb +18 -0
  257. data/lib/spree/core/validators/email.rb +2 -4
  258. data/lib/spree/core/version.rb +5 -1
  259. data/lib/spree/core/versioned_value.rb +75 -0
  260. data/lib/spree/core.rb +40 -16
  261. data/lib/spree/deprecated_instance_variable_proxy.rb +57 -0
  262. data/lib/spree/deprecation.rb +3 -51
  263. data/lib/spree/deprecator.rb +9 -0
  264. data/lib/spree/i18n.rb +1 -1
  265. data/lib/spree/mailer_previews/carton_preview.rb +1 -1
  266. data/lib/spree/migration_helpers.rb +3 -3
  267. data/lib/spree/migrations.rb +13 -11
  268. data/lib/spree/money.rb +5 -118
  269. data/lib/spree/permission_sets/base.rb +5 -30
  270. data/lib/spree/permission_sets/configuration_display.rb +5 -23
  271. data/lib/spree/permission_sets/configuration_management.rb +5 -23
  272. data/lib/spree/permission_sets/dashboard_display.rb +5 -9
  273. data/lib/spree/permission_sets/default_customer.rb +5 -35
  274. data/lib/spree/permission_sets/order_display.rb +5 -19
  275. data/lib/spree/permission_sets/order_management.rb +5 -20
  276. data/lib/spree/permission_sets/product_display.rb +5 -17
  277. data/lib/spree/permission_sets/product_management.rb +5 -19
  278. data/lib/spree/permission_sets/restricted_stock_display.rb +5 -16
  279. data/lib/spree/permission_sets/restricted_stock_management.rb +5 -16
  280. data/lib/spree/permission_sets/stock_display.rb +5 -10
  281. data/lib/spree/permission_sets/stock_management.rb +5 -10
  282. data/lib/spree/permission_sets/super_user.rb +5 -9
  283. data/lib/spree/permission_sets/user_display.rb +5 -11
  284. data/lib/spree/permission_sets/user_management.rb +5 -23
  285. data/lib/spree/permission_sets.rb +5 -18
  286. data/lib/spree/permitted_attributes.rb +35 -14
  287. data/lib/spree/preferences/configuration.rb +88 -0
  288. data/lib/spree/preferences/persistable.rb +7 -1
  289. data/lib/spree/preferences/preferable.rb +13 -0
  290. data/lib/spree/preferences/preferable_class_methods.rb +12 -4
  291. data/lib/spree/preferences/preference_differentiator.rb +29 -0
  292. data/lib/spree/preferences/static_model_preferences.rb +25 -10
  293. data/lib/spree/preferences/store.rb +2 -2
  294. data/lib/spree/testing_support/blacklist_urls.rb +1 -1
  295. data/lib/spree/testing_support/bus_helpers.rb +101 -0
  296. data/lib/spree/testing_support/capybara_ext.rb +11 -1
  297. data/lib/spree/testing_support/common_rake.rb +76 -23
  298. data/lib/spree/testing_support/dummy_ability.rb +7 -0
  299. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/backend/all.js +1 -1
  300. data/lib/spree/testing_support/dummy_app/assets/stylesheets/solidus_admin/tailwind.css +1 -0
  301. data/lib/spree/testing_support/dummy_app/database.yml +39 -28
  302. data/lib/spree/testing_support/dummy_app/migrations.rb +8 -15
  303. data/lib/spree/testing_support/dummy_app/rake_tasks.rb +3 -10
  304. data/lib/spree/testing_support/dummy_app.rb +71 -42
  305. data/lib/spree/testing_support/extension_rake.rb +2 -2
  306. data/lib/spree/testing_support/factories/address_factory.rb +9 -13
  307. data/lib/spree/testing_support/factories/adjustment_factory.rb +1 -13
  308. data/lib/spree/testing_support/factories/adjustment_reason_factory.rb +0 -5
  309. data/lib/spree/testing_support/factories/calculator_factory.rb +4 -10
  310. data/lib/spree/testing_support/factories/carton_factory.rb +2 -10
  311. data/lib/spree/testing_support/factories/country_factory.rb +1 -7
  312. data/lib/spree/testing_support/factories/credit_card_factory.rb +0 -5
  313. data/lib/spree/testing_support/factories/customer_return_factory.rb +2 -11
  314. data/lib/spree/testing_support/factories/image_factory.rb +0 -5
  315. data/lib/spree/testing_support/factories/inventory_unit_factory.rb +4 -14
  316. data/lib/spree/testing_support/factories/line_item_factory.rb +0 -8
  317. data/lib/spree/testing_support/factories/option_type_factory.rb +0 -8
  318. data/lib/spree/testing_support/factories/option_value_factory.rb +0 -5
  319. data/lib/spree/testing_support/factories/order_factory.rb +19 -38
  320. data/lib/spree/testing_support/factories/payment_factory.rb +0 -10
  321. data/lib/spree/testing_support/factories/payment_method_factory.rb +0 -5
  322. data/lib/spree/testing_support/factories/price_factory.rb +0 -7
  323. data/lib/spree/testing_support/factories/product_factory.rb +5 -13
  324. data/lib/spree/testing_support/factories/product_option_type_factory.rb +0 -8
  325. data/lib/spree/testing_support/factories/product_property_factory.rb +0 -8
  326. data/lib/spree/testing_support/factories/property_factory.rb +0 -5
  327. data/lib/spree/testing_support/factories/refund_factory.rb +0 -8
  328. data/lib/spree/testing_support/factories/refund_reason_factory.rb +0 -5
  329. data/lib/spree/testing_support/factories/reimbursement_factory.rb +0 -7
  330. data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +0 -5
  331. data/lib/spree/testing_support/factories/return_authorization_factory.rb +0 -9
  332. data/lib/spree/testing_support/factories/return_item_factory.rb +0 -9
  333. data/lib/spree/testing_support/factories/return_reason_factory.rb +0 -5
  334. data/lib/spree/testing_support/factories/role_factory.rb +0 -5
  335. data/lib/spree/testing_support/factories/shipment_factory.rb +1 -11
  336. data/lib/spree/testing_support/factories/shipping_category_factory.rb +0 -5
  337. data/lib/spree/testing_support/factories/shipping_method_factory.rb +0 -9
  338. data/lib/spree/testing_support/factories/shipping_rate_factory.rb +0 -8
  339. data/lib/spree/testing_support/factories/state_factory.rb +8 -10
  340. data/lib/spree/testing_support/factories/stock_item_factory.rb +5 -9
  341. data/lib/spree/testing_support/factories/stock_location_factory.rb +0 -9
  342. data/lib/spree/testing_support/factories/stock_movement_factory.rb +0 -7
  343. data/lib/spree/testing_support/factories/stock_package_factory.rb +1 -9
  344. data/lib/spree/testing_support/factories/store_credit_category_factory.rb +0 -5
  345. data/lib/spree/testing_support/factories/store_credit_event_factory.rb +0 -8
  346. data/lib/spree/testing_support/factories/store_credit_factory.rb +4 -13
  347. data/lib/spree/testing_support/factories/store_credit_reason_factory.rb +0 -5
  348. data/lib/spree/testing_support/factories/store_credit_type_factory.rb +0 -5
  349. data/lib/spree/testing_support/factories/store_factory.rb +0 -5
  350. data/lib/spree/testing_support/factories/tax_category_factory.rb +0 -8
  351. data/lib/spree/testing_support/factories/tax_rate_factory.rb +0 -9
  352. data/lib/spree/testing_support/factories/taxon_factory.rb +5 -10
  353. data/lib/spree/testing_support/factories/taxonomy_factory.rb +3 -6
  354. data/lib/spree/testing_support/factories/user_factory.rb +6 -9
  355. data/lib/spree/testing_support/factories/variant_factory.rb +0 -10
  356. data/lib/spree/testing_support/factories/variant_property_rule_condition_factory.rb +0 -8
  357. data/lib/spree/testing_support/factories/variant_property_rule_factory.rb +0 -9
  358. data/lib/spree/testing_support/factories/variant_property_rule_value_factory.rb +0 -8
  359. data/lib/spree/testing_support/factories/zone_factory.rb +1 -9
  360. data/lib/spree/testing_support/factory_bot.rb +6 -29
  361. data/lib/spree/testing_support/flaky.rb +22 -0
  362. data/lib/spree/testing_support/order_walkthrough.rb +7 -6
  363. data/lib/spree/testing_support/sequences.rb +0 -5
  364. data/lib/spree/testing_support/shared_examples/calculator.rb +10 -0
  365. data/lib/spree/testing_support/shared_examples/order_factory.rb +141 -0
  366. data/lib/spree/testing_support/shared_examples/working_factory.rb +15 -0
  367. data/lib/spree/testing_support/silence_deprecations.rb +9 -0
  368. data/lib/spree/user_class_handle.rb +2 -2
  369. data/lib/tasks/colorado_delivery_fee.rake +28 -0
  370. data/lib/tasks/payment_method.rake +29 -0
  371. data/lib/tasks/solidus/delete_prices_with_nil_amount.rake +8 -0
  372. data/solidus_core.gemspec +18 -8
  373. metadata +233 -117
  374. data/app/jobs/spree/promotion_code_batch_job.rb +0 -26
  375. data/app/mailers/spree/promotion_code_batch_mailer.rb +0 -15
  376. data/app/models/spree/calculator/distributed_amount.rb +0 -33
  377. data/app/models/spree/calculator/flat_percent_item_total.rb +0 -23
  378. data/app/models/spree/calculator/flexi_rate.rb +0 -22
  379. data/app/models/spree/calculator/percent_on_line_item.rb +0 -13
  380. data/app/models/spree/calculator/tiered_flat_rate.rb +0 -52
  381. data/app/models/spree/calculator/tiered_percent.rb +0 -62
  382. data/app/models/spree/line_item_action.rb +0 -8
  383. data/app/models/spree/order_promotion.rb +0 -27
  384. data/app/models/spree/promotion/actions/create_adjustment.rb +0 -77
  385. data/app/models/spree/promotion/actions/create_item_adjustments.rb +0 -99
  386. data/app/models/spree/promotion/actions/create_quantity_adjustments.rb +0 -139
  387. data/app/models/spree/promotion/actions/free_shipping.rb +0 -58
  388. data/app/models/spree/promotion/rules/first_order.rb +0 -38
  389. data/app/models/spree/promotion/rules/first_repeat_purchase_since.rb +0 -36
  390. data/app/models/spree/promotion/rules/item_total.rb +0 -53
  391. data/app/models/spree/promotion/rules/nth_order.rb +0 -45
  392. data/app/models/spree/promotion/rules/one_use_per_user.rb +0 -25
  393. data/app/models/spree/promotion/rules/option_value.rb +0 -50
  394. data/app/models/spree/promotion/rules/product.rb +0 -74
  395. data/app/models/spree/promotion/rules/store.rb +0 -22
  396. data/app/models/spree/promotion/rules/taxon.rb +0 -87
  397. data/app/models/spree/promotion/rules/user.rb +0 -30
  398. data/app/models/spree/promotion/rules/user_logged_in.rb +0 -20
  399. data/app/models/spree/promotion/rules/user_role.rb +0 -45
  400. data/app/models/spree/promotion.rb +0 -284
  401. data/app/models/spree/promotion_action.rb +0 -43
  402. data/app/models/spree/promotion_category.rb +0 -8
  403. data/app/models/spree/promotion_chooser.rb +0 -34
  404. data/app/models/spree/promotion_code/batch_builder.rb +0 -64
  405. data/app/models/spree/promotion_code.rb +0 -50
  406. data/app/models/spree/promotion_code_batch.rb +0 -27
  407. data/app/models/spree/promotion_handler/cart.rb +0 -55
  408. data/app/models/spree/promotion_handler/coupon.rb +0 -123
  409. data/app/models/spree/promotion_handler/page.rb +0 -26
  410. data/app/models/spree/promotion_handler/shipping.rb +0 -61
  411. data/app/models/spree/promotion_rule.rb +0 -55
  412. data/app/models/spree/promotion_rule_role.rb +0 -8
  413. data/app/models/spree/promotion_rule_store.rb +0 -10
  414. data/app/models/spree/promotion_rule_taxon.rb +0 -8
  415. data/app/models/spree/promotion_rule_user.rb +0 -10
  416. data/app/models/spree/tax/shipping_rate_taxer.rb +0 -24
  417. data/app/subscribers/spree/mailer_subscriber.rb +0 -25
  418. data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +0 -2
  419. data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +0 -2
  420. data/db/migrate/20161017102621_create_spree_promotion_code_batch.rb +0 -38
  421. data/db/migrate/20180202190713_create_promotion_rule_stores.rb +0 -12
  422. data/db/migrate/20180328172631_add_join_characters_to_promotion_code_batch.rb +0 -11
  423. data/db/migrate/20190106184413_remove_code_from_spree_promotions.rb +0 -42
  424. data/lib/generators/solidus/install/templates/vendor/assets/javascripts/spree/frontend/all.js +0 -10
  425. data/lib/generators/solidus/install/templates/vendor/assets/stylesheets/spree/frontend/all.css +0 -9
  426. data/lib/generators/spree/dummy/templates/rails/script/rails +0 -6
  427. data/lib/solidus/migrations/promotions_with_code_handlers.rb +0 -66
  428. data/lib/spree/event/adapters/active_support_notifications.rb +0 -67
  429. data/lib/spree/event/configuration.rb +0 -25
  430. data/lib/spree/event/subscriber.rb +0 -86
  431. data/lib/spree/event/subscriber_registry.rb +0 -94
  432. data/lib/spree/event.rb +0 -119
  433. data/lib/spree/permission_sets/promotion_display.rb +0 -15
  434. data/lib/spree/permission_sets/promotion_management.rb +0 -15
  435. data/lib/spree/testing_support/dummy_app/assets/javascripts/spree/frontend/all.js +0 -10
  436. data/lib/spree/testing_support/dummy_app/assets/stylesheets/spree/frontend/all.css +0 -9
  437. data/lib/spree/testing_support/dummy_app/views/layouts/application.html.erb +0 -1
  438. data/lib/spree/testing_support/factories/order_promotion_factory.rb +0 -16
  439. data/lib/spree/testing_support/factories/promotion_category_factory.rb +0 -12
  440. data/lib/spree/testing_support/factories/promotion_code_factory.rb +0 -16
  441. data/lib/spree/testing_support/factories/promotion_factory.rb +0 -92
  442. data/lib/spree/testing_support/factories.rb +0 -11
  443. data/lib/spree/testing_support.rb +0 -31
  444. data/lib/tasks/upgrade.rake +0 -15
@@ -22,11 +22,11 @@ class Spree::OrderShipping
22
22
  address: shipment.order.ship_address,
23
23
  shipping_method: shipment.shipping_method,
24
24
  shipped_at: Time.current,
25
- external_number: external_number,
25
+ external_number:,
26
26
  # TODO: Remove the `|| shipment.tracking` once Shipment#ship! is called by
27
27
  # OrderShipping#ship rather than vice versa
28
28
  tracking_number: tracking_number || shipment.tracking,
29
- suppress_mailer: suppress_mailer
29
+ suppress_mailer:
30
30
  )
31
31
  end
32
32
 
@@ -44,36 +44,32 @@ class Spree::OrderShipping
44
44
  # @return The carton created.
45
45
  def ship(inventory_units:, stock_location:, address:, shipping_method:,
46
46
  shipped_at: Time.current, external_number: nil, tracking_number: nil, suppress_mailer: false)
47
-
48
47
  carton = nil
49
48
 
50
49
  Spree::InventoryUnit.transaction do
51
50
  inventory_units.each(&:ship!)
52
51
 
53
52
  carton = Spree::Carton.create!(
54
- stock_location: stock_location,
55
- address: address,
56
- shipping_method: shipping_method,
57
- inventory_units: inventory_units,
58
- shipped_at: shipped_at,
59
- external_number: external_number,
53
+ stock_location:,
54
+ address:,
55
+ shipping_method:,
56
+ inventory_units:,
57
+ shipped_at:,
58
+ external_number:,
60
59
  tracking: tracking_number
61
60
  )
62
61
  end
63
62
 
64
63
  inventory_units.map(&:shipment).uniq.each do |shipment|
65
- # Temporarily propagate the tracking number to the shipment as well
66
- # TODO: Remove tracking numbers from shipments.
67
- shipment.update!(tracking: tracking_number)
68
-
69
- next unless shipment.inventory_units.reload.all? { |iu| iu.shipped? || iu.canceled? }
70
- # TODO: make OrderShipping#ship_shipment call Shipment#ship! rather than
71
- # having Shipment#ship! call OrderShipping#ship_shipment. We only really
72
- # need this `update_columns` for the specs, until we make that change.
73
- shipment.update_columns(state: 'shipped', shipped_at: Time.current)
64
+ if shipment.inventory_units.reload.all? { |iu| iu.shipped? || iu.canceled? }
65
+ shipment.update!(state: "shipped", shipped_at: Time.current, tracking: tracking_number)
66
+ else
67
+ shipment.update!(tracking: tracking_number)
68
+ end
74
69
  end
75
70
 
76
71
  send_shipment_emails(carton) if stock_location.fulfillable? && !suppress_mailer # e.g. digital gift cards that aren't actually shipped
72
+ @order.shipments.reload
77
73
  @order.recalculate
78
74
 
79
75
  carton
@@ -83,7 +79,7 @@ class Spree::OrderShipping
83
79
 
84
80
  def send_shipment_emails(carton)
85
81
  carton.orders.each do |order|
86
- Spree::Config.carton_shipped_email_class.shipped_email(order: order, carton: carton).deliver_later
82
+ Spree::Config.carton_shipped_email_class.shipped_email(order:, carton:).deliver_later
87
83
  end
88
84
  end
89
85
  end
@@ -17,15 +17,18 @@ module Spree
17
17
 
18
18
  # Apply taxes to the order.
19
19
  #
20
- # This method will create or update adjustments on all line items and
21
- # shipments in the order to reflect the appropriate taxes passed in. It
22
- # will also remove any now inapplicable tax adjustments.
20
+ # This method will create or update adjustments on the order and all line
21
+ # items and shipments in the order to reflect the appropriate taxes passed
22
+ # in. It will also remove any now inapplicable tax adjustments.
23
23
  #
24
24
  # @param [Spree::Tax::OrderTax] taxes the taxes to apply to the order
25
25
  # @return [void]
26
26
  def apply(taxes)
27
+ update_adjustments(@order, taxes.order_taxes) if taxes.order_taxes
28
+
27
29
  @order.line_items.each do |item|
28
30
  taxed_items = taxes.line_item_taxes.select { |element| element.item_id == item.id }
31
+ item.tax_category_id = item.variant_tax_category_id
29
32
  update_adjustments(item, taxed_items)
30
33
  end
31
34
 
@@ -70,7 +73,7 @@ module Spree
70
73
 
71
74
  tax_adjustment ||= item.adjustments.new(
72
75
  source: tax_item.tax_rate,
73
- order_id: item.order_id,
76
+ order_id: item.is_a?(Spree::Order) ? item.id : item.order_id,
74
77
  label: tax_item.label,
75
78
  included: tax_item.included_in_price
76
79
  )
@@ -15,7 +15,7 @@ module Spree
15
15
 
16
16
  # Assign the attributes to the order and save the order
17
17
  # @return true if saved, otherwise false and errors will be set on the order
18
- def apply
18
+ def call
19
19
  order.validate_payments_attributes(@payments_attributes)
20
20
 
21
21
  assign_order_attributes
@@ -24,6 +24,8 @@ module Spree
24
24
  order.save
25
25
  end
26
26
 
27
+ alias_method :apply, :call
28
+
27
29
  private
28
30
 
29
31
  attr_reader :attributes, :payments_attributes, :order
@@ -16,7 +16,7 @@ module Spree
16
16
  # This method should never do anything to the Order that results in a save call on the
17
17
  # object with callbacks (otherwise you will end up in an infinite recursion as the
18
18
  # associations try to save and then in turn try to call +update!+ again.)
19
- def update
19
+ def recalculate
20
20
  order.transaction do
21
21
  update_item_count
22
22
  update_shipment_amounts
@@ -26,10 +26,12 @@ module Spree
26
26
  update_shipments
27
27
  update_shipment_state
28
28
  end
29
- Spree::Event.fire 'order_recalculated', order: order
29
+ Spree::Bus.publish(:order_recalculated, order:)
30
30
  persist_totals
31
31
  end
32
32
  end
33
+ alias_method :update, :recalculate
34
+ deprecate update: :recalculate, deprecator: Spree.deprecator
33
35
 
34
36
  # Updates the +shipment_state+ attribute according to the following logic:
35
37
  #
@@ -110,10 +112,8 @@ module Spree
110
112
  # http://www.hmrc.gov.uk/vat/managing/charging/discounts-etc.htm#1
111
113
  # It also fits the criteria for sales tax as outlined here:
112
114
  # http://www.boe.ca.gov/formspubs/pub113/
113
- update_item_promotions
114
- update_order_promotions
115
- update_taxes
116
- update_cancellations
115
+ update_promotions
116
+ update_tax_adjustments
117
117
  update_item_totals
118
118
  end
119
119
 
@@ -157,12 +157,11 @@ module Spree
157
157
  recalculate_adjustments
158
158
 
159
159
  all_items = line_items + shipments
160
+ order_tax_adjustments = adjustments.select(&:tax?)
160
161
 
161
- order.adjustment_total = all_items.sum(&:adjustment_total) + adjustments.select(&:eligible?).sum(&:amount)
162
- order.included_tax_total = all_items.sum(&:included_tax_total)
163
- order.additional_tax_total = all_items.sum(&:additional_tax_total)
164
-
165
- order.promo_total = all_items.sum(&:promo_total) + adjustments.select(&:eligible?).select(&:promotion?).sum(&:amount)
162
+ order.adjustment_total = all_items.sum(&:adjustment_total) + adjustments.sum(&:amount)
163
+ order.included_tax_total = all_items.sum(&:included_tax_total) + order_tax_adjustments.select(&:included?).sum(&:amount)
164
+ order.additional_tax_total = all_items.sum(&:additional_tax_total) + order_tax_adjustments.reject(&:included?).sum(&:amount)
166
165
 
167
166
  update_order_total
168
167
  end
@@ -189,74 +188,37 @@ module Spree
189
188
  order.state_changes.new(
190
189
  previous_state: old_state,
191
190
  next_state: new_state,
192
- name: name,
191
+ name:,
193
192
  user_id: order.user_id
194
193
  )
195
194
  end
196
195
  end
197
196
 
198
- def update_item_promotions
199
- [*line_items, *shipments].each do |item|
200
- promotion_adjustments = item.adjustments.select(&:promotion?)
201
-
202
- promotion_adjustments.each(&:recalculate)
203
- Spree::Config.promotion_chooser_class.new(promotion_adjustments).update
204
-
205
- item.promo_total = promotion_adjustments.select(&:eligible?).sum(&:amount)
206
- end
207
- end
208
-
209
- # Update and select the best promotion adjustment for the order.
210
- # We don't update the order.promo_total yet. Order totals are updated later
211
- # in #update_adjustment_total since they include the totals from the order's
212
- # line items and/or shipments.
213
- def update_order_promotions
214
- promotion_adjustments = order.adjustments.select(&:promotion?)
215
- promotion_adjustments.each(&:recalculate)
216
- Spree::Config.promotion_chooser_class.new(promotion_adjustments).update
197
+ def update_promotions
198
+ Spree::Config.promotions.order_adjuster_class.new(order).call
217
199
  end
218
200
 
219
- def update_taxes
201
+ def update_tax_adjustments
220
202
  Spree::Config.tax_adjuster_class.new(order).adjust!
221
-
222
- [*line_items, *shipments].each do |item|
223
- tax_adjustments = item.adjustments.select(&:tax?)
224
- # Tax adjustments come in not one but *two* exciting flavours:
225
- # Included & additional
226
-
227
- # Included tax adjustments are those which are included in the price.
228
- # These ones should not affect the eventual total price.
229
- #
230
- # Additional tax adjustments are the opposite, affecting the final total.
231
- item.included_tax_total = tax_adjustments.select(&:included?).sum(&:amount)
232
- item.additional_tax_total = tax_adjustments.reject(&:included?).sum(&:amount)
233
- end
234
203
  end
235
204
 
236
205
  def update_cancellations
237
- line_items.each do |line_item|
238
- line_item.adjustments.select(&:cancellation?).each(&:recalculate)
239
- end
240
206
  end
207
+ deprecate :update_cancellations, deprecator: Spree.deprecator
241
208
 
242
209
  def update_item_totals
243
210
  [*line_items, *shipments].each do |item|
244
- # The cancellation_total isn't persisted anywhere but is included in
245
- # the adjustment_total
246
- item.adjustment_total = item.adjustments.
247
- select(&:eligible?).
248
- reject(&:included?).
249
- sum(&:amount)
211
+ Spree::Config.item_total_class.new(item).recalculate!
250
212
 
251
- if item.changed?
252
- item.update_columns(
253
- promo_total: item.promo_total,
254
- included_tax_total: item.included_tax_total,
255
- additional_tax_total: item.additional_tax_total,
256
- adjustment_total: item.adjustment_total,
257
- updated_at: Time.current,
258
- )
259
- end
213
+ next unless item.changed?
214
+
215
+ item.update_columns(
216
+ promo_total: item.promo_total,
217
+ included_tax_total: item.included_tax_total,
218
+ additional_tax_total: item.additional_tax_total,
219
+ adjustment_total: item.adjustment_total,
220
+ updated_at: Time.current,
221
+ )
260
222
  end
261
223
  end
262
224
  end
@@ -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:)
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,77 +163,56 @@ 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)
206
- log_entries.create!(details: response.to_yaml)
209
+ log_entries.create!(parsed_payment_response_details_with_fallback: response)
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)
@@ -240,7 +243,7 @@ module Spree
240
243
  cvv_result: response.cvv_result,
241
244
  error_code: response.error_code,
242
245
  emv_authorization: response.emv_authorization,
243
- gateway_order_id: gateway_order_id,
246
+ gateway_order_id:,
244
247
  order_number: order.number
245
248
  }
246
249
  end
@@ -7,6 +7,7 @@ module Spree
7
7
  #
8
8
  class Payment < Spree::Base
9
9
  include Spree::Payment::Processing
10
+ include Metadata
10
11
 
11
12
  IDENTIFIER_CHARS = (('A'..'Z').to_a + ('0'..'9').to_a - %w(0 1 I O)).freeze
12
13
  NON_RISKY_AVS_CODES = ['B', 'D', 'H', 'J', 'M', 'Q', 'T', 'V', 'X', 'Y'].freeze
@@ -16,7 +17,6 @@ module Spree
16
17
  belongs_to :source, polymorphic: true, optional: true
17
18
  belongs_to :payment_method, -> { with_discarded }, class_name: 'Spree::PaymentMethod', inverse_of: :payments, optional: true
18
19
 
19
- has_many :offsets, -> { offset_payment }, class_name: "Spree::Payment", foreign_key: :source_id
20
20
  has_many :log_entries, as: :source
21
21
  has_many :state_changes, as: :stateful
22
22
  has_many :capture_events, class_name: 'Spree::PaymentCaptureEvent'
@@ -45,8 +45,6 @@ module Spree
45
45
 
46
46
  scope :from_credit_card, -> { where(source_type: 'Spree::CreditCard') }
47
47
  scope :with_state, ->(state) { where(state: state.to_s) }
48
- # "offset" is reserved by activerecord
49
- scope :offset_payment, -> { where("source_type = 'Spree::Payment' AND amount < 0 AND state = 'completed'") }
50
48
 
51
49
  scope :checkout, -> { with_state('checkout') }
52
50
  scope :completed, -> { with_state('completed') }
@@ -54,7 +52,7 @@ module Spree
54
52
  scope :processing, -> { with_state('processing') }
55
53
  scope :failed, -> { with_state('failed') }
56
54
 
57
- scope :risky, -> { where("avs_response IN (?) OR (cvv_response_code IS NOT NULL and cvv_response_code != 'M') OR state = 'failed'", RISKY_AVS_CODES) }
55
+ scope :risky, -> { failed.or(where(avs_response: RISKY_AVS_CODES)).or(where.not(cvv_response_code: [nil, '', 'M'])) }
58
56
  scope :valid, -> { where.not(state: %w(failed invalid void)) }
59
57
 
60
58
  scope :store_credits, -> { where(source_type: Spree::StoreCredit.to_s) }
@@ -72,7 +70,7 @@ module Spree
72
70
 
73
71
  # @return [Spree::Money] this amount of this payment as money object
74
72
  def money
75
- Spree::Money.new(amount, { currency: currency })
73
+ Spree::Money.new(amount, { currency: })
76
74
  end
77
75
  alias display_amount money
78
76
 
@@ -89,19 +87,11 @@ module Spree
89
87
  end || amount
90
88
  end
91
89
 
92
- # The total amount of the offsets (for old-style refunds) for this payment.
93
- #
94
- # @return [BigDecimal] the total amount of this payment's offsets
95
- def offsets_total
96
- offsets.pluck(:amount).sum
97
- end
98
-
99
90
  # The total amount this payment can be credited.
100
91
  #
101
- # @return [BigDecimal] the amount of this payment minus the offsets
102
- # (old-style refunds) and refunds
92
+ # @return [BigDecimal] the amount of this payment minus refunds
103
93
  def credit_allowed
104
- amount - (offsets_total.abs + refunds.sum(:amount))
94
+ amount - refunds.sum(:amount)
105
95
  end
106
96
 
107
97
  # @return [Boolean] true when this payment can be credited
@@ -127,6 +117,11 @@ module Spree
127
117
  res || payment_method
128
118
  end
129
119
 
120
+ # @return [Boolean] true when this payment is risky
121
+ def risky?
122
+ is_avs_risky? || is_cvv_risky? || state == 'failed'
123
+ end
124
+
130
125
  # @return [Boolean] true when this payment is risky based on address
131
126
  def is_avs_risky?
132
127
  return false if avs_response.blank? || NON_RISKY_AVS_CODES.include?(avs_response)
@@ -137,7 +132,6 @@ module Spree
137
132
  def is_cvv_risky?
138
133
  return false if cvv_response_code == "M"
139
134
  return false if cvv_response_code.nil?
140
- return false if cvv_response_message.present?
141
135
  true
142
136
  end
143
137
 
@@ -165,16 +159,9 @@ module Spree
165
159
 
166
160
  def validate_source
167
161
  if source && !source.valid?
168
- if Gem::Requirement.new(">= 6.1").satisfied_by?(Rails.gem_version)
169
- source.errors.each do |error|
170
- field_name = I18n.t("activerecord.attributes.#{source.class.to_s.underscore}.#{error.attribute}")
171
- errors.add(I18n.t(source.class.to_s.demodulize.underscore, scope: 'spree'), "#{field_name} #{error.message}")
172
- end
173
- else
174
- source.errors.each do |field, error|
175
- field_name = I18n.t("activerecord.attributes.#{source.class.to_s.underscore}.#{field}")
176
- errors.add(I18n.t(source.class.to_s.demodulize.underscore, scope: 'spree'), "#{field_name} #{error}")
177
- end
162
+ source.errors.each do |error|
163
+ field_name = I18n.t("activerecord.attributes.#{source.class.to_s.underscore}.#{error.attribute}")
164
+ errors.add(I18n.t(source.class.to_s.demodulize.underscore, scope: 'spree'), "#{field_name} #{error.message}")
178
165
  end
179
166
  end
180
167
  if errors.any?
@@ -225,7 +212,7 @@ module Spree
225
212
  def set_unique_identifier
226
213
  loop do
227
214
  self.number = generate_identifier
228
- break unless self.class.exists?(number: number)
215
+ break unless self.class.exists?(number:)
229
216
  end
230
217
  end
231
218
 
@@ -72,7 +72,7 @@ module Spree
72
72
 
73
73
  def available_cards
74
74
  if user_id = order.user_id
75
- Spree::CreditCard.where(user_id: user_id)
75
+ Spree::CreditCard.where(user_id:)
76
76
  else
77
77
  Spree::CreditCard.none
78
78
  end
@@ -29,41 +29,45 @@ module Spree
29
29
 
30
30
  def authorize(_money, credit_card, _options = {})
31
31
  profile_id = credit_card.gateway_customer_profile_id
32
+ message_detail = " - #{__method__}"
32
33
  if VALID_CCS.include?(credit_card.number) || (profile_id && profile_id.starts_with?('BGS-'))
33
- ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'D' })
34
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'D' })
34
35
  else
35
- ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, { message: FAILURE_MESSAGE }, test: true)
36
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, { message: FAILURE_MESSAGE + message_detail }, test: true)
36
37
  end
37
38
  end
38
39
 
39
40
  def purchase(_money, credit_card, _options = {})
40
41
  profile_id = credit_card.gateway_customer_profile_id
42
+ message_detail = " - #{__method__}"
41
43
  if VALID_CCS.include?(credit_card.number) || (profile_id && profile_id.starts_with?('BGS-'))
42
- ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'M' })
44
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'M' })
43
45
  else
44
- ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, message: FAILURE_MESSAGE, test: true)
46
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, message: FAILURE_MESSAGE + message_detail, test: true)
45
47
  end
46
48
  end
47
49
 
48
50
  def credit(_money, _credit_card, _response_code, _options = {})
49
- ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE)
51
+ message_detail = " - #{__method__}"
52
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE)
50
53
  end
51
54
 
52
55
  def capture(_money, authorization, _gateway_options)
56
+ message_detail = " - #{__method__}"
53
57
  if authorization == '12345'
54
- ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true)
58
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true)
55
59
  else
56
- ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, error: FAILURE_MESSAGE, test: true)
60
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, error: FAILURE_MESSAGE + message_detail, test: true)
57
61
  end
58
62
  end
59
63
 
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)
64
+ def void(_response_code, _credit_card, options = {})
65
+ message_detail = " - #{__method__}"
66
+ if options[:originator].completed?
67
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE)
68
+ else
69
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE)
70
+ end
67
71
  end
68
72
 
69
73
  def test?
@@ -4,10 +4,6 @@ module Spree
4
4
  # An implementation of a `Spree::PaymentMethod` for credit card payments.
5
5
  #
6
6
  # It's a good candidate as base class for other credit card based payment methods.
7
- #
8
- # See https://github.com/solidusio/solidus_gateway/ for
9
- # officially supported payment method implementations.
10
- #
11
7
  class PaymentMethod::CreditCard < PaymentMethod
12
8
  def payment_source_class
13
9
  Spree::CreditCard
@@ -8,18 +8,32 @@ module Spree
8
8
  end
9
9
 
10
10
  def authorize(_money, credit_card, _options = {})
11
+ message_detail = " - #{__method__}"
12
+
11
13
  if VALID_CCS.include? credit_card.number
12
- ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'A' })
14
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'A' })
13
15
  else
14
- ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, { message: FAILURE_MESSAGE }, test: true)
16
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, { message: FAILURE_MESSAGE }, test: true)
15
17
  end
16
18
  end
17
19
 
18
20
  def purchase(_money, credit_card, _options = {})
21
+ message_detail = " - #{__method__}"
22
+
19
23
  if VALID_CCS.include? credit_card.number
20
- ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'A' })
24
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE, avs_result: { code: 'A' })
25
+ else
26
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, message: FAILURE_MESSAGE, test: true)
27
+ end
28
+ end
29
+
30
+ def void(_response_code, options = {})
31
+ message_detail = " - #{__method__}"
32
+
33
+ if options[:originator].completed?
34
+ ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE)
21
35
  else
22
- ActiveMerchant::Billing::Response.new(false, FAILURE_MESSAGE, message: FAILURE_MESSAGE, test: true)
36
+ ActiveMerchant::Billing::Response.new(true, SUCCESS_MESSAGE + message_detail, {}, test: true, authorization: AUTHORIZATION_CODE)
23
37
  end
24
38
  end
25
39
  end
@@ -107,7 +107,7 @@ module Spree
107
107
  store_credit = Spree::StoreCreditEvent.find_by(authorization_code: auth_code).try(:store_credit)
108
108
 
109
109
  if store_credit.nil?
110
- ActiveMerchant::Billing::Response.new(false, I18n.t('spree.store_credit.unable_to_find_for_action', auth_code: auth_code, action: action_name), {}, {})
110
+ ActiveMerchant::Billing::Response.new(false, I18n.t('spree.store_credit.unable_to_find_for_action', auth_code:, action: action_name), {}, {})
111
111
  else
112
112
  handle_action_call(store_credit, action, action_name, auth_code)
113
113
  end