spree_core 2.1.3 → 2.1.4
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/admin/images_helper.rb +1 -1
- data/app/helpers/spree/base_helper.rb +5 -2
- data/app/models/spree/address.rb +9 -1
- data/app/models/spree/adjustment.rb +2 -2
- data/app/models/spree/calculator/default_tax.rb +5 -1
- data/app/models/spree/credit_card.rb +2 -0
- data/app/models/spree/gateway.rb +1 -1
- data/app/models/spree/inventory_unit.rb +5 -4
- data/app/models/spree/legacy_user.rb +2 -11
- data/app/models/spree/line_item.rb +2 -3
- data/app/models/spree/log_entry.rb +4 -0
- data/app/models/spree/option_type.rb +6 -0
- data/app/models/spree/option_value.rb +12 -1
- data/app/models/spree/order.rb +34 -16
- data/app/models/spree/order/checkout.rb +4 -0
- data/app/models/spree/order_inventory.rb +1 -1
- data/app/models/spree/payment.rb +10 -2
- data/app/models/spree/payment/processing.rb +5 -4
- data/app/models/spree/payment_method.rb +2 -0
- data/app/models/spree/price.rb +5 -0
- data/app/models/spree/product.rb +6 -5
- data/app/models/spree/product/scopes.rb +12 -6
- data/app/models/spree/product_property.rb +1 -1
- data/app/models/spree/promotion.rb +1 -8
- data/app/models/spree/promotion/rules/user_logged_in.rb +1 -3
- data/app/models/spree/property.rb +8 -0
- data/app/models/spree/shipment.rb +9 -14
- data/app/models/spree/shipping_method.rb +3 -2
- data/app/models/spree/shipping_rate.rb +7 -9
- data/app/models/spree/stock/estimator.rb +21 -14
- data/app/models/spree/stock/package.rb +1 -1
- data/app/models/spree/stock/packer.rb +1 -1
- data/app/models/spree/stock/quantifier.rb +11 -2
- data/app/models/spree/stock_item.rb +2 -2
- data/app/models/spree/stock_location.rb +8 -0
- data/app/models/spree/stock_movement.rb +3 -1
- data/app/models/spree/taxon.rb +2 -2
- data/app/models/spree/variant.rb +19 -4
- data/app/models/spree/zone.rb +1 -1
- data/app/views/spree/shared/_routes.html.erb +1 -1
- data/config/locales/en.yml +15 -1
- data/db/default/spree/countries.rb +7 -7
- data/db/migrate/20130417120034_add_index_to_source_columns_on_adjustments.rb +5 -0
- data/db/migrate/20130802022321_migrate_tax_categories_to_line_items.rb +5 -2
- data/db/migrate/20131026154747_add_track_inventory_to_variant.rb +5 -0
- data/db/migrate/20131120234456_add_updated_at_to_variants.rb +5 -0
- data/db/migrate/20131211192741_unique_shipping_method_categories.rb +24 -0
- data/db/migrate/20140120160805_add_index_to_variant_id_and_currency_on_prices.rb +5 -0
- data/lib/generators/spree/dummy/dummy_generator.rb +14 -3
- data/lib/generators/spree/dummy/templates/rails/database.yml +10 -0
- data/lib/spree/core.rb +3 -0
- data/lib/spree/core/controller_helpers/order.rb +4 -1
- data/lib/spree/core/controller_helpers/ssl.rb +5 -7
- data/lib/spree/core/controller_helpers/strong_parameters.rb +6 -0
- data/lib/spree/core/delegate_belongs_to.rb +16 -10
- data/lib/spree/core/engine.rb +11 -2
- data/lib/spree/core/mail_method.rb +27 -0
- data/lib/spree/core/mail_settings.rb +33 -38
- data/lib/spree/core/permalinks.rb +5 -1
- data/lib/spree/core/s3_support.rb +1 -1
- data/lib/spree/core/user_address.rb +30 -0
- data/lib/spree/core/validators/email.rb +9 -3
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/i18n.rb +1 -0
- data/lib/spree/migrations.rb +55 -0
- data/lib/spree/money.rb +171 -1
- data/lib/spree/permitted_attributes.rb +6 -6
- data/lib/spree/testing_support/capybara_ext.rb +6 -5
- data/lib/spree/testing_support/controller_requests.rb +20 -4
- data/lib/spree/testing_support/factories/product_factory.rb +4 -0
- data/lib/spree/testing_support/factories/variant_factory.rb +15 -0
- metadata +158 -164
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4097b8c35f0d4c860dbaeff13518f90e790880e
|
4
|
+
data.tar.gz: 67e8f16ef1ebf41b7fd672a31d17ad3736439856
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 83ed87a684e91dac0ce56b9d1836d0d4e1cee96cb6dd388e1d68dba07fa9d9140cabf3f77f7c50298e42ae026e1827a668aa8355256965044c0bc097157a69db
|
7
|
+
data.tar.gz: a6bbe1a58e61240068e92db9d3f8a2b577b939e363ff286c7ba95f0738884bc64c1f54339b4163aa51053bec6e25323f349c64fb42a08b93c852d9a19ca99901
|
@@ -34,7 +34,7 @@ module Spree
|
|
34
34
|
v.options_text
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
37
|
+
def meta_data
|
38
38
|
object = instance_variable_get('@'+controller_name.singularize)
|
39
39
|
meta = {}
|
40
40
|
|
@@ -51,8 +51,11 @@ module Spree
|
|
51
51
|
keywords: Spree::Config[:default_meta_keywords],
|
52
52
|
description: Spree::Config[:default_meta_description]
|
53
53
|
})
|
54
|
+
meta
|
55
|
+
end
|
54
56
|
|
55
|
-
|
57
|
+
def meta_data_tags
|
58
|
+
meta_data.map do |name, content|
|
56
59
|
tag('meta', name: name, content: content)
|
57
60
|
end.join("\n")
|
58
61
|
end
|
data/app/models/spree/address.rb
CHANGED
@@ -14,7 +14,7 @@ module Spree
|
|
14
14
|
alias_attribute :first_name, :firstname
|
15
15
|
alias_attribute :last_name, :lastname
|
16
16
|
|
17
|
-
def self.
|
17
|
+
def self.build_default
|
18
18
|
country = Spree::Country.find(Spree::Config[:default_country_id]) rescue Spree::Country.first
|
19
19
|
new(country: country)
|
20
20
|
end
|
@@ -24,6 +24,14 @@ module Spree
|
|
24
24
|
# new_record? || (shipments.empty? && checkouts.empty?)
|
25
25
|
# end
|
26
26
|
|
27
|
+
def self.default(user = nil, kind = "bill")
|
28
|
+
if user
|
29
|
+
user.send(:"#{kind}_address") || build_default
|
30
|
+
else
|
31
|
+
build_default
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
27
35
|
def full_name
|
28
36
|
"#{firstname} #{lastname}".strip
|
29
37
|
end
|
@@ -54,8 +54,8 @@ module Spree
|
|
54
54
|
scope :shipping, -> { where(originator_type: 'Spree::ShippingMethod') }
|
55
55
|
scope :optional, -> { where(mandatory: false) }
|
56
56
|
scope :eligible, -> { where(eligible: true) }
|
57
|
-
scope :charge, -> { where(
|
58
|
-
scope :credit, -> { where(
|
57
|
+
scope :charge, -> { where("#{quoted_table_name}.amount >= 0") }
|
58
|
+
scope :credit, -> { where("#{quoted_table_name}.amount < 0") }
|
59
59
|
scope :promotion, -> { where(originator_type: 'Spree::PromotionAction') }
|
60
60
|
scope :manual, -> { where(originator_type: nil) }
|
61
61
|
scope :return_authorization, -> { where(source_type: "Spree::ReturnAuthorization") }
|
@@ -28,7 +28,11 @@ module Spree
|
|
28
28
|
end
|
29
29
|
|
30
30
|
line_items_total = matched_line_items.sum(&:total)
|
31
|
-
|
31
|
+
if rate.included_in_price
|
32
|
+
deduced_total_by_rate(line_items_total, rate)
|
33
|
+
else
|
34
|
+
round_to_two_places(line_items_total * rate.amount)
|
35
|
+
end
|
32
36
|
end
|
33
37
|
|
34
38
|
def compute_line_item(line_item)
|
data/app/models/spree/gateway.rb
CHANGED
@@ -2,16 +2,17 @@ module Spree
|
|
2
2
|
class InventoryUnit < ActiveRecord::Base
|
3
3
|
belongs_to :variant, class_name: "Spree::Variant"
|
4
4
|
belongs_to :order, class_name: "Spree::Order"
|
5
|
-
belongs_to :shipment, class_name: "Spree::Shipment"
|
5
|
+
belongs_to :shipment, class_name: "Spree::Shipment", touch: true
|
6
6
|
belongs_to :return_authorization, class_name: "Spree::ReturnAuthorization"
|
7
7
|
|
8
8
|
scope :backordered, -> { where state: 'backordered' }
|
9
9
|
scope :shipped, -> { where state: 'shipped' }
|
10
10
|
scope :backordered_per_variant, ->(stock_item) do
|
11
|
-
includes(:shipment)
|
11
|
+
includes(:shipment, :order)
|
12
12
|
.where("spree_shipments.state != 'canceled'").references(:shipment)
|
13
13
|
.where(variant_id: stock_item.variant_id)
|
14
|
-
.
|
14
|
+
.where('spree_orders.completed_at is not null')
|
15
|
+
.backordered.order("spree_orders.completed_at ASC")
|
15
16
|
end
|
16
17
|
|
17
18
|
# state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
|
@@ -34,7 +35,7 @@ module Spree
|
|
34
35
|
# lead to issues once users tried to modify the objects returned. That's due
|
35
36
|
# to ActiveRecord `joins(shipment: :stock_location)` only return readonly
|
36
37
|
# objects
|
37
|
-
#
|
38
|
+
#
|
38
39
|
# Returns an array of backordered inventory units as per a given stock item
|
39
40
|
def self.backordered_for_stock_item(stock_item)
|
40
41
|
backordered_per_variant(stock_item).select do |unit|
|
@@ -1,24 +1,15 @@
|
|
1
1
|
# Default implementation of User. This class is intended to be modified by extensions (ex. spree_auth_devise)
|
2
2
|
module Spree
|
3
3
|
class LegacyUser < ActiveRecord::Base
|
4
|
+
include Core::UserAddress
|
5
|
+
|
4
6
|
self.table_name = 'spree_users'
|
5
7
|
has_many :orders, foreign_key: :user_id
|
6
|
-
belongs_to :ship_address, class_name: 'Spree::Address'
|
7
|
-
belongs_to :bill_address, class_name: 'Spree::Address'
|
8
8
|
|
9
9
|
before_destroy :check_completed_orders
|
10
10
|
|
11
11
|
class DestroyWithOrdersError < StandardError; end
|
12
12
|
|
13
|
-
def anonymous?
|
14
|
-
false
|
15
|
-
end
|
16
|
-
|
17
|
-
# Creates an anonymous user
|
18
|
-
def self.anonymous!
|
19
|
-
create
|
20
|
-
end
|
21
|
-
|
22
13
|
def has_spree_role?(role)
|
23
14
|
true
|
24
15
|
end
|
@@ -20,12 +20,11 @@ module Spree
|
|
20
20
|
validates :price, numericality: true
|
21
21
|
validates_with Stock::AvailabilityValidator
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
after_save :update_inventory
|
25
24
|
after_save :update_order
|
26
25
|
after_destroy :update_order
|
27
26
|
|
28
|
-
delegate :name, :description, to: :variant
|
27
|
+
delegate :name, :description, :should_track_inventory?, to: :variant
|
29
28
|
|
30
29
|
attr_accessor :target_shipment
|
31
30
|
|
@@ -9,5 +9,11 @@ module Spree
|
|
9
9
|
default_scope -> { order("#{self.table_name}.position") }
|
10
10
|
|
11
11
|
accepts_nested_attributes_for :option_values, reject_if: lambda { |ov| ov[:name].blank? || ov[:presentation].blank? }, allow_destroy: true
|
12
|
+
|
13
|
+
after_touch :touch_all_products
|
14
|
+
|
15
|
+
def touch_all_products
|
16
|
+
products.find_each(&:touch)
|
17
|
+
end
|
12
18
|
end
|
13
19
|
end
|
@@ -1,9 +1,20 @@
|
|
1
1
|
module Spree
|
2
2
|
class OptionValue < ActiveRecord::Base
|
3
|
-
belongs_to :option_type
|
3
|
+
belongs_to :option_type, :class_name => 'Spree::OptionType', :touch => true
|
4
4
|
acts_as_list scope: :option_type
|
5
5
|
has_and_belongs_to_many :variants, join_table: 'spree_option_values_variants', class_name: "Spree::Variant"
|
6
6
|
|
7
7
|
validates :name, :presentation, presence: true
|
8
|
+
|
9
|
+
after_touch :touch_all_variants
|
10
|
+
|
11
|
+
def touch_all_variants
|
12
|
+
# This can cause a cascade of products to be updated
|
13
|
+
# To disable it in Rails 4.1, we can do this:
|
14
|
+
# https://github.com/rails/rails/pull/12772
|
15
|
+
# Spree::Product.no_touching do
|
16
|
+
variants.find_each(&:touch)
|
17
|
+
# end
|
18
|
+
end
|
8
19
|
end
|
9
20
|
end
|
data/app/models/spree/order.rb
CHANGED
@@ -92,7 +92,7 @@ module Spree
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def self.complete
|
95
|
-
where(
|
95
|
+
where.not(completed_at: nil)
|
96
96
|
end
|
97
97
|
|
98
98
|
def self.incomplete
|
@@ -161,11 +161,12 @@ module Spree
|
|
161
161
|
|
162
162
|
# If true, causes the confirmation step to happen during the checkout process
|
163
163
|
def confirmation_required?
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
164
|
+
Spree::Config[:always_include_confirm_step] ||
|
165
|
+
payments.valid.map(&:payment_method).compact.any?(&:payment_profiles_supported?) ||
|
166
|
+
# Little hacky fix for #4117
|
167
|
+
# If this wasn't here, order would transition to address state on confirm failure
|
168
|
+
# because there would be no valid payments any more.
|
169
|
+
state == 'confirm'
|
169
170
|
end
|
170
171
|
|
171
172
|
# Indicates the number of items in the order
|
@@ -350,7 +351,7 @@ module Spree
|
|
350
351
|
end
|
351
352
|
|
352
353
|
def available_payment_methods
|
353
|
-
@available_payment_methods ||= PaymentMethod.available(:front_end)
|
354
|
+
@available_payment_methods ||= (PaymentMethod.available(:front_end) + PaymentMethod.available(:both)).uniq
|
354
355
|
end
|
355
356
|
|
356
357
|
def pending_payments
|
@@ -447,12 +448,15 @@ module Spree
|
|
447
448
|
state = "#{name}_state"
|
448
449
|
if persisted?
|
449
450
|
old_state = self.send("#{state}_was")
|
450
|
-
self.
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
451
|
+
new_state = self.send(state)
|
452
|
+
unless old_state == new_state
|
453
|
+
self.state_changes.create(
|
454
|
+
previous_state: old_state,
|
455
|
+
next_state: new_state,
|
456
|
+
name: name,
|
457
|
+
user_id: self.user_id
|
458
|
+
)
|
459
|
+
end
|
456
460
|
end
|
457
461
|
end
|
458
462
|
|
@@ -506,10 +510,14 @@ module Spree
|
|
506
510
|
def ensure_updated_shipments
|
507
511
|
if shipments.any?
|
508
512
|
self.shipments.destroy_all
|
509
|
-
|
513
|
+
restart_checkout_flow
|
510
514
|
end
|
511
515
|
end
|
512
516
|
|
517
|
+
def restart_checkout_flow
|
518
|
+
self.update_column(:state, checkout_steps.first)
|
519
|
+
end
|
520
|
+
|
513
521
|
def refresh_shipment_rates
|
514
522
|
shipments.map &:refresh_rates
|
515
523
|
end
|
@@ -518,6 +526,15 @@ module Spree
|
|
518
526
|
(bill_address.empty? && ship_address.empty?) || bill_address.same_as?(ship_address)
|
519
527
|
end
|
520
528
|
|
529
|
+
def is_risky?
|
530
|
+
self.payments.where(%{
|
531
|
+
(avs_response IS NOT NULL and avs_response != 'D') or
|
532
|
+
(cvv_response_code IS NOT NULL and cvv_response_code != 'M') or
|
533
|
+
cvv_response_message IS NOT NULL or
|
534
|
+
state = 'failed'
|
535
|
+
}.squish!).uniq.count > 0
|
536
|
+
end
|
537
|
+
|
521
538
|
private
|
522
539
|
|
523
540
|
def link_by_email
|
@@ -526,7 +543,7 @@ module Spree
|
|
526
543
|
|
527
544
|
# Determine if email is required (we don't want validation errors before we hit the checkout)
|
528
545
|
def require_email
|
529
|
-
return true unless new_record? or
|
546
|
+
return true unless new_record? or ['cart', 'address'].include?(state)
|
530
547
|
end
|
531
548
|
|
532
549
|
def ensure_line_items_present
|
@@ -555,9 +572,10 @@ module Spree
|
|
555
572
|
|
556
573
|
def after_cancel
|
557
574
|
shipments.each { |shipment| shipment.cancel! }
|
575
|
+
payments.completed.each { |payment| payment.credit! }
|
558
576
|
|
559
577
|
send_cancel_email
|
560
|
-
self.payment_state
|
578
|
+
self.update_column(:payment_state, 'credit_owed') unless shipped?
|
561
579
|
end
|
562
580
|
|
563
581
|
def send_cancel_email
|
@@ -151,6 +151,10 @@ module Spree
|
|
151
151
|
@checkout_steps ||= {}
|
152
152
|
end
|
153
153
|
|
154
|
+
def self.checkout_step_names
|
155
|
+
self.checkout_steps.keys
|
156
|
+
end
|
157
|
+
|
154
158
|
def self.add_transition(options)
|
155
159
|
self.next_event_transitions << { options.delete(:from) => options.delete(:to) }.merge(options)
|
156
160
|
end
|
@@ -65,7 +65,7 @@ module Spree
|
|
65
65
|
end
|
66
66
|
|
67
67
|
def add_to_shipment(shipment, variant, quantity)
|
68
|
-
if
|
68
|
+
if variant.should_track_inventory?
|
69
69
|
on_hand, back_order = shipment.stock_location.fill_status(variant, quantity)
|
70
70
|
|
71
71
|
on_hand.times { shipment.set_up_inventory('on_hand', variant, order) }
|
data/app/models/spree/payment.rb
CHANGED
@@ -4,7 +4,7 @@ module Spree
|
|
4
4
|
|
5
5
|
IDENTIFIER_CHARS = (('A'..'Z').to_a + ('0'..'9').to_a - %w(0 1 I O)).freeze
|
6
6
|
|
7
|
-
belongs_to :order, class_name: 'Spree::Order'
|
7
|
+
belongs_to :order, class_name: 'Spree::Order', touch: true
|
8
8
|
belongs_to :source, polymorphic: true
|
9
9
|
belongs_to :payment_method, class_name: 'Spree::PaymentMethod'
|
10
10
|
|
@@ -30,7 +30,7 @@ module Spree
|
|
30
30
|
scope :completed, -> { with_state('completed') }
|
31
31
|
scope :pending, -> { with_state('pending') }
|
32
32
|
scope :failed, -> { with_state('failed') }
|
33
|
-
scope :valid, -> { where(
|
33
|
+
scope :valid, -> { where.not(state: %w(failed invalid)) }
|
34
34
|
|
35
35
|
after_rollback :persist_invalid
|
36
36
|
|
@@ -118,6 +118,14 @@ module Spree
|
|
118
118
|
res || payment_method
|
119
119
|
end
|
120
120
|
|
121
|
+
def is_avs_risky?
|
122
|
+
!(avs_response == "D" || avs_response.nil?)
|
123
|
+
end
|
124
|
+
|
125
|
+
def is_cvv_risky?
|
126
|
+
!(cvv_response_code == "M" || cvv_response_code.nil?)
|
127
|
+
end
|
128
|
+
|
121
129
|
private
|
122
130
|
|
123
131
|
def validate_source
|
@@ -115,14 +115,15 @@ module Spree
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def gateway_options
|
118
|
-
options = { :email
|
119
|
-
:customer
|
120
|
-
:
|
118
|
+
options = { :email => order.email,
|
119
|
+
:customer => order.email,
|
120
|
+
:customer_id => order.user_id,
|
121
|
+
:ip => order.last_ip_address,
|
121
122
|
# Need to pass in a unique identifier here to make some
|
122
123
|
# payment gateways happy.
|
123
124
|
#
|
124
125
|
# For more information, please see Spree::Payment#set_unique_identifier
|
125
|
-
:order_id
|
126
|
+
:order_id => gateway_order_id }
|
126
127
|
|
127
128
|
options.merge!({ :shipping => order.ship_total * 100,
|
128
129
|
:tax => order.tax_total * 100,
|
data/app/models/spree/price.rb
CHANGED
@@ -22,6 +22,11 @@ module Spree
|
|
22
22
|
self[:amount] = parse_price(price)
|
23
23
|
end
|
24
24
|
|
25
|
+
# Remove variant default_scope `deleted_at: nil`
|
26
|
+
def variant
|
27
|
+
Spree::Variant.unscoped { super }
|
28
|
+
end
|
29
|
+
|
25
30
|
private
|
26
31
|
def check_price
|
27
32
|
raise "Price must belong to a variant" if variant.nil?
|
data/app/models/spree/product.rb
CHANGED
@@ -35,15 +35,18 @@ module Spree
|
|
35
35
|
|
36
36
|
has_one :master,
|
37
37
|
-> { where is_master: true },
|
38
|
+
inverse_of: :product,
|
38
39
|
class_name: 'Spree::Variant',
|
39
40
|
dependent: :destroy
|
40
41
|
|
41
42
|
has_many :variants,
|
42
43
|
-> { where(is_master: false).order("#{::Spree::Variant.quoted_table_name}.position ASC") },
|
44
|
+
inverse_of: :product,
|
43
45
|
class_name: 'Spree::Variant'
|
44
46
|
|
45
47
|
has_many :variants_including_master,
|
46
48
|
-> { order("#{::Spree::Variant.quoted_table_name}.position ASC") },
|
49
|
+
inverse_of: :product,
|
47
50
|
class_name: 'Spree::Variant',
|
48
51
|
dependent: :destroy
|
49
52
|
|
@@ -65,8 +68,6 @@ module Spree
|
|
65
68
|
|
66
69
|
has_many :variant_images, -> { order(:position) }, source: :images, through: :variants_including_master
|
67
70
|
|
68
|
-
accepts_nested_attributes_for :variants, allow_destroy: true
|
69
|
-
|
70
71
|
validates :name, presence: true
|
71
72
|
validates :permalink, presence: true
|
72
73
|
validates :price, presence: true, if: proc { Spree::Config[:require_master_price] }
|
@@ -191,10 +192,10 @@ module Spree
|
|
191
192
|
end
|
192
193
|
|
193
194
|
def total_on_hand
|
194
|
-
if
|
195
|
-
self.stock_items.sum(&:count_on_hand)
|
196
|
-
else
|
195
|
+
if self.variants_including_master.any? { |v| !v.should_track_inventory? }
|
197
196
|
Float::INFINITY
|
197
|
+
else
|
198
|
+
self.stock_items.sum(&:count_on_hand)
|
198
199
|
end
|
199
200
|
end
|
200
201
|
|