renalware-core 2.0.130 → 2.0.131
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -2
- data/app/controllers/renalware/admin/users_controller.rb +1 -0
- data/app/controllers/renalware/medications/prescriptions_controller.rb +2 -2
- data/app/controllers/renalware/patients/patients_controller.rb +1 -1
- data/app/jobs/renalware/letters/calculate_page_count_job.rb +5 -0
- data/app/models/concerns/renalware/pdf_compilation.rb +2 -2
- data/app/models/renalware/events/lists/form.rb +1 -1
- data/app/models/renalware/letters/approve_letter.rb +3 -1
- data/app/models/renalware/letters/delivery/email_letter_to_practice.rb +6 -14
- data/app/models/renalware/letters/lists/form.rb +2 -2
- data/app/models/renalware/letters/pdf_renderer.rb +1 -0
- data/app/models/renalware/letters/printing/pdf_combining.rb +2 -2
- data/app/models/renalware/medications/dose_unit.rb +2 -0
- data/app/models/renalware/modalities/description.rb +10 -2
- data/app/models/renalware/pd/apd/glucose_calculator.rb +2 -2
- data/app/models/renalware/system/update_user.rb +3 -0
- data/app/models/renalware/ukrdc/create_encrypted_patient_xml_files.rb +15 -4
- data/app/models/renalware/ukrdc/create_patient_xml_file.rb +16 -3
- data/app/models/renalware/ukrdc/outgoing/rendering/address.rb +38 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/allergy.rb +27 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/base.rb +20 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/cause_of_death.rb +38 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/clinic_visit_observation.rb +24 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/clinician.rb +12 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/diagnoses.rb +63 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/diagnosis.rb +52 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/dialysis_session.rb +81 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/document.rb +46 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/entered_at.rb +26 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/entered_by.rb +12 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/family_doctor.rb +30 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/hd_session_observations.rb +51 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/hd_treatment.rb +26 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/lab_order.rb +80 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/lab_orders.rb +30 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/medication.rb +77 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/name.rb +29 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/observation.rb +70 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/observations.rb +58 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/patient.rb +167 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/patient_number.rb +27 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/patient_numbers.rb +53 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/pd_treatment.rb +27 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/primary_language.rb +35 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/procedures.rb +40 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/renal_diagnosis.rb +35 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/transplant.rb +69 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/treatment.rb +78 -0
- data/app/models/renalware/ukrdc/outgoing/rendering/user.rb +33 -0
- data/app/models/renalware/ukrdc/pathology_observation_requests_query.rb +1 -0
- data/app/models/renalware/ukrdc/xml_renderer.rb +54 -75
- data/app/models/renalware/user.rb +4 -1
- data/app/presenters/renalware/hd/scheduling/diary_presenter.rb +2 -2
- data/app/presenters/renalware/system/users_presenter.rb +1 -1
- data/app/presenters/renalware/ukrdc/transplant_operation_presenter.rb +4 -0
- data/app/views/renalware/admin/users/edit.html.slim +6 -0
- data/app/views/renalware/admin/users/index.html.slim +6 -1
- data/app/views/renalware/api/ukrdc/patients/_clinic_visit_observation.xml.builder +3 -3
- data/app/views/renalware/api/ukrdc/patients/_documents.xml.builder +28 -24
- data/app/views/renalware/api/ukrdc/patients/_sending_facility.xml.builder +1 -1
- data/app/views/renalware/api/ukrdc/patients/_treatments.xml.builder +0 -27
- data/app/views/renalware/api/ukrdc/patients/show.xml.builder +1 -5
- data/app/views/renalware/medications/drug_types/prescriptions/_table.html.slim +1 -1
- data/app/views/renalware/patients/patients/_form.html.slim +1 -0
- data/app/views/renalware/patients/patients/show/_contact_details.html.slim +2 -1
- data/config/initializers/core_extensions.rb +1 -0
- data/config/initializers/devise.rb +1 -1
- data/config/locales/renalware/medications/prescription.yml +2 -0
- data/db/migrate/20170526060804_enable_uuid_extension.rb +1 -1
- data/db/migrate/20191219145651_add_hidden_to_users.rb +8 -0
- data/db/migrate/20200106073329_add_next_of_kin_to_patients.rb +7 -0
- data/db/migrate/20200106210851_create_case_insensitive_index_on_patients.rb +22 -0
- data/lib/core_extensions/active_record/migration_helpers.rb +7 -0
- data/lib/core_extensions/ox/element_additions.rb +18 -0
- data/lib/renalware/engine.rb +2 -1
- data/lib/renalware/version.rb +1 -1
- data/lib/tasks/spec.rake +33 -0
- data/spec/factories/accesses/assessments.rb +18 -0
- data/spec/factories/accesses/catheter_insertion_techniques.rb +8 -0
- data/spec/factories/accesses/plans.rb +1 -1
- data/spec/factories/accesses/plans_types.rb +1 -1
- data/spec/factories/accesses/procedures.rb +2 -2
- data/spec/factories/accesses/profiles.rb +1 -1
- data/spec/factories/accesses/sites.rb +1 -1
- data/spec/factories/accesses/types.rb +1 -1
- data/spec/factories/hd/hd_session_document.rb +8 -8
- data/spec/factories/transplants/donations.rb +1 -1
- data/spec/factories/transplants/recipient_followups.rb +1 -1
- data/spec/factories/transplants/recipient_operations.rb +1 -1
- data/spec/factories/transplants/registration_status_descriptions.rb +1 -1
- data/spec/factories/transplants/registration_statuses.rb +1 -1
- data/spec/factories/transplants/registrations.rb +1 -1
- data/spec/factories/transplants/rejection_episodes.rb +1 -1
- data/spec/factories/transplants/rejection_treatments.rb +1 -1
- data/spec/factories/ukrdc/modality_codes.rb +1 -1
- data/spec/support/capybara_helper.rb +6 -0
- data/spec/support/letters_spec_helper.rb +2 -2
- data/spec/support/pages/accesses/procedure_page.rb +53 -0
- data/spec/support/pages/accesses/profile_page.rb +45 -0
- data/spec/support/pages/clinical/allergy_page.rb +74 -0
- data/spec/support/pages/letters/form.rb +5 -3
- data/spec/support/shared_contexts/a_global_rule_set.rb +1 -1
- data/spec/support/xml_spec_helper.rb +9 -0
- metadata +60 -11
- data/app/views/renalware/api/ukrdc/patients/_clinical_relationships.xml.builder +0 -7
- data/app/views/renalware/api/ukrdc/patients/_family_histories.xml.builder +0 -7
- data/app/views/renalware/api/ukrdc/patients/_program_memberships.xml.builder +0 -7
- data/app/views/renalware/api/ukrdc/patients/_surveys.xml.builder +0 -7
- data/app/views/renalware/api/ukrdc/patients/observations/_blood_pressure.xml.builder +0 -0
- data/app/views/renalware/api/ukrdc/patients/observations/_standing_blood_pressure.xml.builder +0 -0
- data/app/views/renalware/api/ukrdc/patients/observations/_weight.xml.builder +0 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module UKRDC
|
5
|
+
module Outgoing
|
6
|
+
module Rendering
|
7
|
+
class PatientNumber < Rendering::Base
|
8
|
+
pattr_initialize [:number!, :organisation!, :type!]
|
9
|
+
|
10
|
+
def xml
|
11
|
+
name_element
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def name_element
|
17
|
+
create_node("PatientNumber") do |elem|
|
18
|
+
elem << create_node("Number", number)
|
19
|
+
elem << create_node("Organization", organisation)
|
20
|
+
elem << create_node("NumberType", type)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module UKRDC
|
5
|
+
module Outgoing
|
6
|
+
module Rendering
|
7
|
+
class PatientNumbers < Rendering::Base
|
8
|
+
pattr_initialize [:patient!]
|
9
|
+
|
10
|
+
def xml
|
11
|
+
patient_numbers_element
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def patient_numbers_element
|
17
|
+
create_node("PatientNumbers") do |patient_numbers|
|
18
|
+
patient_numbers << nhs_number_element if patient.nhs_number.present?
|
19
|
+
patient_numbers << hospital_number_element if first_hospital_number.present?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def nhs_number_element
|
24
|
+
Rendering::PatientNumber.new(
|
25
|
+
number: patient.nhs_number,
|
26
|
+
organisation: "NHS",
|
27
|
+
type: "NI"
|
28
|
+
).xml
|
29
|
+
end
|
30
|
+
|
31
|
+
def hospital_number_element
|
32
|
+
Rendering::PatientNumber.new(
|
33
|
+
number: first_hospital_number,
|
34
|
+
organisation: "LOCALHOSP",
|
35
|
+
type: "MRN"
|
36
|
+
).xml
|
37
|
+
end
|
38
|
+
|
39
|
+
def first_hospital_number
|
40
|
+
@first_hospital_number ||= patient.hospital_identifier&.id
|
41
|
+
# @first_hospital_number || begin
|
42
|
+
# Renalware.config.patient_hospital_identifiers.values.each do |field|
|
43
|
+
# next if (number = patient.public_send(field)).blank?
|
44
|
+
|
45
|
+
# return number
|
46
|
+
# end
|
47
|
+
# end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module UKRDC
|
7
|
+
module Outgoing
|
8
|
+
module Rendering
|
9
|
+
# Handles rendering a PD Trweatment (aka modality). We defer to the base Treatment
|
10
|
+
# class but pass in some extra arguments to the ctor.
|
11
|
+
class PDTreatment < Rendering::Treatment
|
12
|
+
def initialize(treatment:)
|
13
|
+
encounter_number = [
|
14
|
+
treatment.modality_id,
|
15
|
+
treatment.pd_regime_id
|
16
|
+
].compact.join("-")
|
17
|
+
|
18
|
+
super(
|
19
|
+
treatment: treatment,
|
20
|
+
encounter_number: encounter_number
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module UKRDC
|
5
|
+
module Outgoing
|
6
|
+
module Rendering
|
7
|
+
class PrimaryLanguage < Rendering::Base
|
8
|
+
pattr_initialize [:patient!]
|
9
|
+
|
10
|
+
def xml
|
11
|
+
return unless render_primary_language?
|
12
|
+
|
13
|
+
primary_langauge_element
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# Omit 'Other' language as it is not part of the ISO set, but we have it for some reason
|
19
|
+
def render_primary_language?
|
20
|
+
patient.language.present? && patient.language.code != "ot"
|
21
|
+
end
|
22
|
+
|
23
|
+
# NB NHS_DATA_DICTIONARY_LANGUAGE_CODE is ISO 639-1 plus braille and sign
|
24
|
+
def primary_langauge_element
|
25
|
+
create_node("PrimaryLanguage") do |lang|
|
26
|
+
lang << create_node("CodingStandard", "NHS_DATA_DICTIONARY_LANGUAGE_CODE")
|
27
|
+
lang << create_node("Code", patient.language&.code)
|
28
|
+
lang << create_node("Description", patient.language)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module UKRDC
|
5
|
+
module Outgoing
|
6
|
+
module Rendering
|
7
|
+
class Procedures < Rendering::Base
|
8
|
+
pattr_initialize [:patient!]
|
9
|
+
|
10
|
+
def xml
|
11
|
+
procedures_element
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def procedures_element
|
17
|
+
create_node("Procedures") do |elem|
|
18
|
+
dialysis_session_elements_inside(elem)
|
19
|
+
transplant_operation_elements_inside(elem)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def dialysis_session_elements_inside(elem)
|
24
|
+
patient.finished_hd_sessions.each do |session|
|
25
|
+
session_presenter = Renalware::HD::SessionPresenter.new(session)
|
26
|
+
elem << Rendering::DialysisSession.new(session: session_presenter).xml
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def transplant_operation_elements_inside(elem)
|
31
|
+
patient.transplant_operations.each do |operation|
|
32
|
+
operation_presenter = Renalware::UKRDC::TransplantOperationPresenter.new(operation)
|
33
|
+
elem << Rendering::Transplant.new(operation: operation_presenter).xml
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module UKRDC
|
5
|
+
module Outgoing
|
6
|
+
module Rendering
|
7
|
+
class RenalDiagnosis < Rendering::Base
|
8
|
+
pattr_initialize [:patient!]
|
9
|
+
|
10
|
+
def xml
|
11
|
+
return if patient.prd_description_code.blank?
|
12
|
+
|
13
|
+
renal_diagnosis_element
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# The nested Diagnosis is correct.
|
19
|
+
def renal_diagnosis_element
|
20
|
+
elem = Rendering::Diagnosis.new(
|
21
|
+
coding_standard: "EDTA2",
|
22
|
+
code: patient.prd_description_code,
|
23
|
+
description: patient.prd_description_term,
|
24
|
+
root_elemment_name: "RenalDiagnosis"
|
25
|
+
)
|
26
|
+
if patient.first_seen_on.present?
|
27
|
+
elem.identification_time = patient.first_seen_on
|
28
|
+
end
|
29
|
+
elem.xml
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module UKRDC
|
5
|
+
module Outgoing
|
6
|
+
module Rendering
|
7
|
+
class Transplant < Rendering::Base
|
8
|
+
pattr_initialize [:operation!]
|
9
|
+
|
10
|
+
def xml
|
11
|
+
transplant_element
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def transplant_element
|
17
|
+
create_node("Transplant") do |elem|
|
18
|
+
elem << procedure_type_element
|
19
|
+
elem << procecure_time_element
|
20
|
+
elem << entered_at_element
|
21
|
+
elem << attributes_element
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def procedure_type_element
|
26
|
+
return if operation.operation_type.blank?
|
27
|
+
|
28
|
+
create_node("ProcedureType") do |elem|
|
29
|
+
elem << create_node("CodingStandard", "SNOMED")
|
30
|
+
elem << create_node("Code", operation.procedure_type_snomed_code.to_i)
|
31
|
+
elem << create_node("Description", operation.procedure_type_name)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def procecure_time_element
|
36
|
+
create_node("ProcedureTime", operation.performed_at&.iso8601)
|
37
|
+
end
|
38
|
+
|
39
|
+
def entered_at_element
|
40
|
+
return if operation.hospital_centre_code.blank?
|
41
|
+
|
42
|
+
create_node("EnteredAt") do |elem|
|
43
|
+
elem << create_node("CodingStandard", "ODS")
|
44
|
+
elem << create_node("Code", operation.hospital_centre_code)
|
45
|
+
elem << create_node("Description", operation.hospital_centre_name)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def attributes_element
|
50
|
+
create_node("Attributes") do |elem|
|
51
|
+
if operation.nhsbt_type.present?
|
52
|
+
elem << create_node("TRA77", operation.nhsbt_type)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Not sending TRA76 yet as defined as datetime in XSD and needs changeing there.
|
58
|
+
# if operation.rr_tra76_options.present?
|
59
|
+
# xml.TRA76 do
|
60
|
+
# xml.CodingStandard "CF_RR7_TREATMENT"
|
61
|
+
# xml.Code operation.rr_tra76_options[:code]
|
62
|
+
# xml.Description operation.rr_tra76_options[:description]
|
63
|
+
# end
|
64
|
+
# end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module UKRDC
|
5
|
+
module Outgoing
|
6
|
+
module Rendering
|
7
|
+
class Treatment < Rendering::Base
|
8
|
+
pattr_initialize [:treatment!, :encounter_number, :attributes]
|
9
|
+
|
10
|
+
def xml
|
11
|
+
treatment_element
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
# rubocop:disable Metrics/AbcSize
|
17
|
+
def treatment_element
|
18
|
+
create_node("Treatment") do |elem|
|
19
|
+
elem << create_node("EncounterNumber", encounter_number || treatment.modality_id)
|
20
|
+
elem << create_node("EncounterType", "N")
|
21
|
+
elem << create_node("FromTime", treatment.started_on&.iso8601)
|
22
|
+
if treatment.ended_on.present?
|
23
|
+
elem << create_node("ToTime", treatment.ended_on&.iso8601)
|
24
|
+
end
|
25
|
+
elem << healthcare_facility_element
|
26
|
+
elem << admin_reason_element
|
27
|
+
elem << discharge_reason_element
|
28
|
+
elem << attributes_element
|
29
|
+
end
|
30
|
+
end
|
31
|
+
# rubocop:enable Metrics/AbcSize
|
32
|
+
|
33
|
+
def healthcare_facility_element
|
34
|
+
create_node("HealthCareFacility") do |elem|
|
35
|
+
elem << create_node("CodingStandard", "ODS")
|
36
|
+
code = treatment.hospital_unit&.renal_registry_code || default_unit_code
|
37
|
+
elem << create_node("Code", code)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def admin_reason_element
|
42
|
+
create_node("AdmitReason") do |elem|
|
43
|
+
elem << create_node("CodingStandard", "CF_RR7_TREATMENT")
|
44
|
+
elem << create_node("Code", treatment.modality_code&.txt_code)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def discharge_reason_element
|
49
|
+
return if treatment&.discharge_reason_code.blank?
|
50
|
+
|
51
|
+
create_node("DischargeReason") do |elem|
|
52
|
+
elem << create_node("CodingStandard", "CF_RR7_DISCHARGE")
|
53
|
+
elem << create_node("Code", treatment.discharge_reason_code)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# Attributes is a hash eg { "QBL05" => "HOME" }
|
58
|
+
def attributes_element
|
59
|
+
return if attributes.blank?
|
60
|
+
return unless attributes.values.detect(&:present?)
|
61
|
+
|
62
|
+
create_node("Attributes") do |elem|
|
63
|
+
attributes.each do |key, value|
|
64
|
+
next if value.blank?
|
65
|
+
|
66
|
+
elem << create_node(key, value)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def default_unit_code
|
72
|
+
Renalware.config.ukrdc_site_code
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module UKRDC
|
5
|
+
module Outgoing
|
6
|
+
module Rendering
|
7
|
+
class User < Rendering::Base
|
8
|
+
pattr_initialize [:user!]
|
9
|
+
|
10
|
+
def xml
|
11
|
+
user_element
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def user_element
|
17
|
+
Ox::Element.new(element_name).tap do |elem|
|
18
|
+
elem << create_node("CodingStandard", "LOCAL")
|
19
|
+
elem << create_node("Code", user&.username)
|
20
|
+
elem << create_node("Description", user&.to_s)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# If a superclass called Clinician inherits from this class then the name of
|
25
|
+
# element output will be <Clinician>
|
26
|
+
def element_name
|
27
|
+
self.class.name.demodulize
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,12 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_dependency "renalware/ukrdc"
|
4
|
+
require "benchmark"
|
4
5
|
|
5
6
|
module Renalware
|
6
7
|
module UKRDC
|
7
8
|
class XmlRenderer
|
8
9
|
DEFAULT_TEMPLATE = "/renalware/api/ukrdc/patients/show"
|
9
|
-
attr_reader :template, :
|
10
|
+
attr_reader :template, :errors, :locals
|
10
11
|
|
11
12
|
class Success < Renalware::Success
|
12
13
|
alias xml object
|
@@ -16,9 +17,11 @@ module Renalware
|
|
16
17
|
alias validation_errors object
|
17
18
|
end
|
18
19
|
|
19
|
-
|
20
|
+
# Schema is an instance of Nokogiri::XML::Schema passed in for optimisation reasons.
|
21
|
+
# If it is not passed in we create it.
|
22
|
+
def initialize(schema: nil, template: nil, locals: {})
|
20
23
|
@template = template || DEFAULT_TEMPLATE
|
21
|
-
@
|
24
|
+
@schema = schema
|
22
25
|
@locals = locals
|
23
26
|
end
|
24
27
|
|
@@ -34,93 +37,69 @@ module Renalware
|
|
34
37
|
|
35
38
|
def xml
|
36
39
|
@xml ||= begin
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
)
|
40
|
+
Ox.default_options = { no_empty: false, encoding: "UTF-8" }
|
41
|
+
doc = Ox::Document.new
|
42
|
+
doc << instruct_element
|
43
|
+
doc << UKRDC::Outgoing::Rendering::Patient.new(locals).xml
|
44
|
+
Ox.dump(doc)
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
46
48
|
# Returns an array of SchemaValidation errors
|
47
49
|
def validation_errors
|
48
|
-
@validation_errors ||=
|
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
|
50
|
+
@validation_errors ||= schema.validate(Nokogiri::XML(xml))
|
54
51
|
end
|
55
52
|
|
56
53
|
private
|
57
54
|
|
58
|
-
def
|
59
|
-
|
55
|
+
def instruct_element
|
56
|
+
Ox::Instruct.new(:xml).tap do |instruct|
|
57
|
+
instruct[:version] = "1.0"
|
58
|
+
instruct[:encoding] = "UTF-8"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# It is more performant if schema is passed in in the ctor - but if it isn't we create it.
|
63
|
+
def schema
|
64
|
+
@schema ||= begin
|
65
|
+
Rails.logger.warn "Creating JIT Nokogiri::XML::Schema!"
|
66
|
+
xsd_path = File.join(Renalware::Engine.root, "vendor/xsd/ukrdc/Schema/UKRDC.xsd")
|
67
|
+
xsddoc = Nokogiri::XML(File.read(xsd_path), xsd_path)
|
68
|
+
Nokogiri::XML::Schema.from_document(xsddoc)
|
69
|
+
end
|
60
70
|
end
|
61
71
|
end
|
62
72
|
end
|
63
73
|
end
|
64
74
|
|
75
|
+
# rubocop:disable Layout/LineLength
|
76
|
+
# For reference this is the code used to compare old and new methods of exporting the XML
|
77
|
+
# in the #call method:
|
65
78
|
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
79
|
+
# modified_old_xml = xml_old.gsub("<FamilyDoctor>\n </FamilyDoctor>", "<FamilyDoctor/>")
|
80
|
+
# modified_old_xml = modified_old_xml.gsub("<Diagnoses>\n </Diagnoses>", "<Diagnoses/>")
|
81
|
+
# modified_old_xml = modified_old_xml.gsub("<Encounters>\n </Encounters>", "<Encounters/>")
|
82
|
+
# modified_old_xml = modified_old_xml.gsub("<Medications>\n </Medications>", "<Medications/>")
|
83
|
+
# modified_old_xml = modified_old_xml.gsub("<Procedures>\n </Procedures>", "<Procedures/>")
|
84
|
+
# modified_old_xml = modified_old_xml.gsub("<Attributes>\n </Attributes>", "<Attributes/>")
|
85
|
+
# modified_old_xml = modified_old_xml.gsub("<ResultValue></ResultValue>", "<ResultValue/>")
|
86
|
+
# modified_old_xml = modified_old_xml.gsub("<LabOrders start=\"2017-01-01\" stop=\"2019-12-29\">\n </LabOrders>", "<LabOrders/>")
|
87
|
+
# modified_old_xml = modified_old_xml.gsub("<Observations start=\"2017-01-01\" stop=\"2019-12-29\">\n </Observations>", "<Observations start=\"2017-01-01\" stop=\"2019-12-29\"/>")
|
88
|
+
# modified_old_xml = modified_old_xml.gsub("<LabOrders/>", "<LabOrders start=\"2017-01-01\" stop=\"2019-12-29\"/>")
|
89
|
+
|
90
|
+
# if modified_old_xml != xml
|
91
|
+
# File.open(Rails.root.join("tmp", "#{locals[:patient].id}_old.txt"), "wb") { |f| f.write modified_old_xml }
|
92
|
+
# File.open(Rails.root.join("tmp", "#{locals[:patient].id}_new.txt"), "wb") { |f| f.write xml }
|
73
93
|
# end
|
74
|
-
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
|
79
|
-
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
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
|
94
|
+
#
|
95
|
+
# def xml_old
|
96
|
+
# @xml_old ||= begin
|
97
|
+
# API::UKRDC::PatientsController.new.render_to_string(
|
98
|
+
# template: template,
|
99
|
+
# format: :xml,
|
100
|
+
# locals: locals,
|
101
|
+
# encoding: "UTF-8"
|
102
|
+
# )
|
121
103
|
# end
|
122
104
|
# end
|
123
|
-
|
124
|
-
# # Render XML
|
125
|
-
# respond_with rdc_patient, camelize: true
|
126
|
-
#
|
105
|
+
# rubocop:enable Layout/LineLength
|