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