renalware-core 2.0.0.pre.beta12 → 2.0.0.pre.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (217) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/app/assets/stylesheets/renalware/modules/_letters.scss +0 -1
  4. data/app/assets/stylesheets/renalware/modules/_pathology.scss +4 -0
  5. data/app/assets/stylesheets/renalware/partials/_beta_banner.scss +26 -0
  6. data/app/assets/stylesheets/renalware/partials/_errors.scss +4 -0
  7. data/app/controllers/renalware/admissions/consults_controller.rb +0 -7
  8. data/app/controllers/renalware/concerns/devise_controller_methods.rb +9 -9
  9. data/app/controllers/renalware/hd/mdm_controller.rb +2 -3
  10. data/app/controllers/renalware/hd/mdm_patients_controller.rb +7 -1
  11. data/app/controllers/renalware/letters/letters_controller.rb +1 -1
  12. data/app/controllers/renalware/letters/lists_controller.rb +13 -6
  13. data/app/controllers/renalware/mdm_controller.rb +1 -1
  14. data/app/controllers/renalware/mdm_patients_controller.rb +1 -1
  15. data/app/controllers/renalware/patients/bookmarks_controller.rb +1 -1
  16. data/app/controllers/renalware/patients/clinical_summaries_controller.rb +1 -1
  17. data/app/controllers/renalware/pd/mdm_controller.rb +2 -3
  18. data/app/controllers/renalware/pd/mdm_patients_controller.rb +2 -0
  19. data/app/controllers/renalware/renal/low_clearance/mdm_controller.rb +15 -0
  20. data/app/controllers/renalware/renal/low_clearance/mdm_patients_controller.rb +29 -0
  21. data/app/controllers/renalware/session_timeout_controller.rb +2 -0
  22. data/app/controllers/renalware/system/user_feedback_controller.rb +35 -0
  23. data/app/controllers/renalware/transplants/mdm_controller.rb +1 -3
  24. data/app/controllers/renalware/transplants/mdm_patients_controller.rb +2 -0
  25. data/app/helpers/renalware/application_helper.rb +1 -42
  26. data/app/helpers/renalware/clinic_helper.rb +3 -1
  27. data/app/helpers/renalware/infection_organisms_helper.rb +20 -0
  28. data/app/helpers/renalware/mdm_helper.rb +9 -7
  29. data/app/helpers/renalware/prescriptions_helper.rb +20 -0
  30. data/app/helpers/renalware/side_nav_helper.rb +0 -8
  31. data/app/jobs/application_job.rb +2 -0
  32. data/app/models/concerns/renalware/explicit_state_model.rb +2 -0
  33. data/app/models/concerns/renalware/patient_pathology_scopes.rb +39 -0
  34. data/app/models/concerns/renalware/personable.rb +3 -2
  35. data/app/models/renalware/clinics/appointment.rb +4 -4
  36. data/app/models/renalware/clinics/clinic_visit.rb +2 -2
  37. data/app/models/renalware/drugs/classification.rb +11 -0
  38. data/app/models/renalware/drugs/drug.rb +3 -3
  39. data/app/models/renalware/drugs/type.rb +2 -1
  40. data/app/models/renalware/hd/mdm_patients_query.rb +4 -9
  41. data/app/models/renalware/hd/session/closed.rb +10 -3
  42. data/app/models/renalware/hd/session.rb +2 -1
  43. data/app/models/renalware/hd/sessions/auditable_session_collection.rb +7 -7
  44. data/app/models/renalware/letters/archive.rb +1 -1
  45. data/app/models/renalware/letters/description.rb +1 -1
  46. data/app/models/renalware/letters/event/clinic_visit.rb +4 -0
  47. data/app/models/renalware/letters/letter_factory.rb +1 -0
  48. data/app/models/renalware/letters/part/allergies.rb +1 -1
  49. data/app/models/renalware/letters/part/prescriptions.rb +1 -1
  50. data/app/models/renalware/letters/part/problems.rb +1 -1
  51. data/app/models/renalware/letters/part/recent_pathology_results.rb +14 -12
  52. data/app/models/renalware/letters/part.rb +3 -2
  53. data/app/models/renalware/letters/recipient.rb +1 -1
  54. data/app/models/renalware/letters/signature.rb +3 -1
  55. data/app/models/renalware/pathology/current_observations_for_descriptions_query.rb +7 -4
  56. data/app/models/renalware/pathology/observations_for_descriptions_query.rb +1 -2
  57. data/app/models/renalware/patients/bookmark.rb +1 -1
  58. data/app/models/renalware/patients/patient_hospital_identifiers.rb +4 -4
  59. data/app/models/renalware/patients/practice.rb +3 -3
  60. data/app/models/renalware/patients/primary_care_physician.rb +2 -2
  61. data/app/models/renalware/renal/low_clearance/mdm_patients_query.rb +63 -0
  62. data/app/models/renalware/renal/low_clearance/modality_description.rb +13 -0
  63. data/app/models/renalware/renal/profile.rb +2 -0
  64. data/app/models/renalware/renal/registry/preflight_checks/deaths_query.rb +1 -1
  65. data/app/models/renalware/renal/version.rb +9 -0
  66. data/app/models/renalware/renal.rb +4 -0
  67. data/app/models/renalware/role.rb +4 -3
  68. data/app/models/renalware/roles_user.rb +6 -0
  69. data/app/models/renalware/system/user_feedback.rb +16 -0
  70. data/app/models/renalware/transplants/donor_modality_description.rb +3 -0
  71. data/app/models/renalware/transplants/recipient_modality_description.rb +3 -0
  72. data/app/models/renalware/user.rb +14 -9
  73. data/app/models/renalware.rb +2 -5
  74. data/app/policies/renalware/base_policy.rb +1 -1
  75. data/app/policies/renalware/system/user_feedback_policy.rb +8 -0
  76. data/app/presenters/renalware/hd/mdm_presenter.rb +2 -0
  77. data/app/presenters/renalware/hd/session_access_presenter.rb +1 -1
  78. data/app/presenters/renalware/hd/session_presenter.rb +4 -5
  79. data/app/presenters/renalware/hd/station_presenter.rb +1 -1
  80. data/app/presenters/renalware/letters/letter_presenter.rb +4 -2
  81. data/app/presenters/renalware/mdm_presenter.rb +3 -3
  82. data/app/presenters/renalware/pathology/observations_diff.rb +110 -0
  83. data/app/presenters/renalware/renal/clinical_summary_presenter.rb +32 -4
  84. data/app/presenters/renalware/renal/low_clearance/mdm_presenter.rb +14 -0
  85. data/app/views/renalware/accesses/assessments/show.html.slim +1 -1
  86. data/app/views/renalware/accesses/dashboards/show.html.slim +1 -1
  87. data/app/views/renalware/accesses/procedures/show.html.slim +1 -1
  88. data/app/views/renalware/accesses/profiles/_list.html.slim +1 -1
  89. data/app/views/renalware/accesses/profiles/show.html.slim +1 -1
  90. data/app/views/renalware/admissions/consults/_form.html.slim +12 -12
  91. data/app/views/renalware/admissions/requests/_create_request_link.html.slim +1 -1
  92. data/app/views/renalware/admissions/requests/_form.html.slim +1 -1
  93. data/app/views/renalware/clinical/allergies/_new.html.slim +3 -3
  94. data/app/views/renalware/clinical/allergy_statuses/_form.html.slim +3 -3
  95. data/app/views/renalware/clinical/dry_weights/{_row.html.slim → _dry_weight.html.slim} +0 -0
  96. data/app/views/renalware/clinical/dry_weights/_list.html.slim +1 -2
  97. data/app/views/renalware/clinical/dry_weights/index.html.slim +1 -2
  98. data/app/views/renalware/clinical/profiles/show.html.slim +1 -1
  99. data/app/views/renalware/events/types/index.html.slim +1 -1
  100. data/app/views/renalware/hd/diaries/show.pdf.slim +1 -0
  101. data/app/views/renalware/hd/diary_slots/_form.html.slim +10 -10
  102. data/app/views/renalware/hd/diary_slots/_tab.html.slim +4 -4
  103. data/app/views/renalware/hd/mdm/_sessions.html.slim +1 -1
  104. data/app/views/renalware/hd/mdm_patients/_table.html.slim +7 -8
  105. data/app/views/renalware/hd/ongoing_sessions/_table.html.slim +1 -2
  106. data/app/views/renalware/hd/sessions/_form.html.slim +2 -2
  107. data/app/views/renalware/hd/sessions/_list.html.slim +1 -1
  108. data/app/views/renalware/hd/sessions/_row.html.slim +1 -1
  109. data/app/views/renalware/hd/sessions/_session_nav.html.slim +1 -1
  110. data/app/views/renalware/hd/sessions/_table.html.slim +1 -1
  111. data/app/views/renalware/hd/sessions/closed/_row.html.slim +1 -1
  112. data/app/views/renalware/hd/sessions/open/_row.html.slim +1 -1
  113. data/app/views/renalware/hd/stations/edit.html.slim +1 -1
  114. data/app/views/renalware/hd/stations/index.html.slim +1 -1
  115. data/app/views/renalware/hd/stations/new.html.slim +1 -1
  116. data/app/views/renalware/layouts/_patient.html.slim +1 -1
  117. data/app/views/renalware/layouts/application.html.slim +3 -1
  118. data/app/views/renalware/letters/contacts/_new_person.html.slim +2 -2
  119. data/app/views/renalware/letters/contacts/_person_from_directory.html.slim +2 -2
  120. data/app/views/renalware/letters/formatted_letters/_letter.html.slim +3 -3
  121. data/app/views/renalware/letters/formatted_letters/show.html.slim +1 -1
  122. data/app/views/renalware/letters/formatted_letters/show.inlinepdf.slim +1 -1
  123. data/app/views/renalware/letters/formatted_letters/show.pdf.slim +1 -1
  124. data/app/views/renalware/letters/letters/_electronic_ccs.html.slim +1 -1
  125. data/app/views/renalware/letters/letters/_form.html.slim +5 -2
  126. data/app/views/renalware/letters/letters/_pathology.html.slim +26 -0
  127. data/app/views/renalware/letters/letters/_preview.html.slim +3 -3
  128. data/app/views/renalware/letters/letters/edit.html.slim +11 -12
  129. data/app/views/renalware/letters/letters/new.html.slim +1 -1
  130. data/app/views/renalware/letters/lists/_letter.html.slim +1 -2
  131. data/app/views/renalware/letters/lists/show.html.slim +13 -14
  132. data/app/views/renalware/letters/parts/_recent_pathology_results.html.slim +3 -8
  133. data/app/views/renalware/letters/shared/_electronic_cc_type_tabs.html.slim +3 -3
  134. data/app/views/renalware/mdm/_letters.html.slim +1 -1
  135. data/app/views/renalware/mdm/_measurements.html.slim +1 -1
  136. data/app/views/renalware/mdm_patients/_patient.html.slim +1 -1
  137. data/app/views/renalware/mdm_patients/_table.html.slim +11 -13
  138. data/app/views/renalware/messaging/internal/messages/_form.html.slim +7 -7
  139. data/app/views/renalware/messaging/internal/messages/_send_message_link.html.slim +1 -1
  140. data/app/views/renalware/messaging/internal/messages/_send_reply_link.html.slim +1 -1
  141. data/app/views/renalware/messaging/internal/receipts/_sent_receipt.html.slim +1 -1
  142. data/app/views/renalware/messaging/shared/_messages_type_tabs.html.slim +3 -3
  143. data/app/views/renalware/navigation/_branding.html.slim +1 -1
  144. data/app/views/renalware/navigation/_mdms.html.slim +1 -0
  145. data/app/views/renalware/pathology/observations/_diff.html.slim +22 -0
  146. data/app/views/renalware/patients/_layout.html.slim +1 -1
  147. data/app/views/renalware/patients/alerts/_create_alert_link.html.slim +1 -1
  148. data/app/views/renalware/patients/alerts/_form.html.slim +4 -4
  149. data/app/views/renalware/patients/alerts/_list.html.slim +1 -2
  150. data/app/views/renalware/patients/bookmarks/_delete.html.slim +1 -1
  151. data/app/views/renalware/patients/bookmarks/_new.html.slim +8 -8
  152. data/app/views/renalware/patients/clinical_summaries/_events.html.slim +6 -4
  153. data/app/views/renalware/patients/clinical_summaries/_letters.html.slim +6 -3
  154. data/app/views/renalware/patients/clinical_summaries/_prescriptions.html.slim +2 -2
  155. data/app/views/renalware/patients/clinical_summaries/_problems.html.slim +2 -2
  156. data/app/views/renalware/patients/clinical_summaries/show.html.slim +14 -4
  157. data/app/views/renalware/patients/patients/show.html.slim +1 -1
  158. data/app/views/renalware/patients/side_menu/_modalities.html.slim +2 -2
  159. data/app/views/renalware/patients/worries/_delete.html.slim +1 -1
  160. data/app/views/renalware/patients/worries/_new.html.slim +6 -6
  161. data/app/views/renalware/pd/dashboards/show.html.slim +1 -1
  162. data/app/views/renalware/pd/infection_organisms/_table.html.slim +3 -3
  163. data/app/views/renalware/pd/pet_adequacy_results/_form.html.slim +23 -23
  164. data/app/views/renalware/pd/regime_bags/_form.html.slim +5 -5
  165. data/app/views/renalware/pd/regime_bags/_regime_bag.html.slim +2 -2
  166. data/app/views/renalware/pd/regime_bags/_regime_bags.html.slim +1 -1
  167. data/app/views/renalware/pd/regimes/_current_regime.html.slim +1 -1
  168. data/app/views/renalware/problems/problems/index.html.slim +1 -1
  169. data/app/views/renalware/renal/low_clearance/mdm/_bottom.html.slim +3 -0
  170. data/app/views/renalware/renal/low_clearance/mdm/_low_clearance_profile.html.slim +4 -0
  171. data/app/views/renalware/renal/low_clearance/mdm/_top.html.slim +5 -0
  172. data/app/views/renalware/renal/low_clearance/mdm_patients/_filters.html.slim +9 -0
  173. data/app/views/renalware/renal/profiles/_mini.html.slim +1 -1
  174. data/app/views/renalware/reporting/audits/index.html.slim +1 -1
  175. data/app/views/renalware/research/study_participants/_form.html.slim +3 -3
  176. data/app/views/renalware/shared/_modal_close_link.html.slim +1 -1
  177. data/app/views/renalware/shared/documents/_blood_pressure_input.html.slim +1 -1
  178. data/app/views/renalware/snippets/snippets/_form.html.slim +4 -4
  179. data/app/views/renalware/snippets/snippets/_list.html.slim +3 -3
  180. data/app/views/renalware/snippets/snippets/_row.html.slim +2 -2
  181. data/app/views/renalware/snippets/snippets/_table.html.slim +7 -7
  182. data/app/views/renalware/snippets/snippets/edit.html.slim +1 -1
  183. data/app/views/renalware/snippets/snippets/new.html.slim +1 -1
  184. data/app/views/renalware/system/user_feedback/_banner.html.slim +9 -0
  185. data/app/views/renalware/system/user_feedback/new.html.slim +13 -0
  186. data/app/views/renalware/transplants/donor_dashboards/show.html.slim +2 -2
  187. data/app/views/renalware/transplants/recipient_dashboards/show.html.slim +2 -2
  188. data/config/initializers/inflections.rb +2 -0
  189. data/config/locales/custom.yml +7 -0
  190. data/config/locales/renalware/letters/letter.en.yml +2 -2
  191. data/config/locales/renalware/navigation/renal.en.yml +1 -0
  192. data/config/locales/renalware/renal/low_clearance.en.yml +15 -0
  193. data/config/permissions.yml +1 -0
  194. data/config/routes.rb +10 -0
  195. data/db/migrate/20171114120904_add_pathology_snapshot_to_letters.rb +5 -0
  196. data/db/migrate/20171123123712_add_id_to_roles_users.rb +5 -0
  197. data/db/migrate/20171123143534_add_pk_to_drug_types_drugs.rb +18 -0
  198. data/db/migrate/20171123154116_create_renal_versions.rb +14 -0
  199. data/db/migrate/20171128163543_add_more_missing_indexes.rb +16 -0
  200. data/db/migrate/20171206121652_add_loinc_code_to_observation_descriptions.rb +5 -0
  201. data/db/migrate/20171208211206_create_user_feedback.rb +10 -0
  202. data/db/migrate/20171211130716_remove_unused_patients_cols.rb +6 -0
  203. data/db/seeds/default/modalities/descriptions.rb +1 -0
  204. data/db/views/reporting_anaemia_audit_v01.sql +1 -1
  205. data/db/views/reporting_bone_audit_v01.sql +1 -1
  206. data/lib/renalware/configuration.rb +3 -0
  207. data/lib/renalware/version.rb +1 -1
  208. data/spec/factories/modalities/modality_descriptions.rb +3 -2
  209. data/spec/factories/renal/lcc_modality_description.rb +9 -0
  210. data/spec/factories/system/roles.rb +2 -2
  211. data/spec/factories/system/users.rb +3 -3
  212. data/spec/support/login_macros.rb +2 -2
  213. data/spec/support/roles_spec_helper.rb +1 -1
  214. metadata +35 -6
  215. data/app/models/renalware/patients/message_listener.rb +0 -31
  216. data/config/initializers/version.rb +0 -3
  217. data/spec/support/database_cleaner.rb +0 -16
