renalware-core 2.0.139 → 2.0.140

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/renalware/rollup_compiled.js +50 -0
  3. data/app/assets/stylesheets/renalware/medications_pdf.scss +17 -1
  4. data/app/assets/stylesheets/renalware/modules/_medications.scss +17 -0
  5. data/app/assets/stylesheets/renalware/partials/_utilities.scss +8 -0
  6. data/app/controllers/renalware/medications/home_delivery/events_controller.rb +134 -0
  7. data/app/javascript/renalware/controllers/foundation_modal_controller.js +19 -0
  8. data/app/javascript/renalware/controllers/medications/home_delivery_modal_controller.js +24 -0
  9. data/app/javascript/renalware/index.js +4 -0
  10. data/app/models/renalware/drugs/homecare_form.rb +17 -0
  11. data/app/models/renalware/drugs/supplier.rb +12 -0
  12. data/app/models/renalware/feeds/hl7_message.rb +2 -2
  13. data/app/models/renalware/medications.rb +6 -0
  14. data/app/models/renalware/medications/delivery/event.rb +48 -0
  15. data/app/models/renalware/medications/delivery/event_prescription.rb +24 -0
  16. data/app/models/renalware/medications/delivery/homecare_forms_adapter.rb +104 -0
  17. data/app/models/renalware/medications/delivery/purchase_order_number.rb +27 -0
  18. data/app/models/renalware/medications/prescriptions_by_drug_type_id_query.rb +21 -0
  19. data/app/models/renalware/medications/provider.rb +20 -0
  20. data/app/views/renalware/medications/home_delivery/events/_edit.html.slim +71 -0
  21. data/app/views/renalware/medications/home_delivery/events/edit.html.slim +1 -0
  22. data/app/views/renalware/medications/home_delivery/events/edit.js.erb +4 -0
  23. data/app/views/renalware/medications/home_delivery/events/new.js.erb +3 -0
  24. data/app/views/renalware/medications/home_delivery/events/update.js.erb +5 -0
  25. data/app/views/renalware/medications/home_delivery/prescriptions/index.pdf.slim +4 -1
  26. data/app/views/renalware/medications/prescriptions/_form.html.slim +4 -0
  27. data/app/views/renalware/medications/prescriptions/index.html.slim +15 -5
  28. data/app/views/renalware/shared/_modal_close_link.html.slim +1 -1
  29. data/config/routes/medications.rb +5 -4
  30. data/db/migrate/20200301113102_create_drug_homecare_suppliers.rb +73 -0
  31. data/db/migrate/20200301124200_create_medication_delivery_events.rb +49 -0
  32. data/db/migrate/20200301124300_create_medication_delivery_event_prescriptions.rb +35 -0
  33. data/db/migrate/20200306183423_add_next_delivery_date_to_prescriptions.rb +7 -0
  34. data/lib/renalware/configuration.rb +7 -0
  35. data/lib/renalware/engine.rb +1 -0
  36. data/lib/renalware/version.rb +1 -1
  37. data/spec/factories/drugs/homecare_forms.rb +13 -0
  38. data/spec/factories/drugs/suppliers.rb +7 -0
  39. data/spec/factories/medications/delivery/events.rb +13 -0
  40. data/spec/support/pages/medications/home_delivery_dialog.rb +77 -0
  41. metadata +39 -13
  42. data/app/controllers/renalware/medications/home_delivery/prescriptions_controller.rb +0 -51
  43. data/app/models/renalware/letters/printing/create_pdf_by_interleaving_address_sheet_and_letter_for_each_recipient.rb.dead +0 -90
  44. data/app/models/renalware/pathology/consultant.rb.dead +0 -10
  45. data/app/models/renalware/pathology/view_observation_results.rb.dead +0 -64
  46. data/app/models/renalware/patients/ingestion/update_master_patient_index_job.rb.dead +0 -20
  47. data/app/presenters/renalware/admin/users/summary_part.rb.dead +0 -25
  48. data/app/presenters/renalware/ukrdc/modality_presenter.rb.dead +0 -8
  49. data/app/views/renalware/admin/users/_summary_part.html.slim.dead +0 -4
  50. data/app/views/renalware/letters/lists/index.html.slim.dead +0 -101
  51. data/app/views/renalware/letters/lists/index.html.slim.dead1 +0 -90
  52. data/app/views/renalware/mdm/_biopsies.html.slim.dead +0 -18
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "renalware/medications"
4
+
5
+ module Renalware
6
+ module Medications
7
+ module Delivery
8
+ # Takes
9
+ # - a patient
10
+ # - a homecare delivery_event
11
+ # and build Args used to pass to Renalware::Forms::Homecare::Pdf.generate
12
+ class HomecareFormsAdapter
13
+ pattr_initialize [:delivery_event!]
14
+ delegate :homecare_form, :patient, to: :delivery_event
15
+
16
+ def call
17
+ Forms::Homecare::Pdf.generate(build_args)
18
+ end
19
+
20
+ def valid?(args)
21
+ Forms::Homecare::Pdf.valid?(args)
22
+ end
23
+
24
+ def build_args
25
+ args = Forms::Homecare::Args.new(
26
+ provider: homecare_form.form_name,
27
+ version: homecare_form.form_version,
28
+ family_name: patient.family_name,
29
+ given_name: patient.given_name,
30
+ title: patient.title,
31
+ born_on: patient.born_on,
32
+ nhs_number: patient.nhs_number,
33
+ telephone: patient.telephone1,
34
+ hospital_number: patient.local_patient_id,
35
+ address: [],
36
+ modality: patient.current_modality&.description&.to_s,
37
+ po_number: delivery_event.reference_number,
38
+ drug_type: delivery_event.drug_type.name,
39
+ selected_prescription_duration: selected_prescription_duration,
40
+ prescription_durations: prescription_durations,
41
+ consultant: patient.named_consultant&.to_s,
42
+ generated_at: Time.zone.now,
43
+ hospital_name: Renalware.config.hospital_name,
44
+ hospital_address: hospital_address
45
+ )
46
+
47
+ if patient.current_address
48
+ add = patient.current_address
49
+ args.address = [
50
+ add.street_1,
51
+ add.street_2,
52
+ add.street_3,
53
+ add.town
54
+ ]
55
+ args.postcode = add.postcode
56
+ end
57
+
58
+ prescriptions.each do |prescription|
59
+ args.medications << Forms::Homecare::Args::Medication.new(
60
+ date: prescription.prescribed_on,
61
+ drug: prescription.drug.name,
62
+ dose: "#{prescription.dose_amount} #{prescription.dose_unit}",
63
+ route: prescription.medication_route&.name,
64
+ frequency: prescription.frequency
65
+ )
66
+ end
67
+
68
+ clinical_patient = Clinical.cast_patient(patient)
69
+ args.no_known_allergies = (clinical_patient.allergy_status == :no_known_allergies)
70
+ args.allergies = Array(clinical_patient.allergies).map(&:description)
71
+ args
72
+ end
73
+
74
+ private
75
+
76
+ def hospital_address
77
+ Renalware.config.hospital_address&.split(",")&.map(&:strip)
78
+ end
79
+
80
+ # Return e.g. "3 months"
81
+ def selected_prescription_duration
82
+ duration = delivery_event.prescription_duration.to_i
83
+ unit = delivery_event.homecare_form.prescription_duration_unit
84
+
85
+ "#{duration} #{unit.pluralize(duration)}"
86
+ end
87
+
88
+ def prescription_durations
89
+ homecare_form.prescription_durations.map do |dur|
90
+ "#{dur} #{homecare_form.prescription_duration_unit.pluralize(dur)}"
91
+ end
92
+ end
93
+
94
+ def prescriptions
95
+ PrescriptionsByDrugTypeIdQuery.new(
96
+ patient: delivery_event.patient,
97
+ drug_type_id: delivery_event.drug_type_id,
98
+ provider: :home_delivery
99
+ ).call
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "renalware/medications"
4
+
5
+ module Renalware
6
+ module Medications
7
+ module Delivery
8
+ class PurchaseOrderNumber
9
+ SEQ_NAME = "renalware.medication_delivery_purchase_order_number_seq"
10
+
11
+ class << self
12
+ def next_number
13
+ result = ApplicationRecord.connection.execute("SELECT nextval('#{SEQ_NAME}');")
14
+ result.first["nextval"]
15
+ end
16
+
17
+ def next
18
+ [
19
+ Renalware.config.medication_delivery_purchase_order_prefix,
20
+ next_number
21
+ ].join
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ module Medications
5
+ class PrescriptionsByDrugTypeIdQuery
6
+ pattr_initialize [:drug_type_id!, :patient!, provider: nil]
7
+
8
+ def call
9
+ results = patient
10
+ .prescriptions
11
+ .current
12
+ .includes(:medication_route, :drug)
13
+ .includes(patient: { current_modality: :description })
14
+ .eager_load(drug: [:drug_types])
15
+ .where("drug_types.id": drug_type_id)
16
+
17
+ provider.present? ? results.where(provider: provider) : results
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # frozen_string_literal: true
4
+
3
5
  require_dependency "renalware/medications"
