workarea-reviews 3.0.8 → 3.1.2
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/.eslintrc.json +35 -0
- data/.github/workflows/ci.yml +60 -0
- data/.gitignore +1 -2
- data/.rubocop.yml +3 -0
- data/.stylelintrc.json +8 -0
- data/CHANGELOG.md +24 -12
- data/Gemfile +4 -2
- data/Rakefile +4 -5
- data/app/controllers/workarea/admin/reports_controller.decorator +10 -0
- data/app/helpers/workarea/admin/reviews_helper.rb +6 -5
- data/app/helpers/workarea/storefront/reviews_helper.rb +1 -3
- data/app/helpers/workarea/storefront/reviews_schema_org_helper.rb +34 -0
- data/app/mailers/workarea/admin/status_report_mailer.decorator +2 -2
- data/app/models/workarea/insights/most_active_reviewers.rb +34 -0
- data/app/models/workarea/insights/most_reviewed_products.rb +33 -0
- data/app/models/workarea/insights/top_rated_products.rb +33 -0
- data/app/models/workarea/review.rb +5 -16
- data/app/queries/workarea/reports/reviews_by_product.rb +86 -0
- data/app/queries/workarea/reports/reviews_by_user.rb +71 -0
- data/app/seeds/{reviews.rb → workarea/review_seeds.rb} +17 -6
- data/app/view_models/workarea/admin/dashboards/reports_view_model.decorator +11 -0
- data/app/view_models/workarea/admin/reports/reviews_by_product_view_model.rb +27 -0
- data/app/view_models/workarea/storefront/review_view_model.rb +9 -3
- data/app/views/workarea/admin/dashboards/_reviews_by_product_card.html.haml +17 -0
- data/app/views/workarea/admin/insights/_most_active_reviewers.html.haml +22 -0
- data/app/views/workarea/admin/insights/_most_reviewed_products.html.haml +22 -0
- data/app/views/workarea/admin/insights/_top_rated_products.html.haml +22 -0
- data/app/views/workarea/admin/reports/reviews_by_product.html.haml +44 -0
- data/app/views/workarea/storefront/products/_rating.html.haml +1 -2
- data/app/views/workarea/storefront/products/_reviews.html.haml +5 -5
- data/app/views/workarea/storefront/products/_reviews_aggregate.html.haml +2 -2
- data/app/views/workarea/storefront/review_mailer/review_request.html.haml +2 -0
- data/app/views/workarea/storefront/review_requests/show.html.haml +2 -1
- data/config/initializers/append_points.rb +5 -0
- data/config/initializers/configuration.rb +3 -1
- data/config/initializers/scheduled_jobs.rb +8 -6
- data/config/locales/en.yml +46 -0
- data/config/routes.rb +4 -0
- data/lib/workarea/reviews/engine.rb +4 -0
- data/lib/workarea/reviews/version.rb +1 -1
- data/package.json +9 -0
- data/test/dummy/config/initializers/session_store.rb +3 -1
- data/test/helpers/workarea/storefront/reviews_helper_test.rb +1 -1
- data/test/integration/workarea/admin/reviews_integration_test.rb +5 -1
- data/test/models/workarea/insights/most_active_reviewers_test.rb +32 -0
- data/test/models/workarea/insights/most_reviewed_products_test.rb +32 -0
- data/test/models/workarea/insights/top_rated_products_test.rb +49 -0
- data/test/models/workarea/review_test.rb +29 -18
- data/test/queries/workarea/reports/reviews_by_product_test.rb +104 -0
- data/test/queries/workarea/reports/reviews_by_user_test.rb +102 -0
- data/test/system/workarea/admin/reviews_by_product_system_test.rb +60 -0
- data/test/view_models/workarea/storefront/review_view_model_test.rb +46 -0
- data/workarea-reviews.gemspec +1 -1
- data/yarn.lock +3265 -0
- metadata +33 -8
- data/app/controllers/workarea/admin/import_reviews_controller.rb +0 -35
- data/test/helpers/workarea/admin/reviews_helper_test.rb +0 -17
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: a07fba40d273a1fd46dfa4575601eefe0eb742fafe6da2be58c2ca07fba3b51f
         | 
| 4 | 
            +
              data.tar.gz: 9a5f40859ec940937ac073bfc976ea1e899d05864f3cdf2e2b261b25a2963410
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 49005ddc4805c46ff4bcb725a1c6b30d53f616b912880c6c64404c57334e31281824ea1fe3109204981fbec7db255bc327be890d2fd536ef17a9a80e42e9efb6
         | 