@@ -0,0 +1,11 @@
1
+ require_dependency "renalware/drugs"
2
+
3
+ module Renalware
4
+ module Drugs
5
+ class Classification < ApplicationRecord
6
+ self.table_name = "drug_types_drugs" # a relic from migrating from habtm
7
+ belongs_to :drug
8
+ belongs_to :drug_type, class_name: "Type"
9
+ end
10
+ end
11
+ end
@@ -5,9 +5,9 @@ module Renalware
5
5
  class Drug < ApplicationRecord
6
6
  acts_as_paranoid
7
7
 
8
- has_and_belongs_to_many :drug_types,
9
- class_name: "Type",
10
- association_foreign_key: :drug_type_id
8
+ has_many :classifications, dependent: :destroy
9
+ has_many :drug_types, through: :classifications
10
+
11
11
  scope :ordered, -> { order(:name) }
12
12
 
13
13
  validates :name, presence: true
@@ -5,7 +5,8 @@ module Renalware
5
5
  class Type < ApplicationRecord
6
6
  self.table_name = "drug_types"
7
7
 
8
- has_and_belongs_to_many :drugs, foreign_key: :drug_type_id
8
+ has_many :classifications, foreign_key: :drug_type_id, dependent: :destroy
9
+ has_many :drugs, through: :classifications
9
10
 
