renalware-core 2.0.64 → 2.0.67
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/renalware/application.js.erb +2 -2
- data/app/controllers/renalware/admin/users_controller.rb +1 -1
- data/app/controllers/renalware/api/ukrdc/patients_controller.rb +14 -67
- data/app/controllers/renalware/drugs/drugs_controller.rb +1 -1
- data/app/controllers/renalware/hd/protocols_controller.rb +1 -1
- data/app/controllers/renalware/patients/bookmarks_controller.rb +16 -5
- data/app/controllers/renalware/snippets/snippets_controller.rb +1 -1
- data/app/controllers/renalware/system/user_feedback_controller.rb +1 -1
- data/app/documents/renalware/hd/session_document.rb +1 -0
- data/app/models/renalware/admissions/consult_query.rb +1 -1
- data/app/models/renalware/clinical/dry_weight.rb +4 -0
- data/app/models/renalware/clinical/patient.rb +5 -0
- data/app/models/renalware/clinical/patient_dry_weights_query.rb +1 -1
- data/app/models/renalware/directory/person_query.rb +1 -1
- data/app/models/renalware/hd/mdm_patients_query.rb +1 -1
- data/app/models/renalware/hd/patient.rb +6 -0
- data/app/models/renalware/hd/patient_listener.rb +8 -0
- data/app/models/renalware/hd/sessions/ongoing_query.rb +1 -1
- data/app/models/renalware/hd/sessions/patient_query.rb +1 -1
- data/app/models/renalware/letters/descriptions/search_query.rb +1 -1
- data/app/models/renalware/letters/letter_factory.rb +55 -2
- data/app/models/renalware/letters/letter_query.rb +1 -1
- data/app/models/renalware/letters/recipient.rb +11 -0
- data/app/models/renalware/letters/resolve_default_electronic_ccs.rb +47 -0
- data/app/models/renalware/low_clearance/mdm_patients_query.rb +1 -1
- data/app/models/renalware/medications/prescriptions_by_drug_type_query.rb +1 -1
- data/app/models/renalware/medications/prescriptions_query.rb +1 -1
- data/app/models/renalware/patients/bookmarks_query.rb +49 -0
- data/app/models/renalware/patients/patient_search.rb +1 -1
- data/app/models/renalware/pd/mdm_patients_query.rb +1 -1
- data/app/models/renalware/renal/prd_descriptions/search_query.rb +1 -1
- data/app/models/renalware/transplants/live_donors_query.rb +1 -1
- data/app/models/renalware/transplants/mdm_patients_query.rb +1 -1
- data/app/models/renalware/transplants/registrations/wait_list_query.rb +1 -1
- data/app/models/renalware/ukrdc/create_encrypted_patient_xml_files.rb +13 -11
- data/app/models/renalware/ukrdc/create_patient_xml_file.rb +33 -21
- data/app/models/renalware/ukrdc/transmission_log.rb +1 -1
- data/app/models/renalware/ukrdc/xml_renderer.rb +126 -0
- data/app/presenters/renalware/clinical/dry_weight_presenter.rb +4 -0
- data/app/presenters/renalware/clinical/dry_weights_presenter.rb +15 -9
- data/app/presenters/renalware/ukrdc/modality_presenter.rb +8 -0
- data/app/presenters/renalware/ukrdc/patient_presenter.rb +9 -6
- data/app/views/renalware/api/ukrdc/patients/_clinical_relationships.xml.builder +4 -4
- data/app/views/renalware/api/ukrdc/patients/_encounters.xml.builder +9 -9
- data/app/views/renalware/api/ukrdc/patients/_family_histories.xml.builder +4 -4
- data/app/views/renalware/api/ukrdc/patients/_patient.xml.builder +1 -20
- data/app/views/renalware/api/ukrdc/patients/_program_memberships.xml.builder +4 -4
- data/app/views/renalware/api/ukrdc/patients/_surveys.xml.builder +4 -4
- data/app/views/renalware/api/ukrdc/patients/encounters/_hd_session.xml.builder +31 -31
- data/app/views/renalware/api/ukrdc/patients/encounters/_treatment.xml.builder +34 -0
- data/app/views/renalware/api/ukrdc/patients/lab_orders/_lab_order.xml.builder +1 -1
- data/app/views/renalware/api/ukrdc/patients/show.xml.builder +1 -1
- data/app/views/renalware/hd/mdm/_summary.html.slim +12 -4
- data/app/views/renalware/hd/protocols/_recent_pathology.html.slim +4 -0
- data/app/views/renalware/hd/sessions/_form.html.slim +1 -0
- data/app/views/renalware/mdm/_prescription_buttons.html.slim +15 -0
- data/app/views/renalware/mdm/_prescriptions.html.slim +1 -8
- data/app/views/renalware/patients/bookmarks/_bookmark.html.slim +16 -0
- data/app/views/renalware/patients/bookmarks/_table.html.slim +20 -0
- data/app/views/renalware/patients/bookmarks/index.html.slim +3 -1
- data/app/views/renalware/transplants/mdm/_prescriptions.html.slim +1 -8
- data/config/initializers/core_extensions.rb +1 -1
- data/config/initializers/renalware.rb +3 -0
- data/config/locales/renalware/hd/session.en.yml +7 -0
- data/config/locales/renalware/patients/bookmarks.en.yml +12 -0
- data/config/locales/renalware/patients/side_menu.en.yml +1 -1
- data/db/migrate/20150119160039_create_versions.rb +3 -3
- data/db/migrate/20150120155952_create_problem_versions.rb +3 -3
- data/db/migrate/20150203161438_create_medication_prescription_versions.rb +3 -3
- data/db/migrate/20150515155052_users_have_and_belong_to_many_roles.rb +3 -1
- data/db/migrate/20160120203747_create_access_versions.rb +3 -3
- data/db/migrate/20160121175711_create_hd_versions.rb +3 -3
- data/db/migrate/20170217141529_create_clinic_versions.rb +3 -3
- data/db/migrate/20170217161409_create_patient_versions.rb +3 -3
- data/db/migrate/20170605102519_create_clinical_versions.rb +3 -3
- data/db/migrate/20171002175804_add_rr_columns_to_transplant_registration_status_descriptions.rb +9 -7
- data/db/migrate/20171003093347_create_hospital_wards.rb +14 -12
- data/db/migrate/20171003111228_create_aki_alert_actions.rb +6 -4
- data/db/migrate/20171003122425_create_renal_aki_alerts.rb +18 -16
- data/db/migrate/20171004092235_create_hd_dialysates.rb +9 -7
- data/db/migrate/20171004110909_add_dialysate_id_to_profile_and_session.rb +6 -4
- data/db/migrate/20171005081224_create_reporting_bone_audit.rb +3 -1
- data/db/migrate/20171005091202_reporting_audit_changes.rb +5 -3
- data/db/migrate/20171005130109_create_medication_current_prescriptions.rb +3 -1
- data/db/migrate/20171005144505_create_reporting_anaemia_audit.rb +3 -1
- data/db/migrate/20171009104106_add_legacy_patient_id_to_patients.rb +4 -2
- data/db/migrate/20171009181615_add_columns_to_drug_drugs.rb +6 -4
- data/db/migrate/20171012110133_create_research_studies.rb +19 -17
- data/db/migrate/20171012143050_create_research_study_participants.rb +27 -25
- data/db/migrate/20171013145849_set_patients_secure_id.rb +12 -10
- data/db/migrate/20171016152223_add_index_to_diary_slots.rb +14 -12
- data/db/migrate/20171017132738_add_unique_indexes_to_local_patient_ids.rb +11 -9
- data/db/migrate/20171017171625_update_hd_overall_audit_view.rb +7 -5
- data/db/migrate/20171101121130_create_function_to_render_audit_view_as_json.rb +6 -4
- data/db/migrate/20171101162244_create_consults.rb +21 -19
- data/db/migrate/20171106100216_create_pd_audit_view.rb +3 -1
- data/db/migrate/20171109084751_remove_local_patient_id_unique_idx.rb +11 -9
- data/db/migrate/20171113120217_add_uuid_to_hd_sessions.rb +4 -2
- data/db/migrate/20171114120904_add_pathology_snapshot_to_letters.rb +3 -1
- data/db/migrate/20171118160030_add_tags_to_patient_bookmarks.rb +3 -1
- data/db/migrate/20171123123712_add_id_to_roles_users.rb +3 -1
- data/db/migrate/20171123143534_add_pk_to_drug_types_drugs.rb +13 -12
- data/db/migrate/20171123154116_create_renal_versions.rb +11 -9
- data/db/migrate/20171127082158_add_region_to_addresses.rb +3 -1
- data/db/migrate/20171127092158_create_function_to_import_practices.rb +6 -2
- data/db/migrate/20171127092359_create_fn_to_insert_gps.rb +6 -2
- data/db/migrate/20171128163543_add_more_missing_indexes.rb +14 -12
- data/db/migrate/20171204112150_create_consult_sites.rb +13 -9
- data/db/migrate/20171206121652_add_loinc_code_to_observation_descriptions.rb +3 -1
- data/db/migrate/20171206140738_create_fn_to_load_practice_memberships_csv.rb +9 -5
- data/db/migrate/20171208211206_create_user_feedback.rb +7 -5
- data/db/migrate/20171211130716_remove_unused_patients_cols.rb +4 -2
- data/db/migrate/20171211131918_remove_email_from_primary_care_physicians.rb +5 -3
- data/db/migrate/20171211161400_create_pathology_current_table.rb +9 -7
- data/db/migrate/20171213111513_create_fn_to_refresh_current_obs.rb +6 -2
- data/db/migrate/20171214141335_create_trigger_to_update_current_observation_sets.rb +10 -6
- data/db/migrate/20171214190849_enforce_request_id_on_observations.rb +3 -1
- data/db/migrate/20171215122454_add_pathology_observation_set_to_letters.rb +8 -6
- data/db/migrate/20171219154529_create_admission_admissions.rb +25 -23
- data/db/migrate/20180102155055_update_patient_summaries_to_version_5.rb +3 -1
- data/db/migrate/20180105132358_add_emailed_at_to_letter_recipients.rb +4 -2
- data/db/migrate/20180108185400_remove_null_constraint_from_letters_pathology_snapshot.rb +3 -1
- data/db/migrate/20180112151706_create_low_clearance_profiles.rb +43 -41
- data/db/migrate/20180112151813_create_low_clearance_versions.rb +11 -9
- data/db/migrate/20180119121243_create_trigger_to_preprocess_hl7_msg.rb +10 -6
- data/db/migrate/20180121115246_add_include_pathology_in_letter_to_letters_letterheads.rb +3 -1
- data/db/migrate/20180122173922_create_virology_profiles.rb +5 -1
- data/db/migrate/20180125201356_make_obs_set_trigger_change_updated_at.rb +6 -2
- data/db/migrate/20180126142314_add_uuid_to_letters.rb +4 -2
- data/db/migrate/20180130165803_add_deleted_at_indexes.rb +14 -12
- data/db/migrate/20180201090444_add_created_at_to_delayed_jobs_in_hl7_trig_fn.rb +6 -2
- data/db/migrate/20180202184954_create_view_pathology_observation_digests.rb +3 -1
- data/db/migrate/20180206225525_update_fn_update_current_observation_set_from_trigger.rb +6 -2
- data/db/migrate/20180207082540_create_count_estimate_function.rb +6 -2
- data/db/migrate/20180208150629_add_authentication_token_to_users.rb +3 -1
- data/db/migrate/20180213124203_add_cancelled_to_pathology_observations.rb +7 -5
- data/db/migrate/20180213125734_update_fn_update_current_obs_set_trgger.rb +6 -2
- data/db/migrate/20180213171805_add_display_order_cols_to_observation_descriptions.rb +10 -8
- data/db/migrate/20180214124317_add_cols_to_aki_alerts.rb +7 -5
- data/db/migrate/20180216132741_disable_some_audits.rb +6 -4
- data/db/migrate/20180221210458_add_state_index_on_modalities.rb +3 -1
- data/db/migrate/20180222090501_add_partial_index_to_bookmarks.rb +4 -2
- data/db/migrate/20180223100420_add_sent_to_ukrdc_at_to_patients.rb +3 -1
- data/db/migrate/20180226124724_add_patient_id_to_virology_profile.rb +9 -5
- data/db/migrate/20180226132410_create_ukrdc_transmission_logs.rb +12 -10
- data/db/migrate/20180301095040_update_fn_to_upsert_gp_practive_memberships.rb +7 -3
- data/db/migrate/20180305134959_add_display_group_to_observation_desriptions.rb +23 -22
- data/db/migrate/20180306071308_remove_rogue_aki_alerts_column.rb +3 -1
- data/db/migrate/20180306080518_add_state_tracking_cols_to_letters.rb +17 -15
- data/db/migrate/20180307191650_add_dwell_time_to_pd_regime.rb +3 -1
- data/db/migrate/20180307223111_create_system_visits_and_events.rb +42 -39
- data/db/migrate/20180309140316_add_unique_constraint_to_obr_requestor.rb +3 -1
- data/db/migrate/20180311104609_remove_unique_obr_requestor_order_number_index.rb +4 -2
- data/db/migrate/20180313114927_remove_deleted_at_from_admission_consults.rb +3 -1
- data/db/migrate/20180313124819_remove_tx_operation_constraints.rb +7 -5
- data/db/migrate/20180319191942_create_function_to_sort_without_failing_on_nonnumerics.rb +6 -2
- data/db/migrate/20180323150241_update_path_obs_descs_for_letter_groupings.rb +25 -23
- data/db/migrate/20180326155400_add_admin_notes_to_system_user_feedback.rb +4 -2
- data/db/migrate/20180327100423_add_constraints_to_recipient_operations.rb +3 -1
- data/db/migrate/20180328210434_add_rrt_to_admission_consults.rb +3 -1
- data/db/migrate/20180419141524_add_cols_to_hd_patient_statistics.rb +8 -6
- data/db/migrate/20180422090043_update_hd_overall_audit_to_version_6.rb +85 -84
- data/db/migrate/20180427133558_add_code_to_hospitals_wards.rb +3 -1
- data/db/migrate/20180502093256_add_document_to_virology_profiles.rb +22 -21
- data/db/migrate/20180502110638_create_virology_versions.rb +7 -5
- data/db/migrate/20180510151959_update_hd_overall_audit_to_version_7.rb +8 -4
- data/db/migrate/20180511100345_add_notes_to_transplant_registration_statuses.rb +3 -1
- data/db/migrate/20180511140415_add_message_hash_messaging_messages.rb +4 -2
- data/db/migrate/20180511171835_create_unique_indexes_on_obr_obr_codes.rb +5 -3
- data/db/migrate/20180514151627_create_system_messages.rb +10 -8
- data/db/migrate/20180516111411_create_view_patient_current_modalities.rb +3 -1
- data/db/migrate/20180524072633_add_columns_to_dialysates.rb +10 -8
- data/db/migrate/20180524074320_add_columns_to_hd_dialysers.rb +8 -6
- data/db/migrate/20180605114332_create_pseudo_encrypt_function.rb +6 -2
- data/db/migrate/20180605141806_add_external_id_to_research_study_participants.rb +33 -31
- data/db/migrate/20180605175211_add_application_url_to_research_studies.rb +3 -1
- data/db/migrate/20180622130552_add_external_id_to_hd_sessions.rb +4 -2
- data/db/migrate/20180625124431_add_patient_identifier_to_feed_messages.rb +3 -1
- data/db/migrate/20180628132323_add_letter_date_indexes.rb +9 -7
- data/db/migrate/20180702091222_create_hd_providers.rb +5 -3
- data/db/migrate/20180702091237_create_hd_provider_units.rb +8 -6
- data/db/migrate/20180702091352_create_hd_transmission_log.rb +15 -13
- data/db/migrate/20180712143314_add_hidden_to_modality_descriptions.rb +3 -1
- data/db/migrate/20180718172750_update_audit_letters_authors_to_version_3.rb +13 -11
- data/db/migrate/20180725132557_add_days_text_to_hd_schedule_definitions.rb +21 -19
- data/db/migrate/20180725132808_create_hd_schedule_definition_filters_view.rb +3 -1
- data/db/migrate/20180730154454_add_external_session_id_to_hd_transmission_logs.rb +7 -5
- data/db/migrate/20180802103013_add_hd_mdm_missing_indexes.rb +6 -4
- data/db/migrate/20180802132417_add_missing_indexes_2.rb +16 -14
- data/db/migrate/20180802144507_add_missing_foreign_key_indexes.rb +14 -12
- data/db/migrate/20180803131157_add_uuid_to_hd_transmission_logs.rb +7 -1
- data/db/migrate/20180814103916_create_index_on_lower_patient_family_name.rb +5 -3
- data/db/migrate/20180815144429_update_hd_overall_audit_to_version_8.rb +8 -4
- data/db/migrate/20180831134926_create_daily_reports.rb +3 -6
- data/db/migrate/20180907100545_add_page_count_to_letters.rb +3 -1
- data/db/migrate/20181001162513_add_active_to_hospital_wards.rb +3 -1
- data/db/migrate/20181008144324_update_daily_letters_report_view_to_version_2.rb +0 -2
- data/db/migrate/20181008145159_create_reporting_daily_ukrdc_view.rb +0 -4
- data/db/migrate/20181013115138_update_reporting_daily_pathology_view_to_v2.rb +0 -2
- data/db/migrate/20181025170410_add_ukrdc_helper_column_to_patients.rb +0 -2
- data/db/migrate/20181026145459_create_ukrdc_batch_numbers.rb +5 -3
- data/db/migrate/20181106133500_update_hd_overall_audit_to_version_9.rb +0 -2
- data/db/migrate/20181109110616_create_hd_grouped_transmission_logs_view.rb +0 -2
- data/db/migrate/20181126090401_add_warnings_to_hd_transmission_logs.rb +7 -0
- data/db/migrate/20181126123745_refresh_hd_grouped_transmission_logs_view.rb +8 -0
- data/db/migrate/20181217124025_change_ukrdc_transmission_log_error_type.rb +15 -0
- data/db/seeds/default/practices/nhs_practices_sample.csv +2 -2
- data/db/seeds/default/practices/primary_care_physicians_sample.csv +2 -2
- data/lib/core_extensions/active_record/migration_helpers.rb +43 -1
- data/lib/renalware/engine.rb +2 -0
- data/lib/renalware/version.rb +1 -1
- metadata +55 -19
- data/lib/migration_helper.rb +0 -11
- data/vendor/assets/javascripts/renalware/moment.min.js +0 -1
- data/vendor/assets/javascripts/renalware/mousetrap.js +0 -1044
@@ -88,6 +88,8 @@ module Renalware
|
|
88
88
|
|
89
89
|
def practice_address_for_patient
|
90
90
|
address = letter.patient&.practice&.address
|
91
|
+
ensure_practice_name_is_present_in(address)
|
92
|
+
|
91
93
|
if address.present? && letter.primary_care_physician.present?
|
92
94
|
ensure_address_has_a_name_required_when_displaying_letters(
|
93
95
|
address,
|
@@ -97,6 +99,15 @@ module Renalware
|
|
97
99
|
address
|
98
100
|
end
|
99
101
|
|
102
|
+
# There may not be an organisation name eg "Mill House Clinic" on the address record
|
103
|
+
# (in fact is unlikely) in which case copy it over from the practice so it will be displayed
|
104
|
+
# under the GP's name on the letter.
|
105
|
+
def ensure_practice_name_is_present_in(address)
|
106
|
+
return if address.blank?
|
107
|
+
|
108
|
+
address.organisation_name ||= letter.patient&.practice&.name
|
109
|
+
end
|
110
|
+
|
100
111
|
def address_for_addressee_eg_contact
|
101
112
|
addressee.address.tap do |address|
|
102
113
|
ensure_address_has_a_name_required_when_displaying_letters(
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "attr_extras"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module Letters
|
7
|
+
# This class is responsible for collating the complete set of default electronic ccs for a new
|
8
|
+
# patient letter.
|
9
|
+
# An HD patient for instance might have a named nurse who should always be eCCed into any
|
10
|
+
# letters about them.
|
11
|
+
# Important to note here is that we are of course in the Letters module and have no knowledge
|
12
|
+
# of who should be eCCs and how to resolve those users; these are matters that relate for
|
13
|
+
# example to the user's current modality and the corresponding module (HD, PD, Transplant etc).
|
14
|
+
# So here all we can do is broadcast a (synchronous) event asking anyone listening (ie any
|
15
|
+
# class that is configured to listen in the broadcast_map) to add their eCC users to the
|
16
|
+
# passed in array_of_user_ids array. We will then dedupe and return that array,
|
17
|
+
# where it will be used to initialize the eCC component on the letters UI form with the correct
|
18
|
+
# initial default set up eCC users. This only applies to new letters, ie when displaying the
|
19
|
+
# the UI form for a new letter.
|
20
|
+
#
|
21
|
+
# Example usage:
|
22
|
+
#
|
23
|
+
# array_of_ecc_users = ResolveDefaultElectronicCCs
|
24
|
+
# .for(patient)
|
25
|
+
# .broadcasting_to_configured_subscribers
|
26
|
+
# .call
|
27
|
+
#
|
28
|
+
class ResolveDefaultElectronicCCs
|
29
|
+
include Broadcasting
|
30
|
+
pattr_initialize :patient
|
31
|
+
|
32
|
+
def self.for(patient)
|
33
|
+
new(patient)
|
34
|
+
end
|
35
|
+
|
36
|
+
def call
|
37
|
+
array_of_user_ids = []
|
38
|
+
broadcast(
|
39
|
+
:request_default_electronic_cc_recipients_for_use_in_letters,
|
40
|
+
patient: patient,
|
41
|
+
array_of_user_ids: array_of_user_ids
|
42
|
+
)
|
43
|
+
array_of_user_ids.compact.uniq
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -33,7 +33,7 @@ module Renalware
|
|
33
33
|
.left_outer_joins(:current_observation_set)
|
34
34
|
.with_current_modality_of_class(LowClearance::ModalityDescription)
|
35
35
|
.public_send(named_filter.to_s)
|
36
|
-
.
|
36
|
+
.ransack(query)
|
37
37
|
end
|
38
38
|
end
|
39
39
|
# rubocop:enable Metrics/MethodLength
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/admissions"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module Patients
|
7
|
+
class BookmarksQuery
|
8
|
+
attr_reader :default_relation, :query
|
9
|
+
|
10
|
+
def initialize(default_relation:, params: nil)
|
11
|
+
@default_relation = default_relation
|
12
|
+
@query = params || {}
|
13
|
+
@query[:s] ||= "created_at desc"
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
search.result
|
18
|
+
end
|
19
|
+
|
20
|
+
# Note we *MUST* join onto patients for PatientsRansackHelper.identity_match to work.
|
21
|
+
# It might be better to refactor PatientsRansackHelper so we can include where required
|
22
|
+
# eg below using .extending(PatientsRansackHelper) rather than relying on it being in
|
23
|
+
# included in the model file.
|
24
|
+
# note that adding .includes(:created_by) here creates an ambigous column
|
25
|
+
# 'family_name' error
|
26
|
+
def search
|
27
|
+
@search ||= begin
|
28
|
+
(default_relation || Bookmark)
|
29
|
+
.extend(RansackScopes)
|
30
|
+
.joins(:patient)
|
31
|
+
.eager_load(patient: [current_modality: :description])
|
32
|
+
.order(created_at: :desc)
|
33
|
+
.ransack(query)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module RansackScopes
|
38
|
+
def self.extended(base)
|
39
|
+
# Using a custom ransacker here in order to sort by modality description name
|
40
|
+
# because using a predicate like :patient_current_modality_description_name
|
41
|
+
# results in an INNER JOIN onto modalities.
|
42
|
+
base.ransacker :modality_desc do
|
43
|
+
Arel.sql("modality_descriptions.name")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -6,7 +6,7 @@ module Renalware
|
|
6
6
|
def self.call(params)
|
7
7
|
Renalware::Patient
|
8
8
|
.includes(current_modality: [:description])
|
9
|
-
.
|
9
|
+
.ransack(params[:patient_search]).tap do |search|
|
10
10
|
search.sorts = %w(family_name_case_insensitive given_name)
|
11
11
|
end
|
12
12
|
end
|
@@ -26,7 +26,7 @@ module Renalware
|
|
26
26
|
.eager_load(current_status: :description)
|
27
27
|
.merge(HD::Patient.with_profile)
|
28
28
|
.merge(Renal::Patient.with_profile)
|
29
|
-
.
|
29
|
+
.ransack(query).tap do |s|
|
30
30
|
|
31
31
|
s.sorts = ["patient_family_name, patient_given_name"]
|
32
32
|
end
|
@@ -17,10 +17,9 @@ module Renalware
|
|
17
17
|
:changed_since,
|
18
18
|
:logger,
|
19
19
|
:request_uuid,
|
20
|
-
:paths,
|
21
20
|
:timestamp,
|
22
|
-
:
|
23
|
-
:
|
21
|
+
:batch_number,
|
22
|
+
:summary
|
24
23
|
)
|
25
24
|
|
26
25
|
def initialize(changed_since: nil, patient_ids: nil, logger: nil)
|
@@ -29,20 +28,13 @@ module Renalware
|
|
29
28
|
@logger = logger || Rails.logger
|
30
29
|
@request_uuid = SecureRandom.uuid # helps group logs together
|
31
30
|
@timestamp = Time.zone.now.strftime("%Y%m%d%H%M%S%L")
|
32
|
-
|
31
|
+
@batch_number ||= BatchNumber.next.number
|
33
32
|
@summary = ExportSummary.new
|
34
33
|
end
|
35
34
|
|
36
35
|
def call
|
37
36
|
logger.tagged(request_uuid) do
|
38
|
-
# Skipping transaction for now as worried about the quantity of rows and data invovled.
|
39
37
|
ActiveRecord::Base.transaction do
|
40
|
-
@batch_number = BatchNumber.next.number
|
41
|
-
@paths = Paths.new(
|
42
|
-
timestamp: timestamp,
|
43
|
-
batch_number: batch_number,
|
44
|
-
working_path: config.ukrdc_working_path
|
45
|
-
)
|
46
38
|
summary.milliseconds_taken = Benchmark.ms do
|
47
39
|
create_patient_xml_files
|
48
40
|
encrypt_patient_xml_files
|
@@ -62,6 +54,16 @@ module Renalware
|
|
62
54
|
|
63
55
|
private
|
64
56
|
|
57
|
+
def paths
|
58
|
+
@paths ||= begin
|
59
|
+
Paths.new(
|
60
|
+
timestamp: timestamp,
|
61
|
+
batch_number: batch_number,
|
62
|
+
working_path: config.ukrdc_working_path
|
63
|
+
)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
65
67
|
def create_patient_xml_files
|
66
68
|
patients = ukrdc_patients_who_have_changed_since_last_send
|
67
69
|
summary.num_changed_patients = patients.count
|
@@ -10,24 +10,28 @@ module Renalware
|
|
10
10
|
:patient!,
|
11
11
|
:dir!,
|
12
12
|
:request_uuid!,
|
13
|
-
:renderer,
|
14
13
|
:changes_since,
|
15
14
|
:logger,
|
16
|
-
:batch_number
|
15
|
+
:batch_number,
|
16
|
+
:renderer, # so we can pass a test renderer to bypass real rendering
|
17
|
+
:log
|
17
18
|
]
|
18
19
|
|
19
20
|
# rubocop:disable Metrics/AbcSize
|
20
21
|
def call
|
21
22
|
update_patient_to_indicated_we_checked_them_for_any_relevant_changes
|
22
23
|
UKRDC::TransmissionLog.with_logging(patient, request_uuid) do |log|
|
24
|
+
@log = log
|
23
25
|
logger.info " Patient #{patient.ukrdc_external_id}"
|
24
26
|
xml_payload = build_payload(log)
|
25
|
-
if
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
if xml_payload.present?
|
28
|
+
if xml_payload_same_as_last_sent_payload?(xml_payload)
|
29
|
+
logger.info " skipping as no change in XML file"
|
30
|
+
log.unsent_no_change_since_last_send!
|
31
|
+
else
|
32
|
+
create_xml_file(xml_payload, log)
|
33
|
+
update_patient_to_indicate_we_have_sent_their_data_to_ukrdc
|
34
|
+
end
|
31
35
|
end
|
32
36
|
logger.info " Status: #{log.status}"
|
33
37
|
end
|
@@ -72,17 +76,30 @@ module Renalware
|
|
72
76
|
end
|
73
77
|
|
74
78
|
def build_payload(log)
|
75
|
-
|
76
|
-
|
77
|
-
|
79
|
+
result = attempt_to_generate_patient_ukrdc_xml
|
80
|
+
if result.failure?
|
81
|
+
handle_invalid_xml(result)
|
82
|
+
nil
|
83
|
+
else
|
84
|
+
Payload.new(result.xml).tap do |payload|
|
85
|
+
log.payload = payload.to_s
|
86
|
+
log.payload_hash = payload.to_md5_hash
|
87
|
+
end
|
78
88
|
end
|
79
89
|
end
|
80
90
|
|
81
|
-
def
|
82
|
-
renderer.
|
83
|
-
|
84
|
-
|
85
|
-
|
91
|
+
def attempt_to_generate_patient_ukrdc_xml
|
92
|
+
(renderer || default_renderer).call
|
93
|
+
end
|
94
|
+
|
95
|
+
def handle_invalid_xml(result)
|
96
|
+
log.error = result.validation_errors
|
97
|
+
log.status = :error
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
|
101
|
+
def default_renderer
|
102
|
+
Renalware::UKRDC::XmlRenderer.new(locals: { patient: presenter_for(patient) })
|
86
103
|
end
|
87
104
|
|
88
105
|
def presenter_for(patient)
|
@@ -92,11 +109,6 @@ module Renalware
|
|
92
109
|
)
|
93
110
|
end
|
94
111
|
|
95
|
-
# Note a test might have passed in a mock renderer
|
96
|
-
def renderer
|
97
|
-
@renderer ||= Renalware::API::UKRDC::PatientsController.renderer
|
98
|
-
end
|
99
|
-
|
100
112
|
def xml_filepath
|
101
113
|
xml_filename = Filename.new(patient: patient, batch_number: batch_number).to_s
|
102
114
|
File.join(dir, xml_filename)
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module UKRDC
|
7
|
+
class XmlRenderer
|
8
|
+
DEFAULT_TEMPLATE = "/renalware/api/ukrdc/patients/show"
|
9
|
+
attr_reader :template, :xsd_path, :locals, :errors
|
10
|
+
|
11
|
+
class Success < Renalware::Success
|
12
|
+
alias_method :xml, :object
|
13
|
+
end
|
14
|
+
|
15
|
+
class Failure < Renalware::Failure
|
16
|
+
alias_method :validation_errors, :object
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(template: nil, xsd_path: nil, locals: {})
|
20
|
+
@template = template || DEFAULT_TEMPLATE
|
21
|
+
@xsd_path = xsd_path || default_xsd_path
|
22
|
+
@locals = locals
|
23
|
+
end
|
24
|
+
|
25
|
+
# If we successfully generate the UKRDC XML for a patient, return a Success object where
|
26
|
+
# success#xml is the valid XML
|
27
|
+
# If there are XSD validation messages, we return a Failure object where
|
28
|
+
# failure#validation_messages is an array of XSD validation messages.
|
29
|
+
def call
|
30
|
+
return XmlRenderer::Failure.new(validation_errors) if validation_errors.any?
|
31
|
+
|
32
|
+
XmlRenderer::Success.new(xml)
|
33
|
+
end
|
34
|
+
|
35
|
+
def xml
|
36
|
+
@xml ||= begin
|
37
|
+
API::UKRDC::PatientsController.new.render_to_string(
|
38
|
+
template: template,
|
39
|
+
format: :xml,
|
40
|
+
locals: locals,
|
41
|
+
encoding: "UTF-8"
|
42
|
+
)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Returns an array of SchemaValidation errors
|
47
|
+
def validation_errors
|
48
|
+
@validation_errors ||= begin
|
49
|
+
document = Nokogiri::XML(xml)
|
50
|
+
xsddoc = Nokogiri::XML(File.read(xsd_path), xsd_path)
|
51
|
+
schema = Nokogiri::XML::Schema.from_document(xsddoc)
|
52
|
+
schema.validate(document)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def default_xsd_path
|
59
|
+
File.join(Renalware::Engine.root, "vendor/xsd/ukrdc/Schema/UKRDC.xsd")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# An alternative xml rendering implementation - we moved to a template based approach
|
67
|
+
# for now as its provides more clarity
|
68
|
+
#
|
69
|
+
|
70
|
+
# class Base
|
71
|
+
# include ActiveModel::Serializers::Xml
|
72
|
+
# include Virtus::Model
|
73
|
+
# end
|
74
|
+
|
75
|
+
# class PatientNumber < Base
|
76
|
+
# attribute :number, String
|
77
|
+
# attribute :organisation, String
|
78
|
+
|
79
|
+
# def self.build_nhs_number(number)
|
80
|
+
# new(number: number, organisation: "NHS")
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
|
84
|
+
# class Name < Base
|
85
|
+
# attribute :prefix, String
|
86
|
+
# attribute :family, String
|
87
|
+
# attribute :given, String
|
88
|
+
# attribute :suffix, String
|
89
|
+
# attribute :use, String
|
90
|
+
# end
|
91
|
+
|
92
|
+
# class Patient < Base
|
93
|
+
# attribute :gender, String # 0=Not Known 1=Male 2=Female 9=Not Specified.
|
94
|
+
# attribute :birth_time, DateTime
|
95
|
+
# attribute :death_time, DateTime
|
96
|
+
# attribute :patient_numbers, Array(PatientNumber)
|
97
|
+
# attribute :name, Name
|
98
|
+
# attribute :country_of_birth, String # ISO 3166-1 3-char alphabetic code
|
99
|
+
# end
|
100
|
+
|
101
|
+
# rdc_patient = UKRDC::Patient.new(
|
102
|
+
# gender: patient.sex&.code,
|
103
|
+
# birth_time: patient.born_on,
|
104
|
+
# death_time: patient.died_on,
|
105
|
+
# country_of_birth: "???"
|
106
|
+
# )
|
107
|
+
|
108
|
+
# rdc_patient.name = Name.new(
|
109
|
+
# prefix: patient.title,
|
110
|
+
# family: patient.family_name,
|
111
|
+
# given: patient.given_name,
|
112
|
+
# suffix: patient.suffix
|
113
|
+
# )
|
114
|
+
|
115
|
+
# rdc_patient.patient_numbers << UKRDC::PatientNumber.build_nhs_number(patient.nhs_number)
|
116
|
+
# Renalware.config.patient_hospital_identifiers.each do |_key, field|
|
117
|
+
# number = patient.public_send(field)
|
118
|
+
# unless number.blank?
|
119
|
+
# patient_number = UKRDC::PatientNumber.new(number: number, organisation: "LOCALHOSP")
|
120
|
+
# rdc_patient.patient_numbers << patient_number
|
121
|
+
# end
|
122
|
+
# end
|
123
|
+
|
124
|
+
# # Render XML
|
125
|
+
# respond_with rdc_patient, camelize: true
|
126
|
+
#
|