renalware-core 2.0.139 → 2.0.140
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/renalware/rollup_compiled.js +50 -0
- data/app/assets/stylesheets/renalware/medications_pdf.scss +17 -1
- data/app/assets/stylesheets/renalware/modules/_medications.scss +17 -0
- data/app/assets/stylesheets/renalware/partials/_utilities.scss +8 -0
- data/app/controllers/renalware/medications/home_delivery/events_controller.rb +134 -0
- data/app/javascript/renalware/controllers/foundation_modal_controller.js +19 -0
- data/app/javascript/renalware/controllers/medications/home_delivery_modal_controller.js +24 -0
- data/app/javascript/renalware/index.js +4 -0
- data/app/models/renalware/drugs/homecare_form.rb +17 -0
- data/app/models/renalware/drugs/supplier.rb +12 -0
- data/app/models/renalware/feeds/hl7_message.rb +2 -2
- data/app/models/renalware/medications.rb +6 -0
- data/app/models/renalware/medications/delivery/event.rb +48 -0
- data/app/models/renalware/medications/delivery/event_prescription.rb +24 -0
- data/app/models/renalware/medications/delivery/homecare_forms_adapter.rb +104 -0
- data/app/models/renalware/medications/delivery/purchase_order_number.rb +27 -0
- data/app/models/renalware/medications/prescriptions_by_drug_type_id_query.rb +21 -0
- data/app/models/renalware/medications/provider.rb +20 -0
- data/app/views/renalware/medications/home_delivery/events/_edit.html.slim +71 -0
- data/app/views/renalware/medications/home_delivery/events/edit.html.slim +1 -0
- data/app/views/renalware/medications/home_delivery/events/edit.js.erb +4 -0
- data/app/views/renalware/medications/home_delivery/events/new.js.erb +3 -0
- data/app/views/renalware/medications/home_delivery/events/update.js.erb +5 -0
- data/app/views/renalware/medications/home_delivery/prescriptions/index.pdf.slim +4 -1
- data/app/views/renalware/medications/prescriptions/_form.html.slim +4 -0
- data/app/views/renalware/medications/prescriptions/index.html.slim +15 -5
- data/app/views/renalware/shared/_modal_close_link.html.slim +1 -1
- data/config/routes/medications.rb +5 -4
- data/db/migrate/20200301113102_create_drug_homecare_suppliers.rb +73 -0
- data/db/migrate/20200301124200_create_medication_delivery_events.rb +49 -0
- data/db/migrate/20200301124300_create_medication_delivery_event_prescriptions.rb +35 -0
- data/db/migrate/20200306183423_add_next_delivery_date_to_prescriptions.rb +7 -0
- data/lib/renalware/configuration.rb +7 -0
- data/lib/renalware/engine.rb +1 -0
- data/lib/renalware/version.rb +1 -1
- data/spec/factories/drugs/homecare_forms.rb +13 -0
- data/spec/factories/drugs/suppliers.rb +7 -0
- data/spec/factories/medications/delivery/events.rb +13 -0
- data/spec/support/pages/medications/home_delivery_dialog.rb +77 -0
- metadata +39 -13
- data/app/controllers/renalware/medications/home_delivery/prescriptions_controller.rb +0 -51
- data/app/models/renalware/letters/printing/create_pdf_by_interleaving_address_sheet_and_letter_for_each_recipient.rb.dead +0 -90
- data/app/models/renalware/pathology/consultant.rb.dead +0 -10
- data/app/models/renalware/pathology/view_observation_results.rb.dead +0 -64
- data/app/models/renalware/patients/ingestion/update_master_patient_index_job.rb.dead +0 -20
- data/app/presenters/renalware/admin/users/summary_part.rb.dead +0 -25
- data/app/presenters/renalware/ukrdc/modality_presenter.rb.dead +0 -8
- data/app/views/renalware/admin/users/_summary_part.html.slim.dead +0 -4
- data/app/views/renalware/letters/lists/index.html.slim.dead +0 -101
- data/app/views/renalware/letters/lists/index.html.slim.dead1 +0 -90
- 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,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
|
-
.
|
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
|
@@ -12,11 +12,21 @@
|
|
12
12
|
i.fas.fa-print
|
13
13
|
| Print
|
14
14
|
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
@@ -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 :
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|