solidus_core 4.7.1 → 4.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE +3 -0
- data/app/helpers/spree/base_helper.rb +3 -3
- data/app/helpers/spree/core/controller_helpers/auth.rb +1 -1
- data/app/helpers/spree/core/controller_helpers/common.rb +2 -2
- data/app/helpers/spree/core/controller_helpers/timezone.rb +55 -0
- data/app/helpers/spree/products_helper.rb +3 -3
- data/app/jobs/spree/base_job.rb +1 -1
- data/app/mailers/spree/base_mailer.rb +2 -2
- data/app/models/concerns/spree/user_methods.rb +4 -4
- data/app/models/spree/address.rb +1 -1
- data/app/models/spree/adjustment.rb +1 -1
- data/app/models/spree/calculator/flat_rate.rb +2 -2
- data/app/models/spree/calculator/shipping/flat_rate.rb +1 -1
- data/app/models/spree/calculator/shipping/flexi_rate.rb +1 -1
- data/app/models/spree/calculator/shipping/per_item.rb +1 -1
- data/app/models/spree/calculator/shipping/price_sack.rb +1 -1
- data/app/models/spree/calculator.rb +1 -1
- data/app/models/spree/country.rb +1 -1
- data/app/models/spree/customer_return.rb +7 -0
- data/app/models/spree/exchange.rb +4 -1
- data/app/models/spree/image/active_storage_attachment.rb +15 -0
- data/app/models/spree/image/paperclip_attachment.rb +3 -0
- data/app/models/spree/image.rb +4 -0
- data/app/models/spree/log_entry.rb +26 -22
- data/app/models/spree/money.rb +2 -2
- data/app/models/spree/order/payments.rb +1 -1
- data/app/models/spree/order.rb +15 -17
- data/app/models/spree/order_cancellations.rb +1 -0
- data/app/models/spree/order_mutex.rb +1 -1
- data/app/models/spree/order_shipping.rb +17 -0
- data/app/models/spree/order_updater.rb +1 -1
- data/app/models/spree/payment/processing.rb +0 -1
- data/app/models/spree/payment_create.rb +23 -0
- data/app/models/spree/payment_method/bogus_credit_card.rb +4 -0
- data/app/models/spree/payment_method/check.rb +4 -2
- data/app/models/spree/payment_method.rb +1 -1
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product.rb +10 -7
- data/app/models/spree/product_option_type.rb +2 -0
- data/app/models/spree/refund.rb +17 -0
- data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +1 -1
- data/app/models/spree/return_item.rb +10 -1
- data/app/models/spree/shipment.rb +5 -3
- data/app/models/spree/stock/inventory_unit_builder.rb +1 -0
- data/app/models/spree/stock/simple_coordinator.rb +9 -2
- data/app/models/spree/store.rb +8 -1
- data/app/models/spree/store_credit.rb +1 -1
- data/app/models/spree/tax_calculator/default.rb +2 -0
- data/app/models/spree/taxon.rb +5 -2
- data/app/models/spree/variant/pricing_options.rb +1 -1
- data/app/models/spree/variant/vat_price_generator.rb +1 -0
- data/app/models/spree/variant.rb +3 -3
- data/config/locales/en.yml +13 -0
- data/db/default/spree/states.rb +1 -1
- data/db/migrate/20260924120000_add_address_to_spree_stores.rb +9 -0
- data/lib/generators/solidus/install/app_templates/authentication/existing.rb +0 -2
- data/lib/generators/solidus/install/app_templates/frontend/starter.rb +19 -1
- data/lib/generators/solidus/install/app_templates/payment_method/paypal.rb +2 -1
- data/lib/generators/solidus/install/install_generator.rb +7 -7
- data/lib/spree/app_configuration.rb +51 -0
- data/lib/spree/core/search/base.rb +3 -1
- data/lib/spree/core/version.rb +2 -2
- data/lib/spree/core.rb +0 -1
- data/lib/spree/permitted_attributes.rb +3 -2
- data/lib/spree/preferences/statically_configurable.rb +2 -1
- data/lib/spree/testing_support/capybara_ext.rb +0 -10
- data/lib/spree/testing_support/factories/calculator_factory.rb +6 -0
- data/lib/spree/testing_support/factories/return_item_factory.rb +9 -1
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_factory.rb +4 -0
- data/lib/spree/testing_support/order_walkthrough.rb +1 -1
- data/solidus_core.gemspec +3 -3
- metadata +13 -11
|
@@ -8,6 +8,10 @@ module Spree
|
|
|
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
10
|
# * :wallet_payment_source_id (Integer): The id of a {WalletPaymentSource} to use
|
|
11
|
+
# * :gateway_customer_profile_id, :gateway_payment_profile_id (String): Gateway
|
|
12
|
+
# identifiers for a new {CreditCard}, e.g. a one-time token. Raises
|
|
13
|
+
# ActiveRecord::RecordNotFound if either already belongs to a {CreditCard}
|
|
14
|
+
# owned by a different user.
|
|
11
15
|
# @param request_env [Hash] rack env of user creating the payment
|
|
12
16
|
# @param payment [Payment] Internal use only. Instead of making a new payment, change the attributes for an existing one.
|
|
13
17
|
def initialize(order, attributes, payment: nil, request_env: {})
|
|
@@ -44,6 +48,7 @@ module Spree
|
|
|
44
48
|
def build_source
|
|
45
49
|
payment_method = payment.payment_method
|
|
46
50
|
if source_attributes.present? && payment_method.try(:payment_source_class)
|
|
51
|
+
ensure_gateway_profile_ownership!(payment_method.payment_source_class)
|
|
47
52
|
payment.source = payment_method.payment_source_class.new(source_attributes)
|
|
48
53
|
payment.source.payment_method_id = payment_method.id
|
|
49
54
|
if order && payment.source.respond_to?(:user=)
|
|
@@ -52,6 +57,24 @@ module Spree
|
|
|
52
57
|
end
|
|
53
58
|
end
|
|
54
59
|
|
|
60
|
+
# Gateway profile ids may only be submitted for a new source when they are
|
|
61
|
+
# unknown to the store (e.g. a one-time token) or already belong to the
|
|
62
|
+
# order's user. Raises if either id is stored on a {CreditCard} owned by a
|
|
63
|
+
# different user, so customers cannot pay with another customer's stored
|
|
64
|
+
# gateway credential.
|
|
65
|
+
def ensure_gateway_profile_ownership!(source_class)
|
|
66
|
+
return unless source_class <= Spree::CreditCard
|
|
67
|
+
|
|
68
|
+
%i[gateway_customer_profile_id gateway_payment_profile_id].each do |attribute|
|
|
69
|
+
value = source_attributes[attribute]
|
|
70
|
+
next if value.blank?
|
|
71
|
+
|
|
72
|
+
foreign_cards = Spree::CreditCard.where(attribute => value).where.not(user_id: nil)
|
|
73
|
+
foreign_cards = foreign_cards.where.not(user_id: order.user_id) if order&.user_id
|
|
74
|
+
raise ActiveRecord::RecordNotFound if foreign_cards.exists?
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
55
78
|
def build_from_wallet_payment_source
|
|
56
79
|
wallet_payment_source_id = source_attributes.fetch(:wallet_payment_source_id)
|
|
57
80
|
raise(ActiveRecord::RecordNotFound) if order.user.nil?
|
|
@@ -6,16 +6,18 @@ module Spree
|
|
|
6
6
|
%w[capture void credit]
|
|
7
7
|
end
|
|
8
8
|
|
|
9
|
-
# Indicates whether its possible to capture the payment
|
|
10
9
|
def can_capture?(payment)
|
|
11
10
|
["checkout", "pending"].include?(payment.state)
|
|
12
11
|
end
|
|
13
12
|
|
|
14
|
-
# Indicates whether its possible to void the payment.
|
|
15
13
|
def can_void?(payment)
|
|
16
14
|
payment.state != "void"
|
|
17
15
|
end
|
|
18
16
|
|
|
17
|
+
def can_credit?(payment)
|
|
18
|
+
payment.completed? && payment.credit_allowed > 0
|
|
19
|
+
end
|
|
20
|
+
|
|
19
21
|
def capture(*)
|
|
20
22
|
simulated_successful_billing_response
|
|
21
23
|
end
|
|
@@ -156,7 +156,7 @@ module Spree
|
|
|
156
156
|
end
|
|
157
157
|
|
|
158
158
|
def auto_capture?
|
|
159
|
-
auto_capture.nil? ? Spree::Config
|
|
159
|
+
auto_capture.nil? ? Spree::Config.auto_capture : auto_capture
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
# Check if given source is supported by this payment method
|
data/app/models/spree/price.rb
CHANGED
data/app/models/spree/product.rb
CHANGED
|
@@ -124,7 +124,7 @@ module Spree
|
|
|
124
124
|
validates :meta_keywords, length: {maximum: 255}
|
|
125
125
|
validates :meta_title, length: {maximum: 255}
|
|
126
126
|
validates :name, presence: true
|
|
127
|
-
validates :price, presence: true, if: proc { Spree::Config
|
|
127
|
+
validates :price, presence: true, if: proc { Spree::Config.require_master_price }
|
|
128
128
|
validates :slug, presence: true, uniqueness: {allow_blank: true, case_sensitive: true}
|
|
129
129
|
|
|
130
130
|
attr_accessor :option_values_hash
|
|
@@ -355,14 +355,17 @@ module Spree
|
|
|
355
355
|
run_callbacks(:touch)
|
|
356
356
|
end
|
|
357
357
|
|
|
358
|
-
# Iterate through this product's taxons and taxonomies and touch their timestamps
|
|
358
|
+
# Iterate through this product's taxons and taxonomies and touch their timestamps
|
|
359
359
|
def touch_taxons
|
|
360
|
-
taxons_to_touch = taxons.flat_map(&:self_and_ancestors).uniq
|
|
361
|
-
|
|
362
|
-
Spree::Taxon.where(id: taxons_to_touch.map(&:id)).update_all(updated_at: Time.current)
|
|
360
|
+
taxons_to_touch = taxons.flat_map(&:self_and_ancestors).uniq.sort_by(&:id)
|
|
361
|
+
return if taxons_to_touch.empty?
|
|
363
362
|
|
|
364
|
-
|
|
365
|
-
|
|
363
|
+
time = Time.current
|
|
364
|
+
taxons_to_touch.each { |taxon| taxon.update_column(:updated_at, time) }
|
|
365
|
+
|
|
366
|
+
taxonomy_ids_to_touch = taxons_to_touch.map(&:taxonomy_id).uniq
|
|
367
|
+
Spree::Taxonomy.where(id: taxonomy_ids_to_touch).order(:id).each do |taxonomy|
|
|
368
|
+
taxonomy.touch(time:)
|
|
366
369
|
end
|
|
367
370
|
end
|
|
368
371
|
|
|
@@ -5,5 +5,7 @@ module Spree
|
|
|
5
5
|
belongs_to :product, class_name: "Spree::Product", inverse_of: :product_option_types, touch: true
|
|
6
6
|
belongs_to :option_type, class_name: "Spree::OptionType", inverse_of: :product_option_types
|
|
7
7
|
acts_as_list scope: :product
|
|
8
|
+
|
|
9
|
+
delegate :name, :presentation, :option_values, to: :option_type
|
|
8
10
|
end
|
|
9
11
|
end
|
data/app/models/spree/refund.rb
CHANGED
|
@@ -15,6 +15,7 @@ module Spree
|
|
|
15
15
|
validates :amount, presence: true, numericality: {greater_than: 0}
|
|
16
16
|
|
|
17
17
|
validate :amount_is_less_than_or_equal_to_allowed_amount, on: :create
|
|
18
|
+
validate :payment_is_in_refundable_state, on: :create
|
|
18
19
|
|
|
19
20
|
attr_reader :perform_response
|
|
20
21
|
|
|
@@ -91,6 +92,22 @@ module Spree
|
|
|
91
92
|
end
|
|
92
93
|
end
|
|
93
94
|
|
|
95
|
+
def payment_is_in_refundable_state
|
|
96
|
+
return if payment.nil? || Spree::Config.refundable_payment_states.include?(payment.state)
|
|
97
|
+
|
|
98
|
+
if Spree::Config.require_refundable_payment_state
|
|
99
|
+
errors.add(:payment, :not_refundable)
|
|
100
|
+
else
|
|
101
|
+
Spree.deprecator.warn(
|
|
102
|
+
"Creating a refund for a payment in the '#{payment.state}' state is deprecated " \
|
|
103
|
+
"and will become a validation error in Solidus 5.0. Refunds should only be created " \
|
|
104
|
+
"for payments in one of these states: #{Spree::Config.refundable_payment_states.join(", ")}. " \
|
|
105
|
+
"Set `Spree::Config.require_refundable_payment_state = true` to adopt the new " \
|
|
106
|
+
"behavior early."
|
|
107
|
+
)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
94
111
|
def update_order
|
|
95
112
|
payment.order.recalculate
|
|
96
113
|
end
|
|
@@ -5,7 +5,7 @@ module Spree
|
|
|
5
5
|
module EligibilityValidator
|
|
6
6
|
class TimeSincePurchase < Spree::ReturnItem::EligibilityValidator::BaseValidator
|
|
7
7
|
def eligible_for_return?
|
|
8
|
-
if (@return_item.inventory_unit.order.completed_at + Spree::Config
|
|
8
|
+
if (@return_item.inventory_unit.order.completed_at + Spree::Config.return_eligibility_number_of_days.days) > Time.current
|
|
9
9
|
true
|
|
10
10
|
else
|
|
11
11
|
add_error(:number_of_days, I18n.t("spree.return_item_time_period_ineligible"))
|
|
@@ -41,6 +41,7 @@ module Spree
|
|
|
41
41
|
|
|
42
42
|
validate :eligible_exchange_variant
|
|
43
43
|
validate :belongs_to_same_customer_order
|
|
44
|
+
validate :belongs_to_return_authorization_order, if: -> { inventory_unit_id_changed? || return_authorization_id_changed? }
|
|
44
45
|
validate :validate_acceptance_status_for_reimbursement
|
|
45
46
|
validate :validate_no_other_completed_return_items
|
|
46
47
|
|
|
@@ -179,7 +180,7 @@ module Spree
|
|
|
179
180
|
end
|
|
180
181
|
|
|
181
182
|
def currency
|
|
182
|
-
return_authorization.try(:currency) || Spree::Config
|
|
183
|
+
return_authorization.try(:currency) || Spree::Config.currency
|
|
183
184
|
end
|
|
184
185
|
|
|
185
186
|
private
|
|
@@ -226,6 +227,14 @@ module Spree
|
|
|
226
227
|
end
|
|
227
228
|
end
|
|
228
229
|
|
|
230
|
+
def belongs_to_return_authorization_order
|
|
231
|
+
return unless return_authorization && inventory_unit
|
|
232
|
+
|
|
233
|
+
if return_authorization.order_id != inventory_unit.order_id
|
|
234
|
+
errors.add(:base, I18n.t("spree.return_items_cannot_be_associated_with_multiple_orders"))
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
229
238
|
def eligible_exchange_variant
|
|
230
239
|
return unless exchange_variant && exchange_variant_id_changed?
|
|
231
240
|
unless eligible_exchange_variants.include?(exchange_variant)
|
|
@@ -55,7 +55,7 @@ module Spree
|
|
|
55
55
|
def can_transition_from_pending_to_ready?
|
|
56
56
|
order.can_ship? &&
|
|
57
57
|
inventory_units.all? { |iu| iu.shipped? || iu.allow_ship? || iu.canceled? } &&
|
|
58
|
-
(order.paid? || !Spree::Config
|
|
58
|
+
(order.paid? || !Spree::Config.require_payment_to_ship)
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
def can_transition_from_canceled_to_ready?
|
|
@@ -83,7 +83,7 @@ module Spree
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def currency
|
|
86
|
-
order ? order.currency : Spree::Config
|
|
86
|
+
order ? order.currency : Spree::Config.currency
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
# @return [BigDecimal] the amount of this shipment, taking into
|
|
@@ -229,6 +229,8 @@ module Spree
|
|
|
229
229
|
self.state =
|
|
230
230
|
if shipped?
|
|
231
231
|
"shipped"
|
|
232
|
+
elsif inventory_units.none?
|
|
233
|
+
"pending"
|
|
232
234
|
elsif order.canceled? || inventory_units.all?(&:canceled?)
|
|
233
235
|
"canceled"
|
|
234
236
|
elsif !order.can_ship?
|
|
@@ -267,7 +269,7 @@ module Spree
|
|
|
267
269
|
def to_package
|
|
268
270
|
package = Stock::Package.new(stock_location)
|
|
269
271
|
package.shipment = self
|
|
270
|
-
inventory_units.includes(variant: :product).joins(:variant).group_by(&:state).each do |state, state_inventory_units|
|
|
272
|
+
inventory_units.not_canceled.includes(variant: :product).joins(:variant).group_by(&:state).each do |state, state_inventory_units|
|
|
271
273
|
package.add_multiple state_inventory_units, state.to_sym
|
|
272
274
|
end
|
|
273
275
|
package
|
|
@@ -12,7 +12,7 @@ module Spree
|
|
|
12
12
|
# * Combine allocated and on hand inventory into a single shipment per-location
|
|
13
13
|
#
|
|
14
14
|
# Allocation logic can be changed using a custom class (as
|
|
15
|
-
# configured in Spree::Config
|
|
15
|
+
# configured in Spree::Config.stock.allocator_class)
|
|
16
16
|
#
|
|
17
17
|
# After allocation, splitters are run on each Package (as configured in
|
|
18
18
|
# Spree::Config.environment.stock_splitters)
|
|
@@ -27,7 +27,14 @@ module Spree
|
|
|
27
27
|
:filtered_stock_locations, :inventory_units_by_variant, :desired,
|
|
28
28
|
:availability, :allocator, :packages
|
|
29
29
|
|
|
30
|
-
def initialize(order,
|
|
30
|
+
def initialize(order, inventory_units_deprecated = nil, inventory_units: nil)
|
|
31
|
+
if inventory_units_deprecated
|
|
32
|
+
Spree.deprecator.warn "Using the `inventory_units` positional " \
|
|
33
|
+
"argument is deprecated in favor of using the keyword argument. "
|
|
34
|
+
|
|
35
|
+
inventory_units ||= inventory_units_deprecated
|
|
36
|
+
end
|
|
37
|
+
|
|
31
38
|
@order = order
|
|
32
39
|
@inventory_units =
|
|
33
40
|
inventory_units || Spree::Config.stock.inventory_unit_builder_class.new(order).units
|
data/app/models/spree/store.rb
CHANGED
|
@@ -17,6 +17,8 @@ module Spree
|
|
|
17
17
|
|
|
18
18
|
has_many :orders, class_name: "Spree::Order"
|
|
19
19
|
|
|
20
|
+
belongs_to :address, class_name: "Spree::Address", optional: true, validate: true
|
|
21
|
+
|
|
20
22
|
validates :code, presence: true, uniqueness: {allow_blank: true, case_sensitive: true}
|
|
21
23
|
validates :name, presence: true
|
|
22
24
|
validates :url, presence: true
|
|
@@ -25,7 +27,7 @@ module Spree
|
|
|
25
27
|
self.allowed_ransackable_attributes = %w[name url code]
|
|
26
28
|
|
|
27
29
|
before_save :ensure_default_exists_and_is_unique
|
|
28
|
-
before_destroy :validate_not_default
|
|
30
|
+
before_destroy :validate_not_default, prepend: true
|
|
29
31
|
|
|
30
32
|
enum :reverse_charge_status, {
|
|
31
33
|
disabled: 0,
|
|
@@ -51,6 +53,10 @@ module Spree
|
|
|
51
53
|
end
|
|
52
54
|
end
|
|
53
55
|
|
|
56
|
+
def address_attributes=(attributes)
|
|
57
|
+
self.address = Spree::Address.immutable_merge(address, attributes)
|
|
58
|
+
end
|
|
59
|
+
|
|
54
60
|
def self.default
|
|
55
61
|
where(default: true).first || new
|
|
56
62
|
end
|
|
@@ -73,6 +79,7 @@ module Spree
|
|
|
73
79
|
def validate_not_default
|
|
74
80
|
if default
|
|
75
81
|
errors.add(:base, :cannot_destroy_default_store)
|
|
82
|
+
throw :abort
|
|
76
83
|
end
|
|
77
84
|
end
|
|
78
85
|
end
|
|
@@ -209,7 +209,7 @@ class Spree::StoreCredit < Spree::PaymentSource
|
|
|
209
209
|
def create_credit_record(amount, action_attributes = {})
|
|
210
210
|
# Setting credit_to_new_allocation to true will create a new allocation anytime #credit is called
|
|
211
211
|
# If it is not set, it will update the store credit's amount in place
|
|
212
|
-
credit = if Spree::Config
|
|
212
|
+
credit = if Spree::Config.credit_to_new_allocation
|
|
213
213
|
Spree::StoreCredit.new(create_credit_record_params(amount))
|
|
214
214
|
else
|
|
215
215
|
self.amount_used = amount_used - amount
|
|
@@ -23,6 +23,8 @@ module Spree
|
|
|
23
23
|
#
|
|
24
24
|
# @return [Spree::Tax::OrderTax] the calculated taxes for the order
|
|
25
25
|
def calculate
|
|
26
|
+
ActiveRecord::Associations::Preloader.new(records: order.line_items, associations: {variant: :product}).call
|
|
27
|
+
|
|
26
28
|
Spree::Tax::OrderTax.new(
|
|
27
29
|
order_id: order.id,
|
|
28
30
|
order_taxes: order_rates,
|
data/app/models/spree/taxon.rb
CHANGED
|
@@ -140,8 +140,11 @@ module Spree
|
|
|
140
140
|
private
|
|
141
141
|
|
|
142
142
|
def touch_ancestors_and_taxonomy
|
|
143
|
-
# Touches
|
|
144
|
-
|
|
143
|
+
# Touches ancestors directly rather than through #touch to avoid a recursive taxonomy touch.
|
|
144
|
+
time = Time.current
|
|
145
|
+
self.class.default_scoped.where(id: ancestors.pluck(:id)).order(:id).each do |ancestor|
|
|
146
|
+
ancestor.update_column(:updated_at, time)
|
|
147
|
+
end
|
|
145
148
|
# Have taxonomy touch happen in #touch_ancestors_and_taxonomy rather than association option in order for imports to override.
|
|
146
149
|
taxonomy.try!(:touch)
|
|
147
150
|
end
|
|
@@ -54,7 +54,7 @@ module Spree
|
|
|
54
54
|
# @return [Spree::Variant::PricingOptions] pricing options for pricing a line item
|
|
55
55
|
def self.from_context(context)
|
|
56
56
|
new(
|
|
57
|
-
currency: context.current_store.try!(:default_currency).presence || Spree::Config
|
|
57
|
+
currency: context.current_store.try!(:default_currency).presence || Spree::Config.currency,
|
|
58
58
|
country_iso: context.current_store.try!(:cart_tax_country_iso).presence
|
|
59
59
|
)
|
|
60
60
|
end
|
|
@@ -25,6 +25,7 @@ module Spree
|
|
|
25
25
|
def run
|
|
26
26
|
# Early return if there is no VAT rates in the current store.
|
|
27
27
|
return if !variant.tax_category || variant_vat_rates.empty?
|
|
28
|
+
return if variant.default_price&.amount.nil?
|
|
28
29
|
|
|
29
30
|
country_isos_requiring_price.each do |country_iso|
|
|
30
31
|
# Don't re-create the default price
|
data/app/models/spree/variant.rb
CHANGED
|
@@ -400,17 +400,17 @@ module Spree
|
|
|
400
400
|
|
|
401
401
|
# Ensures a new variant takes the product master price when price is not supplied
|
|
402
402
|
def set_price
|
|
403
|
-
self.price = product.master.price if price.nil? && Spree::Config
|
|
403
|
+
self.price = product.master.price if price.nil? && Spree::Config.require_master_price && !is_master?
|
|
404
404
|
end
|
|
405
405
|
|
|
406
406
|
def check_price
|
|
407
|
-
if price.nil? && Spree::Config
|
|
407
|
+
if price.nil? && Spree::Config.require_master_price && is_master?
|
|
408
408
|
errors.add :price, "Must supply price for variant or master.price for product."
|
|
409
409
|
end
|
|
410
410
|
end
|
|
411
411
|
|
|
412
412
|
def set_cost_currency
|
|
413
|
-
self.cost_currency = Spree::Config
|
|
413
|
+
self.cost_currency = Spree::Config.currency if cost_currency.blank?
|
|
414
414
|
end
|
|
415
415
|
|
|
416
416
|
def create_stock_items
|
data/config/locales/en.yml
CHANGED
|
@@ -158,6 +158,9 @@ en:
|
|
|
158
158
|
display_on: Display
|
|
159
159
|
name: Name
|
|
160
160
|
preference_source: Preference Source
|
|
161
|
+
preferred_server: Server
|
|
162
|
+
preferred_test_mode: Test Mode
|
|
163
|
+
store_ids: Stores
|
|
161
164
|
type: Type
|
|
162
165
|
spree/price:
|
|
163
166
|
amount: Price
|
|
@@ -191,6 +194,7 @@ en:
|
|
|
191
194
|
sku: Master SKU
|
|
192
195
|
slug: Slug
|
|
193
196
|
tax_category: Tax Category
|
|
197
|
+
taxon_ids: Categories
|
|
194
198
|
weight: Weight
|
|
195
199
|
width: Width
|
|
196
200
|
spree/product_property:
|
|
@@ -395,12 +399,15 @@ en:
|
|
|
395
399
|
tax_code: Tax Code
|
|
396
400
|
spree/tax_rate:
|
|
397
401
|
amount: Rate
|
|
402
|
+
calculator_type: Calculator
|
|
398
403
|
expires_at: Expiration Date
|
|
399
404
|
included_in_price: Included in Price
|
|
405
|
+
level: Tax Rate Level
|
|
400
406
|
name: Name
|
|
401
407
|
show_rate_in_label: Show Rate in Label
|
|
402
408
|
starts_at: Start Date
|
|
403
409
|
tax_categories: Tax Categories
|
|
410
|
+
tax_category_ids: Tax Categories
|
|
404
411
|
spree/taxon:
|
|
405
412
|
description: Description
|
|
406
413
|
icon: Icon
|
|
@@ -408,6 +415,7 @@ en:
|
|
|
408
415
|
meta_keywords: Meta Keywords
|
|
409
416
|
meta_title: Meta Title
|
|
410
417
|
name: Name
|
|
418
|
+
parent_id: Parent Category
|
|
411
419
|
permalink: Permalink
|
|
412
420
|
position: Position
|
|
413
421
|
spree/taxonomy:
|
|
@@ -495,6 +503,8 @@ en:
|
|
|
495
503
|
attributes:
|
|
496
504
|
amount:
|
|
497
505
|
greater_than_allowed: is greater than the allowed amount.
|
|
506
|
+
payment:
|
|
507
|
+
not_refundable: cannot be refunded in its current state.
|
|
498
508
|
spree/reimbursement:
|
|
499
509
|
attributes:
|
|
500
510
|
base:
|
|
@@ -1130,6 +1140,7 @@ en:
|
|
|
1130
1140
|
choose_currency: Choose Currency
|
|
1131
1141
|
choose_dashboard_locale: Choose Dashboard Locale
|
|
1132
1142
|
choose_dashboard_theme: Choose Dashboard Theme
|
|
1143
|
+
choose_dashboard_timezone: Choose Dashboard Timezone
|
|
1133
1144
|
choose_location: Choose Location
|
|
1134
1145
|
choose_reason: Choose Reason
|
|
1135
1146
|
city: City
|
|
@@ -1942,6 +1953,7 @@ en:
|
|
|
1942
1953
|
payment_could_not_be_created: Payment could not be created.
|
|
1943
1954
|
payment_identifier: Payment Identifier
|
|
1944
1955
|
payment_information: Payment Information
|
|
1956
|
+
payment_is_not_refundable: This payment cannot be refunded in its current state.
|
|
1945
1957
|
payment_method: Payment Method
|
|
1946
1958
|
payment_method_not_supported: That payment method is unsupported. Please choose another one.
|
|
1947
1959
|
payment_method_settings_warning: If you are changing the payment method type, you must save first before you can edit the payment method settings
|
|
@@ -2093,6 +2105,7 @@ en:
|
|
|
2093
2105
|
return_items: Return Items
|
|
2094
2106
|
return_items_cannot_be_associated_with_multiple_orders: Return items cannot be associated with multiple orders.
|
|
2095
2107
|
return_items_cannot_be_created_for_inventory_units_that_are_already_awaiting_exchange: Return items cannot be created for inventory units that are already awaiting exchange.
|
|
2108
|
+
return_items_must_have_shipped_inventory_units: Return items can only be created for shipped inventory units.
|
|
2096
2109
|
return_number: Return Number
|
|
2097
2110
|
return_quantity: Return Quantity
|
|
2098
2111
|
return_reasons: Return Reasons
|
data/db/default/spree/states.rb
CHANGED
|
@@ -13,7 +13,7 @@ ActiveRecord::Base.transaction do
|
|
|
13
13
|
carmen_country = Carmen::Country.coded(country.iso)
|
|
14
14
|
next unless carmen_country.subregions?
|
|
15
15
|
|
|
16
|
-
if Spree::Config
|
|
16
|
+
if Spree::Config.countries_that_use_nested_subregions.include? country.iso
|
|
17
17
|
create_states(carmen_country.subregions.flat_map(&:subregions), country)
|
|
18
18
|
else
|
|
19
19
|
create_states(carmen_country.subregions, country)
|
|
@@ -4,9 +4,7 @@ begin
|
|
|
4
4
|
user_class.classify.constantize
|
|
5
5
|
rescue NameError
|
|
6
6
|
say_status :error, "Can't find an existing user class named #{user_class.classify}, plese set up one before using this authentication option.", :red
|
|
7
|
-
# rubocop:disable Rails/Exit
|
|
8
7
|
abort
|
|
9
|
-
# rubocop:enable Rails/Exit
|
|
10
8
|
end
|
|
11
9
|
|
|
12
10
|
generate "spree:custom_user #{user_class.shellescape}"
|
|
@@ -1 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
template =
|
|
4
|
+
ENV["SOLIDUS_STOREFRONT_TEMPLATE"] ||
|
|
5
|
+
begin
|
|
6
|
+
version = Spree.solidus_version if defined?(Spree) && Spree.respond_to?(:solidus_version)
|
|
7
|
+
gem_version = version ? Gem::Version.new(version) : nil
|
|
8
|
+
|
|
9
|
+
ref =
|
|
10
|
+
if gem_version && !gem_version.prerelease?
|
|
11
|
+
"v#{gem_version.segments[0, 2].join(".")}"
|
|
12
|
+
else
|
|
13
|
+
"main"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
"https://github.com/solidusio/solidus/raw/#{ref}/storefront/template.rb"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
apply template
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
unless Bundler.locked_gems.dependencies["solidus_paypal_commerce_platform"]
|
|
2
|
-
|
|
2
|
+
# The released gem uses the old enum syntax and breaks on recent Ruby/Rails, so install from GitHub.
|
|
3
|
+
bundle_command "add solidus_paypal_commerce_platform --github solidusio/solidus_paypal_commerce_platform"
|
|
3
4
|
end
|
|
4
5
|
|
|
5
6
|
generate "solidus_paypal_commerce_platform:install --migrate=#{options[:migrate]}"
|
|
@@ -126,7 +126,7 @@ module Solidus
|
|
|
126
126
|
def install_file_attachment
|
|
127
127
|
if options[:active_storage]
|
|
128
128
|
say_status :assets, "Active Storage", :green
|
|
129
|
-
rake "active_storage:install"
|
|
129
|
+
rake "active_storage:install", abort_on_failure: true
|
|
130
130
|
else
|
|
131
131
|
say_status :assets, "Paperclip", :green
|
|
132
132
|
gsub_file "config/initializers/spree.rb", "::ActiveStorageAttachment", "::PaperclipAttachment"
|
|
@@ -158,19 +158,19 @@ module Solidus
|
|
|
158
158
|
|
|
159
159
|
def install_migrations
|
|
160
160
|
say_status :copying, "migrations"
|
|
161
|
-
rake "railties:install:migrations"
|
|
161
|
+
rake "railties:install:migrations", abort_on_failure: true
|
|
162
162
|
end
|
|
163
163
|
|
|
164
164
|
def create_database
|
|
165
165
|
say_status :creating, "database"
|
|
166
|
-
rake "db:create"
|
|
166
|
+
rake "db:create", abort_on_failure: true
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
def run_migrations
|
|
170
170
|
if @run_migrations
|
|
171
171
|
say_status :running, "migrations"
|
|
172
172
|
|
|
173
|
-
rake "db:migrate"
|
|
173
|
+
rake "db:migrate", abort_on_failure: true
|
|
174
174
|
else
|
|
175
175
|
say_status :skipping, "migrations (don't forget to run rake db:migrate)"
|
|
176
176
|
end
|
|
@@ -178,8 +178,8 @@ module Solidus
|
|
|
178
178
|
|
|
179
179
|
def install_subcomponents
|
|
180
180
|
apply_template_for :authentication, @selected_authentication
|
|
181
|
-
apply_template_for :frontend, @selected_frontend
|
|
182
181
|
apply_template_for :payment_method, @selected_payment_method
|
|
182
|
+
apply_template_for :frontend, @selected_frontend
|
|
183
183
|
end
|
|
184
184
|
|
|
185
185
|
def install_solidus_admin
|
|
@@ -200,7 +200,7 @@ module Solidus
|
|
|
200
200
|
rake_options << "ADMIN_EMAIL=#{options[:admin_email]}" if options[:admin_email]
|
|
201
201
|
rake_options << "ADMIN_PASSWORD=#{options[:admin_password]}" if options[:admin_password]
|
|
202
202
|
|
|
203
|
-
rake("db:seed #{rake_options.join(" ")}")
|
|
203
|
+
rake("db:seed #{rake_options.join(" ")}", abort_on_failure: true)
|
|
204
204
|
else
|
|
205
205
|
say_status :skipping, "seed data (you can always run rake db:seed)"
|
|
206
206
|
end
|
|
@@ -209,7 +209,7 @@ module Solidus
|
|
|
209
209
|
def load_sample_data
|
|
210
210
|
if @load_sample_data
|
|
211
211
|
say_status :loading, "sample data"
|
|
212
|
-
rake "spree_sample:load"
|
|
212
|
+
rake "spree_sample:load", abort_on_failure: true
|
|
213
213
|
else
|
|
214
214
|
say_status :skipping, "sample data (you can always run rake spree_sample:load)"
|
|
215
215
|
end
|