renalware-core 2.0.105 → 2.0.106
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 +6 -0
- data/app/assets/javascripts/renalware/hd.js +108 -0
- data/app/assets/stylesheets/renalware/modules/_hd.scss +204 -0
- data/app/controllers/renalware/hd/prescription_administration_authorisations_controller.rb +27 -0
- data/app/controllers/renalware/hd/sessions_controller.rb +14 -3
- data/app/models/renalware/hd/mdm_patients_query.rb +1 -2
- data/app/models/renalware/hd/prescription_administration.rb +48 -0
- data/app/models/renalware/hd/prescription_administration_reason.rb +10 -0
- data/app/models/renalware/hd/session_factory.rb +4 -1
- data/app/models/renalware/hd/sessions/save_session.rb +7 -0
- data/app/models/renalware/pd/mdm_patients_query.rb +1 -2
- data/app/models/renalware/renal/registry/preflight_checks/deaths_query.rb +1 -2
- data/app/models/renalware/transplants/mdm_patients_query.rb +1 -2
- data/app/models/renalware/user.rb +13 -0
- data/app/presenters/renalware/hd/session_presenter.rb +5 -0
- data/app/views/renalware/api/ukrdc/patients/_clinic_visit_observation.xml.builder +1 -2
- data/app/views/renalware/hd/sessions/_form.html.slim +3 -12
- data/app/views/renalware/hd/sessions/_form_actions.html.slim +19 -18
- data/app/views/renalware/hd/sessions/form/_drugs_to_be_administered.html.slim +84 -0
- data/app/views/renalware/hospitals/units/index.html.slim +1 -1
- data/app/views/renalware/transplants/registration_statuses/_list.html.slim +0 -8
- data/config/initializers/simple_form_foundation.rb +18 -0
- data/config/locales/renalware/hd/prescription_administration.en.yml +5 -0
- data/config/locales/renalware/navigation/renal.en.yml +1 -1
- data/config/routes/hd.rb +1 -0
- data/db/migrate/20190624130020_add_authentication_to_hd_prescription_administrations.rb +16 -0
- data/db/migrate/20190627141751_add_tokens_to_hd_prescription_administrations.rb +22 -0
- data/db/migrate/20190716125837_create_hd_prescription_administration_reasons.rb +17 -0
- data/db/seeds/default/hd/prescription_administration_reasons.rb +16 -0
- data/db/seeds/default/hd/seeds.rb +1 -0
- data/lib/renalware/version.rb +1 -1
- data/spec/factories/transplants/modality_descriptions.rb +7 -2
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: efb794ae27f5828ca612778342c373a1c21523c321b8d128fc375b599c73e6f5
|
4
|
+
data.tar.gz: 193b964ca2a0d8dddbe61fdf32ca7dec8a30b13d775d4f711e84f1d348adb0c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7897419fac1a376460c4f7e696ca853686845ba2a4c3918928dfc85964c1a3e2bede291f6db07fa7a3fef179e335fe9b0df62d8cf353278fb18a23d84b89d3fc
|
7
|
+
data.tar.gz: 61043d951f2a2c2194679f0ac9682ee7cb22181ebe3bbc8f51e01f2832facaaef79b8632ef34df056aa7db6c37d2ed4bc3fb2e39af17de9352ae4dbe8353ff9f
|
data/README.md
CHANGED
@@ -223,3 +223,9 @@ docker build -t renalware .
|
|
223
223
|
docker-compose run web rake db:create
|
224
224
|
docker-compose run web rake app:db:create
|
225
225
|
```
|
226
|
+
|
227
|
+
#### Browser testing
|
228
|
+
|
229
|
+
<a href="https://www.browserstack.com">
|
230
|
+
<img alt="Browserstack logo" src="doc/Browserstack-logo.svg" width="188" height="43">
|
231
|
+
</a>
|
@@ -0,0 +1,108 @@
|
|
1
|
+
/*
|
2
|
+
These are functions relating to the authorisation by nurse + witness of prescriptions
|
3
|
+
within the HD Session form.
|
4
|
+
TODO: This needs refactoring.
|
5
|
+
*/
|
6
|
+
$(document).ready(function() {
|
7
|
+
/*
|
8
|
+
If enter is pressed in a password field (out of habit as enter is oftern used when logging in,
|
9
|
+
after entering their password) throw it away. We could map it to a tab but frankly that gets
|
10
|
+
a bit complicated - see here:
|
11
|
+
https://stackoverflow.com/questions/2335553/jquery-how-to-catch-enter-key-and-change-event-to-tab
|
12
|
+
*/
|
13
|
+
$("input.user-password").on("keypress", function(e) {
|
14
|
+
if (e.keyCode == 13) { return false; }
|
15
|
+
});
|
16
|
+
|
17
|
+
$(".hd-drug-administered input[type='radio']").on("change", function(e) {
|
18
|
+
var checked = ($(this).val() == "true");
|
19
|
+
var container = $(this).closest(".hd-drug-administration");
|
20
|
+
$(container).toggleClass("administered", checked)
|
21
|
+
$(container).toggleClass("not-administered", !checked)
|
22
|
+
$(container).removeClass("undecided");
|
23
|
+
$(".authentication", container).toggle(checked)
|
24
|
+
$(".authentication", container).toggleClass("disabled-with-faded-overlay", !checked)
|
25
|
+
$(".reason-why-not-administered", container).toggle(!checked)
|
26
|
+
});
|
27
|
+
|
28
|
+
$(".hd-drug-administration .authentication-user-id").on("select2:select", function(e) {
|
29
|
+
var container = $(this).closest(".user-and-password");
|
30
|
+
var topContainer = $(container).closest(".hd-drug-administration")
|
31
|
+
$(container).find(".authentication-token").val("")
|
32
|
+
$("input.user-password", container).val("");
|
33
|
+
$(container).removeClass("authorised");
|
34
|
+
var tokenCount = $(topContainer).find(".authorised").length;
|
35
|
+
$(topContainer).attr("data-token-count", tokenCount);
|
36
|
+
});
|
37
|
+
|
38
|
+
|
39
|
+
// When a user clicks the link to clear the authorisation (they might have used the wrong user
|
40
|
+
// for instance) the clear the relevant token and password fields and classes.
|
41
|
+
$(".hd-drug-administration .user-and-password .user-and-password--clear").on("click", function(e) {
|
42
|
+
e.preventDefault();
|
43
|
+
var container = $(this).closest(".user-and-password");
|
44
|
+
var topContainer = $(container).closest(".hd-drug-administration")
|
45
|
+
$(container).find(".authentication-token").val("")
|
46
|
+
$("input.user-password", container).val("");
|
47
|
+
$(container).removeClass("authorised");
|
48
|
+
var tokenCount = $(topContainer).find(".authorised").length;
|
49
|
+
$(topContainer).attr("data-token-count", tokenCount);
|
50
|
+
});
|
51
|
+
|
52
|
+
// When the user has entered a password and leaves the password field, make an ajax POST to
|
53
|
+
// authenticate the user and on success return an authorisation token which is added to the html
|
54
|
+
// form - it will be validated when the form is submitted.
|
55
|
+
// TODO: also do this if enter pressed while in the password field.
|
56
|
+
$(".user-and-password input.user-password").on("blur", function(e) {
|
57
|
+
var container = $(this).closest(".user-and-password");
|
58
|
+
var topContainer = $(container).closest(".hd-drug-administration")
|
59
|
+
var authUrl = $(container).closest(".authentication").data("authentication-url");
|
60
|
+
var userSelect = $(container).find(".authentication-user-id");
|
61
|
+
var userId = $(userSelect).find("option:selected").val();
|
62
|
+
var authorisationTokenHiddenField = $(container).find(".authentication-token");
|
63
|
+
var password = $(this).val();
|
64
|
+
|
65
|
+
// Prevent the a 401 xhr code from redirecting us to the login page - see ajax_errors.js
|
66
|
+
$(document).off('ajaxError');
|
67
|
+
|
68
|
+
if (userId && password) {
|
69
|
+
$.ajax({
|
70
|
+
async: false, /* needed as if pwd field has focus and user clicks submit, it would not wait for ajax */
|
71
|
+
url: authUrl,
|
72
|
+
type: "POST",
|
73
|
+
data: "[user][id]=" + userId + "&[user][password]=" + password,
|
74
|
+
beforeSend: function() {
|
75
|
+
// Add a 'working' class during ajax operations so we can show a spinner for example
|
76
|
+
$(container).addClass("working");
|
77
|
+
$(container).removeClass("error");
|
78
|
+
// $(".hd-session-form button[type='submit]").prop("disabled", "disabled")
|
79
|
+
},
|
80
|
+
complete: function() {
|
81
|
+
$(container).removeClass("working");
|
82
|
+
// $(".hd-session-form input[type='submit']").removeProp("disabled")
|
83
|
+
},
|
84
|
+
statusCode: {
|
85
|
+
200: function (token) {
|
86
|
+
// The user id/password combination is valid and a token has been returned.
|
87
|
+
// We save the token to a hidden field so it wikll be submitted in the session form.
|
88
|
+
$(authorisationTokenHiddenField).val(token);
|
89
|
+
$(container).removeClass("unauthorised").addClass("authorised").removeClass("error");
|
90
|
+
// $(userSelect).prop("disabled", true);
|
91
|
+
var tokenCount = $(topContainer).find(".authorised").length;
|
92
|
+
$(topContainer).attr("data-token-count", tokenCount);
|
93
|
+
|
94
|
+
},
|
95
|
+
401: function (data) {
|
96
|
+
// The user id/password combination was not valid
|
97
|
+
console.log('401: Unauthenticated');
|
98
|
+
$(authorisationTokenHiddenField).prop("value", "");
|
99
|
+
$(container).removeClass("authorised").addClass("error");
|
100
|
+
|
101
|
+
var tokenCount = $(topContainer).find(".authorised").length;
|
102
|
+
$(topContainer).attr("data-token-count", tokenCount);
|
103
|
+
}
|
104
|
+
}
|
105
|
+
});
|
106
|
+
}
|
107
|
+
});
|
108
|
+
});
|
@@ -375,3 +375,207 @@ table.hd-sessions {
|
|
375
375
|
margin-bottom: 0.2rem;
|
376
376
|
}
|
377
377
|
}
|
378
|
+
|
379
|
+
/*
|
380
|
+
For the prescription administration section in the HD Session form
|
381
|
+
use flexbox to layout items inside each prescription.
|
382
|
+
*/
|
383
|
+
.hd-drug-administration {
|
384
|
+
display: flex;
|
385
|
+
border: solid 1px $light-grey;
|
386
|
+
margin: .7rem 0;
|
387
|
+
padding: .3rem .6rem;
|
388
|
+
border-right-width: 15px;
|
389
|
+
flex-wrap: wrap;
|
390
|
+
|
391
|
+
.summary {
|
392
|
+
flex-basis: 100%;
|
393
|
+
display: flex; /* also a flex for items within it */
|
394
|
+
|
395
|
+
.hd-drug {
|
396
|
+
flex: 1;
|
397
|
+
padding-bottom: .5rem;
|
398
|
+
color: $mid-grey;
|
399
|
+
|
400
|
+
.hd-drug--name {
|
401
|
+
font-weight: bold;
|
402
|
+
}
|
403
|
+
.hd-drug--name,
|
404
|
+
.hd-drug--dose,
|
405
|
+
.hd-drug--route,
|
406
|
+
.hd-drug--prescribed-on,
|
407
|
+
.hd-drug--frequency {
|
408
|
+
display: inline-block;
|
409
|
+
padding-right: .5rem;
|
410
|
+
color: $dark-grey;
|
411
|
+
}
|
412
|
+
|
413
|
+
.hd-drug--prescriber-name {
|
414
|
+
display: inline-block;
|
415
|
+
color: $mid-grey;
|
416
|
+
}
|
417
|
+
|
418
|
+
.hd-drug--termination {
|
419
|
+
.hd-drug--termination-date {
|
420
|
+
color: $dark-grey;
|
421
|
+
display: inline-block;
|
422
|
+
color: $dark-grey;
|
423
|
+
padding: 0 .3rem;
|
424
|
+
}
|
425
|
+
}
|
426
|
+
}
|
427
|
+
|
428
|
+
/*
|
429
|
+
This is the checkox to indicate the drug was administered.
|
430
|
+
We fix its width as we never want it to shrink.
|
431
|
+
*/
|
432
|
+
.hd-drug-administered {
|
433
|
+
flex-basis: 220px;
|
434
|
+
text-align: right;
|
435
|
+
|
436
|
+
.radio {
|
437
|
+
display: inline-block !important;
|
438
|
+
}
|
439
|
+
}
|
440
|
+
}
|
441
|
+
|
442
|
+
.reason-why-not-administered {
|
443
|
+
display: none;
|
444
|
+
}
|
445
|
+
|
446
|
+
&.undecided {
|
447
|
+
.authentication {
|
448
|
+
display: block;
|
449
|
+
}
|
450
|
+
}
|
451
|
+
|
452
|
+
&.administered {
|
453
|
+
border-right-color: $nhs-red;
|
454
|
+
|
455
|
+
/* The 'status' values for the prescription-administration */
|
456
|
+
&[data-token-count='2'] {
|
457
|
+
border-right-color: $nhs-green;
|
458
|
+
}
|
459
|
+
}
|
460
|
+
|
461
|
+
&.not-administered {
|
462
|
+
.authentication {
|
463
|
+
display: none;
|
464
|
+
}
|
465
|
+
|
466
|
+
.reason-why-not-administered {
|
467
|
+
display: block;
|
468
|
+
}
|
469
|
+
}
|
470
|
+
|
471
|
+
.small-input {
|
472
|
+
max-width: inherit !important;
|
473
|
+
}
|
474
|
+
|
475
|
+
.notes {
|
476
|
+
flex: 1;
|
477
|
+
margin-right: 1rem;
|
478
|
+
|
479
|
+
textarea {
|
480
|
+
height: 5.2rem;
|
481
|
+
}
|
482
|
+
|
483
|
+
@media screen and (max-width: 768px) {
|
484
|
+
// As the screen shrinks, put the user/password boxes under the notes
|
485
|
+
flex-basis: 100%;
|
486
|
+
}
|
487
|
+
}
|
488
|
+
|
489
|
+
/* this section contains select2 inputs and pwd fields for the 2 users */
|
490
|
+
.authentication {
|
491
|
+
flex-basis: 330px;
|
492
|
+
flex-grow: 0;
|
493
|
+
|
494
|
+
// Addinng the disabled-with-faded-overlay class to authentication adds a semi transparent overlay
|
495
|
+
// that indicates the section is no receiving input ie because the drug has been marked
|
496
|
+
// as not administered.
|
497
|
+
&.disabled-with-faded-overlay {
|
498
|
+
position: relative;
|
499
|
+
}
|
500
|
+
|
501
|
+
&.disabled-with-faded-overlay:after {
|
502
|
+
content: " ";
|
503
|
+
z-index: 10;
|
504
|
+
display: block;
|
505
|
+
position: absolute;
|
506
|
+
height: 100%;
|
507
|
+
top: 0;
|
508
|
+
left: 0;
|
509
|
+
right: 0;
|
510
|
+
background: rgba(255, 255, 255, 0.5);
|
511
|
+
}
|
512
|
+
|
513
|
+
.user-and-password {
|
514
|
+
display: inline-block;
|
515
|
+
width: 50%;
|
516
|
+
padding-right: 1rem;
|
517
|
+
vertical-align: top;
|
518
|
+
|
519
|
+
.select2-container--default.select2-container--disabled .select2-selection--single {
|
520
|
+
background-color: $white;
|
521
|
+
}
|
522
|
+
|
523
|
+
.spinner {
|
524
|
+
display: none;
|
525
|
+
}
|
526
|
+
|
527
|
+
&.working {
|
528
|
+
.spinner {
|
529
|
+
display: inline-block;
|
530
|
+
}
|
531
|
+
|
532
|
+
.user-password {
|
533
|
+
background: $mid-grey;
|
534
|
+
}
|
535
|
+
|
536
|
+
}
|
537
|
+
|
538
|
+
.error.invalid-password {
|
539
|
+
display: none;
|
540
|
+
}
|
541
|
+
|
542
|
+
&.error {
|
543
|
+
small.error {
|
544
|
+
display: block;
|
545
|
+
}
|
546
|
+
}
|
547
|
+
|
548
|
+
.select2 {
|
549
|
+
// margin-bottom: 0.75rem;
|
550
|
+
}
|
551
|
+
|
552
|
+
.user-password {
|
553
|
+
margin-bottom: 0;
|
554
|
+
}
|
555
|
+
|
556
|
+
.confirmed {
|
557
|
+
display: none;
|
558
|
+
text-align: center;
|
559
|
+
|
560
|
+
i {
|
561
|
+
font-size: 1.6rem;
|
562
|
+
color: $nhs-green;
|
563
|
+
}
|
564
|
+
|
565
|
+
a {
|
566
|
+
margin-left: .4rem;
|
567
|
+
}
|
568
|
+
}
|
569
|
+
|
570
|
+
&.authorised {
|
571
|
+
.user-password {
|
572
|
+
display: none
|
573
|
+
}
|
574
|
+
|
575
|
+
.confirmed {
|
576
|
+
display: block;
|
577
|
+
}
|
578
|
+
}
|
579
|
+
}
|
580
|
+
}
|
581
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/hd/base_controller"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module HD
|
7
|
+
class PrescriptionAdministrationAuthorisationsController < BaseController
|
8
|
+
skip_after_action :verify_authorized
|
9
|
+
|
10
|
+
def create
|
11
|
+
user = User.find(auth_params[:id])
|
12
|
+
if user.valid_password?(auth_params[:password])
|
13
|
+
render status: :ok, plain: user.auth_token
|
14
|
+
else
|
15
|
+
# head :bad_request
|
16
|
+
head :unauthorized
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def auth_params
|
23
|
+
params.require(:user).permit(:id, :password)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -5,6 +5,7 @@ require "collection_presenter"
|
|
5
5
|
|
6
6
|
module Renalware
|
7
7
|
module HD
|
8
|
+
# rubocop:disable Metrics/ClassLength
|
8
9
|
class SessionsController < BaseController
|
9
10
|
include PresenterHelper
|
10
11
|
include Renalware::Concerns::Pageable
|
@@ -45,6 +46,14 @@ module Renalware
|
|
45
46
|
|
46
47
|
def edit
|
47
48
|
session = Session.for_patient(patient).find(params[:id])
|
49
|
+
session.prescription_administrations.each do |a|
|
50
|
+
if a.administrator_authorised?
|
51
|
+
a.administrator_authorisation_token = a.administered_by&.auth_token
|
52
|
+
end
|
53
|
+
if a.witness_authorised?
|
54
|
+
a.witness_authorisation_token = a.witnessed_by&.auth_token
|
55
|
+
end
|
56
|
+
end
|
48
57
|
authorize session
|
49
58
|
render :edit, locals: locals(session)
|
50
59
|
rescue Pundit::NotAuthorizedError
|
@@ -65,8 +74,7 @@ module Renalware
|
|
65
74
|
end
|
66
75
|
|
67
76
|
def save_session
|
68
|
-
command = Sessions::SaveSession.new(patient: patient,
|
69
|
-
current_user: current_user)
|
77
|
+
command = Sessions::SaveSession.new(patient: patient, current_user: current_user)
|
70
78
|
command.subscribe(self)
|
71
79
|
command.call(params: session_params,
|
72
80
|
id: params[:id],
|
@@ -124,7 +132,9 @@ module Renalware
|
|
124
132
|
:hospital_unit_id, :notes, :dialysate_id,
|
125
133
|
:signed_on_by_id, :signed_off_by_id, :type,
|
126
134
|
prescription_administrations_attributes: [
|
127
|
-
:id, :hd_session_id, :prescription_id, :administered, :notes
|
135
|
+
:id, :hd_session_id, :prescription_id, :administered, :notes,
|
136
|
+
:administered_by_id, :administrator_authorisation_token,
|
137
|
+
:witnessed_by_id, :witness_authorisation_token, :reason_id
|
128
138
|
],
|
129
139
|
document: []]
|
130
140
|
end
|
@@ -136,5 +146,6 @@ module Renalware
|
|
136
146
|
.try(:permit!)
|
137
147
|
end
|
138
148
|
end
|
149
|
+
# rubocop:enable Metrics/ClassLength
|
139
150
|
end
|
140
151
|
end
|
@@ -7,7 +7,6 @@ module Renalware
|
|
7
7
|
class MDMPatientsQuery
|
8
8
|
include ModalityScopes
|
9
9
|
include PatientPathologyScopes
|
10
|
-
MODALITY_NAMES = "HD"
|
11
10
|
DEFAULT_SEARCH_PREDICATE = "hgb_date desc"
|
12
11
|
attr_reader :params, :named_filter
|
13
12
|
|
@@ -35,7 +34,7 @@ module Renalware
|
|
35
34
|
.extending(NamedFilterScopes)
|
36
35
|
.with_current_pathology
|
37
36
|
.with_registration_statuses
|
38
|
-
.
|
37
|
+
.with_current_modality_of_class(Renalware::HD::ModalityDescription)
|
39
38
|
.public_send(named_filter.to_s)
|
40
39
|
.ransack(params)
|
41
40
|
end
|
@@ -6,14 +6,62 @@ module Renalware
|
|
6
6
|
module HD
|
7
7
|
class PrescriptionAdministration < ApplicationRecord
|
8
8
|
include Accountable
|
9
|
+
attr_accessor :administrator_authorisation_token
|
10
|
+
attr_accessor :witness_authorisation_token
|
9
11
|
|
10
12
|
# Set to true by the parent hd_session if we are not signing off at this stage
|
11
13
|
attr_accessor :skip_validation
|
12
14
|
|
13
15
|
belongs_to :hd_session, class_name: "HD::Session", touch: true
|
14
16
|
belongs_to :prescription, class_name: "Medications::Prescription"
|
17
|
+
belongs_to :administered_by, class_name: "User"
|
18
|
+
belongs_to :witnessed_by, class_name: "User"
|
19
|
+
belongs_to :reason, class_name: "PrescriptionAdministrationReason"
|
15
20
|
validates :administered, inclusion: { in: [true, false] }, unless: :skip_validation
|
16
21
|
validates :prescription, presence: true
|
22
|
+
validates :administered_by, presence: true, if: :validate_administrator_and_witness?
|
23
|
+
validates :witnessed_by, presence: true, if: :validate_administrator_and_witness?
|
24
|
+
validate :check_administrator_authorisation_token
|
25
|
+
validate :check_witness_authorisation_token
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def validate_administrator_and_witness?
|
30
|
+
return false if skip_validation || not_administered?
|
31
|
+
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def check_administrator_authorisation_token
|
36
|
+
verify_submitted_user_token(
|
37
|
+
administered_by,
|
38
|
+
administrator_authorisation_token,
|
39
|
+
:administrator_authorisation_token
|
40
|
+
)
|
41
|
+
end
|
42
|
+
|
43
|
+
def check_witness_authorisation_token
|
44
|
+
verify_submitted_user_token(
|
45
|
+
witnessed_by,
|
46
|
+
witness_authorisation_token,
|
47
|
+
:witness_authorisation_token
|
48
|
+
)
|
49
|
+
end
|
50
|
+
|
51
|
+
def verify_submitted_user_token(user, token, error_key)
|
52
|
+
return if skip_validation
|
53
|
+
return if user.blank? || not_administered?
|
54
|
+
|
55
|
+
if token.blank?
|
56
|
+
errors[error_key] << "can't be blank"
|
57
|
+
elsif user.auth_token != token
|
58
|
+
errors[error_key] << "invalid token"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def not_administered?
|
63
|
+
administered.nil? || administered == false
|
64
|
+
end
|
17
65
|
end
|
18
66
|
end
|
19
67
|
end
|
@@ -66,7 +66,10 @@ module Renalware
|
|
66
66
|
return unless session.new_record?
|
67
67
|
|
68
68
|
patient.prescriptions.to_be_administered_on_hd.map do |prescription|
|
69
|
-
session.prescription_administrations.build(
|
69
|
+
session.prescription_administrations.build(
|
70
|
+
prescription: prescription,
|
71
|
+
administered_by: user
|
72
|
+
)
|
70
73
|
end
|
71
74
|
end
|
72
75
|
|
@@ -26,6 +26,13 @@ module Renalware
|
|
26
26
|
session = find_or_build_session(id)
|
27
27
|
session = update_session_attributes(session, signing_off)
|
28
28
|
|
29
|
+
session.prescription_administrations.each do |pa|
|
30
|
+
pa.administrator_authorised =
|
31
|
+
(pa.administrator_authorisation_token == pa.administered_by&.auth_token)
|
32
|
+
pa.witness_authorised =
|
33
|
+
(pa.witness_authorisation_token == pa.witnessed_by&.auth_token)
|
34
|
+
end
|
35
|
+
|
29
36
|
if session.save
|
30
37
|
# Might be cleaner if something listened for this event and created this job there?
|
31
38
|
UpdateRollingPatientStatisticsJob.perform_later(patient) unless session.open?
|
@@ -5,7 +5,6 @@ module Renalware
|
|
5
5
|
class MDMPatientsQuery
|
6
6
|
include ModalityScopes
|
7
7
|
include PatientPathologyScopes
|
8
|
-
MODALITY_NAMES = "PD"
|
9
8
|
DEFAULT_SEARCH_PREDICATE = "hgb_date desc"
|
10
9
|
attr_reader :q, :relation, :named_filter
|
11
10
|
|
@@ -28,7 +27,7 @@ module Renalware
|
|
28
27
|
.extending(ModalityScopes)
|
29
28
|
.extending(PatientPathologyScopes)
|
30
29
|
.extending(NamedFilterScopes)
|
31
|
-
.
|
30
|
+
.with_current_modality_of_class(Renalware::PD::ModalityDescription)
|
32
31
|
.with_current_pathology
|
33
32
|
.with_registration_statuses
|
34
33
|
.left_outer_joins(:current_observation_set)
|
@@ -8,7 +8,6 @@ module Renalware
|
|
8
8
|
module PreflightChecks
|
9
9
|
class DeathsQuery
|
10
10
|
include ModalityScopes
|
11
|
-
MODALITY_NAMES = %w(Death).freeze
|
12
11
|
|
13
12
|
attr_reader :relation, :query_params
|
14
13
|
|
@@ -27,7 +26,7 @@ module Renalware
|
|
27
26
|
.result
|
28
27
|
.extending(ModalityScopes)
|
29
28
|
.preload(current_modality: [:description])
|
30
|
-
.
|
29
|
+
.with_current_modality_of_class(Renalware::Deaths::ModalityDescription)
|
31
30
|
.where("patients.first_cause_id is NULL AND renal_profiles.esrf_on IS NOT NULL")
|
32
31
|
end
|
33
32
|
|
@@ -9,7 +9,6 @@ module Renalware
|
|
9
9
|
class MDMPatientsQuery
|
10
10
|
include ModalityScopes
|
11
11
|
include PatientPathologyScopes
|
12
|
-
MODALITY_NAMES = "Transplant"
|
13
12
|
DEFAULT_SEARCH_PREDICATE = "hgb_date DESC"
|
14
13
|
attr_reader :q, :relation, :named_filter
|
15
14
|
|
@@ -31,7 +30,7 @@ module Renalware
|
|
31
30
|
.extending(ModalityScopes)
|
32
31
|
.extending(PatientPathologyScopes)
|
33
32
|
.extending(NamedFilterScopes)
|
34
|
-
.
|
33
|
+
.with_current_modality_of_class(Transplants::RecipientModalityDescription)
|
35
34
|
.with_current_pathology
|
36
35
|
.left_outer_joins(:current_observation_set)
|
37
36
|
.public_send(named_filter.to_s)
|
@@ -75,6 +75,19 @@ module Renalware
|
|
75
75
|
end
|
76
76
|
end
|
77
77
|
|
78
|
+
# Create a sha that can be saved in another model to indicate a user has authenticated
|
79
|
+
# (or perhaps more correctly, authorised) an action - e.g. in HD Session form where a nurse
|
80
|
+
# and witness both enter their credentials against a prescription administered on HD.
|
81
|
+
# The idea is that we can check the token belongs to the user buy regenerating the token at any
|
82
|
+
# time and checking it still matches. Unlike Devise.friendly_token, we can always regenerate
|
83
|
+
# the same token here for any user as it is salted with the same secret. This secret is not
|
84
|
+
# stored git for staging and production environments.
|
85
|
+
def auth_token
|
86
|
+
digest = OpenSSL::Digest.new("sha256")
|
87
|
+
key = Rails.application.secrets.secret_key_base
|
88
|
+
OpenSSL::HMAC.hexdigest(digest, key, id.to_s)
|
89
|
+
end
|
90
|
+
|
78
91
|
private
|
79
92
|
|
80
93
|
def build_authentication_token
|
@@ -152,6 +152,11 @@ module Renalware
|
|
152
152
|
return parts.last if parts.length > 1
|
153
153
|
end
|
154
154
|
|
155
|
+
# Ensure drug administrations are always in the same order.
|
156
|
+
def prescription_administrations
|
157
|
+
__getobj__.prescription_administrations.order(created_at: :asc)
|
158
|
+
end
|
159
|
+
|
155
160
|
protected
|
156
161
|
|
157
162
|
attr_reader :session, :view_context
|
@@ -9,8 +9,7 @@ xml.Observation do
|
|
9
9
|
xml.ObservationTime visit.datetime
|
10
10
|
|
11
11
|
xml.ObservationCode do
|
12
|
-
|
13
|
-
xml.CodingStandard "PV"
|
12
|
+
xml.CodingStandard "UKRR"
|
14
13
|
xml.Code I18n.t("loinc.#{i18n_key}.code")
|
15
14
|
xml.Description I18n.t("loinc.#{i18n_key}.description")
|
16
15
|
end
|
@@ -124,18 +124,9 @@ ruby:
|
|
124
124
|
= fcm.input :subs_goal, wrapper: :horizontal_tiny
|
125
125
|
= fcm.input :subs_volume, wrapper: :horizontal_tiny
|
126
126
|
|
127
|
-
= render
|
128
|
-
|
129
|
-
|
130
|
-
= f.simple_fields_for :prescription_administrations,
|
131
|
-
f.object.prescription_administrations do |fpa|
|
132
|
-
|
133
|
-
- presenter = Renalware::Medications::PrescriptionPresenter.new(fpa.object.prescription)
|
134
|
-
b= "#{presenter.drug_name}"
|
135
|
-
span= "#{presenter.dose} #{presenter.frequency}"
|
136
|
-
= fpa.input :prescription_id, as: :hidden
|
137
|
-
= fpa.input :administered, as: :inline_radio_buttons
|
138
|
-
= fpa.input :notes, input_html: { class: "small-input" }
|
127
|
+
= render "renalware/hd/sessions/form/drugs_to_be_administered",
|
128
|
+
f: f,
|
129
|
+
prescription_administrations: f.object.prescription_administrations
|
139
130
|
|
140
131
|
= render layout: "renalware/shared/fieldset",
|
141
132
|
locals: { legend: "Notes/Complications", name: "complications" } do
|
@@ -1,19 +1,20 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
= f.button :submit,
|
7
|
-
as: :ssdsdsd,
|
8
|
-
name: "signoff",
|
9
|
-
value: t(".signoff"),
|
10
|
-
data: { disable_with: t(".signoff_disable_with") }
|
11
|
-
- if policy(session).destroy?
|
1
|
+
.hd-session-form-actions
|
2
|
+
= f.button :submit,
|
3
|
+
value: t(".save"),
|
4
|
+
data: { disable_with: t(".save_disable_with") },
|
5
|
+
class: "button secondary"
|
12
6
|
|
|
13
|
-
=
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
7
|
+
= f.button :submit,
|
8
|
+
as: :ssdsdsd,
|
9
|
+
name: "signoff",
|
10
|
+
value: t(".signoff"),
|
11
|
+
data: { disable_with: t(".signoff_disable_with") }
|
12
|
+
- if policy(session).destroy?
|
13
|
+
|
|
14
|
+
= link_to("Delete", patient_hd_session_path(patient, session),
|
15
|
+
data: { confirm: t(".delete_confirmation") },
|
16
|
+
method: :delete,
|
17
|
+
class: "button alert")
|
18
|
+
|
|
19
|
+
span= " or "
|
20
|
+
= link_to "cancel", back_path
|
@@ -0,0 +1,84 @@
|
|
1
|
+
= render layout: "renalware/shared/fieldset",
|
2
|
+
locals: { legend: "HD Drugs", name: "hd_prescriptions" } do
|
3
|
+
|
4
|
+
.hd-drug-administrations
|
5
|
+
= f.simple_fields_for :prescription_administrations,
|
6
|
+
prescription_administrations do |fpa|
|
7
|
+
|
8
|
+
- prescription = Renalware::Medications::PrescriptionPresenter.new(fpa.object.prescription)
|
9
|
+
- administration = fpa.object
|
10
|
+
|
11
|
+
/ There are three possible states for a drug administration:
|
12
|
+
/ 1. administration.administered == nil -> no decision has been made
|
13
|
+
/ 2. administration.administered == false -> drug was not administered
|
14
|
+
/ 3. administration.administered == true -> drug was administered
|
15
|
+
ruby:
|
16
|
+
administration_klass = case administration.administered
|
17
|
+
when true then "administered"
|
18
|
+
when false then "not-administered"
|
19
|
+
else "undecided"
|
20
|
+
end
|
21
|
+
# administration_klass = "not-administered" unless administration.administered?
|
22
|
+
#- administration_klass = "undecided" if administration.administered.nil?
|
23
|
+
.hd-drug-administration(
|
24
|
+
data-token-count="#{'2' if administration.administrator_authorised? && administration.witness_authorised?}"
|
25
|
+
class="#{administration_klass}"
|
26
|
+
)
|
27
|
+
.summary
|
28
|
+
.hd-drug
|
29
|
+
.hd-drug--name= prescription.drug_name
|
30
|
+
.hd-drug--dose= prescription.dose
|
31
|
+
.hd-drug--route= prescription.route_code
|
32
|
+
.hd-drug--frequency= prescription.frequency
|
33
|
+
.hd-drug--prescribed-on= l(prescription.prescribed_on)
|
34
|
+
.hd-drug--prescriber-name= prescription.updated_by
|
35
|
+
|
36
|
+
- if prescription.terminated_on.present?
|
37
|
+
.hd-drug--termination
|
38
|
+
| Terminates
|
39
|
+
.hd-drug--termination-date= l(prescription.terminated_on)
|
40
|
+
|
41
|
+
.hd-drug-administered
|
42
|
+
= fpa.input :administered, as: :inline_radio_buttons
|
43
|
+
|
44
|
+
= fpa.input :prescription_id, as: :hidden
|
45
|
+
|
46
|
+
.notes
|
47
|
+
= fpa.label :notes
|
48
|
+
= fpa.input :notes, label: false, wrapper: :zilch, input_html: { rows: 2 }
|
49
|
+
|
50
|
+
.reason-why-not-administered
|
51
|
+
= fpa.label :reason_id
|
52
|
+
= fpa.association :reason, wrapper: :zilch
|
53
|
+
|
54
|
+
.authentication(
|
55
|
+
class="#{'disabled-with-faded-overlay' unless administration.administered?}"
|
56
|
+
data-authentication-url=renalware.hd_prescription_administration_authorisations_path
|
57
|
+
)
|
58
|
+
/ Output username and password fields for administrator and witness
|
59
|
+
- { administrator: :administered, witness: :witnessed }.each do |user_role, prefix|
|
60
|
+
|
61
|
+
- authorised = administration.public_send(:"#{user_role}_authorised?")
|
62
|
+
- token_symbol = :"#{user_role}_authorisation_token"
|
63
|
+
.user-and-password(
|
64
|
+
class="user-and-password--#{user_role} #{'authorised' if authorised} #{'error' if fpa.object.errors[token_symbol].any?}"
|
65
|
+
)
|
66
|
+
= fpa.hidden_field token_symbol, class: "authentication-token"
|
67
|
+
= fpa.label :"#{prefix}_by"
|
68
|
+
= fpa.association :"#{prefix}_by",
|
69
|
+
as: :user_picker,
|
70
|
+
collection: Renalware::User.ordered,
|
71
|
+
wrapper: :zilch,
|
72
|
+
label: false,
|
73
|
+
input_html: { class: "authentication-user-id" }
|
74
|
+
|
75
|
+
/ Password is only visible as long as the user has not been authenticated
|
76
|
+
= password_field_tag :"#{prefix}_by_password",
|
77
|
+
"",
|
78
|
+
placeholder: "Password",
|
79
|
+
class: "user-password",
|
80
|
+
autocomplete: :off
|
81
|
+
small.error.invalid-password Invalid password
|
82
|
+
.confirmed
|
83
|
+
i.fas.fa-check-circle
|
84
|
+
= link_to "Clear", "#", class: "user-and-password--clear"
|
@@ -19,14 +19,6 @@ article.status-history.secondary
|
|
19
19
|
- registration.statuses.reversed.each do |status|
|
20
20
|
tr
|
21
21
|
td
|
22
|
-
= link_to "Edit",
|
23
|
-
edit_patient_transplants_registration_status_path(patient, status)
|
24
|
-
= pipe_separator
|
25
|
-
= link_to "Delete",
|
26
|
-
patient_transplants_registration_status_path(patient, status),
|
27
|
-
method: :delete,
|
28
|
-
data: { confirm: I18n.t("prompts.confirm_delete") }
|
29
|
-
= pipe_separator
|
30
22
|
= link_to("Toggle",
|
31
23
|
"#status-quick-preview-#{status.id}",
|
32
24
|
data: { behaviour: "toggler" })
|
@@ -91,6 +91,24 @@ SimpleForm.setup do |config|
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
|
94
|
+
config.wrappers :zilch,
|
95
|
+
tag: "div",
|
96
|
+
hint_class: :field_with_hint,
|
97
|
+
error_class: :error do |b|
|
98
|
+
b.use :html5
|
99
|
+
b.use :placeholder
|
100
|
+
b.optional :maxlength
|
101
|
+
b.optional :pattern
|
102
|
+
b.optional :min_max
|
103
|
+
b.optional :readonly
|
104
|
+
|
105
|
+
b.wrapper :right_input_wrapper, tag: :div, class: "" do |ba|
|
106
|
+
ba.use :input
|
107
|
+
ba.use :error, wrap_with: { tag: :small, class: ["error", "small-input"] }
|
108
|
+
ba.use :hint, wrap_with: { tag: :span, class: ["hint", "small-input"] }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
94
112
|
config.wrappers :horizontal_medium,
|
95
113
|
tag: "div",
|
96
114
|
class: "row",
|
@@ -3,6 +3,11 @@ en:
|
|
3
3
|
attributes:
|
4
4
|
renalware/hd/prescription_administration:
|
5
5
|
administered: Administered
|
6
|
+
administered_by: Nurse
|
7
|
+
witnessed_by: Witness
|
8
|
+
witnessed_by_password: Password
|
9
|
+
administered_by_password: Password
|
10
|
+
reason_id: Reason not administered
|
6
11
|
errors:
|
7
12
|
models:
|
8
13
|
renalware/hd/prescription_administration:
|
data/config/routes/hd.rb
CHANGED
@@ -26,6 +26,7 @@ namespace :hd do
|
|
26
26
|
get "patients_dialysing_at_hospital" => "patients#dialysing_at_hospital"
|
27
27
|
end
|
28
28
|
|
29
|
+
resources :prescription_administration_authorisations, only: :create
|
29
30
|
resources :transmission_logs, only: [:show, :index]
|
30
31
|
resources :cannulation_types, except: :show
|
31
32
|
resources :dialysers, except: :show
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class AddAuthenticationToHDPrescriptionAdministrations < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
within_renalware_schema do
|
4
|
+
add_reference :hd_prescription_administrations,
|
5
|
+
:administered_by,
|
6
|
+
foreign_key: { to_table: :users },
|
7
|
+
index: true,
|
8
|
+
null: true
|
9
|
+
add_reference :hd_prescription_administrations,
|
10
|
+
:witnessed_by,
|
11
|
+
foreign_key: { to_table: :users },
|
12
|
+
index: true,
|
13
|
+
null: true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class AddTokensToHDPrescriptionAdministrations < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
within_renalware_schema do
|
4
|
+
# add_column :hd_prescription_administrations, :administrator_authorisation_token, :string
|
5
|
+
# add_column :hd_prescription_administrations, :witness_authorisation_token, :string
|
6
|
+
add_column(
|
7
|
+
:hd_prescription_administrations,
|
8
|
+
:administrator_authorised,
|
9
|
+
:boolean,
|
10
|
+
default: false,
|
11
|
+
null: false
|
12
|
+
)
|
13
|
+
add_column(
|
14
|
+
:hd_prescription_administrations,
|
15
|
+
:witness_authorised,
|
16
|
+
:boolean,
|
17
|
+
default: false,
|
18
|
+
null: false
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateHDPrescriptionAdministrationReasons < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
within_renalware_schema do
|
4
|
+
create_table :hd_prescription_administration_reasons do |t|
|
5
|
+
t.string :name, null: false, index: { unique: true }
|
6
|
+
t.timestamps null: false
|
7
|
+
end
|
8
|
+
|
9
|
+
add_reference(
|
10
|
+
:hd_prescription_administrations,
|
11
|
+
:reason,
|
12
|
+
foreign_key: { to_table: :hd_prescription_administration_reasons },
|
13
|
+
index: true
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
log "Adding HD Prescription Administration Reasons" do
|
5
|
+
[
|
6
|
+
"No supply available",
|
7
|
+
"Target HB exceeded",
|
8
|
+
"Patient refused",
|
9
|
+
"Patient unwell",
|
10
|
+
"Patient received blood transfusion",
|
11
|
+
"Wrong dose / route"
|
12
|
+
].each do |reason|
|
13
|
+
HD::PrescriptionAdministrationReason.find_or_create_by!(name: reason)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/renalware/version.rb
CHANGED
@@ -6,7 +6,12 @@ FactoryBot.define do
|
|
6
6
|
name { "Live Donor" }
|
7
7
|
end
|
8
8
|
|
9
|
-
factory
|
10
|
-
|
9
|
+
factory(
|
10
|
+
:transplant_modality_description,
|
11
|
+
class: "Renalware::Transplants::RecipientModalityDescription"
|
12
|
+
) do
|
13
|
+
initialize_with do
|
14
|
+
Renalware::Transplants::RecipientModalityDescription.find_or_create_by(name: "Transplant")
|
15
|
+
end
|
11
16
|
end
|
12
17
|
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.106
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Airslie
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_type
|
@@ -999,6 +999,7 @@ files:
|
|
999
999
|
- app/assets/javascripts/renalware/events.js
|
1000
1000
|
- app/assets/javascripts/renalware/forms.js
|
1001
1001
|
- app/assets/javascripts/renalware/full_screen.js
|
1002
|
+
- app/assets/javascripts/renalware/hd.js
|
1002
1003
|
- app/assets/javascripts/renalware/iframe.js
|
1003
1004
|
- app/assets/javascripts/renalware/keyboard_shortcuts.js
|
1004
1005
|
- app/assets/javascripts/renalware/layout.js
|
@@ -1152,6 +1153,7 @@ files:
|
|
1152
1153
|
- app/controllers/renalware/hd/ongoing_sessions_controller.rb
|
1153
1154
|
- app/controllers/renalware/hd/patients_controller.rb
|
1154
1155
|
- app/controllers/renalware/hd/preference_sets_controller.rb
|
1156
|
+
- app/controllers/renalware/hd/prescription_administration_authorisations_controller.rb
|
1155
1157
|
- app/controllers/renalware/hd/protocols_controller.rb
|
1156
1158
|
- app/controllers/renalware/hd/sessions_controller.rb
|
1157
1159
|
- app/controllers/renalware/hd/stations_controller.rb
|
@@ -1497,6 +1499,7 @@ files:
|
|
1497
1499
|
- app/models/renalware/hd/patients_with_unmet_preferences_query.rb
|
1498
1500
|
- app/models/renalware/hd/preference_set.rb
|
1499
1501
|
- app/models/renalware/hd/prescription_administration.rb
|
1502
|
+
- app/models/renalware/hd/prescription_administration_reason.rb
|
1500
1503
|
- app/models/renalware/hd/profile.rb
|
1501
1504
|
- app/models/renalware/hd/profile_for_modality.rb
|
1502
1505
|
- app/models/renalware/hd/profiles_in_date_range_query.rb
|
@@ -2357,6 +2360,7 @@ files:
|
|
2357
2360
|
- app/views/renalware/hd/sessions/dna/_row.html.slim
|
2358
2361
|
- app/views/renalware/hd/sessions/dna/_show.html.slim
|
2359
2362
|
- app/views/renalware/hd/sessions/edit.html.slim
|
2363
|
+
- app/views/renalware/hd/sessions/form/_drugs_to_be_administered.html.slim
|
2360
2364
|
- app/views/renalware/hd/sessions/index.html.slim
|
2361
2365
|
- app/views/renalware/hd/sessions/new.html.slim
|
2362
2366
|
- app/views/renalware/hd/sessions/open/_form.html.slim
|
@@ -3534,9 +3538,12 @@ files:
|
|
3534
3538
|
- db/migrate/20190611152859_add_fields_to_transplant_recipient_workup.rb
|
3535
3539
|
- db/migrate/20190612124015_create_transplant_rejection_episodes.rb
|
3536
3540
|
- db/migrate/20190617121528_create_transplant_rejection_treatments.rb
|
3541
|
+
- db/migrate/20190624130020_add_authentication_to_hd_prescription_administrations.rb
|
3542
|
+
- db/migrate/20190627141751_add_tokens_to_hd_prescription_administrations.rb
|
3537
3543
|
- db/migrate/20190705083727_alter_ukrdc_treatments.rb
|
3538
3544
|
- db/migrate/20190705105921_create_hd_profile_for_modalites.rb
|
3539
3545
|
- db/migrate/20190709101610_create_pd_regime_for_modalities.rb
|
3546
|
+
- db/migrate/20190716125837_create_hd_prescription_administration_reasons.rb
|
3540
3547
|
- db/migrate/20190718091430_add_code_to_modality_descriptions.rb
|
3541
3548
|
- db/migrate/20190718095851_add_discharge_reason_code_to_ukrdc_treatments.rb
|
3542
3549
|
- db/migrate/20190722145936_change_type_of_patients_ukrdc_external_id.rb
|
@@ -3572,6 +3579,7 @@ files:
|
|
3572
3579
|
- db/seeds/default/hd/cannulation_types.rb
|
3573
3580
|
- db/seeds/default/hd/dialysers.csv
|
3574
3581
|
- db/seeds/default/hd/dialysers.rb
|
3582
|
+
- db/seeds/default/hd/prescription_administration_reasons.rb
|
3575
3583
|
- db/seeds/default/hd/seeds.rb
|
3576
3584
|
- db/seeds/default/housekeeping.rb
|
3577
3585
|
- db/seeds/default/letters/seeds.rb
|