spree_core 2.4.10 → 3.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/app/assets/images/logo/spree_50.png +0 -0
- data/app/controllers/spree/base_controller.rb +1 -2
- data/app/helpers/spree/base_helper.rb +41 -131
- data/app/helpers/spree/products_helper.rb +1 -1
- data/app/models/concerns/spree/adjustment_source.rb +51 -15
- data/app/models/concerns/spree/calculated_adjustments.rb +1 -0
- data/app/models/concerns/spree/display_money.rb +32 -0
- data/app/models/concerns/spree/named_type.rb +1 -1
- data/app/models/concerns/spree/number_generator.rb +39 -0
- data/app/models/concerns/spree/user_reporting.rb +3 -8
- data/app/models/spree/address.rb +0 -2
- data/app/models/spree/adjustable/adjustments_updater.rb +70 -0
- data/app/models/spree/adjustable/promotion_accumulator.rb +75 -0
- data/app/models/spree/adjustment.rb +17 -26
- data/app/models/spree/app_configuration.rb +4 -33
- data/app/models/spree/base.rb +0 -3
- data/app/models/spree/calculator.rb +0 -5
- data/app/models/spree/classification.rb +1 -1
- data/app/models/spree/country.rb +10 -4
- data/app/models/spree/credit_card.rb +14 -15
- data/app/models/spree/customer_return.rb +18 -25
- data/app/models/spree/gateway/bogus.rb +0 -4
- data/app/models/spree/line_item.rb +2 -5
- data/app/models/spree/option_type.rb +2 -4
- data/app/models/spree/option_value.rb +0 -2
- data/app/models/spree/order.rb +74 -134
- data/app/models/spree/order/checkout.rb +1 -1
- data/app/models/spree/order_contents.rb +9 -8
- data/app/models/spree/order_updater.rb +8 -1
- data/app/models/spree/payment.rb +13 -23
- data/app/models/spree/payment/gateway_options.rb +86 -0
- data/app/models/spree/payment/processing.rb +8 -39
- data/app/models/spree/payment_method.rb +3 -6
- data/app/models/spree/price.rb +2 -6
- data/app/models/spree/product.rb +27 -16
- data/app/models/spree/product_property.rb +1 -5
- data/app/models/spree/promotion.rb +7 -15
- data/app/models/spree/promotion/actions/create_adjustment.rb +4 -45
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +8 -63
- data/app/models/spree/promotion/actions/create_line_items.rb +3 -12
- data/app/models/spree/promotion/actions/free_shipping.rb +4 -24
- data/app/models/spree/promotion/rules/option_value.rb +49 -0
- data/app/models/spree/promotion_action.rb +6 -0
- data/app/models/spree/promotion_handler/cart.rb +14 -18
- data/app/models/spree/promotion_handler/coupon.rb +1 -1
- data/app/models/spree/promotion_rule.rb +0 -1
- data/app/models/spree/property.rb +0 -2
- data/app/models/spree/refund.rb +0 -15
- data/app/models/spree/reimbursement.rb +4 -4
- data/app/models/spree/reimbursement_type/credit.rb +1 -1
- data/app/models/spree/reimbursement_type/original_payment.rb +1 -1
- data/app/models/spree/return_authorization.rb +4 -11
- data/app/models/spree/return_item.rb +16 -11
- data/app/models/spree/return_item/eligibility_validator/default.rb +2 -0
- data/app/models/spree/return_item/eligibility_validator/inventory_shipped.rb +16 -0
- data/app/models/spree/return_item/eligibility_validator/no_reimbursements.rb +16 -0
- data/app/models/spree/shipment.rb +20 -31
- data/app/models/spree/shipment_handler.rb +1 -1
- data/app/models/spree/shipping_method.rb +12 -13
- data/app/models/spree/state.rb +7 -0
- data/app/models/spree/state_change.rb +1 -6
- data/app/models/spree/stock/availability_validator.rb +9 -10
- data/app/models/spree/stock/coordinator.rb +1 -1
- data/app/models/spree/stock/estimator.rb +6 -6
- data/app/models/spree/stock/quantifier.rb +1 -1
- data/app/models/spree/stock_item.rb +1 -7
- data/app/models/spree/stock_location.rb +3 -1
- data/app/models/spree/stock_movement.rb +1 -8
- data/app/models/spree/stock_transfer.rb +11 -5
- data/app/models/spree/store.rb +2 -2
- data/app/models/spree/tax_rate.rb +30 -55
- data/app/models/spree/taxon.rb +8 -8
- data/app/models/spree/taxonomy.rb +8 -13
- data/app/models/spree/tracker.rb +1 -1
- data/app/models/spree/variant.rb +6 -15
- data/app/models/spree/zone.rb +43 -9
- data/config/initializers/user_class_extensions.rb +0 -12
- data/config/locales/en.yml +76 -85
- data/config/routes.rb +1 -1
- data/db/default/spree/countries.rb +23 -13
- data/db/default/spree/states.rb +24 -12
- data/db/default/spree/stores.rb +1 -1
- data/db/migrate/20120831092320_spree_one_two.rb +36 -36
- data/db/migrate/20120831092359_spree_promo_one_two.rb +1 -1
- data/db/migrate/20130211190146_create_spree_stock_items.rb +1 -1
- data/db/migrate/20130211191120_create_spree_stock_locations.rb +1 -1
- data/db/migrate/20130301162924_create_shipping_method_categories.rb +1 -1
- data/db/migrate/20130304162240_create_spree_shipping_rates.rb +1 -1
- data/db/migrate/20130305143310_create_stock_movements.rb +1 -1
- data/db/migrate/20130418125341_create_spree_stock_transfers.rb +1 -1
- data/db/migrate/20140205120320_create_spree_payment_capture_events.rb +1 -1
- data/db/migrate/20140309024355_create_spree_stores.rb +1 -1
- data/db/migrate/20140309033438_create_store_from_preferences.rb +0 -7
- data/db/migrate/20140625214618_create_spree_refunds.rb +1 -1
- data/db/migrate/20140702140656_create_spree_return_authorization_inventory_unit.rb +1 -1
- data/db/migrate/20140713140455_create_spree_return_authorization_reasons.rb +1 -1
- data/db/migrate/20140713140527_create_spree_refund_reasons.rb +1 -1
- data/db/migrate/20140715182625_create_spree_promotion_categories.rb +1 -1
- data/db/migrate/20140718133010_create_spree_customer_returns.rb +1 -1
- data/db/migrate/20140725131539_create_spree_reimbursements.rb +1 -1
- data/db/migrate/20140731150017_create_spree_reimbursement_types.rb +1 -1
- data/db/migrate/20140911173301_add_kind_to_zone.rb +11 -0
- data/db/migrate/20141215232040_remove_token_permissions_table.rb +6 -0
- data/db/migrate/20141215235502_remove_extra_products_slug_index.rb +5 -0
- data/db/migrate/20141217215630_update_product_slug_index.rb +6 -0
- data/db/migrate/20141218025915_rename_identifier_to_number_for_payment.rb +5 -0
- data/db/migrate/20150121022521_remove_environment_from_payment_method.rb +6 -0
- data/db/migrate/20150122145607_add_resellable_to_return_items.rb +5 -0
- data/db/migrate/20150122202432_add_code_to_spree_promotion_categories.rb +5 -0
- data/db/migrate/20150128032538_remove_environment_from_tracker.rb +6 -0
- data/db/migrate/20150128060325_remove_spree_configurations.rb +16 -0
- data/lib/generators/spree/dummy/templates/rails/test.rb +1 -1
- data/lib/generators/spree/install/templates/config/initializers/spree.rb +4 -0
- data/lib/spree/core.rb +2 -12
- data/lib/spree/core/controller_helpers/respond_with.rb +8 -18
- data/lib/spree/core/engine.rb +1 -7
- data/lib/spree/core/routes.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/money.rb +10 -10
- data/lib/spree/permitted_attributes.rb +4 -8
- data/lib/spree/testing_support/authorization_helpers.rb +3 -5
- data/lib/spree/testing_support/capybara_ext.rb +3 -3
- data/lib/spree/testing_support/common_rake.rb +2 -2
- data/lib/spree/testing_support/factories/order_factory.rb +3 -13
- data/lib/spree/testing_support/factories/payment_method_factory.rb +0 -3
- data/lib/spree/testing_support/factories/prototype_factory.rb +5 -0
- data/lib/spree/testing_support/factories/return_item_factory.rb +5 -1
- data/lib/spree/testing_support/factories/stock_location_factory.rb +3 -3
- data/lib/spree/testing_support/factories/tracker_factory.rb +0 -1
- data/lib/spree/testing_support/factories/user_factory.rb +1 -1
- data/lib/spree/testing_support/factories/zone_factory.rb +8 -0
- data/lib/tasks/core.rake +1 -1
- data/lib/tasks/email.rake +6 -3
- metadata +48 -35
- data/app/helpers/spree/checkout_helper.rb +0 -31
- data/app/helpers/spree/orders_helper.rb +0 -17
- data/app/helpers/spree/store_helper.rb +0 -16
- data/app/helpers/spree/taxons_helper.rb +0 -19
- data/app/models/concerns/spree/ransackable_attributes.rb +0 -19
- data/app/models/friendly_id/slug_decorator.rb +0 -3
- data/app/models/spree/billing_integration.rb +0 -21
- data/app/models/spree/configuration.rb +0 -5
- data/app/models/spree/item_adjustments.rb +0 -82
- data/app/models/spree/order_merger.rb +0 -65
- data/app/models/spree/order_populator.rb +0 -43
- data/app/models/spree/product_scope/scopes.rb +0 -47
- data/app/models/spree/variant/scopes.rb +0 -42
- data/db/migrate/20150515211137_fix_adjustment_order_id.rb +0 -70
- data/db/migrate/20150522181728_add_deleted_at_to_friendly_id_slugs.rb +0 -6
- data/db/migrate/20150707204155_enable_acts_as_paranoid_on_calculators.rb +0 -6
- data/lib/spree/core/controller_helpers/ssl.rb +0 -60
- data/lib/spree/core/permalinks.rb +0 -71
- data/lib/spree/testing_support/factories/configuration_factory.rb +0 -6
data/app/models/spree/address.rb
CHANGED
@@ -16,8 +16,6 @@ module Spree
|
|
16
16
|
alias_attribute :first_name, :firstname
|
17
17
|
alias_attribute :last_name, :lastname
|
18
18
|
|
19
|
-
self.whitelisted_ransackable_attributes = %w[firstname lastname]
|
20
|
-
|
21
19
|
def self.build_default
|
22
20
|
country = Spree::Country.find(Spree::Config[:default_country_id]) rescue Spree::Country.first
|
23
21
|
new(country: country)
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Spree
|
2
|
+
module Adjustable
|
3
|
+
class AdjustmentsUpdater
|
4
|
+
def self.update(adjustable)
|
5
|
+
new(adjustable).update
|
6
|
+
end
|
7
|
+
|
8
|
+
def initialize(adjustable)
|
9
|
+
@adjustable = adjustable
|
10
|
+
adjustable.reload if shipment? && persisted?
|
11
|
+
end
|
12
|
+
|
13
|
+
def update
|
14
|
+
return unless persisted?
|
15
|
+
update_promo_adjustments
|
16
|
+
update_tax_adjustments
|
17
|
+
persist_totals
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :adjustable
|
23
|
+
delegate :adjustments, :persisted?, to: :adjustable
|
24
|
+
|
25
|
+
def update_promo_adjustments
|
26
|
+
promo_adjustments = adjustments.competing_promos.reload.map { |a| a.update!(adjustable) }
|
27
|
+
promos_total = promo_adjustments.compact.sum
|
28
|
+
choose_best_promo_adjustment unless promos_total == 0
|
29
|
+
@promo_total = best_promo_adjustment.try(:amount).to_f
|
30
|
+
end
|
31
|
+
|
32
|
+
def update_tax_adjustments
|
33
|
+
tax = (adjustable.try(:all_adjustments) || adjustable.adjustments).tax
|
34
|
+
@included_tax_total = tax.is_included.reload.map(&:update!).compact.sum
|
35
|
+
@additional_tax_total = tax.additional.reload.map(&:update!).compact.sum
|
36
|
+
end
|
37
|
+
|
38
|
+
def persist_totals
|
39
|
+
adjustable.update_columns(
|
40
|
+
promo_total: @promo_total,
|
41
|
+
included_tax_total: @included_tax_total,
|
42
|
+
additional_tax_total: @additional_tax_total,
|
43
|
+
adjustment_total: @promo_total + @additional_tax_total,
|
44
|
+
updated_at: Time.now
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
def shipment?
|
49
|
+
adjustable.is_a?(Shipment)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Picks one (and only one) competing discount to be eligible for
|
53
|
+
# this order. This adjustment provides the most discount, and if
|
54
|
+
# two adjustments have the same amount, then it will pick the
|
55
|
+
# latest one.
|
56
|
+
def choose_best_promo_adjustment
|
57
|
+
if best_promo_adjustment
|
58
|
+
other_promotions = adjustments.competing_promos.where.not(id: best_promo_adjustment.id)
|
59
|
+
other_promotions.update_all(eligible: false)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def best_promo_adjustment
|
64
|
+
@best_promo_adjustment ||= begin
|
65
|
+
adjustments.competing_promos.eligible.reorder("amount ASC, created_at DESC, id DESC").first
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Spree
|
2
|
+
module Adjustable
|
3
|
+
class PromotionAccumulator
|
4
|
+
attr_reader :adjustments, :sources, :promotions
|
5
|
+
|
6
|
+
# Adds accumulator as an attribute of adjustable to
|
7
|
+
# avoid changing number of passed arguments to
|
8
|
+
# adjustment#update! and concequential methods
|
9
|
+
def self.add_to(adjustable)
|
10
|
+
class << adjustable
|
11
|
+
attr_accessor :promotion_accumulator
|
12
|
+
end
|
13
|
+
|
14
|
+
adjustable.promotion_accumulator = new(adjustable)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(adjustable)
|
18
|
+
@adjustable = adjustable
|
19
|
+
@adjustments, @sources, @promotions = [], [], []
|
20
|
+
all_adjustments.each { |a| add_adjustment(a) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_adjustment(adjustment, opts = {})
|
24
|
+
return unless adjustment.promotion?
|
25
|
+
source = opts[:source] || adjustment.source
|
26
|
+
promotion = opts[:promotion] || source.promotion
|
27
|
+
|
28
|
+
add(adjustments, adjustment, adjustment.id)
|
29
|
+
add(sources, source, adjustment.source_id)
|
30
|
+
add(promotions, promotion, source.promotion_id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def promotions_adjustments(promotion_id, adjustments = adjustments)
|
34
|
+
where(sources, promotion_id: promotion_id).map do |source|
|
35
|
+
where(adjustments, source_id: source.id)
|
36
|
+
end.flatten
|
37
|
+
end
|
38
|
+
|
39
|
+
def promo_total(*args)
|
40
|
+
promotions_adjustments(*args).map(&:amount).reduce(0, &:+)
|
41
|
+
end
|
42
|
+
|
43
|
+
def total_with_promotion(promotion_id)
|
44
|
+
amount + ship_total + promo_total(promotion_id)
|
45
|
+
end
|
46
|
+
|
47
|
+
def item_total_with_promotion(promotion_id)
|
48
|
+
amount + promo_total(promotion_id, item_adjustments)
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
attr_reader :adjustable
|
54
|
+
delegate :order, to: :adjustable
|
55
|
+
delegate :amount, :ship_total, to: :order
|
56
|
+
|
57
|
+
def all_adjustments
|
58
|
+
order.all_adjustments.promotion.includes(source: [:promotion]).where.
|
59
|
+
not("adjustable_id = ? AND adjustable_type = ?", adjustable.id, adjustable.class.to_s)
|
60
|
+
end
|
61
|
+
|
62
|
+
def add(array, object, id)
|
63
|
+
array << object if array.none? { |a| a.id == id }
|
64
|
+
end
|
65
|
+
|
66
|
+
def item_adjustments
|
67
|
+
adjustments.select { |a| a.adjustable_type != 'Spree::Shipment' }
|
68
|
+
end
|
69
|
+
|
70
|
+
def where(array, opts = {})
|
71
|
+
array.select { |a| opts.all? { |k, v| a.respond_to?(k) && a.send(k) == v } }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -24,7 +24,7 @@ module Spree
|
|
24
24
|
class Adjustment < Spree::Base
|
25
25
|
belongs_to :adjustable, polymorphic: true, touch: true
|
26
26
|
belongs_to :source, polymorphic: true
|
27
|
-
belongs_to :order, class_name:
|
27
|
+
belongs_to :order, class_name: "Spree::Order"
|
28
28
|
|
29
29
|
validates :adjustable, presence: true
|
30
30
|
validates :order, presence: true
|
@@ -44,6 +44,10 @@ module Spree
|
|
44
44
|
after_create :update_adjustable_adjustment_total
|
45
45
|
after_destroy :update_adjustable_adjustment_total
|
46
46
|
|
47
|
+
class_attribute :competing_promos_source_types
|
48
|
+
|
49
|
+
self.competing_promos_source_types = ['Spree::PromotionAction']
|
50
|
+
|
47
51
|
scope :open, -> { where(state: 'open') }
|
48
52
|
scope :closed, -> { where(state: 'closed') }
|
49
53
|
scope :tax, -> { where(source_type: 'Spree::TaxRate') }
|
@@ -62,6 +66,10 @@ module Spree
|
|
62
66
|
scope :return_authorization, -> { where(source_type: "Spree::ReturnAuthorization") }
|
63
67
|
scope :is_included, -> { where(included: true) }
|
64
68
|
scope :additional, -> { where(included: false) }
|
69
|
+
scope :competing_promos, -> { where(source_type: competing_promos_source_types) }
|
70
|
+
|
71
|
+
extend DisplayMoney
|
72
|
+
money_methods :amount
|
65
73
|
|
66
74
|
def closed?
|
67
75
|
state == "closed"
|
@@ -71,36 +79,19 @@ module Spree
|
|
71
79
|
adjustable ? adjustable.currency : Spree::Config[:currency]
|
72
80
|
end
|
73
81
|
|
74
|
-
def display_amount
|
75
|
-
Spree::Money.new(amount, { currency: currency })
|
76
|
-
end
|
77
|
-
|
78
82
|
def promotion?
|
79
|
-
|
83
|
+
source_type == 'Spree::PromotionAction'
|
80
84
|
end
|
81
85
|
|
82
|
-
# Recalculate amount given a target e.g. Order, Shipment, LineItem
|
83
|
-
#
|
84
86
|
# Passing a target here would always be recommended as it would avoid
|
85
87
|
# hitting the database again and would ensure you're compute values over
|
86
88
|
# the specific object amount passed here.
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
return amount if closed?
|
94
|
-
if source.present?
|
95
|
-
amount = source.compute_amount(target || adjustable)
|
96
|
-
self.update_columns(
|
97
|
-
amount: amount,
|
98
|
-
updated_at: Time.now,
|
99
|
-
)
|
100
|
-
if promotion?
|
101
|
-
self.update_column(:eligible, source.promotion.eligible?(adjustable))
|
102
|
-
end
|
103
|
-
end
|
89
|
+
def update!(target = adjustable)
|
90
|
+
return amount if closed? || source.blank?
|
91
|
+
amount = source.compute_amount(target)
|
92
|
+
attributes = { amount: amount, updated_at: Time.now }
|
93
|
+
attributes[:eligible] = source.promotion.eligible?(target) if promotion?
|
94
|
+
update_columns(attributes)
|
104
95
|
amount
|
105
96
|
end
|
106
97
|
|
@@ -108,7 +99,7 @@ module Spree
|
|
108
99
|
|
109
100
|
def update_adjustable_adjustment_total
|
110
101
|
# Cause adjustable's total to be recalculated
|
111
|
-
|
102
|
+
Adjustable::AdjustmentsUpdater.update(adjustable)
|
112
103
|
end
|
113
104
|
|
114
105
|
end
|
@@ -25,31 +25,20 @@ module Spree
|
|
25
25
|
preference :admin_products_per_page, :integer, default: 10
|
26
26
|
preference :allow_checkout_on_gateway_error, :boolean, default: false
|
27
27
|
preference :allow_guest_checkout, :boolean, default: true
|
28
|
-
preference :allow_return_item_amount_editing, :boolean, default: false # Determines whether an admin is allowed to change a return item's pre-calculated amount
|
29
|
-
preference :allow_ssl_in_development_and_test, :boolean, default: false
|
30
|
-
preference :allow_ssl_in_production, :boolean, default: true
|
31
|
-
preference :allow_ssl_in_staging, :boolean, default: true
|
32
|
-
preference :alternative_billing_phone, :boolean, default: false # Request extra phone for bill addr
|
33
28
|
preference :alternative_shipping_phone, :boolean, default: false # Request extra phone for ship addr
|
34
29
|
preference :always_include_confirm_step, :boolean, default: false # Ensures confirmation step is always in checkout_progress bar, but does not force a confirm step if your payment methods do not support it.
|
35
30
|
preference :always_put_site_name_in_title, :boolean, default: true
|
36
31
|
preference :auto_capture, :boolean, default: false # automatically capture the credit card (as opposed to just authorize and capture later)
|
37
32
|
preference :auto_capture_on_dispatch, :boolean, default: false # Captures payment for each shipment in Shipment#after_ship callback, and makes Shipment.ready when payment authorized.
|
38
33
|
preference :binary_inventory_cache, :boolean, default: false # only invalidate product cache when a stock item changes whether it is in_stock
|
39
|
-
preference :check_for_spree_alerts, :boolean, default:
|
34
|
+
preference :check_for_spree_alerts, :boolean, default: true
|
40
35
|
preference :checkout_zone, :string, default: nil # replace with the name of a zone if you would like to limit the countries
|
41
36
|
preference :company, :boolean, default: false # Request company field for billing and shipping addr
|
42
37
|
preference :currency, :string, default: "USD"
|
43
|
-
preference :currency_decimal_mark, :string, default: "."
|
44
|
-
preference :currency_symbol_position, :string, default: "before"
|
45
|
-
preference :currency_sign_before_symbol, :boolean, default: true
|
46
|
-
preference :currency_thousands_separator, :string, default: ","
|
47
|
-
preference :display_currency, :boolean, default: false
|
48
38
|
preference :default_country_id, :integer
|
49
39
|
preference :dismissed_spree_alerts, :string, default: ''
|
50
40
|
preference :expedited_exchanges, :boolean, default: false # NOTE this requires payment profiles to be supported on your gateway of choice as well as a delayed job handler to be configured with activejob. kicks off an exchange shipment upon return authorization save. charge customer if they do not return items within timely manner.
|
51
41
|
preference :expedited_exchanges_days_window, :integer, default: 14 # the amount of days the customer has to return their item after the expedited exchange is shipped in order to avoid being charged
|
52
|
-
preference :hide_cents, :boolean, default: false
|
53
42
|
preference :last_check_for_spree_alerts, :string, default: nil
|
54
43
|
preference :layout, :string, default: 'spree/layouts/spree_application'
|
55
44
|
preference :logo, :string, default: 'logo/spree_50.png'
|
@@ -59,7 +48,6 @@ module Spree
|
|
59
48
|
preference :products_per_page, :integer, default: 12
|
60
49
|
preference :promotions_per_page, :integer, default: 15
|
61
50
|
preference :customer_returns_per_page, :integer, default: 15
|
62
|
-
preference :redirect_https_to_http, :boolean, :default => false
|
63
51
|
preference :require_master_price, :boolean, default: true
|
64
52
|
preference :restock_inventory, :boolean, default: true # Determines if a return item is restocked automatically once it has been received
|
65
53
|
preference :return_eligibility_number_of_days, :integer, default: 365
|
@@ -67,13 +55,13 @@ module Spree
|
|
67
55
|
preference :show_only_complete_orders_by_default, :boolean, default: true
|
68
56
|
preference :show_variant_full_price, :boolean, default: false #Displays variant full price or difference with product price. Default false to be compatible with older behavior
|
69
57
|
preference :show_products_without_price, :boolean, default: false
|
70
|
-
preference :show_raw_product_description, :boolean, :
|
58
|
+
preference :show_raw_product_description, :boolean, default: false
|
71
59
|
preference :tax_using_ship_address, :boolean, default: true
|
72
60
|
preference :track_inventory_levels, :boolean, default: true # Determines whether to track on_hand values for variants / products.
|
73
61
|
|
74
62
|
# Default mail headers settings
|
75
|
-
preference :send_core_emails, :boolean, :
|
76
|
-
preference :mails_from, :string, :
|
63
|
+
preference :send_core_emails, :boolean, default: true
|
64
|
+
preference :mails_from, :string, default: 'spree@example.com'
|
77
65
|
|
78
66
|
# searcher_class allows spree extension writers to provide their own Search class
|
79
67
|
def searcher_class
|
@@ -83,22 +71,5 @@ module Spree
|
|
83
71
|
def searcher_class=(sclass)
|
84
72
|
@searcher_class = sclass
|
85
73
|
end
|
86
|
-
|
87
|
-
# all the following can be deprecated when store prefs are no longer supported
|
88
|
-
DEPRECATED_STORE_PREFERENCES = {
|
89
|
-
site_name: :name,
|
90
|
-
site_url: :url,
|
91
|
-
default_meta_description: :meta_description,
|
92
|
-
default_meta_keywords: :meta_keywords,
|
93
|
-
default_seo_title: :seo_title,
|
94
|
-
}
|
95
|
-
|
96
|
-
DEPRECATED_STORE_PREFERENCES.each do |old_preference_name, store_method|
|
97
|
-
# support all the old preference methods with a warning
|
98
|
-
define_method "preferred_#{old_preference_name}" do
|
99
|
-
ActiveSupport::Deprecation.warn("#{old_preference_name} is no longer supported on Spree::Config, please access it through #{store_method} on Spree::Store")
|
100
|
-
Store.default.send(store_method)
|
101
|
-
end
|
102
|
-
end
|
103
74
|
end
|
104
75
|
end
|
data/app/models/spree/base.rb
CHANGED
@@ -1,9 +1,6 @@
|
|
1
1
|
class Spree::Base < ActiveRecord::Base
|
2
2
|
include Spree::Preferences::Preferable
|
3
3
|
serialize :preferences, Hash
|
4
|
-
|
5
|
-
include Spree::RansackableAttributes
|
6
|
-
|
7
4
|
after_initialize do
|
8
5
|
self.preferences = default_preferences.merge(preferences) if has_attribute?(:preferences)
|
9
6
|
end
|
@@ -1,10 +1,5 @@
|
|
1
1
|
module Spree
|
2
2
|
class Calculator < Spree::Base
|
3
|
-
# Conditional check for backwards compatibilty since acts as paranoid was added late https://github.com/spree/spree/issues/5858
|
4
|
-
if connection.table_exists?(:spree_calculators) && connection.column_exists?(:spree_calculators, :deleted_at)
|
5
|
-
acts_as_paranoid
|
6
|
-
end
|
7
|
-
|
8
3
|
belongs_to :calculable, polymorphic: true
|
9
4
|
|
10
5
|
# This method calls a compute_<computable> method. must be overriden in concrete calculator.
|
@@ -2,7 +2,7 @@ module Spree
|
|
2
2
|
class Classification < Spree::Base
|
3
3
|
self.table_name = 'spree_products_taxons'
|
4
4
|
acts_as_list scope: :taxon
|
5
|
-
belongs_to :product, class_name: "Spree::Product", inverse_of: :classifications
|
5
|
+
belongs_to :product, class_name: "Spree::Product", inverse_of: :classifications
|
6
6
|
belongs_to :taxon, class_name: "Spree::Taxon", inverse_of: :classifications, touch: true
|
7
7
|
|
8
8
|
# For #3494
|
data/app/models/spree/country.rb
CHANGED
@@ -3,12 +3,18 @@ module Spree
|
|
3
3
|
has_many :states, -> { order('name ASC') }, dependent: :destroy
|
4
4
|
has_many :addresses, dependent: :nullify
|
5
5
|
|
6
|
+
has_many :zone_members,
|
7
|
+
-> { where(zoneable_type: 'Spree::Country') },
|
8
|
+
class_name: 'Spree::ZoneMember',
|
9
|
+
foreign_key: :zoneable_id
|
10
|
+
|
11
|
+
has_many :zones, through: :zone_members, class_name: 'Spree::Zone'
|
12
|
+
|
6
13
|
validates :name, :iso_name, presence: true
|
7
14
|
|
8
|
-
def self.
|
9
|
-
|
10
|
-
|
11
|
-
states_required
|
15
|
+
def self.default
|
16
|
+
country_id = Spree::Config[:default_country_id]
|
17
|
+
country_id.present? ? find(country_id) : find_by!(iso: 'US')
|
12
18
|
end
|
13
19
|
|
14
20
|
def <=>(other)
|
@@ -18,8 +18,6 @@ module Spree
|
|
18
18
|
validates :name, presence: true, if: :require_card_numbers?, on: :create
|
19
19
|
validates :verification_value, presence: true, if: :require_card_numbers?, on: :create, unless: :imported
|
20
20
|
|
21
|
-
validate :expiry_not_in_the_past
|
22
|
-
|
23
21
|
scope :with_payment_profile, -> { where('gateway_customer_profile_id IS NOT NULL') }
|
24
22
|
scope :default, -> { where(default: true) }
|
25
23
|
|
@@ -35,6 +33,20 @@ module Spree
|
|
35
33
|
jcb: /^(?:2131|1800|35\d{3})\d{11}$/
|
36
34
|
}
|
37
35
|
|
36
|
+
# As of rails 4.2 string columns always return strings, perhaps we should
|
37
|
+
# change these to integer columns on db level
|
38
|
+
def month
|
39
|
+
if type_casted = super
|
40
|
+
type_casted.to_i
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def year
|
45
|
+
if type_casted = super
|
46
|
+
type_casted.to_i
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
38
50
|
def expiry=(expiry)
|
39
51
|
return unless expiry.present?
|
40
52
|
|
@@ -135,19 +147,6 @@ module Spree
|
|
135
147
|
|
136
148
|
private
|
137
149
|
|
138
|
-
def expiry_not_in_the_past
|
139
|
-
if year.present? && month.present?
|
140
|
-
if month.to_i < 1 || month.to_i > 12
|
141
|
-
errors.add(:base, :expiry_invalid)
|
142
|
-
else
|
143
|
-
current = Time.current
|
144
|
-
if year.to_i < current.year or (year.to_i == current.year and month.to_i < current.month)
|
145
|
-
errors.add(:base, :card_expired)
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
150
|
def require_card_numbers?
|
152
151
|
!self.encrypted_data.present? && !self.has_payment_profile?
|
153
152
|
end
|
@@ -2,31 +2,24 @@ module Spree
|
|
2
2
|
class CustomerReturn < Spree::Base
|
3
3
|
belongs_to :stock_location
|
4
4
|
|
5
|
-
has_many :reimbursements, inverse_of: :customer_return
|
6
|
-
has_many :return_authorizations, through: :return_items
|
7
5
|
has_many :return_items, inverse_of: :customer_return
|
6
|
+
has_many :return_authorizations, through: :return_items
|
7
|
+
has_many :reimbursements, inverse_of: :customer_return
|
8
8
|
|
9
9
|
after_create :process_return!
|
10
10
|
before_create :generate_number
|
11
11
|
|
12
12
|
validates :return_items, presence: true
|
13
13
|
validates :stock_location, presence: true
|
14
|
-
|
15
|
-
validate :must_have_return_authorization, on: :create
|
16
14
|
validate :return_items_belong_to_same_order
|
17
15
|
|
18
16
|
accepts_nested_attributes_for :return_items
|
19
17
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
18
|
+
extend DisplayMoney
|
19
|
+
money_methods pre_tax_total: { currency: Spree::Config[:currency] }
|
23
20
|
|
24
|
-
def
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
def display_pre_tax_total
|
29
|
-
Spree::Money.new(pre_tax_total, { currency: Spree::Config[:currency] })
|
21
|
+
def pre_tax_total
|
22
|
+
return_items.sum(:pre_tax_amount)
|
30
23
|
end
|
31
24
|
|
32
25
|
# Temporarily tie a customer_return to one order
|
@@ -39,21 +32,15 @@ module Spree
|
|
39
32
|
order.try(:id)
|
40
33
|
end
|
41
34
|
|
42
|
-
def
|
43
|
-
return_items.
|
35
|
+
def fully_reimbursed?
|
36
|
+
completely_decided? && return_items.accepted.includes(:reimbursement).all? { |return_item| return_item.reimbursement.try(:reimbursed?) }
|
44
37
|
end
|
45
38
|
|
46
|
-
|
47
|
-
|
48
|
-
def inventory_units
|
49
|
-
return_items.flat_map(&:inventory_unit)
|
39
|
+
def completely_decided?
|
40
|
+
!return_items.undecided.exists?
|
50
41
|
end
|
51
42
|
|
52
|
-
|
53
|
-
if item = return_items.find { |ri| ri.return_authorization.blank? }
|
54
|
-
errors.add(:base, Spree.t(:missing_return_authorization, item_name: item.inventory_unit.variant.name))
|
55
|
-
end
|
56
|
-
end
|
43
|
+
private
|
57
44
|
|
58
45
|
def generate_number
|
59
46
|
self.number ||= loop do
|
@@ -68,9 +55,15 @@ module Spree
|
|
68
55
|
end
|
69
56
|
|
70
57
|
def return_items_belong_to_same_order
|
71
|
-
if return_items.select
|
58
|
+
if return_items.select{ |return_item| return_item.inventory_unit.order_id != order_id }.any?
|
72
59
|
errors.add(:base, Spree.t(:return_items_cannot_be_associated_with_multiple_orders))
|
73
60
|
end
|
74
61
|
end
|
62
|
+
|
63
|
+
def inventory_units
|
64
|
+
return_items.flat_map(&:inventory_unit)
|
65
|
+
end
|
66
|
+
|
75
67
|
end
|
76
68
|
end
|
69
|
+
|