4
6
 
5
7
  module Renalware
@@ -11,3 +13,21 @@ module Renalware
11
13
  end
12
14
  end
13
15
  end
16
+
17
+ # require_dependency "renalware/medications"
18
+
19
+ # module Renalware
20
+ # module Medications
21
+ # class Provider < ApplicationRecord
22
+ # validates :name, presence: true
23
+ # validates :code, presence: true
24
+ # has_many :provider_drug_types, dependent: :restrict_with_exception
25
+ # has_many :drug_types, through: :provider_drug_types
26
+
27
+ # # TODOL: read from db
28
+ # def self.codes
29
+ # %i(gp hospital home_delivery)
30
+ # end
31
+ # end
32
+ # end
33
+ # end
@@ -0,0 +1,71 @@
1
+ / This modal asks the user whether they successfully printed the homecare delivery form.
2
+ / If it was successful, we make a call to update event#printed = true and then dismiss the form
3
+ / (see update.js.erb)
4
+ .modal
5
+ = simple_form_for(event,
6
+ url: patient_medications_home_delivery_event_path(id: event.id),
7
+ remote: true,
8
+ authenticity_token: true,
9
+ method: :patch,
10
+ data: { target: "home-delivery-modal.form" },
11
+ as: :event) do |f|
12
+
13
+ .modal__header
14
+ h2
15
+ | Print home delivery drugs
16
+ span= " PO: #{event.reference_number}"
17
+ = render "renalware/shared/modal_close_link"
18
+
19
+ .modal__body
20
+ #error-message
21
+ = render "renalware/shared/errors", model: event
22
+
23
+ / There are 2 main divs in the modal
24
+ / - the first is initially displayed and has the print options and a print button
25
+ / - the second is displayed once Print has been clicked, and asked asks for feedback as to
26
+ / whether printing was successful or not. It it was successful we set
27
+ .form-fields data-target="home-delivery-modal.printOptions"
28
+ - homecare_forms = Renalware::Drugs::HomecareForm.all
29
+ = f.association :drug_type,
30
+ collection: Renalware::Drugs::Type.where(id: homecare_forms.map(&:drug_type_id)),
31
+ include_blank: false,
32
+ input_html: { \
33
+ data: { \
34
+ action: "change->home-delivery-modal#refreshForm", \
35
+ target: "home-delivery-modal.drugtype" \
36
+ } \
37
+ },
38
+ wrapper: :horizontal_medium
39
+
40
+ = f.input :prescription_duration,
41
+ collection: event.homecare_form.prescription_durations,
42
+ include_blank: false,
43
+ label_method: lambda { |dur| \
44
+ "#{dur} #{event.homecare_form.prescription_duration_unit.pluralize(dur)}" \
45
+ },\
46
+ wrapper: :horizontal_medium,
47
+ input_html: { data: { action: "change->home-delivery-modal#refreshForm" } }
48
+
49
+ .panel
50
+ u= "Homecare supply form"
51
+ br
52
+ = "#{event.homecare_form&.supplier&.name} '#{event.homecare_form&.form_name} version #{event.homecare_form&.form_version}'"
53
+
54
+ - disabled_args = event.errors.any? ? { disabled: "disabled" } : {}
55
+ = link_to "Print",
56
+ renalware.patient_medications_home_delivery_event_path(id: event.id, format: :pdf),
57
+ target: "_blank",
58
+ class: "button primary right home-delivery--print",
59
+ data: { action: "click->home-delivery-modal#askForPrintFeedback" },
60
+ **disabled_args
61
+
62
+ .show-after-printing.visuallyhidden data-target="home-delivery-modal.printFeedback"
63
+
64
+ h2 Was printing successful?
65
+ .right
66
+ = link_to "No - I didnt print anything",
67
+ "#",
68
+ class: "button secondary reveal-modal-close",
69
+ "aria-label" => "Close"
70
+
71
+ = f.submit "Yes - mark as printed", class: "button primary ", name: "event[printed]"
@@ -0,0 +1 @@
1
+ = render "edit", event: event
@@ -0,0 +1,4 @@
1
+ // Something about the form changed (eg drugtype dropdown changed) causing a submission
2
+ // so we re re-display the form here.
3
+ var modal = $("#print-home-delivery-drugs-modal")
4
+ $(modal).html("<%= j(render 'edit', event: event, format: :html) %>");
@@ -0,0 +1,3 @@
1
+ $("#print-home-delivery-drugs-modal #error-message").html(
2
+ '<%= message + ": " + event.errors.full_messages.join(", ") %>'
3
+ );
@@ -0,0 +1,5 @@
1
+ // User indicated the homecare form was successfully printed, so we updated
2
+ // the printed flag to true and are no dismissing the dialog.
3
+ // TODO: Ideally we would call the stimulus controller action here
4
+ $("#print-home-delivery-drugs-modal").foundation('reveal', 'close');
5
+ $("#print-home-delivery-drugs-modal").html("")
@@ -7,7 +7,10 @@ html
7
7
  head
