spree_core 3.3.6 → 3.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|