renalware-core 2.0.0.pre.rc13 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/stylesheets/renalware/base/_variables.scss +3 -3
- data/app/assets/stylesheets/renalware/modules/_clinical.scss +107 -4
- data/app/assets/stylesheets/renalware/modules/_patients.scss +0 -77
- data/app/assets/stylesheets/renalware/partials/_layout.scss +67 -7
- data/app/assets/stylesheets/renalware/partials/_navigation.scss +2 -7
- data/app/assets/stylesheets/renalware/partials/_tables.scss +1 -1
- data/app/controllers/renalware/base_controller.rb +5 -0
- data/app/controllers/renalware/clinics/visits_controller.rb +1 -1
- data/app/controllers/renalware/concerns/pdf_renderable.rb +2 -1
- data/app/controllers/renalware/devise/sessions_controller.rb +5 -0
- data/app/controllers/renalware/letters/pdf_letter_cache_controller.rb +13 -0
- data/app/controllers/renalware/pd/regimes_controller.rb +1 -1
- data/app/controllers/renalware/renal/aki_alerts_controller.rb +20 -3
- data/app/controllers/renalware/research/studies_controller.rb +3 -1
- data/app/controllers/renalware/session_timeout_controller.rb +1 -1
- data/app/models/renalware/letters/html_renderer.rb +2 -1
- data/app/models/renalware/letters/pdf_letter_cache.rb +4 -1
- data/app/models/renalware/letters/pdf_renderer.rb +2 -1
- data/app/models/renalware/pathology/create_observations_grouped_by_date_table.rb +0 -3
- data/app/models/renalware/pathology/observations_grouped_by_date_query.rb +7 -1
- data/app/models/renalware/pd/apd_regime.rb +6 -0
- data/app/models/renalware/renal/aki_alert.rb +1 -0
- data/app/models/renalware/renal/aki_alert_query.rb +32 -0
- data/app/models/renalware/renal/aki_alert_search_form.rb +31 -0
- data/app/models/renalware/system/event.rb +12 -0
- data/app/models/renalware/system/user_feedback.rb +3 -1
- data/app/models/renalware/system/visit.rb +11 -0
- data/app/presenters/renalware/events/summary_part.rb +3 -1
- data/app/presenters/renalware/letters/summary_part.rb +1 -1
- data/app/presenters/renalware/mdm_presenter.rb +4 -1
- data/app/presenters/renalware/medications/summary_part.rb +2 -0
- data/app/presenters/renalware/problems/summary_part.rb +4 -2
- data/app/presenters/renalware/summary_part.rb +4 -0
- data/app/views/renalware/accesses/procedures/_list.html.slim +7 -5
- data/app/views/renalware/accesses/profiles/_list.html.slim +5 -5
- data/app/views/renalware/admin/cache/show.html.slim +26 -2
- data/app/views/renalware/devise/sessions/_warning.html.slim +7 -0
- data/app/views/renalware/devise/sessions/new.html.slim +15 -21
- data/app/views/renalware/events/events/_summary_part.html.slim +1 -1
- data/app/views/renalware/events/events/cell/_investigation.html.slim +0 -2
- data/app/views/renalware/events/events/toggled_cell/_biopsy.html.slim +1 -1
- data/app/views/renalware/events/events/toggled_cell/_investigation.html.slim +1 -1
- data/app/views/renalware/events/events/toggled_cell/_simple.html.slim +1 -1
- data/app/views/renalware/events/events/toggled_cell/_swab.html.slim +1 -1
- data/app/views/renalware/hd/cannulation_types/_form.html.slim +7 -10
- data/app/views/renalware/hd/cannulation_types/edit.html.slim +2 -1
- data/app/views/renalware/hd/cannulation_types/index.html.slim +4 -3
- data/app/views/renalware/hd/cannulation_types/new.html.slim +2 -1
- data/app/views/renalware/hd/dialysers/_form.html.slim +8 -11
- data/app/views/renalware/hd/dialysers/edit.html.slim +2 -1
- data/app/views/renalware/hd/dialysers/index.html.slim +4 -3
- data/app/views/renalware/hd/dialysers/new.html.slim +2 -1
- data/app/views/renalware/layouts/_non_patient.html.slim +14 -13
- data/app/views/renalware/layouts/_patient.html.slim +5 -5
- data/app/views/renalware/letters/_summary_part.html.slim +1 -1
- data/app/views/renalware/letters/letters/show.html.slim +16 -15
- data/app/views/renalware/medications/_summary_part.html.slim +18 -17
- data/app/views/renalware/modalities/reasons/index.html.slim +1 -3
- data/app/views/renalware/navigation/_footer.html.slim +2 -2
- data/app/views/renalware/navigation/_help_items.html.slim +1 -0
- data/app/views/renalware/navigation/_more_help_items.html.slim +1 -0
- data/app/views/renalware/navigation/_user.html.slim +4 -0
- data/app/views/renalware/pathology/requests/requests/index.html.slim +40 -42
- data/app/views/renalware/pathology/requests/rules/index.html.slim +15 -18
- data/app/views/renalware/patients/_side_menu.html.slim +0 -1
- data/app/views/renalware/patients/alerts/_alert.html.slim +7 -7
- data/app/views/renalware/patients/alerts/_list.html.slim +1 -3
- data/app/views/renalware/patients/alerts/create.js.erb +1 -1
- data/app/views/renalware/patients/alerts/destroy.js.erb +1 -1
- data/app/views/renalware/patients/primary_care_physicians/_form.html.slim +22 -25
- data/app/views/renalware/patients/primary_care_physicians/edit.html.slim +2 -1
- data/app/views/renalware/patients/primary_care_physicians/index.html.slim +4 -3
- data/app/views/renalware/patients/primary_care_physicians/new.html.slim +2 -1
- data/app/views/renalware/patients/side_menu/_general.html.slim +1 -1
- data/app/views/renalware/pd/_apd_regimes.html.slim +4 -38
- data/app/views/renalware/pd/_capd_regimes.html.slim +4 -45
- data/app/views/renalware/pd/_regimes.html.slim +32 -0
- data/app/views/renalware/pd/assessments/_form.html.slim +8 -5
- data/app/views/renalware/pd/regimes/_apd_fields.html.slim +1 -0
- data/app/views/renalware/pd/regimes/_apd_regime_show.html.slim +2 -0
- data/app/views/renalware/pd/regimes/_current_apd_regime.html.slim +3 -0
- data/app/views/renalware/problems/problems/_summary_part.html.slim +1 -1
- data/app/views/renalware/renal/aki_alerts/_filters.html.slim +25 -0
- data/app/views/renalware/renal/aki_alerts/index.html.slim +18 -14
- data/app/views/renalware/research/_alert.html.slim +6 -0
- data/app/views/renalware/research/_alerts.html.slim +6 -0
- data/app/views/renalware/research/studies/index.html.slim +2 -0
- data/app/views/renalware/system/email_templates/index.html.slim +7 -8
- data/app/views/renalware/system/user_feedback/new.html.slim +3 -7
- data/app/views/renalware/transplants/mdm/_pathology_cmvdna.html.slim +0 -1
- data/app/views/renalware/virology/vaccinations/_toggled_cell.html.slim +1 -1
- data/config/initializers/ahoy.rb +14 -0
- data/config/locales/renalware/events/investigation.en.yml +8 -0
- data/config/locales/renalware/patients/side_menu.en.yml +1 -1
- data/config/routes.rb +1 -0
- data/db/migrate/20180307191650_add_dwell_time_to_pd_regime.rb +5 -0
- data/db/migrate/20180307223111_create_system_visits_and_events.rb +44 -0
- data/db/migrate/20180309140316_add_unique_constraint_to_obr_requestor.rb +5 -0
- data/db/migrate/20180311071146_update_patient_summaries_to_version6.rb +5 -0
- data/db/views/patient_summaries_v06.sql +16 -0
- data/lib/renalware/configuration.rb +3 -0
- data/lib/renalware/engine.rb +1 -1
- data/lib/renalware/version.rb +1 -1
- data/spec/factories/pathology/observation_requests.rb +3 -1
- metadata +34 -8
- data/app/assets/stylesheets/renalware/patient_pages.scss +0 -43
- data/app/views/renalware/hd/cannulation_types/_header.html.slim +0 -5
- data/app/views/renalware/hd/dialysers/_header.html.slim +0 -5
- data/app/views/renalware/patients/primary_care_physicians/_header.html.slim +0 -5
@@ -6,10 +6,14 @@ module Renalware
|
|
6
6
|
include Renalware::Concerns::Pageable
|
7
7
|
|
8
8
|
def index
|
9
|
-
|
10
|
-
|
9
|
+
query = search_form.query
|
10
|
+
alerts = query.call.page(page).per(per_page)
|
11
11
|
authorize alerts
|
12
|
-
render locals: {
|
12
|
+
render locals: {
|
13
|
+
alerts: alerts,
|
14
|
+
form: search_form,
|
15
|
+
search: query.search
|
16
|
+
}
|
13
17
|
end
|
14
18
|
|
15
19
|
def edit
|
@@ -28,6 +32,13 @@ module Renalware
|
|
28
32
|
|
29
33
|
private
|
30
34
|
|
35
|
+
def search_form
|
36
|
+
@search_form ||= begin
|
37
|
+
options = params.key?(:q) ? search_params : {}
|
38
|
+
AKIAlertSearchForm.new(options)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
31
42
|
def render_edit(alert)
|
32
43
|
render :edit, locals: { alert: alert }
|
33
44
|
end
|
@@ -44,6 +55,12 @@ module Renalware
|
|
44
55
|
:max_cre, :cre_date, :max_aki, :aki_date
|
45
56
|
)
|
46
57
|
end
|
58
|
+
|
59
|
+
def search_params
|
60
|
+
params
|
61
|
+
.require(:q) {}
|
62
|
+
.permit(:term, :on_hotlist, :action, :hospital_unit_id, :hospital_ward_id, :s)
|
63
|
+
end
|
47
64
|
end
|
48
65
|
end
|
49
66
|
end
|
@@ -3,8 +3,10 @@ require_dependency "renalware/research"
|
|
3
3
|
module Renalware
|
4
4
|
module Research
|
5
5
|
class StudiesController < BaseController
|
6
|
+
include Renalware::Concerns::Pageable
|
7
|
+
|
6
8
|
def index
|
7
|
-
studies = Study.ordered
|
9
|
+
studies = Study.ordered.page(page).per(per_page)
|
8
10
|
authorize studies
|
9
11
|
render locals: { studies: studies }
|
10
12
|
end
|
@@ -53,7 +53,7 @@ module Renalware
|
|
53
53
|
# Returns a truthy value if we came from a devise URL like users/sign_in
|
54
54
|
def referrer_is_a_devise_url?
|
55
55
|
referrer = request.referer
|
56
|
-
return if request.blank?
|
56
|
+
return if request.blank? || referrer.blank?
|
57
57
|
regex_defining_devise_paths = %r{(#{new_user_session_path}|users\/password|users\/sign_up)}
|
58
58
|
URI.parse(referrer).path =~ regex_defining_devise_paths
|
59
59
|
end
|
@@ -35,6 +35,8 @@ module Renalware
|
|
35
35
|
module Letters
|
36
36
|
class PdfLetterCache
|
37
37
|
class << self
|
38
|
+
delegate :clear, to: :store
|
39
|
+
|
38
40
|
def fetch(letter)
|
39
41
|
store.fetch(cache_key_for(letter)) { yield }
|
40
42
|
end
|
@@ -46,7 +48,8 @@ module Renalware
|
|
46
48
|
# valid and a new key and cache entry will be created.
|
47
49
|
def cache_key_for(letter)
|
48
50
|
timestamp = letter&.updated_at&.strftime("%Y%m%d%H%M%S")
|
49
|
-
|
51
|
+
pat_id = letter.patient.id
|
52
|
+
"letter-pdf-#{letter.id}-#{pat_id}-#{timestamp}-#{Digest::MD5.hexdigest(letter.to_html)}"
|
50
53
|
end
|
51
54
|
|
52
55
|
def cache_path
|
@@ -36,7 +36,8 @@ module Renalware
|
|
36
36
|
|
37
37
|
def initialize(patient:, observation_descriptions:, page: 1, per_page: 50)
|
38
38
|
@patient = patient
|
39
|
-
@observation_descriptions =
|
39
|
+
@observation_descriptions =
|
40
|
+
observation_descriptions.presence || observation_descriptions_null_object
|
40
41
|
@page = Integer(page)
|
41
42
|
@limit = Integer(per_page)
|
42
43
|
end
|
@@ -52,11 +53,16 @@ module Renalware
|
|
52
53
|
end
|
53
54
|
|
54
55
|
def all
|
56
|
+
return Pathology::Observation.none if observation_descriptions.empty?
|
55
57
|
conn.execute(to_paginated_sql)
|
56
58
|
end
|
57
59
|
|
58
60
|
private
|
59
61
|
|
62
|
+
def observation_descriptions_null_object
|
63
|
+
Pathology::Observation.none
|
64
|
+
end
|
65
|
+
|
60
66
|
def to_sql
|
61
67
|
<<-SQL.squish
|
62
68
|
select obs_req.patient_id, cast(observed_at as date) as observed_on,
|
@@ -20,6 +20,7 @@ module Renalware
|
|
20
20
|
additional_manual_exchange_volumes: 500..5_000,
|
21
21
|
cycles_per_apd: 2..20,
|
22
22
|
overnight_volumes: 3_000..25_000,
|
23
|
+
dwell_times: 10..120,
|
23
24
|
tidal_percentages: (60..100).step(5).to_a
|
24
25
|
).freeze
|
25
26
|
|
@@ -63,6 +64,11 @@ module Renalware
|
|
63
64
|
numericality: { only_integer: true },
|
64
65
|
numeric_inclusion: { in: VALID_RANGES.therapy_times }
|
65
66
|
|
67
|
+
validates :dwell_time,
|
68
|
+
allow_nil: true,
|
69
|
+
numericality: { only_integer: true },
|
70
|
+
numeric_inclusion: { in: VALID_RANGES.dwell_times }
|
71
|
+
|
66
72
|
validate :all_active_days_have_the_same_available_volume
|
67
73
|
|
68
74
|
before_save -> { APD::CalculateVolumes.new(self).call }
|
@@ -4,6 +4,7 @@ module Renalware
|
|
4
4
|
module Renal
|
5
5
|
class AKIAlert < ApplicationRecord
|
6
6
|
include Accountable
|
7
|
+
include PatientsRansackHelper
|
7
8
|
scope :ordered, ->{ order(created_at: :desc) }
|
8
9
|
belongs_to :patient, class_name: "Renal::Patient", touch: true
|
9
10
|
belongs_to :action, class_name: "Renal::AKIAlertAction"
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_dependency "renalware/clinics"
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module Renal
|
5
|
+
class AKIAlertQuery
|
6
|
+
DEFAULT_SORT = "aki_date :desc".freeze
|
7
|
+
attr_reader :query
|
8
|
+
|
9
|
+
def initialize(query = nil)
|
10
|
+
@query = query || {}
|
11
|
+
@query[:s] = DEFAULT_SORT if @query[:s].blank?
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.call(query)
|
15
|
+
new(query).call
|
16
|
+
end
|
17
|
+
|
18
|
+
def call
|
19
|
+
search.result
|
20
|
+
end
|
21
|
+
|
22
|
+
def search
|
23
|
+
@search ||= begin
|
24
|
+
AKIAlert
|
25
|
+
.joins(:patient) # required for PatientsRansackHelper - see Admission
|
26
|
+
.includes(:patient, :updated_by, :action, hospital_ward: :hospital_unit)
|
27
|
+
.ransack(query)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_dependency "renalware/renal"
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module Renal
|
5
|
+
class AKIAlertSearchForm
|
6
|
+
include ActiveModel::Model
|
7
|
+
include Virtus::Model
|
8
|
+
|
9
|
+
attribute :hospital_unit_id, Integer
|
10
|
+
attribute :hospital_ward_id, Integer
|
11
|
+
attribute :action, String
|
12
|
+
attribute :term, String
|
13
|
+
attribute :on_hotlist, String
|
14
|
+
attribute :s, String
|
15
|
+
|
16
|
+
def query
|
17
|
+
@query ||= begin
|
18
|
+
options = {
|
19
|
+
identity_match: term,
|
20
|
+
hospital_ward_id_eq: hospital_ward_id,
|
21
|
+
hospital_ward_hospital_unit_id_eq: hospital_unit_id,
|
22
|
+
action_id_eq: action,
|
23
|
+
hotlist_eq: on_hotlist,
|
24
|
+
s: s
|
25
|
+
}
|
26
|
+
AKIAlertQuery.new(options)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require_dependency "renalware/system"
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module System
|
5
|
+
class Event < ApplicationRecord
|
6
|
+
include Ahoy::QueryMethods # See https://github.com/ankane/ahoy
|
7
|
+
|
8
|
+
belongs_to :visit, class_name: "System::Visit"
|
9
|
+
belongs_to :user, optional: true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -10,7 +10,9 @@ module Renalware
|
|
10
10
|
|
11
11
|
belongs_to :author, class_name: "User"
|
12
12
|
|
13
|
-
enumerize :category,
|
13
|
+
enumerize :category,
|
14
|
+
in: %i(urgent_bug non_urgent_bug missing_feature general_comment),
|
15
|
+
default: :general_comment
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -28,8 +28,10 @@ module Renalware
|
|
28
28
|
# We purposefully don't use the recent_events relation here as it has includes and a limit
|
29
29
|
# and apart from being slower, using LIMIT in cache_key sql has been known to produce
|
30
30
|
# inconsistent results.
|
31
|
+
# We need to include the patient.cache_key otherwise if there are no events, the key will
|
32
|
+
# be the same for other patients with no events.
|
31
33
|
def cache_key
|
32
|
-
Events::Event.for_patient(patient).cache_key
|
34
|
+
[patient.cache_key, Events::Event.for_patient(patient).cache_key].join("~")
|
33
35
|
end
|
34
36
|
|
35
37
|
def to_partial_path
|
@@ -120,7 +120,10 @@ module Renalware
|
|
120
120
|
if codes.nil?
|
121
121
|
Pathology::RelevantObservationDescription.all
|
122
122
|
else
|
123
|
-
|
123
|
+
codes = Array(codes)
|
124
|
+
descriptions = Pathology::ObservationDescription.for(Array(codes))
|
125
|
+
warn("No OBX(es) found for codes #{codes}") if descriptions.empty?
|
126
|
+
descriptions
|
124
127
|
end
|
125
128
|
end
|
126
129
|
|
@@ -39,12 +39,14 @@ module Renalware
|
|
39
39
|
def cache_key
|
40
40
|
# Based on AR::Relation.cache_key, this key incorporates the following, scoped to the
|
41
41
|
# current patient:
|
42
|
+
# - patient cachekey eg renalware/patients/166-20180306184938146827
|
42
43
|
# - max(prescriptions.updated)
|
43
44
|
# - count(prescriptions)
|
44
45
|
# - max(drug.updated_at) in drugs across all prescriptions
|
45
46
|
# - count(drugs) across all prescriptions (same as prescriptions.count so not really
|
46
47
|
# required, but comes for free with AR::Relation.cache_key)
|
47
48
|
[
|
49
|
+
patient.cache_key,
|
48
50
|
prescriptions.cache_key,
|
49
51
|
Drugs::Drug.where(id: prescriptions.pluck(:drug_id)).cache_key
|
50
52
|
].join("$")
|
@@ -5,12 +5,14 @@ require_dependency "renalware/problems"
|
|
5
5
|
module Renalware
|
6
6
|
module Problems
|
7
7
|
class SummaryPart < Renalware::SummaryPart
|
8
|
-
delegate :cache_key, to: :problems
|
9
|
-
|
10
8
|
def problems
|
11
9
|
@problems ||= patient.problems.ordered
|
12
10
|
end
|
13
11
|
|
12
|
+
def cache_key
|
13
|
+
[patient.cache_key, patient.problems.cache_key].join("~")
|
14
|
+
end
|
15
|
+
|
14
16
|
def to_partial_path
|
15
17
|
"renalware/problems/problems/summary_part"
|
16
18
|
end
|
@@ -7,12 +7,13 @@ article.access-procedures
|
|
7
7
|
|
8
8
|
table.auto-layout
|
9
9
|
thead
|
10
|
-
th
|
11
|
-
th Performed
|
10
|
+
th.col-width-small
|
11
|
+
th.col-width-date Performed
|
12
12
|
th Procedure
|
13
|
-
th Side
|
13
|
+
th.col-width-tiny Side
|
14
14
|
th Performed By
|
15
|
-
th First Use
|
15
|
+
th.col-width-date First Use
|
16
|
+
th Notes
|
16
17
|
th Outcome
|
17
18
|
|
18
19
|
tbody
|
@@ -27,4 +28,5 @@ article.access-procedures
|
|
27
28
|
td= procedure.side
|
28
29
|
td= procedure.performed_by
|
29
30
|
td= procedure.first_used_on
|
30
|
-
td=
|
31
|
+
td.col-width-mediumish-with-ellipsis(title=procedure.notes)=procedure.notes
|
32
|
+
td.col-width-mediumish-with-ellipsis(title=procedure.outcome)=procedure.outcome
|
@@ -7,12 +7,12 @@ article.access-profiles
|
|
7
7
|
|
8
8
|
table.auto-layout
|
9
9
|
thead
|
10
|
-
th
|
11
|
-
th Formed On
|
12
|
-
th Start Date
|
13
|
-
th Term. Date
|
10
|
+
th.col-width-small
|
11
|
+
th.col-width-date Formed On
|
12
|
+
th.col-width-date Start Date
|
13
|
+
th.col-width-date Term. Date
|
14
14
|
th Type
|
15
|
-
th Side
|
15
|
+
th.col-width-small Side
|
16
16
|
|
17
17
|
tbody
|
18
18
|
- @profiles.each do |profile|
|
@@ -1,5 +1,6 @@
|
|
1
|
-
= within_admin_layout(title: "Cache") do
|
1
|
+
= within_admin_layout(title: "Clearing the Cache") do
|
2
2
|
.panel
|
3
|
+
h2 Application Cache
|
3
4
|
p
|
4
5
|
| The cache (backed by Redis) stores some queries and html fragments in order to make
|
5
6
|
| the rendering of pages faster and less resource intensive. Cached elements are invalidated
|
@@ -7,7 +8,9 @@
|
|
7
8
|
| count of records, in order to catch edits, inserts and deletions) or the html template
|
8
9
|
| changes (changes are only reflected after am app restart in this latter case).
|
9
10
|
p
|
10
|
-
|
|
11
|
+
| You can check the size and number of keys in the Redis cache by running
|
12
|
+
code redis-cli --stat
|
13
|
+
p There are certain cases where you might need to clear the cache:
|
11
14
|
ol
|
12
15
|
li
|
13
16
|
| You have changed the underlying database data directly in SQL without also updating the
|
@@ -18,3 +21,24 @@
|
|
18
21
|
method: :delete,
|
19
22
|
data: { confirm: "Are you sure you want to clear the application cache?\n" },
|
20
23
|
class: "button alert"
|
24
|
+
|
25
|
+
.panel
|
26
|
+
h2 PDF Letter Cache
|
27
|
+
p
|
28
|
+
| The PDF letter cache stores generated PDFs so they do not need to be regenerated if
|
29
|
+
| unless their content has changed. It is a FileStore cache and the files are stored
|
30
|
+
| in
|
31
|
+
code shared/tmp/pdf_letter_cache
|
32
|
+
| - though in a folder layout that a little tricky to navigate
|
33
|
+
| and search if you are looking for something; however it is NOT meant to be the canonical
|
34
|
+
| source for PDF letters, rather a volatile cache to aid performance. EPR should be the place
|
35
|
+
| to look for letter content - or just view the PDF through the UI.
|
36
|
+
p
|
37
|
+
| You may wish to clear the PDF Letter Cache if you notice any anomalies in the PDFs. Please
|
38
|
+
| raise a GitHub issue after clearing the cache so we can look into it.
|
39
|
+
|
40
|
+
= link_to "Clear the PDF Letter Cache",
|
41
|
+
letters_pdf_letter_cache_path,
|
42
|
+
method: :delete,
|
43
|
+
data: { confirm: "Are you sure you want to clear the PDF letter cache?\n" },
|
44
|
+
class: "button alert"
|