8
8
  = wicked_pdf_stylesheet_link_tag "renalware/medications_pdf"
9
9
  heading
10
- .our-ref= "RW ref: #{patient.hospital_identifier}"
10
+ .references
11
+ .purchase_order_no= "PO: #{purchase_order_number}"
12
+ .our-ref= "RW ref: #{patient.hospital_identifier}"
13
+ .drug_types= "Drug types: #{drug_types.map(&:name).join(", ")}"
11
14
  span.logo
12
15
  = wicked_pdf_image_tag "renalware/NHS-Black.jpg", width: 50
13
16
  .address
@@ -48,6 +48,10 @@ ruby:
48
48
  as: :date_picker,
49
49
  wrapper: :horizontal_datepicker
50
50
 
51
+ = f.input :next_delivery_date,
52
+ as: :date_picker,
53
+ wrapper: :horizontal_datepicker
54
+
51
55
  .row.actions
52
56
  .small-9.columns
53
57
  = f.button :submit, "Save"
@@ -12,11 +12,21 @@
12
12
  i.fas.fa-print
13
13
  | Print
14
14
  |&nbsp;
15
- = link_to patient_medications_home_delivery_prescriptions_path(@patient),
16
- class: "button secondary with-icon",
17
- target: :blank do
18
- i.fa.fa-print
19
- | Print home delivery drugs
15
+
16
+ span(data-controller="foundation-modal",
17
+ data-foundation-modal-url=new_patient_medications_home_delivery_event_path(patient))
18
+ = link_to "#",
19
+ class: "button secondary with-icon",
20
+ target: :blank,
21
+ id: "show-home-delivery-modal",
22
+ data: { action: "click->foundation-modal#openRemotePartial" } do
23
+ i.fa.fa-print
24
+ | Print home delivery drugs
25
+ #print-home-delivery-drugs-modal.reveal-modal.small(data-reveal
26
+ data-refresh-url=request.original_fullpath
27
+ data-target="foundation-modal.container"
28
+ data-controller="home-delivery-modal"
29
+ data-home-delivery-url1=new_patient_medications_home_delivery_event_url(@patient))
20
30
 
