spree_core 4.1.0.rc3 → 4.1.0
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 +21 -7
- data/app/helpers/spree/products_helper.rb +12 -10
- data/app/models/spree/order.rb +11 -1
- data/app/models/spree/order/store_credit.rb +2 -0
- data/app/models/spree/product.rb +20 -1
- data/app/models/spree/shipment.rb +1 -0
- data/app/presenters/spree/variant_presenter.rb +10 -4
- data/app/presenters/spree/variants/option_types_presenter.rb +16 -5
- data/config/locales/en.yml +4 -3
- data/db/default/spree/store_credit_categories.rb +1 -0
- data/lib/spree/core/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3057b4eecebae24385eed939c3236d14177222693d927f85e7fac5ac775cbdec
|
4
|
+
data.tar.gz: 8f5f40c80e021a02bb985b119f9c6f5e90d268392b81984df85d0f738208866e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a495af06eebc663bb6c69ccf12b411989f8283ac36edd633b21421bf0b152dbc91315515ea1c5189a1c4b43f45d397fd1d076ad9e35c08e35bdf8f6df573d50e
|
7
|
+
data.tar.gz: e559d035f7ef2359141281dbc4d42dd2f0791ac0c42f7ecc47a638ba0f1dd1bffab385e35389b70409ce1bf856c609a4dabf7edbbb428778f05545e12269b726
|
@@ -25,6 +25,8 @@ module Spree
|
|
25
25
|
def link_to_tracking(shipment, options = {})
|
26
26
|
return unless shipment.tracking && shipment.shipping_method
|
27
27
|
|
28
|
+
options[:target] ||= :blank
|
29
|
+
|
28
30
|
if shipment.tracking_url
|
29
31
|
link_to(shipment.tracking, shipment.tracking_url, options)
|
30
32
|
else
|
@@ -104,15 +106,27 @@ module Spree
|
|
104
106
|
Spree::Core::Engine.frontend_available?
|
105
107
|
end
|
106
108
|
|
109
|
+
# we should always try to render image of the default variant
|
110
|
+
# same as it's done on PDP
|
111
|
+
def default_image_for_product(product)
|
112
|
+
if product.default_variant.images.any?
|
113
|
+
product.default_variant.images.first
|
114
|
+
elsif product.variant_images.any?
|
115
|
+
product.variant_images.first
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
107
119
|
def default_image_for_product_or_variant(product_or_variant)
|
108
|
-
|
109
|
-
if product_or_variant.is_a?(Spree::Product)
|
110
|
-
product_or_variant
|
111
|
-
elsif product_or_variant.is_a?(Spree::Variant)
|
112
|
-
product_or_variant.
|
120
|
+
Rails.cache.fetch("spree/default-image/#{product_or_variant.cache_key_with_version}") do
|
121
|
+
if product_or_variant.is_a?(Spree::Product)
|
122
|
+
default_image_for_product(product_or_variant)
|
123
|
+
elsif product_or_variant.is_a?(Spree::Variant)
|
124
|
+
if product_or_variant.images.any?
|
125
|
+
product_or_variant.images.first
|
126
|
+
else
|
127
|
+
default_image_for_product(product_or_variant.product)
|
128
|
+
end
|
113
129
|
end
|
114
|
-
else
|
115
|
-
product_or_variant.images.first
|
116
130
|
end
|
117
131
|
end
|
118
132
|
|
@@ -31,12 +31,12 @@ module Spree
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
def default_variant(variants)
|
35
|
-
variants_option_types_presenter(variants).default_variant ||
|
34
|
+
def default_variant(variants, product)
|
35
|
+
variants_option_types_presenter(variants, product).default_variant || product.default_variant
|
36
36
|
end
|
37
37
|
|
38
|
-
def used_variants_options(variants)
|
39
|
-
variants_option_types_presenter(variants).options
|
38
|
+
def used_variants_options(variants, product)
|
39
|
+
variants_option_types_presenter(variants, product).options
|
40
40
|
end
|
41
41
|
|
42
42
|
# converts line breaks in product description into <p> tags (for html display purposes)
|
@@ -94,10 +94,12 @@ module Spree
|
|
94
94
|
end
|
95
95
|
|
96
96
|
def product_images(product, variants)
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
97
|
+
if product.variants_and_option_values(current_currency).any?
|
98
|
+
variants_without_master_images = variants.reject(&:is_master).map(&:images).flatten
|
99
|
+
|
100
|
+
if variants_without_master_images.any?
|
101
|
+
return variants_without_master_images
|
102
|
+
end
|
101
103
|
end
|
102
104
|
|
103
105
|
variants.map(&:images).flatten
|
@@ -143,11 +145,11 @@ module Spree
|
|
143
145
|
end
|
144
146
|
end
|
145
147
|
|
146
|
-
def variants_option_types_presenter(variants)
|
148
|
+
def variants_option_types_presenter(variants, product)
|
147
149
|
@_variants_option_types_presenter ||= begin
|
148
150
|
option_types = Spree::Variants::OptionTypesFinder.new(variant_ids: variants.map(&:id)).execute
|
149
151
|
|
150
|
-
Spree::Variants::OptionTypesPresenter.new(option_types, variants)
|
152
|
+
Spree::Variants::OptionTypesPresenter.new(option_types, variants, product)
|
151
153
|
end
|
152
154
|
end
|
153
155
|
end
|
data/app/models/spree/order.rb
CHANGED
@@ -21,7 +21,8 @@ module Spree
|
|
21
21
|
extend Spree::DisplayMoney
|
22
22
|
money_methods :outstanding_balance, :item_total, :adjustment_total,
|
23
23
|
:included_tax_total, :additional_tax_total, :tax_total,
|
24
|
-
:shipment_total, :promo_total, :total
|
24
|
+
:shipment_total, :promo_total, :total,
|
25
|
+
:cart_promo_total
|
25
26
|
|
26
27
|
alias display_ship_total display_shipment_total
|
27
28
|
alias_attribute :ship_total, :shipment_total
|
@@ -631,6 +632,15 @@ module Spree
|
|
631
632
|
coupons
|
632
633
|
end
|
633
634
|
|
635
|
+
# Returns item and whole order discount amount for Order
|
636
|
+
# without Shipment disccounts (eg. Free Shipping)
|
637
|
+
# @return [BigDecimal]
|
638
|
+
def cart_promo_total
|
639
|
+
all_adjustments.eligible.nonzero.promotion.
|
640
|
+
where.not(adjustable_type: 'Spree::Shipment').
|
641
|
+
sum(:amount)
|
642
|
+
end
|
643
|
+
|
634
644
|
private
|
635
645
|
|
636
646
|
def link_by_email
|
data/app/models/spree/product.rb
CHANGED
@@ -75,6 +75,7 @@ module Spree
|
|
75
75
|
has_many :orders, through: :line_items
|
76
76
|
|
77
77
|
has_many :variant_images, -> { order(:position) }, source: :images, through: :variants_including_master
|
78
|
+
has_many :variant_images_without_master, -> { order(:position) }, source: :images, through: :variants
|
78
79
|
|
79
80
|
after_create :add_associations_from_prototype
|
80
81
|
after_create :build_variants_from_option_values_hash, if: :option_values_hash
|
@@ -150,10 +151,28 @@ module Spree
|
|
150
151
|
variants.any?
|
151
152
|
end
|
152
153
|
|
154
|
+
# Returns default Variant for Product
|
155
|
+
# If `track_inventory_levels` is enabled it will try to find the first Variant
|
156
|
+
# in stock or backorderable, if there's none it will return first Variant sorted
|
157
|
+
# by `position` attribute
|
158
|
+
# If `track_inventory_levels` is disabled it will return first Variant sorted
|
159
|
+
# by `position` attribute
|
160
|
+
#
|
161
|
+
# @return [Spree::Variant]
|
153
162
|
def default_variant
|
154
|
-
|
163
|
+
track_inventory = Spree::Config[:track_inventory_levels]
|
164
|
+
|
165
|
+
Rails.cache.fetch("spree/default-variant/#{cache_key_with_version}/#{track_inventory}") do
|
166
|
+
if track_inventory && variants.in_stock_or_backorderable.any?
|
167
|
+
variants.in_stock_or_backorderable.first
|
168
|
+
else
|
169
|
+
has_variants? ? variants.first : master
|
170
|
+
end
|
171
|
+
end
|
155
172
|
end
|
156
173
|
|
174
|
+
# Returns default Variant ID for Product
|
175
|
+
# @return [Integer]
|
157
176
|
def default_variant_id
|
158
177
|
default_variant.id
|
159
178
|
end
|
@@ -40,6 +40,7 @@ module Spree
|
|
40
40
|
scope :with_state, ->(*s) { where(state: s) }
|
41
41
|
# sort by most recent shipped_at, falling back to created_at. add "id desc" to make specs that involve this scope more deterministic.
|
42
42
|
scope :reverse_chronological, -> { order(Arel.sql('coalesce(spree_shipments.shipped_at, spree_shipments.created_at) desc'), id: :desc) }
|
43
|
+
scope :valid, -> { where.not(state: :canceled) }
|
43
44
|
|
44
45
|
# shipment state machine (see http://github.com/pluginaweek/state_machine/tree/master for details)
|
45
46
|
state_machine initial: :pending, use_transactions: false do
|
@@ -18,6 +18,7 @@ module Spree
|
|
18
18
|
display_price: display_price(variant),
|
19
19
|
is_product_available_in_currency: @is_product_available_in_currency,
|
20
20
|
backorderable: backorderable?(variant),
|
21
|
+
in_stock: in_stock?(variant),
|
21
22
|
images: images(variant),
|
22
23
|
option_values: option_values(variant),
|
23
24
|
}.merge(
|
@@ -52,16 +53,21 @@ module Spree
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def backorderable_variant_ids
|
55
|
-
@backorderable_variant_ids ||= Spree::Variant.
|
56
|
-
|
56
|
+
@backorderable_variant_ids ||= Spree::Variant.where(id: @variants.map(&:id)).backorderable.ids
|
57
|
+
end
|
58
|
+
|
59
|
+
def in_stock?(variant)
|
60
|
+
in_stock_variant_ids.include?(variant.id)
|
61
|
+
end
|
62
|
+
|
63
|
+
def in_stock_variant_ids
|
64
|
+
@in_stock_variant_ids ||= Spree::Variant.where(id: @variants.map(&:id)).in_stock.ids
|
57
65
|
end
|
58
66
|
|
59
67
|
def variant_attributes(variant)
|
60
68
|
{
|
61
69
|
id: variant.id,
|
62
70
|
sku: variant.sku,
|
63
|
-
price: variant.price,
|
64
|
-
in_stock: variant.in_stock?,
|
65
71
|
purchasable: variant.purchasable?
|
66
72
|
}
|
67
73
|
end
|
@@ -1,9 +1,10 @@
|
|
1
1
|
module Spree
|
2
2
|
module Variants
|
3
3
|
class OptionTypesPresenter
|
4
|
-
def initialize(option_types, variants)
|
4
|
+
def initialize(option_types, variants, product)
|
5
5
|
@option_types = option_types
|
6
6
|
@variant_ids = variants.map(&:id)
|
7
|
+
@product = product
|
7
8
|
end
|
8
9
|
|
9
10
|
def default_variant
|
@@ -30,7 +31,7 @@ module Spree
|
|
30
31
|
return {} if option_types.empty?
|
31
32
|
|
32
33
|
@default_variant_data ||= begin
|
33
|
-
find_in_stock_variant_data || find_backorderable_variant_data || find_first_variant_data
|
34
|
+
try_default_variant || find_in_stock_variant_data || find_backorderable_variant_data || find_first_variant_data
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
@@ -44,7 +45,17 @@ module Spree
|
|
44
45
|
|
45
46
|
def find_variant_data(&block)
|
46
47
|
option_types.first.option_values.each do |option_value|
|
47
|
-
variant = option_value.variants.where(id: @variant_ids).find(&block)
|
48
|
+
variant = option_value.variants.where(id: @variant_ids).order(:position).find(&block)
|
49
|
+
|
50
|
+
return { variant: variant, option_value: option_value } if variant
|
51
|
+
end
|
52
|
+
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
|
56
|
+
def try_default_variant
|
57
|
+
option_types.first.option_values.each do |option_value|
|
58
|
+
variant = option_value.variants.where(id: @product.default_variant_id).first
|
48
59
|
|
49
60
|
return { variant: variant, option_value: option_value } if variant
|
50
61
|
end
|
@@ -54,7 +65,7 @@ module Spree
|
|
54
65
|
|
55
66
|
def find_first_variant_data
|
56
67
|
option_value = option_types.first.option_values.first
|
57
|
-
variant = option_value.variants.where(id: @variant_ids).first
|
68
|
+
variant = option_value.variants.where(id: @variant_ids).order(:position).first
|
58
69
|
|
59
70
|
{ variant: variant, option_value: option_value }
|
60
71
|
end
|
@@ -65,7 +76,7 @@ module Spree
|
|
65
76
|
id: option_value.id,
|
66
77
|
position: option_value.position,
|
67
78
|
presentation: option_value.presentation,
|
68
|
-
variant_id: option_value.variants.where(id: @variant_ids).first.id,
|
79
|
+
variant_id: option_value.variants.where(id: @variant_ids).order(:position).first.id,
|
69
80
|
is_default: option_value == default_variant_data[:option_value]
|
70
81
|
}
|
71
82
|
end
|
data/config/locales/en.yml
CHANGED
@@ -488,7 +488,7 @@ en:
|
|
488
488
|
add_variant: Add Variant
|
489
489
|
add_store: New Store
|
490
490
|
add_store_credit: Add Store Credit
|
491
|
-
added_to_cart: Added to
|
491
|
+
added_to_cart: Added to cart successfully!
|
492
492
|
additional_item: Additional Item
|
493
493
|
address: Address
|
494
494
|
address1: Address
|
@@ -636,7 +636,7 @@ en:
|
|
636
636
|
add_promo_code: ADD PROMO CODE
|
637
637
|
checkout: checkout
|
638
638
|
empty_info: 'Your cart is empty.'
|
639
|
-
header: Your shopping
|
639
|
+
header: Your shopping cart
|
640
640
|
product: product
|
641
641
|
quantity: quantity
|
642
642
|
title: Shopping Cart
|
@@ -1213,7 +1213,7 @@ en:
|
|
1213
1213
|
not_found_filters2: Please try another choose.
|
1214
1214
|
not_found_text1: We couldn’t find products for '%{keywords}'.
|
1215
1215
|
not_found_text2: Please try another search.
|
1216
|
-
price:
|
1216
|
+
price: price
|
1217
1217
|
price_high_to_low: PRICE (HIGH - LOW)
|
1218
1218
|
price_low_to_high: PRICE (LOW - HIGH)
|
1219
1219
|
result: RESULT
|
@@ -1367,6 +1367,7 @@ en:
|
|
1367
1367
|
authorized: Authorized
|
1368
1368
|
canceled: Canceled
|
1369
1369
|
return_authorization_updated: Return authorization updated
|
1370
|
+
return_authorization_canceled: Return authorization canceled
|
1370
1371
|
return_authorizations: Return Authorizations
|
1371
1372
|
return_item_inventory_unit_ineligible: Return item's inventory unit must be shipped
|
1372
1373
|
return_item_inventory_unit_reimbursed: Return item's inventory unit is already reimbursed
|
@@ -0,0 +1 @@
|
|
1
|
+
Spree::StoreCreditCategory.find_or_create_by!(name: 'Default')
|
data/lib/spree/core/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spree_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.1.0
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Schofield
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-02
|
11
|
+
date: 2020-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemerchant
|
@@ -677,6 +677,7 @@ files:
|
|
677
677
|
- db/default/spree/default_reimbursement_type.rb
|
678
678
|
- db/default/spree/roles.rb
|
679
679
|
- db/default/spree/states.rb
|
680
|
+
- db/default/spree/store_credit_categories.rb
|
680
681
|
- db/default/spree/stores.rb
|
681
682
|
- db/default/spree/zones.rb
|
682
683
|
- db/migrate/20120831092320_spree_one_two.rb
|