workarea-core 3.5.16 → 3.5.21

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/workarea/current_tracking.rb +4 -2
  3. data/app/controllers/workarea/impersonation.rb +4 -2
  4. data/app/mailers/workarea/application_mailer.rb +4 -1
  5. data/app/middleware/workarea/application_middleware.rb +5 -2
  6. data/app/models/workarea/checkout.rb +6 -2
  7. data/app/models/workarea/data_file/csv.rb +9 -1
  8. data/app/models/workarea/inquiry.rb +2 -1
  9. data/app/models/workarea/order/item.rb +4 -4
  10. data/app/models/workarea/search/admin/inventory_sku.rb +5 -1
  11. data/app/models/workarea/shipping/service.rb +12 -5
  12. data/app/models/workarea/tax/rate.rb +3 -1
  13. data/app/queries/workarea/search/admin_search.rb +4 -0
  14. data/app/queries/workarea/search/admin_sorting.rb +1 -1
  15. data/app/queries/workarea/search/product_entries.rb +12 -6
  16. data/config/initializers/00_configuration.rb +23 -8
  17. data/config/initializers/05_scheduled_jobs.rb +1 -1
  18. data/config/initializers/22_session_store.rb +1 -1
  19. data/config/locales/en.yml +3 -0
  20. data/lib/generators/workarea/install/install_generator.rb +13 -0
  21. data/lib/generators/workarea/install/templates/initializer.rb.erb +1 -13
  22. data/lib/tasks/cache.rake +3 -33
  23. data/lib/tasks/help.rake +4 -43
  24. data/lib/tasks/insights.rake +3 -35
  25. data/lib/tasks/migrate.rake +3 -96
  26. data/lib/tasks/search.rake +6 -68
  27. data/lib/tasks/services.rake +4 -54
  28. data/lib/workarea.rb +10 -0
  29. data/lib/workarea/configuration.rb +4 -3
  30. data/lib/workarea/configuration/administrable_options.rb +2 -1
  31. data/lib/workarea/core/engine.rb +4 -0
  32. data/lib/workarea/scheduled_jobs.rb +1 -1
  33. data/lib/workarea/tasks/cache.rb +43 -0
  34. data/lib/workarea/tasks/help.rb +55 -0
  35. data/lib/workarea/tasks/insights.rb +47 -0
  36. data/lib/workarea/tasks/migrate.rb +106 -0
  37. data/lib/workarea/tasks/search.rb +105 -0
  38. data/lib/workarea/tasks/services.rb +71 -0
  39. data/lib/workarea/version.rb +1 -1
  40. data/lib/workarea/visit.rb +8 -1
  41. data/lib/workarea/warnings.rb +1 -1
  42. data/test/generators/workarea/install_generator_test.rb +6 -2
  43. data/test/integration/workarea/authentication_test.rb +2 -1
  44. data/test/lib/workarea/scheduled_jobs_test.rb +1 -5
  45. data/test/mailers/workarea/application_mailer_test.rb +10 -0
  46. data/test/models/workarea/checkout_test.rb +57 -0
  47. data/test/models/workarea/data_file/csv_test.rb +2 -1
  48. data/test/models/workarea/data_file/import_test.rb +40 -0
  49. data/test/models/workarea/order/item_test.rb +9 -0
  50. data/test/models/workarea/shipping/service_test.rb +26 -0
  51. data/test/queries/workarea/search/admin_search_test.rb +10 -0
  52. data/test/workers/workarea/status_reporter_test.rb +3 -1
  53. data/workarea-core.gemspec +1 -1
  54. metadata +10 -4
@@ -1,11 +1,10 @@
1
+ require 'workarea/tasks/help'
2
+
1
3
  namespace :workarea do
2
4
  desc 'Drop and recreate help articles (Warning: all current help will be deleted!)'
3
5
  task reload_help: :environment do
4
6
  puts 'Deleting help articles...'
5
- Workarea::Help::Article.delete_all
6
- Workarea::Help::Asset.delete_all
7
-
8
- Workarea::HelpSeeds.new.perform
7
+ Workarea::Tasks::Help.reload
9
8
  Rake::Task['workarea:search_index:help'].invoke
10
9
  end
11
10
 
@@ -16,44 +15,6 @@ namespace :workarea do
16
15
  end
17
16
 
18
17
  task dump_help: :environment do