| 7 | 
            +
              data.tar.gz: 27fc7ae007ceb0b676576a8a93e270869aa8c362d76054e15faa0863911be3872eed903604132d15382fdd52cdc5f251f21ed514b6a515a4b93c24187d2290ee
         | 
    
        data/.eslintrc.json
    ADDED
    
    | @@ -0,0 +1,35 @@ | |
| 1 | 
            +
            {
         | 
| 2 | 
            +
                "extends": "eslint:recommended",
         | 
| 3 | 
            +
                "rules": {
         | 
| 4 | 
            +
                  "semi": ["error", "always"],
         | 
| 5 | 
            +
                  "eqeqeq": ["error", "always"]
         | 
| 6 | 
            +
                },
         | 
| 7 | 
            +
                "globals": {
         | 
| 8 | 
            +
                  "window": true,
         | 
| 9 | 
            +
                  "document": true,
         | 
| 10 | 
            +
                  "WORKAREA": true,
         | 
| 11 | 
            +
                  "$": true,
         | 
| 12 | 
            +
                  "jQuery": true,
         | 
| 13 | 
            +
                  "_": true,
         | 
| 14 | 
            +
                  "feature": true,
         | 
| 15 | 
            +
                  "JST": true,
         | 
| 16 | 
            +
                  "Turbolinks": true,
         | 
| 17 | 
            +
                  "I18n": true,
         | 
| 18 | 
            +
                  "Chart": true,
         | 
| 19 | 
            +
                  "Dropzone": true,
         | 
| 20 | 
            +
                  "strftime": true,
         | 
| 21 | 
            +
                  "Waypoint": true,
         | 
| 22 | 
            +
                  "wysihtml": true,
         | 
| 23 | 
            +
                  "LocalTime": true,
         | 
| 24 | 
            +
                  "describe": true,
         | 
| 25 | 
            +
                  "after": true,
         | 
| 26 | 
            +
                  "afterEach": true,
         | 
| 27 | 
            +
                  "before": true,
         | 
| 28 | 
            +
                  "beforeEach": true,
         | 
| 29 | 
            +
                  "it": true,
         | 
| 30 | 
            +
                  "expect": true,
         | 
| 31 | 
            +
                  "sinon": true,
         | 
| 32 | 
            +
                  "fixture": true,
         | 
| 33 | 
            +
                  "chai": true
         | 
| 34 | 
            +
                }
         | 
| 35 | 
            +
            }
         | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            name: CI
         | 
| 2 | 
            +
            on: [push]
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            jobs:
         | 
| 5 | 
            +
              static_analysis:
         | 
| 6 | 
            +
                runs-on: ubuntu-latest
         | 
| 7 | 
            +
                steps:
         | 
| 8 | 
            +
                - uses: actions/checkout@v1
         | 
| 9 | 
            +
                - uses: workarea-commerce/ci/bundler-audit@v1
         | 
| 10 | 
            +
                - uses: workarea-commerce/ci/rubocop@v1
         | 
| 11 | 
            +
                - uses: workarea-commerce/ci/eslint@v1
         | 
| 12 | 
            +
                  with:
         | 
| 13 | 
            +
                    args: '**/*.js'
         | 
| 14 | 
            +
                - uses: workarea-commerce/ci/stylelint@v1
         | 
| 15 | 
            +
                  with:
         | 
| 16 | 
            +
                    args: '**/*.scss'
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              admin_tests:
         | 
| 19 | 
            +
                runs-on: ubuntu-latest
         | 
| 20 | 
            +
                steps:
         | 
| 21 | 
            +
                - uses: actions/checkout@v1
         | 
| 22 | 
            +
                - uses: actions/setup-ruby@v1
         | 
| 23 | 
            +
                  with:
         | 
| 24 | 
            +
                    ruby-version: 2.6.x
         | 
| 25 | 
            +
                - uses: workarea-commerce/ci/test@v1
         | 
| 26 | 
            +
                  with:
         | 
| 27 | 
            +
                    command: bin/rails app:workarea:test:admin
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              core_tests:
         | 
| 30 | 
            +
                runs-on: ubuntu-latest
         | 
| 31 | 
            +
                steps:
         | 
| 32 | 
            +
                - uses: actions/checkout@v1
         | 
