spree_core 5.4.0.beta2 → 5.4.0.beta4
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/finders/spree/products/find.rb +1 -14
- data/app/jobs/spree/exports/generate_job.rb +1 -1
- data/app/jobs/spree/reports/generate_job.rb +1 -1
- data/app/models/concerns/spree/product_scopes.rb +32 -4
- data/app/models/spree/address.rb +0 -14
- data/app/models/spree/api_key.rb +8 -5
- data/app/models/spree/country.rb +2 -23
- data/app/models/spree/coupon_code.rb +6 -1
- data/app/models/spree/current.rb +3 -2
- data/app/models/spree/exports/coupon_codes.rb +18 -0
- data/app/models/spree/market.rb +9 -2
- data/app/models/spree/market_country.rb +17 -0
- data/app/models/spree/newsletter_subscriber.rb +0 -3
- data/app/models/spree/order.rb +2 -5
- data/app/models/spree/product.rb +3 -13
- data/app/models/spree/reimbursement.rb +0 -2
- data/app/models/spree/shipment.rb +0 -1
- data/app/models/spree/shipment_handler.rb +0 -2
- data/app/models/spree/taxon.rb +10 -10
- data/app/models/spree/variant.rb +1 -1
- data/app/models/spree/zone.rb +21 -9
- data/app/presenters/spree/csv/coupon_code_presenter.rb +31 -0
- data/app/services/spree/newsletter/subscribe.rb +2 -2
- data/app/subscribers/spree/invitation_email_subscriber.rb +1 -1
- data/config/locales/en.yml +1 -0
- data/lib/spree/core/engine.rb +2 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +0 -1
- data/lib/spree_core.rb +0 -1
- data/lib/tasks/cli.rake +50 -0
- metadata +7 -29
- data/app/models/concerns/spree/filter_param.rb +0 -21
- data/app/models/spree/newsletter_subscriber/emails.rb +0 -12
- data/app/models/spree/order/emails.rb +0 -24
- data/app/models/spree/reimbursement/emails.rb +0 -11
- data/app/models/spree/shipment/emails.rb +0 -12
- data/lib/generators/spree/cursor_rules/cursor_rules_generator.rb +0 -19
- data/lib/generators/spree/cursor_rules/templates/spree_rules.mdc +0 -385
- data/lib/normalize_string.rb +0 -18
- data/lib/spree/core/importer/order.rb +0 -244
- data/lib/spree/core/importer/product.rb +0 -67
- data/lib/spree/core/importer.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 29b95e3e3222214cdeef8094a1a9553636c875d88857244241431196d06399d2
|
|
4
|
+
data.tar.gz: 93c9f4d387fce7ba5e2e9f4b6454f9c46f1b8a15cfe180a16739c17bf76a5125
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5c8a23c3edd35dacb0493c5435e28d114fc2611b4b25a0d85b4b5e4579f38402fb61a3a65a9f3b361fae8f67d5f58ac73984b6ab2cd4bcbb0326813589a18330
|
|
7
|
+
data.tar.gz: 1fabd1160061e412e2e9a4a1e92083686938a5313c3b29193e410bc07d6118d60af4bd7c2951794273c20f8b053f1dfc5acba8dfe748a722f5895aacc17d33d9
|
|
@@ -22,14 +22,8 @@ module Spree
|
|
|
22
22
|
@in_stock = params.dig(:filter, :in_stock)
|
|
23
23
|
@backorderable = params.dig(:filter, :backorderable)
|
|
24
24
|
@purchasable = params.dig(:filter, :purchasable)
|
|
25
|
-
@out_of_stock = params.dig(:filter, :out_of_stock).to_b
|
|
26
25
|
@tags = params.dig(:filter, :tags).to_s.split(',').compact_blank
|
|
27
26
|
@vendor_ids = params.dig(:filter, :vendor_ids)&.split(',')&.compact_blank || []
|
|
28
|
-
|
|
29
|
-
if @purchasable.present? && @out_of_stock.present?
|
|
30
|
-
@purchasable = false
|
|
31
|
-
@out_of_stock = false
|
|
32
|
-
end
|
|
33
27
|
end
|
|
34
28
|
|
|
35
29
|
def execute
|
|
@@ -50,7 +44,6 @@ module Spree
|
|
|
50
44
|
products = show_only_stock(products)
|
|
51
45
|
products = show_only_backorderable(products)
|
|
52
46
|
products = show_only_purchasable(products)
|
|
53
|
-
products = show_only_out_of_stock(products)
|
|
54
47
|
products = by_taxonomies(products)
|
|
55
48
|
products = ordered(products)
|
|
56
49
|
products = by_vendor_ids(products)
|
|
@@ -62,7 +55,7 @@ module Spree
|
|
|
62
55
|
|
|
63
56
|
attr_reader :ids, :skus, :price, :currency, :taxons, :concat_taxons, :name, :options, :option_value_ids, :scope,
|
|
64
57
|
:sort_by, :deleted, :discontinued, :store, :in_stock, :backorderable, :purchasable, :tags,
|
|
65
|
-
:query, :vendor_ids, :
|
|
58
|
+
:query, :vendor_ids, :slug, :taxonomies
|
|
66
59
|
|
|
67
60
|
def query?
|
|
68
61
|
query.present?
|
|
@@ -294,12 +287,6 @@ module Spree
|
|
|
294
287
|
products.in_stock_or_backorderable
|
|
295
288
|
end
|
|
296
289
|
|
|
297
|
-
def show_only_out_of_stock(products)
|
|
298
|
-
return products unless out_of_stock.present?
|
|
299
|
-
|
|
300
|
-
products.out_of_stock
|
|
301
|
-
end
|
|
302
|
-
|
|
303
290
|
def map_prices(prices)
|
|
304
291
|
prices.map do |price|
|
|
305
292
|
price == 'Infinity' ? BigDecimal::INFINITY : price.to_f
|
|
@@ -81,9 +81,34 @@ module Spree
|
|
|
81
81
|
where(Price.table_name => { amount: price.. })
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
add_search_scope
|
|
85
|
-
|
|
84
|
+
# Can't use add_search_scope for this as it needs a default argument
|
|
85
|
+
# Ransack calls with '1' to activate, '0' or nil to skip
|
|
86
|
+
# In Ruby code: in_stock(true) for in-stock, in_stock(false) for out-of-stock
|
|
87
|
+
def self.in_stock(in_stock = true)
|
|
88
|
+
if in_stock == '0' || !in_stock
|
|
89
|
+
all
|
|
90
|
+
else
|
|
91
|
+
joins(:variants_including_master).merge(Spree::Variant.in_stock_or_backorderable)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
add_search_scope :price_lte do |price|
|
|
96
|
+
where(Price.table_name => { amount: ..price })
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
add_search_scope :price_gte do |price|
|
|
100
|
+
where(Price.table_name => { amount: price.. })
|
|
101
|
+
end
|
|
102
|
+
search_scopes << :in_stock
|
|
103
|
+
|
|
104
|
+
def self.out_of_stock(out_of_stock = true)
|
|
105
|
+
if out_of_stock == '0' || !out_of_stock
|
|
106
|
+
all
|
|
107
|
+
else
|
|
108
|
+
where.not(id: joins(:variants_including_master).merge(Spree::Variant.in_stock_or_backorderable))
|
|
109
|
+
end
|
|
86
110
|
end
|
|
111
|
+
search_scopes << :out_of_stock
|
|
87
112
|
|
|
88
113
|
add_search_scope :backorderable do
|
|
89
114
|
joins(:variants_including_master).merge(Spree::Variant.backorderable)
|
|
@@ -243,7 +268,7 @@ module Spree
|
|
|
243
268
|
|
|
244
269
|
def self.not_discontinued(only_not_discontinued = true)
|
|
245
270
|
if only_not_discontinued != '0' && only_not_discontinued
|
|
246
|
-
where(discontinue_on: [nil, Time.current..])
|
|
271
|
+
where(discontinue_on: [nil, Time.current.beginning_of_minute..])
|
|
247
272
|
else
|
|
248
273
|
all
|
|
249
274
|
end
|
|
@@ -261,7 +286,10 @@ module Spree
|
|
|
261
286
|
# Can't use add_search_scope for this as it needs a default argument
|
|
262
287
|
def self.available(available_on = nil, currency = nil)
|
|
263
288
|
scope = not_discontinued.where(status: 'active')
|
|
264
|
-
|
|
289
|
+
if available_on
|
|
290
|
+
available_on = available_on.beginning_of_minute if available_on.respond_to?(:beginning_of_minute)
|
|
291
|
+
scope = scope.where("#{Product.quoted_table_name}.available_on <= ?", available_on)
|
|
292
|
+
end
|
|
265
293
|
|
|
266
294
|
unless Spree::Config.show_products_without_price
|
|
267
295
|
currency ||= Spree::Store.default.default_currency
|
data/app/models/spree/address.rb
CHANGED
|
@@ -27,8 +27,6 @@ module Spree
|
|
|
27
27
|
# those attributes depending of the logic of their applications
|
|
28
28
|
ADDRESS_FIELDS = %w(firstname lastname company address1 address2 city state zipcode country phone)
|
|
29
29
|
EXCLUDED_KEYS_FOR_COMPARISON = %w(id updated_at created_at deleted_at label user_id public_metadata private_metadata)
|
|
30
|
-
FIELDS_TO_NORMALIZE = %w(firstname lastname phone alternative_phone company address1 address2 city zipcode)
|
|
31
|
-
|
|
32
30
|
if defined?(Spree::Security::Addresses)
|
|
33
31
|
include Spree::Security::Addresses
|
|
34
32
|
end
|
|
@@ -53,7 +51,6 @@ module Spree
|
|
|
53
51
|
before_validation :normalize_country
|
|
54
52
|
before_validation :normalize_state
|
|
55
53
|
before_validation :clear_invalid_state_entities, if: -> { country.present? }, on: :update
|
|
56
|
-
before_validation :remove_emoji_and_normalize
|
|
57
54
|
|
|
58
55
|
after_create :set_user_attributes, if: -> { user.present? }
|
|
59
56
|
|
|
@@ -294,17 +291,6 @@ module Spree
|
|
|
294
291
|
end
|
|
295
292
|
end
|
|
296
293
|
|
|
297
|
-
def remove_emoji_and_normalize
|
|
298
|
-
attributes_to_normalize = attributes.slice(*FIELDS_TO_NORMALIZE)
|
|
299
|
-
normalized_attributes = attributes_to_normalize.compact_blank.deep_transform_values do |value|
|
|
300
|
-
NormalizeString.remove_emoji_and_normalize(value.to_s).strip
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
normalized_attributes.transform_keys! { |key| key.gsub('original_', '') } if defined?(Spree::Security::Addresses)
|
|
304
|
-
|
|
305
|
-
assign_attributes(normalized_attributes)
|
|
306
|
-
end
|
|
307
|
-
|
|
308
294
|
def set_user_attributes
|
|
309
295
|
if user.name.blank?
|
|
310
296
|
user.first_name = firstname
|
data/app/models/spree/api_key.rb
CHANGED
|
@@ -6,11 +6,14 @@ module Spree
|
|
|
6
6
|
PREFIXES = { 'publishable' => 'pk_', 'secret' => 'sk_' }.freeze
|
|
7
7
|
TOKEN_LENGTH = 24
|
|
8
8
|
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
|
|
9
|
+
# Returns the raw token value. For publishable keys this is the persisted
|
|
10
|
+
# +token+ column. For secret keys it is only available in memory immediately
|
|
11
|
+
# after creation (not persisted).
|
|
12
|
+
#
|
|
13
|
+
# @return [String, nil]
|
|
14
|
+
def plaintext_token
|
|
15
|
+
publishable? ? token : @plaintext_token
|
|
16
|
+
end
|
|
14
17
|
|
|
15
18
|
belongs_to :store, class_name: 'Spree::Store'
|
|
16
19
|
belongs_to :created_by, polymorphic: true, optional: true
|
data/app/models/spree/country.rb
CHANGED
|
@@ -38,29 +38,8 @@ module Spree
|
|
|
38
38
|
iso.upcase.chars.map { |c| (c.ord + 127397).chr(Encoding::UTF_8) }.join
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
44
|
-
# @return [String, nil] currency code (e.g., 'USD', 'EUR') or nil if no market found
|
|
45
|
-
def market_currency
|
|
46
|
-
current_market&.currency
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Returns the default locale for this country from its market in the current store.
|
|
50
|
-
# Looks up which market contains this country and returns that market's default locale.
|
|
51
|
-
#
|
|
52
|
-
# @return [String, nil] locale code (e.g., 'en', 'de') or nil if no market found
|
|
53
|
-
def market_locale
|
|
54
|
-
current_market&.default_locale
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# Returns the supported locales for this country from its market in the current store.
|
|
58
|
-
#
|
|
59
|
-
# @return [Array<String>] locale codes (e.g., ['en', 'fr']) or empty array if no market found
|
|
60
|
-
def market_supported_locales
|
|
61
|
-
current_market&.supported_locales_list || []
|
|
62
|
-
end
|
|
63
|
-
|
|
41
|
+
# Lookups Market for Country for the current Store
|
|
42
|
+
# @return [Spree::Market, nil]
|
|
64
43
|
def current_market
|
|
65
44
|
@current_market ||= Spree::Current.store&.market_for_country(self)
|
|
66
45
|
end
|
|
@@ -19,7 +19,8 @@ module Spree
|
|
|
19
19
|
validates :code, presence: true, uniqueness: { scope: spree_base_uniqueness_scope, conditions: -> { where(deleted_at: nil) } }
|
|
20
20
|
validates :state, :promotion, presence: true
|
|
21
21
|
|
|
22
|
-
self.whitelisted_ransackable_attributes = %w[state code]
|
|
22
|
+
self.whitelisted_ransackable_attributes = %w[state code promotion_id]
|
|
23
|
+
self.whitelisted_ransackable_associations = %w[promotion]
|
|
23
24
|
|
|
24
25
|
def self.used?(code)
|
|
25
26
|
used_with_code(code).any?
|
|
@@ -36,5 +37,9 @@ module Spree
|
|
|
36
37
|
def display_code
|
|
37
38
|
code.upcase
|
|
38
39
|
end
|
|
40
|
+
|
|
41
|
+
def to_csv(_store = nil)
|
|
42
|
+
Spree::CSV::CouponCodePresenter.new(self).call
|
|
43
|
+
end
|
|
39
44
|
end
|
|
40
45
|
end
|
data/app/models/spree/current.rb
CHANGED
|
@@ -34,10 +34,11 @@ module Spree
|
|
|
34
34
|
super || market&.default_locale || store&.default_locale
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
# Returns the current tax zone
|
|
37
|
+
# Returns the current tax zone.
|
|
38
|
+
# Fallback: market's tax zone (from default country) -> global default tax zone.
|
|
38
39
|
# @return [Spree::Zone, nil]
|
|
39
40
|
def zone
|
|
40
|
-
super || default_tax_zone
|
|
41
|
+
super || market&.tax_zone || default_tax_zone
|
|
41
42
|
end
|
|
42
43
|
|
|
43
44
|
# Returns the default tax zone (memoized per request).
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Exports
|
|
3
|
+
class CouponCodes < Spree::Export
|
|
4
|
+
def csv_headers
|
|
5
|
+
Spree::CSV::CouponCodePresenter::HEADERS
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def scope_includes
|
|
9
|
+
[:promotion, :order]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def scope
|
|
13
|
+
model_class.joins(promotion: :stores).where(spree_stores: { id: store.id })
|
|
14
|
+
.accessible_by(current_ability)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
data/app/models/spree/market.rb
CHANGED
|
@@ -44,8 +44,7 @@ module Spree
|
|
|
44
44
|
joins(:market_countries)
|
|
45
45
|
.where(store_id: store.id)
|
|
46
46
|
.where(spree_market_countries: { country_id: country.id })
|
|
47
|
-
.
|
|
48
|
-
.first
|
|
47
|
+
.take
|
|
49
48
|
end
|
|
50
49
|
|
|
51
50
|
# Returns the default market for a store, or falls back to the first by position
|
|
@@ -65,6 +64,14 @@ module Spree
|
|
|
65
64
|
countries.order(:name).first
|
|
66
65
|
end
|
|
67
66
|
|
|
67
|
+
# Returns the tax zone matching this market's default country.
|
|
68
|
+
# Used by Spree::Current to determine the browsing tax zone before a customer enters an address.
|
|
69
|
+
#
|
|
70
|
+
# @return [Spree::Zone, nil]
|
|
71
|
+
def tax_zone
|
|
72
|
+
@tax_zone ||= Spree::Zone.match(default_country)
|
|
73
|
+
end
|
|
74
|
+
|
|
68
75
|
# Returns supported locales as an array, always including default_locale
|
|
69
76
|
#
|
|
70
77
|
# @return [Array<String>]
|
|
@@ -8,6 +8,7 @@ module Spree
|
|
|
8
8
|
validates :market, :country, presence: true
|
|
9
9
|
validates :country_id, uniqueness: { scope: :market_id }
|
|
10
10
|
validate :country_covered_by_shipping_zone
|
|
11
|
+
validate :country_unique_per_store
|
|
11
12
|
|
|
12
13
|
private
|
|
13
14
|
|
|
@@ -21,5 +22,21 @@ module Spree
|
|
|
21
22
|
errors.add(:country, :not_in_shipping_zone)
|
|
22
23
|
end
|
|
23
24
|
end
|
|
25
|
+
|
|
26
|
+
def country_unique_per_store
|
|
27
|
+
return if market.blank? || country.blank?
|
|
28
|
+
|
|
29
|
+
store = market.store
|
|
30
|
+
return if store.blank?
|
|
31
|
+
|
|
32
|
+
existing = self.class.joins(:market)
|
|
33
|
+
.where(country_id: country_id)
|
|
34
|
+
.where(spree_markets: { store_id: store.id, deleted_at: nil })
|
|
35
|
+
.where.not(id: id)
|
|
36
|
+
|
|
37
|
+
if existing.exists?
|
|
38
|
+
errors.add(:country, :already_in_market)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
24
41
|
end
|
|
25
42
|
end
|
data/app/models/spree/order.rb
CHANGED
|
@@ -3,7 +3,6 @@ require_dependency 'spree/order/currency_updater'
|
|
|
3
3
|
require_dependency 'spree/order/digital'
|
|
4
4
|
require_dependency 'spree/order/payments'
|
|
5
5
|
require_dependency 'spree/order/store_credit'
|
|
6
|
-
require_dependency 'spree/order/emails'
|
|
7
6
|
require_dependency 'spree/order/gift_card'
|
|
8
7
|
|
|
9
8
|
module Spree
|
|
@@ -22,7 +21,6 @@ module Spree
|
|
|
22
21
|
include Spree::Order::Payments
|
|
23
22
|
include Spree::Order::StoreCredit
|
|
24
23
|
include Spree::Order::AddressBook
|
|
25
|
-
include Spree::Order::Emails
|
|
26
24
|
include Spree::Order::Webhooks
|
|
27
25
|
include Spree::Core::NumberGenerator.new(prefix: 'R')
|
|
28
26
|
include Spree::Order::GiftCard
|
|
@@ -311,9 +309,9 @@ module Spree
|
|
|
311
309
|
# @return [Boolean]
|
|
312
310
|
def order_refunded?
|
|
313
311
|
return false if item_count.zero?
|
|
312
|
+
return false if refunds_total.zero?
|
|
314
313
|
|
|
315
|
-
|
|
316
|
-
refunds_total == total_minus_store_credits - additional_tax_total.abs
|
|
314
|
+
payment_state.in?(%w[void failed]) || refunds_total == total_minus_store_credits - additional_tax_total.abs
|
|
317
315
|
end
|
|
318
316
|
|
|
319
317
|
def refunds_total
|
|
@@ -965,7 +963,6 @@ module Spree
|
|
|
965
963
|
payments.store_credits.pending.each(&:void!)
|
|
966
964
|
end
|
|
967
965
|
|
|
968
|
-
send_cancel_email
|
|
969
966
|
update_with_updater!
|
|
970
967
|
send_order_canceled_webhook
|
|
971
968
|
publish_order_canceled_event
|
data/app/models/spree/product.rb
CHANGED
|
@@ -197,18 +197,6 @@ module Spree
|
|
|
197
197
|
scope :by_source, ->(source) { send(source) }
|
|
198
198
|
scope :paused, -> { where(status: 'paused') }
|
|
199
199
|
scope :published, -> { where(status: 'active') }
|
|
200
|
-
scope :in_stock_items, -> { joins(:variants).merge(Spree::Variant.in_stock_or_backorderable) }
|
|
201
|
-
scope :out_of_stock_items, lambda {
|
|
202
|
-
joins(variants_including_master: :stock_items).
|
|
203
|
-
where(spree_variants: { track_inventory: true }).
|
|
204
|
-
where.not(id: Spree::Variant.where(track_inventory: false).pluck(:product_id).uniq).
|
|
205
|
-
where(spree_stock_items: { backorderable: false }).
|
|
206
|
-
group(:id).
|
|
207
|
-
having("SUM(#{Spree::StockItem.table_name}.count_on_hand) <= 0")
|
|
208
|
-
}
|
|
209
|
-
scope :out_of_stock, lambda {
|
|
210
|
-
joins(:stock_items).where("#{Spree::Variant.table_name}.track_inventory = ? OR #{Spree::StockItem.table_name}.count_on_hand <= ?", false, 0)
|
|
211
|
-
}
|
|
212
200
|
|
|
213
201
|
attr_accessor :option_values_hash
|
|
214
202
|
|
|
@@ -232,7 +220,9 @@ module Spree
|
|
|
232
220
|
self.whitelisted_ransackable_associations = %w[taxons stores variants_including_master master variants tags labels
|
|
233
221
|
shipping_category classifications option_types]
|
|
234
222
|
self.whitelisted_ransackable_scopes = %w[not_discontinued search_by_name in_taxon price_between
|
|
235
|
-
|
|
223
|
+
price_lte price_gte
|
|
224
|
+
multi_search in_stock out_of_stock with_option_value_ids
|
|
225
|
+
|
|
236
226
|
ascend_by_price descend_by_price]
|
|
237
227
|
|
|
238
228
|
[
|
|
@@ -4,7 +4,6 @@ module Spree
|
|
|
4
4
|
|
|
5
5
|
include Spree::Core::NumberGenerator.new(prefix: 'RI', length: 9)
|
|
6
6
|
include Spree::NumberIdentifier
|
|
7
|
-
include Spree::Reimbursement::Emails
|
|
8
7
|
|
|
9
8
|
class IncompleteReimbursementError < StandardError; end
|
|
10
9
|
|
|
@@ -116,7 +115,6 @@ module Spree
|
|
|
116
115
|
if unpaid_amount_within_tolerance?
|
|
117
116
|
reimbursed!
|
|
118
117
|
reimbursement_success_hooks.each { |h| h.call self }
|
|
119
|
-
send_reimbursement_email
|
|
120
118
|
else
|
|
121
119
|
errored!
|
|
122
120
|
reimbursement_failure_hooks.each { |h| h.call self }
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
class ShipmentHandler
|
|
3
|
-
include Spree::Shipment::Emails
|
|
4
3
|
include Spree::IntegrationsConcern
|
|
5
4
|
|
|
6
5
|
class << self
|
|
@@ -25,7 +24,6 @@ module Spree
|
|
|
25
24
|
@shipment.process_order_payments if Spree::Config[:auto_capture_on_dispatch]
|
|
26
25
|
@shipment.touch :shipped_at
|
|
27
26
|
update_order_shipment_state
|
|
28
|
-
send_shipped_email
|
|
29
27
|
end
|
|
30
28
|
|
|
31
29
|
protected
|
data/app/models/spree/taxon.rb
CHANGED
|
@@ -5,16 +5,16 @@ module Spree
|
|
|
5
5
|
has_prefix_id :txn # Spree-specific: taxon
|
|
6
6
|
|
|
7
7
|
RULES_MATCH_POLICIES = %w[all any].freeze
|
|
8
|
-
SORT_ORDERS =
|
|
9
|
-
manual
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
]
|
|
8
|
+
SORT_ORDERS = [
|
|
9
|
+
'manual',
|
|
10
|
+
'best_selling',
|
|
11
|
+
'price asc',
|
|
12
|
+
'price desc',
|
|
13
|
+
'available_on desc',
|
|
14
|
+
'available_on asc',
|
|
15
|
+
'name asc',
|
|
16
|
+
'name desc'
|
|
17
|
+
].freeze
|
|
18
18
|
|
|
19
19
|
include Spree::TranslatableResource
|
|
20
20
|
include Spree::TranslatableResourceSlug
|
data/app/models/spree/variant.rb
CHANGED
data/app/models/spree/zone.rb
CHANGED
|
@@ -52,15 +52,27 @@ module Spree
|
|
|
52
52
|
|
|
53
53
|
# Returns the matching zone with the highest priority zone type (State, Country, Zone.)
|
|
54
54
|
# Returns nil in the case of no matches.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
55
|
+
# Accepts either an address (with country_id/state_id) or a Spree::Country directly.
|
|
56
|
+
def self.match(address_or_country)
|
|
57
|
+
return unless address_or_country
|
|
58
|
+
|
|
59
|
+
if address_or_country.is_a?(Spree::Country)
|
|
60
|
+
country_id = address_or_country.id
|
|
61
|
+
state_id = nil
|
|
62
|
+
else
|
|
63
|
+
country_id = address_or_country.country_id
|
|
64
|
+
state_id = address_or_country.state_id
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
matches = includes(:zone_members).
|
|
68
|
+
order('spree_zones.zone_members_count', 'spree_zones.created_at').
|
|
69
|
+
where("(spree_zone_members.zoneable_type = 'Spree::Country' AND " \
|
|
70
|
+
'spree_zone_members.zoneable_id = ?) OR ' \
|
|
71
|
+
"(spree_zone_members.zoneable_type = 'Spree::State' AND " \
|
|
72
|
+
'spree_zone_members.zoneable_id = ?)', country_id, state_id).
|
|
73
|
+
references(:zones)
|
|
74
|
+
|
|
75
|
+
return if matches.empty?
|
|
64
76
|
|
|
65
77
|
%w[state country].each do |zone_kind|
|
|
66
78
|
if match = matches.detect { |zone| zone_kind == zone.kind }
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module CSV
|
|
3
|
+
class CouponCodePresenter
|
|
4
|
+
HEADERS = [
|
|
5
|
+
'Code',
|
|
6
|
+
'State',
|
|
7
|
+
'Promotion Name',
|
|
8
|
+
'Order Number',
|
|
9
|
+
'Created At',
|
|
10
|
+
'Updated At'
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
13
|
+
def initialize(coupon_code)
|
|
14
|
+
@coupon_code = coupon_code
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
attr_accessor :coupon_code
|
|
18
|
+
|
|
19
|
+
def call
|
|
20
|
+
[
|
|
21
|
+
coupon_code.display_code,
|
|
22
|
+
coupon_code.state,
|
|
23
|
+
coupon_code.promotion&.name,
|
|
24
|
+
coupon_code.order&.number,
|
|
25
|
+
coupon_code.created_at&.strftime('%Y-%m-%d %H:%M:%S'),
|
|
26
|
+
coupon_code.updated_at&.strftime('%Y-%m-%d %H:%M:%S')
|
|
27
|
+
]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -19,8 +19,8 @@ module Spree
|
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
#
|
|
23
|
-
subscriber.
|
|
22
|
+
# publish event to trigger email delivery via subscriber
|
|
23
|
+
subscriber.publish_event('newsletter_subscriber.subscribed') unless subscriber.verified?
|
|
24
24
|
subscriber
|
|
25
25
|
end
|
|
26
26
|
|
data/config/locales/en.yml
CHANGED
|
@@ -292,6 +292,7 @@ en:
|
|
|
292
292
|
spree/market_country:
|
|
293
293
|
attributes:
|
|
294
294
|
country:
|
|
295
|
+
already_in_market: is already assigned to another market in this store
|
|
295
296
|
not_in_shipping_zone: is not covered by any shipping zone. Please set up a shipping zone first.
|
|
296
297
|
spree/payment:
|
|
297
298
|
attributes:
|
data/lib/spree/core/engine.rb
CHANGED
|
@@ -180,7 +180,8 @@ module Spree
|
|
|
180
180
|
Spree::Exports::Orders,
|
|
181
181
|
Spree::Exports::Customers,
|
|
182
182
|
Spree::Exports::GiftCards,
|
|
183
|
-
Spree::Exports::NewsletterSubscribers
|
|
183
|
+
Spree::Exports::NewsletterSubscribers,
|
|
184
|
+
Spree::Exports::CouponCodes
|
|
184
185
|
]
|
|
185
186
|
|
|
186
187
|
Rails.application.config.spree.import_types = [
|
data/lib/spree/core/version.rb
CHANGED
data/lib/spree/core.rb
CHANGED
|
@@ -427,7 +427,6 @@ require 'spree/events'
|
|
|
427
427
|
require 'spree/webhooks'
|
|
428
428
|
|
|
429
429
|
require 'spree/core/partials'
|
|
430
|
-
require 'spree/core/importer'
|
|
431
430
|
require 'spree/core/controller_helpers/auth'
|
|
432
431
|
require 'spree/core/controller_helpers/common'
|
|
433
432
|
require 'spree/core/controller_helpers/order'
|