workarea-reviews 3.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.editorconfig +20 -0
- data/.eslintignore +2 -0
- data/.eslintrc +24 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +37 -0
- data/.github/ISSUE_TEMPLATE/documentation-request.md +17 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.gitignore +16 -0
- data/.scss-lint.yml +188 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +763 -0
- data/CODE_OF_CONDUCT.md +3 -0
- data/CONTRIBUTING.md +3 -0
- data/Gemfile +6 -0
- data/LICENSE +52 -0
- data/README.md +107 -0
- data/Rakefile +54 -0
- data/app/assets/images/workarea/admin/icons/star.svg +1 -0
- data/app/assets/images/workarea/storefront/icons/empty_star.svg +1 -0
- data/app/assets/images/workarea/storefront/icons/half_star.svg +1 -0
- data/app/assets/images/workarea/storefront/icons/star.svg +1 -0
- data/app/assets/javascripts/workarea/storefront/reviews/modules/product_review_ajax_submit.js +39 -0
- data/app/assets/javascripts/workarea/storefront/reviews/modules/product_reviews_sort_menus.js +82 -0
- data/app/assets/javascripts/workarea/storefront/reviews/modules/rating_buttons.js +103 -0
- data/app/assets/javascripts/workarea/storefront/reviews/templates/sort_by_property.jst.ejs +11 -0
- data/app/assets/stylesheets/workarea/storefront/reviews/components/_rating.scss +28 -0
- data/app/assets/stylesheets/workarea/storefront/reviews/components/_reviews.scss +59 -0
- data/app/assets/stylesheets/workarea/storefront/reviews/components/_reviews_aggregate.scss +38 -0
- data/app/assets/stylesheets/workarea/storefront/reviews/components/_write_review.scss +63 -0
- data/app/controllers/workarea/admin/catalog_products_controller.decorator +9 -0
- data/app/controllers/workarea/admin/import_reviews_controller.rb +35 -0
- data/app/controllers/workarea/admin/reviews_controller.rb +51 -0
- data/app/controllers/workarea/storefront/review_requests_controller.rb +50 -0
- data/app/controllers/workarea/storefront/reviews_controller.rb +53 -0
- data/app/helpers/workarea/admin/reviews_helper.rb +12 -0
- data/app/helpers/workarea/storefront/reviews_helper.rb +24 -0
- data/app/mailers/workarea/admin/status_report_mailer.decorator +8 -0
- data/app/mailers/workarea/storefront/review_mailer.rb +23 -0
- data/app/models/workarea/catalog/product.decorator +15 -0
- data/app/models/workarea/fulfillment.decorator +11 -0
- data/app/models/workarea/review.rb +135 -0
- data/app/models/workarea/review/request.rb +62 -0
- data/app/models/workarea/search/admin/review.rb +72 -0
- data/app/models/workarea/search/storefront/product.decorator +9 -0
- data/app/models/workarea/sort.decorator +17 -0
- data/app/queries/workarea/review_request_params.rb +47 -0
- data/app/queries/workarea/review_summary.rb +11 -0
- data/app/queries/workarea/search/admin_reviews.rb +40 -0
- data/app/queries/workarea/search/category_browse.decorator +9 -0
- data/app/queries/workarea/search/product_search.decorator +9 -0
- data/app/seeds/review_seeds.rb +49 -0
- data/app/services/workarea/create_review.rb +99 -0
- data/app/view_models/workarea/admin/product_view_model.decorator +7 -0
- data/app/view_models/workarea/admin/review_view_model.rb +23 -0
- data/app/view_models/workarea/admin/reviews_search_view_model.rb +46 -0
- data/app/view_models/workarea/storefront/product_view_model.decorator +13 -0
- data/app/view_models/workarea/storefront/review_view_model.rb +14 -0
- data/app/views/workarea/admin/activities/_review_create.html.haml +12 -0
- data/app/views/workarea/admin/activities/_review_destroy.html.haml +10 -0
- data/app/views/workarea/admin/activities/_review_update.html.haml +10 -0
- data/app/views/workarea/admin/reviews/_aux_navigation.html.haml +5 -0
- data/app/views/workarea/admin/reviews/_catalog_products_aux_link.html.haml +5 -0
- data/app/views/workarea/admin/reviews/_dashboard_navigation.html.haml +1 -0
- data/app/views/workarea/admin/reviews/_menu.html.haml +3 -0
- data/app/views/workarea/admin/reviews/_summary.html.haml +12 -0
- data/app/views/workarea/admin/reviews/edit.html.haml +77 -0
- data/app/views/workarea/admin/reviews/index.html.haml +74 -0
- data/app/views/workarea/admin/status_report_mailer/_reviews.html.haml +5 -0
- data/app/views/workarea/storefront/products/_rating.html.haml +10 -0
- data/app/views/workarea/storefront/products/_reviews.html.haml +23 -0
- data/app/views/workarea/storefront/products/_reviews_aggregate.html.haml +22 -0
- data/app/views/workarea/storefront/products/_reviews_summary.html.haml +2 -0
- data/app/views/workarea/storefront/review_mailer/review_request.html.haml +22 -0
- data/app/views/workarea/storefront/review_requests/show.html.haml +44 -0
- data/app/views/workarea/storefront/reviews/new.html.haml +68 -0
- data/app/views/workarea/storefront/style_guides/_reviews_product_summary_docs.html.haml +13 -0
- data/app/views/workarea/storefront/style_guides/components/_reviews.html.haml +17 -0
- data/app/workers/workarea/create_review_requests.rb +33 -0
- data/app/workers/workarea/schedule_review_requests.rb +44 -0
- data/app/workers/workarea/send_review_requests.rb +12 -0
- data/app/workers/workarea/update_product_review_data.rb +26 -0
- data/bin/rails +18 -0
- data/config/initializers/append_points.rb +70 -0
- data/config/initializers/assets.rb +1 -0
- data/config/initializers/configuration.rb +29 -0
- data/config/initializers/rack_attack.rb +11 -0
- data/config/initializers/recaptcha.rb +19 -0
- data/config/initializers/scheduled_jobs.rb +8 -0
- data/config/locales/en.yml +104 -0
- data/config/routes.rb +21 -0
- data/lib/tasks/verify.rake +16 -0
- data/lib/workarea/mailer_previews/storefront/review_mailer_preview.rb +10 -0
- data/lib/workarea/reviews.rb +13 -0
- data/lib/workarea/reviews/engine.rb +12 -0
- data/lib/workarea/reviews/version.rb +5 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/config/manifest.js +4 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/jobs/application_job.rb +2 -0
- data/test/dummy/app/mailers/application_mailer.rb +4 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +34 -0
- data/test/dummy/bin/update +29 -0
- data/test/dummy/config.ru +5 -0
- data/test/dummy/config/application.rb +25 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/cable.yml +9 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +55 -0
- data/test/dummy/config/environments/production.rb +86 -0
- data/test/dummy/config/environments/test.rb +43 -0
- data/test/dummy/config/initializers/application_controller_renderer.rb +6 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/new_framework_defaults.rb +21 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/workarea.rb +5 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/puma.rb +47 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/config/spring.rb +6 -0
- data/test/dummy/db/seeds.rb +2 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/factories/reviews.rb +32 -0
- data/test/fixtures/reviews.csv +5 -0
- data/test/helpers/workarea/admin/reviews_helper_test.rb +17 -0
- data/test/helpers/workarea/storefront/reviews_helper_test.rb +19 -0
- data/test/integration/workarea/admin/reviews_integration_test.rb +33 -0
- data/test/integration/workarea/storefront/review_requests_integration_test.rb +63 -0
- data/test/integration/workarea/storefront/reviews_integration_test.rb +82 -0
- data/test/javascripts/fixtures/product_review_ajax_submit.html.haml +4 -0
- data/test/javascripts/product_review_ajax_submit_spec.js +28 -0
- data/test/javascripts/spec_helper.js +23 -0
- data/test/models/workarea/review/request_test.rb +18 -0
- data/test/models/workarea/review_test.rb +94 -0
- data/test/models/workarea/search/storefront/product_test.decorator +14 -0
- data/test/queries/workarea/review_request_params_test.rb +64 -0
- data/test/services/workarea/create_review_test.rb +131 -0
- data/test/system/workarea/admin/review_system_test.rb +96 -0
- data/test/system/workarea/storefront/review_request_system_test.rb +34 -0
- data/test/system/workarea/storefront/review_system_test.rb +113 -0
- data/test/teaspoon_env.rb +10 -0
- data/test/test_helper.rb +11 -0
- data/test/workers/workarea/create_review_requests_test.rb +38 -0
- data/test/workers/workarea/schedule_review_requests_test.rb +115 -0
- data/test/workers/workarea/send_review_requests_test.rb +30 -0
- data/workarea-reviews.gemspec +22 -0
- metadata +241 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Storefront
|
3
|
+
class ReviewMailer < Storefront::ApplicationMailer
|
4
|
+
include TransactionalMailer
|
5
|
+
|
6
|
+
def review_request(request_id)
|
7
|
+
@request = Review::Request.find(request_id)
|
8
|
+
@content = Content::Email.find_content('review_request')
|
9
|
+
@product = Storefront::ProductViewModel.wrap(
|
10
|
+
Catalog::Product.find(@request.product_id)
|
11
|
+
)
|
12
|
+
|
13
|
+
mail(
|
14
|
+
to: @request.email,
|
15
|
+
subject: t(
|
16
|
+
'workarea.storefront.email.review_request.subject',
|
17
|
+
product: @product.name
|
18
|
+
)
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Catalog::Product, with: :reviews do
|
3
|
+
decorated do
|
4
|
+
# @!attribute total_reviews
|
5
|
+
# @return [Integer] the total number of approved reviews
|
6
|
+
#
|
7
|
+
field :total_reviews, type: Integer, default: 0
|
8
|
+
|
9
|
+
# @!attribute average_rating
|
10
|
+
# @return [Float] the average rating of approved reviews
|
11
|
+
#
|
12
|
+
field :average_rating, type: Float
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Fulfillment, with: :reviews do
|
3
|
+
def ship_items(tracking_number, shipped_items)
|
4
|
+
super.tap do |result|
|
5
|
+
if result && Workarea.config.send_transactional_emails
|
6
|
+
ScheduleReviewRequests.perform_async(id, shipped_items)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module Workarea
|
2
|
+
class Review
|
3
|
+
include ApplicationDocument
|
4
|
+
|
5
|
+
field :user_id, type: String
|
6
|
+
field :user_info, type: String
|
7
|
+
field :first_name, type: String
|
8
|
+
field :last_name, type: String
|
9
|
+
field :email, type: String
|
10
|
+
field :product_id, type: String
|
11
|
+
field :rating, type: Integer
|
12
|
+
field :title, type: String
|
13
|
+
field :body, type: String
|
14
|
+
field :approved, type: Boolean, default: false
|
15
|
+
field :verified, type: Boolean, default: false
|
16
|
+
|
17
|
+
index(product_id: 1, approved: 1)
|
18
|
+
index(approved: 1)
|
19
|
+
index(created_at: 1)
|
20
|
+
|
21
|
+
validates :product_id, presence: true
|
22
|
+
validates :user_info, presence: true
|
23
|
+
validates :body, presence: true
|
24
|
+
validates :rating, presence: true,
|
25
|
+
numericality: {
|
26
|
+
greater_than_or_equal_to: 1,
|
27
|
+
less_than_or_equal_to: 5,
|
28
|
+
only_integer: true
|
29
|
+
}
|
30
|
+
|
31
|
+
validate :user_must_have_spent_money_to_create_review
|
32
|
+
|
33
|
+
before_save :ensure_title
|
34
|
+
|
35
|
+
scope :by_product, ->(id) { where(product_id: id) }
|
36
|
+
scope :approved, -> { where(approved: true) }
|
37
|
+
scope :pending, -> { where(approved: false) }
|
38
|
+
|
39
|
+
def self.sorts
|
40
|
+
[ Workarea::Sort.pending,
|
41
|
+
Workarea::Sort.newest,
|
42
|
+
Workarea::Sort.modified,
|
43
|
+
Workarea::Sort.title,
|
44
|
+
Workarea::Sort.rating ]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Get {Mongoid::Criteria} for the reviews for a certain product.
|
48
|
+
# Optionally allow including unapproved reviews (for the admin).
|
49
|
+
#
|
50
|
+
# @param [String] product_id
|
51
|
+
# @param [optional, Boolean] allow_unapproved
|
52
|
+
# @return [Mongoid::Criteria]
|
53
|
+
#
|
54
|
+
def self.find_for_product(product_id, allow_unapproved = false)
|
55
|
+
criteria = by_product(product_id)
|
56
|
+
allow_unapproved ? criteria : criteria.approved
|
57
|
+
end
|
58
|
+
|
59
|
+
# Lookup aggregate stats on product reviews for a product.
|
60
|
+
#
|
61
|
+
# @param [String] product_id
|
62
|
+
# @return [Hash]
|
63
|
+
#
|
64
|
+
def self.find_single_aggregates(product_id)
|
65
|
+
stats = by_product(product_id).approved.aggregates(:rating)
|
66
|
+
{ count: stats['count'] || 0, average: stats['avg'] || 0 }
|
67
|
+
end
|
68
|
+
|
69
|
+
# Lookup aggregate review stats on multiple products.
|
70
|
+
# Used for show stats on browse/detail.
|
71
|
+
#
|
72
|
+
# @param [Array<String>] product_ids
|
73
|
+
# @return [Hash] results Keys are product IDs, values are stats Hash
|
74
|
+
#
|
75
|
+
def self.find_aggregates(*product_ids)
|
76
|
+
product_ids = Array(product_ids).flatten
|
77
|
+
|
78
|
+
if product_ids.one?
|
79
|
+
find_single_aggregates(product_ids.first)
|
80
|
+
else
|
81
|
+
product_ids.inject({}) do |memo, product_id|
|
82
|
+
memo[product_id] = find_single_aggregates(product_id)
|
83
|
+
memo
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Find sort score for a product. Used in the search index for sorting by
|
89
|
+
# best reviewed.
|
90
|
+
#
|
91
|
+
# Balances a small number of ratings with the uncertainty of only having a few ratings.
|
92
|
+
# See: http://masanjin.net/blog/how-to-rank-products-based-on-user-input
|
93
|
+
#
|
94
|
+
# @param [String] product_id
|
95
|
+
# @return [Float]
|
96
|
+
#
|
97
|
+
def self.find_sorting_score(product_id)
|
98
|
+
reviews = find_for_product(product_id)
|
99
|
+
|
100
|
+
votes = [ reviews.select { |r| r.rating == 1 }.length,
|
101
|
+
reviews.select { |r| r.rating == 2 }.length,
|
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 }
|
110
|
+
|
111
|
+
posterior.
|
112
|
+
map.with_index { |v, i| (i + 1) * v }.
|
113
|
+
inject { |a, b| a + b }.
|
114
|
+
to_f / sum
|
115
|
+
end
|
116
|
+
|
117
|
+
def anonymous?
|
118
|
+
!user_id.present?
|
119
|
+
end
|
120
|
+
|
121
|
+
def ensure_title
|
122
|
+
self.title = body.truncate(50) if title.blank?
|
123
|
+
end
|
124
|
+
|
125
|
+
def user_must_have_spent_money_to_create_review
|
126
|
+
if Workarea.config.require_purchase_to_post_review
|
127
|
+
user = User.find(user_id)
|
128
|
+
if user.total_spent.to_f.zero?
|
129
|
+
err_msg = I18n.t('workarea.storefront.reviews.total_spent_validation')
|
130
|
+
errors.add(:user, err_msg)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Workarea
|
2
|
+
class Review
|
3
|
+
class Request
|
4
|
+
include ApplicationDocument
|
5
|
+
include UrlToken
|
6
|
+
|
7
|
+
field :order_id, type: String
|
8
|
+
field :user_id, type: String
|
9
|
+
field :product_id, type: String
|
10
|
+
|
11
|
+
field :email, type: String
|
12
|
+
|
13
|
+
field :send_after, type: DateTime
|
14
|
+
field :sent_at, type: DateTime
|
15
|
+
field :completed_at, type: DateTime
|
16
|
+
field :canceled_at, type: DateTime
|
17
|
+
|
18
|
+
index(order_id: 1)
|
19
|
+
index(send_after: 1, sent_at: 1, canceled_at: 1)
|
20
|
+
|
21
|
+
index(
|
22
|
+
{ created_at: 1 },
|
23
|
+
{ expire_after_seconds: Workarea.config.review_request_ttl }
|
24
|
+
)
|
25
|
+
|
26
|
+
scope :by_order, ->(order_id) { where(order_id: order_id) }
|
27
|
+
scope :ready_to_send, ->(from = Time.current) do
|
28
|
+
where(:send_after.lte => from, :sent_at => nil, :canceled_at => nil)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.cancel_for_orders!(order_ids)
|
32
|
+
self.in(order_id: Array.wrap(order_ids))
|
33
|
+
.where(completed_at: nil)
|
34
|
+
.update_all(canceled_at: Time.current)
|
35
|
+
end
|
36
|
+
|
37
|
+
def scheduled?
|
38
|
+
send_after.present?
|
39
|
+
end
|
40
|
+
|
41
|
+
def sent?
|
42
|
+
sent_at.present?
|
43
|
+
end
|
44
|
+
|
45
|
+
def completed?
|
46
|
+
completed_at.present? || canceled?
|
47
|
+
end
|
48
|
+
|
49
|
+
def canceled?
|
50
|
+
canceled_at.present?
|
51
|
+
end
|
52
|
+
|
53
|
+
def complete!
|
54
|
+
update_attributes(completed_at: Time.current)
|
55
|
+
end
|
56
|
+
|
57
|
+
def send!
|
58
|
+
update_attributes(sent_at: Time.current)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Search
|
3
|
+
class Admin
|
4
|
+
class Review < Search::Admin
|
5
|
+
def type
|
6
|
+
'review'
|
7
|
+
end
|
8
|
+
|
9
|
+
def status
|
10
|
+
'active'
|
11
|
+
end
|
12
|
+
|
13
|
+
def facets
|
14
|
+
super.merge(
|
15
|
+
state: state,
|
16
|
+
rating: model.rating,
|
17
|
+
verification: verification
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def jump_to_text
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def name
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def jump_to_position
|
30
|
+
6
|
31
|
+
end
|
32
|
+
|
33
|
+
def search_text
|
34
|
+
[model.product_id, model.user_id]
|
35
|
+
end
|
36
|
+
|
37
|
+
def review_text
|
38
|
+
[model.title, model.body, product&.name].compact
|
39
|
+
end
|
40
|
+
|
41
|
+
def state
|
42
|
+
if model.approved?
|
43
|
+
I18n.t('workarea.admin.reviews.approved')
|
44
|
+
else
|
45
|
+
I18n.t('workarea.admin.reviews.pending')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def verification
|
50
|
+
if model.verified?
|
51
|
+
I18n.t('workarea.admin.reviews.verified')
|
52
|
+
else
|
53
|
+
I18n.t('workarea.admin.reviews.unverified')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def as_document
|
58
|
+
super.merge(
|
59
|
+
review_text: review_text,
|
60
|
+
rating: model.rating
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def product
|
67
|
+
@product ||= Catalog::Product.find(model.product_id) rescue nil
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Workarea
|
2
|
+
decorate Sort, with: :reviews do
|
3
|
+
class_methods do
|
4
|
+
def top_rated
|
5
|
+
new(I18n.t('workarea.sorts.top_rated'), :top_rated, :'sorts.rating', :desc)
|
6
|
+
end
|
7
|
+
|
8
|
+
def highest_rating
|
9
|
+
new(I18n.t('workarea.sorts.highest_rating'), :highest_rating, :rating, :desc)
|
10
|
+
end
|
11
|
+
|
12
|
+
def lowest_rating
|
13
|
+
new(I18n.t('workarea.sorts.lowest_rating'), :lowest_rating, :rating, :asc)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Workarea
|
2
|
+
class ReviewRequestParams
|
3
|
+
attr_reader :request, :params
|
4
|
+
|
5
|
+
def initialize(request, params)
|
6
|
+
@request = request
|
7
|
+
@params = params
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_h
|
11
|
+
params.merge(
|
12
|
+
product_id: @request.product_id,
|
13
|
+
user_id: @request.user_id,
|
14
|
+
email: @request.email,
|
15
|
+
user_info: user_info,
|
16
|
+
first_name: first_name,
|
17
|
+
last_name: last_name,
|
18
|
+
verified: true
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def user_info
|
25
|
+
return user.public_info if user&.public_info.present?
|
26
|
+
|
27
|
+
[first_name.first, last_name.first].join
|
28
|
+
end
|
29
|
+
|
30
|
+
def first_name
|
31
|
+
user&.first_name || billing_address.first_name
|
32
|
+
end
|
33
|
+
|
34
|
+
def last_name
|
35
|
+
user&.last_name || billing_address.last_name
|
36
|
+
end
|
37
|
+
|
38
|
+
def user
|
39
|
+
return nil unless @request.user_id.present?
|
40
|
+
@user ||= User.find(@request.user_id)
|
41
|
+
end
|
42
|
+
|
43
|
+
def billing_address
|
44
|
+
@billing_address ||= Payment.find(@request.order_id).address
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Workarea
|
2
|
+
module Search
|
3
|
+
class AdminReviews
|
4
|
+
include Query
|
5
|
+
include AdminIndexSearch
|
6
|
+
include AdminSorting
|
7
|
+
include Pagination
|
8
|
+
|
9
|
+
document Search::Admin
|
10
|
+
|
11
|
+
def initialize(params = {})
|
12
|
+
super(params.merge(type: 'review'))
|
13
|
+
end
|
14
|
+
|
15
|
+
def fields
|
16
|
+
super + %w(review_text)
|
17
|
+
end
|
18
|
+
|
19
|
+
def facets
|
20
|
+
super + [
|
21
|
+
TermsFacet.new(self, 'state'),
|
22
|
+
TermsFacet.new(self, 'rating'),
|
23
|
+
TermsFacet.new(self, 'verification')
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
def sort
|
28
|
+
result = super || []
|
29
|
+
|
30
|
+
if params[:sort] == Sort.highest_rating.to_s
|
31
|
+
result.prepend(Sort.highest_rating.field => Sort.highest_rating.direction)
|
32
|
+
elsif params[:sort] == Sort.lowest_rating.to_s
|
33
|
+
result.prepend(Sort.lowest_rating.field => Sort.lowest_rating.direction)
|
34
|
+
end
|
35
|
+
|
36
|
+
result
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|