study_engine 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|