| 33 | 
            +
                - uses: actions/setup-ruby@v1
         | 
| 34 | 
            +
                  with:
         | 
| 35 | 
            +
                    ruby-version: 2.6.x
         | 
| 36 | 
            +
                - uses: workarea-commerce/ci/test@v1
         | 
| 37 | 
            +
                  with:
         | 
| 38 | 
            +
                    command: bin/rails app:workarea:test:core
         | 
| 39 | 
            +
             | 
| 40 | 
            +
              storefront_tests:
         | 
| 41 | 
            +
                runs-on: ubuntu-latest
         | 
| 42 | 
            +
                steps:
         | 
| 43 | 
            +
                - uses: actions/checkout@v1
         | 
| 44 | 
            +
                - uses: actions/setup-ruby@v1
         | 
| 45 | 
            +
                  with:
         | 
| 46 | 
            +
                    ruby-version: 2.6.x
         | 
| 47 | 
            +
                - uses: workarea-commerce/ci/test@v1
         | 
| 48 | 
            +
                  with:
         | 
| 49 | 
            +
                    command: bin/rails app:workarea:test:storefront
         | 
| 50 | 
            +
             | 
| 51 | 
            +
              plugins_tests:
         | 
| 52 | 
            +
                runs-on: ubuntu-latest
         | 
| 53 | 
            +
                steps:
         | 
| 54 | 
            +
                - uses: actions/checkout@v1
         | 
| 55 | 
            +
                - uses: actions/setup-ruby@v1
         | 
| 56 | 
            +
                  with:
         | 
| 57 | 
            +
                    ruby-version: 2.6.x
         | 
| 58 | 
            +
                - uses: workarea-commerce/ci/test@v1
         | 
| 59 | 
            +
                  with:
         | 
| 60 | 
            +
                    command: bin/rails app:workarea:test:plugins
         | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/.rubocop.yml
    ADDED
    
    
    
        data/.stylelintrc.json
    ADDED
    
    
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,24 +1,36 @@ | |
| 1 | 
            -
            Workarea Reviews 3. | 
| 1 | 
            +
            Workarea Reviews 3.1.2 (2020-10-30)
         | 
| 2 2 | 
             
            --------------------------------------------------------------------------------
         | 
| 3 3 |  | 
| 4 | 
            -
            *    | 
| 4 | 
            +
            *   Handle reviews with user_ids that do not match a user
         | 
| 5 5 |  | 
| 6 | 
            +
                REVIEWS-6
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                Matt Duffy
         | 
| 6 9 |  | 
| 7 10 |  | 
| 8 | 
            -
             | 
| 11 | 
            +
             | 
| 12 | 
            +
            Workarea Reviews 3.1.1 (2020-01-07)
         | 
| 9 13 | 
             
            --------------------------------------------------------------------------------
         | 
| 10 14 |  | 
| 11 | 
            -
            *    | 
| 15 | 
            +
            *   Fix failing reviews helper test
         | 
| 12 16 |  | 
| 13 | 
            -
                 | 
| 14 | 
            -
                for those upgrading to a newer version some data needs to be changed in
         | 
| 15 | 
            -
                order to make this happen retroactively for older reviews. Add a Rake
         | 
| 16 | 
            -
                task for adding the `:verified` field to reviews where the user actually
         | 
| 17 | 
            -
                bought the product. For any reviews that are made after the upgrade,
         | 
| 18 | 
            -
                this will be automatically assigned as the review is being created.
         | 
| 17 | 
            +
                Idk how we didn't catch this, like, 6 years ago.
         | 
| 19 18 |  | 
| 20 | 
            -
                REVIEWS- | 
| 21 | 
            -
                 | 
| 19 | 
            +
                REVIEWS-5
         | 
| 20 | 
            +
                Curt Howard
         | 
| 21 | 
            +
             | 
| 22 | 
            +
             | 
| 23 | 
            +
             | 
| 24 | 
            +
            Workarea Reviews 3.1.0 (2019-11-26)
         | 
| 25 | 
            +
            --------------------------------------------------------------------------------
         | 
| 26 | 
            +
             | 
| 27 | 
            +
            *   Updates for v3.5 compatibility
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                Ben Crouse
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            *   Initial commit on master
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                Curt Howard
         | 
| 22 34 |  | 
| 23 35 |  | 
| 24 36 |  | 
    
        data/Gemfile
    CHANGED
    
    | @@ -1,6 +1,8 @@ | |