19
- Workarea::Help::Article.all.each_by(50) do |article|
20
- article_root = Rails.root.join(
21
- 'data',
22
- 'help',
23
- article.category.systemize,
24
- article.name.systemize
25
- )
26
-
27
- asset_path = article_root.join('assets')
28
-
29
- FileUtils.mkdir_p(article_root)
30
-
31
- if article.thumbnail.present?
32
- article.thumbnail.to_file(article_root.join(article.thumbnail.name))
33
- end
34
-
35
- Workarea::Help::Asset.all.each_by(50) do |asset|
36
- if article.summary.include?(asset.url) || article.body.include?(asset.url)
37
- FileUtils.mkdir_p(asset_path)
38
- asset.to_file(asset_path.join(asset.name))
39
- reference = "<%= #{asset.name.split('.').first} %>"
40
-
41
- article.summary.gsub!(asset.url, reference)
42
- article.body.gsub!(asset.url, reference)
43
- end
44
- end
45
-
46
- if article.summary.present?
47
- File.open(article_root.join('summary.md'), 'w') do |file|
48
- file.write(article.summary)
49
- end
50
- end
51
-
52
- if article.body.present?
53
- File.open(article_root.join('body.md'), 'w') do |file|
54
- file.write(article.body)
55
- end
56
- end
57
- end
18
+ Workarea::Tasks::Help.dump
58
19
  end
59
20
  end
@@ -1,49 +1,17 @@
1
- require 'active_support/testing/time_helpers'
1
+ require 'workarea/tasks/insights'
2
2
 
3
3
  namespace :workarea do
4
4
  namespace :insights do
5
5
  desc 'Creates metrics and insights based on orders'
6
6
  task generate: :environment do
7
- include ActiveSupport::Testing::TimeHelpers
8
- batch_size = ENV['WORKAREA_INSIGHTS_BATCH_SIZE'].presence || 1000
9
-
10
- Workarea::Order
11
- .placed
12
- .each_by(batch_size.to_i) { |o| Workarea::SaveOrderMetrics.perform(o) }
13
-
14
- 8.times do |i|
15
- travel_to (i.weeks.ago.beginning_of_week + 1.hour)
16
- Workarea::GenerateInsights.generate_all!
17
- end
18
-
7
+ Workarea::Tasks::Insights.generate
19
8
  puts "Success! Generated #{Workarea::Insights::Base.count} insights."
20
9
  end
21
10
 
22
11
  # Clear the metrics/insights environment - deletes lots of data, this task
23
12
  # is very dangerous! Useful for testing/debugging.
24
13
  task reset: :environment do
25
- Workarea::Order
26
- .where(:metrics_saved_at.gt => 0)
27
- .update_all(metrics_saved_at: nil)
28
-
29
-
30
- Workarea::Metrics::CategoryByDay.delete_all
31
- Workarea::Metrics::CountryByDay.delete_all
32
- Workarea::Metrics::DiscountByDay.delete_all
33
- Workarea::Metrics::MenuByDay.delete_all
34
- Workarea::Metrics::ProductByDay.delete_all
35
- Workarea::Metrics::ProductByWeek.delete_all
36
- Workarea::Metrics::ProductForLastWeek.delete_all
37
- Workarea::Metrics::SalesByDay.delete_all
38
- Workarea::Metrics::SearchByDay.delete_all
39
- Workarea::Metrics::SearchByWeek.delete_all
40
- Workarea::Metrics::SearchForLastWeek.delete_all
41
- Workarea::Metrics::SkuByDay.delete_all
42
- Workarea::Metrics::TenderByDay.delete_all
43
- Workarea::Metrics::TrafficReferrerByDay.delete_all
44
- Workarea::Metrics::User.delete_all
45
- Workarea::Insights::Base.delete_all
46
-
14
+ Workarea::Tasks::Insights.reset!
47
15
  puts "Success! Insights and metrics have been cleared."
48
16
  end
49
17
  end
@@ -1,103 +1,10 @@
1
+ require 'workarea/tasks/migrate'
2
+
1
3
  namespace :workarea do
2
4
  namespace :migrate do
3
5
  desc 'Migrate the database from v3.4 to v3.5'
4
6
  task v3_5: :environment do
