renalware-core 2.0.137 → 2.0.138

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/renalware/icons/home.svg +1 -0
  3. data/app/assets/images/renalware/icons/settings.svg +1 -0
  4. data/app/assets/javascripts/renalware/components/hd.js +0 -109
  5. data/app/assets/javascripts/renalware/components/toggler.js +0 -29
  6. data/app/assets/javascripts/renalware/core.js.erb +5 -1
  7. data/app/assets/javascripts/renalware/rollup_compiled.js +3888 -0
  8. data/app/assets/stylesheets/renalware/modules/_hd.scss +40 -17
  9. data/app/assets/stylesheets/renalware/partials/_dashboards.scss +1 -1
  10. data/app/assets/stylesheets/renalware/partials/_modal_window.scss +1 -0
  11. data/app/assets/stylesheets/renalware/partials/_navigation.scss +45 -2
  12. data/app/assets/stylesheets/renalware/partials/_pagination.scss +21 -0
  13. data/app/assets/stylesheets/renalware/partials/_tables.scss +9 -0
  14. data/app/assets/stylesheets/renalware/protocol_pdf.scss +45 -6
  15. data/app/components/renalware/application_component.rb +1 -1
  16. data/app/components/renalware/hd/administer_prescription_dropdown_component.html.slim +22 -0
  17. data/app/components/renalware/hd/administer_prescription_dropdown_component.rb +22 -0
  18. data/app/components/renalware/hd/prescription_last_administration_component.html.slim +6 -0
  19. data/app/components/renalware/hd/prescription_last_administration_component.rb +19 -0
  20. data/app/components/renalware/letters/letters_in_progress_component.html.slim +1 -1
  21. data/app/components/renalware/system/admin_menu_component.html.slim +25 -0
  22. data/app/components/renalware/system/admin_menu_component.rb +56 -0
  23. data/app/components/renalware/system/users_awaiting_approval_component.html.slim +6 -0
  24. data/app/components/renalware/system/users_awaiting_approval_component.rb +25 -0
  25. data/app/controllers/renalware/admin/dashboards_controller.rb +9 -0
  26. data/app/controllers/renalware/hd/base_controller.rb +4 -0
  27. data/app/controllers/renalware/hd/prescription_administrations_controller.rb +87 -0
  28. data/app/controllers/renalware/hd/sessions_controller.rb +6 -44
  29. data/app/controllers/renalware/hd/transmission_logs_controller.rb +7 -6
  30. data/app/controllers/renalware/hd/witnesses_controller.rb +62 -0
  31. data/app/helpers/renalware/application_helper.rb +1 -0
  32. data/app/helpers/renalware/layout_helper.rb +12 -0
  33. data/app/helpers/renalware/toggle_helper.rb +13 -4
  34. data/app/javascript/renalware/controllers/another_test_controller.js +8 -0
  35. data/app/javascript/renalware/controllers/hd/prescription_administration_controller.js +22 -0
  36. data/app/javascript/renalware/controllers/test_controller.js +8 -0
  37. data/app/javascript/renalware/controllers/toggle_controller.js +36 -0
  38. data/app/javascript/renalware/index.js +25 -0
  39. data/app/models/renalware/hd/patient.rb +1 -0
  40. data/app/models/renalware/hd/prescription_administration.rb +57 -33
  41. data/app/models/renalware/hd/prescription_last_administration_query.rb +29 -0
  42. data/app/models/renalware/hd/sessions/save_session.rb +1 -25
  43. data/app/models/renalware/hd/witness_form.rb +31 -0
  44. data/app/policies/renalware/hd/prescription_administration_policy.rb +8 -0
  45. data/app/presenters/renalware/admin/users/{summary_part.rb → summary_part.rb.dead} +0 -0
  46. data/app/presenters/renalware/hd/dashboard_presenter.rb +16 -7
  47. data/app/views/renalware/accesses/plans/_details.html.slim +1 -1
  48. data/app/views/renalware/admin/cache/show.html.slim +1 -1
  49. data/app/views/renalware/admin/dashboards/show.html.slim +4 -0
  50. data/app/views/renalware/admin/users/{_summary_part.html.slim → _summary_part.html.slim.dead} +1 -1
  51. data/app/views/renalware/admin/users/edit.html.slim +1 -1
  52. data/app/views/renalware/admin/users/index.html.slim +1 -1
  53. data/app/views/renalware/admissions/_summary_part.html.slim +5 -4
  54. data/app/views/renalware/admissions/consults/_summary_part.html.slim +7 -7
  55. data/app/views/renalware/dashboard/dashboards/_content.html.slim +5 -5
  56. data/app/views/renalware/drugs/drugs/edit.html.slim +2 -2
  57. data/app/views/renalware/drugs/drugs/index.html.slim +1 -1
  58. data/app/views/renalware/drugs/drugs/new.html.slim +1 -1
  59. data/app/views/renalware/events/types/edit.html.slim +1 -1
  60. data/app/views/renalware/events/types/index.html.slim +1 -1
  61. data/app/views/renalware/events/types/new.html.slim +1 -1
  62. data/app/views/renalware/hd/cannulation_types/edit.html.slim +1 -1
  63. data/app/views/renalware/hd/cannulation_types/index.html.slim +5 -5
  64. data/app/views/renalware/hd/cannulation_types/new.html.slim +1 -1
  65. data/app/views/renalware/hd/dashboards/_page_actions.html.slim +4 -1
  66. data/app/views/renalware/hd/dashboards/show.html.slim +1 -0
  67. data/app/views/renalware/hd/dialysates/edit.html.slim +1 -1
  68. data/app/views/renalware/hd/dialysates/index.html.slim +1 -1
  69. data/app/views/renalware/hd/dialysates/new.html.slim +1 -1
  70. data/app/views/renalware/hd/dialysers/edit.html.slim +1 -1
  71. data/app/views/renalware/hd/dialysers/index.html.slim +4 -5
  72. data/app/views/renalware/hd/dialysers/new.html.slim +1 -1
  73. data/app/views/renalware/hd/prescription_administrations/_form.html.slim +96 -0
  74. data/app/views/renalware/hd/prescription_administrations/_row.html.slim +25 -0
  75. data/app/views/renalware/hd/prescription_administrations/_table.html.slim +8 -0
  76. data/app/views/renalware/hd/prescription_administrations/_thead.html.slim +11 -0
  77. data/app/views/renalware/hd/prescription_administrations/create.js.erb +4 -0
  78. data/app/views/renalware/hd/prescription_administrations/edit.html.slim +5 -0
  79. data/app/views/renalware/hd/prescription_administrations/edit.js.erb +11 -0
  80. data/app/views/renalware/hd/prescription_administrations/index.html.slim +3 -0
  81. data/app/views/renalware/hd/prescription_administrations/new.html.slim +3 -0
  82. data/app/views/renalware/hd/prescription_administrations/new.js.erb +5 -0
  83. data/app/views/renalware/hd/protocols/_allergies.html.slim +3 -0
  84. data/app/views/renalware/hd/protocols/_latest_dry_weight.html.slim +3 -2
  85. data/app/views/renalware/hd/protocols/_prescriptions.html.slim +15 -7
  86. data/app/views/renalware/hd/protocols/_profile.html.slim +12 -12
  87. data/app/views/renalware/hd/protocols/_protocol.pdf.slim +2 -3
  88. data/app/views/renalware/hd/sessions/_form.html.slim +2 -6
  89. data/app/views/renalware/hd/sessions/_index_tabs.html.slim +11 -0
  90. data/app/views/renalware/hd/sessions/_list.html.slim +21 -1
  91. data/app/views/renalware/hd/sessions/_table.html.slim +1 -18
  92. data/app/views/renalware/hd/sessions/closed/_form.html.slim +1 -2
  93. data/app/views/renalware/hd/sessions/edit.html.slim +1 -2
  94. data/app/views/renalware/hd/sessions/new.html.slim +1 -2
  95. data/app/views/renalware/hd/sessions/open/_form.html.slim +1 -2
  96. data/app/views/renalware/hd/transmission_logs/index.html.slim +2 -2
  97. data/app/views/renalware/hd/witnesses/_form.html.slim +49 -0
  98. data/app/views/renalware/hd/witnesses/edit.html.slim +1 -0
  99. data/app/views/renalware/hd/witnesses/edit.js.erb +3 -0
  100. data/app/views/renalware/hd/witnesses/update.js.erb +4 -0
  101. data/app/views/renalware/layouts/_admin.html.slim +28 -0
  102. data/app/views/renalware/layouts/_patient.html.slim +1 -1
  103. data/app/views/renalware/letters/batches/index.html.slim +1 -1
  104. data/app/views/renalware/letters/letters/_letter.html.slim +1 -1
  105. data/app/views/renalware/modalities/descriptions/edit.html.slim +1 -1
  106. data/app/views/renalware/modalities/descriptions/index.html.slim +1 -1
  107. data/app/views/renalware/modalities/descriptions/new.html.slim +1 -1
  108. data/app/views/renalware/navigation/_admin.html.slim +1 -1
  109. data/app/views/renalware/navigation/_menu.html.slim +7 -6
  110. data/app/views/renalware/navigation/_user.html.slim +3 -4
  111. data/app/views/renalware/pathology/observation_requests/_filters.html.slim +1 -1
  112. data/app/views/renalware/pathology/requests/requests/index.html.slim +1 -1
  113. data/app/views/renalware/pathology/requests/rules/index.html.slim +1 -1
  114. data/app/views/renalware/patients/_layout.html.slim +1 -1
  115. data/app/views/renalware/patients/_summary_part.html.slim +1 -1
  116. data/app/views/renalware/patients/primary_care_physicians/edit.html.slim +1 -1
  117. data/app/views/renalware/patients/primary_care_physicians/index.html.slim +3 -5
  118. data/app/views/renalware/patients/primary_care_physicians/new.html.slim +1 -1
  119. data/app/views/renalware/pd/bag_types/edit.html.slim +1 -1
  120. data/app/views/renalware/pd/bag_types/index.html.slim +1 -1
  121. data/app/views/renalware/pd/bag_types/new.html.slim +1 -1
  122. data/app/views/renalware/problems/problems/_summary_part.html.slim +1 -1
  123. data/app/views/renalware/research/study_participants/index.html.slim +2 -3
  124. data/app/views/renalware/surveys/_pos_s_summary_part.html.slim +2 -1
  125. data/app/views/renalware/system/email_templates/index.html.slim +5 -1
  126. data/app/views/renalware/system/messages/edit.html.slim +1 -1
  127. data/app/views/renalware/system/messages/index.html.slim +1 -1
  128. data/app/views/renalware/system/messages/new.html.slim +1 -1
  129. data/app/views/renalware/system/user_feedback/edit.html.slim +1 -1
  130. data/app/views/renalware/system/user_feedback/index.html.slim +1 -1
  131. data/app/views/renalware/transplants/mdm/_bottom.html.slim +1 -1
  132. data/config/initializers/pagy.rb +9 -0
  133. data/config/locales/renalware/hd/dashboards.en.yml +1 -0
  134. data/config/locales/renalware/hd/session.en.yml +2 -1
  135. data/config/routes/admin.rb +1 -0
  136. data/config/routes/hd.rb +9 -0
  137. data/db/migrate/20190627141751_add_tokens_to_hd_prescription_administrations.rb +0 -2
  138. data/db/migrate/20200204153231_alter_hd_prescription_administrations.rb +18 -0
  139. data/db/seeds/default/accesses/access_pd_catheter_insertion_techniques.rb +0 -1
  140. data/db/seeds/default/accesses/access_plan_types.rb +0 -1
  141. data/db/seeds/default/accesses/access_sites.rb +0 -1
  142. data/db/seeds/default/clinics/clinics.rb +0 -1
  143. data/db/seeds/default/events/event_types.rb +0 -1
  144. data/db/seeds/default/hd/cannulation_types.rb +0 -1
  145. data/db/seeds/default/hd/dialysers.rb +0 -1
  146. data/db/seeds/default/modalities/reasons.rb +19 -19
  147. data/db/seeds/default/pathology/measurement_units.rb +0 -1
  148. data/db/seeds/default/patients/patients_ethnicities.rb +0 -1
  149. data/db/seeds/default/patients/patients_languages.rb +1 -0
  150. data/db/seeds/default/patients/patients_religions.rb +0 -1
  151. data/db/seeds/default/pd/bag_types.rb +0 -1
  152. data/db/seeds/default/pd/organisms.rb +0 -1
  153. data/db/seeds/default/pd/systems.rb +0 -1
  154. data/db/seeds/default/pd/training_sites.rb +0 -1
  155. data/db/seeds/default/pd/training_types.rb +0 -1
  156. data/db/seeds/default/practices/practices.rb +2 -2
  157. data/db/seeds/default/practices/primary_care_physicians.rb +1 -2
  158. data/db/seeds/default/renal/prd_descriptions.rb +1 -0
  159. data/db/seeds/default/system/roles.rb +1 -1
  160. data/lib/renalware/engine.rb +1 -0
  161. data/lib/renalware/version.rb +1 -1
  162. data/spec/factories/hd/prescription_administrations.rb +17 -0
  163. data/spec/support/factory_bot.rb +2 -0
  164. data/spec/support/pages/hd/prescription_administration_dialog.rb +132 -0
  165. metadata +62 -12
  166. data/app/assets/javascripts/renalware/components/bla.es6 +0 -1
  167. data/app/controllers/renalware/hd/prescription_administration_authorisations_controller.rb +0 -27
  168. data/app/javascript/controllers/clipboard_controller.js.dead +0 -16
  169. data/app/views/renalware/hd/sessions/_administered_drugs_row.html.slim +0 -27
  170. data/app/views/renalware/hd/sessions/_administered_drugs_thead.html.slim +0 -11
  171. data/app/views/renalware/hd/sessions/_prescription_administrations.html.slim +0 -20
  172. data/app/views/renalware/hd/sessions/closed/_administered_drugs_row.html.slim +0 -3
  173. data/app/views/renalware/hd/sessions/form/_drugs_to_be_administered.html.slim +0 -84
