solidus_core 4.4.2 → 4.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/app/helpers/spree/core/controller_helpers/auth.rb +66 -0
  3. data/app/helpers/spree/core/controller_helpers/common.rb +82 -0
  4. data/app/helpers/spree/core/controller_helpers/order.rb +86 -0
  5. data/app/helpers/spree/core/controller_helpers/payment_parameters.rb +165 -0
  6. data/app/helpers/spree/core/controller_helpers/pricing.rb +19 -0
  7. data/app/helpers/spree/core/controller_helpers/search.rb +16 -0
  8. data/app/helpers/spree/core/controller_helpers/store.rb +19 -0
  9. data/app/helpers/spree/core/controller_helpers/strong_parameters.rb +74 -0
  10. data/app/models/concerns/spree/metadata.rb +64 -0
  11. data/app/models/concerns/spree/user_address_book.rb +4 -5
  12. data/app/models/spree/core/state_machines/inventory_unit.rb +42 -0
  13. data/app/models/spree/core/state_machines/order/class_methods.rb +217 -0
  14. data/app/models/spree/core/state_machines/order.rb +42 -0
  15. data/app/models/spree/core/state_machines/payment.rb +61 -0
  16. data/app/models/spree/core/state_machines/reimbursement.rb +33 -0
  17. data/app/models/spree/core/state_machines/return_authorization.rb +32 -0
  18. data/app/models/spree/core/state_machines/return_item/acceptance_status.rb +51 -0
  19. data/app/models/spree/core/state_machines/return_item/reception_status.rb +42 -0
  20. data/app/models/spree/core/state_machines/shipment.rb +58 -0
  21. data/app/models/spree/customer_return.rb +2 -0
  22. data/app/models/spree/item_total.rb +28 -0
  23. data/app/models/spree/legacy_user.rb +1 -0
  24. data/app/models/spree/line_item.rb +21 -0
  25. data/app/models/spree/money.rb +120 -0
  26. data/app/models/spree/order.rb +20 -9
  27. data/app/models/spree/order_merger.rb +1 -1
  28. data/app/models/spree/order_taxation.rb +1 -0
  29. data/app/models/spree/order_updater.rb +13 -30
  30. data/app/models/spree/payment.rb +1 -0
  31. data/app/models/spree/permission_sets/base.rb +45 -0
  32. data/app/models/spree/permission_sets/configuration_display.rb +53 -0
  33. data/app/models/spree/permission_sets/configuration_management.rb +52 -0
  34. data/app/models/spree/permission_sets/dashboard_display.rb +28 -0
  35. data/app/models/spree/permission_sets/default_customer.rb +83 -0
  36. data/app/models/spree/permission_sets/order_display.rb +50 -0
  37. data/app/models/spree/permission_sets/order_management.rb +50 -0
  38. data/app/models/spree/permission_sets/product_display.rb +43 -0
  39. data/app/models/spree/permission_sets/product_management.rb +47 -0
  40. data/app/models/spree/permission_sets/restricted_stock_display.rb +33 -0
  41. data/app/models/spree/permission_sets/restricted_stock_management.rb +33 -0
  42. data/app/models/spree/permission_sets/stock_display.rb +26 -0
  43. data/app/models/spree/permission_sets/stock_management.rb +26 -0
  44. data/app/models/spree/permission_sets/super_user.rb +26 -0
  45. data/app/models/spree/permission_sets/user_display.rb +27 -0
  46. data/app/models/spree/permission_sets/user_management.rb +44 -0
  47. data/app/models/spree/product.rb +7 -0
  48. data/app/models/spree/refund.rb +2 -0
  49. data/app/models/spree/return_authorization.rb +2 -0
  50. data/app/models/spree/shipment.rb +2 -0
  51. data/app/models/spree/simple_order_contents.rb +4 -1
  52. data/app/models/spree/store_credit_event.rb +1 -0
  53. data/app/models/spree/tax/tax_helpers.rb +12 -1
  54. data/app/models/spree/tax_calculator/default.rb +1 -1
  55. data/app/models/spree/taxon.rb +22 -2
  56. data/app/models/spree/taxon_brand_selector.rb +22 -0
  57. data/app/models/spree/unauthorized_redirect_handler.rb +24 -0
  58. data/app/models/spree/user_address.rb +9 -3
  59. data/app/models/spree/variant.rb +14 -1
  60. data/config/locales/en.yml +14 -0
  61. data/db/migrate/20220419170826_remove_archived_user_addresses.rb +12 -0
  62. data/db/migrate/20250129061658_add_metadata_to_spree_resources.rb +29 -0
  63. data/db/migrate/20250201172950_add_gtin_and_condition_to_spree_variant.rb +6 -0
  64. data/db/migrate/20250207104016_add_primary_taxon_to_products.rb +7 -0
  65. data/lib/generators/solidus/install/app_templates/authentication/custom.rb +0 -5
  66. data/lib/generators/solidus/install/app_templates/frontend/starter.rb +1 -1
  67. data/lib/generators/spree/dummy/dummy_generator.rb +1 -1
  68. data/lib/generators/spree/dummy/templates/rails/application.rb.tt +1 -1
  69. data/lib/generators/spree/dummy/templates/rails/manifest.js +3 -0
  70. data/lib/spree/app_configuration.rb +49 -0
  71. data/lib/spree/core/controller_helpers/auth.rb +5 -61
  72. data/lib/spree/core/controller_helpers/common.rb +5 -80
  73. data/lib/spree/core/controller_helpers/order.rb +5 -86
  74. data/lib/spree/core/controller_helpers/payment_parameters.rb +5 -163
  75. data/lib/spree/core/controller_helpers/pricing.rb +5 -17
  76. data/lib/spree/core/controller_helpers/search.rb +5 -14
  77. data/lib/spree/core/controller_helpers/store.rb +5 -17
  78. data/lib/spree/core/controller_helpers/strong_parameters.rb +5 -71
  79. data/lib/spree/core/engine.rb +5 -0
  80. data/lib/spree/core/state_machines/inventory_unit.rb +5 -40
  81. data/lib/spree/core/state_machines/order.rb +5 -250
  82. data/lib/spree/core/state_machines/payment.rb +5 -59
  83. data/lib/spree/core/state_machines/reimbursement.rb +5 -31
  84. data/lib/spree/core/state_machines/return_authorization.rb +5 -30
  85. data/lib/spree/core/state_machines/return_item/acceptance_status.rb +5 -49
  86. data/lib/spree/core/state_machines/return_item/reception_status.rb +5 -40
  87. data/lib/spree/core/state_machines/shipment.rb +5 -56
  88. data/lib/spree/core/state_machines.rb +48 -81
  89. data/lib/spree/core/version.rb +2 -2
  90. data/lib/spree/core.rb +0 -10
  91. data/lib/spree/money.rb +5 -118
  92. data/lib/spree/permission_sets/base.rb +5 -42
  93. data/lib/spree/permission_sets/configuration_display.rb +5 -51
  94. data/lib/spree/permission_sets/configuration_management.rb +5 -50
  95. data/lib/spree/permission_sets/dashboard_display.rb +5 -26
  96. data/lib/spree/permission_sets/default_customer.rb +5 -81
  97. data/lib/spree/permission_sets/order_display.rb +5 -48
  98. data/lib/spree/permission_sets/order_management.rb +5 -48
  99. data/lib/spree/permission_sets/product_display.rb +5 -41
  100. data/lib/spree/permission_sets/product_management.rb +5 -45
  101. data/lib/spree/permission_sets/restricted_stock_display.rb +5 -31
  102. data/lib/spree/permission_sets/restricted_stock_management.rb +5 -31
  103. data/lib/spree/permission_sets/stock_display.rb +5 -24
  104. data/lib/spree/permission_sets/stock_management.rb +5 -24
  105. data/lib/spree/permission_sets/super_user.rb +5 -24
  106. data/lib/spree/permission_sets/user_display.rb +5 -25
  107. data/lib/spree/permission_sets/user_management.rb +5 -42
  108. data/lib/spree/permission_sets.rb +5 -16
  109. data/lib/spree/permitted_attributes.rb +18 -7
  110. data/lib/spree/preferences/configuration.rb +4 -0
  111. data/lib/spree/preferences/persistable.rb +1 -1
  112. data/lib/spree/testing_support/capybara_ext.rb +10 -0
  113. data/lib/spree/testing_support/dummy_app.rb +1 -1
  114. data/lib/spree/testing_support/factories/order_factory.rb +9 -1
  115. data/solidus_core.gemspec +1 -1
  116. metadata +64 -24
  117. data/lib/generators/spree/dummy/templates/rails/script/rails +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a77feaec973407e0036df672af2decbf5a3a0fcae38d4041dcbd5fea19bfbaf