5
- count = 0
6
-
7
- Workarea::Release.where(:undo_at.gte => Time.current).each do |release|
8
- undo = release.build_undo(publish_at: release.undo_at).tap(&:save!)
9
-
10
- release.changesets.each do |changeset|
11
- changeset.build_undo(release: undo).save!
12
- end
13
-
14
- Workarea::Scheduler.delete(release.undo_job_id)
15
-
16
- release.update_attributes!(undo_at: nil, undo_job_id: nil)
17
- count += 1
18
- end
19
-
20
- Workarea::Release.all.each { |r| Workarea::IndexAdminSearch.perform(r) }
21
-
22
- puts "✅ #{count} undo releases have been created."
23
-
24
- count = 0
25
-
26
- Workarea::Tax::Category.all.each_by(100) do |category|
27
- category.rates.each_by(500) do |rate|
28
- rate.postal_code_percentage = rate.percentage
29
- rate.percentage = nil
30
- end
31
-
32
- category.save!
33
- count += 1
34
- end
35
-
36
- puts "✅ #{count} tax categories updated."
37
-
38
- count = 0
39
- failed_ids = []
40
- backup = Mongo::Collection.new(Mongoid::Clients.default.database, 'workarea_legacy_segments')
41
-
42
- legacy_segments = Workarea::Segment.collection.find.to_a
43
- legacy_segments.each do |doc|
44
- backup.insert_one(doc)
45
- Workarea::Segment.collection.delete_one(doc.slice('_id'))
46
-
47
- segment = Workarea::Segment.new(
48
- id: doc['_id'],
49
- name: doc['name'],
50
- subscribed_user_ids: doc['subscribed_user_ids'],
51
- created_at: doc['created_at'],
52
- updated_at: doc['updated_at']
53
- )
54
-
55
- doc['conditions'].each do |condition|
56
- if condition['_type'] =~ /UserTag/
57
- segment.rules << Workarea::Segment::Rules::Tags.new(tags: condition['tags'])
58
- elsif condition['_type'] =~ /TotalSpent/
59
- rule = Workarea::Segment::Rules::Revenue.new
60
-
61
- if condition['operator'] == 'equals'
62
- rule.minimum = rule.maximum = Money.demongoize(condition['amount'])
63
- elsif condition['operator'] == 'less_than_or_equals'
64
- rule.maximum = Money.demongoize(condition['amount'])
65
- elsif condition['operator'] == 'less_than'
66
- rule.maximum = (Money.demongoize(condition['amount']) - 0.01.to_m)
67
- elsif condition['operator'] == 'greater_than_or_equals'
68
- rule.minimum = Money.demongoize(condition['amount'])
69
- elsif condition['operator'] == 'greater_than'
70
- rule.minimum = (Money.demongoize(condition['amount']) + 0.01.to_m)
71
- end
72
-
73
- segment.rules << rule
74
- end
75
- end
76
-
77
- if doc['conditions'].size == segment.rules.size && segment.save
78
- count += 1
79
- else
80
- failed_ids << doc['_id']
81
- end
82
- end
83
-
84
- puts "✅ #{count} segments have been migrated." if count > 0
85
- if failed_ids.any?
86
- puts "⛔️ #{failed_ids.count} segments failed to migrate."
87
- puts "You can find copies of the original segments in the workarea_legacy_segments collection."
88
- puts "The segments that failed are #{failed_ids.to_sentence}."
89
- end
90
-
91
- Workarea::Segment::LifeCycle.create!
92
- puts "✅ Life cycle segments have been created."
93
-
94
- admin_ids = Workarea::User.admins.pluck(:id)
95
- admin_ids.each do |id|
96
- Workarea::SynchronizeUserMetrics.new.perform(id)
97
- end
98
- puts "✅ #{admin_ids.count} admins have had their metrics synchronized." if admin_ids.count > 0
99
-
100
- puts "\nMigration complete!"
7
+ Workarea::Tasks::Migrate.v3_5
101
8
  end
102
9
  end
103
10
  end
@@ -1,8 +1,9 @@
1
+ require 'workarea/tasks/search'
2
+
1
3
  namespace :workarea do
2
4
  namespace :search_index do
3
5
  def setup
4
- require 'sidekiq/testing/inline' unless ENV['INLINE'] == 'false'
5
- Workarea.config.bulk_index_batch_size = ENV['BATCH_SIZE'].to_i if ENV['BATCH_SIZE'].present?
6
+ Workarea::Tasks::Search.setup
6
7
  end
7
8
 
8
9
  desc 'Reindex all data'
@@ -16,84 +17,21 @@ namespace :workarea do
16
17
  task admin: :environment do
17
18
  setup
18
19
  puts 'Indexing admin...'
19
- Workarea::QueuesPauser.with_paused_queues do
20
- Workarea::Search::Admin.reset_indexes!
21
- end
22
-
23
- Mongoid.models.each do |klass|
24
- next unless Workarea::Search::Admin.for(klass.first).present?
25
-
26
- klass.all.each_slice_of(Workarea.config.bulk_index_batch_size) do |models|
27
- Workarea::BulkIndexAdmin.perform_by_models(models)
28
- end
29
- end
30
-
31
- Workarea.config.jump_to_navigation.to_a.each do |tuple|
32
- Workarea::Search::Admin::Navigation.new(tuple).save
33
- end
20
+ Workarea::Tasks::Search.index_admin
34
21
  end
