workarea-core 3.5.17 → 3.5.22
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/controllers/workarea/current_tracking.rb +6 -2
- data/app/controllers/workarea/impersonation.rb +4 -2
- data/app/middleware/workarea/application_middleware.rb +5 -2
- data/app/models/workarea/metrics/user.rb +18 -8
- data/app/models/workarea/order/item.rb +4 -4
- data/app/models/workarea/release.rb +8 -0
- data/app/models/workarea/search/admin/inventory_sku.rb +5 -1
- data/app/models/workarea/search/storefront.rb +1 -5
- data/app/models/workarea/search/storefront/product.rb +1 -14
- data/app/models/workarea/shipping/service.rb +12 -5
- data/app/models/workarea/tax/rate.rb +3 -1
- data/app/queries/workarea/product_releases.rb +1 -11
- data/app/queries/workarea/search/admin_search.rb +4 -0
- data/app/queries/workarea/search/admin_sorting.rb +1 -1
- data/app/queries/workarea/search/product_entries.rb +12 -6
- data/app/workers/workarea/update_email.rb +33 -0
- data/config/initializers/00_configuration.rb +23 -8
- data/config/initializers/05_scheduled_jobs.rb +1 -1
- data/config/initializers/22_session_store.rb +1 -1
- data/config/locales/en.yml +1 -0
- data/lib/generators/workarea/install/templates/initializer.rb.erb +0 -12
- data/lib/tasks/cache.rake +3 -33
- data/lib/tasks/help.rake +4 -43
- data/lib/tasks/insights.rake +3 -35
- data/lib/tasks/migrate.rake +3 -96
- data/lib/tasks/search.rake +6 -68
- data/lib/tasks/services.rake +4 -54
- data/lib/workarea.rb +10 -0
- data/lib/workarea/changelog.rake +1 -1
- data/lib/workarea/configuration.rb +4 -3
- data/lib/workarea/configuration/administrable_options.rb +2 -1
- data/lib/workarea/core/engine.rb +4 -0
- data/lib/workarea/scheduled_jobs.rb +1 -1
- data/lib/workarea/tasks/cache.rb +43 -0
- data/lib/workarea/tasks/help.rb +55 -0
- data/lib/workarea/tasks/insights.rb +47 -0
- data/lib/workarea/tasks/migrate.rb +106 -0
- data/lib/workarea/tasks/search.rb +105 -0
- data/lib/workarea/tasks/services.rb +71 -0
- data/lib/workarea/version.rb +1 -1
- data/lib/workarea/visit.rb +8 -1
- data/lib/workarea/warnings.rb +1 -1
- data/test/generators/workarea/install_generator_test.rb +0 -2
- data/test/integration/workarea/authentication_test.rb +2 -1
- data/test/lib/workarea/scheduled_jobs_test.rb +1 -5
- data/test/models/workarea/data_file/csv_test.rb +2 -1
- data/test/models/workarea/metrics/user_test.rb +55 -52
- data/test/models/workarea/order/item_test.rb +9 -0
- data/test/models/workarea/shipping/service_test.rb +26 -0
- data/test/queries/workarea/search/admin_search_test.rb +10 -0
- data/test/workers/workarea/status_reporter_test.rb +3 -1
- data/test/workers/workarea/update_email_test.rb +39 -0
- metadata +10 -4
- data/app/workers/workarea/update_payment_profile_email.rb +0 -22
- data/test/workers/workarea/update_payment_profile_email_test.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 48dfcf76f720a117fd8f3a16cdbef856816837692dc53f731b38729c5d37b9ef
|
4
|
+
data.tar.gz: a1ffa660f618f5d1b428ce4db9c6d768f0a12c3490ea45f02d699fa4b5ff441f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 509b598d21369c93345837d160e2a95d271c4c0d06276192f050a2997badec0b1542a012be9c1ed10d7bb176816372825abc08370d8fb67b3cd961a96ecb6246
|
7
|
+
data.tar.gz: 0cf582e5e981a1524f7b1cb2229f542c2d99f8b152802386aa68a42a09de7c84602ee8c07659011ecc3a1bec1ca6ddcfdb85c2e7aa8ecdcf6333c42808b81027
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Workarea
|
2
2
|
module CurrentTracking
|
3
3
|
extend ActiveSupport::Concern
|
4
|
-
include HttpCaching
|
5
4
|
|
6
5
|
included do
|
7
6
|
before_action :ensure_current_metrics
|
@@ -27,7 +26,12 @@ module Workarea
|
|
27
26
|
if email.blank?
|
28
27
|
cookies.delete(:email)
|
29
28
|
elsif email != cookies.signed[:email]
|
30
|
-
|
29
|
+
unless impersonating?
|
30
|
+
Metrics::User
|
31
|
+
.find_or_initialize_by(id: email)
|
32
|
+
.merge_views!(current_visit&.metrics)
|
33
|
+
end
|
34
|
+
|
31
35
|
cookies.permanent.signed[:email] = email
|
32
36
|
end
|
33
37
|
|
@@ -15,10 +15,11 @@ module Workarea
|
|
15
15
|
session[:user_id] = user.id.to_s
|
16
16
|
|
17
17
|
user.mark_impersonated_by!(current_user)
|
18
|
-
|
18
|
+
update_tracking!(email: user.email)
|
19
19
|
end
|
20
20
|
|
21
21
|
def stop_impersonation
|
22
|
+
update_tracking!(email: current_admin.email)
|
22
23
|
session[:user_id] = current_admin.id.to_s
|
23
24
|
session.delete(:admin_id)
|
24
25
|
end
|
@@ -39,7 +40,8 @@ module Workarea
|
|
39
40
|
end
|
40
41
|
|
41
42
|
def current_impersonation
|
42
|
-
@current_impersonation
|
43
|
+
return @current_impersonation if defined?(@current_impersonation)
|
44
|
+
@current_impersonation = User.find(session[:user_id]) rescue nil
|
43
45
|
end
|
44
46
|
|
45
47
|
def admin_browse_as_guest
|
@@ -1,12 +1,15 @@
|
|
1
1
|
module Workarea
|
2
2
|
class ApplicationMiddleware
|
3
|
+
ASSET_REGEX = /(jpe?g|png|ico|gif|bmp|webp|tif?f|css|js|svg|otf|ttf|woff|woff2)$/
|
4
|
+
|
3
5
|
def initialize(app)
|
4
6
|
@app = app
|
5
7
|
end
|
6
8
|
|
7
9
|
def call(env)
|
8
10
|
request = Rack::Request.new(env)
|
9
|
-
|
11
|
+
env['workarea.asset_request'] = request.path =~ ASSET_REGEX
|
12
|
+
return @app.call(env) if env['workarea.asset_request']
|
10
13
|
|
11
14
|
set_locale(env, request)
|
12
15
|
setup_environment(env, request)
|
@@ -25,7 +28,7 @@ module Workarea
|
|
25
28
|
env['workarea.visit'] = Visit.new(env)
|
26
29
|
env['workarea.cache_varies'] = Cache::Varies.new(env['workarea.visit']).to_s
|
27
30
|
env['rack-cache.cache_key'] = Cache::RackCacheKey
|
28
|
-
env['rack-cache.force-pass'] = env['workarea.visit'].admin?
|
31
|
+
env['rack-cache.force-pass'] = env['workarea.visit'].admin? && !env['workarea.asset_request']
|
29
32
|
end
|
30
33
|
|
31
34
|
def set_segment_request_headers(env)
|
@@ -110,6 +110,8 @@ module Workarea
|
|
110
110
|
end
|
111
111
|
|
112
112
|
def merge!(other)
|
113
|
+
return if other.blank?
|
114
|
+
|
113
115
|
# To recalculate average_order_value
|
114
116
|
self.orders += other.orders
|
115
117
|
self.revenue += other.revenue
|
@@ -132,14 +134,8 @@ module Workarea
|
|
132
134
|
update['$max'] = { last_order_at: other.last_order_at.utc } if other.last_order_at.present?
|
133
135
|
|
134
136
|
self.class.collection.update_one({ _id: id }, update, upsert: true)
|
137
|
+
other.delete
|
135
138
|
|
136
|
-
self.class.save_affinity(
|
137
|
-
id: id,
|
138
|
-
action: 'viewed',
|
139
|
-
product_ids: other.viewed.product_ids,
|
140
|
-
category_ids: other.viewed.category_ids,
|
141
|
-
search_ids: other.viewed.search_ids
|
142
|
-
)
|
143
139
|
self.class.save_affinity(
|
144
140
|
id: id,
|
145
141
|
action: 'purchased',
|
@@ -148,7 +144,21 @@ module Workarea
|
|
148
144
|
search_ids: other.purchased.search_ids
|
149
145
|
)
|
150
146
|
|
151
|
-
|
147
|
+
merge_views!(other)
|
148
|
+
end
|
149
|
+
|
150
|
+
def merge_views!(other)
|
151
|
+
return if other.blank?
|
152
|
+
|
153
|
+
self.class.save_affinity(
|
154
|
+
id: id,
|
155
|
+
action: 'viewed',
|
156
|
+
product_ids: other.viewed.product_ids,
|
157
|
+
category_ids: other.viewed.category_ids,
|
158
|
+
search_ids: other.viewed.search_ids
|
159
|
+
)
|
160
|
+
|
161
|
+
reload rescue self # save_affinity might not have actually persisted anything
|
152
162
|
end
|
153
163
|
end
|
154
164
|
end
|
@@ -33,17 +33,17 @@ module Workarea
|
|
33
33
|
# To allow for custom policies defining their own methods here
|
34
34
|
Workarea.config.fulfillment_policies.each do |class_name|
|
35
35
|
define_method "#{class_name.demodulize.underscore}?" do
|
36
|
-
|
36
|
+
fulfilled_by?(class_name.demodulize.underscore)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
40
40
|
# These methods exist for findability
|
41
41
|
def shipping?
|
42
|
-
|
42
|
+
fulfilled_by?('shipping')
|
43
43
|
end
|
44
44
|
|
45
45
|
def download?
|
46
|
-
|
46
|
+
fulfilled_by?('download')
|
47
47
|
end
|
48
48
|
|
49
49
|
# Whether this order has any items that need to be fulfilled by a particular
|
@@ -53,7 +53,7 @@ module Workarea
|
|
53
53
|
# @return [Boolean]
|
54
54
|
#
|
55
55
|
def fulfilled_by?(*types)
|
56
|
-
types.
|
56
|
+
types.map(&:to_s).include?(fulfillment)
|
57
57
|
end
|
58
58
|
|
59
59
|
# Whether this item is a digital (not-shipped) type of item.
|
@@ -129,6 +129,14 @@ module Workarea
|
|
129
129
|
scoped.sort_by { |r| [r.publish_at, r.created_at] }
|
130
130
|
end
|
131
131
|
|
132
|
+
def self.schedule_affected_by_changesets(changesets)
|
133
|
+
changesets
|
134
|
+
.uniq(&:release)
|
135
|
+
.reject { |cs| cs.release.blank? }
|
136
|
+
.flat_map { |cs| [cs.release] + cs.release.scheduled_after }
|
137
|
+
.uniq
|
138
|
+
end
|
139
|
+
|
132
140
|
def as_current
|
133
141
|
self.class.with_current(self) { yield }
|
134
142
|
end
|
@@ -83,11 +83,7 @@ module Workarea
|
|
83
83
|
end
|
84
84
|
|
85
85
|
def releases
|
86
|
-
changesets
|
87
|
-
.uniq(&:release)
|
88
|
-
.reject { |cs| cs.release.blank? }
|
89
|
-
.flat_map { |cs| [cs.release] + cs.release.scheduled_after }
|
90
|
-
.uniq
|
86
|
+
Release.schedule_affected_by_changesets(changesets)
|
91
87
|
end
|
92
88
|
|
93
89
|
def as_document
|
@@ -122,21 +122,8 @@ module Workarea
|
|
122
122
|
ProductPrimaryImageUrl.new(model).path
|
123
123
|
end
|
124
124
|
|
125
|
-
# All {Releasable}s that could affect the product's Elasticsearch document
|
126
|
-
# should add their changesets to this method.
|
127
|
-
#
|
128
|
-
# @example Add to the changesets affecting a product in a decorator
|
129
|
-
# def changesets
|
130
|
-
# super.merge(SomeReleasable.for_product(product.id).changesets_with_children)
|
131
|
-
# end
|
132
|
-
#
|
133
|
-
# @return [Mongoid::Criteria]
|
134
|
-
#
|
135
125
|
def changesets
|
136
|
-
|
137
|
-
pricing.each { |ps| criteria.merge!(ps.changesets_with_children) }
|
138
|
-
criteria.merge!(FeaturedProducts.changesets(model.id))
|
139
|
-
criteria.includes(:release)
|
126
|
+
ProductReleases.new(model).changesets
|
140
127
|
end
|
141
128
|
|
142
129
|
private
|
@@ -37,15 +37,22 @@ module Workarea
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.by_price(price)
|
40
|
-
cache.select do |
|
41
|
-
(
|
42
|
-
(
|
40
|
+
cache.select do |service|
|
41
|
+
(service.subtotal_min.nil? || service.subtotal_min <= price) &&
|
42
|
+
(service.subtotal_max.nil? || service.subtotal_max >= price)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
46
|
def self.find_tax_code(carrier, name)
|
47
|
-
|
48
|
-
|
47
|
+
service = find_by(carrier: carrier, name: name) rescue nil
|
48
|
+
service.present? ? service.tax_code : default_tax_code(carrier, name)
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.default_tax_code(carrier, name)
|
52
|
+
default = Workarea.config.default_shipping_service_tax_code
|
53
|
+
return default unless default.respond_to?(:call)
|
54
|
+
|
55
|
+
default.call(carrier, name)
|
49
56
|
end
|
50
57
|
|
51
58
|
def find_rate(price = 0.to_m)
|
@@ -57,7 +57,9 @@ module Workarea
|
|
57
57
|
percentage_field = super
|
58
58
|
return percentage_field unless percentage_field.zero?
|
59
59
|
|
60
|
-
country_percentage
|
60
|
+
[country_percentage, region_percentage, postal_code_percentage]
|
61
|
+
.compact
|
62
|
+
.sum
|
61
63
|
end
|
62
64
|
end
|
63
65
|
end
|
@@ -1,10 +1,4 @@
|
|
1
1
|
module Workarea
|
2
|
-
#
|
3
|
-
# TODO remove in v3.6
|
4
|
-
#
|
5
|
-
# This is no longer used, this logic was moved into the search models to allow
|
6
|
-
# it to be used for any model (not just products).
|
7
|
-
#
|
8
2
|
class ProductReleases
|
9
3
|
attr_reader :product
|
10
4
|
|
@@ -13,11 +7,7 @@ module Workarea
|
|
13
7
|
end
|
14
8
|
|
15
9
|
def releases
|
16
|
-
changesets
|
17
|
-
.uniq(&:release)
|
18
|
-
.reject { |cs| cs.release.blank? }
|
19
|
-
.flat_map { |cs| [cs.release] + cs.release.scheduled_after }
|
20
|
-
.uniq
|
10
|
+
Release.schedule_affected_by_changesets(changesets)
|
21
11
|
end
|
22
12
|
|
23
13
|
# All {Releasable}s that could affect the product's Elasticsearch document
|
@@ -18,17 +18,23 @@ module Workarea
|
|
18
18
|
|
19
19
|
def live_entries
|
20
20
|
@live_entries ||= @products.reduce([]) do |memo, product|
|
21
|
-
memo +
|
21
|
+
memo + live_entries_for(product)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def release_entries
|
26
|
-
@release_entries ||= @products.reduce([]) do |
|
27
|
-
|
26
|
+
@release_entries ||= @products.reduce([]) do |memo, product|
|
27
|
+
memo + release_entries_for(product)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def live_entries_for(product)
|
32
|
+
Array.wrap(index_entries_for(product.without_release))
|
33
|
+
end
|
28
34
|
|
29
|
-
|
30
|
-
|
31
|
-
|
35
|
+
def release_entries_for(product)
|
36
|
+
ProductReleases.new(product).releases.reduce([]) do |memo, release|
|
37
|
+
memo + Array.wrap(index_entries_for(product.in_release(release)))
|
32
38
|
end
|
33
39
|
end
|
34
40
|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Workarea
|
2
|
+
class UpdateEmail
|
3
|
+
include Sidekiq::Worker
|
4
|
+
include Sidekiq::CallbacksWorker
|
5
|
+
|
6
|
+
sidekiq_options(
|
7
|
+
enqueue_on: { User => :update, with: -> { [id, changes] } }
|
8
|
+
)
|
9
|
+
|
10
|
+
def perform(id, changes)
|
11
|
+
return unless changes['email'].present? && changes['email'].first.present?
|
12
|
+
|
13
|
+
old_email, new_email = changes['email']
|
14
|
+
update_payment_profile(id, old_email, new_email)
|
15
|
+
update_metrics(old_email, new_email)
|
16
|
+
end
|
17
|
+
|
18
|
+
def update_payment_profile(id, old_email, new_email)
|
19
|
+
user = User.find(id)
|
20
|
+
user.email = old_email # set old email so we lookup by old email value
|
21
|
+
|
22
|
+
Payment::Profile.update_email(PaymentReference.new(user), new_email)
|
23
|
+
end
|
24
|
+
|
25
|
+
def update_metrics(old_email, new_email)
|
26
|
+
old_metrics = Metrics::User.find(old_email) rescue nil
|
27
|
+
return if old_metrics.blank?
|
28
|
+
|
29
|
+
new_metrics = Metrics::User.find_or_initialize_by(id: new_email)
|
30
|
+
new_metrics.merge!(old_metrics)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -76,6 +76,17 @@ Workarea::Configuration.define_fields do
|
|
76
76
|
zip: '19106'
|
77
77
|
},
|
78
78
|
description: 'Origin location for calculating shipping costs'
|
79
|
+
|
80
|
+
# This can be overwritten within the app to use a proc for more complex
|
81
|
+
# scenarios.
|
82
|
+
field 'Default Shipping Service Tax Code',
|
83
|
+
type: String,
|
84
|
+
allow_blank: true,
|
85
|
+
description: %(
|
86
|
+
Tax code assigned to shipping options when an existing service does
|
87
|
+
not exist. This is useful for third-party gateways to assign tax codes
|
88
|
+
to dynamically generated options.
|
89
|
+
).squish
|
79
90
|
end
|
80
91
|
|
81
92
|
fieldset 'Payment', namespaced: false do
|
@@ -116,11 +127,6 @@ Workarea::Configuration.define_fields do
|
|
116
127
|
end
|
117
128
|
|
118
129
|
fieldset 'Search', namespaced: false do
|
119
|
-
field 'Default Search Facet Result Sizes',
|
120
|
-
type: :integer,
|
121
|
-
default: 10,
|
122
|
-
description: 'The number of filter results returned for each filter type.'
|
123
|
-
|
124
130
|
field 'Search Facet Result Sizes',
|
125
131
|
type: :hash,
|
126
132
|
values_type: :integer,
|
@@ -128,7 +134,15 @@ Workarea::Configuration.define_fields do
|
|
128
134
|
description: %(
|
129
135
|
The number of filter results returned for any specified filter type. If no
|
130
136
|
size is defined for a filter type, the default will be what is specified
|
131
|
-
in the default config
|
137
|
+
in the default config below.
|
138
|
+
).squish
|
139
|
+
|
140
|
+
field 'Default Search Facet Result Sizes',
|
141
|
+
type: :integer,
|
142
|
+
default: 10,
|
143
|
+
description: %(
|
144
|
+
The number of filter results returned for each filter type when not
|
145
|
+
specified above.
|
132
146
|
).squish
|
133
147
|
|
134
148
|
field 'Search Size Facet Sort',
|
@@ -156,14 +170,15 @@ Workarea::Configuration.define_fields do
|
|
156
170
|
end
|
157
171
|
|
158
172
|
fieldset 'Communication', namespaced: false do
|
173
|
+
|
159
174
|
field 'Email From',
|
160
175
|
type: :string,
|
161
|
-
default:
|
176
|
+
default: -> { "#{Workarea.config.site_name} <noreply@#{Workarea.config.host}>" },
|
162
177
|
description: 'The email address used as the sender of system emails'
|
163
178
|
|
164
179
|
field 'Email To',
|
165
180
|
type: :string,
|
166
|
-
default:
|
181
|
+
default: -> { "#{Workarea.config.site_name} <customerservice@#{Workarea.config.host}>" },
|
167
182
|
description: 'The email address that receives user generated emails, e.g. contact us inquiries'
|
168
183
|
|
169
184
|
field 'Inquiry Subjects',
|