10
11
  include OrderedSetScope
11
12
 
@@ -3,10 +3,12 @@ module Renalware
3
3
  class MDMPatientsQuery
4
4
  include ModalityScopes
5
5
  MODALITY_NAMES = "HD".freeze
6
+ DEFAULT_SEARCH_PREDICATE = "hgb_date".freeze
6
7
  attr_reader :q, :relation
7
8
 
8
9
  def initialize(relation: HD::Patient.all, q:)
9
- @q = q
10
+ @q = q || {}
11
+ @q[:s] = DEFAULT_SEARCH_PREDICATE if @q[:s].blank?
10
12
  @relation = relation
11
13
  end
12
14
 
@@ -19,17 +21,10 @@ module Renalware
19
21
  relation
20
22
  .includes(:hd_profile)
21
23
  .extending(ModalityScopes)
22
- .extending(Scopes)
24
+ .extending(PatientPathologyScopes)
23
25
  .with_current_key_pathology
24
26
  .with_current_modality_matching(MODALITY_NAMES)
25
27
  .search(q)
26
- # .order("pathology_current_key_observations.hgb_result asc")
27
- end
28
- end
29
-
30
- module Scopes
31
- def with_current_key_pathology
32
- eager_load(:current_key_observation_set) # .joins(:current_key_observation)
33
28
  end
