spree_core 2.2.2 → 2.2.3
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/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.
|