| 1 1 | 
             
            source 'https://rubygems.org'
         | 
| 2 | 
            -
            git_source(:github) { |repo| " | 
| 2 | 
            +
            git_source(:github) { |repo| "https://github.com/#{repo}.git" }
         | 
| 3 3 |  | 
| 4 4 | 
             
            gemspec
         | 
| 5 5 |  | 
| 6 | 
            -
            gem ' | 
| 6 | 
            +
            gem 'byebug'
         | 
| 7 | 
            +
             | 
| 8 | 
            +
            gem 'workarea', github: 'workarea-commerce/workarea', branch: 'v3.5-stable'
         | 
    
        data/Rakefile
    CHANGED
    
    | @@ -28,13 +28,12 @@ desc "Release version #{Workarea::Reviews::VERSION} of the gem" | |
| 28 28 | 
             
            task :release do
         | 
| 29 29 | 
             
              host = "https://#{ENV['BUNDLE_GEMS__WEBLINC__COM']}@gems.weblinc.com"
         | 
| 30 30 |  | 
| 31 | 
            -
               | 
| 32 | 
            -
               | 
| 33 | 
            -
               | 
| 34 | 
            -
              #system 'git push origin HEAD'
         | 
| 31 | 
            +
              Rake::Task['workarea:changelog'].execute
         | 
| 32 | 
            +
              system 'git add CHANGELOG.md'
         | 
| 33 | 
            +
              system 'git commit -m "Update CHANGELOG"'
         | 
| 35 34 |  | 
| 36 35 | 
             
              system "git tag -a v#{Workarea::Reviews::VERSION} -m 'Tagging #{Workarea::Reviews::VERSION}'"
         | 
| 37 | 
            -
              system 'git push --tags'
         | 
| 36 | 
            +
              system 'git push origin HEAD --follow-tags'
         | 
| 38 37 |  | 
| 39 38 | 
             
              system 'gem build workarea-reviews.gemspec'
         | 
| 40 39 | 
             
              system "gem push workarea-reviews-#{Workarea::Reviews::VERSION}.gem"
         | 
| @@ -1,11 +1,12 @@ | |
| 1 1 | 
             
            module Workarea
         | 
| 2 2 | 
             
              module Admin
         | 
| 3 3 | 
             
                module ReviewsHelper
         | 
| 4 | 
            -
                  def  | 
| 5 | 
            -
                     | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 4 | 
            +
                  def reviews_report_filter_options
         | 
| 5 | 
            +
                    [
         | 
| 6 | 
            +
                      [t('workarea.admin.reports.reviews_by_product.filters.all'), nil],
         | 
| 7 | 
            +
                      [t('workarea.admin.reports.reviews_by_product.filters.approved'), 'approved'],
         | 
| 8 | 
            +
                      [t('workarea.admin.reports.reviews_by_product.filters.unapproved'), 'unapproved']
         | 
| 9 | 
            +
                    ]
         | 
| 9 10 | 
             
                  end
         | 
| 10 11 | 
             
                end
         | 
| 11 12 | 
             
              end
         | 
| @@ -6,10 +6,8 @@ module Workarea | |
| 6 6 | 
             
                    empty_star_count = 5 - rating.ceil
         | 
| 7 7 | 
             
                    half_star_size = (rating % 1).round(2) * 100
         | 
| 8 8 | 
             
                    half_star_width = 20 + (half_star_size - 0) * (80.0 - 20) / (100.0 - 0)
         | 
| 9 | 
            -
                    itemprop = options[:aggregate] ? 'aggregateRating' : 'reviewRating'
         | 
| 10 | 
            -
                    itemtype = options[:aggregate] ? 'http://schema.org/AggregateRating' : 'http://schema.org/Rating'
         | 
| 11 9 |  | 
| 12 | 
            -
                    render 'workarea/storefront/products/rating', rating: rating, full_star_count: full_star_count, empty_star_count: empty_star_count, half_star_width: half_star_width, half_star_size: half_star_size | 
| 10 | 
            +
                    render 'workarea/storefront/products/rating', rating: rating, full_star_count: full_star_count, empty_star_count: empty_star_count, half_star_width: half_star_width, half_star_size: half_star_size
         | 
| 13 11 | 
             
                  end
         | 
| 14 12 |  | 
| 15 13 | 
             
                  def display_purchase_requirement_message
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            module Workarea
         | 
| 2 | 
            +
              module Storefront
         | 
| 3 | 
            +
                module ReviewsSchemaOrgHelper
         | 
| 4 | 
            +
                  def product_schema(product, related_products: nil)
         | 
| 5 | 
            +
                    schema = super.merge(
         | 
| 6 | 
            +
                      'review': product.reviews.map do |review|
         | 
| 7 | 
            +
                        {
         | 
| 8 | 
            +
                          '@type': 'Review',
         | 
| 9 | 
            +
                          'author': review.user_info,
         | 
| 10 | 
            +
                          'datePublished': review.created_at.strftime('%Y-%m-%d'),
         | 
| 11 | 
            +
                          'description': review.body,
         | 
| 12 | 
            +
                          'name': review.title,
         | 
| 13 | 
            +
                          'reviewRating': {
         | 
| 14 | 
            +
                            '@type': 'Rating',
         | 
| 15 | 
            +
                            'bestRating': '5',
         | 
| 16 | 
            +
                            'worstRating': '1',
         | 
| 17 | 
            +
                            'ratingValue': review.rating.round(2).to_s
         | 
| 18 | 
            +
                          }
         | 
| 19 | 
            +
                        }
         | 
| 20 | 
            +
                      end
         | 
| 21 | 
            +
                    )
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                    if product.total_reviews > 0 && product.average_rating.present?
         | 
| 24 | 
            +
                      schema['aggregateRating'] = {
         | 
| 25 | 
            +
                        'reviewCount': product.total_reviews.to_s,
         | 
| 26 | 
            +
                        'ratingValue': product.average_rating.round(2).to_s
         | 
| 27 | 
            +
                      }
         | 
| 28 | 
            +
                    end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                    schema
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 1 | 
            +
            module Workarea
         | 
| 2 | 
            +
              module Insights
         | 
| 3 | 
            +
                class MostActiveReviewers < Base
         | 
| 4 | 
            +
                  class << self
         | 
| 5 | 
            +
                    def dashboards
         | 
| 6 | 
            +
                      %w(people marketing)
         | 
| 7 | 
            +
                    end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def generate_monthly!
         | 
| 10 | 
            +
                      results = generate_results
         | 
| 11 | 
            +
                      create!(results: results) if results.present?
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    def generate_results
         | 
| 15 | 
            +
                      report
         | 
| 16 | 
            +
                        .results
         | 
| 17 | 
            +
                        .select { |r| r['reviews'] > 0 }
         | 
| 18 | 
            +
                        .take(Workarea.config.insights_users_list_max_results)
         | 
| 19 | 
            +
                        .map { |result| result.merge(email: result['_id']) }
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    def report
         | 
| 23 | 
            +
                      Reports::ReviewsByUser.new(
         | 
| 24 | 
            +
                        starts_at: beginning_of_last_month,
         | 
| 25 | 
            +
                        ends_at: end_of_last_month,
         | 
| 26 | 
            +
                        sort_by: 'activity_score',
         | 
| 27 | 
            +
                        sort_direction: 'desc',
         | 
| 28 | 
            +
                        results_filter: 'approved'
         | 
| 29 | 
            +
                      )
         | 
| 30 | 
            +
                    end
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
                end
         | 
| 33 | 
            +
              end
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            module Workarea
         | 
| 2 | 
            +
              module Insights
         | 
| 3 | 
            +
                class MostReviewedProducts < Base
         | 
| 4 | 
            +
                  class << self
         | 
| 5 | 
            +
                    def dashboards
         | 
| 6 | 
            +
                      %w(marketing)
         | 
| 7 | 
            +
                    end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def generate_monthly!
         | 
| 10 | 
            +
                      results = generate_results
         | 
| 11 | 
            +
                      create!(results: results) if results.present?
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    def generate_results
         | 
| 15 | 
            +
                      report
         | 
| 16 | 
            +
                        .results
         | 
| 17 | 
            +
                        .select { |r| r['reviews'] > 0 }
         | 
| 18 | 
            +
                        .take(Workarea.config.insights_products_list_max_results)
         | 
| 19 | 
            +
                        .map { |result| result.merge(product_id: result['_id']) }
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    def report
         | 
| 23 | 
            +
                      Reports::ReviewsByProduct.new(
         | 
| 24 | 
            +
                        starts_at: beginning_of_last_month,
         | 
| 25 | 
            +
                        ends_at: end_of_last_month,
         | 
| 26 | 
            +
                        sort_by: 'reviews',
         | 
| 27 | 
            +
                        sort_direction: 'desc'
         | 
| 28 | 
            +
                      )
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            module Workarea
         | 
| 2 | 
            +
              module Insights
         | 
| 3 | 
            +
                class TopRatedProducts < Base
         | 
| 4 | 
            +
                  class << self
         | 
| 5 | 
            +
                    def dashboards
         | 
| 6 | 
            +
                      %w(marketing)
         | 
| 7 | 
            +
                    end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                    def generate_monthly!
         | 
| 10 | 
            +
                      results = generate_results
         | 
| 11 | 
            +
                      create!(results: results) if results.present?
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    def generate_results
         | 
| 15 | 
            +
                      report
         | 
| 16 | 
            +
                        .results
         | 
| 17 | 
            +
                        .select { |r| r['reviews'] > 0 }
         | 
| 18 | 
            +
                        .take(Workarea.config.insights_products_list_max_results)
         | 
| 19 | 
            +
                        .map { |result| result.merge(product_id: result['_id']) }
         | 
| 20 | 
            +
                    end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                    def report
         | 
| 23 | 
            +
                      Reports::ReviewsByProduct.new(
         | 
| 24 | 
            +
                        starts_at: beginning_of_last_month,
         | 
| 25 | 
            +
                        ends_at: end_of_last_month,
         | 
| 26 | 
            +
                        sort_by: 'weighted_average_rating',
         | 
| 27 | 
            +
                        sort_direction: 'desc'
         | 
| 28 | 
            +
                      )
         | 
| 29 | 
            +
                    end
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
              end
         | 
| 33 | 
            +
            end
         | 
| @@ -95,23 +95,12 @@ module Workarea | |
| 95 95 | 
             
                # @return [Float]
         | 
| 96 96 | 
             
                #
         | 
| 97 97 | 
             
                def self.find_sorting_score(product_id)
         | 
| 98 | 
            -
                  reviews = find_for_product(product_id)
         | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
                            reviews.select { |r| r.rating == 3 }.length,
         | 
| 103 | 
            -
                            reviews.select { |r| r.rating == 4 }.length,
         | 
| 104 | 
            -
                            reviews.select { |r| r.rating == 5 }.length ]
         | 
