renalware-core 2.0.79 → 2.0.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/models/renalware/ukrdc/treatment.rb +17 -0
- data/app/models/renalware/ukrdc/treatment_timeline/generate_timeline.rb +35 -0
- data/app/models/renalware/ukrdc/treatment_timeline/generate_treatments.rb +45 -0
- data/app/models/renalware/ukrdc/treatment_timeline/generator_factory.rb +33 -0
- data/app/models/renalware/ukrdc/treatment_timeline/generators/deaths_timeline.rb +17 -0
- data/app/models/renalware/ukrdc/treatment_timeline/generators/generic_timeline.rb +17 -0
- data/app/models/renalware/ukrdc/treatment_timeline/generators/hd_timeline.rb +145 -0
- data/app/models/renalware/ukrdc/treatment_timeline/generators/low_clearance_timelinex.rb +17 -0
- data/app/models/renalware/ukrdc/treatment_timeline/generators/pd_timeline.rb +18 -0
- data/app/models/renalware/ukrdc/treatment_timeline/generators/transplants_donor_timeline.rb +17 -0
- data/app/models/renalware/ukrdc/treatment_timeline/generators/transplants_recipient_timeline.rb +17 -0
- data/app/models/renalware/ukrdc/treatment_timeline/prepare_tables.rb +28 -0
- data/app/models/renalware/ukrdc/treatment_timeline/remap_model_table_names_to_their_prepared_equivalents.rb +70 -0
- data/app/presenters/renalware/ukrdc/patient_presenter.rb +4 -1
- data/app/views/renalware/api/ukrdc/patients/_diagnoses.xml.builder +9 -9
- data/app/views/renalware/api/ukrdc/patients/_encounters.xml.builder +1 -6
- data/app/views/renalware/api/ukrdc/patients/_treatments.xml.builder +28 -0
- data/app/views/renalware/api/ukrdc/patients/procedures/_dialysis_session.xml.builder +0 -1
- data/app/views/renalware/api/ukrdc/patients/show.xml.builder +1 -1
- data/db/migrate/20190520091324_create_ukrdc_treatments.rb +18 -0
- data/db/migrate/20190607134717_add_ukrdc_modality_code_id_to_modality_descriptions.rb +22 -0
- data/lib/renalware/version.rb +1 -1
- data/lib/tasks/ukrdc.rake +8 -0
- data/spec/factories/ukrdc/modality_codes.rb +17 -0
- data/spec/support/patients_spec_helper.rb +5 -1
- metadata +19 -4
- data/app/views/renalware/api/ukrdc/patients/encounters/_hd_session.xml.builder +0 -38
- data/app/views/renalware/api/ukrdc/patients/encounters/_treatment.xml.builder +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3aa90a846be2948db0c68e68384a6199d8fc84504fbdbd8eaf890a587d3242d
|
4
|
+
data.tar.gz: 0730cc42cf7371c20d3c3589bf3b1e66078fd263ecce33e61bf03ebf25e69bd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: edd227674f0d89c5d865b0f6a4ccc9fc7e1827e30809b11cb740838e93c6ba9e02746d756059b7a56b4161e2d7366dc11d210c83f679ead2a9f90d4bff4986d6
|
7
|
+
data.tar.gz: 64fc99a1982ec5674374e5d84dbe366757cc18fc0fd0db442d2b0a998b2d6b522fd2227efdb5825e1f9709698b2165c40750b4f28c7373171eec4928526d1519
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ Rails application, and configure it to include the Renalware engine. The host ap
|
|
15
15
|
extremely thin, adding no custom features other than site-specific configuration, or it may include
|
16
16
|
Ruby, HTML and JavaScript to override or augment renalware-core's features.
|
17
17
|
|
18
|
-
While the engine is
|
18
|
+
While the engine is intended to be deployed inside a host application in production, it can be run
|
19
19
|
stand-alone in a local development environment (or indeed deployed in a limited way to somewhere like Heroku) by employing
|
20
20
|
the _dummy_ host application that ships inside the engine. This dummy app (in `./spec/dummy`)
|
21
21
|
allows a developer to quickly mount the engine, and is used also used Rails integration tests (which is why
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module UKRDC
|
7
|
+
class Treatment < ApplicationRecord
|
8
|
+
belongs_to :patient
|
9
|
+
belongs_to :clinician, class_name: "Renalware::User"
|
10
|
+
belongs_to :modality_code
|
11
|
+
validates :patient, presence: true
|
12
|
+
validates :modality_code, presence: true
|
13
|
+
|
14
|
+
scope :ordered, -> { order(started_on: :asc, ended_on: :asc) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
require "attr_extras"
|
5
|
+
|
6
|
+
# rubocop:disable Rails/Output
|
7
|
+
module Renalware
|
8
|
+
module UKRDC
|
9
|
+
module TreatmentTimeline
|
10
|
+
#
|
11
|
+
# Re-generates the ukrdc_treatments for a patient from their modalities and other information.
|
12
|
+
#
|
13
|
+
class GenerateTimeline
|
14
|
+
pattr_initialize :patient
|
15
|
+
|
16
|
+
def call
|
17
|
+
PrepareTables.call
|
18
|
+
RemapModelTableNamesToTheirPreparedEquivalents.call
|
19
|
+
|
20
|
+
modalities.each do |modality|
|
21
|
+
print "#{modality.description.name} "
|
22
|
+
GeneratorFactory.call(modality).call
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def modalities
|
29
|
+
patient.modalities.order(started_on: :asc, updated_at: :asc)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
# rubocop:enable Rails/Output
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
require "attr_extras"
|
5
|
+
require "benchmark"
|
6
|
+
|
7
|
+
module Renalware
|
8
|
+
module UKRDC
|
9
|
+
module TreatmentTimeline
|
10
|
+
# Re-generates the ukrdc_treatments table
|
11
|
+
class GenerateTreatments
|
12
|
+
def self.call
|
13
|
+
new.call
|
14
|
+
end
|
15
|
+
|
16
|
+
def call
|
17
|
+
elapsed_ms = Benchmark.ms do
|
18
|
+
generate_treatments
|
19
|
+
end
|
20
|
+
log("\nCreated #{UKRDC::Treatment.count} UKRDC Treatments in #{elapsed_ms / 1000.0}s")
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def patient_scope
|
26
|
+
Renalware::Patient.select(:id)
|
27
|
+
end
|
28
|
+
|
29
|
+
# rubocop:disable Rails/Output
|
30
|
+
def generate_treatments
|
31
|
+
Rails.logger.info "#{patient_scope.count} patients"
|
32
|
+
patient_scope.find_each do |patient|
|
33
|
+
print "\n#{patient.id}: "
|
34
|
+
GenerateTimeline.new(patient).call
|
35
|
+
end
|
36
|
+
end
|
37
|
+
# rubocop:enable Rails/Output
|
38
|
+
|
39
|
+
def log(msg)
|
40
|
+
Rails.logger.info(msg)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
require "attr_extras"
|
5
|
+
require "benchmark"
|
6
|
+
|
7
|
+
module Renalware
|
8
|
+
module UKRDC
|
9
|
+
module TreatmentTimeline
|
10
|
+
class GeneratorFactory
|
11
|
+
DEFAULT_TYPE = "Generic"
|
12
|
+
|
13
|
+
# Returns the class of object to suitable for generating the treatment timeline for the
|
14
|
+
# requested modality. If the modality description type is nil then we use a generic
|
15
|
+
# generator. If no generator class is defined matching the description.type, we also
|
16
|
+
# return nil.
|
17
|
+
# Example:
|
18
|
+
# given the modality_description.type of Renalware::Bla::BlaModalityDescription
|
19
|
+
# we will look to see if the constant GenerateBlaBlaTimeline exists and return an instance
|
20
|
+
# if so - otherwise we return an instance of the default generator GenerateGenericTimeline.
|
21
|
+
def self.call(modality)
|
22
|
+
type = modality.description.type.presence || DEFAULT_TYPE
|
23
|
+
type = type.gsub("::", "").gsub(/^Renalware/, "").gsub(/ModalityDescription$/, "")
|
24
|
+
(klass_for(type) || klass_for(DEFAULT_TYPE)).new(modality)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.klass_for(type)
|
28
|
+
"Renalware::UKRDC::TreatmentTimeline::Generators::#{type}Timeline".safe_constantize
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module UKRDC
|
7
|
+
module TreatmentTimeline
|
8
|
+
module Generators
|
9
|
+
class DeathsTimeline
|
10
|
+
pattr_initialize :modality
|
11
|
+
|
12
|
+
def call; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module UKRDC
|
7
|
+
module TreatmentTimeline
|
8
|
+
module Generators
|
9
|
+
class GenericTimeline
|
10
|
+
pattr_initialize :modality
|
11
|
+
|
12
|
+
def call; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
|
5
|
+
# rubocop:disable Rails/Output
|
6
|
+
module Renalware
|
7
|
+
module UKRDC
|
8
|
+
module TreatmentTimeline
|
9
|
+
module Generators
|
10
|
+
class HDTimeline
|
11
|
+
pattr_initialize :modality
|
12
|
+
delegate :patient, to: :modality
|
13
|
+
|
14
|
+
def call
|
15
|
+
create_treatment_from_modality
|
16
|
+
create_treatments_within_modality
|
17
|
+
deduplicate
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def create_treatment_from_modality
|
23
|
+
print "[#{treatment.txt_code}] "
|
24
|
+
treatments << Treatment.create!(
|
25
|
+
patient: patient,
|
26
|
+
clinician: modality.created_by,
|
27
|
+
started_on: modality.started_on,
|
28
|
+
ended_on: modality.ended_on,
|
29
|
+
modality_code: treatment
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
class ProfileDecorator < DumbDelegator
|
34
|
+
def initialize(profile, last_profile:)
|
35
|
+
@last_profile = last_profile
|
36
|
+
super(profile)
|
37
|
+
end
|
38
|
+
|
39
|
+
def hd_type
|
40
|
+
document.dialysis.hd_type
|
41
|
+
end
|
42
|
+
|
43
|
+
def changed?
|
44
|
+
return true if last_profile.blank?
|
45
|
+
|
46
|
+
hd_type_changed? || hospital_unit_changed?
|
47
|
+
end
|
48
|
+
|
49
|
+
def unchanged?
|
50
|
+
!changed?
|
51
|
+
end
|
52
|
+
|
53
|
+
def hd_type_changed?
|
54
|
+
last_profile.document.dialysis.hd_type != hd_type
|
55
|
+
end
|
56
|
+
|
57
|
+
def hospital_unit_changed?
|
58
|
+
last_profile.hospital_unit_id != hospital_unit_id
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
attr_reader :last_profile
|
64
|
+
end
|
65
|
+
|
66
|
+
# 3 things trigger a new Treatment for an HD patient
|
67
|
+
# - change of site
|
68
|
+
# - change of hd_type to from hd and (hdf_pre || hdf_post)
|
69
|
+
# - change of hd prescription
|
70
|
+
# Looop through the hd_profiles and trigger an new treatment when these change
|
71
|
+
def create_treatments_within_modality
|
72
|
+
profiles = hd_profiles_for(patient, from: modality.started_on, to: modality.ended_on)
|
73
|
+
last_profile = NullObject.instance
|
74
|
+
|
75
|
+
profiles.each do |profile_|
|
76
|
+
profile = ProfileDecorator.new(profile_, last_profile: last_profile)
|
77
|
+
create_treatment_from(profile) if profile.changed?
|
78
|
+
last_profile = profile_
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# - if modality started on same day as hd profile prescribed then use HD Profile hd_type
|
83
|
+
# if present else hd
|
84
|
+
# - if modality started before hd_profile setup and hd_profile is hdf, we'll have
|
85
|
+
# 2 treatments: hd then hdf
|
86
|
+
# - if hosp unit changes within the modality timeframe, trigger a new treatment
|
87
|
+
# - if medications change? new treatment? Check with GS
|
88
|
+
def deduplicate
|
89
|
+
# p treatments.map(&:id)
|
90
|
+
end
|
91
|
+
|
92
|
+
# rubocop:disable Metrics/AbcSize
|
93
|
+
def create_treatment_from(profile)
|
94
|
+
code = treatment_for_hd_type(profile.hd_type)
|
95
|
+
print "[#{code.txt_code}] "
|
96
|
+
treatments << Treatment.create!(
|
97
|
+
patient: patient,
|
98
|
+
clinician: modality.created_by,
|
99
|
+
started_on: modality.started_on,
|
100
|
+
ended_on: modality.ended_on,
|
101
|
+
modality_code: treatment_for_hd_type(profile.hd_type)
|
102
|
+
)
|
103
|
+
end
|
104
|
+
# rubocop:enable Metrics/AbcSize
|
105
|
+
|
106
|
+
def treatments
|
107
|
+
@treatments ||= []
|
108
|
+
end
|
109
|
+
|
110
|
+
def treatment_for_hd_type(hd_type)
|
111
|
+
ukrr_name = case hd_type.to_s.downcase
|
112
|
+
when "hd" then "Haemodialysis"
|
113
|
+
when "hdf_pre", "hdf_post" then "Haemodiafiltration"
|
114
|
+
end
|
115
|
+
UKRDC::ModalityCode.find_by!(description: ukrr_name)
|
116
|
+
end
|
117
|
+
|
118
|
+
def hd_profiles_for(patient, from:, to: Time.zone.now)
|
119
|
+
conditions = {
|
120
|
+
patient_id: patient.id,
|
121
|
+
prescribed_on: from..DateTime::Infinity.new
|
122
|
+
}
|
123
|
+
|
124
|
+
scope = Renalware::HD::Profile
|
125
|
+
.with_deactivated
|
126
|
+
.order(prescribed_on: :asc, deactivated_at: :desc)
|
127
|
+
|
128
|
+
scope
|
129
|
+
.where(conditions.merge(deactivated_at: from..to))
|
130
|
+
.or(scope.where(conditions.merge(deactivated_at: nil)))
|
131
|
+
end
|
132
|
+
|
133
|
+
def hd_patient
|
134
|
+
Renalware::HD.cast_patient(patient)
|
135
|
+
end
|
136
|
+
|
137
|
+
def treatment
|
138
|
+
ModalityCode.find_by!(description: "Haemodialysis")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
# rubocop:enable Rails/Output
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module UKRDC
|
7
|
+
module TreatmentTimelinex
|
8
|
+
module Generators
|
9
|
+
class LowClearanceTimeline
|
10
|
+
pattr_initialize :modality
|
11
|
+
|
12
|
+
def call; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module UKRDC
|
7
|
+
module TreatmentTimeline
|
8
|
+
module Generators
|
9
|
+
class PDTimeline
|
10
|
+
pattr_initialize :modality
|
11
|
+
delegate :patient, to: :modality
|
12
|
+
|
13
|
+
def call; end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module UKRDC
|
7
|
+
module TreatmentTimeline
|
8
|
+
module Generators
|
9
|
+
class TransplantsDonorTimeline
|
10
|
+
pattr_initialize :modality
|
11
|
+
|
12
|
+
def call; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/app/models/renalware/ukrdc/treatment_timeline/generators/transplants_recipient_timeline.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/ukrdc"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module UKRDC
|
7
|
+
module TreatmentTimeline
|
8
|
+
module Generators
|
9
|
+
class TransplantsRecipientTimeline
|
10
|
+
pattr_initialize :modality
|
11
|
+
|
12
|
+
def call; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module UKRDC
|
5
|
+
module TreatmentTimeline
|
6
|
+
# If the host site has defined a SQL function called ukrdc_prepare_tables() in any schema in
|
7
|
+
# the current SEARCH_PATH, then we call it here. It will (we hope) generate massaged copies of
|
8
|
+
# tables needed to later generate e.g. UKRDC treatments - for example at KCH the hd_profiles
|
9
|
+
# table is massaged to correct migration artefacts and issues prior to the generation of the
|
10
|
+
# UKRDC Treatment Timeline. Elsewhere we detect the presence of these prepared
|
11
|
+
# tables (eg ukrdc_prepared_hd_profiles) and use them as the underlying table behind, in this
|
12
|
+
# example, Renalware::HD::Profile, by setting class.table_name = 'ukrdc_prepared_hd_profiles'.
|
13
|
+
# If the site has not defined the ukrdc_prepare_tables SQL function then we exit gracefully.
|
14
|
+
class PrepareTables
|
15
|
+
def self.call
|
16
|
+
connection = ActiveRecord::Base.connection
|
17
|
+
result = connection.execute(<<-SQL)
|
18
|
+
select 1 where exists(select 1 from pg_proc where proname = 'ukrdc_prepare_tables');
|
19
|
+
SQL
|
20
|
+
if result.ntuples == 1
|
21
|
+
connection.execute("select ukrdc_prepare_tables();")
|
22
|
+
return true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# For use only in rake task! See comments below
|
4
|
+
module Renalware
|
5
|
+
module UKRDC
|
6
|
+
module TreatmentTimeline
|
7
|
+
# Wehen generating the tratment timeline, sites may want to pre-prepare a massaged version
|
8
|
+
# of say hd_profiles, in order to correct any anomalies. This service object
|
9
|
+
# will remap the table_name of the supplied (or default models) to the
|
10
|
+
# 'ukrdc_prepared_*' version if it exists. Otrherwise it will not change the table name.
|
11
|
+
# Note that this can only be done when executing as a rake task (which has its own process)
|
12
|
+
# as I beleive changing the table_name will affect all threads in the same process - so doing
|
13
|
+
# this in a puma process would mean users start to see only the contents of the
|
14
|
+
# ukrdc_prepared_tables. Not good :0.
|
15
|
+
class RemapModelTableNamesToTheirPreparedEquivalents
|
16
|
+
ALLOWED_PROCESSES = %w(rake rspec).freeze
|
17
|
+
MODELS = [
|
18
|
+
Renalware::HD::Profile
|
19
|
+
].freeze
|
20
|
+
class ExecutionNotAllowedError < StandardError; end
|
21
|
+
|
22
|
+
def self.call(models = MODELS)
|
23
|
+
new.call(models)
|
24
|
+
end
|
25
|
+
|
26
|
+
def call(models)
|
27
|
+
fail_unless_running_in_rake_or_rspec
|
28
|
+
Array(models).each do |model_class|
|
29
|
+
prepared_table_name = prepared_table_name_for(model_class.table_name)
|
30
|
+
model_class.table_name = prepared_table_name if table_exists?(prepared_table_name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def fail_unless_running_in_rake_or_rspec
|
37
|
+
unless ALLOWED_PROCESSES.include?(File.basename($PROGRAM_NAME))
|
38
|
+
raise(
|
39
|
+
ExecutionNotAllowedError,
|
40
|
+
"Can only be called from #{ALLOWED_PROCESSES.join(', ')}"
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def prepared_table_name_for(table_name)
|
46
|
+
"ukrdc_prepared_#{table_name}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def table_exists?(table_name)
|
50
|
+
result = connection.execute(<<-SQL)
|
51
|
+
SELECT 1
|
52
|
+
WHERE EXISTS (
|
53
|
+
SELECT 1 FROM information_schema.tables WHERE table_name = '#{table_name}')
|
54
|
+
SQL
|
55
|
+
result.ntuples == 1
|
56
|
+
end
|
57
|
+
|
58
|
+
def connection
|
59
|
+
ActiveRecord::Base.connection
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module X
|
64
|
+
def table_name
|
65
|
+
"ukrdc_prepared_#{super}"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -96,7 +96,10 @@ module Renalware
|
|
96
96
|
|
97
97
|
# We always send the patients current prescriptions.
|
98
98
|
def prescriptions
|
99
|
-
__getobj__
|
99
|
+
__getobj__
|
100
|
+
.prescriptions
|
101
|
+
.includes(:termination, :medication_route, :drug)
|
102
|
+
.order(:prescribed_on)
|
100
103
|
end
|
101
104
|
|
102
105
|
def observation_requests
|
@@ -3,15 +3,6 @@
|
|
3
3
|
# https://github.com/renalreg/ukrdc/blob/6d95e364dd8de857839fe6cdbd4e7fc3fb4c1d42/Schema/Diagnoses/Diagnosis.xsd
|
4
4
|
xml = builder
|
5
5
|
xml.Diagnoses do
|
6
|
-
if patient.dead? && patient.first_cause.present?
|
7
|
-
# Only 1 CauseOfDeath element is allowed so we ignore patient.second_cause
|
8
|
-
render(
|
9
|
-
"renalware/api/ukrdc/patients/diagnoses/cause_of_death",
|
10
|
-
builder: xml,
|
11
|
-
cause: patient.first_cause
|
12
|
-
)
|
13
|
-
end
|
14
|
-
|
15
6
|
patient.yes_comorbidities.each do |comorb|
|
16
7
|
xml.Diagnosis do
|
17
8
|
xml.Diagnosis do
|
@@ -44,6 +35,15 @@ xml.Diagnoses do
|
|
44
35
|
end
|
45
36
|
end
|
46
37
|
|
38
|
+
if patient.dead? && patient.first_cause.present?
|
39
|
+
# Only 1 CauseOfDeath element is allowed so we ignore patient.second_cause
|
40
|
+
render(
|
41
|
+
"renalware/api/ukrdc/patients/diagnoses/cause_of_death",
|
42
|
+
builder: xml,
|
43
|
+
cause: patient.first_cause
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
47
|
if patient.prd_description_code.present?
|
48
48
|
xml.RenalDiagnosis do
|
49
49
|
xml.Diagnosis do
|
@@ -3,10 +3,5 @@
|
|
3
3
|
xml = builder
|
4
4
|
|
5
5
|
xml.Encounters do
|
6
|
-
patient
|
7
|
-
render "renalware/api/ukrdc/patients/encounters/treatment",
|
8
|
-
builder: xml,
|
9
|
-
patient: patient,
|
10
|
-
session: Renalware::HD::SessionPresenter.new(session)
|
11
|
-
end
|
6
|
+
render "treatments", builder: xml, patient: patient
|
12
7
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
xml = builder
|
4
|
+
|
5
|
+
# A temporary output ot the treatment timeline using just this modality descriptions with a
|
6
|
+
# crude renal reg modality code assigned to them - HD PD Transplant vCKD - all other modalities
|
7
|
+
# fall through the gaps at this stage until we implement this properly. Also sub RR modal codes
|
8
|
+
# like CAPD and HDF are not yet implemented, just the top level modality.
|
9
|
+
patient.modalities.each do |modality|
|
10
|
+
next if modality.description.ukrdc_modality_code_id.blank?
|
11
|
+
|
12
|
+
xml.Treatment do
|
13
|
+
xml.EncounterNumber modality.id
|
14
|
+
xml.EncounterType "N"
|
15
|
+
xml.FromTime modality.started_on.to_time&.iso8601
|
16
|
+
xml.ToTime modality.ended_on.to_time&.iso8601
|
17
|
+
|
18
|
+
xml.HealthCareFacility do
|
19
|
+
xml.CodingStandard "ODS"
|
20
|
+
xml.Code Renalware.config.ukrdc_site_code
|
21
|
+
end
|
22
|
+
|
23
|
+
xml.AdmitReason do
|
24
|
+
xml.CodingStandard "CF_RR7_TREATMENT"
|
25
|
+
xml.Code Renalware::UKRDC::ModalityCode.find(modality.description.ukrdc_modality_code_id).txt_code
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -23,7 +23,7 @@ xml.ukrdc(:PatientRecord, namespace_and_schema) do
|
|
23
23
|
render "medications", builder: xml, patient: patient
|
24
24
|
render "procedures", builder: xml, patient: patient
|
25
25
|
render "documents", builder: xml, patient: patient
|
26
|
-
|
26
|
+
render "encounters", builder: xml, patient: patient
|
27
27
|
render "program_memberships", builder: xml, patient: patient
|
28
28
|
render "clinical_relationships", builder: xml, patient: patient
|
29
29
|
render "surveys", builder: xml, patient: patient
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateUKRDCTreatments < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
within_renalware_schema do
|
4
|
+
create_table :ukrdc_treatments do |t|
|
5
|
+
t.references :patient, foreign_key: true, index: true, null: false
|
6
|
+
t.references :clinician, foreign_key: { to_table: :users }, index: true, null: true
|
7
|
+
t.references :modality_code, foreign_key: { to_table: :ukrdc_modality_codes }, index: true, null: false
|
8
|
+
t.references :modality, index: true, null: true
|
9
|
+
t.references :modality_description, index: true, null: true, foreign_key: true
|
10
|
+
t.references :hospital_centre, null: true, foreign_key: true, index: true
|
11
|
+
t.references :hospital_unit, null: true, foreign_key: true, index: true
|
12
|
+
t.date :started_on, null: false
|
13
|
+
t.date :ended_on
|
14
|
+
t.timestamps null: false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class AddUKRDCModalityCodeIdToModalityDescriptions < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
# add_column :modality_descriptions, :ukrdc_modality_code_id, :integer
|
4
|
+
add_reference :modality_descriptions,
|
5
|
+
:ukrdc_modality_code,
|
6
|
+
foreign_key: true
|
7
|
+
|
8
|
+
reversible do |direction|
|
9
|
+
direction.up do
|
10
|
+
connection.execute(<<-SQL.squish)
|
11
|
+
update renalware.modality_descriptions set ukrdc_modality_code_id = (select id from renalware.ukrdc_modality_codes where qbl_code = '19') where name = 'PD';
|
12
|
+
update renalware.modality_descriptions set ukrdc_modality_code_id = (select id from renalware.ukrdc_modality_codes where qbl_code = '1') where name = 'HD';
|
13
|
+
update renalware.modality_descriptions set ukrdc_modality_code_id = (select id from renalware.ukrdc_modality_codes where qbl_code = '29') where name = 'Transplant';
|
14
|
+
update renalware.modality_descriptions set ukrdc_modality_code_id = (select id from renalware.ukrdc_modality_codes where qbl_code = '900') where name = 'vCKD';
|
15
|
+
SQL
|
16
|
+
end
|
17
|
+
direction.down do
|
18
|
+
# noop
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/renalware/version.rb
CHANGED
data/lib/tasks/ukrdc.rake
CHANGED
@@ -41,4 +41,12 @@ namespace :ukrdc do
|
|
41
41
|
patient_ids: args.fetch(:patient_ids, "").split(" ").map(&:to_i)
|
42
42
|
).call
|
43
43
|
end
|
44
|
+
|
45
|
+
desc "Regenerates the ukrdc_treatments table ready for exporting to UKRDC in another task"
|
46
|
+
task generate_treatments: :environment do
|
47
|
+
logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT))
|
48
|
+
logger.level = Logger::INFO
|
49
|
+
Rails.logger = logger
|
50
|
+
Renalware::UKRDC::TreatmentTimeline::GenerateTreatments.call
|
51
|
+
end
|
44
52
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
FactoryBot.define do
|
4
|
+
factory :ukrdc_modality_code, class: Renalware::UKRDC::ModalityCode do
|
5
|
+
trait :hd do
|
6
|
+
description { "Haemodialysis" }
|
7
|
+
txt_code { 1 }
|
8
|
+
qbl_code { 1 }
|
9
|
+
end
|
10
|
+
|
11
|
+
trait :hdf do
|
12
|
+
description { "Haemodiafiltration" }
|
13
|
+
txt_code { 3 }
|
14
|
+
qbl_code { 3 }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -6,7 +6,8 @@ module PatientsSpecHelper
|
|
6
6
|
started_on: Time.zone.today,
|
7
7
|
by: Renalware::User.first)
|
8
8
|
|
9
|
-
|
9
|
+
# ChangePatientModality returns a Success or Failure object
|
10
|
+
new_modality = Renalware::Modalities::ChangePatientModality
|
10
11
|
.new(patient: patient, user: by)
|
11
12
|
.call(
|
12
13
|
description: modality_description,
|
@@ -14,5 +15,8 @@ module PatientsSpecHelper
|
|
14
15
|
)
|
15
16
|
|
16
17
|
patient.reload # need to do this in order for current_modality to be set
|
18
|
+
|
19
|
+
# Return ther object associated with the returned Success or Failure object
|
20
|
+
new_modality.object
|
17
21
|
end
|
18
22
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: renalware-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.80
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Airslie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_type
|
@@ -1825,6 +1825,19 @@ files:
|
|
1825
1825
|
- app/models/renalware/ukrdc/paths.rb
|
1826
1826
|
- app/models/renalware/ukrdc/patients_query.rb
|
1827
1827
|
- app/models/renalware/ukrdc/transmission_log.rb
|
1828
|
+
- app/models/renalware/ukrdc/treatment.rb
|
1829
|
+
- app/models/renalware/ukrdc/treatment_timeline/generate_timeline.rb
|
1830
|
+
- app/models/renalware/ukrdc/treatment_timeline/generate_treatments.rb
|
1831
|
+
- app/models/renalware/ukrdc/treatment_timeline/generator_factory.rb
|
1832
|
+
- app/models/renalware/ukrdc/treatment_timeline/generators/deaths_timeline.rb
|
1833
|
+
- app/models/renalware/ukrdc/treatment_timeline/generators/generic_timeline.rb
|
1834
|
+
- app/models/renalware/ukrdc/treatment_timeline/generators/hd_timeline.rb
|
1835
|
+
- app/models/renalware/ukrdc/treatment_timeline/generators/low_clearance_timelinex.rb
|
1836
|
+
- app/models/renalware/ukrdc/treatment_timeline/generators/pd_timeline.rb
|
1837
|
+
- app/models/renalware/ukrdc/treatment_timeline/generators/transplants_donor_timeline.rb
|
1838
|
+
- app/models/renalware/ukrdc/treatment_timeline/generators/transplants_recipient_timeline.rb
|
1839
|
+
- app/models/renalware/ukrdc/treatment_timeline/prepare_tables.rb
|
1840
|
+
- app/models/renalware/ukrdc/treatment_timeline/remap_model_table_names_to_their_prepared_equivalents.rb
|
1828
1841
|
- app/models/renalware/ukrdc/xml_renderer.rb
|
1829
1842
|
- app/models/renalware/user.rb
|
1830
1843
|
- app/models/renalware/version.rb
|
@@ -2118,9 +2131,8 @@ files:
|
|
2118
2131
|
- app/views/renalware/api/ukrdc/patients/_sending_facility.xml.builder
|
2119
2132
|
- app/views/renalware/api/ukrdc/patients/_social_histories.xml.builder
|
2120
2133
|
- app/views/renalware/api/ukrdc/patients/_surveys.xml.builder
|
2134
|
+
- app/views/renalware/api/ukrdc/patients/_treatments.xml.builder
|
2121
2135
|
- app/views/renalware/api/ukrdc/patients/diagnoses/_cause_of_death.xml.builder
|
2122
|
-
- app/views/renalware/api/ukrdc/patients/encounters/_hd_session.xml.builder
|
2123
|
-
- app/views/renalware/api/ukrdc/patients/encounters/_treatment.xml.builder
|
2124
2136
|
- app/views/renalware/api/ukrdc/patients/lab_orders/_lab_order.xml.builder
|
2125
2137
|
- app/views/renalware/api/ukrdc/patients/lab_orders/_result_item.xml.builder
|
2126
2138
|
- app/views/renalware/api/ukrdc/patients/observations/_blood_pressure.xml.builder
|
@@ -3472,12 +3484,14 @@ files:
|
|
3472
3484
|
- db/migrate/20190513131826_add_view_count_to_system_help.rb
|
3473
3485
|
- db/migrate/20190513135312_create_pathology_code_groups.rb
|
3474
3486
|
- db/migrate/20190516093707_add_graft_nephectomy_on_to_tx_op_followup.rb
|
3487
|
+
- db/migrate/20190520091324_create_ukrdc_treatments.rb
|
3475
3488
|
- db/migrate/20190531172829_add_last_change_date_to_patient_practices.rb
|
3476
3489
|
- db/migrate/20190602114659_create_system_api_logs.rb
|
3477
3490
|
- db/migrate/20190603084428_add_pages_to_system_api_logs.rb
|
3478
3491
|
- db/migrate/20190603135247_add_columns_to_patient_primary_care_physicians.rb
|
3479
3492
|
- db/migrate/20190603143834_update_import_practice_memberships_csv.rb
|
3480
3493
|
- db/migrate/20190603165812_drop_import_practices_csv_function.rb
|
3494
|
+
- db/migrate/20190607134717_add_ukrdc_modality_code_id_to_modality_descriptions.rb
|
3481
3495
|
- db/seeds.rb
|
3482
3496
|
- db/seeds/default/accesses/access_pd_catheter_insertion_techniques.csv
|
3483
3497
|
- db/seeds/default/accesses/access_pd_catheter_insertion_techniques.rb
|
@@ -3804,6 +3818,7 @@ files:
|
|
3804
3818
|
- spec/factories/transplants/registration_status_descriptions.rb
|
3805
3819
|
- spec/factories/transplants/registration_statuses.rb
|
3806
3820
|
- spec/factories/transplants/registrations.rb
|
3821
|
+
- spec/factories/ukrdc/modality_codes.rb
|
3807
3822
|
- spec/factories/virology/patients.rb
|
3808
3823
|
- spec/factories/virology/vaccinations.rb
|
3809
3824
|
- spec/support/capybara_helper.rb
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# xml = builder
|
4
|
-
|
5
|
-
# xml.Treatment do
|
6
|
-
# xml.EncounterNumber session.uuid
|
7
|
-
# xml.comment! "TODO: EncounterType TBC"
|
8
|
-
# xml.EncounterType "R"
|
9
|
-
# xml.FromTime session.start_datetime&.to_datetime
|
10
|
-
# xml.ToTime session.stop_datetime&.to_datetime
|
11
|
-
|
12
|
-
# xml.HealthCareFacility do
|
13
|
-
# xml.CodingStandard "ODS"
|
14
|
-
# xml.Code session.hospital_unit_renal_registry_code
|
15
|
-
# xml.Description session.hospital_unit_name
|
16
|
-
# end
|
17
|
-
|
18
|
-
# xml.AdmitReason do
|
19
|
-
# xml.comment! "AdmitReason 1 == Haemodialysis - TBC - may need to capture/derive"
|
20
|
-
# xml.CodingStandard "CF_RR7_TREATMENT"
|
21
|
-
# xml.Code "1"
|
22
|
-
# end
|
23
|
-
|
24
|
-
# xml.EnteredAt do
|
25
|
-
# xml.Code session.hospital_unit_renal_registry_code
|
26
|
-
# end
|
27
|
-
|
28
|
-
# xml.Attributes do
|
29
|
-
# xml.HDP01 session.patient&.hd_profile&.schedule_definition&.days_per_week
|
30
|
-
# xml.HDP02 session.duration
|
31
|
-
# xml.HDP03 session.document.dialysis.flow_rate
|
32
|
-
# xml.HDP04 session&.dialysate&.sodium_content
|
33
|
-
# xml.QBL05 session.access_type
|
34
|
-
# xml.comment! "ERF61 - defaulting to 5 if not present, as element is required"
|
35
|
-
# xml.ERF61 patient.current_registration_status_rr_code || "5" # 5= not assessed
|
36
|
-
# xml.PAT35 patient.first_seen_on
|
37
|
-
# end
|
38
|
-
# end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
xml = builder
|
4
|
-
|
5
|
-
xml.Treatment do
|
6
|
-
xml.FromTime modality.started_on
|
7
|
-
xml.ToTime modality.ended_on
|
8
|
-
|
9
|
-
xml.HealthCareFacility do
|
10
|
-
xml.CodingStandard "ODS"
|
11
|
-
xml.Code Renalware.config.ukrdc_site_code
|
12
|
-
end
|
13
|
-
|
14
|
-
# xml.AdmitReason do
|
15
|
-
# xml.comment! "AdmitReason 1 == Haemodialysis - TBC - may need to capture/derive"
|
16
|
-
# xml.CodingStandard "CF_RR7_TREATMENT"
|
17
|
-
# xml.Code "1"
|
18
|
-
# end
|
19
|
-
|
20
|
-
# xml.EnteredAt do
|
21
|
-
# xml.Code session.hospital_unit_renal_registry_code
|
22
|
-
# end
|
23
|
-
|
24
|
-
# xml.Attributes do
|
25
|
-
# xml.HDP01 session.patient&.hd_profile&.schedule_definition&.days_per_week
|
26
|
-
# xml.HDP02 session.duration
|
27
|
-
# xml.HDP03 session.document.dialysis.flow_rate
|
28
|
-
# xml.HDP04 session&.dialysate&.sodium_content
|
29
|
-
# xml.QBL05 session.access_type
|
30
|
-
# xml.comment! "ERF61 - defaulting to 5 if not present, as element is required"
|
31
|
-
# xml.ERF61 patient.current_registration_status_rr_code || "5" # 5= not assessed
|
32
|
-
# xml.PAT35 patient.first_seen_on
|
33
|
-
# end
|
34
|
-
end
|