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.
- 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
|