| 105 | 
            -
             | 
| 106 | 
            -
                  prior = [2, 2, 2, 2, 2]
         | 
| 107 | 
            -
             | 
| 108 | 
            -
                  posterior = votes.zip(prior).map { |a, b| a + b }
         | 
| 109 | 
            -
                  sum = posterior.inject { |a, b| a + b }
         | 
| 98 | 
            +
                  reviews = find_for_product(product_id).to_a
         | 
| 99 | 
            +
                  count = (1..5).each_with_object({}) do |i, memo|
         | 
| 100 | 
            +
                    memo[i] = reviews.select { |r| r.rating == i }.length + 2
         | 
| 101 | 
            +
                  end
         | 
| 110 102 |  | 
| 111 | 
            -
                   | 
| 112 | 
            -
                    map.with_index { |v, i| (i + 1) * v }.
         | 
| 113 | 
            -
                    inject { |a, b| a + b }.
         | 
| 114 | 
            -
                    to_f / sum
         | 
| 103 | 
            +
                  count.sum { |rating, count| rating * count }.to_f / count.values.sum
         | 
| 115 104 | 
             
                end
         | 
| 116 105 |  | 
| 117 106 | 
             
                def anonymous?
         | 
| @@ -0,0 +1,86 @@ | |
| 1 | 
            +
            module Workarea
         | 
