spree_core 2.2.2 → 2.2.3
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 +2 -2
- data/app/helpers/spree/products_helper.rb +1 -1
- data/app/helpers/spree/store_helper.rb +1 -1
- data/app/models/spree/adjustment.rb +10 -9
- data/app/models/spree/app_configuration.rb +1 -0
- data/app/models/spree/credit_card.rb +6 -5
- data/app/models/spree/line_item.rb +3 -3
- data/app/models/spree/order.rb +4 -8
- data/app/models/spree/order/checkout.rb +2 -0
- data/app/models/spree/order_contents.rb +3 -0
- data/app/models/spree/order_updater.rb +2 -2
- data/app/models/spree/payment.rb +10 -9
- data/app/models/spree/payment/processing.rb +1 -1
- data/app/models/spree/product.rb +18 -1
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +5 -3
- data/app/models/spree/promotion_action.rb +2 -0
- data/app/models/spree/promotion_handler/coupon.rb +13 -4
- data/app/models/spree/return_authorization.rb +9 -8
- data/app/models/spree/stock/estimator.rb +1 -1
- data/app/models/spree/zone.rb +5 -5
- data/app/views/spree/order_mailer/confirm_email.text.erb +20 -2
- data/app/views/spree/shared/_routes.html.erb +5 -5
- data/config/locales/en.yml +1 -0
- data/db/migrate/20131118183431_add_line_item_id_to_spree_inventory_units.rb +2 -2
- data/db/migrate/20140601011216_set_shipment_total_for_users_upgrading.rb +12 -0
- data/db/migrate/20140609201656_add_deleted_at_to_spree_promotion_actions.rb +6 -0
- data/db/migrate/20140616202624_remove_uncaptured_amount_from_spree_payments.rb +5 -0
- data/lib/spree/core/product_duplicator.rb +6 -2
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/testing_support/factories/promotion_factory.rb +31 -1
- metadata +14 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f612c6f42ba3ade084e50bdca945ccf34f1ce76f
|
4
|
+
data.tar.gz: f84f159adfe58ab3b210da9b0d596a54d3d758c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 39a5a14c31bfeb6eaff2d0f2b99eacd506e01f882fa5c20f6f03efc1d8e74d7f965a37e0d1f5f857ef25e0735056905708c8960b89310a776d2fc506d702b9d3
|
7
|
+
data.tar.gz: 7c92311fcbbd4cc550c32c3473352f719e94d40367fde91c05779a7274eff4a34c6d3ed096c69fc9eacbb921ab4f20ad3c3ba722d8060646e4ace2813e2d9dcb
|
@@ -20,11 +20,11 @@ module Spree
|
|
20
20
|
text = "#{text}: (#{Spree.t('empty')})"
|
21
21
|
css_class = 'empty'
|
22
22
|
else
|
23
|
-
text = "#{text}: (#{simple_current_order.item_count}) <span class='amount'>#{simple_current_order.display_total.to_html}</span>"
|
23
|
+
text = "#{text}: (#{simple_current_order.item_count}) <span class='amount'>#{simple_current_order.display_total.to_html}</span>"
|
24
24
|
css_class = 'full'
|
25
25
|
end
|
26
26
|
|
27
|
-
link_to text, spree.cart_path, :class => "cart-info #{css_class}"
|
27
|
+
link_to text.html_safe, spree.cart_path, :class => "cart-info #{css_class}"
|
28
28
|
end
|
29
29
|
|
30
30
|
# human readable list of variant options
|
@@ -55,7 +55,7 @@ module Spree
|
|
55
55
|
def cache_key_for_products
|
56
56
|
count = @products.count
|
57
57
|
max_updated_at = (@products.maximum(:updated_at) || Date.today).to_s(:number)
|
58
|
-
"#{current_currency}/spree/products/all-#{params[:page]}-#{max_updated_at}-#{count}"
|
58
|
+
"#{I18n.locale}/#{current_currency}/spree/products/all-#{params[:page]}-#{max_updated_at}-#{count}"
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
@@ -24,7 +24,7 @@ module Spree
|
|
24
24
|
class Adjustment < ActiveRecord::Base
|
25
25
|
belongs_to :adjustable, polymorphic: true
|
26
26
|
belongs_to :source, polymorphic: true
|
27
|
-
belongs_to :order, :
|
27
|
+
belongs_to :order, class_name: "Spree::Order"
|
28
28
|
|
29
29
|
validates :label, presence: true
|
30
30
|
validates :amount, numericality: true
|
@@ -59,6 +59,14 @@ module Spree
|
|
59
59
|
state == "closed"
|
60
60
|
end
|
61
61
|
|
62
|
+
def currency
|
63
|
+
adjustable ? adjustable.currency : Spree::Config[:currency]
|
64
|
+
end
|
65
|
+
|
66
|
+
def display_amount
|
67
|
+
Spree::Money.new(amount, { currency: currency })
|
68
|
+
end
|
69
|
+
|
62
70
|
def promotion?
|
63
71
|
source.class < Spree::PromotionAction
|
64
72
|
end
|
@@ -88,19 +96,12 @@ module Spree
|
|
88
96
|
amount
|
89
97
|
end
|
90
98
|
|
91
|
-
def currency
|
92
|
-
adjustable ? adjustable.currency : Spree::Config[:currency]
|
93
|
-
end
|
94
|
-
|
95
|
-
def display_amount
|
96
|
-
Spree::Money.new(amount, { currency: currency })
|
97
|
-
end
|
98
|
-
|
99
99
|
private
|
100
100
|
|
101
101
|
def update_adjustable_adjustment_total
|
102
102
|
# Cause adjustable's total to be recalculated
|
103
103
|
Spree::ItemAdjustments.new(adjustable).update if adjustable
|
104
104
|
end
|
105
|
+
|
105
106
|
end
|
106
107
|
end
|
@@ -57,6 +57,7 @@ module Spree
|
|
57
57
|
preference :max_level_in_taxons_menu, :integer, default: 1 # maximum nesting level in taxons menu
|
58
58
|
preference :orders_per_page, :integer, default: 15
|
59
59
|
preference :prices_inc_tax, :boolean, default: false
|
60
|
+
preference :properties_per_page, :integer, default: 15
|
60
61
|
preference :products_per_page, :integer, default: 12
|
61
62
|
preference :promotions_per_page, :integer, default: 15
|
62
63
|
preference :redirect_https_to_http, :boolean, :default => false
|
@@ -37,9 +37,10 @@ module Spree
|
|
37
37
|
elsif match = expiry.match(/(\d{2})(\d{2,4})/) # will match mmyy and mmyyyy
|
38
38
|
[match[1], match[2]]
|
39
39
|
end
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
if self[:year]
|
41
|
+
self[:year] = "20" + self[:year] if self[:year].length == 2
|
42
|
+
self[:year] = self[:year].to_i
|
43
|
+
end
|
43
44
|
self[:month] = self[:month].to_i
|
44
45
|
end
|
45
46
|
|
@@ -111,8 +112,8 @@ module Spree
|
|
111
112
|
:month => month,
|
112
113
|
:year => year,
|
113
114
|
:verification_value => verification_value,
|
114
|
-
:first_name => first_name,
|
115
|
-
:last_name => last_name
|
115
|
+
:first_name => first_name || name.to_s.split(/[[:space:]]/, 2)[0],
|
116
|
+
:last_name => last_name || name.to_s.split(/[[:space:]]/, 2)[1]
|
116
117
|
)
|
117
118
|
end
|
118
119
|
|
@@ -28,7 +28,7 @@ module Spree
|
|
28
28
|
after_save :update_inventory
|
29
29
|
after_save :update_adjustments
|
30
30
|
|
31
|
-
after_create :
|
31
|
+
after_create :update_tax_charge
|
32
32
|
|
33
33
|
delegate :name, :description, :should_track_inventory?, to: :variant
|
34
34
|
|
@@ -108,6 +108,7 @@ module Spree
|
|
108
108
|
|
109
109
|
def update_adjustments
|
110
110
|
if quantity_changed?
|
111
|
+
update_tax_charge # Called to ensure pre_tax_amount is updated.
|
111
112
|
recalculate_adjustments
|
112
113
|
end
|
113
114
|
end
|
@@ -116,7 +117,7 @@ module Spree
|
|
116
117
|
Spree::ItemAdjustments.new(self).update
|
117
118
|
end
|
118
119
|
|
119
|
-
def
|
120
|
+
def update_tax_charge
|
120
121
|
Spree::TaxRate.adjust(order, [self])
|
121
122
|
end
|
122
123
|
|
@@ -127,4 +128,3 @@ module Spree
|
|
127
128
|
end
|
128
129
|
end
|
129
130
|
end
|
130
|
-
|
data/app/models/spree/order.rb
CHANGED
@@ -121,7 +121,7 @@ module Spree
|
|
121
121
|
|
122
122
|
def all_adjustments
|
123
123
|
Adjustment.where("order_id = :order_id OR (adjustable_id = :order_id AND adjustable_type = 'Spree::Order')",
|
124
|
-
:
|
124
|
+
order_id: self.id)
|
125
125
|
end
|
126
126
|
|
127
127
|
# For compatiblity with Calculator::PriceSack
|
@@ -439,8 +439,9 @@ module Spree
|
|
439
439
|
def empty!
|
440
440
|
line_items.destroy_all
|
441
441
|
updater.update_item_count
|
442
|
-
|
443
442
|
adjustments.destroy_all
|
443
|
+
shipments.destroy_all
|
444
|
+
|
444
445
|
update_totals
|
445
446
|
persist_totals
|
446
447
|
end
|
@@ -532,12 +533,7 @@ module Spree
|
|
532
533
|
end
|
533
534
|
|
534
535
|
def is_risky?
|
535
|
-
self.payments.
|
536
|
-
(avs_response IS NOT NULL and avs_response != '' and avs_response != 'D' and avs_response != 'M') or
|
537
|
-
(cvv_response_code IS NOT NULL and cvv_response_code != 'M') or
|
538
|
-
cvv_response_message IS NOT NULL and cvv_response_message != '' or
|
539
|
-
state = 'failed'
|
540
|
-
}.squish!).uniq.count > 0
|
536
|
+
self.payments.risky.count > 0
|
541
537
|
end
|
542
538
|
|
543
539
|
def approved_by(user)
|
@@ -222,6 +222,8 @@ module Spree
|
|
222
222
|
raise Core::GatewayError.new Spree.t(:invalid_credit_card)
|
223
223
|
end
|
224
224
|
|
225
|
+
credit_card.verification_value = params[:cvc_confirm] if params[:cvc_confirm].present?
|
226
|
+
|
225
227
|
attributes[:payments_attributes].first[:source] = credit_card
|
226
228
|
attributes[:payments_attributes].first[:payment_method_id] = credit_card.payment_method_id
|
227
229
|
attributes[:payments_attributes].first.delete :source_attributes
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spree
|
2
2
|
class OrderUpdater
|
3
3
|
attr_reader :order
|
4
|
-
delegate :payments, :line_items, :adjustments, :shipments, :update_hooks, to: :order
|
4
|
+
delegate :payments, :line_items, :adjustments, :all_adjustments, :shipments, :update_hooks, to: :order
|
5
5
|
|
6
6
|
def initialize(order)
|
7
7
|
@order = order
|
@@ -30,7 +30,7 @@ module Spree
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def recalculate_adjustments
|
33
|
-
|
33
|
+
all_adjustments.includes(:adjustable).map(&:adjustable).uniq.each { |adjustable| Spree::ItemAdjustments.new(adjustable).update }
|
34
34
|
end
|
35
35
|
|
36
36
|
# Updates the following Order total values:
|
data/app/models/spree/payment.rb
CHANGED
@@ -2,7 +2,9 @@ module Spree
|
|
2
2
|
class Payment < ActiveRecord::Base
|
3
3
|
include Spree::Payment::Processing
|
4
4
|
|
5
|
-
IDENTIFIER_CHARS
|
5
|
+
IDENTIFIER_CHARS = (('A'..'Z').to_a + ('0'..'9').to_a - %w(0 1 I O)).freeze
|
6
|
+
NON_RISKY_AVS_CODES = ['B', 'D', 'H', 'J', 'M', 'Q', 'T', 'V', 'X', 'Y'].freeze
|
7
|
+
RISKY_AVS_CODES = ['A', 'C', 'E', 'F', 'G', 'I', 'K', 'L', 'N', 'O', 'P', 'R', 'S', 'U', 'W', 'Z'].freeze
|
6
8
|
|
7
9
|
belongs_to :order, class_name: 'Spree::Order', touch: true, inverse_of: :payments
|
8
10
|
belongs_to :source, polymorphic: true
|
@@ -16,7 +18,6 @@ module Spree
|
|
16
18
|
|
17
19
|
before_validation :validate_source
|
18
20
|
before_create :set_unique_identifier
|
19
|
-
before_save :update_uncaptured_amount
|
20
21
|
|
21
22
|
after_save :create_payment_profile, if: :profiles_supported?
|
22
23
|
|
@@ -33,6 +34,7 @@ module Spree
|
|
33
34
|
scope :completed, -> { with_state('completed') }
|
34
35
|
scope :pending, -> { with_state('pending') }
|
35
36
|
scope :failed, -> { with_state('failed') }
|
37
|
+
scope :risky, -> { where("avs_response IN (?) OR (cvv_response_code IS NOT NULL and cvv_response_code != 'M') OR state = 'failed'", RISKY_AVS_CODES) }
|
36
38
|
scope :valid, -> { where.not(state: %w(failed invalid)) }
|
37
39
|
|
38
40
|
after_rollback :persist_invalid
|
@@ -94,7 +96,7 @@ module Spree
|
|
94
96
|
case amount
|
95
97
|
when String
|
96
98
|
separator = I18n.t('number.currency.format.separator')
|
97
|
-
number = amount.delete("^0-9-#{separator}").tr(separator, '.')
|
99
|
+
number = amount.delete("^0-9-#{separator}\.").tr(separator, '.')
|
98
100
|
number.to_d if number.present?
|
99
101
|
end || amount
|
100
102
|
end
|
@@ -132,8 +134,7 @@ module Spree
|
|
132
134
|
end
|
133
135
|
|
134
136
|
def is_avs_risky?
|
135
|
-
return false if avs_response
|
136
|
-
return false if avs_response.blank?
|
137
|
+
return false if avs_response.blank? || NON_RISKY_AVS_CODES.include?(avs_response)
|
137
138
|
return true
|
138
139
|
end
|
139
140
|
|
@@ -144,6 +145,10 @@ module Spree
|
|
144
145
|
return true
|
145
146
|
end
|
146
147
|
|
148
|
+
def uncaptured_amount
|
149
|
+
amount - capture_events.sum(:amount)
|
150
|
+
end
|
151
|
+
|
147
152
|
private
|
148
153
|
|
149
154
|
def validate_source
|
@@ -193,9 +198,5 @@ module Spree
|
|
193
198
|
def generate_identifier
|
194
199
|
Array.new(8){ IDENTIFIER_CHARS.sample }.join
|
195
200
|
end
|
196
|
-
|
197
|
-
def update_uncaptured_amount
|
198
|
-
self.uncaptured_amount = amount - capture_events.sum(:amount)
|
199
|
-
end
|
200
201
|
end
|
201
202
|
end
|
data/app/models/spree/product.rb
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
module Spree
|
22
22
|
class Product < ActiveRecord::Base
|
23
23
|
extend FriendlyId
|
24
|
-
friendly_id :
|
24
|
+
friendly_id :slug_candidates, use: :slugged
|
25
25
|
|
26
26
|
acts_as_paranoid
|
27
27
|
has_many :product_option_types, dependent: :destroy, inverse_of: :product
|
@@ -77,9 +77,12 @@ module Spree
|
|
77
77
|
validates :price, presence: true, if: proc { Spree::Config[:require_master_price] }
|
78
78
|
validates :shipping_category_id, presence: true
|
79
79
|
validates :slug, length: { minimum: 3 }
|
80
|
+
validates :slug, uniqueness: true
|
80
81
|
|
81
82
|
before_validation :normalize_slug, on: :update
|
82
83
|
|
84
|
+
after_destroy :punch_slug
|
85
|
+
|
83
86
|
attr_accessor :option_values_hash
|
84
87
|
|
85
88
|
accepts_nested_attributes_for :product_properties, allow_destroy: true, reject_if: lambda { |pp| pp[:property_name].blank? }
|
@@ -213,6 +216,7 @@ module Spree
|
|
213
216
|
end
|
214
217
|
|
215
218
|
private
|
219
|
+
|
216
220
|
def normalize_slug
|
217
221
|
self.slug = normalize_friendly_id(slug)
|
218
222
|
end
|
@@ -265,6 +269,19 @@ module Spree
|
|
265
269
|
taxonomy_ids_to_touch = taxons_to_touch.map(&:taxonomy_id).flatten.uniq
|
266
270
|
Spree::Taxonomy.where(id: taxonomy_ids_to_touch).update_all(updated_at: Time.current)
|
267
271
|
end
|
272
|
+
|
273
|
+
# Try building a slug based on the following fields in increasing order of specificity.
|
274
|
+
def slug_candidates
|
275
|
+
[
|
276
|
+
:name,
|
277
|
+
[:name, :sku]
|
278
|
+
]
|
279
|
+
end
|
280
|
+
|
281
|
+
def punch_slug
|
282
|
+
update(slug: "#{Time.now.to_i}_#{slug}") # punch slug with date prefix to allow reuse of original
|
283
|
+
end
|
284
|
+
|
268
285
|
end
|
269
286
|
end
|
270
287
|
|
@@ -41,8 +41,9 @@ module Spree
|
|
41
41
|
# Ensure a negative amount which does not exceed the sum of the order's
|
42
42
|
# item_total and ship_total
|
43
43
|
def compute_amount(adjustable)
|
44
|
-
|
45
|
-
|
44
|
+
promotion_amount = self.calculator.compute(adjustable).to_f.abs
|
45
|
+
|
46
|
+
[adjustable.amount, promotion_amount].min * -1
|
46
47
|
end
|
47
48
|
|
48
49
|
private
|
@@ -62,7 +63,8 @@ module Spree
|
|
62
63
|
end
|
63
64
|
|
64
65
|
def deals_with_adjustments
|
65
|
-
adjustment_scope =
|
66
|
+
adjustment_scope = self.adjustments.includes(:order).references(:spree_orders)
|
67
|
+
|
66
68
|
# For incomplete orders, remove the adjustment completely.
|
67
69
|
adjustment_scope.where("spree_orders.completed_at IS NULL").each do |adjustment|
|
68
70
|
adjustment.destroy
|
@@ -2,6 +2,8 @@
|
|
2
2
|
# PromotionActions perform the necessary tasks when a promotion is activated by an event and determined to be eligible.
|
3
3
|
module Spree
|
4
4
|
class PromotionAction < ActiveRecord::Base
|
5
|
+
acts_as_paranoid
|
6
|
+
|
5
7
|
belongs_to :promotion, class_name: 'Spree::Promotion'
|
6
8
|
|
7
9
|
scope :of_type, ->(t) { where(type: t) }
|
@@ -36,15 +36,16 @@ module Spree
|
|
36
36
|
|
37
37
|
def handle_present_promotion(promotion)
|
38
38
|
return promotion_usage_limit_exceeded if promotion.usage_limit_exceeded?(order)
|
39
|
+
return promotion_applied if promotion_exists_on_order?(order, promotion)
|
39
40
|
return ineligible_for_this_order unless promotion.eligible?(order)
|
40
41
|
|
41
42
|
# If any of the actions for the promotion return `true`,
|
42
43
|
# then result here will also be `true`.
|
43
44
|
result = promotion.activate(:order => order)
|
44
45
|
if result
|
45
|
-
determine_promotion_application_result
|
46
|
+
determine_promotion_application_result
|
46
47
|
else
|
47
|
-
self.error = Spree.t(:
|
48
|
+
self.error = Spree.t(:coupon_code_unknown_error)
|
48
49
|
end
|
49
50
|
end
|
50
51
|
|
@@ -56,7 +57,15 @@ module Spree
|
|
56
57
|
self.error = Spree.t(:coupon_code_not_eligible)
|
57
58
|
end
|
58
59
|
|
59
|
-
def
|
60
|
+
def promotion_applied
|
61
|
+
self.error = Spree.t(:coupon_code_already_applied)
|
62
|
+
end
|
63
|
+
|
64
|
+
def promotion_exists_on_order?(order, promotion)
|
65
|
+
order.promotions.include? promotion
|
66
|
+
end
|
67
|
+
|
68
|
+
def determine_promotion_application_result
|
60
69
|
detector = lambda { |p|
|
61
70
|
if p.source.promotion.code
|
62
71
|
p.source.promotion.code.downcase == order.coupon_code.downcase
|
@@ -67,7 +76,7 @@ module Spree
|
|
67
76
|
discount ||= order.shipment_adjustments.promotion.detect(&detector)
|
68
77
|
discount ||= order.adjustments.promotion.detect(&detector)
|
69
78
|
|
70
|
-
if
|
79
|
+
if discount.eligible
|
71
80
|
order.update_totals
|
72
81
|
order.persist_totals
|
73
82
|
self.success = Spree.t(:coupon_code_applied)
|
@@ -3,7 +3,7 @@ module Spree
|
|
3
3
|
belongs_to :order, class_name: 'Spree::Order'
|
4
4
|
|
5
5
|
has_many :inventory_units
|
6
|
-
|
6
|
+
belongs_to :stock_location
|
7
7
|
before_create :generate_number
|
8
8
|
before_save :force_positive_amount
|
9
9
|
|
@@ -81,16 +81,17 @@ module Spree
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def process_return
|
84
|
-
inventory_units.each do |iu|
|
84
|
+
inventory_units(include: :variant).each do |iu|
|
85
85
|
iu.return!
|
86
|
-
|
87
|
-
|
86
|
+
|
87
|
+
if iu.variant.should_track_inventory?
|
88
|
+
if stock_item = Spree::StockItem.find_by(variant_id: iu.variant_id, stock_location_id: stock_location_id)
|
89
|
+
Spree::StockMovement.create!(stock_item_id: stock_item.id, quantity: 1)
|
90
|
+
end
|
91
|
+
end
|
88
92
|
end
|
89
93
|
|
90
|
-
|
91
|
-
credit.source = self
|
92
|
-
credit.adjustable = order
|
93
|
-
credit.save
|
94
|
+
Adjustment.create(adjustable: order, amount: compute_amount, label: Spree.t(:rma_credit), source: self)
|
94
95
|
order.update!
|
95
96
|
|
96
97
|
order.return if inventory_units.all?(&:returned?)
|
@@ -52,8 +52,8 @@ module Spree
|
|
52
52
|
package.shipping_methods.select do |ship_method|
|
53
53
|
calculator = ship_method.calculator
|
54
54
|
begin
|
55
|
-
calculator.available?(package) &&
|
56
55
|
ship_method.include?(order.ship_address) &&
|
56
|
+
calculator.available?(package) &&
|
57
57
|
(calculator.preferences[:currency].nil? ||
|
58
58
|
calculator.preferences[:currency] == currency)
|
59
59
|
rescue Exception => exception
|
data/app/models/spree/zone.rb
CHANGED
@@ -71,12 +71,12 @@ module Spree
|
|
71
71
|
# All zoneables belonging to the zone members. Will be a collection of either
|
72
72
|
# countries or states depending on the zone type.
|
73
73
|
def zoneables
|
74
|
-
members.collect(&:zoneable)
|
74
|
+
members.includes(:zoneable).collect(&:zoneable)
|
75
75
|
end
|
76
76
|
|
77
77
|
def country_ids
|
78
78
|
if kind == 'country'
|
79
|
-
members.
|
79
|
+
members.pluck(:zoneable_id)
|
80
80
|
else
|
81
81
|
[]
|
82
82
|
end
|
@@ -84,7 +84,7 @@ module Spree
|
|
84
84
|
|
85
85
|
def state_ids
|
86
86
|
if kind == 'state'
|
87
|
-
members.
|
87
|
+
members.pluck(:zoneable_id)
|
88
88
|
else
|
89
89
|
[]
|
90
90
|
end
|
@@ -117,9 +117,9 @@ module Spree
|
|
117
117
|
return false if zone_members.empty? || target.zone_members.empty?
|
118
118
|
|
119
119
|
if kind == target.kind
|
120
|
-
return false if target.zoneables.
|
120
|
+
return false if (target.zoneables.collect(&:id) - zoneables.collect(&:id)).present?
|
121
121
|
else
|
122
|
-
return false if target.zoneables.
|
122
|
+
return false if (target.zoneables.collect(&:country).collect(&:id) - zoneables.collect(&:id)).present?
|
123
123
|
end
|
124
124
|
true
|
125
125
|
end
|
@@ -10,11 +10,29 @@
|
|
10
10
|
<% end %>
|
11
11
|
============================================================
|
12
12
|
<%= Spree.t('order_mailer.confirm_email.subtotal', :subtotal => @order.display_item_total) %>
|
13
|
+
<% if @order.line_item_adjustments.exists? %>
|
14
|
+
<% if @order.all_adjustments.promotion.eligible.exists? %>
|
15
|
+
<% @order.all_adjustments.promotion.eligible.group_by(&:label).each do |label, adjustments| %>
|
16
|
+
<%= Spree.t(:promotion) %>: <%= label %> <%= Spree::Money.new(adjustments.sum(&:amount), currency: @order.currency) %>
|
17
|
+
<% end %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
13
20
|
|
14
|
-
<% @order.
|
15
|
-
|
21
|
+
<% @order.shipments.group_by { |s| s.selected_shipping_rate.try(:name) }.each do |name, shipments| %>
|
22
|
+
<%= Spree.t(:shipping) %>: <%= name %> <%= Spree::Money.new(shipments.sum(&:discounted_cost), currency: @order.currency) %>
|
23
|
+
<% end %>
|
24
|
+
|
25
|
+
<% if @order.all_adjustments.eligible.tax.exists? %>
|
26
|
+
<% @order.all_adjustments.eligible.tax.group_by(&:label).each do |label, adjustments| %>
|
27
|
+
<%= Spree.t(:tax) %>: <%= label %> <%= Spree::Money.new(adjustments.sum(&:amount), currency: @order.currency) %>
|
28
|
+
<% end %>
|
16
29
|
<% end %>
|
17
30
|
|
31
|
+
<% @order.adjustments.eligible.each do |adjustment| %>
|
32
|
+
<% next if (adjustment.source_type == 'Spree::TaxRate') and (adjustment.amount == 0) %>
|
33
|
+
<%= adjustment.label %> <%= adjustment.display_amount %>
|
34
|
+
<% end %>
|
35
|
+
============================================================
|
18
36
|
<%= Spree.t('order_mailer.confirm_email.total', :total => @order.display_total) %>
|
19
37
|
|
20
38
|
<%= Spree.t('order_mailer.confirm_email.thanks') %>
|
@@ -1,13 +1,13 @@
|
|
1
1
|
<script>
|
2
2
|
if (Spree === undefined) {
|
3
|
-
var Spree = {}
|
3
|
+
var Spree = {};
|
4
4
|
}
|
5
5
|
if (Spree.routes == undefined) {
|
6
|
-
Spree.routes = {}
|
6
|
+
Spree.routes = {};
|
7
7
|
}
|
8
|
-
Spree.routes.states_search = "<%= spree.api_states_path(:format => 'json') %>"
|
8
|
+
Spree.routes.states_search = "<%= spree.api_states_path(:format => 'json') %>";
|
9
9
|
Spree.routes.apply_coupon_code = function(order_id) {
|
10
|
-
return "<%= spree.api_orders_path %>/" + order_id + "/apply_coupon_code"
|
10
|
+
return "<%= spree.api_orders_path %>/" + order_id + "/apply_coupon_code";
|
11
11
|
}
|
12
|
-
Spree.routes.root = "<%= spree.root_url if spree.respond_to? :root_url %>"
|
12
|
+
Spree.routes.root = "<%= spree.root_url if spree.respond_to? :root_url %>";
|
13
13
|
</script>
|
data/config/locales/en.yml
CHANGED
@@ -485,6 +485,7 @@ en:
|
|
485
485
|
coupon_code_max_usage: Coupon code usage limit exceeded
|
486
486
|
coupon_code_not_eligible: This coupon code is not eligible for this order
|
487
487
|
coupon_code_not_found: The coupon code you entered doesn't exist. Please try again.
|
488
|
+
coupon_code_unknown_error: This coupon code could not be applied to the cart at this time.
|
488
489
|
create: Create
|
489
490
|
create_a_new_account: Create a new account
|
490
491
|
created_at: Created At
|
@@ -8,9 +8,9 @@ class AddLineItemIdToSpreeInventoryUnits < ActiveRecord::Migration
|
|
8
8
|
shipments = Spree::Shipment.includes(:inventory_units, :order)
|
9
9
|
|
10
10
|
shipments.find_each do |shipment|
|
11
|
-
shipment.inventory_units.group_by(&:
|
11
|
+
shipment.inventory_units.group_by(&:variant_id).each do |variant, units|
|
12
12
|
|
13
|
-
line_item = shipment.order.
|
13
|
+
line_item = shipment.order.line_items.find_by(variant_id: variant_id)
|
14
14
|
next unless line_item
|
15
15
|
|
16
16
|
Spree::InventoryUnit.where(id: units.map(&:id)).update_all(line_item_id: line_item.id)
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class SetShipmentTotalForUsersUpgrading < ActiveRecord::Migration
|
2
|
+
def up
|
3
|
+
# NOTE You might not need this at all unless you're upgrading from Spree 2.1.x
|
4
|
+
# or below. For those upgrading this should populate the Order#shipment_total
|
5
|
+
# for legacy orders
|
6
|
+
execute "UPDATE spree_orders
|
7
|
+
SET shipment_total = (SELECT SUM(spree_shipments.cost) AS sum_id
|
8
|
+
FROM spree_shipments
|
9
|
+
WHERE spree_shipments.order_id = spree_orders.id)
|
10
|
+
WHERE spree_orders.completed_at IS NOT NULL AND spree_orders.shipment_total = 0"
|
11
|
+
end
|
12
|
+
end
|
@@ -2,8 +2,12 @@ module Spree
|
|
2
2
|
class ProductDuplicator
|
3
3
|
attr_accessor :product
|
4
4
|
|
5
|
-
|
5
|
+
@@clone_images_default = true
|
6
|
+
mattr_accessor :clone_images_default
|
7
|
+
|
8
|
+
def initialize(product, include_images = @@clone_images_default)
|
6
9
|
@product = product
|
10
|
+
@include_images = include_images
|
7
11
|
end
|
8
12
|
|
9
13
|
def duplicate
|
@@ -38,7 +42,7 @@ module Spree
|
|
38
42
|
master.dup.tap do |new_master|
|
39
43
|
new_master.sku = "COPY OF #{master.sku}"
|
40
44
|
new_master.deleted_at = nil
|
41
|
-
new_master.images = master.images.map { |image| duplicate_image image }
|
45
|
+
new_master.images = master.images.map { |image| duplicate_image image } if @include_images
|
42
46
|
new_master.price = master.price
|
43
47
|
new_master.currency = master.currency
|
44
48
|
end
|
data/lib/spree/core/version.rb
CHANGED
@@ -2,7 +2,7 @@ FactoryGirl.define do
|
|
2
2
|
factory :promotion, class: Spree::Promotion do
|
3
3
|
name 'Promo'
|
4
4
|
|
5
|
-
|
5
|
+
trait :with_line_item_adjustment do
|
6
6
|
ignore do
|
7
7
|
adjustment_rate 10
|
8
8
|
end
|
@@ -15,6 +15,36 @@ FactoryGirl.define do
|
|
15
15
|
promotion.save
|
16
16
|
end
|
17
17
|
end
|
18
|
+
factory :promotion_with_item_adjustment, traits: [:with_line_item_adjustment]
|
19
|
+
|
20
|
+
trait :with_order_adjustment do
|
21
|
+
ignore do
|
22
|
+
order_adjustment_amount 10
|
23
|
+
end
|
24
|
+
|
25
|
+
after(:create) do |promotion, evaluator|
|
26
|
+
calculator = Spree::Calculator::FlatRate.new
|
27
|
+
calculator.preferred_amount = evaluator.order_adjustment_amount
|
28
|
+
action = Spree::Promotion::Actions::CreateAdjustment.create!(:calculator => calculator)
|
29
|
+
promotion.actions << action
|
30
|
+
promotion.save!
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
trait :with_item_total_rule do
|
35
|
+
ignore do
|
36
|
+
item_total_threshold_amount 10
|
37
|
+
end
|
38
|
+
|
39
|
+
after(:create) do |promotion, evaluator|
|
40
|
+
rule = Spree::Promotion::Rules::ItemTotal.create!(
|
41
|
+
preferred_operator: 'gte',
|
42
|
+
preferred_amount: evaluator.item_total_threshold_amount
|
43
|
+
)
|
44
|
+
promotion.rules << rule
|
45
|
+
promotion.save!
|
46
|
+
end
|
47
|
+
end
|
18
48
|
|
19
49
|
end
|
20
50
|
end
|
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: 2.2.
|
4
|
+
version: 2.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sean Schofield
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemerchant
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 1.
|
19
|
+
version: 1.43.1
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 1.
|
26
|
+
version: 1.43.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: acts_as_list
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -112,16 +112,16 @@ dependencies:
|
|
112
112
|
name: friendly_id
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 5.0.
|
117
|
+
version: 5.0.4
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 5.0.
|
124
|
+
version: 5.0.4
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: highline
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -226,14 +226,14 @@ dependencies:
|
|
226
226
|
requirements:
|
227
227
|
- - "~>"
|
228
228
|
- !ruby/object:Gem::Version
|
229
|
-
version: 4.0.
|
229
|
+
version: 4.0.6
|
230
230
|
type: :runtime
|
231
231
|
prerelease: false
|
232
232
|
version_requirements: !ruby/object:Gem::Requirement
|
233
233
|
requirements:
|
234
234
|
- - "~>"
|
235
235
|
- !ruby/object:Gem::Version
|
236
|
-
version: 4.0.
|
236
|
+
version: 4.0.6
|
237
237
|
- !ruby/object:Gem::Dependency
|
238
238
|
name: ransack
|
239
239
|
requirement: !ruby/object:Gem::Requirement
|
@@ -590,6 +590,9 @@ files:
|
|
590
590
|
- db/migrate/20140219060952_add_considered_risky_to_orders.rb
|
591
591
|
- db/migrate/20140307235515_add_user_id_to_spree_credit_cards.rb
|
592
592
|
- db/migrate/20140415041315_add_user_id_created_by_id_index_to_order.rb
|
593
|
+
- db/migrate/20140601011216_set_shipment_total_for_users_upgrading.rb
|
594
|
+
- db/migrate/20140609201656_add_deleted_at_to_spree_promotion_actions.rb
|
595
|
+
- db/migrate/20140616202624_remove_uncaptured_amount_from_spree_payments.rb
|
593
596
|
- db/seeds.rb
|
594
597
|
- lib/generators/spree/custom_user/custom_user_generator.rb
|
595
598
|
- lib/generators/spree/custom_user/templates/authentication_helpers.rb.tt
|
@@ -738,7 +741,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
738
741
|
version: '0'
|
739
742
|
requirements: []
|
740
743
|
rubyforge_project:
|
741
|
-
rubygems_version: 2.2.
|
744
|
+
rubygems_version: 2.2.2
|
742
745
|
signing_key:
|
743
746
|
specification_version: 4
|
744
747
|
summary: The bare bones necessary for Spree.
|