study_engine 0.0.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 +7 -0
- data/Rakefile +42 -0
- data/app/assets/images/study_engine/spinner.gif +0 -0
- data/app/assets/images/study_engine/sprite/delete.png +0 -0
- data/app/assets/images/study_engine/sprite/download.png +0 -0
- data/app/assets/images/study_engine/sprite/edit.png +0 -0
- data/app/assets/images/study_engine/sprite/incomplete.png +0 -0
- data/app/assets/images/study_engine/sprite/metrc-sm.png +0 -0
- data/app/assets/images/study_engine/sprite/metrc.png +0 -0
- data/app/assets/images/study_engine/sprite/new.png +0 -0
- data/app/assets/javascripts/study_engine/admin_notes.js.coffee +12 -0
- data/app/assets/javascripts/study_engine/assessment_notifications.js.coffee +36 -0
- data/app/assets/javascripts/study_engine/assessment_timeout.js.coffee +24 -0
- data/app/assets/javascripts/study_engine/disable_buttons_after_click.js.coffee +6 -0
- data/app/assets/javascripts/study_engine/fire_click_event_immediately_on_mobile.js.coffee.erb +10 -0
- data/app/assets/javascripts/study_engine/response_validation.js.coffee +8 -0
- data/app/assets/javascripts/study_engine/restart_assessment_button.js.coffee +3 -0
- data/app/assets/javascripts/study_engine/study_engine.js.coffee +9 -0
- data/app/assets/javascripts/study_engine/study_id_picker.js.coffee +28 -0
- data/app/assets/stylesheets/study_engine.sass +1 -0
- data/app/assets/stylesheets/study_engine/_constant.sass +52 -0
- data/app/assets/stylesheets/study_engine/_mobile.sass +8 -0
- data/app/assets/stylesheets/study_engine/_tablet.sass +36 -0
- data/app/assets/stylesheets/study_engine/application.sass +101 -0
- data/app/assets/stylesheets/study_engine/base/_form.sass +131 -0
- data/app/assets/stylesheets/study_engine/base/_list.sass +38 -0
- data/app/assets/stylesheets/study_engine/base/_tables.sass +33 -0
- data/app/assets/stylesheets/study_engine/base/_text.sass +78 -0
- data/app/assets/stylesheets/study_engine/components/-fields/_login-fields.sass +14 -0
- data/app/assets/stylesheets/study_engine/components/-fields/_start-fields.sass +101 -0
- data/app/assets/stylesheets/study_engine/components/-nav/_global-nav.sass +19 -0
- data/app/assets/stylesheets/study_engine/components/-table/_results-table.sass +75 -0
- data/app/assets/stylesheets/study_engine/components/-table/_users-table.sass +11 -0
- data/app/assets/stylesheets/study_engine/components/_assessment-questions.sass +30 -0
- data/app/assets/stylesheets/study_engine/components/_form-buttons.sass +102 -0
- data/app/assets/stylesheets/study_engine/components/_helpt-text.sass +2 -0
- data/app/assets/stylesheets/study_engine/components/_method-icons.sass +15 -0
- data/app/assets/stylesheets/study_engine/components/_notes-modal.sass +65 -0
- data/app/assets/stylesheets/study_engine/components/_progress-bar.sass +25 -0
- data/app/assets/stylesheets/study_engine/components/_sortable-columns.sass +26 -0
- data/app/assets/stylesheets/study_engine/components/_table-actions.sass +8 -0
- data/app/assets/stylesheets/study_engine/components/_table-buttons.sass +17 -0
- data/app/assets/stylesheets/study_engine/components/_user-privileges.sass +3 -0
- data/app/assets/stylesheets/study_engine/mixins/_actions-table.sass +11 -0
- data/app/assets/stylesheets/study_engine/mixins/_buttons.sass +55 -0
- data/app/assets/stylesheets/study_engine/mixins/_checkbox-columns.sass +50 -0
- data/app/assets/stylesheets/study_engine/mixins/_custom-radios.sass +47 -0
- data/app/assets/stylesheets/study_engine/mixins/_icons.sass +38 -0
- data/app/assets/stylesheets/study_engine/mixins/_notification-text.sass +23 -0
- data/app/controllers/study_engine/admin/application_controller.rb +6 -0
- data/app/controllers/study_engine/admin/assessments_controller.rb +79 -0
- data/app/controllers/study_engine/admin/notes_controller.rb +17 -0
- data/app/controllers/study_engine/application_controller.rb +12 -0
- data/app/controllers/study_engine/assessments_controller.rb +94 -0
- data/app/helpers/study_engine/helpers.rb +15 -0
- data/app/helpers/study_engine/mailer_helpers.rb +11 -0
- data/app/mailers/study_engine/mailer.rb +25 -0
- data/app/models/study_engine/answer.rb +36 -0
- data/app/models/study_engine/assessment.rb +118 -0
- data/app/models/study_engine/begin_assessment_form.rb +110 -0
- data/app/models/study_engine/existing_assessments_form.rb +99 -0
- data/app/models/study_engine/form.rb +59 -0
- data/app/models/study_engine/report.rb +69 -0
- data/app/models/study_engine/result.rb +46 -0
- data/app/models/study_engine/screen_results.rb +54 -0
- data/app/models/study_engine/study_id.rb +47 -0
- data/app/models/study_engine/study_id/bank.rb +38 -0
- data/app/models/study_engine/study_id/sync.rb +52 -0
- data/app/models/study_engine/update_assessments_form.rb +53 -0
- data/app/views/study_engine/_progress_bar.html.slim +4 -0
- data/app/views/study_engine/admin/assessments/_assessment.html.slim +36 -0
- data/app/views/study_engine/admin/assessments/domain_results.csv.csvbuilder +17 -0
- data/app/views/study_engine/admin/assessments/edit.html.slim +68 -0
- data/app/views/study_engine/admin/assessments/index.html.slim +26 -0
- data/app/views/study_engine/admin/assessments/item_results.csv.csvbuilder +24 -0
- data/app/views/study_engine/admin/assessments/new.html.slim +46 -0
- data/app/views/study_engine/admin/assessments/screen_results.csv.csvbuilder +2 -0
- data/app/views/study_engine/assessments/complete.html.slim +25 -0
- data/app/views/study_engine/assessments/create.html.slim +46 -0
- data/app/views/study_engine/assessments/index.html.slim +43 -0
- data/app/views/study_engine/assessments/restart.html.slim +28 -0
- data/app/views/study_engine/assessments/show.html.slim +60 -0
- data/app/views/study_engine/mailer/assessment_recorded_notification.erb +8 -0
- data/app/views/study_engine/mailer/assessment_url_notification.erb +6 -0
- data/config/routes.rb +15 -0
- data/db/migrate/20160422185859_create_tables.rb +52 -0
- data/lib/study_engine.rb +5 -0
- data/lib/study_engine/config.rb +37 -0
- data/lib/study_engine/cucumber.rb +96 -0
- data/lib/study_engine/engine.rb +7 -0
- data/lib/study_engine/version.rb +3 -0
- data/lib/tasks/study_engine_tasks.rake +10 -0
- data/spec/ar_helper.rb +30 -0
- data/spec/models/study_engine/answer_spec.rb +28 -0
- data/spec/models/study_engine/assessment_spec.rb +250 -0
- data/spec/models/study_engine/begin_assessment_form_spec.rb +87 -0
- data/spec/models/study_engine/existing_assessments_form_spec.rb +171 -0
- data/spec/models/study_engine/report_spec.rb +48 -0
- data/spec/models/study_engine/result_spec.rb +102 -0
- data/spec/models/study_engine/screen_results_spec.rb +69 -0
- data/spec/models/study_engine/study_id/bank_spec.rb +72 -0
- data/spec/models/study_engine/study_id/sync_spec.rb +61 -0
- data/spec/models/study_engine/study_id_spec.rb +7 -0
- data/spec/models/study_engine/update_assessments_form_spec.rb +38 -0
- data/spec/rails_helper.rb +50 -0
- data/spec/schema.rb +65 -0
- data/spec/spec_helper.rb +72 -0
- data/spec/support/CATEngine3.exe +0 -0
- data/spec/support/forms/01. Physical Function Bank.xml +1213 -0
- data/spec/support/forms/02. Pain Interference Bank.xml +443 -0
- data/spec/support/forms/03. Anxiety Bank.xml +322 -0
- data/spec/support/forms/04. Depression Bank.xml +311 -0
- data/spec/support/forms/05. Ability to Participate Social bank Version 2.xml +353 -0
- data/spec/support/forms/06. Psychosocial Illness Impact Pos Bank.xml +900 -0
- data/spec/support/forms/07. Applied Cognition Gen Concerns Bank.xml +377 -0
- data/spec/support/forms/08. Satisfaction with Roles and Activities Bank Version 2.xml +443 -0
- data/spec/support/forms/09. Sleep Disturbance Bank.xml +300 -0
- data/spec/support/forms/10. Emotional Support Bank.xml +163 -0
- data/spec/support/forms/A - 07. Psychosocial Illness Impact Pos Bank.xml +471 -0
- data/spec/support/forms/A - 08. Pain interference Bank.xml +443 -0
- data/spec/support/forms/A - 09. Depression Bank.xml +311 -0
- data/spec/support/forms/B - 07. Physical Function Short Form.xml +123 -0
- data/spec/support/forms/B - 08. Physical Function Remainder A.xml +543 -0
- data/spec/support/forms/B - 09. Ability to Participate Social bank Version 2.xml +353 -0
- data/spec/support/forms/C - 07. Physical Function Short Form.xml +123 -0
- data/spec/support/forms/C - 08. Physical Function Remainder B.xml +553 -0
- data/spec/support/forms/C - 09. Anxiety Bank.xml +322 -0
- data/spec/support/parameters/01. Physical Function Bank.xml +682 -0
- data/spec/support/parameters/02. Pain Interference Bank.xml +256 -0
- data/spec/support/parameters/03. Anxiety Bank.xml +190 -0
- data/spec/support/parameters/04. Depression Bank.xml +184 -0
- data/spec/support/parameters/05. Ability to Participate Social bank Version 2.xml +226 -0
- data/spec/support/parameters/06. Psychosocial Illness Impact Pos Bank.xml +211 -0
- data/spec/support/parameters/07. Applied Cognition Gen Concerns Bank.xml +1 -0
- data/spec/support/parameters/08. Satisfaction with Roles and Activities Bank Version 2.xml +1 -0
- data/spec/support/parameters/09. Sleep Disturbance Bank.xml +1 -0
- data/spec/support/parameters/10. Emotional Support Bank.xml +1 -0
- metadata +394 -0
@@ -0,0 +1,17 @@
|
|
1
|
+
module StudyEngine
|
2
|
+
class Admin::NotesController < Admin::ApplicationController
|
3
|
+
before_action :require_admin
|
4
|
+
|
5
|
+
def update
|
6
|
+
assessment.update_column :notes, params[:notes]
|
7
|
+
render text: assessment.notes?
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def assessment
|
13
|
+
Assessment.find(params[:assessment_id])
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require "study_engine/config"
|
2
|
+
require "cat_engine/question"
|
3
|
+
|
4
|
+
module StudyEngine
|
5
|
+
class AssessmentsController < ::StudyEngine::ApplicationController
|
6
|
+
expose :assessment, :welcome_content, :events, :enabled_application_methods
|
7
|
+
|
8
|
+
def index
|
9
|
+
@welcome_content = StudyEngine.welcome_content
|
10
|
+
@assessment = BeginAssessmentForm.new
|
11
|
+
assessment.coordinator = current_user
|
12
|
+
end
|
13
|
+
|
14
|
+
def create
|
15
|
+
@assessment = BeginAssessmentForm.new(params[:assessment])
|
16
|
+
assessment.coordinator = current_user
|
17
|
+
if assessment.save
|
18
|
+
if assessment.by_url?
|
19
|
+
flash.now.notice = "An assessment has been created."
|
20
|
+
::StudyEngine::Mailer.assessment_url_notification(current_user.email, assessment).deliver_now
|
21
|
+
render :create
|
22
|
+
elsif assessment.by_mail?
|
23
|
+
flash.now.notice = "An assessment has been created."
|
24
|
+
render :create
|
25
|
+
else
|
26
|
+
redirect_to assessment
|
27
|
+
end
|
28
|
+
elsif assessment.restartable?
|
29
|
+
flash.now[:alert] = "Partial assessment data already exists for this ID number and event. Would you like to resume or restart?"
|
30
|
+
render :restart
|
31
|
+
else
|
32
|
+
flash.now[:alert] = assessment.errors.full_messages.join(", ")
|
33
|
+
render :index
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def show
|
38
|
+
if assessment.complete?
|
39
|
+
if assessment.completed_at.nil?
|
40
|
+
assessment.touch :completed_at
|
41
|
+
send_notification
|
42
|
+
end
|
43
|
+
render :complete
|
44
|
+
else
|
45
|
+
render :show
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def edit
|
50
|
+
redirect_to assessment
|
51
|
+
end
|
52
|
+
|
53
|
+
def update
|
54
|
+
assessment.save_answer Answer.new(question: CatEngine::Question.new(params[:cat_engine_question]))
|
55
|
+
redirect_to assessment
|
56
|
+
end
|
57
|
+
|
58
|
+
def timeout
|
59
|
+
@assessment = BeginAssessmentForm.new_from_model(assessment)
|
60
|
+
flash.now[:alert] = "Assessment timed out due to inactivity. Would you like to resume or restart?"
|
61
|
+
render :restart
|
62
|
+
end
|
63
|
+
|
64
|
+
def notification
|
65
|
+
send_notification
|
66
|
+
head :ok
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def send_notification
|
72
|
+
if email = assessment.coordinator_email
|
73
|
+
::StudyEngine::Mailer.assessment_recorded_notification(email, assessment).deliver_now
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def assessment
|
78
|
+
@assessment ||= Assessment.find(params[:id])
|
79
|
+
end
|
80
|
+
|
81
|
+
def current_user_required?
|
82
|
+
return true unless %w[show update notification].include?(params[:action]) && assessment.by_url?
|
83
|
+
end
|
84
|
+
|
85
|
+
def events
|
86
|
+
StudyEngine.events
|
87
|
+
end
|
88
|
+
|
89
|
+
def enabled_application_methods
|
90
|
+
StudyEngine.enabled_application_methods
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module StudyEngine
|
2
|
+
module Helpers
|
3
|
+
def progress_bar percent
|
4
|
+
render partial: "study_engine/progress_bar", locals: { percent: percent }
|
5
|
+
end
|
6
|
+
|
7
|
+
def sortable_link_url report, field
|
8
|
+
"?field=#{field}&direction=#{(report.field == field && report.direction == "ASC") ? "DESC" : "ASC"}"
|
9
|
+
end
|
10
|
+
|
11
|
+
def sortable_link_class report, field
|
12
|
+
"current-#{report.direction.downcase}" if report.field == field
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module StudyEngine
|
2
|
+
module MailerHelpers
|
3
|
+
def domains_and_group_summary assessment
|
4
|
+
finished = assessment.results.select(&:finished?).count
|
5
|
+
total = assessment.results.count
|
6
|
+
domains = [finished, total].join("/")
|
7
|
+
[domains, assessment.group_index_name].join(" ").strip
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "study_engine/config"
|
2
|
+
|
3
|
+
module StudyEngine
|
4
|
+
class Mailer < ActionMailer::Base
|
5
|
+
helper MailerHelpers
|
6
|
+
|
7
|
+
default content_type: "text/html"
|
8
|
+
|
9
|
+
def assessment_url_notification email, assessment
|
10
|
+
@assessment = assessment
|
11
|
+
subject = "URL for #{assessment.study_id} #{assessment.event}"
|
12
|
+
mail to: email,
|
13
|
+
subject: subject,
|
14
|
+
content_type: "text/plain"
|
15
|
+
end
|
16
|
+
|
17
|
+
def assessment_recorded_notification email, assessment
|
18
|
+
@study_name = StudyEngine.study_name
|
19
|
+
@assessment = assessment
|
20
|
+
subject = "#{assessment.study_id} #{assessment.event} recorded"
|
21
|
+
mail to: email, subject: subject, content_type: "text/plain", cc: StudyEngine.notification_email
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require "cat_engine/response"
|
2
|
+
require "cat_engine/question"
|
3
|
+
|
4
|
+
module StudyEngine
|
5
|
+
class Answer < ActiveRecord::Base
|
6
|
+
belongs_to :result
|
7
|
+
|
8
|
+
def question
|
9
|
+
CatEngine::Question.new(id: question_id, promis_id: question_promis_id, context: question_context, title: question_title, responses: [])
|
10
|
+
end
|
11
|
+
|
12
|
+
def question= value
|
13
|
+
self.response = value.selected_response
|
14
|
+
value.each_pair do |key, value|
|
15
|
+
if key == :response_before
|
16
|
+
self.response_before = value
|
17
|
+
else
|
18
|
+
send :"question_#{key}=", value
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def response
|
24
|
+
CatEngine::Response.new(id: response_id, promis_id: response_promis_id, before: response_before, title: response_title)
|
25
|
+
end
|
26
|
+
|
27
|
+
def response= value
|
28
|
+
value.each_pair do |key, value|
|
29
|
+
send :"response_#{key}=", value
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_accessor :question_responses
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require "study_engine/config"
|
2
|
+
require "study_engine/study_id"
|
3
|
+
|
4
|
+
module StudyEngine
|
5
|
+
class Assessment < ActiveRecord::Base
|
6
|
+
cattr_accessor(:timeout_interval) { 10.minutes }
|
7
|
+
|
8
|
+
default_scope -> { includes(:persisted_results) }
|
9
|
+
|
10
|
+
def timestamp_attributes_for_create
|
11
|
+
super + [:assessment_updated_at]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.by_event event
|
15
|
+
where(event: event)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.by_study_id study_id
|
19
|
+
return none unless study_id
|
20
|
+
where(study_id: study_id)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.by_site site
|
24
|
+
where("study_id RLIKE '...-#{site}-....'")
|
25
|
+
end
|
26
|
+
|
27
|
+
has_many :persisted_results, class_name: "Result", dependent: :destroy
|
28
|
+
|
29
|
+
before_create :assign_group_index
|
30
|
+
|
31
|
+
belongs_to :coordinator, class_name: "User"
|
32
|
+
|
33
|
+
def coordinator_email
|
34
|
+
coordinator.try(:email)
|
35
|
+
end
|
36
|
+
|
37
|
+
def restarted_assessment
|
38
|
+
Assessment.by_study_id(study_id).where(event: event).where.not(id: id).last
|
39
|
+
end
|
40
|
+
|
41
|
+
def stream_id
|
42
|
+
StudyID.new("STR-#{study_id.site}-#{1000 + id}") unless new_record?
|
43
|
+
end
|
44
|
+
|
45
|
+
def notes?
|
46
|
+
notes.present?
|
47
|
+
end
|
48
|
+
|
49
|
+
serialize :study_id, StudyID
|
50
|
+
|
51
|
+
def results
|
52
|
+
@results ||= begin
|
53
|
+
bank_ids = StudyEngine.bank_finder.call(self)
|
54
|
+
return persisted_results if persisted_results.length == bank_ids.length
|
55
|
+
bank_ids.map do |bank_id|
|
56
|
+
persisted_results.find_or_initialize_by(bank_id: bank_id)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def current_result
|
62
|
+
results.find { |result| !result.finished? }
|
63
|
+
end
|
64
|
+
|
65
|
+
def percent_complete
|
66
|
+
(results.select(&:finished?).count / results.count.to_f * 100).round
|
67
|
+
end
|
68
|
+
|
69
|
+
delegate :current_question, to: :current_result
|
70
|
+
|
71
|
+
def save_answer answer
|
72
|
+
current_result.save_answer answer
|
73
|
+
save!
|
74
|
+
touch :assessment_updated_at
|
75
|
+
end
|
76
|
+
|
77
|
+
def complete?
|
78
|
+
current_result.nil?
|
79
|
+
end
|
80
|
+
|
81
|
+
def incomplete?
|
82
|
+
!complete?
|
83
|
+
end
|
84
|
+
|
85
|
+
def results_summary
|
86
|
+
"#{results.select(&:finished?).count}/#{results.count}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def full_history
|
90
|
+
persisted_results.flat_map(&:answers).map(&:question_id)
|
91
|
+
end
|
92
|
+
|
93
|
+
def by_url?
|
94
|
+
method_applied == "By URL"
|
95
|
+
end
|
96
|
+
|
97
|
+
def by_mail?
|
98
|
+
method_applied == "By mail"
|
99
|
+
end
|
100
|
+
|
101
|
+
def group_index_name
|
102
|
+
return "" if group_index.nil?
|
103
|
+
event_groups[group_index]
|
104
|
+
end
|
105
|
+
|
106
|
+
private
|
107
|
+
|
108
|
+
def assign_group_index
|
109
|
+
return unless event_groups.any?
|
110
|
+
self.group_index = restarted_assessment.try(:group_index) || self.class.by_event(event).count % event_groups.length
|
111
|
+
end
|
112
|
+
|
113
|
+
def event_groups
|
114
|
+
StudyEngine.groups[event] || []
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require "study_engine/form"
|
2
|
+
require "study_engine/assessment"
|
3
|
+
require "study_engine/config"
|
4
|
+
|
5
|
+
module StudyEngine
|
6
|
+
class BeginAssessmentForm < Form
|
7
|
+
wraps "study_engine/assessment"
|
8
|
+
|
9
|
+
attributes :study_id, :event, :method_applied, :coordinator
|
10
|
+
|
11
|
+
attr_accessor :restart
|
12
|
+
|
13
|
+
delegate :study, :site, :id, to: :study_id, prefix: true
|
14
|
+
delegate :study=, :site=, :id=, to: :study_id, prefix: true
|
15
|
+
|
16
|
+
validate :presence_of_event
|
17
|
+
validate :format_of_study_id
|
18
|
+
validate :uniqueness_of_study_id_and_event, unless: :restart
|
19
|
+
validate :presence_of_previous_events
|
20
|
+
|
21
|
+
def study_id_study
|
22
|
+
study_options.one? ? study_options.first : study_id.study
|
23
|
+
end
|
24
|
+
|
25
|
+
def study_id_site
|
26
|
+
site_options.one? ? site_options.first : study_id.site
|
27
|
+
end
|
28
|
+
|
29
|
+
def study_id_id
|
30
|
+
id_options.one? ? id_options.first : study_id.id
|
31
|
+
end
|
32
|
+
|
33
|
+
def study_id
|
34
|
+
@study_id ||= StudyID.new
|
35
|
+
end
|
36
|
+
|
37
|
+
def method_applied
|
38
|
+
@method_applied || "In-person"
|
39
|
+
end
|
40
|
+
|
41
|
+
def existing_assessment
|
42
|
+
if study_id and new_record?
|
43
|
+
@existing_assessment ||= Assessment.by_study_id(study_id).where(event: event).last
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def restartable?
|
48
|
+
existing_assessment.try(:incomplete?)
|
49
|
+
end
|
50
|
+
|
51
|
+
def study_options
|
52
|
+
StudyID::Bank.studies_grouped_by_site.fetch(coordinator.try(:site_id)) { StudyID::Bank.studies }
|
53
|
+
end
|
54
|
+
|
55
|
+
def site_options
|
56
|
+
coordinator.try(:site_id).present? ? [coordinator.site_id] : StudyID::Bank.sites
|
57
|
+
end
|
58
|
+
|
59
|
+
def id_options
|
60
|
+
ids_grouped_by_study_and_site[study_id_study.to_s + study_id_site.to_s]
|
61
|
+
end
|
62
|
+
|
63
|
+
def ids_grouped_by_study_and_site
|
64
|
+
StudyID::Bank.ids_grouped_by_study_and_site
|
65
|
+
end
|
66
|
+
|
67
|
+
delegate :by_url?, :by_mail?, :group_index_name, :created_at, :assessment_updated_at, to: :@model
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def format_of_study_id
|
72
|
+
if study_id.present?
|
73
|
+
unless study_id.valid?
|
74
|
+
errors.add :base, "METRC study ID must be in the following format: XXX-XXX-####"
|
75
|
+
end
|
76
|
+
else
|
77
|
+
errors.add :base, "METRC study ID can not be blank. Enter ID in the following format: XXX-XXX-####"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def presence_of_event
|
82
|
+
if event.blank?
|
83
|
+
events = StudyEngine.events.dup
|
84
|
+
events.map!(&:titleize)
|
85
|
+
events.last.prepend("or ")
|
86
|
+
events = events.join(", ")
|
87
|
+
errors.add :base, "Study event can not be blank. Choose #{events} assessment."
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def uniqueness_of_study_id_and_event
|
92
|
+
if existing_assessment
|
93
|
+
errors.add :base, "Assessment data has already been collected for this ID number and event. Please check these fields to confirm you are beginning an assessment for the correct ID and event."
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def presence_of_previous_events
|
98
|
+
index = StudyEngine.events.index(event)
|
99
|
+
return if index.nil? || index.zero?
|
100
|
+
previous_events = StudyEngine.events[0...index]
|
101
|
+
|
102
|
+
previous_events.each do |previous_event|
|
103
|
+
if Assessment.by_study_id(study_id).by_event(previous_event).none?
|
104
|
+
errors.add :base, "#{previous_event.capitalize} assessment must already exist to administer #{event} assessment"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|