| 2 | 
            +
              module Reports
         | 
| 3 | 
            +
                class ReviewsByProduct
         | 
| 4 | 
            +
                  include Report
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                  self.reporting_class = Review
         | 
| 7 | 
            +
                  self.sort_fields = %w(reviews verified average_rating weighted_average_rating)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  def aggregation
         | 
| 10 | 
            +
                    [filter_results, project_used_fields, group_by_product, project_averages]
         | 
| 11 | 
            +
                  end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  def filter_results
         | 
| 14 | 
            +
                    {
         | 
| 15 | 
            +
                      '$match' => {
         | 
| 16 | 
            +
                        'created_at' => { '$gte' => starts_at, '$lte' => ends_at },
         | 
| 17 | 
            +
                        **approval_query
         | 
| 18 | 
            +
                      }
         | 
| 19 | 
            +
                    }
         | 
| 20 | 
            +
                  end
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  def project_used_fields
         | 
| 23 | 
            +
                    {
         | 
| 24 | 
            +
                      '$project' => {
         | 
| 25 | 
            +
                        'product_id' => 1,
         | 
| 26 | 
            +
                        'rating' => 1,
         | 
| 27 | 
            +
                        'verified' => 1
         | 
| 28 | 
            +
                      }
         | 
| 29 | 
            +
                    }
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  def group_by_product
         | 