@@ -0,0 +1,8 @@
1
+ import { Controller } from "stimulus"
2
+
3
+ // A test controller to establish that rollup + stimulus + babel are working
4
+ export default class extends Controller {
5
+ connect() {
6
+ this.element.textContent = "AnotherTestController connected"
7
+ }
8
+ }
@@ -0,0 +1,22 @@
1
+ import { Controller } from "stimulus"
2
+ const $ = window.$
3
+
4
+ export default class extends Controller {
5
+ static targets = ["container","radio"]
6
+
7
+ connect() {
8
+ window.initDatepickersIn(".hd-drug-administration")
9
+ }
10
+
11
+ toggleAdministered() {
12
+ var checked = event.target.value == "true"
13
+ this.containerTarget.classList.toggle("administered", checked)
14
+ this.containerTarget.classList.toggle("not-administered", !checked)
15
+ this.containerTarget.classList.remove("undecided")
16
+ // The rest of this actions are using jQuery for now.
17
+ $(".authentication", this.containerTarget).toggle(checked)
18
+ $(".authentication", this.containerTarget).toggleClass("disabled-with-faded-overlay", !checked)
19
+ $(".reason-why-not-administered", this.containerTarget).toggle(!checked)
20
+ $("#btn_save_and_witness_later").toggle(checked)
21
+ }
22
+ }
@@ -0,0 +1,8 @@
1
+ import { Controller } from "stimulus"
2
+
3
+ // A test controller to establish that rollup + stimulus + babel are working
4
+ export default class extends Controller {
5
+ connect() {
6
+ this.element.textContent = "TestController connected."
7
+ }
8
+ }
@@ -0,0 +1,36 @@
1
+ const $ = window.$
2
+ import { Controller } from "stimulus"
3
+
4
+ // Used when a table has toggleable rows (initially hidden rows that can be toggled open
5
+ // to see e.g. notes or extended details) and each master row and its toggleable sibling are
6
+ // nested in a tbody (this is valid HTML) - ie there are probably two trs per tbody, and the last
7
+ // one is toggleable. If you need anyting more complex you'll need to clone or adapt this
8
+ // controller
9
+ export default class extends Controller {
10
+ // This handler toggles the last tr in the current tbody. We use multiple tbodys in each table
11
+ // to make toggling like this simpler, and to group the related (visible and toggleable) rows
12
+ // together.
13
+ row(event) {
14
+ event.preventDefault
15
+ const tbody = event.target.closest("tbody")
16
+ tbody.classList.toggle("toggleable--open")
17
+ // Update masonry - TODO: move to a module
18
+ $(".grid > .row").masonry("layout")
19
+ }
20
+
21
+ // Toggle the last tr in each tbody in the current table.
22
+ // The link that triggers this event will most likelt be a double chevron icon
23
+ // sitting in a thead.
24
+ table(event) {
25
+ event.preventDefault
26
+ const table = event.target.closest("table")
27
+ const thead = event.target.closest("thead")
28
+ // Use an Array rather a NodeList here as IE does not support NodeList.forEach
29
+ const tbodies = Array.prototype.slice.call(table.querySelectorAll("tbody"))
30
+ const hide = thead.classList.contains("toggleable--open")
31
+ thead.classList.toggle("toggleable--open")
32
+ tbodies.forEach(function(tbody) { tbody.classList.toggle("toggleable--open", !hide) })
33
+ // Update masonry - TODO: move to a module
34
+ $(".grid > .row").masonry("layout")
35
+ }
36
+ }
@@ -0,0 +1,25 @@
1
+ import "@stimulus/polyfills" // required for IE11 support
2
+ import { Application } from "stimulus"
3
+
4
+ // Manually import stimulusjs controllers for now as we had problems with the stimulus-controllers
5
+ // package on CI ('file.isDirectory is not a function')
6
+ // and cannot use the webpacker-helper/require method as per usual in a rails app as we
7
+ // do not use webpacker in this engine because it is a poor fit. We just want to compile all
8
+ // es6 assets into a file in app/assets/javascripts so that they can be used in the asset pipeline
9
+ // by a host app initially. We could publish our package to e.g. GH packages at some point in the
10
+ // future so that a host app can include us using webpacker and skip the asset pipeline, but we
11
+ // are a little way off that.
12
+ // So the approach right now is quite simple - to allow is to use stimulus.js and IE11
13
+ // (via the polyfill) for new js development, and the remaining js can be ported or moved at some
14
+ // point in the future.
15
+ // The rollupjs setup from adapted from the approach used by ActiveStorage
16
+ import TestController from "./controllers/test_controller"
17
+ import AnotherTestController from "./controllers/another_test_controller"
18
+ import ToggleController from "./controllers/toggle_controller"
19
+ import HDPrescriptionController from "./controllers/hd/prescription_administration_controller"
20
+
21
+ const application = Application.start()
22
+ application.register("test", TestController)
23
+ application.register("another_test", AnotherTestController)
24
+ application.register("toggle", ToggleController)
25
+ application.register("hd-prescription-administration", HDPrescriptionController)
@@ -8,6 +8,7 @@ module Renalware
8
8
  has_one :hd_profile, class_name: "Profile"