34
29
  end
35
30
  end
@@ -26,21 +26,28 @@ module Renalware
26
26
 
27
27
  class SessionDocument < ::Renalware::HD::SessionDocument
28
28
  class Info < Renalware::HD::SessionDocument::Info
29
+ # rubocop:disable Rails/Validation
29
30
  validates_presence_of attribute_set.map(&:name)
31
+ # rubocop:enable Rails/Validation
30
32
  end
31
33
  attribute :info, Info
32
34
 
33
35
  class Observations < Renalware::HD::SessionDocument::Observations
34
- validates_presence_of :pulse, :blood_pressure, :weight_measured, :temperature_measured
35
- validates_presence_of :weight, if: ->{ weight_measured&.yes? }
36
- validates_presence_of :temperature, if: ->{ temperature_measured&.yes? }
36
+ validates :pulse, presence: true
37
+ validates :blood_pressure, presence: true
38
+ validates :weight_measured, presence: true
39
+ validates :temperature_measured, presence: true
40
+ validates :weight, presence: { if: ->{ weight_measured&.yes? } }
41
+ validates :temperature, presence: { if: ->{ temperature_measured&.yes? } }
37
42
  validates :blood_pressure, "renalware/patients/blood_pressure_presence" => true
38
43
  end
39
44
  attribute :observations_before, Observations
