renalware-core 2.0.25 → 2.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/renalware/modules/_pathology.scss +28 -1
- data/app/assets/stylesheets/renalware/modules/_system.scss +27 -0
- data/app/assets/stylesheets/renalware/partials/_forms.scss +2 -1
- data/app/assets/stylesheets/renalware/partials/_tooltip.scss +347 -0
- data/app/controllers/renalware/hospitals/wards_controller.rb +61 -3
- data/app/controllers/renalware/session_timeout_controller.rb +1 -0
- data/app/controllers/renalware/system/messages_controller.rb +69 -0
- data/app/models/concerns/renalware/patients_ransack_helper.rb +2 -2
- data/app/models/renalware/admissions/consult_query.rb +2 -3
- data/app/models/renalware/pathology/adjust_observation.rb +72 -0
- data/app/models/renalware/pathology/create_observation_requests.rb +5 -1
- data/app/models/renalware/pathology/message_listener.rb +1 -0
- data/app/models/renalware/pathology/observation_requests_attributes_builder.rb +5 -1
- data/app/models/renalware/pathology/observations_grouped_by_date_query.rb +1 -1
- data/app/models/renalware/pathology/observations_grouped_by_date_table.rb +17 -3
- data/app/models/renalware/pathology.rb +3 -0
- data/app/models/renalware/system/message.rb +41 -0
- data/app/policies/renalware/system/message_policy.rb +21 -0
- data/app/views/renalware/admin/cache/show.html.slim +2 -2
- data/app/views/renalware/devise/sessions/new.html.slim +1 -0
- data/app/views/renalware/hospitals/units/index.html.slim +3 -1
- data/app/views/renalware/hospitals/wards/_form.html.slim +3 -0
- data/app/views/renalware/hospitals/wards/edit.html.slim +12 -0
- data/app/views/renalware/hospitals/wards/index.html.slim +27 -0
- data/app/views/renalware/hospitals/wards/new.html.slim +12 -0
- data/app/views/renalware/letters/formatted_letters/_letter.html.slim +4 -0
- data/app/views/renalware/navigation/_super_admin.html.slim +1 -0
- data/app/views/renalware/pathology/historical_observation_results/_table.html.slim +7 -2
- data/app/views/renalware/pathology/historical_observation_results/index.html.slim +1 -3
- data/app/views/renalware/pathology/recent_observation_results/_table.html.slim +20 -12
- data/app/views/renalware/system/messages/_form.html.slim +18 -0
- data/app/views/renalware/system/messages/_list.html.slim +4 -0
- data/app/views/renalware/system/messages/_message.html.slim +4 -0
- data/app/views/renalware/system/messages/edit.html.slim +3 -0
- data/app/views/renalware/system/messages/index.html.slim +30 -0
- data/app/views/renalware/system/messages/new.html.slim +3 -0
- data/app/views/renalware/transplants/mdm/_bottom.html.slim +2 -2
- data/config/initializers/renalware.rb +2 -1
- data/config/permissions.yml +1 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20180514151627_create_system_messages.rb +13 -0
- data/db/migrate/20180516111411_create_view_patient_current_modalities.rb +5 -0
- data/db/views/patient_current_modalities_v01.sql +16 -0
- data/lib/renalware/version.rb +1 -1
- data/spec/factories/system/messages.rb +9 -0
- metadata +21 -2
@@ -0,0 +1,72 @@
|
|
1
|
+
require_dependency "renalware/pathology"
|
2
|
+
require "attr_extras"
|
3
|
+
|
4
|
+
module Renalware
|
5
|
+
module Pathology
|
6
|
+
# A utility class used for example by the host app to provide a generic way of adjusting
|
7
|
+
# an observation, usually in a Wisper listener on receipt of a broadcast pathology message
|
8
|
+
# probably 'after_observation_request_persisted'.
|
9
|
+
#
|
10
|
+
# Example usage:
|
11
|
+
#
|
12
|
+
# # Subscribe our class to pathology messages.
|
13
|
+
# Renalware.configure do |config|
|
14
|
+
# map = config.broadcast_subscription_map
|
15
|
+
# map["Renalware::Pathology::CreateObservationRequests"] << "MyListener"
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# class MyListener
|
19
|
+
# def after_observation_request_persisted(observation_request)
|
20
|
+
# service = Renalware::Pathology::AdjustObservation.new(
|
21
|
+
# observation_request: observation_request,
|
22
|
+
# code: "EGFR",
|
23
|
+
# policy: ->(patient, observation){
|
24
|
+
# .. some logic returning true or false to indicate to adjust or not
|
25
|
+
# }
|
26
|
+
# )
|
27
|
+
# service.call do |egfr_observation_requiring_adjustment|
|
28
|
+
# egfr_observation_requiring_adjustment.result += 1 or whatever
|
29
|
+
# egfr_observation_requiring_adjustment.comment = "adjusted (original = 123)"
|
30
|
+
# egfr_observation_requiring_adjustment.save!
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
class AdjustObservation
|
35
|
+
pattr_initialize [:observation_request!, :code!, :policy!]
|
36
|
+
delegate :patient, to: :observation_request
|
37
|
+
|
38
|
+
# Will yield the requested observation if one found - the caller is responsible for
|
39
|
+
# making and saving the adjustment.
|
40
|
+
def call
|
41
|
+
return unless request_has_the_relevant_observation?
|
42
|
+
return if observation_result_is_zero?
|
43
|
+
return unless adjustment_required?
|
44
|
+
|
45
|
+
yield observation
|
46
|
+
end
|
47
|
+
|
48
|
+
def request_has_the_relevant_observation?
|
49
|
+
observation.present?
|
50
|
+
end
|
51
|
+
|
52
|
+
def observation_result_is_zero?
|
53
|
+
observation.result.to_f.zero?
|
54
|
+
end
|
55
|
+
|
56
|
+
def adjustment_required?
|
57
|
+
policy.call(patient, observation)
|
58
|
+
end
|
59
|
+
|
60
|
+
def observation
|
61
|
+
@observation ||= begin
|
62
|
+
observation_request
|
63
|
+
.observations
|
64
|
+
.joins(:description)
|
65
|
+
.find_by(
|
66
|
+
pathology_observation_descriptions: { code: code }
|
67
|
+
) || Renalware::NullObject.instance
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -10,11 +10,15 @@ require_dependency "renalware/pathology"
|
|
10
10
|
module Renalware
|
11
11
|
module Pathology
|
12
12
|
class CreateObservationRequests
|
13
|
+
include Wisper::Publisher
|
14
|
+
|
13
15
|
def call(params)
|
14
16
|
Array(params).each do |request|
|
15
17
|
patient = find_patient(request.fetch(:patient_id))
|
16
18
|
observation_params = request.fetch(:observation_request)
|
17
|
-
|
19
|
+
broadcast :before_observation_request_persisted, observation_params
|
20
|
+
obr = patient.observation_requests.create!(observation_params)
|
21
|
+
broadcast :after_observation_request_persisted, obr
|
18
22
|
end
|
19
23
|
end
|
20
24
|
|
@@ -9,6 +9,7 @@ require_dependency "renalware/pathology"
|
|
9
9
|
module Renalware
|
10
10
|
module Pathology
|
11
11
|
class MessageListener
|
12
|
+
# Note: We are already inside a transaction here
|
12
13
|
def message_processed(message_payload)
|
13
14
|
pathology_params = parse_pathology_params(message_payload)
|
14
15
|
create_observation_requests_and_their_child_observations_from(pathology_params)
|
@@ -9,7 +9,7 @@ module Renalware
|
|
9
9
|
# Note:
|
10
10
|
# - A message can have multiple observation_requests, each with its own observations.
|
11
11
|
# - This class could be removed and a Builder class used to create the database models
|
12
|
-
#
|
12
|
+
# directly - this would remove the extra level of indirection that this class introduces.
|
13
13
|
class ObservationRequestsAttributesBuilder
|
14
14
|
DEFAULT_REQUESTOR_NAME = "UNKNOWN"
|
15
15
|
delegate :patient_identification, :observation_requests, to: :message_payload
|
@@ -87,10 +87,14 @@ module Renalware
|
|
87
87
|
|
88
88
|
def find_request_description(code)
|
89
89
|
RequestDescription.find_by!(code: code)
|
90
|
+
rescue ActiveRecord::RecordNotFound
|
91
|
+
raise MissingRequestDescriptionError, code
|
90
92
|
end
|
91
93
|
|
92
94
|
def find_observation_description(code)
|
93
95
|
ObservationDescription.find_by!(code: code)
|
96
|
+
rescue ActiveRecord::RecordNotFound
|
97
|
+
raise MissingObservationDescriptionError, code
|
94
98
|
end
|
95
99
|
|
96
100
|
def validate_observation(observation, observation_description)
|
@@ -68,7 +68,7 @@ module Renalware
|
|
68
68
|
def to_sql
|
69
69
|
<<-SQL.squish
|
70
70
|
select obs_req.patient_id, cast(observed_at as date) as observed_on,
|
71
|
-
jsonb_object_agg(obs_desc.code, obs.result) results
|
71
|
+
jsonb_object_agg(obs_desc.code, ARRAY[obs.result, obs.comment]) results
|
72
72
|
from pathology_observations obs
|
73
73
|
inner join pathology_observation_requests obs_req on obs.request_id = obs_req.id
|
74
74
|
inner join pathology_observation_descriptions obs_desc on obs.description_id = obs_desc.id
|
@@ -41,6 +41,10 @@ module Renalware
|
|
41
41
|
@rows ||= relation.all.map(&:with_indifferent_access).map { |row| Row.new(row) }
|
42
42
|
end
|
43
43
|
|
44
|
+
# Each row wraps a PGResult (database row).
|
45
|
+
# Each row is all the pathology results for this patient on a particular day.
|
46
|
+
# Hence there is one observed_on date but multiple results which are the columns going across
|
47
|
+
# the table.
|
44
48
|
class Row
|
45
49
|
pattr_initialize :row
|
46
50
|
|
@@ -49,11 +53,21 @@ module Renalware
|
|
49
53
|
end
|
50
54
|
|
51
55
|
def result_for(code)
|
52
|
-
|
56
|
+
row_hash[code&.to_sym]&.first
|
53
57
|
end
|
54
58
|
|
55
|
-
def
|
56
|
-
|
59
|
+
def comment_for(code)
|
60
|
+
row_hash[code&.to_sym]&.last
|
61
|
+
end
|
62
|
+
|
63
|
+
# A hash keyed by OBX code, containing an array of [result, comment] arrays, e.g.
|
64
|
+
#
|
65
|
+
# { "HGB": [[123,nil],[124,'Some comment about the result',[..]], "PLT": [..] }
|
66
|
+
#
|
67
|
+
# This is a compressed format (as opposed to returning more verbose json) to
|
68
|
+
# improve performance. Just remember that for any result, its an array of [result, comment]
|
69
|
+
def row_hash
|
70
|
+
@row_hash = JSON.parse(row[:results]).with_indifferent_access
|
57
71
|
end
|
58
72
|
end
|
59
73
|
end
|
@@ -19,5 +19,8 @@ module Renalware
|
|
19
19
|
def configure
|
20
20
|
SubscriptionRegistry.instance.register(Feeds::MessageProcessor, MessageListener)
|
21
21
|
end
|
22
|
+
|
23
|
+
class MissingRequestDescriptionError < StandardError; end
|
24
|
+
class MissingObservationDescriptionError < StandardError; end
|
22
25
|
end
|
23
26
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/system"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module System
|
7
|
+
class Message < ApplicationRecord
|
8
|
+
extend Enumerize
|
9
|
+
validates :body, presence: true
|
10
|
+
validates :display_from, timeliness: { type: :datetime }, presence: true
|
11
|
+
validates :display_until,
|
12
|
+
timeliness: { type: :datetime, allow_blank: true, after: :display_from }
|
13
|
+
enumerize :severity, in: %i(default warning info success)
|
14
|
+
|
15
|
+
scope :active, lambda{
|
16
|
+
where(
|
17
|
+
"display_from <= ? and (display_until is null or display_until >= ?)",
|
18
|
+
Time.zone.now,
|
19
|
+
Time.zone.now
|
20
|
+
)
|
21
|
+
}
|
22
|
+
|
23
|
+
# Return true if the message should be visible.
|
24
|
+
# A message is visible if display_from is in the past and display_until is nil
|
25
|
+
# or in the future
|
26
|
+
def active?
|
27
|
+
return false if display_from.nil?
|
28
|
+
now = Time.zone.now
|
29
|
+
self.display_until ||= far_future_date
|
30
|
+
return true if display_from < now && display_until > now
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def far_future_date
|
37
|
+
Time.zone.parse("2999-01-01 00:00:01")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/snippets"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module System
|
7
|
+
class MessagePolicy < BasePolicy
|
8
|
+
def new?
|
9
|
+
user_is_super_admin?
|
10
|
+
end
|
11
|
+
|
12
|
+
def create?
|
13
|
+
user_is_super_admin?
|
14
|
+
end
|
15
|
+
|
16
|
+
def destroy?
|
17
|
+
user_is_super_admin?
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -34,8 +34,8 @@
|
|
34
34
|
| source for PDF letters, rather a volatile cache to aid performance. EPR should be the place
|
35
35
|
| to look for letter content - or just view the PDF through the UI.
|
36
36
|
p
|
37
|
-
| You may wish to clear the PDF Letter Cache if you notice any anomalies in the PDFs.
|
38
|
-
| raise a GitHub issue after clearing the cache so we can look into it.
|
37
|
+
| You may wish to clear the PDF Letter Cache if you notice any anomalies in the PDFs.
|
38
|
+
| Please raise a GitHub issue after clearing the cache so we can look into it.
|
39
39
|
|
40
40
|
= link_to "Clear the PDF Letter Cache",
|
41
41
|
letters_pdf_letter_cache_path,
|
@@ -14,7 +14,7 @@
|
|
14
14
|
th.col-width-small NRD Code
|
15
15
|
th.col-width-small HD Site?
|
16
16
|
th.col-width-tiny Stations
|
17
|
-
th.col-width-
|
17
|
+
th.col-width-largish
|
18
18
|
tbody
|
19
19
|
- hospital_units.each do |unit|
|
20
20
|
tr
|
@@ -36,3 +36,5 @@
|
|
36
36
|
= link_to("HD Stations", hd_unit_stations_path(unit))
|
37
37
|
= pipe_separator
|
38
38
|
= link_to("HD Diaries", hd_unit_diaries_path(unit))
|
39
|
+
= pipe_separator
|
40
|
+
= link_to("Wards", hospitals_unit_wards_path(unit))
|
@@ -0,0 +1,12 @@
|
|
1
|
+
= within_admin_layout(title: "Edit", breadcrumbs: [ \
|
2
|
+
breadcrumb_for(ward.hospital_unit.name, hospitals_units_path),
|
3
|
+
breadcrumb_for("Wards", hospitals_unit_wards_path(ward.hospital_unit)) \
|
4
|
+
]) do
|
5
|
+
|
6
|
+
= simple_form_for ward,
|
7
|
+
url: hospitals_unit_ward_path(ward.hospital_unit, ward),
|
8
|
+
html: { autocomplete: "off" },
|
9
|
+
as: :ward,
|
10
|
+
wrapper: "horizontal_form" do |f|
|
11
|
+
|
12
|
+
= render "form", f: f
|
@@ -0,0 +1,27 @@
|
|
1
|
+
= content_for(:actions) do
|
2
|
+
= link_to "Add",
|
3
|
+
new_hospitals_unit_ward_path(unit),
|
4
|
+
class: "button"
|
5
|
+
|
6
|
+
= within_admin_layout(title: "Wards", breadcrumbs: \
|
7
|
+
breadcrumb_for(unit.name, hospitals_units_path)) do
|
8
|
+
|
9
|
+
table.hospital-wards
|
10
|
+
thead
|
11
|
+
th.col-width-tiny
|
12
|
+
th.col-width-medium Code
|
13
|
+
th Name
|
14
|
+
tbody
|
15
|
+
- wards.each do |ward|
|
16
|
+
tr
|
17
|
+
td
|
18
|
+
- if policy(ward).edit?
|
19
|
+
= link_to "Edit", edit_hospitals_unit_ward_path(unit, ward)
|
20
|
+
- if policy(ward).destroy?
|
21
|
+
= pipe_separator
|
22
|
+
= link_to "Delete",
|
23
|
+
hospitals_unit_ward_path(unit, ward),
|
24
|
+
method: :delete,
|
25
|
+
data: { confirm: "Are you sure?" }
|
26
|
+
td= ward.code
|
27
|
+
td= ward.name
|
@@ -0,0 +1,12 @@
|
|
1
|
+
= within_admin_layout(title: "New", breadcrumbs: [ \
|
2
|
+
breadcrumb_for(ward.hospital_unit.name, hospitals_units_path),
|
3
|
+
breadcrumb_for("Wards", hospitals_unit_wards_path(ward.hospital_unit)) \
|
4
|
+
]) do
|
5
|
+
|
6
|
+
= simple_form_for ward,
|
7
|
+
url: hospitals_unit_wards_path(unit_id: ward.hospital_unit.id),
|
8
|
+
html: { autocomplete: "off" },
|
9
|
+
as: :ward,
|
10
|
+
wrapper: "horizontal_form" do |f|
|
11
|
+
|
12
|
+
= render "form", f: f
|
@@ -154,6 +154,9 @@ scss:
|
|
154
154
|
|
155
155
|
.allergies {
|
156
156
|
margin-bottom: 1rem;
|
157
|
+
float: left;
|
158
|
+
clear: left;
|
159
|
+
width: 50%;
|
157
160
|
|
158
161
|
h3 {
|
159
162
|
padding-right: 1rem;
|
@@ -220,6 +223,7 @@ scss:
|
|
220
223
|
.message {
|
221
224
|
margin-top: 30px;
|
222
225
|
margin-bottom: 20px;
|
226
|
+
clear: both;
|
223
227
|
|
224
228
|
p {
|
225
229
|
margin-bottom: 15px;
|
@@ -7,7 +7,12 @@ table#observations
|
|
7
7
|
tbody
|
8
8
|
- table.rows.each do |row|
|
9
9
|
tr
|
10
|
-
|
10
|
+
th.date= l(row.observed_on)
|
11
11
|
- table.observation_descriptions.each do |desc|
|
12
12
|
- code = desc.code
|
13
|
-
|
13
|
+
- if row.comment_for(code).present?
|
14
|
+
td(class=code.downcase data-balloon=row.comment_for(code) data-balloon-pos="up")
|
15
|
+
.triangle-top-right
|
16
|
+
= row.result_for(code)
|
17
|
+
- else
|
18
|
+
td(class=code.downcase)= row.result_for(code)
|
@@ -2,11 +2,9 @@
|
|
2
2
|
navigation_partial: "renalware/pathology/navigation" do
|
3
3
|
- if table.rows.empty?
|
4
4
|
p No results available for this patient.
|
5
|
-
|
6
5
|
- else
|
7
|
-
p.hint Hover over table then scroll horizontally to view more results.
|
8
|
-
|
9
6
|
.embedded-scroll
|
7
|
+
p.hint Hover over table then scroll horizontally to view more results.
|
10
8
|
= render "table", table: table
|
11
9
|
|
12
10
|
= paginate(table)
|
@@ -2,17 +2,25 @@
|
|
2
2
|
/ historical results, we transpose the cols and rows so we have
|
3
3
|
/ dates along the top and OBX codes down the left.
|
4
4
|
table#observations
|
5
|
-
|
6
|
-
th Year
|
7
|
-
- table.rows.each do |row|
|
8
|
-
th.date= row.observed_on.year
|
9
|
-
tr
|
10
|
-
th Date
|
11
|
-
- table.rows.each do |row|
|
12
|
-
th= row.observed_on.strftime("%d/%m")
|
13
|
-
- table.observation_descriptions.each do |desc|
|
14
|
-
- code = desc.code
|
5
|
+
thead
|
15
6
|
tr
|
16
|
-
th
|
7
|
+
th Year
|
17
8
|
- table.rows.each do |row|
|
18
|
-
|
9
|
+
th.date= row.observed_on.year
|
10
|
+
thead
|
11
|
+
tr
|
12
|
+
th Date
|
13
|
+
- table.rows.each do |row|
|
14
|
+
th= row.observed_on.strftime("%d/%m")
|
15
|
+
tbody
|
16
|
+
- table.observation_descriptions.each do |desc|
|
17
|
+
- code = desc.code
|
18
|
+
tr
|
19
|
+
th(title=desc.name)= code
|
20
|
+
- table.rows.each do |row|
|
21
|
+
- if row.comment_for(code).present?
|
22
|
+
td(class=code.downcase data-balloon=row.comment_for(code) data-balloon-pos="up")
|
23
|
+
.triangle-top-right
|
24
|
+
= row.result_for(code)
|
25
|
+
- else
|
26
|
+
td(class=code.downcase)= row.result_for(code)
|
@@ -0,0 +1,18 @@
|
|
1
|
+
- severities = Renalware::System::Message.severity.values.map{|val| [val&.humanize, val] }
|
2
|
+
= simple_form_for(message,
|
3
|
+
as: :message,
|
4
|
+
html: { autocomplete: "off" }) do |f|
|
5
|
+
|
6
|
+
= render "renalware/shared/errors", model: f.object
|
7
|
+
|
8
|
+
= f.input :title, placeholder: "An optional title"
|
9
|
+
= f.trix_editor :body, wrapper: :horizontal_large
|
10
|
+
br
|
11
|
+
= f.input :severity,
|
12
|
+
collection: severities,
|
13
|
+
input_html: { style: "width:100px" },
|
14
|
+
include_blank: nil
|
15
|
+
= f.input :display_from, as: :datetime_picker
|
16
|
+
= f.input :display_until, as: :datetime_picker
|
17
|
+
br
|
18
|
+
= f.submit "Save", class: :button
|
@@ -0,0 +1,30 @@
|
|
1
|
+
= content_for(:actions) do
|
2
|
+
= link_to "Add", new_system_message_path, class: :button
|
3
|
+
|
4
|
+
= within_admin_layout(title: "System Messages") do
|
5
|
+
.system-messages
|
6
|
+
table
|
7
|
+
thead
|
8
|
+
th
|
9
|
+
th
|
10
|
+
th.col-width-tiny Severity
|
11
|
+
th.col-width-date-time Display from
|
12
|
+
th.col-width-date-time Display until
|
13
|
+
th.col-width-tiny Active now
|
14
|
+
tbody
|
15
|
+
- messages.each do |message|
|
16
|
+
tr
|
17
|
+
td
|
18
|
+
= link_to "Edit", edit_system_message_path(message)
|
19
|
+
= pipe_separator
|
20
|
+
= link_to "Delete",
|
21
|
+
system_message_path(message),
|
22
|
+
method: :delete,
|
23
|
+
data: { confirm: I18n.t("prompts.confirm_delete") }
|
24
|
+
td
|
25
|
+
= render message
|
26
|
+
/td= simple_format(message.body)
|
27
|
+
td= message.severity&.humanize
|
28
|
+
td= l(message.display_from)
|
29
|
+
td= l(message.display_until)
|
30
|
+
td= yes_no(message.active?)
|
@@ -8,10 +8,10 @@
|
|
8
8
|
.columns.small-12.medium-4
|
9
9
|
= render "measurements", mdm: mdm
|
10
10
|
.row
|
11
|
-
.columns.medium-12
|
11
|
+
.columns.medium-12
|
12
12
|
= render "clinic_visits", mdm: mdm
|
13
13
|
|
14
|
-
.columns.medium-12.large-
|
14
|
+
.columns.medium-12.large-4
|
15
15
|
= render "biopsies", mdm: mdm
|
16
16
|
.row
|
17
17
|
.columns.medium-12.large-12
|
@@ -11,7 +11,8 @@ Renalware.configure do |config|
|
|
11
11
|
"Renalware::Letters::PatientListener",
|
12
12
|
"Renalware::HD::PatientListener"
|
13
13
|
],
|
14
|
-
"Renalware::Letters::ApproveLetter" => []
|
14
|
+
"Renalware::Letters::ApproveLetter" => [],
|
15
|
+
"Renalware::Pathology::CreateObservationRequests" => []
|
15
16
|
}
|
16
17
|
end
|
17
18
|
|
data/config/permissions.yml
CHANGED
data/config/routes.rb
CHANGED
@@ -178,6 +178,7 @@ Renalware::Engine.routes.draw do
|
|
178
178
|
|
179
179
|
namespace :hospitals do
|
180
180
|
resources :units, except: :show do
|
181
|
+
resources :wards
|
181
182
|
scope format: true, constraints: { format: :json } do
|
182
183
|
resources :wards, only: :index
|
183
184
|
end
|
@@ -267,6 +268,7 @@ Renalware::Engine.routes.draw do
|
|
267
268
|
namespace :system do
|
268
269
|
resources :email_templates, only: :index
|
269
270
|
resources :user_feedback, except: :destroy, controller: "user_feedback"
|
271
|
+
resources :messages
|
270
272
|
end
|
271
273
|
|
272
274
|
namespace :transplants do
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class CreateSystemMessages < ActiveRecord::Migration[5.1]
|
2
|
+
def change
|
3
|
+
create_table :system_messages do |t|
|
4
|
+
t.string :title, null: true
|
5
|
+
t.text :body, null: false
|
6
|
+
t.integer :message_type, null: false, default: 0
|
7
|
+
t.string :severity
|
8
|
+
t.datetime :display_from, null: false
|
9
|
+
t.datetime :display_until
|
10
|
+
t.timestamps null: false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
select
|
2
|
+
patients.id as patient_id,
|
3
|
+
patients.secure_id as patient_secure_id,
|
4
|
+
current_modality.id as modality_id,
|
5
|
+
modality_descriptions.id as modality_description_id,
|
6
|
+
modality_descriptions.name as modality_name,
|
7
|
+
current_modality.started_on as started_on
|
8
|
+
from patients
|
9
|
+
-- this join only required as currently there can be > 1 current modality for a patient
|
10
|
+
-- here we select the current modality with the most recent started_on
|
11
|
+
left outer join (
|
12
|
+
select distinct on (patient_id) * from modality_modalities
|
13
|
+
order by patient_id, started_on desc
|
14
|
+
) as current_modality
|
15
|
+
on patients.id = current_modality.patient_id
|
16
|
+
left outer join modality_descriptions on modality_descriptions.id = current_modality.description_id;
|
data/lib/renalware/version.rb
CHANGED