spree_core 3.3.6 → 3.4.0.rc1
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/app/helpers/spree/base_helper.rb +17 -18
- data/app/helpers/spree/products_helper.rb +5 -5
- data/app/models/concerns/spree/calculated_adjustments.rb +4 -3
- data/app/models/concerns/spree/default_price.rb +4 -5
- data/app/models/concerns/spree/display_money.rb +1 -1
- data/app/models/concerns/spree/named_type.rb +1 -1
- data/app/models/concerns/spree/ransackable_attributes.rb +5 -6
- data/app/models/concerns/spree/user_address.rb +6 -6
- data/app/models/concerns/spree/user_methods.rb +3 -3
- data/app/models/concerns/spree/user_payment_source.rb +4 -2
- data/app/models/concerns/spree/user_reporting.rb +1 -1
- data/app/models/spree/ability.rb +3 -3
- data/app/models/spree/address.rb +13 -9
- data/app/models/spree/adjustable/adjuster/promotion.rb +1 -1
- data/app/models/spree/adjustable/adjustments_updater.rb +2 -2
- data/app/models/spree/adjustable/promotion_accumulator.rb +6 -4
- data/app/models/spree/adjustment.rb +2 -3
- data/app/models/spree/app_configuration.rb +5 -6
- data/app/models/spree/base.rb +1 -1
- data/app/models/spree/calculator/default_tax.rb +4 -5
- data/app/models/spree/calculator/flat_percent_item_total.rb +1 -1
- data/app/models/spree/calculator/flat_rate.rb +3 -3
- data/app/models/spree/calculator/flexi_rate.rb +5 -5
- data/app/models/spree/calculator/price_sack.rb +9 -9
- data/app/models/spree/calculator/shipping/flat_percent_item_total.rb +1 -1
- data/app/models/spree/calculator/shipping/flat_rate.rb +3 -3
- data/app/models/spree/calculator/shipping/flexi_rate.rb +7 -7
- data/app/models/spree/calculator/shipping/per_item.rb +2 -2
- data/app/models/spree/calculator/shipping/price_sack.rb +4 -4
- data/app/models/spree/calculator/tiered_flat_rate.rb +3 -2
- data/app/models/spree/calculator/tiered_percent.rb +4 -3
- data/app/models/spree/calculator.rb +4 -4
- data/app/models/spree/classification.rb +2 -2
- data/app/models/spree/credit_card.rb +1 -1
- data/app/models/spree/exchange.rb +4 -5
- data/app/models/spree/gateway/bogus.rb +20 -20
- data/app/models/spree/gateway/bogus_simple.rb +2 -4
- data/app/models/spree/gateway.rb +4 -4
- data/app/models/spree/image.rb +3 -3
- data/app/models/spree/inventory_unit.rb +30 -30
- data/app/models/spree/line_item.rb +7 -9
- data/app/models/spree/option_type.rb +1 -1
- data/app/models/spree/order/checkout.rb +5 -5
- data/app/models/spree/order/currency_updater.rb +1 -4
- data/app/models/spree/order/payments.rb +4 -4
- data/app/models/spree/order/store_credit.rb +2 -2
- data/app/models/spree/order.rb +11 -29
- data/app/models/spree/order_contents.rb +6 -5
- data/app/models/spree/order_inventory.rb +3 -4
- data/app/models/spree/order_updater.rb +13 -14
- data/app/models/spree/payment/processing.rb +25 -26
- data/app/models/spree/payment.rb +72 -79
- data/app/models/spree/payment_capture_event.rb +1 -1
- data/app/models/spree/payment_method/check.rb +1 -1
- data/app/models/spree/payment_method/store_credit.rb +5 -5
- data/app/models/spree/payment_method.rb +7 -7
- data/app/models/spree/preferences/configuration.rb +6 -9
- data/app/models/spree/preferences/preferable.rb +11 -11
- data/app/models/spree/preferences/preferable_class_methods.rb +2 -3
- data/app/models/spree/preferences/scoped_store.rb +6 -5
- data/app/models/spree/preferences/store.rb +9 -14
- data/app/models/spree/price.rb +1 -1
- data/app/models/spree/product/scopes.rb +49 -49
- data/app/models/spree/product.rb +16 -16
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +2 -1
- data/app/models/spree/promotion/actions/free_shipping.rb +1 -1
- data/app/models/spree/promotion/rules/first_order.rb +7 -6
- data/app/models/spree/promotion/rules/item_total.rb +3 -5
- data/app/models/spree/promotion/rules/one_use_per_user.rb +1 -2
- data/app/models/spree/promotion/rules/option_value.rb +14 -6
- data/app/models/spree/promotion/rules/product.rb +4 -4
- data/app/models/spree/promotion/rules/taxon.rb +6 -6
- data/app/models/spree/promotion/rules/user.rb +3 -3
- data/app/models/spree/promotion/rules/user_logged_in.rb +1 -1
- data/app/models/spree/promotion.rb +15 -16
- data/app/models/spree/promotion_action.rb +1 -1
- data/app/models/spree/promotion_handler/cart.rb +3 -2
- data/app/models/spree/promotion_handler/free_shipping.rb +1 -3
- data/app/models/spree/promotion_handler/page.rb +3 -3
- data/app/models/spree/promotion_rule.rb +5 -4
- data/app/models/spree/refund.rb +8 -8
- data/app/models/spree/reimbursement/credit.rb +1 -1
- data/app/models/spree/reimbursement/reimbursement_type_engine.rb +1 -3
- data/app/models/spree/reimbursement.rb +4 -8
- data/app/models/spree/reimbursement_performer.rb +0 -5
- data/app/models/spree/reimbursement_tax_calculator.rb +5 -12
- data/app/models/spree/reimbursement_type.rb +2 -2
- data/app/models/spree/return_authorization.rb +22 -26
- data/app/models/spree/return_item/eligibility_validator/default.rb +3 -3
- data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/order_completed.rb +2 -2
- data/app/models/spree/return_item/eligibility_validator/rma_required.rb +2 -3
- data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +2 -2
- data/app/models/spree/return_item.rb +15 -19
- data/app/models/spree/returns_calculator.rb +1 -2
- data/app/models/spree/shipment.rb +14 -35
- data/app/models/spree/shipment_handler.rb +10 -12
- data/app/models/spree/shipping_calculator.rb +5 -6
- data/app/models/spree/shipping_method.rb +3 -3
- data/app/models/spree/shipping_rate.rb +2 -2
- data/app/models/spree/state.rb +2 -2
- data/app/models/spree/stock/availability_validator.rb +1 -1
- data/app/models/spree/stock/content_item.rb +2 -3
- data/app/models/spree/stock/coordinator.rb +3 -2
- data/app/models/spree/stock/differentiator.rb +3 -2
- data/app/models/spree/stock/estimator.rb +7 -5
- data/app/models/spree/stock/package.rb +5 -5
- data/app/models/spree/stock/packer.rb +1 -1
- data/app/models/spree/stock/prioritizer.rb +5 -7
- data/app/models/spree/stock/quantifier.rb +0 -1
- data/app/models/spree/stock/splitter/backordered.rb +2 -4
- data/app/models/spree/stock/splitter/base.rb +3 -2
- data/app/models/spree/stock/splitter/shipping_category.rb +2 -1
- data/app/models/spree/stock_item.rb +1 -1
- data/app/models/spree/stock_location.rb +12 -11
- data/app/models/spree/stock_movement.rb +1 -3
- data/app/models/spree/stock_transfer.rb +1 -1
- data/app/models/spree/store.rb +4 -4
- data/app/models/spree/store_credit.rb +3 -3
- data/app/models/spree/tax_category.rb +1 -1
- data/app/models/spree/tax_rate.rb +10 -10
- data/app/models/spree/taxon.rb +13 -13
- data/app/models/spree/taxonomy.rb +9 -8
- data/app/models/spree/validations/db_maximum_length_validator.rb +2 -3
- data/app/models/spree/variant.rb +30 -41
- data/app/models/spree/zone.rb +10 -10
- data/app/validators/db_maximum_length_validator.rb +5 -5
- data/config/initializers/acts_as_taggable_on.rb +3 -3
- data/config/initializers/assets.rb +1 -1
- data/config/initializers/friendly_id.rb +1 -1
- data/config/initializers/premailer_assets.rb +1 -1
- data/config/locales/en.yml +8 -2
- data/db/default/spree/states.rb +1 -0
- data/lib/generators/spree/custom_user/custom_user_generator.rb +12 -15
- data/lib/generators/spree/install/install_generator.rb +45 -32
- data/lib/spree/core/components.rb +3 -3
- data/lib/spree/core/controller_helpers/auth.rb +5 -10
- data/lib/spree/core/controller_helpers/common.rb +2 -3
- data/lib/spree/core/controller_helpers/order.rb +3 -7
- data/lib/spree/core/controller_helpers/respond_with.rb +4 -4
- data/lib/spree/core/engine.rb +3 -3
- data/lib/spree/core/environment/calculators.rb +0 -1
- data/lib/spree/core/environment_extension.rb +8 -8
- data/lib/spree/core/importer/order.rb +64 -67
- data/lib/spree/core/importer/product.rb +10 -9
- data/lib/spree/core/product_filters.rb +17 -18
- data/lib/spree/core/routes.rb +2 -6
- data/lib/spree/core/search/base.rb +62 -59
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +4 -6
- data/lib/spree/i18n.rb +3 -5
- data/lib/spree/localized_number.rb +0 -2
- data/lib/spree/migrations.rb +8 -7
- data/lib/spree/money.rb +3 -7
- data/lib/spree/permitted_attributes.rb +2 -2
- data/lib/spree/responder.rb +4 -5
- data/lib/spree/testing_support/authorization_helpers.rb +3 -3
- data/lib/spree/testing_support/caching.rb +5 -5
- data/lib/spree/testing_support/capybara_ext.rb +16 -18
- data/lib/spree/testing_support/common_rake.rb +8 -9
- data/lib/spree/testing_support/controller_requests.rb +6 -6
- data/lib/spree/testing_support/extension_rake.rb +2 -3
- data/lib/spree/testing_support/factories/address_factory.rb +1 -1
- data/lib/spree/testing_support/factories/adjustment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/calculator_factory.rb +1 -1
- data/lib/spree/testing_support/factories/country_factory.rb +1 -1
- data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
- data/lib/spree/testing_support/factories/customer_return_factory.rb +1 -3
- data/lib/spree/testing_support/factories/image_factory.rb +2 -2
- data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -1
- data/lib/spree/testing_support/factories/line_item_factory.rb +2 -2
- data/lib/spree/testing_support/factories/options_factory.rb +1 -1
- data/lib/spree/testing_support/factories/order_factory.rb +1 -1
- data/lib/spree/testing_support/factories/payment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/payment_method_factory.rb +4 -4
- data/lib/spree/testing_support/factories/price_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_option_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/product_property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/promotion_category_factory.rb +1 -2
- data/lib/spree/testing_support/factories/promotion_factory.rb +1 -2
- data/lib/spree/testing_support/factories/promotion_rule_factory.rb +1 -1
- data/lib/spree/testing_support/factories/property_factory.rb +1 -1
- data/lib/spree/testing_support/factories/prototype_factory.rb +1 -1
- data/lib/spree/testing_support/factories/refund_factory.rb +1 -1
- data/lib/spree/testing_support/factories/reimbursement_factory.rb +2 -2
- data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/return_authorization_factory.rb +1 -1
- data/lib/spree/testing_support/factories/return_item_factory.rb +1 -1
- data/lib/spree/testing_support/factories/role_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +2 -2
- data/lib/spree/testing_support/factories/shipping_category_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +3 -3
- data/lib/spree/testing_support/factories/state_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_item_factory.rb +1 -1
- data/lib/spree/testing_support/factories/stock_location_factory.rb +2 -2
- data/lib/spree/testing_support/factories/stock_movement_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_category_factory.rb +2 -2
- data/lib/spree/testing_support/factories/store_credit_event_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_credit_type_factory.rb +1 -1
- data/lib/spree/testing_support/factories/store_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tag_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tax_category_factory.rb +2 -2
- data/lib/spree/testing_support/factories/tax_rate_factory.rb +1 -1
- data/lib/spree/testing_support/factories/taxon_factory.rb +1 -1
- data/lib/spree/testing_support/factories/taxonomy_factory.rb +1 -1
- data/lib/spree/testing_support/factories/tracker_factory.rb +1 -1
- data/lib/spree/testing_support/factories/user_factory.rb +1 -1
- data/lib/spree/testing_support/factories/variant_factory.rb +1 -2
- data/lib/spree/testing_support/factories/zone_factory.rb +1 -1
- data/lib/spree/testing_support/factories/zone_member_factory.rb +1 -1
- data/lib/spree/testing_support/factories.rb +3 -3
- data/lib/spree/testing_support/flash.rb +1 -3
- data/lib/spree/testing_support/i18n.rb +5 -6
- data/lib/spree/testing_support/kernel.rb +1 -2
- data/lib/spree/testing_support/order_walkthrough.rb +12 -15
- data/lib/spree/testing_support/preferences.rb +0 -1
- data/lib/tasks/core.rake +47 -56
- data/lib/tasks/email.rake +2 -2
- data/lib/tasks/exchanges.rake +5 -5
- data/spree_core.gemspec +1 -1
- metadata +5 -9
- data/app/models/spree/calculator/percent_per_item.rb +0 -51
- data/config/initializers/premailer_rails.rb +0 -3
- data/lib/spree/core/delegate_belongs_to.rb +0 -99
- data/lib/spree/testing_support/microdata.rb +0 -192
@@ -16,7 +16,7 @@ module Spree
|
|
16
16
|
if store_credit.nil?
|
17
17
|
ActiveMerchant::Billing::Response.new(false, Spree.t('store_credit_payment_method.unable_to_find'), {}, {})
|
18
18
|
else
|
19
|
-
action =
|
19
|
+
action = lambda do |store_credit|
|
20
20
|
store_credit.authorize(
|
21
21
|
amount_in_cents / 100.0.to_d,
|
22
22
|
gateway_options[:currency],
|
@@ -28,7 +28,7 @@ module Spree
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def capture(amount_in_cents, auth_code, gateway_options = {})
|
31
|
-
action =
|
31
|
+
action = lambda do |store_credit|
|
32
32
|
store_credit.capture(
|
33
33
|
amount_in_cents / 100.0.to_d,
|
34
34
|
auth_code,
|
@@ -57,14 +57,14 @@ module Spree
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def void(auth_code, gateway_options = {})
|
60
|
-
action =
|
60
|
+
action = lambda do |store_credit|
|
61
61
|
store_credit.void(auth_code, action_originator: gateway_options[:originator])
|
62
62
|
end
|
63
63
|
handle_action(action, :void, auth_code)
|
64
64
|
end
|
65
65
|
|
66
66
|
def credit(amount_in_cents, auth_code, gateway_options)
|
67
|
-
action =
|
67
|
+
action = lambda do |store_credit|
|
68
68
|
currency = gateway_options[:currency] || store_credit.currency
|
69
69
|
originator = gateway_options[:originator]
|
70
70
|
|
@@ -82,7 +82,7 @@ module Spree
|
|
82
82
|
if !store_credit_event || !store_credit
|
83
83
|
handle_action(nil, :cancel, false)
|
84
84
|
else
|
85
|
-
action =
|
85
|
+
action = lambda do |store_credit|
|
86
86
|
store_credit.credit(store_credit_event.amount, auth_code, store_credit.currency)
|
87
87
|
end
|
88
88
|
handle_action(action, :cancel, auth_code)
|
@@ -13,8 +13,8 @@ module Spree
|
|
13
13
|
validates :name, presence: true
|
14
14
|
|
15
15
|
with_options dependent: :restrict_with_error do
|
16
|
-
has_many :payments, class_name:
|
17
|
-
has_many :credit_cards, class_name:
|
16
|
+
has_many :payments, class_name: 'Spree::Payment', inverse_of: :payment_method
|
17
|
+
has_many :credit_cards, class_name: 'Spree::CreditCard'
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.providers
|
@@ -36,7 +36,7 @@ module Spree
|
|
36
36
|
type.demodulize.downcase
|
37
37
|
end
|
38
38
|
|
39
|
-
def self.find_with_destroyed
|
39
|
+
def self.find_with_destroyed(*args)
|
40
40
|
unscoped { find(*args) }
|
41
41
|
end
|
42
42
|
|
@@ -50,19 +50,19 @@ module Spree
|
|
50
50
|
|
51
51
|
# Custom gateways should redefine this method. See Gateway implementation
|
52
52
|
# as an example
|
53
|
-
def reusable_sources(
|
53
|
+
def reusable_sources(_order)
|
54
54
|
[]
|
55
55
|
end
|
56
56
|
|
57
57
|
def auto_capture?
|
58
|
-
|
58
|
+
auto_capture.nil? ? Spree::Config[:auto_capture] : auto_capture
|
59
59
|
end
|
60
60
|
|
61
|
-
def supports?(
|
61
|
+
def supports?(_source)
|
62
62
|
true
|
63
63
|
end
|
64
64
|
|
65
|
-
def cancel(
|
65
|
+
def cancel(_response)
|
66
66
|
raise ::NotImplementedError, 'You must implement cancel method for this payment method.'
|
67
67
|
end
|
68
68
|
|
@@ -33,15 +33,15 @@ module Spree::Preferences
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def reset
|
36
|
-
preferences.each do |name,
|
36
|
+
preferences.each do |name, _value|
|
37
37
|
set_preference name, preference_default(name)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
alias
|
42
|
-
alias
|
41
|
+
alias [] get_preference
|
42
|
+
alias []= set_preference
|
43
43
|
|
44
|
-
alias
|
44
|
+
alias get get_preference
|
45
45
|
|
46
46
|
def set(*args)
|
47
47
|
options = args.extract_options!
|
@@ -49,13 +49,11 @@ module Spree::Preferences
|
|
49
49
|
set_preference name, value
|
50
50
|
end
|
51
51
|
|
52
|
-
if args.size == 2
|
53
|
-
set_preference args[0], args[1]
|
54
|
-
end
|
52
|
+
set_preference args[0], args[1] if args.size == 2
|
55
53
|
end
|
56
54
|
|
57
55
|
def method_missing(method, *args)
|
58
|
-
name = method.to_s.
|
56
|
+
name = method.to_s.delete('=')
|
59
57
|
if has_preference? name
|
60
58
|
if method.to_s =~ /=$/
|
61
59
|
set_preference(name, args.first)
|
@@ -66,6 +64,5 @@ module Spree::Preferences
|
|
66
64
|
super
|
67
65
|
end
|
68
66
|
end
|
69
|
-
|
70
67
|
end
|
71
68
|
end
|
@@ -59,7 +59,7 @@ module Spree::Preferences::Preferable
|
|
59
59
|
end
|
60
60
|
|
61
61
|
def has_preference!(name)
|
62
|
-
raise NoMethodError
|
62
|
+
raise NoMethodError, "#{name} preference not defined" unless has_preference? name
|
63
63
|
end
|
64
64
|
|
65
65
|
def has_preference?(name)
|
@@ -81,7 +81,7 @@ module Spree::Preferences::Preferable
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def clear_preferences
|
84
|
-
preferences.keys.each {|pref| preferences.delete pref}
|
84
|
+
preferences.keys.each { |pref| preferences.delete pref }
|
85
85
|
end
|
86
86
|
|
87
87
|
private
|
@@ -98,24 +98,24 @@ module Spree::Preferences::Preferable
|
|
98
98
|
value.to_i
|
99
99
|
when :boolean
|
100
100
|
if value.is_a?(FalseClass) ||
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
101
|
+
value.nil? ||
|
102
|
+
value == 0 ||
|
103
|
+
value =~ /^(f|false|0)$/i ||
|
104
|
+
(value.respond_to?(:empty?) && value.empty?)
|
105
|
+
false
|
106
106
|
else
|
107
|
-
|
107
|
+
true
|
108
108
|
end
|
109
109
|
when :array
|
110
110
|
value.is_a?(Array) ? value : Array.wrap(value)
|
111
111
|
when :hash
|
112
112
|
case value.class.to_s
|
113
|
-
when
|
113
|
+
when 'Hash'
|
114
114
|
value
|
115
|
-
when
|
115
|
+
when 'String'
|
116
116
|
# only works with hashes whose keys are strings
|
117
117
|
JSON.parse value.gsub('=>', ':')
|
118
|
-
when
|
118
|
+
when 'Array'
|
119
119
|
begin
|
120
120
|
value.try(:to_h)
|
121
121
|
rescue TypeError
|
@@ -1,11 +1,10 @@
|
|
1
1
|
module Spree::Preferences
|
2
2
|
module PreferableClassMethods
|
3
|
-
|
4
3
|
def preference(name, type, *args)
|
5
4
|
options = args.extract_options!
|
6
5
|
options.assert_valid_keys(:default)
|
7
6
|
default = options[:default]
|
8
|
-
default = ->{ options[:default] } unless default.is_a?(Proc)
|
7
|
+
default = -> { options[:default] } unless default.is_a?(Proc)
|
9
8
|
|
10
9
|
# cache_key will be nil for new objects, then if we check if there
|
11
10
|
# is a pending preference before going to default
|
@@ -37,7 +36,7 @@ module Spree::Preferences
|
|
37
36
|
end
|
38
37
|
|
39
38
|
def preference_setter_method(name)
|
40
|
-
|
39
|
+
"preferred_#{name}=".to_sym
|
41
40
|
end
|
42
41
|
|
43
42
|
def preference_default_getter_method(name)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Spree::Preferences
|
2
2
|
class ScopedStore
|
3
|
-
def initialize
|
3
|
+
def initialize(prefix, suffix = nil)
|
4
4
|
@prefix = prefix
|
5
5
|
@suffix = suffix
|
6
6
|
end
|
@@ -9,20 +9,21 @@ module Spree::Preferences
|
|
9
9
|
Spree::Preferences::Store.instance
|
10
10
|
end
|
11
11
|
|
12
|
-
def fetch
|
12
|
+
def fetch(key, &block)
|
13
13
|
store.fetch(key_for(key), &block)
|
14
14
|
end
|
15
15
|
|
16
|
-
def []=
|
16
|
+
def []=(key, value)
|
17
17
|
store[key_for(key)] = value
|
18
18
|
end
|
19
19
|
|
20
|
-
def delete
|
20
|
+
def delete(key)
|
21
21
|
store.delete(key_for(key))
|
22
22
|
end
|
23
23
|
|
24
24
|
private
|
25
|
-
|
25
|
+
|
26
|
+
def key_for(key)
|
26
27
|
[rails_cache_id, @prefix, key, @suffix].compact.join('/')
|
27
28
|
end
|
28
29
|
|
@@ -7,7 +7,6 @@
|
|
7
7
|
require 'singleton'
|
8
8
|
|
9
9
|
module Spree::Preferences
|
10
|
-
|
11
10
|
class StoreInstance
|
12
11
|
attr_accessor :persistence
|
13
12
|
|
@@ -20,11 +19,11 @@ module Spree::Preferences
|
|
20
19
|
@cache.write(key, value)
|
21
20
|
persist(key, value)
|
22
21
|
end
|
23
|
-
|
22
|
+
alias []= set
|
24
23
|
|
25
24
|
def exist?(key)
|
26
25
|
@cache.exist?(key) ||
|
27
|
-
|
26
|
+
should_persist? && Spree::Preference.where(key: key).exists?
|
28
27
|
end
|
29
28
|
|
30
29
|
def get(key)
|
@@ -40,13 +39,13 @@ module Spree::Preferences
|
|
40
39
|
# has been cleared from the cache
|
41
40
|
|
42
41
|
# does it exist in the database?
|
43
|
-
if preference = Spree::Preference.find_by(key: key)
|
42
|
+
val = if preference = Spree::Preference.find_by(key: key)
|
44
43
|
# it does exist
|
45
|
-
|
46
|
-
|
44
|
+
preference.value
|
45
|
+
else
|
47
46
|
# use the fallback value
|
48
|
-
|
49
|
-
|
47
|
+
yield
|
48
|
+
end
|
50
49
|
|
51
50
|
# Cache either the value from the db or the fallback value.
|
52
51
|
# This avoids hitting the db with subsequent queries.
|
@@ -57,7 +56,7 @@ module Spree::Preferences
|
|
57
56
|
yield
|
58
57
|
end
|
59
58
|
end
|
60
|
-
|
59
|
+
alias fetch get
|
61
60
|
|
62
61
|
def delete(key)
|
63
62
|
@cache.delete(key)
|
@@ -86,15 +85,11 @@ module Spree::Preferences
|
|
86
85
|
end
|
87
86
|
|
88
87
|
def should_persist?
|
89
|
-
@persistence
|
90
|
-
rescue PG::ConnectionBad, ActiveRecord::NoDatabaseError
|
91
|
-
false
|
88
|
+
@persistence && ActiveRecord::Base.connected? && Spree::Preference.table_exists?
|
92
89
|
end
|
93
|
-
|
94
90
|
end
|
95
91
|
|
96
92
|
class Store < StoreInstance
|
97
93
|
include Singleton
|
98
94
|
end
|
99
|
-
|
100
95
|
end
|
data/app/models/spree/price.rb
CHANGED
@@ -5,7 +5,7 @@ module Spree
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def self.add_search_scope(name, &block)
|
8
|
-
|
8
|
+
singleton_class.send(:define_method, name.to_sym, &block)
|
9
9
|
search_scopes << name.to_sym
|
10
10
|
end
|
11
11
|
|
@@ -21,18 +21,18 @@ module Spree
|
|
21
21
|
def self.add_simple_scopes(scopes)
|
22
22
|
scopes.each do |name|
|
23
23
|
# We should not define price scopes here, as they require something slightly different
|
24
|
-
next if name.to_s.include?(
|
24
|
+
next if name.to_s.include?('master_price')
|
25
25
|
parts = name.to_s.match(/(.*)_by_(.*)/)
|
26
|
-
|
26
|
+
scope(name.to_s, -> { order("#{Product.quoted_table_name}.#{parts[2]} #{parts[1] == 'ascend' ? 'ASC' : 'DESC'}") })
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
def self.property_conditions(property)
|
31
31
|
properties = Property.table_name
|
32
32
|
conditions = case property
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
when String then { "#{properties}.name" => property }
|
34
|
+
when Property then { "#{properties}.id" => property.id }
|
35
|
+
else { "#{properties}.id" => property.to_i }
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -77,8 +77,8 @@ module Spree
|
|
77
77
|
# SELECT COUNT(*) ...
|
78
78
|
add_search_scope :in_taxon do |taxon|
|
79
79
|
includes(:classifications).
|
80
|
-
|
81
|
-
|
80
|
+
where('spree_products_taxons.taxon_id' => taxon.self_and_descendants.pluck(:id)).
|
81
|
+
order('spree_products_taxons.position ASC')
|
82
82
|
end
|
83
83
|
|
84
84
|
# This scope selects products in all taxons AND all its descendants
|
@@ -98,17 +98,17 @@ module Spree
|
|
98
98
|
# a simple test for product with a certain property-value pairing
|
99
99
|
# note that it can test for properties with NULL values, but not for absent values
|
100
100
|
add_search_scope :with_property_value do |property, value|
|
101
|
-
joins(:properties)
|
102
|
-
|
103
|
-
|
101
|
+
joins(:properties).
|
102
|
+
where("#{ProductProperty.table_name}.value = ?", value).
|
103
|
+
where(property_conditions(property))
|
104
104
|
end
|
105
105
|
|
106
106
|
add_search_scope :with_option do |option|
|
107
107
|
option_types = OptionType.table_name
|
108
108
|
conditions = case option
|
109
|
-
|
110
|
-
|
111
|
-
|
109
|
+
when String then { "#{option_types}.name" => option }
|
110
|
+
when OptionType then { "#{option_types}.id" => option.id }
|
111
|
+
else { "#{option_types}.id" => option.to_i }
|
112
112
|
end
|
113
113
|
|
114
114
|
joins(:option_types).where(conditions)
|
@@ -117,9 +117,9 @@ module Spree
|
|
117
117
|
add_search_scope :with_option_value do |option, value|
|
118
118
|
option_values = OptionValue.table_name
|
119
119
|
option_type_id = case option
|
120
|
-
|
121
|
-
|
122
|
-
|
120
|
+
when String then OptionType.find_by(name: option) || option.to_i
|
121
|
+
when OptionType then option.id
|
122
|
+
else option.to_i
|
123
123
|
end
|
124
124
|
|
125
125
|
conditions = "#{option_values}.name = ? AND #{option_values}.option_type_id = ?", value, option_type_id
|
@@ -131,8 +131,8 @@ module Spree
|
|
131
131
|
# 2) have a product property with a value matching the one given
|
132
132
|
add_search_scope :with do |value|
|
133
133
|
includes(variants_including_master: :option_values).
|
134
|
-
|
135
|
-
|
134
|
+
includes(:product_properties).
|
135
|
+
where("#{OptionValue.table_name}.name = ? OR #{ProductProperty.table_name}.value = ?", value, value)
|
136
136
|
end
|
137
137
|
|
138
138
|
# Finds all products that have a name containing the given words.
|
@@ -166,7 +166,7 @@ module Spree
|
|
166
166
|
# order: 'COALESCE(cnt, 0) DESC'
|
167
167
|
add_search_scope :descend_by_popularity do
|
168
168
|
joins(:master).
|
169
|
-
|
169
|
+
order(%Q{
|
170
170
|
COALESCE((
|
171
171
|
SELECT
|
172
172
|
COUNT(#{LineItem.quoted_table_name}.id)
|
@@ -195,7 +195,7 @@ module Spree
|
|
195
195
|
end
|
196
196
|
search_scopes << :not_discontinued
|
197
197
|
# Can't use add_search_scope for this as it needs a default argument
|
198
|
-
def self.available(available_on = nil,
|
198
|
+
def self.available(available_on = nil, _currency = nil)
|
199
199
|
available_on ||= Time.current
|
200
200
|
not_discontinued.joins(master: :prices).where("#{Product.quoted_table_name}.available_on <= ?", available_on)
|
201
201
|
end
|
@@ -207,11 +207,11 @@ module Spree
|
|
207
207
|
search_scopes << :active
|
208
208
|
|
209
209
|
add_search_scope :taxons_name_eq do |name|
|
210
|
-
group(
|
210
|
+
group('spree_products.id').joins(:taxons).where(Taxon.arel_table[:name].eq(name))
|
211
211
|
end
|
212
212
|
|
213
213
|
def self.distinct_by_product_ids(sort_order = nil)
|
214
|
-
sort_column = sort_order.split(
|
214
|
+
sort_column = sort_order.split(' ').first
|
215
215
|
|
216
216
|
# Postgres will complain when using ordering by expressions not present in
|
217
217
|
# SELECT DISTINCT. e.g.
|
@@ -237,35 +237,35 @@ module Spree
|
|
237
237
|
|
238
238
|
private
|
239
239
|
|
240
|
-
|
241
|
-
|
242
|
-
|
240
|
+
def self.price_table_name
|
241
|
+
Price.quoted_table_name
|
242
|
+
end
|
243
243
|
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
244
|
+
# specifically avoid having an order for taxon search (conflicts with main order)
|
245
|
+
def self.prepare_taxon_conditions(taxons)
|
246
|
+
ids = taxons.map { |taxon| taxon.self_and_descendants.pluck(:id) }.flatten.uniq
|
247
|
+
joins(:classifications).where(Classification.table_name => { taxon_id: ids })
|
248
|
+
end
|
249
249
|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
250
|
+
# Produce an array of keywords for use in scopes.
|
251
|
+
# Always return array with at least an empty string to avoid SQL errors
|
252
|
+
def self.prepare_words(words)
|
253
|
+
return [''] if words.blank?
|
254
|
+
a = words.split(/[,\s]/).map(&:strip)
|
255
|
+
a.any? ? a : ['']
|
256
|
+
end
|
257
257
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
258
|
+
def self.get_taxons(*ids_or_records_or_names)
|
259
|
+
taxons = Taxon.table_name
|
260
|
+
ids_or_records_or_names.flatten.map do |t|
|
261
|
+
case t
|
262
|
+
when Integer then Taxon.find_by(id: t)
|
263
|
+
when ApplicationRecord then t
|
264
|
+
when String
|
265
|
+
Taxon.find_by(name: t) ||
|
266
266
|
Taxon.where("#{taxons}.permalink LIKE ? OR #{taxons}.permalink = ?", "%/#{t}/", "#{t}/").first
|
267
|
-
|
268
|
-
|
269
|
-
|
267
|
+
end
|
268
|
+
end.compact.flatten.uniq
|
269
|
+
end
|
270
270
|
end
|
271
271
|
end
|
data/app/models/spree/product.rb
CHANGED
@@ -51,20 +51,20 @@ module Spree
|
|
51
51
|
belongs_to :shipping_category, class_name: 'Spree::ShippingCategory', inverse_of: :products
|
52
52
|
|
53
53
|
has_one :master,
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
-> { where is_master: true },
|
55
|
+
inverse_of: :product,
|
56
|
+
class_name: 'Spree::Variant'
|
57
57
|
|
58
58
|
has_many :variants,
|
59
|
-
|
60
|
-
|
61
|
-
|
59
|
+
-> { where(is_master: false).order(:position) },
|
60
|
+
inverse_of: :product,
|
61
|
+
class_name: 'Spree::Variant'
|
62
62
|
|
63
63
|
has_many :variants_including_master,
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
-> { order(:position) },
|
65
|
+
inverse_of: :product,
|
66
|
+
class_name: 'Spree::Variant',
|
67
|
+
dependent: :destroy
|
68
68
|
|
69
69
|
has_many :prices, -> { order('spree_variants.position, spree_variants.id, currency') }, through: :variants
|
70
70
|
|
@@ -105,9 +105,9 @@ module Spree
|
|
105
105
|
|
106
106
|
attr_accessor :option_values_hash
|
107
107
|
|
108
|
-
accepts_nested_attributes_for :product_properties, allow_destroy: true, reject_if:
|
108
|
+
accepts_nested_attributes_for :product_properties, allow_destroy: true, reject_if: ->(pp) { pp[:property_name].blank? }
|
109
109
|
|
110
|
-
alias
|
110
|
+
alias options product_option_types
|
111
111
|
|
112
112
|
self.whitelisted_ransackable_associations = %w[stores variants_including_master master variants]
|
113
113
|
self.whitelisted_ransackable_attributes = %w[description name slug discontinue_on]
|
@@ -123,7 +123,7 @@ module Spree
|
|
123
123
|
delegate :display_amount, :display_price, :has_default_price?,
|
124
124
|
:images, to: :find_or_build_master
|
125
125
|
|
126
|
-
|
126
|
+
alias master_images images
|
127
127
|
|
128
128
|
def find_or_build_master
|
129
129
|
master || build_master
|
@@ -192,7 +192,7 @@ module Spree
|
|
192
192
|
# eg categorise_variants_from_option(color) => {"red" -> [...], "blue" -> [...]}
|
193
193
|
def categorise_variants_from_option(opt_type)
|
194
194
|
return {} unless option_types.include?(opt_type)
|
195
|
-
variants.active.group_by { |v| v.option_values.detect { |o| o.option_type == opt_type} }
|
195
|
+
variants.active.group_by { |v| v.option_values.detect { |o| o.option_type == opt_type } }
|
196
196
|
end
|
197
197
|
|
198
198
|
def self.like_any(fields, values)
|
@@ -307,7 +307,7 @@ module Spree
|
|
307
307
|
end
|
308
308
|
|
309
309
|
def update_slug_history
|
310
|
-
|
310
|
+
save!
|
311
311
|
end
|
312
312
|
|
313
313
|
def anything_changed?
|
@@ -349,7 +349,7 @@ module Spree
|
|
349
349
|
# Required to avoid Variant#check_price validation failing on create.
|
350
350
|
unless master.default_price && master.valid?
|
351
351
|
master.errors.each do |att, error|
|
352
|
-
|
352
|
+
errors.add(att, error)
|
353
353
|
end
|
354
354
|
end
|
355
355
|
end
|
@@ -8,7 +8,8 @@ module Spree
|
|
8
8
|
before_validation -> { self.calculator ||= Calculator::PercentOnLineItem.new }
|
9
9
|
|
10
10
|
def perform(options = {})
|
11
|
-
order
|
11
|
+
order = options[:order]
|
12
|
+
promotion = options[:promotion]
|
12
13
|
create_unique_adjustments(order, order.line_items) do |line_item|
|
13
14
|
promotion.line_item_actionable?(order, line_item)
|
14
15
|
end
|
@@ -24,13 +24,14 @@ module Spree
|
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
27
|
-
def completed_orders
|
28
|
-
user ? user.orders.complete : orders_by_email
|
29
|
-
end
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
28
|
+
def completed_orders
|
29
|
+
user ? user.orders.complete : orders_by_email
|
30
|
+
end
|
31
|
+
|
32
|
+
def orders_by_email
|
33
|
+
Spree::Order.where(email: email).complete
|
34
|
+
end
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
@@ -9,15 +9,14 @@ module Spree
|
|
9
9
|
preference :amount_max, :decimal, default: 1000.00
|
10
10
|
preference :operator_max, :string, default: '<'
|
11
11
|
|
12
|
-
|
13
12
|
OPERATORS_MIN = ['gt', 'gte']
|
14
|
-
OPERATORS_MAX = ['lt','lte']
|
13
|
+
OPERATORS_MAX = ['lt', 'lte']
|
15
14
|
|
16
15
|
def applicable?(promotable)
|
17
16
|
promotable.is_a?(Spree::Order)
|
18
17
|
end
|
19
18
|
|
20
|
-
def eligible?(order,
|
19
|
+
def eligible?(order, _options = {})
|
21
20
|
item_total = order.item_total
|
22
21
|
|
23
22
|
lower_limit_condition = item_total.send(preferred_operator_min == 'gte' ? :>= : :>, BigDecimal.new(preferred_amount_min.to_s))
|
@@ -30,6 +29,7 @@ module Spree
|
|
30
29
|
end
|
31
30
|
|
32
31
|
private
|
32
|
+
|
33
33
|
def formatted_amount_min
|
34
34
|
Spree::Money.new(preferred_amount_min).to_s
|
35
35
|
end
|
@@ -38,7 +38,6 @@ module Spree
|
|
38
38
|
Spree::Money.new(preferred_amount_max).to_s
|
39
39
|
end
|
40
40
|
|
41
|
-
|
42
41
|
def ineligible_message_max
|
43
42
|
if preferred_operator_max == 'gte'
|
44
43
|
eligibility_error_message(:item_total_more_than_or_equal, amount: formatted_amount_max)
|
@@ -54,7 +53,6 @@ module Spree
|
|
54
53
|
eligibility_error_message(:item_total_less_than_or_equal, amount: formatted_amount_min)
|
55
54
|
end
|
56
55
|
end
|
57
|
-
|
58
56
|
end
|
59
57
|
end
|
60
58
|
end
|