renalware-core 2.0.79 → 2.0.80
Sign up to get free protection for your applications and to get access to all the features.
- 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
|