21
31
  = within_patient_layout(title: "Prescriptions") do
22
32
  = render "filter_form", search: current_search, drug_types: drug_types, treatable: treatable
@@ -1,4 +1,4 @@
1
1
  = link_to "#",
2
2
  "aria-label" => "Close",
3
- class: "reveal-modal-close" do
3
+ class: "reveal-modal-close close-x" do
4
4
  i.fas.fa-window-close
@@ -4,10 +4,11 @@ resources :patients, only: [] do
4
4
  resources :prescriptions, controller: "medications/prescriptions", except: [:destroy]
5
5
  namespace :medications do
6
6
  namespace :home_delivery do
7
- resources :prescriptions,
8
- only: [:index],
9
- constraints: { format: /(pdf)/ },
10
- defaults: { format: :pdf }
7
+ resources :events, only: [:new, :create, :edit, :update, :show]
8
+ # resources :prescriptions,
9
+ # only: [:index],
10
+ # constraints: { format: /(pdf)/ },
11
+ # defaults: { format: :pdf }
11
12
  end
12
13
  resources :prescriptions, only: [] do
13
14
  resource :termination, only: [:new, :create]
@@ -0,0 +1,73 @@
1
+ class CreateDrugHomecareSuppliers < ActiveRecord::Migration[5.2]
2
+ def change
3
+ within_renalware_schema do
4
+ create_enum :duration, %w(minute hour day week month year)
5
+
6
+ create_table(
7
+ :drug_suppliers,
8
+ comment: "A list of suppliers who deliver drugs eg for homecare"
9
+ ) do |t|
10
+ t.string(
11
+ :name,
12
+ null: false,
13
+ comment: "The providers display name e.g. 'Fresenius'"
14
+ )
15
+ t.timestamps
16
+ end
17
+
18
+ # Has many through
19
+ create_table(
20
+ :drug_homecare_forms,
21
+ comment: "X-ref table that says which drug_type is supplied by which (homecare) supplier "\
22
+ "and the data required (see form_name and form_version) to programmatically "\
23
+ "select and create the right PDF Homecare Supply form for them (using the " \
24
+ "renalware-forms gem) so this can be printed out and signed."
25
+ ) do |t|
26
+ t.references :drug_type, null: false
27
+ t.references :supplier, null: false, foreign_key: { to_table: :drug_suppliers }
28
+
29
+ t.string(
30
+ :form_name,
31
+ null: false,
32
+ comment: "The lower-case programmatic name used for this provider, eg 'fresenius'"
33
+ )
34
+ t.string(
35
+ :form_version,
36
+ null: false,
37
+ comment: "A number e.g. '1' that specified what version of the homecare supply form" \
38
+ "should be created"
39
+ )
40
+ t.string(
41
+ :prescription_durations,
42
+ null: false,
43
+ array: true,
44
+ default: [],
45
+ comment: "An array of options where each integer is a number of units - these will be "\
46
+ "displayed as dropdown options presented to the user, and checkboxes "\
47
+ "on the homecare delivery form PDF. E.g [3,6] will "\
48
+ "be displayed as options '3 months' and '6 months' (see also "\
49
+ "prescription_duration_unit)"
50
+ )
51
+ t.integer(
52
+ :prescription_duration_default,
53
+ null: true,
54
+ comment: "The default option to pre-select when displaying prescription_duration_options"
55
+ )
56
+ t.enum(
57
+ :prescription_duration_unit,
58
+ null: false,
59
+ enum_name: :duration,
60
+ comment: "E.g. 'week' or 'month'"
61
+ )
62
+ t.timestamps null: false
63
+ end
64
+
65
+ add_index(
66
+ :drug_homecare_forms,
67
+ [:drug_type_id, :supplier_id],
68
+ unique: true,
69
+ comment: "A supplier can only have one form active for any drug type"
70
+ )
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,49 @@
1
+ class CreateMedicationDeliveryEvents < ActiveRecord::Migration[5.2]
2
+ def change
3
+ within_renalware_schema do
4
+ create_table :medication_delivery_events do |t|
5
+ t.references(
6
+ :homecare_form,
7
+ foreign_key: { to_table: :drug_homecare_forms },
8
+ index: true,
9
+ null: false
10
+ )
11
+ t.references(
12
+ :drug_type,
13
+ foreign_key: { to_table: :drug_types },
14
+ index: true,
15
+ null: false
16
+ )
17
+ t.references(:patient, index: true, null: false)
18
+ t.string :reference_number, null: true
19
+ t.integer :prescription_duration
20
+ t.boolean :printed, default: false, null: false
21
+ t.references :created_by, foreign_key: { to_table: :users }, index: true, null: false
22
+ t.references :updated_by, foreign_key: { to_table: :users }, index: true, null: false
23
+ t.datetime :deleted_at, index: true
24
+ t.timestamps null: false
25
+ end
26
+
27
+ # Create a sequence to generate home_delivery etc purchase order numbers.
28
+ # These aren't guaranteed to be contiguous because of the way we use them.
29
+ reversible do |direction|
30
+ direction.up do
31
+ connection.execute(<<-SQL.squish)
32
+ CREATE SEQUENCE renalware.medication_delivery_purchase_order_number_seq
33
+ AS integer
34
+ START WITH 100
35
+ INCREMENT BY 1
36
+ NO MINVALUE
37
+ NO MAXVALUE
38
+ CACHE 1;
39
+ SQL
40
+ end
41
+ direction.down do
42
+ connection.execute(
43
+ "drop sequence if exists renalware.medication_delivery_purchase_order_number_seq;"
44
+ )
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end