4
- data.tar.gz: ed69345a425cef54bb72257aa687711c9379903866886035f54510dc076aedb4
3
+ metadata.gz: cb7dd71ea62d43498c1c5877746964d21c86df53336f0258493212019fc2d44e
4
+ data.tar.gz: '0068830026c1ca0fe52e4a01e78aa6ae34ab69ee2bc513e59b5626f218f31891'
5
5
  SHA512:
6
- metadata.gz: 47c13a634466741aa45278e9fd7007eed9621ac595ae9bcfd9c5f8bbeeeae932b2419e620ec574b00a68c4f90a8a8e866042744895cf71d5443dc42ff39577b8
7
- data.tar.gz: 3d8a8943ae006304d636ba1c54108a01d46b390bf10085c917002caaeb2b3b4c55986ba528efa8a6b18ce2b2f39d49b40d589cff4233a7c67977e634adeacf13
6
+ metadata.gz: 69ba883f25bb741c7694a9cf6023cec99562c2f7d4fbc9ac8b958b36ded1e4ee26cc7bf7007851bc4fcfbefdc822cd6c8a4f10da84118b72b677a54cc4eb1836
7
+ data.tar.gz: 9f11f391a6afa095008c9b48a0f881a1037391c6d2277e3933d04de588f84ed6958c6d074f01362cded9e9c05e20e52fd41bf860b087b0dcc4e19f455d9afbd1
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cancan'
4
+
5
+ module Spree
6
+ module Core
7
+ module ControllerHelpers
8
+ module Auth
9
+ extend ActiveSupport::Concern
10
+
11
+ # @!attribute [rw] unauthorized_redirect
12
+ # @!scope class
13
+ # Extension point for overriding behaviour of access denied errors.
14
+ # Default behaviour is to redirect back or to "/unauthorized" with a flash
15
+ # message.
16
+ # @return [Proc] action to take when access denied error is raised.
17
+
18
+ included do
19
+ before_action :set_guest_token
20
+ helper_method :spree_current_user
21
+
22
+ class_attribute :unauthorized_redirect
23
+ deprecate :unauthorized_redirect= => "Use a custom Spree::Config.unauthorized_redirect_handler_class instead", :deprecator => Spree.deprecator
24
+
25
+ rescue_from CanCan::AccessDenied, with: :handle_unauthorized_access
26
+ end
27
+
28
+ # Needs to be overriden so that we use Spree's Ability rather than anyone else's.
29
+ def current_ability
30
+ @current_ability ||= Spree::Ability.new(spree_current_user)
31
+ end
32
+
33
+ def redirect_back_or_default(default)
34
+ redirect_to(session["spree_user_return_to"] || default)
35
+ session["spree_user_return_to"] = nil
36
+ end
37
+
38
+ def set_guest_token
39
+ if cookies.signed[:guest_token].blank?
40
+ cookies.permanent.signed[:guest_token] = Spree::Config[:guest_token_cookie_options].merge(
41
+ value: SecureRandom.urlsafe_base64(nil, false),
42
+ httponly: true
43
+ )
44
+ end
45
+ end
46
+
47
+ def store_location
48
+ Spree::UserLastUrlStorer.new(self).store_location
49
+ end
50
+
51
+ # Auth extensions are expected to define it, otherwise it's a no-op
52
+ def spree_current_user
53
+ defined?(super) ? super : nil
54
+ end
55
+
56
+ def handle_unauthorized_access
57
+ if unauthorized_redirect
58
+ instance_exec(&unauthorized_redirect)
59
+ else
60
+ Spree::Config.unauthorized_redirect_handler_class.new(self).call
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'carmen'
4
+
5
+ module Spree
6
+ module Core
7
+ module ControllerHelpers
8
+ module Common
9
+ extend ActiveSupport::Concern
10
+ included do
11
+ helper_method :title
12
+ helper_method :title=
13
+ helper_method :accurate_title
14
+
15
+ layout :get_layout
16
+
17
+ before_action :set_user_language
18
+ end
19
+
20
+ protected
21
+
22
+ # can be used in views as well as controllers.
23
+ # e.g. <% self.title = 'This is a custom title for this view' %>
24
+ attr_writer :title
25
+
26
+ def title
27
+ title_string = @title.presence || accurate_title
28
+ if title_string.present?
29
+ if Spree::Config[:always_put_site_name_in_title]
30
+ [title_string, default_title].join(' - ')
31
+ else
32
+ title_string
33
+ end
34
+ else
35
+ default_title
36
+ end
37
+ end
38
+
39
+ def default_title
40
+ current_store.name
41
+ end
42
+
43
+ # this is a hook for subclasses to provide title
44
+ def accurate_title
45
+ current_store.seo_title
46
+ end
47
+
48
+ private
49
+
50
+ def set_user_language_locale_key
51
+ :locale
52
+ end
53
+
54
+ def set_user_language
55
+ available_locales = Spree.i18n_available_locales
56
+ locale = [
57
+ params[:locale],
58
+ session[set_user_language_locale_key],
59
+ (config_locale if respond_to?(:config_locale, true)),
60
+ I18n.default_locale
61
+ ].detect do |candidate|
62
+ candidate &&
63
+ available_locales.include?(candidate.to_sym)
64
+ end
65
+ session[set_user_language_locale_key] = locale
66
+ I18n.locale = locale
67
+ Carmen.i18n_backend.locale = locale
68
+ end
69
+
70
+ # Returns which layout to render.
71
+ #
72
+ # You can set the layout you want to render inside your Spree configuration with the +:layout+ option.
73
+ #
74
+ # Default layout is: +app/views/spree/layouts/spree_application+
75
+ #
76
+ def get_layout
77
+ Spree::Config[:layout]
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core
5
+ module ControllerHelpers
6
+ module Order
7
+ extend ActiveSupport::Concern
8
+ include ControllerHelpers::Pricing
9
+
10
+ included do
11
+ helper_method :current_order
12
+ end
13
+
14
+ # The current incomplete order from the guest_token for use in cart and during checkout
15
+ def current_order(options = {})
16
+ should_create = options[:create_order_if_necessary] || false
17
+ should_build = options[:build_order_if_necessary] || should_create
18
+
19
+ return @current_order if @current_order
20
+
21
+ @current_order = find_order_by_token_or_user(lock: options[:lock])
22
+
23
+ if should_build && (@current_order.nil? || @current_order.completed?)
24
+ @current_order = Spree::Order.new(new_order_params)
25
+ @current_order.user ||= spree_current_user
26
+ # See issue https://github.com/spree/spree/issues/3346 for reasons why this line is here
27
+ @current_order.created_by ||= spree_current_user
28
+ @current_order.save! if should_create
29
+ end
30
+
31
+ if @current_order
32
+ @current_order.record_ip_address(ip_address)
33
+ @current_order
34
+ end
35
+ end
36
+
37
+ def associate_user
38
+ @order ||= current_order
39
+ if spree_current_user && @order && (@order.user.blank? || @order.email.blank?)
40
+ @order.associate_user!(spree_current_user)
41
+ end
42
+ end
43
+
44
+ def set_current_order
45
+ if spree_current_user && current_order
46
+ spree_current_user.orders.by_store(current_store).incomplete.where('id != ?', current_order.id).find_each do |order|
47
+ current_order.merge!(order, spree_current_user)
48
+ end
49
+ end
50
+ end
51
+
52
+ def ip_address
53
+ request.remote_ip
54
+ end
55
+
56
+ private
57
+
58
+ def last_incomplete_order
59
+ @last_incomplete_order ||= spree_current_user.last_incomplete_spree_order(store: current_store)
60
+ end
61
+
62
+ def current_order_params
63
+ { currency: current_pricing_options.currency, guest_token: cookies.signed[:guest_token], store_id: current_store.id, user_id: spree_current_user.try(:id) }
64
+ end
65
+
66
+ def new_order_params
67
+ current_order_params.merge(last_ip_address: ip_address)
68
+ end
69
+
70
+ def find_order_by_token_or_user(options = {})
71
+ should_lock = options[:lock] || false
72
+
73
+ # Find any incomplete orders for the guest_token
74
+ order = Spree::Order.incomplete.lock(should_lock).find_by(current_order_params)
75
+
76
+ # Find any incomplete orders for the current user
77
+ if order.nil? && spree_current_user
78
+ order = last_incomplete_order
79
+ end
80
+
81
+ order
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core::ControllerHelpers::PaymentParameters
5
+ # This method handles the awkwardness of how the html forms are currently
6
+ # set up for frontend.
7
+ #
8
+ # This method expects a params hash in the format of:
9
+ #
10
+ # {
11
+ # payment_source: {
12
+ # # The keys here are spree_payment_method.id's
13
+ # '1' => {...source attributes for payment method 1...},
14
+ # '2' => {...source attributes for payment method 2...},
15
+ # },
16
+ # order: {
17
+ # # Note that only a single entry is expected/handled in this array
18
+ # payments_attributes: [
19
+ # {
20
+ # payment_method_id: '1',
21
+ # },
22
+ # ],
23
+ # ...other params...
24
+ # },
25
+ # ...other params...
26
+ # }
27
+ #
28
+ # And this method modifies the params into the format of:
29
+ #
30
+ # {
31
+ # order: {
32
+ # payments_attributes: [
33
+ # {
34
+ # payment_method_id: '1',
35
+ # source_attributes: {...source attributes for payment method 1...}
36
+ # },
37
+ # ],
38
+ # ...other params...
39
+ # },
40
+ # ...other params...
41
+ # }
42
+ #
43
+ def move_payment_source_into_payments_attributes(params)
44
+ # Step 1: Gather all the information and ensure all the pieces are there.
45
+
46
+ return params if params[:payment_source].blank?
47
+
48
+ payment_params = params[:order] &&
49
+ params[:order][:payments_attributes] &&
50
+ params[:order][:payments_attributes].first
51
+ return params if payment_params.blank?
52
+
53
+ payment_method_id = payment_params[:payment_method_id]
54
+ return params if payment_method_id.blank?
55
+
56
+ source_params = params[:payment_source][payment_method_id]
57
+ return params if source_params.blank?
58
+
59
+ # Step 2: Perform the modifications.
60
+
61
+ payment_params[:source_attributes] = source_params
62
+ params.delete(:payment_source)
63
+
64
+ params
65
+ end
66
+
67
+ # This method handles the awkwardness of how the html forms are currently
68
+ # set up for frontend.
69
+ #
70
+ # This method expects a params hash in the format of:
71
+ #
72
+ # {
73
+ # order: {
74
+ # wallet_payment_source_id: '123',
75
+ # ...other params...
76
+ # },
77
+ # cvc_confirm: '456', # optional
78
+ # ...other params...
79
+ # }
80
+ #
81
+ # And this method modifies the params into the format of:
82
+ #
83
+ # {
84
+ # order: {
85
+ # payments_attributes: [
86
+ # {
87
+ # source_attributes: {
88
+ # wallet_payment_source_id: '123',
89
+ # verification_value: '456',
90
+ # },
91
+ # },
92
+ # ]
93
+ # ...other params...
94
+ # },
95
+ # ...other params...
96
+ # }
97
+ #
98
+ def move_wallet_payment_source_id_into_payments_attributes(params)
99
+ return params if params[:order].blank?
100
+
101
+ wallet_payment_source_id = params[:order][:wallet_payment_source_id].presence
102
+ cvc_confirm = params[:cvc_confirm].presence
103
+
104
+ return params if wallet_payment_source_id.nil?
105
+
106
+ params[:order][:payments_attributes] = [
107
+ {
108
+ source_attributes: {
109
+ wallet_payment_source_id:,
110
+ verification_value: cvc_confirm
111
+ }
112
+ }
113
+ ]
114
+
115
+ params[:order].delete(:wallet_payment_source_id)
116
+ params.delete(:cvc_confirm)
117
+
118
+ params
119
+ end
120
+
121
+ # This is a strange thing to do since an order can have multiple payments
122
+ # but we always assume that it only has a single payment and that its
123
+ # amount should be the current order total after store credit is applied.
124
+ # We should reconsider this method and its usage at some point.
125
+ #
126
+ # This method expects a params hash in the format of:
127
+ #
128
+ # {
129
+ # order: {
130
+ # # Note that only a single entry is expected/handled in this array
131
+ # payments_attributes: [
132
+ # {
133
+ # ...params...
134
+ # },
135
+ # ],
136
+ # ...other params...
137
+ # },
138
+ # ...other params...
139
+ # }
140
+ #
141
+ # And this method modifies the params into the format of:
142
+ #
143
+ # {
144
+ # order: {
145
+ # payments_attributes: [
146
+ # {
147
+ # ...params...
148
+ # amount: <the order total after store credit>,
149
+ # },
150
+ # ],
151
+ # ...other params...
152
+ # },
153
+ # ...other params...
154
+ # }
155
+ #
156
+ def set_payment_parameters_amount(params, order)
157
+ return params if params[:order].blank?
158
+ return params if params[:order][:payments_attributes].blank?
159
+
160
+ params[:order][:payments_attributes].first[:amount] = order.order_total_after_store_credit
161
+
162
+ params
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core
5
+ module ControllerHelpers
6
+ module Pricing
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ helper_method :current_pricing_options
11
+ end
12
+
13
+ def current_pricing_options
14
+ Spree::Config.pricing_options_class.from_context(self)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core
5
+ module ControllerHelpers
6
+ module Search
7
+ def build_searcher(params)
8
+ Spree::Config.searcher_class.new(params).tap do |searcher|
9
+ searcher.current_user = spree_current_user
10
+ searcher.pricing_options = current_pricing_options
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core
5
+ module ControllerHelpers
6
+ module Store
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ helper_method :current_store
11
+ end
12
+
13
+ def current_store
14
+ @current_store ||= Spree::Config.current_store_selector_class.new(request).store
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core
5
+ module ControllerHelpers
6
+ module StrongParameters
7
+ def permitted_attributes
8
+ Spree::PermittedAttributes
9
+ end
10
+
11
+ delegate(*Spree::PermittedAttributes::ATTRIBUTES,
12
+ to: :permitted_attributes,
13
+ prefix: :permitted)
14
+
15
+ def permitted_credit_card_update_attributes
16
+ permitted_attributes.credit_card_update_attributes + [
17
+ address_attributes: permitted_address_attributes
18
+ ]
19
+ end
20
+
21
+ def permitted_payment_attributes
22
+ permitted_attributes.payment_attributes + [
23
+ source_attributes: permitted_source_attributes
24
+ ]
25
+ end
26
+
27
+ def permitted_source_attributes
28
+ permitted_attributes.source_attributes + [
29
+ address_attributes: permitted_address_attributes
30
+ ]
31
+ end
32
+
33
+ def permitted_checkout_address_attributes
34
+ permitted_attributes.checkout_address_attributes
35
+ end
36
+
37
+ def permitted_checkout_delivery_attributes
38
+ permitted_attributes.checkout_delivery_attributes
39
+ end
40
+
41
+ def permitted_checkout_payment_attributes
42
+ permitted_attributes.checkout_payment_attributes
43
+ end
44
+
45
+ def permitted_checkout_confirm_attributes
46
+ permitted_attributes.checkout_confirm_attributes
47
+ end
48
+
49
+ def permitted_order_attributes
50
+ permitted_checkout_address_attributes +
51
+ permitted_checkout_delivery_attributes +
52
+ permitted_checkout_payment_attributes +
53
+ permitted_attributes.customer_metadata_attributes +
54
+ permitted_checkout_confirm_attributes + [
55
+ line_items_attributes: permitted_line_item_attributes
56
+ ]
57
+ end
58
+
59
+ def permitted_product_attributes
60
+ permitted_attributes.product_attributes + [
61
+ product_properties_attributes: permitted_product_properties_attributes
62
+ ]
63
+ end
64
+
65
+ def permitted_user_attributes
66
+ permitted_attributes.user_attributes + [
67
+ bill_address_attributes: permitted_address_attributes,
68
+ ship_address_attributes: permitted_address_attributes
69
+ ]
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Metadata
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ attribute :customer_metadata, :json, default: {}
9
+ attribute :admin_metadata, :json, default: {}
10
+
11
+ validate :validate_metadata_limits, if: :validate_metadata_enabled?
12
+ end
13
+
14
+ class_methods do
15
+ def meta_data_columns
16
+ %i[customer_metadata admin_metadata]
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def validate_metadata_enabled?
23
+ Spree::Config.meta_data_validation_enabled
24
+ end
25
+
26
+ def validate_metadata_limits
27
+ self.class.meta_data_columns.each { |column| validate_metadata_column(column) }
28
+ end
29
+
30
+ def validate_metadata_column(column)
31
+ config = Spree::Config
32
+ metadata = send(column)
33
+
34
+ return if metadata.nil?
35
+
36
+ # Check for maximum number of keys
37
+ validate_metadata_keys_count(metadata, column, config.meta_data_max_keys)
38
+
39
+ # Check for maximum key and value size
40
+ metadata.each do |key, value|
41
+ validate_metadata_key(key, column, config.meta_data_max_key_length)
42
+ validate_metadata_value(key, value, column, config.meta_data_max_value_length)
43
+ end
44
+ end
45
+
46
+ def validate_metadata_keys_count(metadata, column, max_keys)
47
+ return unless metadata.keys.count > max_keys
48
+
49
+ errors.add(column, "must not have more than #{max_keys} keys")
50
+ end
51
+
52
+ def validate_metadata_key(key, column, max_key_length)
53
+ return unless key.to_s.length > max_key_length
54
+
55
+ errors.add(column, "key '#{key}' exceeds #{max_key_length} characters")
56
+ end
57
+
58
+ def validate_metadata_value(key, value, column, max_value_length)
59
+ return unless value.to_s.length > max_value_length
60
+
61
+ errors.add(column, "value for key '#{key}' exceeds #{max_value_length} characters")
62
+ end
63
+ end
64
+ end
@@ -5,7 +5,7 @@ module Spree
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- has_many :user_addresses, -> { active }, foreign_key: "user_id", class_name: "Spree::UserAddress" do
8
+ has_many :user_addresses, foreign_key: "user_id", class_name: "Spree::UserAddress" do
9
9
  def find_first_by_address_values(address_attrs)