35
22
 
36
23
  desc 'Reindex storefront'
37
24
  task storefront: :environment do
38
25
  setup
39
26
  puts 'Indexing storefront...'
40
-
41
- Workarea::QueuesPauser.with_paused_queues do
42
- Workarea::Search::Storefront.reset_indexes!
43
- Workarea::Search::Storefront.ensure_dynamic_mappings
44
- end
45
-
46
- # This code finds all unique filters for products so we can index a sample
47
- # product for each to ensure the dynamic mappings get created.
48
- #
49
- # This is necessary to fix mapping errors from Elasticsearch when trying
50
- # to index category percolations against fields which have no mapping.
51
- #
52
- map = %{
53
- function() {
54
- for (var key in this.filters.#{I18n.locale}) {
55
- emit(key, null);
56
- }
57
- }
58
- }
59
- reduce = 'function(key) { return null; }'
60
- results = Workarea::Catalog::Product.map_reduce(map, reduce).out(inline: 1)
61
- unique_filters = results.map { |r| r['_id'] }
62
-
63
- sample_products = unique_filters.reduce([]) do |memo, filter|
64
- filter = "filters.#{I18n.locale}.#{filter}"
65
- memo << Workarea::Catalog::Product.exists(filter => true).sample
66
- end
67
-
68
- sample_products.each do |product|
69
- Workarea::Search::Storefront::Product.new(product).save
70
- end
71
-
72
- Workarea::Catalog::Category.all.each_by(Workarea.config.bulk_index_batch_size) do |category|
73
- Workarea::Search::Storefront::CategoryQuery.new(category).create
74
- Workarea::Search::Storefront::Category.new(category).save
75
- end
76
-
77
- Workarea::Content::Page.all.each_by(Workarea.config.bulk_index_batch_size) do |page|
78
- Workarea::Search::Storefront::Page.new(page).save
79
- end
80
-
81
- Workarea::BulkIndexProducts.perform
82
- Workarea::BulkIndexSearches.perform
27
+ Workarea::Tasks::Search.index_storefront
83
28
  end
84
29
 
85
30
  desc 'Reindex help'
86
31
  task help: :environment do
87
32
  setup
88
33
  puts 'Indexing help...'
89
-
90
- Workarea::QueuesPauser.with_paused_queues do
91
- Workarea::Search::Help.reset_indexes!
92
- end
93
-
94
- Workarea::Help::Article.all.each_by(Workarea.config.bulk_index_batch_size) do |help_article|
95
- Workarea::Search::Help.new(help_article).save
96
- end
34
+ Workarea::Tasks::Search.index_help
97
35
  end
98
36
  end
99
37
  end
@@ -1,73 +1,23 @@
1
- require 'workarea/version'
1
+ require 'workarea/tasks/services'
2
2
 
3
3
  namespace :workarea do
4
4
  namespace :services do
5
- def assert_docker_compose_installed!
6
- unless system('docker-compose -v > /dev/null 2>&1')
7
- STDERR.puts <<~eos
8
- **************************************************
9
- ⛔️ ERROR: workarea:services tasks depend on Docker Compose being installed. \
10
- See https://docs.docker.com/compose/install/ for how to install.
11
- **************************************************
12
- eos
13
- exit
14
- end
15
- end
16
-
17
- def compose_file_path
18
- File.join(Gem::Specification.find_by_name('workarea').gem_dir, 'docker-compose.yml')
19
- end
20
-
21
- def compose_env
22
- {
23
- 'COMPOSE_FILE' => compose_file_path,
24
- 'COMPOSE_PROJECT_NAME' => File.basename(Dir.pwd),
25
-
26
- 'MONGODB_VERSION' => Workarea::VERSION::MONGODB::STRING,
27
- 'MONGODB_PORT' => ENV['WORKAREA_MONGODB_PORT'] || '27017',
28
-
29
- 'REDIS_VERSION' => Workarea::VERSION::REDIS::STRING,
30
- 'REDIS_PORT' => ENV['WORKAREA_REDIS_PORT'] || '6379',
31
-
32
- 'ELASTICSEARCH_VERSION' => Workarea::VERSION::ELASTICSEARCH::STRING,
33
- 'ELASTICSEARCH_PORT' => ENV['WORKAREA_ELASTICSEARCH_PORT'] || '9200'
34
- }
35
- end
36
-
37
5
  desc 'Start Workarea background services for this app'
