renalware-core 2.0.58 → 2.0.60
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/app/controllers/renalware/letters/letters_controller.rb +6 -5
- data/app/jobs/renalware/hd/generate_monthly_statistics.rb +1 -1
- data/app/models/concerns/renalware/patients_ransack_helper.rb +1 -0
- data/app/models/renalware/hd/generate_monthly_statistics_for_patient.rb +1 -1
- data/app/models/renalware/hd/grouped_transmission_log.rb +13 -0
- data/app/models/renalware/letters/approve_letter.rb +11 -1
- data/app/models/renalware/letters/delivery/email_letter_to_practice.rb +5 -1
- data/app/models/renalware/letters/determine_counterpart_ccs.rb +11 -4
- data/app/models/renalware/letters/letter.rb +1 -1
- data/app/models/renalware/letters/letter/pending_review.rb +1 -0
- data/app/models/renalware/letters/letter_factory.rb +6 -0
- data/app/models/renalware/letters/recipient.rb +8 -1
- data/app/models/renalware/letters/revise_letter.rb +1 -0
- data/app/presenters/renalware/letters/letter_presenter.rb +16 -1
- data/app/views/renalware/letters/formatted_letters/_letter.html.slim +0 -1
- data/app/views/renalware/letters/letters/_main_recipient.html.slim +1 -1
- data/app/views/renalware/transplants/mdm/_pathology_extra.html.slim +1 -1
- data/config/locales/renalware/hd/mdm_patients.yml +2 -0
- data/db/migrate/20181026145459_create_ukrdc_batch_numbers.rb +1 -1
- data/db/migrate/20181106133500_update_hd_overall_audit_to_version_9.rb +6 -0
- data/db/migrate/20181109110616_create_hd_grouped_transmission_logs_view.rb +9 -0
- data/db/views/hd_grouped_transmission_logs_v01.sql +31 -0
- data/db/views/pathology_current_key_observation_sets_v02.sql +2 -2
- data/db/views/reporting_bone_audit_v01.sql +1 -2
- data/db/views/reporting_hd_overall_audit_v09.sql +46 -0
- data/lib/age_calculator.rb +2 -2
- data/lib/renalware/version.rb +1 -1
- data/spec/factories/pathology/observation_descriptions.rb +1 -1
- data/spec/support/letters_spec_helper.rb +12 -9
- data/spec/support/pages/letters/form.rb +61 -0
- data/spec/support/pages/letters/patient_letters.rb +20 -0
- metadata +9 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9dc5eb19acc5300d23730446add99eb55745348e42272ec591918587b4a45dad
|
|
4
|
+
data.tar.gz: 9d740996dd4ad60bcfb9cf4a736a7b27fc304952ced9892ef0b0bb871ba3add6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 938df4717062d531ce6bbba9f56f28f81b006c68e0548accb891924d0997b11e4ab89aadc978134c9dd1e2bbb96b00131e0f36bc55435d4edfbca18da63840d7
|
|
7
|
+
data.tar.gz: 93226d8f3c9d9ff9f178d3589c45a5d1ca85203838e01409ea9d77c806e602bf8f9276df966bf950c475c20a66bf560f673a8711d3a6433332f097eac6df1dba
|
|
@@ -28,11 +28,12 @@ module Renalware
|
|
|
28
28
|
|
|
29
29
|
def new
|
|
30
30
|
@patient = load_and_authorize_patient
|
|
31
|
-
letter = LetterFactory
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
letter = LetterFactory.new(
|
|
32
|
+
@patient,
|
|
33
|
+
event: find_event,
|
|
34
|
+
author: current_user,
|
|
35
|
+
clinical: clinical?
|
|
36
|
+
)
|
|
36
37
|
.with_contacts_as_default_ccs
|
|
37
38
|
.build
|
|
38
39
|
RememberedLetterPreferences.new(session).apply_to(letter)
|
|
@@ -60,7 +60,7 @@ module Renalware
|
|
|
60
60
|
# These are the codes for the results we want to store in
|
|
61
61
|
# hd_patient_statics.pathology_snapshot - we are only interested in these
|
|
62
62
|
# results. They will be used for instance in reporting_hd_overall_audit
|
|
63
|
-
CODES = %w(HGB
|
|
63
|
+
CODES = %w(HGB PTHI PHOS CRE URE URR).freeze
|
|
64
64
|
|
|
65
65
|
def initialize(patient:)
|
|
66
66
|
@observation_set = Pathology.cast_patient(patient).fetch_current_observation_set
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Renalware
|
|
4
|
+
module HD
|
|
5
|
+
# Targets a Postgres view
|
|
6
|
+
# TODO: Write tests inc the ordering of data (parent then child) in the view.
|
|
7
|
+
class GroupedTransmissionLog < ApplicationRecord
|
|
8
|
+
scope :for_uuid, ->(uuid) { where(uuid: uuid) }
|
|
9
|
+
scope :incoming, -> { where(direction: :in) }
|
|
10
|
+
scope :outgoing, -> { where(direction: :out) }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -15,9 +15,10 @@ module Renalware
|
|
|
15
15
|
|
|
16
16
|
def call(by:)
|
|
17
17
|
Letter.transaction do
|
|
18
|
+
add_missing_counterpart_cc_recipients
|
|
19
|
+
archive_recipients
|
|
18
20
|
sign(by: by)
|
|
19
21
|
archive_content(by: by)
|
|
20
|
-
archive_recipients
|
|
21
22
|
broadcast(:letter_approved, letter)
|
|
22
23
|
end
|
|
23
24
|
end
|
|
@@ -40,6 +41,15 @@ module Renalware
|
|
|
40
41
|
def archive_recipients
|
|
41
42
|
letter.archive_recipients!
|
|
42
43
|
end
|
|
44
|
+
|
|
45
|
+
def add_missing_counterpart_cc_recipients
|
|
46
|
+
DetermineCounterpartCCs.new(letter).call.each do |recipient|
|
|
47
|
+
already_a_recipient = letter.recipients.exists?(addressee: recipient.addressee)
|
|
48
|
+
unless already_a_recipient
|
|
49
|
+
recipient.save!
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
43
53
|
end
|
|
44
54
|
end
|
|
45
55
|
end
|
|
@@ -38,11 +38,15 @@ module Renalware
|
|
|
38
38
|
# _aj_globalid: gid://dummy/Renalware::Letters::Letter/3
|
|
39
39
|
# which it turns out works fine when the letter is loaded by GlobalId/ActiveJob;
|
|
40
40
|
# it correctly casts the letter to its STI type e.g. Letters::Approved in the job.
|
|
41
|
+
# Note we are already in a tx here from the letterlistener so if we for instance
|
|
42
|
+
# call deliver and not deliver_later, we will get a LetterIsNotApprovedOrCompletedError
|
|
43
|
+
# error when it looks up the letter as its approved state has not yet been saved.
|
|
44
|
+
# We could possibly use an async LetterListener and remove the async here.
|
|
41
45
|
Letter.transaction do
|
|
42
46
|
PracticeMailer.patient_letter(
|
|
43
47
|
letter: letter.becomes(Letter),
|
|
44
48
|
to: practice_email_address
|
|
45
|
-
).deliver_later
|
|
49
|
+
).deliver_later # ! see comment
|
|
46
50
|
|
|
47
51
|
# Flag as sent
|
|
48
52
|
gp_recipient.update(emailed_at: Time.zone.now)
|
|
@@ -11,8 +11,10 @@ module Renalware
|
|
|
11
11
|
class DetermineCounterpartCCs < SimpleDelegator
|
|
12
12
|
def call
|
|
13
13
|
counterpart_css = []
|
|
14
|
-
counterpart_css << build_recipient("patient") if cc_patient?
|
|
15
|
-
|
|
14
|
+
counterpart_css << build_recipient("patient", patient) if cc_patient?
|
|
15
|
+
if cc_primary_care_physican?
|
|
16
|
+
counterpart_css << build_recipient("primary_care_physician", primary_care_physician)
|
|
17
|
+
end
|
|
16
18
|
counterpart_css
|
|
17
19
|
end
|
|
18
20
|
|
|
@@ -27,8 +29,13 @@ module Renalware
|
|
|
27
29
|
patient.cc_on_letter?(self)
|
|
28
30
|
end
|
|
29
31
|
|
|
30
|
-
def build_recipient(person_role)
|
|
31
|
-
Recipient.new(
|
|
32
|
+
def build_recipient(person_role, addressee)
|
|
33
|
+
Recipient.new(
|
|
34
|
+
person_role: person_role,
|
|
35
|
+
role: :cc,
|
|
36
|
+
addressee: addressee,
|
|
37
|
+
letter: __getobj__
|
|
38
|
+
)
|
|
32
39
|
end
|
|
33
40
|
end
|
|
34
41
|
end
|
|
@@ -63,7 +63,7 @@ module Renalware
|
|
|
63
63
|
scope :with_author, -> { includes(:author) }
|
|
64
64
|
scope :with_patient, -> { includes(patient: :primary_care_physician) }
|
|
65
65
|
scope :with_event, -> { includes(:event) }
|
|
66
|
-
scope :with_cc_recipients, -> { includes(cc_recipients:
|
|
66
|
+
scope :with_cc_recipients, -> { includes(cc_recipients: :addressee) }
|
|
67
67
|
scope :approved_or_completed, lambda {
|
|
68
68
|
where(type: [state_class_name(:approved), state_class_name(:completed)])
|
|
69
69
|
}
|
|
@@ -35,6 +35,7 @@ module Renalware
|
|
|
35
35
|
# Using self.id rather than letter.id in case the becomes! has lost the id
|
|
36
36
|
# for some reason. Also moved presenter.content to a new line so we can more easily see
|
|
37
37
|
# if that is causing the error as it does a lot of processing to build the letter.
|
|
38
|
+
# TODO: investigate
|
|
38
39
|
achived_letter_content = presenter.content
|
|
39
40
|
letter.build_archive(by: by, content: achived_letter_content, letter_id: id)
|
|
40
41
|
end
|
|
@@ -4,6 +4,12 @@ require_dependency "renalware/letters"
|
|
|
4
4
|
|
|
5
5
|
module Renalware
|
|
6
6
|
module Letters
|
|
7
|
+
# Build a new draft letter.
|
|
8
|
+
# Used e.g from .
|
|
9
|
+
# - LettersController#new - when building the initial letter form
|
|
10
|
+
# (in which case params are those suppplied in #new)
|
|
11
|
+
# - LettersController#create via DraftLetter.build - before saving the letter, in which case
|
|
12
|
+
# params is the posted hash of letter attributes from the html form.
|
|
7
13
|
class LetterFactory
|
|
8
14
|
def initialize(patient, params = {})
|
|
9
15
|
@params = LetterParamsProcessor.new(patient).call(params)
|
|
@@ -19,7 +19,6 @@ module Renalware
|
|
|
19
19
|
reject_if: :patient_or_primary_care_physician?
|
|
20
20
|
|
|
21
21
|
validates :addressee_id, presence: { if: :contact? }
|
|
22
|
-
|
|
23
22
|
validate :person_role_present?
|
|
24
23
|
|
|
25
24
|
# Check we have a person_role. If we don't add an error to the parent letter if one is
|
|
@@ -37,10 +36,18 @@ module Renalware
|
|
|
37
36
|
(address || current_address).to_s
|
|
38
37
|
end
|
|
39
38
|
|
|
39
|
+
# Archiving a letter means taking the current address for the recipient (they could be a
|
|
40
|
+
# practice, patient, gp etc) and copying their address into a new Address row so it becomes
|
|
41
|
+
# immutably recorded as a definitive statement of where the letter was sent.
|
|
42
|
+
# Without this, if for example the patient's address subsequently changes, we would only be
|
|
43
|
+
# able to resolve the new address for the patient, not the address used at the time the letter
|
|
44
|
+
# was sent. We could also look at the archived letter content however to see what was
|
|
45
|
+
# physically on the letter, but we can't do that in SQL.
|
|
40
46
|
def archive!
|
|
41
47
|
build_address if address.blank?
|
|
42
48
|
|
|
43
49
|
address.copy_from(current_address)
|
|
50
|
+
|
|
44
51
|
# Its possible a migrated address might not have a postcode. Don't let archiving fail
|
|
45
52
|
# at this stage because of that as the user cannot be informed at this stage
|
|
46
53
|
# so skip address validation.
|
|
@@ -15,6 +15,7 @@ module Renalware
|
|
|
15
15
|
def call(patient, letter_id, params = {})
|
|
16
16
|
letter = patient.letters.pending.find(letter_id)
|
|
17
17
|
Letter.transaction do
|
|
18
|
+
# See e.g. Letter::Draft.revise
|
|
18
19
|
letter.revise(params)
|
|
19
20
|
if letter.changes.key?(:pathology_timestamp)
|
|
20
21
|
letter.pathology_snapshot = build_pathology_snapshot(patient)
|
|
@@ -37,6 +37,13 @@ module Renalware
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
def cc_recipients_for_envelop_stuffing
|
|
41
|
+
@cc_recipients_for_envelop_stuffing ||= begin
|
|
42
|
+
recipients = build_cc_recipients
|
|
43
|
+
present_cc_recipients(recipients)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
40
47
|
def electronic_cc_receipts
|
|
41
48
|
@electronic_cc_receipts ||=
|
|
42
49
|
CollectionPresenter.new(super, Letters::ElectonicReceiptPresenter)
|
|
@@ -124,8 +131,16 @@ module Renalware
|
|
|
124
131
|
end
|
|
125
132
|
|
|
126
133
|
# Include the counterpart cc recipients (i.e. patient and/or primary care physician)
|
|
134
|
+
# Because of ApproveLetter#add_missing_counterpart_cc_recipients we need to only
|
|
135
|
+
# bring in determine_counterpart_ccs if the letter is not yet approved
|
|
127
136
|
def build_cc_recipients
|
|
128
|
-
|
|
137
|
+
# Get CCs order by person_role: :desc so that gp floats above contacts
|
|
138
|
+
persisted_ccs = __getobj__.cc_recipients.order(person_role: :desc)
|
|
139
|
+
if draft? || pending_review?
|
|
140
|
+
determine_counterpart_ccs + persisted_ccs
|
|
141
|
+
else
|
|
142
|
+
persisted_ccs
|
|
143
|
+
end
|
|
129
144
|
end
|
|
130
145
|
|
|
131
146
|
def present_cc_recipients(recipients)
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# The presenter in this case is a bit unconventional as it returns a reformatted
|
|
6
6
|
# array of OpenStructs which are easier to consume that any other format we currently have.
|
|
7
7
|
presenter = Renalware::Pathology::ObservationsForCodesPresenter
|
|
8
|
-
.new(patient: mdm.patient, codes: %w(HBA FER
|
|
8
|
+
.new(patient: mdm.patient, codes: %w(HBA FER PTHI))
|
|
9
9
|
|
|
10
10
|
article
|
|
11
11
|
header
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class CreateUKRDCBatchNumbers < ActiveRecord::Migration[5.2]
|
|
2
2
|
def change
|
|
3
|
-
create_table
|
|
3
|
+
create_table "renalware.ukrdc_batch_numbers" do |t|
|
|
4
4
|
# no other columns, we just use the id as the batch number when sending data to the UKRDC.
|
|
5
5
|
t.timestamps null: false
|
|
6
6
|
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
-- This view puts child HD:TransmissionLogs logs next to their parent
|
|
2
|
+
-- e.g.
|
|
3
|
+
-- id, parent_id
|
|
4
|
+
-- 104,null
|
|
5
|
+
-- 105,104
|
|
6
|
+
-- 106,104
|
|
7
|
+
-- 107,null
|
|
8
|
+
-- 108,107
|
|
9
|
+
-- 109,null
|
|
10
|
+
-- 110,109
|
|
11
|
+
-- 111,109
|
|
12
|
+
-- ...
|
|
13
|
+
--
|
|
14
|
+
-- You can sort the view in reverse chronological order using eg
|
|
15
|
+
-- select * from diaverum_logs order by id desc, updated_at desc
|
|
16
|
+
-- The WITH RECURSIVE allows a CTE to reference itself.
|
|
17
|
+
-- Note also the window function OVER to allow us to generate maxlevel
|
|
18
|
+
-- Adapted from https://stackoverflow.com/questions/17261792/postgresql-recursive-self-join
|
|
19
|
+
with recursive parent_child_logs(parent_id, id, uuid, level) as (
|
|
20
|
+
select t.parent_id, t.id, uuid, 1 as level
|
|
21
|
+
from hd_transmission_logs t where t.parent_id is null
|
|
22
|
+
union all
|
|
23
|
+
select parent_child_logs.id, t.id, t.uuid, parent_child_logs.level + 1
|
|
24
|
+
from hd_transmission_logs t join parent_child_logs on t.parent_id = parent_child_logs.id
|
|
25
|
+
),
|
|
26
|
+
ordered_parent_child_logs as (
|
|
27
|
+
select id, parent_id, level, max(level) over (partition by id) as maxlevel from parent_child_logs
|
|
28
|
+
)
|
|
29
|
+
SELECT h.* from ordered_parent_child_logs
|
|
30
|
+
inner join hd_transmission_logs h on h.id = ordered_parent_child_logs.id
|
|
31
|
+
where level = maxlevel order by id asc, updated_at asc;
|
|
@@ -11,6 +11,6 @@ select p.id as patient_id,
|
|
|
11
11
|
(select observed_at from pathology_current_observations where description_code = 'HBA' and patient_id = p.id) as hba_observed_at,
|
|
12
12
|
(select result from pathology_current_observations where description_code = 'FER' and patient_id = p.id) as fer_result,
|
|
13
13
|
(select observed_at from pathology_current_observations where description_code = 'FER' and patient_id = p.id) as fer_observed_at,
|
|
14
|
-
(select result from pathology_current_observations where description_code = '
|
|
15
|
-
(select observed_at from pathology_current_observations where description_code = '
|
|
14
|
+
(select result from pathology_current_observations where description_code = 'PTHI' and patient_id = p.id) as pth_result,
|
|
15
|
+
(select observed_at from pathology_current_observations where description_code = 'PTHI' and patient_id = p.id) as pth_observed_at
|
|
16
16
|
from patients p
|
|
@@ -20,7 +20,7 @@ select
|
|
|
20
20
|
inner join modality_modalities m on m.patient_id = p.id
|
|
21
21
|
inner join modality_descriptions md on m.description_id = md.id
|
|
22
22
|
) e1
|
|
23
|
-
left join lateral (select result::decimal pth from pathology_current_observations where description_code = '
|
|
23
|
+
left join lateral (select result::decimal pth from pathology_current_observations where description_code = 'PTHI' and patient_id = e1.patient_id) e2 ON true
|
|
24
24
|
left join lateral (select result::decimal phos from pathology_current_observations where description_code = 'PHOS' and patient_id = e1.patient_id) e3 ON true
|
|
25
25
|
left join lateral (select result::decimal cca from pathology_current_observations where description_code = 'CCA' and patient_id = e1.patient_id) e4 ON true
|
|
26
26
|
left join lateral (select phos phos_lt_1_8 where phos < 1.8) e5 ON true
|
|
@@ -29,4 +29,3 @@ select
|
|
|
29
29
|
left join lateral (select cca cca_2_1_to_2_4 where cca between 2.1 and 2.4) e8 ON true
|
|
30
30
|
where modality_desc in ('HD','PD','Transplant', 'Low Clearance')
|
|
31
31
|
group by modality_desc
|
|
32
|
-
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
WITH fistula_or_graft_access_types AS (
|
|
2
|
+
select id from access_types where name ilike '%fistula%' or name ilike '%graft%'
|
|
3
|
+
)
|
|
4
|
+
, patients_w_fistula_or_graft as (
|
|
5
|
+
select patient_id from access_profiles where type_id in (select id from fistula_or_graft_access_types)
|
|
6
|
+
),
|
|
7
|
+
stats as (
|
|
8
|
+
select
|
|
9
|
+
s.patient_id,
|
|
10
|
+
s.hospital_unit_id,
|
|
11
|
+
s.month,
|
|
12
|
+
s.year,
|
|
13
|
+
s.session_count,
|
|
14
|
+
s.number_of_missed_sessions,
|
|
15
|
+
s.number_of_sessions_with_dialysis_minutes_shortfall_gt_5_pct,
|
|
16
|
+
exists(select x.patient_id from patients_w_fistula_or_graft x where x.patient_id = s.patient_id) as has_fistula_or_graft,
|
|
17
|
+
((number_of_missed_sessions::float / NULLIF(session_count::float, 0)) * 100.0) > 10.0 as missed_sessions_gt_10_pct,
|
|
18
|
+
s.dialysis_minutes_shortfall::float,
|
|
19
|
+
convert_to_float(s.pathology_snapshot -> 'HGB' ->> 'result') > 100 as hgb_gt_100,
|
|
20
|
+
convert_to_float(s.pathology_snapshot -> 'HGB' ->> 'result') > 130 as hgb_gt_130,
|
|
21
|
+
convert_to_float(s.pathology_snapshot -> 'PTHI' ->> 'result') < 300 as pth_lt_300,
|
|
22
|
+
convert_to_float(s.pathology_snapshot -> 'URR' ->> 'result') > 64 as urr_gt_64,
|
|
23
|
+
convert_to_float(s.pathology_snapshot -> 'URR' ->> 'result') > 69 as urr_gt_69,
|
|
24
|
+
convert_to_float(s.pathology_snapshot -> 'PHOS' ->> 'result') < 1.8 as phos_lt_1_8
|
|
25
|
+
from hd_patient_statistics s
|
|
26
|
+
where s.rolling is null
|
|
27
|
+
)
|
|
28
|
+
select
|
|
29
|
+
hu.name,
|
|
30
|
+
stats.year,
|
|
31
|
+
stats.month,
|
|
32
|
+
count(*) as patient_count,
|
|
33
|
+
round(avg(stats.dialysis_minutes_shortfall)::decimal, 2) as avg_missed_hd_time,
|
|
34
|
+
round(avg(number_of_sessions_with_dialysis_minutes_shortfall_gt_5_pct),2) as pct_shortfall_gt_5_pct,
|
|
35
|
+
round(((count(*) filter(where missed_sessions_gt_10_pct = true))::float / count(*)::float * 100)::decimal, 2) as pct_missed_sessions_gt_10_pct,
|
|
36
|
+
round(((count(*) filter(where hgb_gt_100 = true))::float / count(*)::float * 100)::decimal, 2) as percentage_hgb_gt_100,
|
|
37
|
+
round(((count(*) filter(where hgb_gt_130 = true))::float / count(*)::float * 100)::decimal, 2) as percentage_hgb_gt_130,
|
|
38
|
+
round(((count(*) filter(where pth_lt_300 = true))::float / count(*)::float * 100)::decimal, 2) as percentage_pth_lt_300,
|
|
39
|
+
round(((count(*) filter(where urr_gt_64 = true))::float / count(*)::float * 100)::decimal, 2) as percentage_urr_gt_64,
|
|
40
|
+
round(((count(*) filter(where urr_gt_69 = true))::float / count(*)::float * 100)::decimal, 2) as percentage_urr_gt_69,
|
|
41
|
+
round(((count(*) filter(where phos_lt_1_8 = true))::float / count(*)::float * 100)::decimal, 2) as percentage_phosphate_lt_1_8,
|
|
42
|
+
round(((((count(*) FILTER (WHERE (stats.has_fistula_or_graft = true)))::double precision / (count(*))::double precision) * (100)::double precision))::numeric, 2) AS percentage_access_fistula_or_graft
|
|
43
|
+
from stats
|
|
44
|
+
inner join hospital_units hu on hu.id = stats.hospital_unit_id
|
|
45
|
+
group by hu.name, stats.year, stats.month
|
|
46
|
+
order by hu.name, stats.year asc, stats.month asc;
|
data/lib/age_calculator.rb
CHANGED
|
@@ -24,9 +24,9 @@ class AgeCalculator
|
|
|
24
24
|
|
|
25
25
|
def build_calculation(birth_date, current_date)
|
|
26
26
|
OpenStruct.new(
|
|
27
|
-
days:
|
|
27
|
+
days: current_date.day - birth_date.day,
|
|
28
28
|
months: current_date.month - birth_date.month,
|
|
29
|
-
years:
|
|
29
|
+
years: current_date.year - birth_date.year,
|
|
30
30
|
borrowed_month: false
|
|
31
31
|
)
|
|
32
32
|
end
|
data/lib/renalware/version.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# rubocop:disable Metrics/MethodLength
|
|
3
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
|
4
4
|
module LettersSpecHelper
|
|
5
5
|
def build_letter(state: :draft, to:, patient:, **args)
|
|
6
6
|
trait = "#{state}_letter".to_sym
|
|
@@ -42,15 +42,17 @@ module LettersSpecHelper
|
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
|
|
45
|
-
def
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
def create_aproved_letter_to_patient_with_cc_to_gp_and_one_contact(
|
|
46
|
+
user: nil,
|
|
47
|
+
body: "test",
|
|
48
|
+
page_count: 1,
|
|
49
|
+
practice_email: nil
|
|
50
|
+
)
|
|
49
51
|
user ||= create(:user)
|
|
50
52
|
|
|
51
53
|
practice = create(
|
|
52
54
|
:practice,
|
|
53
|
-
email:
|
|
55
|
+
email: practice_email
|
|
54
56
|
)
|
|
55
57
|
primary_care_physician = create(
|
|
56
58
|
:letter_primary_care_physician,
|
|
@@ -99,7 +101,7 @@ module LettersSpecHelper
|
|
|
99
101
|
letter = create_letter(
|
|
100
102
|
to: :patient,
|
|
101
103
|
patient: patient,
|
|
102
|
-
state:
|
|
104
|
+
state: :pending_review,
|
|
103
105
|
page_count: page_count,
|
|
104
106
|
body: body
|
|
105
107
|
)
|
|
@@ -111,7 +113,8 @@ module LettersSpecHelper
|
|
|
111
113
|
letter: letter,
|
|
112
114
|
addressee: contact
|
|
113
115
|
)
|
|
114
|
-
letter
|
|
116
|
+
Renalware::Letters::ApproveLetter.new(letter).call(by: user)
|
|
117
|
+
Renalware::Letters::Letter.find(letter.id)
|
|
115
118
|
end
|
|
116
119
|
end
|
|
117
|
-
# rubocop:enable Metrics/MethodLength
|
|
120
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../page_object"
|
|
4
|
+
|
|
5
|
+
# rubocop disable Metrics/LineLength
|
|
6
|
+
module Pages
|
|
7
|
+
module Letters
|
|
8
|
+
class Form < PageObject
|
|
9
|
+
PERSON_ROLE_TO_RADIO_ID_MAP = {
|
|
10
|
+
patient: :letter_main_recipient_attributes_person_role_patient,
|
|
11
|
+
primary_care_physician: :letter_main_recipient_attributes_person_role_primary_care_physician,
|
|
12
|
+
gp: :letter_main_recipient_attributes_person_role_primary_care_physician,
|
|
13
|
+
contact: :letter_main_recipient_attributes_person_role_contact
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
16
|
+
def issued_on=(date)
|
|
17
|
+
fill_in "Date", with: I18n.l(date)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def letterhead=(letterhead)
|
|
21
|
+
select letterhead, from: "Letterhead"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def author=(user)
|
|
25
|
+
select user.to_s, from: "Author"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def description=(value)
|
|
29
|
+
fill_in "Description", with: value
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def main_recipient=(main_recipient_role)
|
|
33
|
+
within ".letter_main_recipient_person_role" do
|
|
34
|
+
radio_id = map_main_recipient_to_radio_id(main_recipient_role)
|
|
35
|
+
choose(radio_id)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# If using :contact as main_recipient then we need to select which recipient to use
|
|
40
|
+
# from the contacts dropdown
|
|
41
|
+
def main_recipient_contact_name=(name)
|
|
42
|
+
select name, from: "letter_main_recipient_attributes_addressee_id"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def submit
|
|
46
|
+
within ".top" do
|
|
47
|
+
click_on "Create"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def map_main_recipient_to_radio_id(main_recipient_type)
|
|
54
|
+
PERSON_ROLE_TO_RADIO_ID_MAP.fetch(
|
|
55
|
+
main_recipient_type.to_s.downcase.to_sym
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
# rubocop enable Metrics/LineLength
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../page_object"
|
|
4
|
+
|
|
5
|
+
module Pages
|
|
6
|
+
module Letters
|
|
7
|
+
class PatientLetters < PageObject
|
|
8
|
+
def go(patient)
|
|
9
|
+
visit patient_letters_letters_path(patient)
|
|
10
|
+
self
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def create_simple_letter
|
|
14
|
+
click_on "Create"
|
|
15
|
+
click_on "Simple Letter"
|
|
16
|
+
Pages::Letters::Form.new
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
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.60
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Airslie
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-11-
|
|
11
|
+
date: 2018-11-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: active_type
|
|
@@ -1424,6 +1424,7 @@ files:
|
|
|
1424
1424
|
- app/models/renalware/hd/find_or_create_diary_by_week_query.rb
|
|
1425
1425
|
- app/models/renalware/hd/find_or_create_master_diary.rb
|
|
1426
1426
|
- app/models/renalware/hd/generate_monthly_statistics_for_patient.rb
|
|
1427
|
+
- app/models/renalware/hd/grouped_transmission_log.rb
|
|
1427
1428
|
- app/models/renalware/hd/master_diary.rb
|
|
1428
1429
|
- app/models/renalware/hd/mdm_patients_form.rb
|
|
1429
1430
|
- app/models/renalware/hd/mdm_patients_query.rb
|
|
@@ -3342,6 +3343,8 @@ files:
|
|
|
3342
3343
|
- db/migrate/20181013115138_update_reporting_daily_pathology_view_to_v2.rb
|
|
3343
3344
|
- db/migrate/20181025170410_add_ukrdc_helper_column_to_patients.rb
|
|
3344
3345
|
- db/migrate/20181026145459_create_ukrdc_batch_numbers.rb
|
|
3346
|
+
- db/migrate/20181106133500_update_hd_overall_audit_to_version_9.rb
|
|
3347
|
+
- db/migrate/20181109110616_create_hd_grouped_transmission_logs_view.rb
|
|
3345
3348
|
- db/seeds.rb
|
|
3346
3349
|
- db/seeds/default/accesses/access_pd_catheter_insertion_techniques.csv
|
|
3347
3350
|
- db/seeds/default/accesses/access_pd_catheter_insertion_techniques.rb
|
|
@@ -3426,6 +3429,7 @@ files:
|
|
|
3426
3429
|
- db/triggers/feed_messages_preprocessing_trigger_v01.sql
|
|
3427
3430
|
- db/triggers/update_current_observation_set_trigger_v01.sql
|
|
3428
3431
|
- db/triggers/update_research_study_participants_trigger_v01.sql
|
|
3432
|
+
- db/views/hd_grouped_transmission_logs_v01.sql
|
|
3429
3433
|
- db/views/hd_schedule_definition_filters_v01.sql
|
|
3430
3434
|
- db/views/medication_current_prescriptions_v01.sql
|
|
3431
3435
|
- db/views/pathology_current_key_observation_sets_v01.sql
|
|
@@ -3454,6 +3458,7 @@ files:
|
|
|
3454
3458
|
- db/views/reporting_hd_overall_audit_v06.sql
|
|
3455
3459
|
- db/views/reporting_hd_overall_audit_v07.sql
|
|
3456
3460
|
- db/views/reporting_hd_overall_audit_v08.sql
|
|
3461
|
+
- db/views/reporting_hd_overall_audit_v09.sql
|
|
3457
3462
|
- db/views/reporting_main_authors_audit_v01.sql
|
|
3458
3463
|
- db/views/reporting_main_authors_audit_v02.sql
|
|
3459
3464
|
- db/views/reporting_main_authors_audit_v03.sql
|
|
@@ -3676,6 +3681,8 @@ files:
|
|
|
3676
3681
|
- spec/support/matchers/have_pdf_page_text.rb
|
|
3677
3682
|
- spec/support/matchers/validate_timeliness_of.rb
|
|
3678
3683
|
- spec/support/pages/admissions/consults_page.rb
|
|
3684
|
+
- spec/support/pages/letters/form.rb
|
|
3685
|
+
- spec/support/pages/letters/patient_letters.rb
|
|
3679
3686
|
- spec/support/pages/page_object.rb
|
|
3680
3687
|
- spec/support/pathology_spec_helper.rb
|
|
3681
3688
|
- spec/support/patients_spec_helper.rb
|