10
10
  detect { |ua| ua.address == Spree::Address.new(address_attrs) }
11
11
  end
@@ -22,7 +22,7 @@ module Spree
22
22
  end
23
23
 
24
24
  if user_address.persisted?
25
- user_address.update!(column_for_default => true, archived: false)
25
+ user_address.update!(column_for_default => true)
26
26
  else
27
27
  user_address.write_attribute(column_for_default, true)
28
28
  end
@@ -151,7 +151,7 @@ module Spree
151
151
  user_address = user_addresses.find_by(address_id:)
152
152
  if user_address
153
153
  remove_user_address_reference(address_id)
154
- user_address.update(archived: true, default: false)
154
+ user_address.destroy!
155
155
  else
156
156
  false
157
157
  end
@@ -160,10 +160,9 @@ module Spree
160
160
  private
161
161
 
162
162
  def prepare_user_address(new_address)
163
- user_address = user_addresses.all_historical.find_first_by_address_values(new_address.attributes)
163
+ user_address = user_addresses.find_first_by_address_values(new_address.attributes)
164
164
  user_address ||= user_addresses.build
165
165
  user_address.address = new_address
166
- user_address.archived = false
167
166
  user_address
168
167
  end
169
168
 
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Spree
4
+ module Core
5
+ class StateMachines
6
+ # Inventory Units' state machine
7
+ #
8
+ # for each event the following instance methods are dynamically implemented:
9
+ # #<event_name>
10
+ # #<event_name>!
11
+ # #can_<event_name>?
12
+ #
13
+ # for each state the following instance methods are implemented:
14
+ # #<state_name>?
15
+ #
16
+ module InventoryUnit
17
+ extend ActiveSupport::Concern
18
+
19
+ included do
20
+ state_machine initial: :on_hand do
21
+ event :fill_backorder do
22
+ transition to: :on_hand, from: :backordered
23
+ end
24
+ after_transition on: :fill_backorder, do: :fulfill_order
25
+
26
+ event :ship do
27
+ transition to: :shipped, if: :allow_ship?
28
+ end
29
+
30
+ event :return do
31
+ transition to: :returned, from: :shipped
32
+ end
33
+
34
+ event :cancel do
35
+ transition to: :canceled, from: ::Spree::InventoryUnit::CANCELABLE_STATES.map(&:to_sym)
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end