spree_core 2.1.3 → 2.1.4
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/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
|
|