9
9
  has_one :hd_preference_set, class_name: "PreferenceSet"
10
10
  has_many :hd_sessions, class_name: "Session"
11
+ has_many :prescription_administrations
11
12
  scope :with_profile, lambda {
12
13
  includes(hd_profile: :hospital_unit)
13
14
  .joins(<<-SQL)
@@ -7,63 +7,87 @@ module Renalware
7
7
  class PrescriptionAdministration < ApplicationRecord
8
8
  include Accountable
9
9
  acts_as_paranoid
10
- attr_accessor :administrator_authorisation_token
11
- attr_accessor :witness_authorisation_token
12
10
 
13
11
  # Set to true by the parent hd_session if we are not signing off at this stage
14
- attr_accessor :skip_validation
12
+ attr_accessor :skip_witness_validation
13
+ attr_accessor :skip_administrator_validation
14
+ attr_accessor :administered_by_password
15
+ attr_accessor :witnessed_by_password
15
16
 
16
17
  belongs_to :hd_session, class_name: "HD::Session", touch: true
17
18
  belongs_to :prescription, class_name: "Medications::Prescription"
18
19
  belongs_to :administered_by, class_name: "User"
19
20
  belongs_to :witnessed_by, class_name: "User"
20
21
  belongs_to :reason, class_name: "PrescriptionAdministrationReason"
21
- validates :administered, inclusion: { in: [true, false] }, unless: :skip_validation
22
+ validates :recorded_on, presence: true
23
+ validates :administered, inclusion: { in: [true, false] }
22
24
  validates :prescription, presence: true
23
- validates :administered_by, presence: true, if: :validate_administrator_and_witness?
24
- validates :witnessed_by, presence: true, if: :validate_administrator_and_witness?
25
- validate :check_administrator_authorisation_token
26
- validate :check_witness_authorisation_token
27
- scope :ordered, -> { order(created_at: :desc) }
25
+ validates :administered_by, presence: true, if: :validate_administrator?
26
+ validates :witnessed_by, presence: true, if: :validate_witness?
27
+ validate :check_administered_by_password, if: :validate_administrator?
28
+ validate :check_witnessed_by_password, if: :validate_witness?
29
+ validate :witness_cannot_be_administrator
30
+
31
+ scope :ordered, -> { order(recorded_on: :desc, created_at: :desc) }
32
+
33
+ def authorised?
34
+ return true unless administered?
35
+
36
+ administrator_authorised? && witness_authorised?
37
+ end
38
+
39
+ def witnessed?
40
+ administered? && witness_authorised?
41
+ end
28
42
 
29
43
  private
30
44
 
31
- def validate_administrator_and_witness?
32
- return false if skip_validation || not_administered?
33
- return false unless Renalware.config.hd_session_prescriptions_require_signoff
45
+ def witness_cannot_be_administrator
46
+ return unless authorised?
47
+
48
+ if administered_by_id.present? && administered_by_id == witnessed_by_id
49
+ errors.add(:witnessed_by_id, "Must be a different user")
50
+ end
51
+ end
52
+
53
+ def validate_witness?
54
+ return false if not_administered?
55
+ return false if skip_witness_validation
34
56
 
35
57
  true
36
58
  end
37
59
 
38
- def check_administrator_authorisation_token
39
- verify_submitted_user_token(
40
- administered_by,
41
- administrator_authorisation_token,
42
- :administrator_authorisation_token
43
- )
60
+ def validate_administrator?
61
+ return false if not_administered?
62
+ return false if skip_administrator_validation
63
+
64
+ true
44
65
  end
45
66
 
46
- def check_witness_authorisation_token
47
- verify_submitted_user_token(
48
- witnessed_by,
49
- witness_authorisation_token,
50
- :witness_authorisation_token
51
- )
67
+ def not_administered?
68
+ administered.nil? || administered == false
52
69
  end
53
70
 
54
- def verify_submitted_user_token(user, token, error_key)
55
- return if skip_validation
56
- return if user.blank? || not_administered?
71
+ def check_administered_by_password
72
+ return if administered_by.blank?
57
73
 
58
- if token.blank?
59
- errors[error_key] << "can't be blank"
60
- elsif user.auth_token != token
61
- errors[error_key] << "invalid token"
74
+ self.administrator_authorised = false
75
+ if administered_by.valid_password?(administered_by_password)
76
+ self.administrator_authorised = true
77
+ else
78
+ errors.add(:administered_by_password, "Invalid password")
62
79
  end
63
80
  end
64
81
 
65
- def not_administered?
66
- administered.nil? || administered == false
82
+ def check_witnessed_by_password
83
+ return if witnessed_by.blank?
84
+
85
+ self.witness_authorised = false
86
+ if witnessed_by.valid_password?(witnessed_by_password)
87
+ self.witness_authorised = true
88
+ else
89
+ errors.add(:witnessed_by_password, "Invalid password")
90
+ end
67
91
  end
68
92
  end
69
93
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ module HD
5
+ # Find the lastest PrescriptionAdministration for a particular prescription - ie the last time
6
+ # it was given.
7
+ class PrescriptionLastAdministrationQuery
8
+ pattr_initialize [:prescription!]
9
+ delegate :patient, to: :prescription
10
+
11
+ def call
12
+ raise ArgumentError if prescription.blank?
13
+ raise ArgumentError if patient.blank?
14
+
15
+ hd_patient
16
+ .prescription_administrations
17
+ .where(prescription: prescription, administered: true)
18
+ .order(recorded_on: :desc, created_at: :desc)
19
+ .first
20
+ end
21
+
22
+ private
23
+
24
+ def hd_patient
25
+ HD.cast_patient(patient)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -19,20 +19,12 @@ module Renalware
19
19
  # Closed (sign-off) but next time they want to save as Open (not signed off)
20
20
  # - so we need make sure the hidden :type form value is not rendered as :closed
21
21
  # This is getting a bit confusing and might need some refactoring, for example by
22
- # driving the :type to save as using the button on the form (which we already do using
23
- # the sign-off name of the SignOff button - see signed_off?
22
+ # driving the :type to save using the button name on the form
24
23
  def call(params:, id: nil, signing_off: false)
25
24
  @params = parse_params(params)
26
25
  session = find_or_build_session(id)
27
26
  session = update_session_attributes(session, signing_off)
28
27
 
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
-
36
28
  if session.save
37
29
  # Might be cleaner if something listened for this event and created this job there?
38
30
  # UpdateRollingPatientStatisticsJob.perform_later(patient) unless session.open?
@@ -59,21 +51,11 @@ module Renalware
59
51
  def update_session_attributes(session, signing_off)
60
52
  session = signed_off(session) if signing_off
61
53
  session.attributes = params
62
- force_validation_of_nested_prescription_administrations(session)
63
- skip_validation_on_prescription_administrations(session) unless signing_off
64
54
  session.by = current_user
65
55
  lookup_access_type_abbreviation(session)
66
56
  session
67
57
  end
68
58
 
69
- def force_validation_of_nested_prescription_administrations(session)
70
- # These valid? calls required because while accepts_nested_attributes yields validation
71
- # errors on create, no errors are raise when updating existing records.
72
- # It might be something I don't understand about how accepts_nested_attributes works in
73
- # this scenario. Anyway calling valid? causes the errors collection to be updated.
74
- session.prescription_administrations.each(&:valid?)
75
- end
76
-
77
59
  def find_or_build_session(id)
78
60
  if id.present?
79
61
  Session.for_patient(patient).find(id)
@@ -110,12 +92,6 @@ module Renalware
110
92
 
111
93
  session.document.info.access_type_abbreviation = access_type.abbreviation
112
94
  end
113
-
114
- def skip_validation_on_prescription_administrations(session)
115
- session.prescription_administrations.each do |pa|
116
- pa.skip_validation = true
117
- end
118
- end
119
95
  end
120
96
  end
121
97
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ module HD
5
+ # Form object to help us update the PrescriptionAdministration#witnesses_by
6
+ # See WitnessesController#edit/update and the corresponding html and js views.
7
+ class WitnessForm
8
+ include ActiveModel::Model
9
+ include Virtus::Model
10
+
11
+ attribute :user_id, Integer
12
+ attribute :password, String
13
+ attribute :prescription_administration_id, Integer
14
+ attribute :update_user_only, Boolean
15
+
16
+ validates :user_id, presence: true
17
+ validates :prescription_administration_id, presence: true
18
+ validates :password, presence: { unless: :update_user_only }
19
+ validate :password_is_correct, unless: :update_user_only
20
+
21
+ private
22
+
23
+ def password_is_correct
24
+ witness = User.find(user_id)
25
+ unless witness.valid_password?(password)
26
+ errors.add(:password, "Invalid password")
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ module HD
5
+ class PrescriptionAdministrationPolicy < BasePolicy
6
+ end
7
+ end
8
+ end
@@ -45,7 +45,6 @@ module Renalware
45
45
  end
46
46
  end
47
47
 
48
- # rubocop:disable Metrics/MethodLength
49
48
  def sessions
50
49
  @sessions ||= begin
51
50
  hd_sessions = Session
@@ -53,17 +52,27 @@ module Renalware
53
52
  :hospital_unit,
54
53
  :patient,
55
54
  :signed_on_by,
56
- :signed_off_by,
57
- prescription_administrations: [
58
- { prescription: [:medication_route, :drug] }, :administered_by, :reason
59
- ]
55
+ :signed_off_by
60
56
  )
