ccls-ccls_engine 3.11.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +182 -0
- data/app/models/abstract.rb +181 -0
- data/app/models/abstract_search.rb +50 -0
- data/app/models/abstract_validations.rb +324 -0
- data/app/models/address.rb +70 -0
- data/app/models/address_type.rb +15 -0
- data/app/models/addressing.rb +147 -0
- data/app/models/aliquot.rb +44 -0
- data/app/models/aliquot_sample_format.rb +13 -0
- data/app/models/analysis.rb +14 -0
- data/app/models/bc_request.rb +20 -0
- data/app/models/candidate_control.rb +101 -0
- data/app/models/context.rb +23 -0
- data/app/models/context_data_source.rb +4 -0
- data/app/models/county.rb +16 -0
- data/app/models/data_source.rb +24 -0
- data/app/models/diagnosis.rb +23 -0
- data/app/models/document_type.rb +16 -0
- data/app/models/document_version.rb +27 -0
- data/app/models/enrollment.rb +78 -0
- data/app/models/enrollment_validations.rb +167 -0
- data/app/models/follow_up.rb +16 -0
- data/app/models/follow_up_type.rb +18 -0
- data/app/models/gift_card.rb +22 -0
- data/app/models/gift_card_search.rb +137 -0
- data/app/models/home_exposure_response.rb +24 -0
- data/app/models/homex_outcome.rb +75 -0
- data/app/models/hospital.rb +22 -0
- data/app/models/icf_master_id.rb +30 -0
- data/app/models/icf_master_tracker.rb +217 -0
- data/app/models/icf_master_tracker_change.rb +9 -0
- data/app/models/icf_master_tracker_update.rb +50 -0
- data/app/models/ineligible_reason.rb +26 -0
- data/app/models/instrument.rb +26 -0
- data/app/models/instrument_type.rb +17 -0
- data/app/models/instrument_version.rb +28 -0
- data/app/models/interview.rb +122 -0
- data/app/models/interview_method.rb +17 -0
- data/app/models/interview_outcome.rb +16 -0
- data/app/models/language.rb +28 -0
- data/app/models/live_birth_data_update.rb +142 -0
- data/app/models/operational_event.rb +99 -0
- data/app/models/operational_event_type.rb +31 -0
- data/app/models/organization.rb +28 -0
- data/app/models/patient.rb +63 -0
- data/app/models/patient_validations.rb +118 -0
- data/app/models/person.rb +28 -0
- data/app/models/phone_number.rb +105 -0
- data/app/models/phone_type.rb +15 -0
- data/app/models/project.rb +39 -0
- data/app/models/project_outcome.rb +19 -0
- data/app/models/race.rb +31 -0
- data/app/models/refusal_reason.rb +23 -0
- data/app/models/sample.rb +168 -0
- data/app/models/sample_kit.rb +14 -0
- data/app/models/sample_outcome.rb +16 -0
- data/app/models/sample_temperature.rb +14 -0
- data/app/models/sample_type.rb +37 -0
- data/app/models/search.rb +195 -0
- data/app/models/section.rb +18 -0
- data/app/models/state.rb +25 -0
- data/app/models/study_subject.rb +237 -0
- data/app/models/study_subject_abstracts.rb +47 -0
- data/app/models/study_subject_addresses.rb +34 -0
- data/app/models/study_subject_associations.rb +38 -0
- data/app/models/study_subject_duplicates.rb +111 -0
- data/app/models/study_subject_enrollments.rb +17 -0
- data/app/models/study_subject_homex_outcome.rb +22 -0
- data/app/models/study_subject_identifier.rb +153 -0
- data/app/models/study_subject_interviews.rb +25 -0
- data/app/models/study_subject_languages.rb +21 -0
- data/app/models/study_subject_operational_events.rb +66 -0
- data/app/models/study_subject_patient.rb +177 -0
- data/app/models/study_subject_pii.rb +74 -0
- data/app/models/study_subject_races.rb +25 -0
- data/app/models/study_subject_search.rb +260 -0
- data/app/models/study_subject_validations.rb +116 -0
- data/app/models/subject_language.rb +11 -0
- data/app/models/subject_race.rb +11 -0
- data/app/models/subject_relationship.rb +21 -0
- data/app/models/subject_type.rb +22 -0
- data/app/models/tracing_status.rb +20 -0
- data/app/models/transfer.rb +40 -0
- data/app/models/unit.rb +14 -0
- data/app/models/vital_status.rb +19 -0
- data/app/models/zip_code.rb +36 -0
- data/config/abstract_fields.yml +1038 -0
- data/config/abstract_sections.yml +77 -0
- data/config/home_exposure_response_fields.yml +583 -0
- data/config/icf_master_tracker_update.yml +56 -0
- data/config/live_birth_data_update.yml +56 -0
- data/config/shared_use_db.yml +4 -0
- data/generators/ccls_engine/USAGE +2 -0
- data/generators/ccls_engine/ccls_engine_generator.rb +123 -0
- data/generators/ccls_engine/templates/autotest_ccls_engine.rb +3 -0
- data/generators/ccls_engine/templates/ccls_engine.rake +12 -0
- data/generators/ccls_engine/templates/fixtures/address_types.yml +30 -0
- data/generators/ccls_engine/templates/fixtures/context_data_sources.yml +54 -0
- data/generators/ccls_engine/templates/fixtures/contexts.yml +19 -0
- data/generators/ccls_engine/templates/fixtures/data_sources.yml +40 -0
- data/generators/ccls_engine/templates/fixtures/diagnoses.yml +40 -0
- data/generators/ccls_engine/templates/fixtures/document_types.yml +65 -0
- data/generators/ccls_engine/templates/fixtures/document_versions.csv +155 -0
- data/generators/ccls_engine/templates/fixtures/follow_up_types.yml +16 -0
- data/generators/ccls_engine/templates/fixtures/hospitals.yml +114 -0
- data/generators/ccls_engine/templates/fixtures/ineligible_reasons.yml +35 -0
- data/generators/ccls_engine/templates/fixtures/instrument_types.yml +26 -0
- data/generators/ccls_engine/templates/fixtures/instrument_versions.yml +22 -0
- data/generators/ccls_engine/templates/fixtures/instruments.yml +22 -0
- data/generators/ccls_engine/templates/fixtures/interview_methods.yml +30 -0
- data/generators/ccls_engine/templates/fixtures/interview_outcomes.yml +31 -0
- data/generators/ccls_engine/templates/fixtures/languages.yml +34 -0
- data/generators/ccls_engine/templates/fixtures/operational_event_types.yml +141 -0
- data/generators/ccls_engine/templates/fixtures/organizations.yml +198 -0
- data/generators/ccls_engine/templates/fixtures/people.yml +130 -0
- data/generators/ccls_engine/templates/fixtures/phone_types.yml +30 -0
- data/generators/ccls_engine/templates/fixtures/project_outcomes.yml +25 -0
- data/generators/ccls_engine/templates/fixtures/projects.yml +59 -0
- data/generators/ccls_engine/templates/fixtures/races.yml +52 -0
- data/generators/ccls_engine/templates/fixtures/refusal_reasons.yml +55 -0
- data/generators/ccls_engine/templates/fixtures/sample_outcomes.yml +36 -0
- data/generators/ccls_engine/templates/fixtures/sample_temperatures.yml +16 -0
- data/generators/ccls_engine/templates/fixtures/sample_types.yml +147 -0
- data/generators/ccls_engine/templates/fixtures/sections.yml +31 -0
- data/generators/ccls_engine/templates/fixtures/states.yml +363 -0
- data/generators/ccls_engine/templates/fixtures/subject_relationships.yml +46 -0
- data/generators/ccls_engine/templates/fixtures/subject_types.yml +30 -0
- data/generators/ccls_engine/templates/fixtures/tracing_statuses.yml +30 -0
- data/generators/ccls_engine/templates/fixtures/units.yml +13 -0
- data/generators/ccls_engine/templates/fixtures/vital_statuses.yml +28 -0
- data/generators/ccls_engine/templates/functional/roles_controller_test.rb +142 -0
- data/generators/ccls_engine/templates/functional/sessions_controller_test.rb +19 -0
- data/generators/ccls_engine/templates/functional/users_controller_test.rb +94 -0
- data/generators/ccls_engine/templates/images/sort_down.png +0 -0
- data/generators/ccls_engine/templates/images/sort_up.png +0 -0
- data/generators/ccls_engine/templates/initializer.rb +28 -0
- data/generators/ccls_engine/templates/javascripts/ccls_engine.js +24 -0
- data/generators/ccls_engine/templates/javascripts/jquery-ui.js +763 -0
- data/generators/ccls_engine/templates/javascripts/jquery.js +154 -0
- data/generators/ccls_engine/templates/javascripts/jrails.js +1 -0
- data/generators/ccls_engine/templates/migrations/create_user_invitations.rb +18 -0
- data/generators/ccls_engine/templates/migrations/create_users.rb +33 -0
- data/generators/ccls_engine/templates/migrations/drop_user_invitations.rb +18 -0
- data/generators/ccls_engine/templates/stylesheets/ccls_engine.css +180 -0
- data/generators/ccls_engine/templates/stylesheets/user.css +35 -0
- data/generators/ccls_engine/templates/stylesheets/users.css +23 -0
- data/generators/ccls_engine/templates/unit/core_extension_test.rb +18 -0
- data/generators/ccls_engine/templates/unit/role_test.rb +30 -0
- data/generators/ccls_engine/templates/unit/user_test.rb +321 -0
- data/lib/ccls-ccls_engine.rb +1 -0
- data/lib/ccls_engine.rb +135 -0
- data/lib/ccls_engine/action_view_extension.rb +3 -0
- data/lib/ccls_engine/action_view_extension/base.rb +53 -0
- data/lib/ccls_engine/action_view_extension/form_builder.rb +39 -0
- data/lib/ccls_engine/active_record_extension.rb +2 -0
- data/lib/ccls_engine/active_record_extension/base.rb +70 -0
- data/lib/ccls_engine/active_record_shared.rb +8 -0
- data/lib/ccls_engine/assertions.rb +69 -0
- data/lib/ccls_engine/autotest.rb +54 -0
- data/lib/ccls_engine/ccls_user.rb +117 -0
- data/lib/ccls_engine/core_extension.rb +14 -0
- data/lib/ccls_engine/date_and_time_formats.rb +30 -0
- data/lib/ccls_engine/factories.rb +880 -0
- data/lib/ccls_engine/factory_test_helper.rb +276 -0
- data/lib/ccls_engine/helper.rb +112 -0
- data/lib/ccls_engine/icf_master_tracker_update_test_helper.rb +121 -0
- data/lib/ccls_engine/live_birth_data_update_test_helper.rb +110 -0
- data/lib/ccls_engine/package_test_helper.rb +49 -0
- data/lib/ccls_engine/shared_database.rb +20 -0
- data/lib/ccls_engine/tasks.rb +1 -0
- data/lib/ccls_engine/test_tasks.rb +52 -0
- data/lib/ccls_engine/translation_table.rb +86 -0
- data/lib/shared_migration.rb +5 -0
- data/lib/surveyor/survey_extensions.rb +125 -0
- data/lib/tasks/application.rake +286 -0
- data/lib/tasks/calnet_authenticated.rake +6 -0
- data/lib/tasks/common_lib.rake +7 -0
- data/lib/tasks/database.rake +288 -0
- data/lib/tasks/documentation.rake +71 -0
- data/lib/tasks/homex_import.rake +723 -0
- data/lib/tasks/odms_import.rake +1116 -0
- data/lib/tasks/simply_authorized.rake +6 -0
- data/lib/tasks/ucb_ccls_engine_tasks.rake +4 -0
- data/lib/tasks/use_db.rake +4 -0
- data/rails/init.rb +4 -0
- data/test/unit/ccls/abstract_search_test.rb +150 -0
- data/test/unit/ccls/abstract_test.rb +674 -0
- data/test/unit/ccls/address_test.rb +155 -0
- data/test/unit/ccls/address_type_test.rb +25 -0
- data/test/unit/ccls/addressing_test.rb +466 -0
- data/test/unit/ccls/aliquot_sample_format_test.rb +20 -0
- data/test/unit/ccls/aliquot_test.rb +156 -0
- data/test/unit/ccls/analysis_test.rb +31 -0
- data/test/unit/ccls/bc_request_test.rb +43 -0
- data/test/unit/ccls/candidate_control_test.rb +712 -0
- data/test/unit/ccls/context_data_source_test.rb +26 -0
- data/test/unit/ccls/context_test.rb +40 -0
- data/test/unit/ccls/core_extension_test.rb +17 -0
- data/test/unit/ccls/county_test.rb +34 -0
- data/test/unit/ccls/data_source_test.rb +41 -0
- data/test/unit/ccls/diagnosis_test.rb +51 -0
- data/test/unit/ccls/document_type_test.rb +35 -0
- data/test/unit/ccls/document_version_test.rb +68 -0
- data/test/unit/ccls/enrollment_test.rb +575 -0
- data/test/unit/ccls/follow_up_test.rb +23 -0
- data/test/unit/ccls/follow_up_type_test.rb +34 -0
- data/test/unit/ccls/gift_card_search_test.rb +153 -0
- data/test/unit/ccls/gift_card_test.rb +40 -0
- data/test/unit/ccls/home_exposure_response_test.rb +83 -0
- data/test/unit/ccls/homex_outcome_test.rb +199 -0
- data/test/unit/ccls/hospital_test.rb +102 -0
- data/test/unit/ccls/icf_master_id_test.rb +30 -0
- data/test/unit/ccls/icf_master_tracker_change_test.rb +14 -0
- data/test/unit/ccls/icf_master_tracker_test.rb +132 -0
- data/test/unit/ccls/icf_master_tracker_update_test.rb +176 -0
- data/test/unit/ccls/ineligible_reason_test.rb +48 -0
- data/test/unit/ccls/instrument_test.rb +62 -0
- data/test/unit/ccls/instrument_type_test.rb +39 -0
- data/test/unit/ccls/instrument_version_test.rb +71 -0
- data/test/unit/ccls/interview_method_test.rb +44 -0
- data/test/unit/ccls/interview_outcome_test.rb +34 -0
- data/test/unit/ccls/interview_test.rb +298 -0
- data/test/unit/ccls/language_test.rb +47 -0
- data/test/unit/ccls/live_birth_data_update_test.rb +358 -0
- data/test/unit/ccls/operational_event_test.rb +187 -0
- data/test/unit/ccls/operational_event_type_test.rb +51 -0
- data/test/unit/ccls/organization_test.rb +64 -0
- data/test/unit/ccls/patient_test.rb +538 -0
- data/test/unit/ccls/person_test.rb +55 -0
- data/test/unit/ccls/phone_number_test.rb +244 -0
- data/test/unit/ccls/phone_type_test.rb +32 -0
- data/test/unit/ccls/project_outcome_test.rb +34 -0
- data/test/unit/ccls/project_test.rb +60 -0
- data/test/unit/ccls/race_test.rb +37 -0
- data/test/unit/ccls/refusal_reason_test.rb +52 -0
- data/test/unit/ccls/role_test.rb +26 -0
- data/test/unit/ccls/sample_kit_test.rb +35 -0
- data/test/unit/ccls/sample_outcome_test.rb +34 -0
- data/test/unit/ccls/sample_temperature_test.rb +25 -0
- data/test/unit/ccls/sample_test.rb +363 -0
- data/test/unit/ccls/sample_type_test.rb +58 -0
- data/test/unit/ccls/section_test.rb +34 -0
- data/test/unit/ccls/state_test.rb +31 -0
- data/test/unit/ccls/study_subject_abstracts_test.rb +115 -0
- data/test/unit/ccls/study_subject_addresses_test.rb +93 -0
- data/test/unit/ccls/study_subject_duplicates_test.rb +407 -0
- data/test/unit/ccls/study_subject_enrollments_test.rb +65 -0
- data/test/unit/ccls/study_subject_homex_outcome_test.rb +64 -0
- data/test/unit/ccls/study_subject_identifier_test.rb +439 -0
- data/test/unit/ccls/study_subject_interviews_test.rb +26 -0
- data/test/unit/ccls/study_subject_languages_test.rb +142 -0
- data/test/unit/ccls/study_subject_operational_events_test.rb +53 -0
- data/test/unit/ccls/study_subject_patient_test.rb +249 -0
- data/test/unit/ccls/study_subject_pii_test.rb +278 -0
- data/test/unit/ccls/study_subject_races_test.rb +203 -0
- data/test/unit/ccls/study_subject_search_test.rb +704 -0
- data/test/unit/ccls/study_subject_test.rb +770 -0
- data/test/unit/ccls/subject_language_test.rb +43 -0
- data/test/unit/ccls/subject_race_test.rb +35 -0
- data/test/unit/ccls/subject_relationship_test.rb +43 -0
- data/test/unit/ccls/subject_type_test.rb +40 -0
- data/test/unit/ccls/tracing_status_test.rb +32 -0
- data/test/unit/ccls/transfer_test.rb +81 -0
- data/test/unit/ccls/translation_table_test.rb +40 -0
- data/test/unit/ccls/unit_test.rb +21 -0
- data/test/unit/ccls/user_test.rb +156 -0
- data/test/unit/ccls/vital_status_test.rb +36 -0
- data/test/unit/ccls/zip_code_test.rb +55 -0
- metadata +633 -0
@@ -0,0 +1,26 @@
|
|
1
|
+
class Instrument < ActiveRecordShared
|
2
|
+
|
3
|
+
acts_as_list
|
4
|
+
default_scope :order => :position
|
5
|
+
|
6
|
+
acts_like_a_hash
|
7
|
+
|
8
|
+
belongs_to :project
|
9
|
+
belongs_to :interview_method
|
10
|
+
has_many :instrument_versions
|
11
|
+
|
12
|
+
validates_presence_of :project_id
|
13
|
+
validates_presence_of :project, :if => :project_id
|
14
|
+
|
15
|
+
validates_presence_of :name
|
16
|
+
validates_length_of :name, :maximum => 250, :allow_blank => true
|
17
|
+
|
18
|
+
validates_complete_date_for :began_use_on, :allow_nil => true
|
19
|
+
validates_complete_date_for :ended_use_on, :allow_nil => true
|
20
|
+
|
21
|
+
# Return name
|
22
|
+
def to_s
|
23
|
+
name
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# == requires
|
2
|
+
# * description ( unique and > 3 chars )
|
3
|
+
# * project
|
4
|
+
class InstrumentType < ActiveRecordShared
|
5
|
+
|
6
|
+
acts_as_list
|
7
|
+
default_scope :order => :position
|
8
|
+
|
9
|
+
acts_like_a_hash
|
10
|
+
|
11
|
+
belongs_to :project
|
12
|
+
has_many :instrument_versions
|
13
|
+
|
14
|
+
validates_presence_of :project_id
|
15
|
+
validates_presence_of :project, :if => :project_id
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# == requires
|
2
|
+
# * key ( unique )
|
3
|
+
# * description ( unique and > 3 chars )
|
4
|
+
# * interview_type_id
|
5
|
+
class InstrumentVersion < ActiveRecordShared
|
6
|
+
|
7
|
+
acts_as_list
|
8
|
+
default_scope :order => :position
|
9
|
+
|
10
|
+
acts_like_a_hash
|
11
|
+
|
12
|
+
belongs_to :language
|
13
|
+
belongs_to :instrument_type
|
14
|
+
belongs_to :instrument
|
15
|
+
has_many :interviews
|
16
|
+
|
17
|
+
validates_presence_of :instrument_type_id
|
18
|
+
validates_presence_of :instrument_type, :if => :instrument_type_id
|
19
|
+
|
20
|
+
validates_complete_date_for :began_use_on, :allow_nil => true
|
21
|
+
validates_complete_date_for :ended_use_on, :allow_nil => true
|
22
|
+
|
23
|
+
# Returns description
|
24
|
+
def to_s
|
25
|
+
description
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# == requires
|
2
|
+
# * address_id
|
3
|
+
# * interviewer_id
|
4
|
+
# * study_subject_id
|
5
|
+
class Interview < ActiveRecordShared
|
6
|
+
|
7
|
+
belongs_to :study_subject
|
8
|
+
attr_protected( :study_subject_id, :study_subject )
|
9
|
+
|
10
|
+
##
|
11
|
+
# why is this here? Homex for assigning interview outcome
|
12
|
+
accepts_nested_attributes_for :study_subject
|
13
|
+
|
14
|
+
belongs_to :address
|
15
|
+
belongs_to :interviewer, :class_name => 'Person'
|
16
|
+
belongs_to :instrument_version
|
17
|
+
belongs_to :interview_method
|
18
|
+
belongs_to :language
|
19
|
+
belongs_to :subject_relationship
|
20
|
+
|
21
|
+
delegate :is_other?, :to => :subject_relationship, :allow_nil => true, :prefix => true
|
22
|
+
|
23
|
+
validates_complete_date_for :began_on, :allow_nil => true
|
24
|
+
validates_complete_date_for :ended_on, :allow_nil => true
|
25
|
+
validates_complete_date_for :intro_letter_sent_on, :allow_nil => true
|
26
|
+
|
27
|
+
validates_length_of :subject_relationship_other, :maximum => 250, :allow_blank => true
|
28
|
+
validates_length_of :respondent_first_name, :maximum => 250, :allow_blank => true
|
29
|
+
validates_length_of :respondent_last_name, :maximum => 250, :allow_blank => true
|
30
|
+
|
31
|
+
validate :presence_of_subject_relationship_other,
|
32
|
+
:if => :subject_relationship_is_other?
|
33
|
+
|
34
|
+
validates_absence_of :subject_relationship_other,
|
35
|
+
:message => "not allowed",
|
36
|
+
:if => :subject_relationship_id_blank?
|
37
|
+
|
38
|
+
validates_inclusion_of :began_at_hour, :in => (1..12),
|
39
|
+
:allow_blank => true
|
40
|
+
validates_inclusion_of :began_at_minute, :in => (0..59),
|
41
|
+
:allow_blank => true
|
42
|
+
validates_format_of :began_at_meridiem, :with => /\A(AM|PM)\z/i,
|
43
|
+
:allow_blank => true
|
44
|
+
validates_inclusion_of :ended_at_hour, :in => (1..12),
|
45
|
+
:allow_blank => true
|
46
|
+
validates_inclusion_of :ended_at_minute, :in => (0..59),
|
47
|
+
:allow_blank => true
|
48
|
+
validates_format_of :ended_at_meridiem, :with => /\A(AM|PM)\z/i,
|
49
|
+
:allow_blank => true
|
50
|
+
|
51
|
+
before_save :update_intro_operational_event,
|
52
|
+
:if => :intro_letter_sent_on_changed?
|
53
|
+
|
54
|
+
before_save :set_began_at
|
55
|
+
before_save :set_ended_at
|
56
|
+
attr_protected :began_at
|
57
|
+
attr_protected :ended_at
|
58
|
+
|
59
|
+
# Returns string containing respondent's first and last name
|
60
|
+
def respondent_full_name
|
61
|
+
[respondent_first_name, respondent_last_name].compact.join(' ')
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
def set_began_at
|
67
|
+
if [began_on, began_at_hour,began_at_minute,began_at_meridiem].all?
|
68
|
+
self.began_at = DateTime.parse(
|
69
|
+
"#{began_on} #{began_at_hour}:#{began_at_minute} #{began_at_meridiem}")
|
70
|
+
# "#{began_on} #{began_at_hour}:#{began_at_minute} #{began_at_meridiem} PST")
|
71
|
+
else
|
72
|
+
self.began_at = nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def set_ended_at
|
77
|
+
if [ended_on, ended_at_hour,ended_at_minute,ended_at_meridiem].all?
|
78
|
+
self.ended_at = DateTime.parse(
|
79
|
+
"#{ended_on} #{ended_at_hour}:#{ended_at_minute} #{ended_at_meridiem}")
|
80
|
+
# "#{ended_on} #{ended_at_hour}:#{ended_at_minute} #{ended_at_meridiem} PST")
|
81
|
+
else
|
82
|
+
self.ended_at = nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def subject_relationship_id_blank?
|
87
|
+
subject_relationship_id.blank?
|
88
|
+
end
|
89
|
+
|
90
|
+
def update_intro_operational_event
|
91
|
+
oet = OperationalEventType['intro']
|
92
|
+
hxe = study_subject.enrollments.find_by_project_id(Project['HomeExposures'].id)
|
93
|
+
if oet && hxe
|
94
|
+
oe = hxe.operational_events.find(:first,
|
95
|
+
:conditions => { :operational_event_type_id => oet.id } )
|
96
|
+
if oe
|
97
|
+
oe.update_attributes(
|
98
|
+
:description => oet.description,
|
99
|
+
:occurred_on => intro_letter_sent_on
|
100
|
+
)
|
101
|
+
else
|
102
|
+
# hxe.operational_events << OperationalEvent.create!(
|
103
|
+
OperationalEvent.create!(
|
104
|
+
:enrollment => hxe,
|
105
|
+
:operational_event_type => oet,
|
106
|
+
:description => oet.description,
|
107
|
+
:occurred_on => intro_letter_sent_on
|
108
|
+
)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# custom validation for custom message without standard attribute prefix
|
114
|
+
def presence_of_subject_relationship_other
|
115
|
+
if subject_relationship_other.blank?
|
116
|
+
errors.add(:subject_relationship_other, ActiveRecord::Error.new(
|
117
|
+
self, :base, :blank, {
|
118
|
+
:message => "You must specify a relationship with 'other relationship' is selected." } ) )
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# don't know exactly
|
2
|
+
class InterviewMethod < ActiveRecordShared
|
3
|
+
|
4
|
+
acts_as_list
|
5
|
+
default_scope :order => :position
|
6
|
+
|
7
|
+
acts_like_a_hash
|
8
|
+
|
9
|
+
has_many :interviews
|
10
|
+
has_many :instruments
|
11
|
+
|
12
|
+
# Returns description
|
13
|
+
def to_s
|
14
|
+
description
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# == requires
|
2
|
+
# * code ( unique )
|
3
|
+
# * description ( unique and > 3 chars )
|
4
|
+
class Language < ActiveRecordShared
|
5
|
+
|
6
|
+
acts_as_list
|
7
|
+
default_scope :order => :position
|
8
|
+
|
9
|
+
acts_like_a_hash
|
10
|
+
|
11
|
+
has_many :interviews
|
12
|
+
has_many :instrument_versions
|
13
|
+
|
14
|
+
validates_presence_of :code
|
15
|
+
validates_uniqueness_of :code
|
16
|
+
|
17
|
+
# Returns description
|
18
|
+
def to_s
|
19
|
+
description
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns boolean of comparison
|
23
|
+
# true only if key == 'other'
|
24
|
+
def is_other?
|
25
|
+
key == 'other'
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
class LiveBirthDataUpdate < ActiveRecordShared
|
2
|
+
|
3
|
+
has_attached_file :csv_file,
|
4
|
+
YAML::load(ERB.new(IO.read(File.expand_path(
|
5
|
+
File.join(File.dirname(__FILE__),'../..','config/live_birth_data_update.yml')
|
6
|
+
))).result)[Rails.env]
|
7
|
+
|
8
|
+
def to_candidate_controls
|
9
|
+
results = []
|
10
|
+
if !self.csv_file_file_name.blank? &&
|
11
|
+
File.exists?(self.csv_file.path)
|
12
|
+
(f=FasterCSV.open( self.csv_file.path, 'rb',{
|
13
|
+
:headers => true })).each do |line|
|
14
|
+
|
15
|
+
# masterid,ca_co_status,biomom,biodad,date,mother_full_name,mother_maiden_name,father_full_name,child_full_name,child_dobm,child_dobd,child_doby,child_gender,birthplace_country,birthplace_state,birthplace_city,mother_hispanicity,mother_hispanicity_mex,mother_race,mother_race_other,father_hispanicity,father_hispanicity_mex,father_race,father_race_other
|
16
|
+
|
17
|
+
if line['ca_co_status'] == 'case'
|
18
|
+
study_subject = StudySubject.find_by_icf_master_id(line['masterid'])
|
19
|
+
if study_subject
|
20
|
+
results.push(study_subject)
|
21
|
+
else
|
22
|
+
results.push("Could not find study_subject with masterid #{line['masterid']}")
|
23
|
+
next
|
24
|
+
end
|
25
|
+
elsif line['ca_co_status'] == 'control'
|
26
|
+
study_subject = StudySubject.find_by_icf_master_id(line['masterid'])
|
27
|
+
unless study_subject
|
28
|
+
results.push("Could not find study_subject with masterid #{line['masterid']}")
|
29
|
+
next
|
30
|
+
end
|
31
|
+
|
32
|
+
dob = unless(
|
33
|
+
line['child_doby'].blank? ||
|
34
|
+
line['child_dobm'].blank? ||
|
35
|
+
line['child_dobd'].blank? )
|
36
|
+
Date.new(
|
37
|
+
line['child_doby'].to_i,
|
38
|
+
line['child_dobm'].to_i,
|
39
|
+
line['child_dobd'].to_i)
|
40
|
+
else
|
41
|
+
nil
|
42
|
+
end
|
43
|
+
child_names = line["child_full_name"].to_s.split_name
|
44
|
+
father_names = line["father_full_name"].to_s.split_name
|
45
|
+
mother_names = line["mother_full_name"].to_s.split_name
|
46
|
+
#
|
47
|
+
# incoming data may be strings, but
|
48
|
+
# nil DOES NOT EQUAL "" for integer comparison
|
49
|
+
# so MUST nilify blank integer fields or will never find
|
50
|
+
# the record and will create duplicates every time.
|
51
|
+
#
|
52
|
+
# biomom = ( ( line["biomom"].blank? ) ? nil : line["biomom"] )
|
53
|
+
# biodad = ( ( line["biodad"].blank? ) ? nil : line["biodad"] )
|
54
|
+
# mother_hispanicity = ( (line["mother_hispanicity"].blank? ) ?
|
55
|
+
# nil : line["mother_hispanicity"] )
|
56
|
+
# mother_race = ( (line["mother_race"].blank? ) ?
|
57
|
+
# nil : line["mother_race"] )
|
58
|
+
# father_hispanicity = ( (line["father_hispanicity"].blank? ) ?
|
59
|
+
# nil : line["father_hispanicity"] )
|
60
|
+
# father_race = ( (line["father_race"].blank? ) ?
|
61
|
+
# nil : line["father_race"] )
|
62
|
+
|
63
|
+
candidate_control_options = {
|
64
|
+
# :related_patid => identifier.patid,
|
65
|
+
:related_patid => study_subject.patid,
|
66
|
+
:mom_is_biomom => line["biomom"].nilify_blank,
|
67
|
+
:dad_is_biodad => line["biodad"].nilify_blank,
|
68
|
+
#"date":nil # some event's occurred on
|
69
|
+
:first_name => child_names[0],
|
70
|
+
:middle_name => child_names[1],
|
71
|
+
:last_name => child_names[2],
|
72
|
+
# :father_first_name => father_names[0], # doesn't exist
|
73
|
+
# :father_middle_name => father_names[1], # doesn't exist
|
74
|
+
# :father_last_name => father_names[2], # doesn't exist
|
75
|
+
:mother_first_name => mother_names[0],
|
76
|
+
:mother_middle_name => mother_names[1],
|
77
|
+
:mother_last_name => mother_names[2],
|
78
|
+
:mother_maiden_name => line["mother_maiden_name"],
|
79
|
+
:dob => dob,
|
80
|
+
:sex => line["child_gender"],
|
81
|
+
#"birthplace_country":"United States" # doesn't exist
|
82
|
+
#"birthplace_state":"CA" # doesn't exist
|
83
|
+
#"birthplace_city":"Oakland" # doesn't exist
|
84
|
+
:mother_hispanicity_id => line["mother_hispanicity"].nilify_blank,
|
85
|
+
#"mother_hispanicity_mex":"2" # doesn't exist
|
86
|
+
:mother_race_id => line["mother_race"].nilify_blank,
|
87
|
+
#"mother_race_other":nil # doesn't exist
|
88
|
+
:father_hispanicity_id => line["father_hispanicity"].nilify_blank,
|
89
|
+
#"father_hispanicity_mex":"2" # doesn't exist
|
90
|
+
:father_race_id => line["father_race"].nilify_blank
|
91
|
+
#"father_race_other":nil # doesn't exist
|
92
|
+
}
|
93
|
+
candidate_control = CandidateControl.find(:first,
|
94
|
+
:conditions => candidate_control_options )
|
95
|
+
|
96
|
+
if candidate_control.nil?
|
97
|
+
candidate_control = CandidateControl.create( candidate_control_options )
|
98
|
+
# TODO what if there's an error?
|
99
|
+
end
|
100
|
+
# unless candidate_control.new_record?
|
101
|
+
# results.push(candidate_control.id)
|
102
|
+
# end
|
103
|
+
results.push(candidate_control)
|
104
|
+
|
105
|
+
else
|
106
|
+
results.push("Unexpected ca_co_status :#{line['ca_co_status']}:")
|
107
|
+
end # elsif line['ca_co_status'] == 'control'
|
108
|
+
end # (f=FasterCSV.open( self.csv_file.path, 'rb',{ :headers => true })).each
|
109
|
+
end # if !self.csv_file_file_name.blank? && File.exists?(self.csv_file.path)
|
110
|
+
results # TODO why am I returning anything? will I use this later?
|
111
|
+
end # def to_candidate_controls
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
# Probably better to move this somewhere more appropriate
|
117
|
+
# Perhaps CommonLib::StringExtension
|
118
|
+
# Trying to get actual names from hospital, so, hopefully,
|
119
|
+
# this won't be needed.
|
120
|
+
|
121
|
+
String.class_eval do
|
122
|
+
|
123
|
+
def split_name
|
124
|
+
# Really only want to split on spaces so just remove the problem chars.
|
125
|
+
# May have to add others later.
|
126
|
+
names = self.gsub(/\240/,' ').split
|
127
|
+
first = names.shift.to_s.squish
|
128
|
+
last = names.pop.to_s.squish
|
129
|
+
middle = names.join(' ').squish
|
130
|
+
[first,middle,last]
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
# Object and not String because could be NilClass
|
136
|
+
Object.class_eval do
|
137
|
+
|
138
|
+
def nilify_blank
|
139
|
+
( self.blank? ) ? nil : self
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# == requires
|
2
|
+
# * operational_event_type_id
|
3
|
+
class OperationalEvent < ActiveRecordShared
|
4
|
+
|
5
|
+
default_scope :order => 'occurred_on DESC'
|
6
|
+
belongs_to :enrollment
|
7
|
+
belongs_to :operational_event_type
|
8
|
+
|
9
|
+
validates_presence_of :enrollment_id
|
10
|
+
validates_presence_of :enrollment, :if => :enrollment_id
|
11
|
+
|
12
|
+
validates_presence_of :operational_event_type_id
|
13
|
+
validates_presence_of :operational_event_type, :if => :operational_event_type_id
|
14
|
+
|
15
|
+
validates_complete_date_for :occurred_on, :allow_nil => true
|
16
|
+
validates_length_of :description, :maximum => 250, :allow_blank => true
|
17
|
+
validates_length_of :event_notes, :maximum => 65000, :allow_blank => true
|
18
|
+
|
19
|
+
# Returns description
|
20
|
+
def to_s
|
21
|
+
description
|
22
|
+
end
|
23
|
+
|
24
|
+
# TODO perhaps move the search stuff into OperationalEventSearch?
|
25
|
+
|
26
|
+
# find wrapper
|
27
|
+
def self.search(options={})
|
28
|
+
find(:all,
|
29
|
+
:joins => joins(options),
|
30
|
+
:order => order(options),
|
31
|
+
:conditions => conditions(options)
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
before_save :copy_operational_event_type_description
|
36
|
+
|
37
|
+
protected
|
38
|
+
|
39
|
+
def copy_operational_event_type_description
|
40
|
+
if self.description.blank?
|
41
|
+
self.description = operational_event_type.description
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.valid_orders
|
46
|
+
%w( id occurred_on description type )
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.valid_order?(order)
|
50
|
+
valid_orders.include?(order)
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.order(options={})
|
54
|
+
if options.has_key?(:order) && valid_order?(options[:order])
|
55
|
+
order_string = case options[:order]
|
56
|
+
when 'type' then 'operational_event_types.description'
|
57
|
+
else options[:order]
|
58
|
+
end
|
59
|
+
dir = case options[:dir].try(:downcase)
|
60
|
+
when 'asc' then 'asc'
|
61
|
+
when 'desc' then 'desc'
|
62
|
+
else 'desc'
|
63
|
+
end
|
64
|
+
[order_string,dir].join(' ')
|
65
|
+
else
|
66
|
+
nil
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.joins(options={})
|
71
|
+
# TODO may have to use sql for LEFT JOINS rather than the rails symbol
|
72
|
+
joins = []
|
73
|
+
if options.has_key?(:order) && valid_order?(options[:order])
|
74
|
+
case options[:order]
|
75
|
+
when 'type' then joins << :operational_event_type
|
76
|
+
# 'LEFT JOIN operational_event_types ON operational_events.operational_event_type_id = operational_event_types.id',
|
77
|
+
end
|
78
|
+
end
|
79
|
+
if options.has_key?(:study_subject_id) and !options[:study_subject_id].blank?
|
80
|
+
joins << :enrollment
|
81
|
+
# 'LEFT JOIN enrollments ON operational_events.enrollment_id = enrollments.id',
|
82
|
+
end
|
83
|
+
joins
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.conditions(options={})
|
87
|
+
conditions = [[],[]]
|
88
|
+
if options.has_key?(:study_subject_id) and !options[:study_subject_id].blank?
|
89
|
+
conditions[0] << '(enrollments.study_subject_id = ?)'
|
90
|
+
conditions[1] << options[:study_subject_id]
|
91
|
+
end
|
92
|
+
unless conditions.flatten.empty?
|
93
|
+
[ conditions[0].join(' AND '), *(conditions[1].flatten) ]
|
94
|
+
else
|
95
|
+
nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|