workarea-core 3.5.15 → 3.5.20

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.
Files changed (50) 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 +7 -7
  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/inventory/sku.rb +2 -2
  10. data/app/models/workarea/metrics/user.rb +24 -8
  11. data/app/models/workarea/order.rb +10 -0
  12. data/app/models/workarea/order/item.rb +4 -4
  13. data/app/models/workarea/payment.rb +1 -6
  14. data/app/models/workarea/search/admin/inventory_sku.rb +5 -1
  15. data/app/models/workarea/shipping/service.rb +12 -5
  16. data/app/models/workarea/tax/rate.rb +3 -1
  17. data/app/queries/workarea/search/admin_search.rb +4 -0
  18. data/app/queries/workarea/search/admin_sorting.rb +1 -1
  19. data/config/initializers/00_configuration.rb +23 -8
  20. data/config/initializers/22_session_store.rb +1 -1
  21. data/config/locales/en.yml +3 -0
  22. data/lib/generators/workarea/install/install_generator.rb +13 -0
  23. data/lib/generators/workarea/install/templates/initializer.rb.erb +1 -13
  24. data/lib/tasks/cache.rake +3 -33
  25. data/lib/tasks/help.rake +4 -43
  26. data/lib/tasks/insights.rake +3 -35
  27. data/lib/tasks/migrate.rake +3 -96
  28. data/lib/tasks/search.rake +6 -68
  29. data/lib/tasks/services.rake +4 -54
  30. data/lib/workarea/configuration.rb +11 -2
  31. data/lib/workarea/configuration/administrable_options.rb +1 -5
  32. data/lib/workarea/core/engine.rb +4 -0
  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/test/generators/workarea/install_generator_test.rb +6 -2
  42. data/test/integration/workarea/authentication_test.rb +2 -1
  43. data/test/mailers/workarea/application_mailer_test.rb +10 -0
  44. data/test/models/workarea/checkout_test.rb +57 -0
  45. data/test/models/workarea/data_file/import_test.rb +40 -0
  46. data/test/models/workarea/order/item_test.rb +9 -0
  47. data/test/models/workarea/shipping/service_test.rb +26 -0
  48. data/test/queries/workarea/search/admin_search_test.rb +10 -0
  49. data/workarea-core.gemspec +1 -1
  50. metadata +10 -4
@@ -4,19 +4,7 @@ Workarea.configure do |config|
4
4
 
5
5
  config.host = {
6
6
  'test' => 'www.example.com',
7
- 'development' => 'localhost:3000',
7
+ 'development' => 'localhost',
8
8
  'production' => 'www.<%= app_name.dasherize %>.com' # TODO
9
9
  }[Rails.env]
10
-
11
- config.email_to = {
12
- 'test' => "#{config.site_name} <customerservice@example.com>",
13
- 'development' => "#{config.site_name} <customerservice@<%= app_name %>.test>",
14
- 'production' => "#{config.site_name} <customerservice@<%= app_name.dasherize %>.com>" # TODO
15
- }[Rails.env]
16
-
17
- config.email_from = {
18
- 'test' => "#{config.site_name} <noreply@example.com>",
19
- 'development' => "#{config.site_name} <noreply@<%= app_name %>.test",
20
- 'production' => "#{config.site_name} <noreply@<%= app_name.dasherize %>.com>" # TODO
21
- }[Rails.env]
22
10
  end
@@ -1,40 +1,10 @@
1
+ require 'workarea/tasks/cache'
2
+
1
3
  namespace :workarea do
2
4
  namespace :cache do
3
5
  desc 'Prime images cache'
4
6
  task prime_images: :environment do
5
- include Rails.application.routes.url_helpers
6
- include Workarea::Storefront::ProductsHelper
7
- include Workarea::Core::Engine.routes.url_helpers
8
-
9
- built_in_jobs = [:thumb, :gif, :jpg, :png, :strip, :convert, :optimized]
10
-
11
- jobs = Dragonfly.app(:workarea).processor_methods.reject do |job|
12
- built_in_jobs.include?(job)
13
- end
14
-
15
- Workarea::Catalog::Product.all.each_by(50) do |product|
16
- product.images.each do |image|
17
- jobs.each do |job|
18
- url = URI.join(
19
- "https://#{Workarea.config.host}",
20
- dynamic_product_image_url(
21
- image.product.slug,
22
- image.option,
23
- image.id,
24
- job,
25
- only_path: true
26
- )
27
- ).to_s
28
-
29
- begin
30
- `curl #{url}`
31
- puts "Downloaded image #{url}"
32
- rescue StandardError => e
33
- puts e.inspect
34
- end
35
- end
36
- end
37
- end
7
+ Workarea::Tasks::Cache.prime_images
38
8
  end
39
9
  end
40
10
  end
@@ -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