40
45
  attribute :observations_after, Observations
41
46
 
42
47
  class Dialysis < Renalware::HD::SessionDocument::Dialysis
48
+ # rubocop:disable Rails/Validation
43
49
  validates_presence_of attribute_set.map(&:name)
50
+ # rubocop:enable Rails/Validation
44
51
  end
45
52
  attribute :dialysis, Dialysis
46
53
 
@@ -8,7 +8,8 @@ module Renalware
8
8
  include Accountable
9
9
  include ExplicitStateModel
10
10
 
11
- validates_presence_of :type # Prevent instances of this of this base from being saved
11
+ # Prevent instances of this of this base class from being saved
12
+ validates :type, presence: true
12
13
 
13
14
  has_states :open, :closed, :dna
14
15
 
@@ -35,13 +35,6 @@ module Renalware
35
35
  number_of_sessions_with_dialysis_minutes_shortfall_gt_5_pct
36
36
  ).freeze
37
37
 
38
- def to_h
39
- AUDITABLE_ATTRIBUTES.each_with_object({}) do |sym, hash|
40
- hash[sym] = public_send(sym)
41
- hash
42
- end
43
- end
44
-
45
38
  def initialize(sessions)
46
39
  @sessions = Array(sessions).map do |session|
47
40
  Renalware::HD::Sessions::AuditableSession.new(session)
@@ -49,6 +42,13 @@ module Renalware
49
42
  super(@sessions)
50
43
  end
51
44
 
45
+ def to_h
46
+ AUDITABLE_ATTRIBUTES.each_with_object({}) do |sym, hash|
47
+ hash[sym] = public_send(sym)
48
+ hash
49
+ end
50
+ end
51
+
52
52
  def number_of_missed_sessions
53
53
  sessions.count(&:dna?)
54
54
  end
@@ -7,7 +7,7 @@ module Renalware
7
7
 
8
8
  belongs_to :letter
9
9
 
10
- validates_presence_of :content
10
+ validates :content, presence: true
11
11
  end
12
12
  end
13
13
  end
@@ -3,7 +3,7 @@ require_dependency "renalware/letters"
3
3
  module Renalware
4
4
  module Letters
5
5
  class Description < ApplicationRecord
6
- validates_presence_of :text
6
+ validates :text, presence: true
7
7
 
8
8
  has_many :letters
9
9
  end
@@ -21,6 +21,10 @@ module Renalware
21
21
  "Clinic Visit"
22
22
  end
23
23
 
24
+ def clinical?
25
+ true
26
+ end
27
+
24
28
  def to_link