| 33 | 
            +
                    {
         | 
| 34 | 
            +
                      '$group' => {
         | 
| 35 | 
            +
                        '_id' => '$product_id',
         | 
| 36 | 
            +
                        'reviews' => { '$sum' => 1 },
         | 
| 37 | 
            +
                        'verified' => { '$sum' => { '$cond' => { 'if' => '$verified', 'then' => 1, 'else' => 0 } } },
         | 
| 38 | 
            +
                        'rating_tally' => { '$sum' => '$rating' },
         | 
| 39 | 
            +
                        'rated_5' => { '$sum' => { '$cond' => { 'if' => { '$eq' => ['$rating', 5] }, 'then' => 1, 'else' => 0 } } },
         | 
| 40 | 
            +
                        'rated_4' => { '$sum' => { '$cond' => { 'if' => { '$eq' => ['$rating', 4] }, 'then' => 1, 'else' => 0 } } },
         | 
| 41 | 
            +
                        'rated_3' => { '$sum' => { '$cond' => { 'if' => { '$eq' => ['$rating', 3] }, 'then' => 1, 'else' => 0 } } },
         | 
| 42 | 
            +
                        'rated_2' => { '$sum' => { '$cond' => { 'if' => { '$eq' => ['$rating', 2] }, 'then' => 1, 'else' => 0 } } },
         | 
| 43 | 
            +
                        'rated_1' => { '$sum' => { '$cond' => { 'if' => { '$eq' => ['$rating', 1] }, 'then' => 1, 'else' => 0 } } }
         | 
| 44 | 
            +
                      }
         | 
| 45 | 
            +
                    }
         | 
| 46 | 
            +
                  end
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  def project_averages
         | 
| 49 | 
            +
                    {
         | 
| 50 | 
            +
                      '$project' => {
         | 
| 51 | 
            +
                        'product_id' => 1,
         | 
| 52 | 
            +
                        'reviews' => 1,
         | 
| 53 | 
            +
                        'verified' => 1,
         | 
| 54 | 
            +
                        'average_rating' => { '$divide' => ['$rating_tally', '$reviews'] },
         | 
| 55 | 
            +
                        'weighted_average_rating' => {
         | 
| 56 | 
            +
                          '$divide' => [
         | 
| 57 | 
            +
                            {
         | 
| 58 | 
            +
                              '$sum' => [
         | 
| 59 | 
            +
                                { '$multiply' => [{ '$sum' => [2, '$rated_5'] }, 5] },
         | 
| 60 | 
            +
                                { '$multiply' => [{ '$sum' => [2, '$rated_4'] }, 4] },
         | 
| 61 | 
            +
                                { '$multiply' => [{ '$sum' => [2, '$rated_3'] }, 3] },
         | 
| 62 | 
            +
                                { '$multiply' => [{ '$sum' => [2, '$rated_2'] }, 2] },
         | 
| 63 | 
            +
                                { '$multiply' => [{ '$sum' => [2, '$rated_1'] }, 1] }
         | 
| 64 | 
            +
                              ]
         | 
| 65 | 
            +
                            },
         | 
| 66 | 
            +
                            { '$sum' => [10, '$rated_5', '$rated_4', '$rated_3', '$rated_2', '$rated_1'] }
         | 
| 67 | 
            +
                          ]
         | 
| 68 | 
            +
                        }
         | 
| 69 | 
            +
                      }
         | 
| 70 | 
            +
                    }
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                  private
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                  def approval_query
         | 
| 76 | 
            +
                    if params[:results_filter] == 'approved'
         | 
| 77 | 
            +
                      { approved: true }
         | 
| 78 | 
            +
                    elsif params[:results_filter] == 'unapproved'
         | 
| 79 | 
            +
                      { approved: false }
         | 
| 80 | 
            +
                    else
         | 
| 81 | 
            +
                      {}
         | 
| 82 | 
            +
                    end
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
              end
         | 
| 86 | 
            +
            end
         |