spree_core 5.4.0.beta3 → 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/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 +13 -2
- data/app/models/spree/address.rb +0 -14
- 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 +8 -0
- data/app/models/spree/product.rb +2 -0
- 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/lib/spree/core/engine.rb +2 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree_core.rb +0 -1
- metadata +6 -19
- data/lib/normalize_string.rb +0 -18
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
|
|
@@ -91,6 +91,14 @@ module Spree
|
|
|
91
91
|
joins(:variants_including_master).merge(Spree::Variant.in_stock_or_backorderable)
|
|
92
92
|
end
|
|
93
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
|
|
94
102
|
search_scopes << :in_stock
|
|
95
103
|
|
|
96
104
|
def self.out_of_stock(out_of_stock = true)
|
|
@@ -260,7 +268,7 @@ module Spree
|
|
|
260
268
|
|
|
261
269
|
def self.not_discontinued(only_not_discontinued = true)
|
|
262
270
|
if only_not_discontinued != '0' && only_not_discontinued
|
|
263
|
-
where(discontinue_on: [nil, Time.current..])
|
|
271
|
+
where(discontinue_on: [nil, Time.current.beginning_of_minute..])
|
|
264
272
|
else
|
|
265
273
|
all
|
|
266
274
|
end
|
|
@@ -278,7 +286,10 @@ module Spree
|
|
|
278
286
|
# Can't use add_search_scope for this as it needs a default argument
|
|
279
287
|
def self.available(available_on = nil, currency = nil)
|
|
280
288
|
scope = not_discontinued.where(status: 'active')
|
|
281
|
-
|
|
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
|
|
282
293
|
|
|
283
294
|
unless Spree::Config.show_products_without_price
|
|
284
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/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
|
@@ -64,6 +64,14 @@ module Spree
|
|
|
64
64
|
countries.order(:name).first
|
|
65
65
|
end
|
|
66
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
|
+
|
|
67
75
|
# Returns supported locales as an array, always including default_locale
|
|
68
76
|
#
|
|
69
77
|
# @return [Array<String>]
|
data/app/models/spree/product.rb
CHANGED
|
@@ -220,7 +220,9 @@ module Spree
|
|
|
220
220
|
self.whitelisted_ransackable_associations = %w[taxons stores variants_including_master master variants tags labels
|
|
221
221
|
shipping_category classifications option_types]
|
|
222
222
|
self.whitelisted_ransackable_scopes = %w[not_discontinued search_by_name in_taxon price_between
|
|
223
|
+
price_lte price_gte
|
|
223
224
|
multi_search in_stock out_of_stock with_option_value_ids
|
|
225
|
+
|
|
224
226
|
ascend_by_price descend_by_price]
|
|
225
227
|
|
|
226
228
|
[
|
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
|
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
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spree_core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.4.0.
|
|
4
|
+
version: 5.4.0.beta4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sean Schofield
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date: 2026-03-
|
|
13
|
+
date: 2026-03-04 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: i18n-tasks
|
|
@@ -490,20 +490,6 @@ dependencies:
|
|
|
490
490
|
- - ">="
|
|
491
491
|
- !ruby/object:Gem::Version
|
|
492
492
|
version: '0'
|
|
493
|
-
- !ruby/object:Gem::Dependency
|
|
494
|
-
name: any_ascii
|
|
495
|
-
requirement: !ruby/object:Gem::Requirement
|
|
496
|
-
requirements:
|
|
497
|
-
- - "~>"
|
|
498
|
-
- !ruby/object:Gem::Version
|
|
499
|
-
version: 0.3.2
|
|
500
|
-
type: :runtime
|
|
501
|
-
prerelease: false
|
|
502
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
503
|
-
requirements:
|
|
504
|
-
- - "~>"
|
|
505
|
-
- !ruby/object:Gem::Version
|
|
506
|
-
version: 0.3.2
|
|
507
493
|
- !ruby/object:Gem::Dependency
|
|
508
494
|
name: safely_block
|
|
509
495
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -935,6 +921,7 @@ files:
|
|
|
935
921
|
- app/models/spree/event.rb
|
|
936
922
|
- app/models/spree/exchange.rb
|
|
937
923
|
- app/models/spree/export.rb
|
|
924
|
+
- app/models/spree/exports/coupon_codes.rb
|
|
938
925
|
- app/models/spree/exports/customers.rb
|
|
939
926
|
- app/models/spree/exports/gift_cards.rb
|
|
940
927
|
- app/models/spree/exports/newsletter_subscribers.rb
|
|
@@ -1165,6 +1152,7 @@ files:
|
|
|
1165
1152
|
- app/models/spree/zone.rb
|
|
1166
1153
|
- app/models/spree/zone_member.rb
|
|
1167
1154
|
- app/paginators/spree/shared/paginate.rb
|
|
1155
|
+
- app/presenters/spree/csv/coupon_code_presenter.rb
|
|
1168
1156
|
- app/presenters/spree/csv/customer_presenter.rb
|
|
1169
1157
|
- app/presenters/spree/csv/gift_card_presenter.rb
|
|
1170
1158
|
- app/presenters/spree/csv/metafields_helper.rb
|
|
@@ -1463,7 +1451,6 @@ files:
|
|
|
1463
1451
|
- lib/generators/spree/model_decorator/model_decorator_generator.rb
|
|
1464
1452
|
- lib/generators/spree/model_decorator/templates/model_decorator.rb.tt
|
|
1465
1453
|
- lib/mobility/plugins/store_based_fallbacks.rb
|
|
1466
|
-
- lib/normalize_string.rb
|
|
1467
1454
|
- lib/spree/analytics.rb
|
|
1468
1455
|
- lib/spree/core.rb
|
|
1469
1456
|
- lib/spree/core/components.rb
|
|
@@ -1653,9 +1640,9 @@ licenses:
|
|
|
1653
1640
|
- BSD-3-Clause
|
|
1654
1641
|
metadata:
|
|
1655
1642
|
bug_tracker_uri: https://github.com/spree/spree/issues
|
|
1656
|
-
changelog_uri: https://github.com/spree/spree/releases/tag/v5.4.0.
|
|
1643
|
+
changelog_uri: https://github.com/spree/spree/releases/tag/v5.4.0.beta4
|
|
1657
1644
|
documentation_uri: https://docs.spreecommerce.org/
|
|
1658
|
-
source_code_uri: https://github.com/spree/spree/tree/v5.4.0.
|
|
1645
|
+
source_code_uri: https://github.com/spree/spree/tree/v5.4.0.beta4
|
|
1659
1646
|
post_install_message:
|
|
1660
1647
|
rdoc_options: []
|
|
1661
1648
|
require_paths:
|
data/lib/normalize_string.rb
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
require 'any_ascii'
|
|
2
|
-
|
|
3
|
-
module NormalizeString
|
|
4
|
-
def self.normalize(string)
|
|
5
|
-
return unless string.present?
|
|
6
|
-
|
|
7
|
-
AnyAscii.transliterate(string)
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def self.remove_emoji_and_normalize(string, keep_emoji_when_empty: false)
|
|
11
|
-
return unless string.present?
|
|
12
|
-
|
|
13
|
-
result = AnyAscii.transliterate(string.gsub(/\p{So}/, ''))
|
|
14
|
-
return result if result.present? || !keep_emoji_when_empty
|
|
15
|
-
|
|
16
|
-
normalize(string)
|
|
17
|
-
end
|
|
18
|
-
end
|