25
29
  lambda { |patient, event = self|
26
30
  link_to(
@@ -16,6 +16,7 @@ module Renalware
16
16
  include_primary_care_physician_as_default_main_recipient
17
17
  assign_default_ccs
18
18
  build_salutation
19
+ letter.pathology_timestamp = Time.zone.now
19
20
  letter
20
21
  end
21
22
 
@@ -6,7 +6,7 @@ module Renalware
6
6
  class Part::Allergies < SimpleDelegator
7
7
  attr_reader :allergy_status
8
8
 
9
- def initialize(patient, _event = Event::Unknown.new)
9
+ def initialize(patient, _letter, _event = Event::Unknown.new)
10
10
  patient = ::Renalware::Clinical.cast_patient(patient.__getobj__)
11
11
  @allergy_status = patient.allergy_status
12
12
  super(patient.allergies)
@@ -6,7 +6,7 @@ module Renalware
6
6
  class Part::Prescriptions < DumbDelegator
7
7
  include ::PresenterHelper
8
8
 
9
- def initialize(patient, _event = Event::Unknown.new)
9
+ def initialize(patient, _letter, _event = Event::Unknown.new)
10
10
  @patient = patient
11
11
  super(prescriptions)
12
12
  end
@@ -3,7 +3,7 @@ require "renalware/letters/part"
3
3
  module Renalware
4
4
  module Letters
5
5
  class Part::Problems < DumbDelegator
6
- def initialize(patient, _event = Event::Unknown.new)
6
+ def initialize(patient, _letter, _event = Event::Unknown.new)
7
7
  @patient = patient
8
8
  super(patient.problems.includes(:notes))
9
9
  end
@@ -1,5 +1,7 @@
1
1
  require "renalware/letters/part"
2
2
 
3
+ # When rendered, the template in `to_partial_path` will be used, and our Part object here will be
4
+ # available in the partial as `recent_pathology_results`.
3
5
  module Renalware
4
6
  module Letters
5
7
  class Part::RecentPathologyResults < Part
@@ -16,19 +18,19 @@ module Renalware
16
18
  end
17
19
 
18
20
  def find_recent_pathology_results
19
- presenter = Pathology::CurrentObservationResults::Presenter.new
20
- descriptions = Letters::RelevantObservationDescription.all
21
- query = Pathology::CurrentObservationsForDescriptionsQuery.new(
22
- patient: @patient,
23
- descriptions: descriptions
24
- )
25
-
26
- # Only select display result with a value
27
- results = query.call.reject{ |result| result.result.blank? }
21
+ check_letter
22
+ range = Time.zone.at(1)..letter.pathology_timestamp
23
+ Renalware::Pathology::CurrentObservationsForDescriptionsQuery.new(
24
+ patient: patient,
25
+ descriptions: Renalware::Letters::RelevantObservationDescription.all
26
+ ).call.where(observed_at: range).reject{ |obs| obs.id.nil? }
27
+ end
28
28
 
29
- # Removes the header from the results, this will be unnecessary when
30
- # a custom Presenter is implemented
31
- presenter.present(results)[1..-1]
29
+ def check_letter
30
+ if letter.pathology_timestamp.blank?
31
+ raise ArgumentError,
32
+ "letter.pathology_timestamp cannot be nil when rendering letter pathology!"
33
+ end
32
34
  end
33
35
  end
34
36
  end
@@ -3,10 +3,11 @@ require "renalware/letters/part"
3
3
  module Renalware
4
4
  module Letters
5
5
  class Part
6
- attr_reader :patient, :event
6
+ attr_reader :patient, :letter, :event
7
7
 
8
- def initialize(patient, event)
8
+ def initialize(patient, letter, event)
9
9
  @patient = patient
10
+ @letter = letter
10
11
  @event = event
11
12
  end
12
13
  end
@@ -16,7 +16,7 @@ module Renalware
16
16
  allow_destroy: true,
17
17
  reject_if: :patient_or_primary_care_physician?
18
18
 
19
- validates_presence_of :addressee_id, if: :contact?
19
+ validates :addressee_id, presence: { if: :contact? }
20
20
 
21
21
  delegate :primary_care_physician?, :patient?, :contact?, to: :person_role
22
22
 
@@ -6,7 +6,9 @@ module Renalware
6
6
  belongs_to :user
7
7
  belongs_to :letter
8
8
 
9
- validates_presence_of :user, :letter, :signed_at
9
+ validates :user, presence: true
10
+ validates :letter, presence: true
11
+ validates :signed_at, presence: true
10
12
 
11
13
  def to_s
12
14
  name = user.full_name
@@ -32,13 +32,12 @@ module Renalware
32
32
  def call
33
33
  # Note:
34
34
  #
35
- # CurrentObservation.where(patient: @patient, description_name: @descriptions.map(&:name))
35
+ # CurrentObservation.where(patient: patient, description_name: descriptions.map(&:name))
36
36
  #
37
37
  # is potentially a replacement for the SQL below, but it does not return
38
38
  # null values. We'd need a bit of SQL to join again onto pathology_observation_descriptions
39
39
  # and fill the missing observations with NULLs in order to keep the output of this query
40
40
  # the same.
41
-
42
41
  Observation
43
42
  .includes(:description)
44
43
  .select(<<-SQL)
@@ -58,10 +57,14 @@ module Renalware
58
57
  .order("pathology_observation_descriptions.id")
59
58
  .ordered
60
59
  .where(["pathology_observation_requests.patient_id = ? OR " \
61
- "pathology_observation_requests.patient_id IS NULL", @patient.id])
62
- .where(pathology_observation_descriptions: { id: @descriptions })
60
+ "pathology_observation_requests.patient_id IS NULL", patient.id])
61
+ .where(pathology_observation_descriptions: { id: descriptions })
63
62
  end
64
63
  # rubocop:enable Metrics/MethodLength
64
+
65
+ private
66
+
67
+ attr_reader :patient, :descriptions
65
68
  end
66
69
  end
67
70
  end
@@ -1,9 +1,8 @@
1
1
  require_dependency "renalware/pathology"
2
2
 
3
+ # Responsible for finding Observations for the specified descriptions.
3
4
  module Renalware
4
5
  module Pathology
5
- # Responsible for finding Observations for the specified descriptions.
6
- #
7
6
  class ObservationsForDescriptionsQuery