38
6
  task :up do
39
7
  puts 'Starting Workarea services...'
40
- assert_docker_compose_installed!
41
-
42
- if system(compose_env, "docker-compose up -d #{ENV['COMPOSE_ARGUMENTS']} #{ENV['WORKAREA_SERVICES']}")
43
- puts '✅ Success! Workarea services are running in the background. Run workarea:services:down to stop them.'
44
- else
45
- STDERR.puts '⛔️ Error! There was an error starting Workarea services.'
46
- end
8
+ Workarea::Tasks::Services.up
47
9
  end
48
10
 
49
11
  desc 'Stop Workarea external services for this app'
50
12
  task :down do
51
13
  puts 'Stopping Workarea services...'
52
- assert_docker_compose_installed!
53
-
54
- if system(compose_env, "docker-compose down #{ENV['COMPOSE_ARGUMENTS']}")
55
- puts '✅ Success! Workarea services are stopped. Run workarea:services:up to start them.'
56
- else
57
- STDERR.puts '⛔️ Error! There was an error stopping Workarea services.'
58
- end
14
+ Workarea::Tasks::Services.down
59
15
  end
60
16
 
61
17
  desc 'Remove data volumes associated with Workarea external services. Stops containers.'
62
18
  task :clean do
63
19
  puts 'Removing Workarea service data...'
64
- assert_docker_compose_installed!
65
-
66
- if system(compose_env, "docker-compose down -v #{ENV['COMPOSE_ARGUMENTS']}")
67
- puts '✅ Success! Workarea service volumes have been removed. Run workarea:services:up to start services and recreate volumes.'
68
- else
69
- STDERR.puts '⛔️ Error! There was an error removing Workarea service volumes.'
70
- end
20
+ Workarea::Tasks::Services.clean
71
21
  end
72
22
  end
73
23
  end
@@ -182,6 +182,16 @@ module Workarea
182
182
  def self.deprecation
183
183
  @deprecation ||= ActiveSupport::Deprecation.new('3.6', 'Workarea')
184
184
  end
185
+
186
+ # Whether the app should skip connecting to external services on boot,
187
+ # such as Mongo, Elasticsearch, or Redis. Note that this will break
188
+ # functionality relying on these services.
189
+ #
190
+ # @return [Boolean]
191
+ #
192
+ def self.skip_services?
193
+ !!(ENV['WORKAREA_SKIP_SERVICES'] =~ /true/)
194
+ end
185
195
  end
186
196
 
187
197
  require 'workarea/core'
@@ -26,8 +26,6 @@ module Workarea
26
26
 
27
27
  config.site_name = 'Workarea'
28
28
  config.host = 'www.example.com'
29
- config.email_to = 'customerservice@example.com'
30
- config.email_from = 'noreply@example.com'
31
29
 
32
30
  # Config sent to the ImageMagick through Dragonfly for optimizing jpgs
33
31
  # All metadata profiles are removed, comments cleared by comment -set ""
@@ -942,7 +940,10 @@ module Workarea
942
940
 
943
941
  # Whether the app should skip connecting to external services on boot,
944
942
  # such as Mongo, Elasticsearch, or Redis.
945
- config.skip_service_connections = ENV['WORKAREA_SKIP_SERVICES'].to_s =~ /true/
943
+ #
944
+ # @deprecated Use `Workarea.skip_services?` instead
945
+ #
946
+ config.skip_service_connections = Workarea.skip_services?
946
947
 
947
948
  # This is a feature flag, which enables localized active fields. If you're
948
949
  # upgrading, you can set this to false to avoid having to do a MongoDB
@@ -12,7 +12,8 @@ module Workarea
12
12
  private
13
13
 
14
14
  def check_fieldsets?(name)
15
- ::Mongoid.clients.any? &&
15
+ !Workarea.skip_services? &&
16
+ ::Mongoid.clients.any? &&
16
17
  Configuration::Admin.fields.keys.include?(name.to_s)
17
18
  end
18
19
  end
@@ -78,6 +78,10 @@ module Workarea
78
78
  # get autoloaded. Without this, admin actions like updating product
79
79
  # attributes raises a {NameError} "uninitialized constant BulkIndexProducts".
80
80
  require_dependency 'workarea/bulk_index_products'
81
+
82
+ # Fixes a constant error raised in middleware (when doing segmentation)
83
+ # No idea what the cause is. TODO revisit after Zeitwerk.
84
+ require_dependency 'workarea/metrics/user'
81
85
  end
82
86
  end
83
87
  end