61
57
  .for_patient(patient)
62
- .limit(10).ordered.merge(PrescriptionAdministration.ordered)
58
+ .limit(10).ordered
63
59
  CollectionPresenter.new(hd_sessions, SessionPresenter, view_context)
64
60
  end
65
61
  end
66
- # rubocop:enable Metrics/MethodLength
62
+
63
+ def prescription_administrations
64
+ patient
65
+ .prescription_administrations
66
+ .includes(
67
+ [
68
+ :administered_by,
69
+ :witnessed_by,
70
+ :reason,
71
+ prescription: [:medication_route, :drug]
72
+ ]
73
+ )
74
+ .limit(10).ordered
75
+ end
67
76
 
68
77
  def can_add_hd_profile?
69
78
  profile.new_record? && policy_for(profile).edit? && has_ever_been_on_hd?
@@ -1,5 +1,5 @@
1
1
  = definition_list_for(plan, size: :large) do |list|
2
- = list.definition(:created_at){ |value| l(value) }
2
+ = list.definition(:created_at) { |value| l(value) }
3
3
  = list.definition(:decided_by)
4
4
  = list.definition(:plan_type)
5
5
  = list.definition(:notes)
@@ -1,4 +1,4 @@
1
- = within_admin_layout(title: "Clearing the Cache") do
1
+ = within_new_admin_layout(title: "Clearing the Cache") do
2
2
  .panel
3
3
  h2 Application Cache
4
4
  p
@@ -0,0 +1,4 @@
1
+ = within_new_admin_layout(title: "Admin Dashboard") do
2
+ .row
3
+ .columns
4
+ = render Renalware::System::UsersAwaitingApprovalComponent.new(current_user: current_user)
@@ -1,4 +1,4 @@
1
1
  article.admin--users
2
2
  header
3
- h2 Admin
3
+ h2 User admin
4
4
  =link_to summary_part.users_needing_approval_title, admin_users_path(q: { unapproved: true })
@@ -1,4 +1,4 @@
1
- = within_admin_layout(title: "Edit",
1
+ = within_new_admin_layout(title: "Edit",
2
2
  breadcrumbs: breadcrumb_for("Users", admin_users_path)) do
3
3
 
4
4
  h2= user
@@ -4,7 +4,7 @@
4
4
  = content_for(:tabs) do
5
5
  = render "tabs", user_search: user_search
6
6
 
7
- = within_admin_layout(title: "Users") do
7
+ = within_new_admin_layout(title: "Users") do
8
8
  table.admin-users
9
9
  thead
10
10
  th.col-width-tiny