8
7
  def initialize(relation: Observation.all, descriptions: ObservationDescription.all)
9
8
  @relation = relation
@@ -10,7 +10,7 @@ module Renalware
10
10
 
11
11
  validates :patient, presence: true
12
12
  validates :user, presence: true
13
- validates_uniqueness_of :user_id, scope: [:patient_id, :deleted_at]
13
+ validates :user_id, uniqueness: { scope: [:patient_id, :deleted_at] }
14
14
 
15
15
  scope :ordered, -> { order(urgent: :desc, updated_at: :asc) }
16
16
  end
@@ -18,10 +18,6 @@ module Renalware
18
18
  delegate :to_s, to: :first
19
19
  alias_method :to_sym, :name
20
20
 
21
- def initialize(patient)
22
- @patient = patient
23
- end
24
-
25
21
  Identifier = Struct.new(:name, :id) do
26
22
  def to_s
27
23
  return "" unless id
@@ -29,6 +25,10 @@ module Renalware
29
25
  end
30
26
  end
31
27
 
28
+ def initialize(patient)
29
+ @patient = patient
30
+ end
31
+
32
32
  def first
33
33
  @first ||= Identifier.new(*all.first)
34
34
  end
@@ -8,9 +8,9 @@ module Renalware
8
8
 
9
9
  accepts_nested_attributes_for :address, allow_destroy: true
10
10
 
11
- validates_presence_of :name
12
- validates_presence_of :address
13
- validates_presence_of :code
11
+ validates :name, presence: true
12
+ validates :address, presence: true
13
+ validates :code, presence: true
14
14
  end
15
15
  end
16
16
  end
@@ -18,8 +18,8 @@ module Renalware
18
18
 
19
19
  validates_with PrimaryCarePhysicians::AddressValidator
20
20
  validates :email, email: true, allow_blank: true
21
- validates_uniqueness_of :code
22
- validates_presence_of :practitioner_type
21
+ validates :code, uniqueness: true
22
+ validates :practitioner_type, presence: true
23
23
 
24
24
  scope :ordered, -> { order(family_name: :asc) }
25
25
 
@@ -0,0 +1,63 @@
1
+ require_dependency "renalware/renal"
2
+
3
+ module Renalware
4
+ module Renal
5
+ module LowClearance
6
+ class MDMPatientsQuery
7
+ include ModalityScopes
8
+ DEFAULT_SEARCH_PREDICATE = "ure_date ASC".freeze
9
+ attr_reader :query, :relation, :named_filter
10
+
11
+ def initialize(relation: Patient.all, query: nil, named_filter: nil)
12
+ @query = query || {}
13
+ @named_filter = named_filter || :none
14
+ @query[:s] = DEFAULT_SEARCH_PREDICATE if @query[:s].blank?
15
+ @relation = relation
16
+ end
17
+
18
+ def call
19
+ search.result
20
+ end
21
+
22
+ def search
23
+ @search ||= begin
24
+ relation
25
+ .extending(PatientPathologyScopes)
26
+ .extending(ModalityScopes)
27
+ .extending(NamedFilterScopes)
28
+ .with_current_key_pathology
29
+ .with_current_modality_of_class(LowClearance::ModalityDescription)
30
+ .public_send(named_filter.to_s)
31
+ .search(query)
32
+ end
33
+ end
34
+
35
+ module NamedFilterScopes
36
+ def none
37
+ self # NOOP
38
+ end
39
+
40
+ def on_worryboard
41
+ joins("RIGHT OUTER JOIN patient_worries ON patient_worries.patient_id = patients.id")
42
+ end
43
+
44
+ def tx_candidates
45
+ self
46
+ end
47
+
48
+ def urea
49
+ where("pathology_current_key_observation_sets.ure_result::float >= 30")
50
+ end
51
+
52
+ def hgb_low
53
+ where("pathology_current_key_observation_sets.hgb_result::float < 100")
54
+ end
55
+
56
+ def hgb_high
57
+ where("pathology_current_key_observation_sets.hgb_result::float > 130")
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,13 @@
1
+ require_dependency "renalware/renal"
2
+
3
+ module Renalware
4
+ module Renal
5
+ module LowClearance
6
+ class ModalityDescription < Modalities::Description
7
+ def to_sym
8
+ :low_clearance
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -7,6 +7,8 @@ module Renalware
7
7
  include Document::Base
8
8
  extend Enumerize
9
9
 
10
+ has_paper_trail class_name: "Renalware::Renal::Version"
11
+
10
12
  belongs_to :patient, touch: true
11
13
  belongs_to :prd_description
12
14
  has_one :address_at_diagnosis, as: :addressable, class_name: "Address"
@@ -36,7 +36,7 @@ module Renalware
36
36
  @search ||= relation.ransack(query_params)
37
37
  end
38
38
 
39
- def self.missing_data_for(patient)
39
+ def self.missing_data_for(_patient)
40
40
  [
41
41
  :cause_of_death
42
42
  ]
@@ -0,0 +1,9 @@
1
+ require_dependency "renalware/accesses"
2
+
3
+ module Renalware
4
+ module Renal
5
+ class Version < PaperTrail::Version
6
+ self.table_name = :renal_versions
7
+ end
8
+ end
9
+ end
@@ -9,5 +9,9 @@ module Renalware
9
9
  def self.cast_patient(patient)
10
10
  ActiveType.cast(patient, ::Renalware::Renal::Patient)
11
11
  end
12
+
13
+ module LowClearance
14
+ MDM_FILTERS = %w(urea hgb_low hgb_high on_worryboard).freeze # tx_candidates
15
+ end
12
16
  end
13
17
  end
@@ -1,10 +1,11 @@
1
1
  module Renalware
2
2
  class Role < ApplicationRecord
3
- ROLES = %i(devops super_admin admin clinician read_only).freeze
3
+ ROLES = %i(devops super_admin admin clinical read_only).freeze
4
4
 
5
- has_and_belongs_to_many :users, join_table: :roles_users
5
+ has_many :roles_users, dependent: :destroy
6
+ has_many :users, through: :roles_users
6
7
 
7
- validates_uniqueness_of :name
8
+ validates :name, uniqueness: true
8
9
 
9
10
  def self.fetch(ids)
10
11
  return none if Array.wrap(ids).empty?
@@ -0,0 +1,6 @@
1
+ module Renalware
2
+ class RolesUser < ApplicationRecord
3
+ belongs_to :role
4
+ belongs_to :user
5
+ end
6
+ end
@@ -0,0 +1,16 @@
1
+ require_dependency "renalware/system"
2
+
3
+ module Renalware
4
+ module System
5
+ class UserFeedback < ApplicationRecord
6
+ extend Enumerize
7
+ validates :author, presence: true
8
+ validates :category, presence: true
9
+ validates :comment, presence: true
10
+
11
+ belongs_to :author, class_name: "User"
12
+
13
+ enumerize :category, in: %i(general bug missing_feature), default: :general
14
+ end
15
+ end
16
+ end
@@ -3,6 +3,9 @@ require_dependency "renalware/transplants"
3
3
  module Renalware
4
4
  module Transplants
5
5
  class DonorModalityDescription < Modalities::Description
6
+ def to_sym
7
+ :transplant
8
+ end
6
9
  end
7
10
  end
8
11
  end
@@ -3,6 +3,9 @@ require_dependency "renalware/transplants"
3
3
  module Renalware
4
4
  module Transplants
5
5
  class RecipientModalityDescription < Modalities::Description
6
+ def to_sym
7
+ :transplant
8
+ end
6
9
  end
7
10
  end
8
11
  end
@@ -3,18 +3,21 @@ module Renalware
3
3
  include Deviseable
4
4
  include Personable
5
5
 
6
- has_and_belongs_to_many :roles, join_table: :roles_users
6
+ has_many :roles_users, dependent: :destroy
7
+ has_many :roles, through: :roles_users
7
8
 
8
9
  validates :username, presence: true, uniqueness: true
9
- validates_presence_of :given_name
10
- validates_presence_of :family_name
10
+ validates :given_name, presence: true
11
+ validates :family_name, presence: true
11
12
  validate :approval_with_roles, on: :update
12
- validates_presence_of :professional_position,
13
- on: :update,
14
- unless: :skip_validation
15
- validates_presence_of :signature,
16
- on: :update,
17
- unless: :skip_validation
13
+ validates :professional_position, presence: {
14
+ on: :update,
15
+ unless: :skip_validation
16
+ }
17
+ validates :signature, presence: {
18
+ on: :update,
19
+ unless: :skip_validation
20
+ }
18
21
 
19
22
  scope :unapproved, -> { where(approved: [nil, false]) }
20
23
  scope :inactive, lambda {
@@ -38,9 +41,11 @@ module Renalware
38
41
  %i(unapproved inactive)
39
42
  end
40
43
 
44
+ # rubocop:disable Naming/PredicateName
41
45
  def has_role?(name)
42
46
  role_names.include?(name.to_s)
43
47
  end
48
+ # rubocop:enable Naming/PredicateName
44
49
 
45
50
  def role_names
46
51
  @role_names ||= roles.pluck(:name)
@@ -1,10 +1,7 @@
1
1
  module Renalware
2
- def self.table_name_prefix
3
- # 'renalware_' # TODO: eventually, prefix the tables
4
- ""
5
- end
6
-
2
+ # :nocov
7
3
  def self.use_relative_model_naming?
8
4
  true
9
5
  end
6
+ # :nocov
10
7
  end
@@ -70,7 +70,7 @@ module Renalware
70
70
  end
71
71
 
72
72
  def has_write_privileges?
73
- user_is_super_admin? || user_is_admin? || user_is_clinician?
73
+ user_is_super_admin? || user_is_admin? || user_is_clinical?
74
74
  end
75
75
 
76
76
  def has_any_role?
@@ -0,0 +1,8 @@
1
+ require_dependency "renalware/snippets"
2
+
3
+ module Renalware
4
+ module System
5
+ class UserFeedbackPolicy < BasePolicy
6
+ end
7
+ end
8
+ end