renalware-core 2.0.44 → 2.0.45
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/application.scss +1 -0
- data/app/assets/stylesheets/renalware/modules/_clinical.scss +3 -1
- data/app/assets/stylesheets/renalware/modules/_patients.scss +0 -1
- data/app/assets/stylesheets/renalware/modules/_snippets.scss +3 -1
- data/app/assets/stylesheets/renalware/partials/_button.scss +6 -2
- data/app/assets/stylesheets/renalware/partials/_tables.scss +1 -1
- data/app/assets/stylesheets/renalware/partials/_tabs.scss +3 -1
- data/app/assets/stylesheets/renalware/table_pdf.scss +1 -1
- data/app/controllers/renalware/clinics/appointments_controller.rb +1 -3
- data/app/controllers/renalware/clinics/visits_controller.rb +2 -5
- data/app/controllers/renalware/patients/worryboard_controller.rb +2 -4
- data/app/controllers/renalware/renal/aki_alerts_controller.rb +2 -7
- data/app/documents/renalware/dated_confirmation.rb +1 -1
- data/app/documents/renalware/transplants/recipient_operation_document.rb +1 -1
- data/app/helpers/renalware/drugs_helper.rb +6 -3
- data/app/helpers/renalware/primary_care_physicians_helper.rb +3 -1
- data/app/jobs/refresh_materialized_view_job.rb +20 -0
- data/app/jobs/renalware/hd/generate_monthly_statistics.rb +3 -0
- data/app/mailers/renalware/previews/report_preview.rb +14 -0
- data/app/mailers/renalware/reporting/report_mailer.rb +57 -0
- data/app/models/concerns/renalware/broadcasting.rb +28 -4
- data/app/models/renalware/patients/worry_query.rb +0 -2
- data/app/models/renalware/renal/aki_alert_search_form.rb +1 -3
- data/app/models/renalware/ukrdc/send_patients.rb +25 -1
- data/app/models/renalware/ukrdc/transmission_log.rb +1 -1
- data/app/presenters/renalware/ukrdc/patient_presenter.rb +1 -1
- data/app/views/renalware/admin/users/index.html.slim +2 -2
- data/app/views/renalware/admissions/consults/index.html.slim +1 -1
- data/app/views/renalware/admissions/requests/_create_request_link.html.slim +1 -1
- data/app/views/renalware/admissions/requests/_request.html.slim +2 -2
- data/app/views/renalware/base/_modality_missing_warning.html.slim +1 -1
- data/app/views/renalware/clinical/allergies/_mini.html.slim +1 -1
- data/app/views/renalware/clinics/appointments/index.html.slim +3 -3
- data/app/views/renalware/hd/dashboards/_page_actions.html.slim +3 -3
- data/app/views/renalware/hd/diaries/edit.html.slim +2 -2
- data/app/views/renalware/hd/diaries/index.html.slim +1 -1
- data/app/views/renalware/hd/stations/_station.html.slim +1 -1
- data/app/views/renalware/letters/electronic_receipts/_table.html.slim +1 -1
- data/app/views/renalware/letters/lists/_letter.html.slim +1 -1
- data/app/views/renalware/low_clearance/dashboards/_page_actions.html.slim +2 -2
- data/app/views/renalware/mdm/_top_navigation.html.slim +1 -1
- data/app/views/renalware/medications/prescriptions/index.html.slim +1 -1
- data/app/views/renalware/messaging/internal/messages/_send_message_link.html.slim +1 -1
- data/app/views/renalware/messaging/internal/messages/_send_reply_link.html.slim +1 -1
- data/app/views/renalware/messaging/internal/receipts/_receipt.html.slim +1 -1
- data/app/views/renalware/navigation/_patient_search.html.slim +1 -1
- data/app/views/renalware/navigation/_user.html.slim +1 -1
- data/app/views/renalware/patients/_header.html.slim +2 -2
- data/app/views/renalware/patients/alerts/_alert.html.slim +2 -2
- data/app/views/renalware/patients/alerts/_create_alert_link.html.slim +1 -1
- data/app/views/renalware/patients/bookmarks/_delete.html.slim +5 -4
- data/app/views/renalware/patients/bookmarks/_new.html.slim +1 -1
- data/app/views/renalware/patients/patients/_patient.html.slim +2 -2
- data/app/views/renalware/patients/worries/_delete.html.slim +1 -1
- data/app/views/renalware/patients/worries/_new.html.slim +1 -1
- data/app/views/renalware/pd/dashboards/show/_page_actions.html.slim +4 -4
- data/app/views/renalware/pd/exit_site_infections/show.html.slim +1 -1
- data/app/views/renalware/pd/peritonitis_episodes/show.html.slim +1 -1
- data/app/views/renalware/problems/problems/_current_table.html.slim +1 -1
- data/app/views/renalware/renal/aki_alerts/index.html.slim +1 -1
- data/app/views/renalware/reporting/report_mailer/daily_summary.html.slim +14 -0
- data/app/views/renalware/reporting/report_mailer/daily_summary.text.erb +15 -0
- data/app/views/renalware/research/_alert.html.slim +2 -2
- data/app/views/renalware/shared/_modal_close_link.html.slim +1 -1
- data/app/views/renalware/snippets/snippets/_list.html.slim +2 -2
- data/app/views/renalware/snippets/snippets/_search_form.html.slim +1 -1
- data/app/views/renalware/transplants/live_donors/_filters.html.slim +1 -1
- data/app/views/renalware/transplants/recipient_dashboards/_modality_missing_warning.html.slim +1 -1
- data/app/views/renalware/transplants/recipient_dashboards/_page_actions.html.slim +1 -1
- data/config/gpg/renalware_test.gpg +0 -0
- data/config/initializers/ransack.rb +1 -1
- data/config/initializers/renalware.rb +20 -2
- data/config/locales/renalware/reporting/reporting_daily.en.yml +7 -0
- data/config/locales/renalware/virology/virology.en.yml +1 -0
- data/db/migrate/20180831134606_add_reporting_indexes.rb +13 -0
- data/db/migrate/20180831134926_create_daily_reports.rb +6 -0
- data/db/seeds/default/reporting/audits.yml +1 -2
- data/db/views/reporting_daily_letters_v01.sql +3 -0
- data/db/views/reporting_daily_pathology_v01.sql +16 -0
- data/lib/gpg_encrypt_folder.rb +74 -0
- data/lib/renalware/configuration.rb +5 -0
- data/lib/renalware/engine.rb +5 -4
- data/lib/renalware/version.rb +1 -1
- data/lib/tasks/audit.rake +5 -0
- data/lib/tasks/reporting.rake +9 -0
- metadata +43 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1a1c9ca94f32bd1524f80152063a831f780ac70f397b086d5c76b923834a13c4
|
4
|
+
data.tar.gz: 103a797720d5e2dd3bd4f130c7bfe784a34cb28e1576898c5ca3a4653e1a8d5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6500f6621008bb20a91c3853a54637e8a4c66eaace10a8d11528c2d35876c4723b408952933f0bf9dfd62bd12f1f48d14d9a2c78e8995de28a3c9e2c98e79abe
|
7
|
+
data.tar.gz: 2cc83be3409bdc4e0b72e00d69d8bbad46ad678198bc754633a15b95abe1e202431618df4e6eb8ccdf1599ff8015ca7f3f606a9f32d016947a03e4dd5712666e
|
@@ -27,14 +27,18 @@
|
|
27
27
|
background-color: $nhs-blue;
|
28
28
|
}
|
29
29
|
|
30
|
-
i.fa
|
30
|
+
i.fa,
|
31
|
+
i.fas,
|
32
|
+
i.far {
|
31
33
|
margin-right: .5rem;
|
32
34
|
}
|
33
35
|
|
34
36
|
&.with-icon {
|
35
37
|
padding-left: 0.7rem;
|
36
38
|
|
37
|
-
i.fa
|
39
|
+
i.fa,
|
40
|
+
i.fas,
|
41
|
+
i.far {
|
38
42
|
font-size: 1.1rem;
|
39
43
|
margin-right: 0.6rem;
|
40
44
|
}
|
@@ -5,11 +5,10 @@ module Renalware
|
|
5
5
|
module Clinics
|
6
6
|
class VisitsController < BaseController
|
7
7
|
include Renalware::Concerns::Pageable
|
8
|
-
PER_PAGE = 25
|
9
8
|
|
10
9
|
def index
|
11
10
|
visits_query = VisitQuery.new(query_params)
|
12
|
-
visits = visits_query.call.page(page).per(
|
11
|
+
visits = visits_query.call.page(page).per(per_page)
|
13
12
|
authorize visits
|
14
13
|
|
15
14
|
render locals: {
|
@@ -23,9 +22,7 @@ module Renalware
|
|
23
22
|
private
|
24
23
|
|
25
24
|
def query_params
|
26
|
-
params
|
27
|
-
.fetch(:q, {})
|
28
|
-
.merge(page: page, per_page: per_page)
|
25
|
+
params.fetch(:q, {})
|
29
26
|
end
|
30
27
|
end
|
31
28
|
end
|
@@ -10,7 +10,7 @@ module Renalware
|
|
10
10
|
def show
|
11
11
|
authorize Worry, :index?
|
12
12
|
query = WorryQuery.new(query_params)
|
13
|
-
worries = query.call
|
13
|
+
worries = query.call.page(page).per(per_page)
|
14
14
|
render locals: {
|
15
15
|
query: query.search,
|
16
16
|
worries: worries,
|
@@ -21,9 +21,7 @@ module Renalware
|
|
21
21
|
private
|
22
22
|
|
23
23
|
def query_params
|
24
|
-
params
|
25
|
-
.fetch(:q, {})
|
26
|
-
.merge(page: page, per_page: per_page)
|
24
|
+
params.fetch(:q, {})
|
27
25
|
end
|
28
26
|
end
|
29
27
|
end
|
@@ -27,7 +27,7 @@ module Renalware
|
|
27
27
|
def update
|
28
28
|
authorize alert
|
29
29
|
if alert.update(aki_alert_params.merge(by: current_user))
|
30
|
-
redirect_to renal_aki_alerts_path
|
30
|
+
redirect_to renal_aki_alerts_path
|
31
31
|
else
|
32
32
|
render_edit(alert)
|
33
33
|
end
|
@@ -60,7 +60,6 @@ module Renalware
|
|
60
60
|
def search_form
|
61
61
|
@search_form ||= begin
|
62
62
|
options = params.key?(:q) ? search_params : {}
|
63
|
-
options[:named_filter] = named_filter
|
64
63
|
AKIAlertSearchForm.new(options)
|
65
64
|
end
|
66
65
|
end
|
@@ -89,11 +88,7 @@ module Renalware
|
|
89
88
|
end
|
90
89
|
|
91
90
|
def path_params
|
92
|
-
params.permit([:controller, :action
|
93
|
-
end
|
94
|
-
|
95
|
-
def named_filter
|
96
|
-
params[:named_filter]
|
91
|
+
params.permit([:controller, :action])
|
97
92
|
end
|
98
93
|
end
|
99
94
|
end
|
@@ -8,7 +8,7 @@ module Renalware
|
|
8
8
|
attribute :confirmed_on, Date
|
9
9
|
|
10
10
|
validates :confirmed_on, timeliness: { type: :date, allow_blank: true }
|
11
|
-
validates :confirmed_on, presence: true, if: ->(
|
11
|
+
validates :confirmed_on, presence: true, if: ->(obj) { obj.status.try(:yes?) }
|
12
12
|
|
13
13
|
def to_s
|
14
14
|
datestamp = confirmed_on.present? ? "(#{I18n.l(confirmed_on)})" : nil
|
@@ -49,7 +49,7 @@ module Renalware
|
|
49
49
|
validates :warm_ischaemic_time_in_minutes, numericality: { allow_blank: true }
|
50
50
|
validates :ukt_cause_of_death_other,
|
51
51
|
presence: true,
|
52
|
-
if: ->(
|
52
|
+
if: ->(obj) { obj.ukt_cause_of_death.try(:text) =~ /specify/ }
|
53
53
|
end
|
54
54
|
attribute :cadaveric_donor, CadavericDonor
|
55
55
|
|
@@ -3,9 +3,12 @@
|
|
3
3
|
module Renalware
|
4
4
|
module DrugsHelper
|
5
5
|
def drug_select_options
|
6
|
-
options_for_select
|
7
|
-
|
8
|
-
|
6
|
+
options_for_select(
|
7
|
+
Drugs::Type
|
8
|
+
.all
|
9
|
+
.reject{ |dt| dt.name == "Peritonitis" }
|
10
|
+
.map { |dt| [dt.name, dt.name.downcase] }
|
11
|
+
)
|
9
12
|
end
|
10
13
|
|
11
14
|
def drug_types_colour_tag(drug_types)
|
@@ -25,7 +25,9 @@ module Renalware
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def practices_list(practices)
|
28
|
-
practice_links = practices.map
|
28
|
+
practice_links = practices.map do |prac|
|
29
|
+
link_to(prac.name, "#", title: format_address(prac.address))
|
30
|
+
end
|
29
31
|
practice_links.join(tag(:br)).html_safe
|
30
32
|
end
|
31
33
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Refresh a materialized view asynchronously via the delayed_job queue.
|
5
|
+
# If no view_name supplied, refresh all materialized views
|
6
|
+
#
|
7
|
+
class RefreshMaterializedViewJob < ApplicationJob
|
8
|
+
queue_with_priority 6
|
9
|
+
|
10
|
+
def perform(view_name: nil)
|
11
|
+
conn = ActiveRecord::Base.connection
|
12
|
+
if view_name.present?
|
13
|
+
Rails.logger.info("Refreshing materialized view #{view_name}...")
|
14
|
+
conn.execute("REFRESH MATERIALIZED VIEW #{view_name};")
|
15
|
+
else
|
16
|
+
Rails.logger.info("Refreshing all materialized views...")
|
17
|
+
conn.execute("SELECT refresh_all_matierialized_views();")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -6,6 +6,8 @@ require "month_period"
|
|
6
6
|
# for each HD patient.
|
7
7
|
module Renalware
|
8
8
|
module HD
|
9
|
+
# TODO: not sure this needs to be a job - doesn't seem to be used as such
|
10
|
+
# instead is invoked directly
|
9
11
|
class GenerateMonthlyStatistics < ApplicationJob
|
10
12
|
queue_as :hd_patient_statistics
|
11
13
|
queue_with_priority 1
|
@@ -29,6 +31,7 @@ module Renalware
|
|
29
31
|
year: period.year
|
30
32
|
)
|
31
33
|
end
|
34
|
+
|
32
35
|
Rails.logger.info(
|
33
36
|
"Enqueued GenerateMonthlyStatisticsForPatientJob jobs for "\
|
34
37
|
"#{patients_with_a_closed_hd_session_in_period.length} patients"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/reporting"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module Reporting
|
7
|
+
# Preview all emails at http://localhost:3000/rails/mailers/report
|
8
|
+
class ReportPreview < ActionMailer::Preview
|
9
|
+
def daily_summary
|
10
|
+
Reporting::ReportMailer.daily_summary
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/reporting"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module Reporting
|
7
|
+
class ReportMailer < ApplicationMailer
|
8
|
+
def daily_summary(to: "dev@airslie.com")
|
9
|
+
mail(
|
10
|
+
to: Array(to),
|
11
|
+
subject: "Renalware daily summary #{I18n.l(Time.zone.today)}"
|
12
|
+
) do |format|
|
13
|
+
format.text { render(locals: { view_data: view_data }) }
|
14
|
+
format.html { render(locals: { view_data: view_data }) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# Piggybacks on the reporting mechanism used elswhere for generating reports from json.
|
21
|
+
#
|
22
|
+
# returns e.g.
|
23
|
+
# {
|
24
|
+
# "reporting_daily_letters" => {
|
25
|
+
# "runat" => "2018-08-31T16:51:58.939876+00:00",
|
26
|
+
# "data" => [
|
27
|
+
# [0] {
|
28
|
+
# "letters_created_today" => 0,
|
29
|
+
# "letters_printed_today" => 0
|
30
|
+
# }
|
31
|
+
# ]
|
32
|
+
# },
|
33
|
+
# "another_view" :...
|
34
|
+
# }
|
35
|
+
def view_data
|
36
|
+
reporting_daily_views.each_with_object({}) do |view_name, hash|
|
37
|
+
hash[view_name] = JSON.parse(
|
38
|
+
Reporting::FetchAuditJson.call(view_name)
|
39
|
+
).with_indifferent_access
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# returns eg ["reporting_daily_pathology", "reporting_daily_letters"]
|
44
|
+
def reporting_daily_views
|
45
|
+
result = ActiveRecord::Base.connection.execute(<<-SQL)
|
46
|
+
SELECT relname FROM pg_class
|
47
|
+
WHERE relkind = 'v'
|
48
|
+
AND relname like 'reporting_daily_%'
|
49
|
+
AND relnamespace IN (
|
50
|
+
SELECT oid FROM pg_namespace WHERE nspname = 'renalware'
|
51
|
+
) order by relname desc;
|
52
|
+
SQL
|
53
|
+
result.values.flatten
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -7,6 +7,28 @@ module Renalware
|
|
7
7
|
include Wisper::Publisher
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
10
|
+
class Subscriber
|
11
|
+
attr_reader :klass_name, :async
|
12
|
+
alias_method :async?, :async
|
13
|
+
|
14
|
+
def initialize(klass_name, async: false)
|
15
|
+
@klass_name = klass_name
|
16
|
+
@async = async
|
17
|
+
end
|
18
|
+
|
19
|
+
# Note that when using the wisper-activejob gem (so we can use delayed_job for instance)
|
20
|
+
# we subscribe the class not an instance, and the subscriber must have class
|
21
|
+
# methods matching the event names it wants to handle.
|
22
|
+
# https://github.com/krisleech/wisper-activejob
|
23
|
+
def instance
|
24
|
+
async? ? klass : klass.new
|
25
|
+
end
|
26
|
+
|
27
|
+
def klass
|
28
|
+
klass_name.to_s.constantize
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
10
32
|
# Subscribes any listeners configured in Renalware.config.broadcast_subscription_map
|
11
33
|
# to the current instance.
|
12
34
|
#
|
@@ -25,10 +47,12 @@ module Renalware
|
|
25
47
|
# See https://github.com/krisleech/wisper
|
26
48
|
#
|
27
49
|
def broadcasting_to_configured_subscribers
|
28
|
-
subscribers = Renalware.config.broadcast_subscription_map[self.class.name]
|
29
|
-
|
30
|
-
|
31
|
-
|
50
|
+
subscribers = Array(Renalware.config.broadcast_subscription_map[self.class.name])
|
51
|
+
subscribers.each do |subscriber|
|
52
|
+
# Support String subscribers eg a simple class name as well as Subscriber instances.
|
53
|
+
subscriber = Subscriber.new(subscriber) unless subscriber.respond_to?(:klass)
|
54
|
+
subscribe(subscriber.instance, async: subscriber.async?)
|
55
|
+
end
|
32
56
|
self
|
33
57
|
end
|
34
58
|
end
|
@@ -14,7 +14,6 @@ module Renalware
|
|
14
14
|
attribute :term, String
|
15
15
|
attribute :on_hotlist, String
|
16
16
|
attribute :s, String
|
17
|
-
attribute :named_filter, String
|
18
17
|
|
19
18
|
def query
|
20
19
|
@query ||= begin
|
@@ -24,8 +23,7 @@ module Renalware
|
|
24
23
|
hospital_ward_id_eq: hospital_ward_id,
|
25
24
|
action_id_eq: action,
|
26
25
|
hotlist_eq: on_hotlist,
|
27
|
-
s: s
|
28
|
-
named_filter: named_filter
|
26
|
+
s: s
|
29
27
|
}
|
30
28
|
AKIAlertQuery.new(options)
|
31
29
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_dependency "renalware/ukrdc"
|
4
|
+
require "gpg_encrypt_folder"
|
4
5
|
|
5
6
|
module Renalware
|
6
7
|
module UKRDC
|
@@ -25,6 +26,7 @@ module Renalware
|
|
25
26
|
|
26
27
|
private
|
27
28
|
|
29
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
28
30
|
def send_patients
|
29
31
|
logger.info("Generating XML files for #{patient_ids&.any? ? patient_ids : 'all'} patients")
|
30
32
|
query = Renalware::UKRDC::PatientsQuery.new.call(changed_since: changed_since)
|
@@ -47,9 +49,11 @@ module Renalware
|
|
47
49
|
logger: logger
|
48
50
|
).call
|
49
51
|
end
|
52
|
+
encrypt_xml_files_in(dir)
|
50
53
|
end
|
51
54
|
logger.info("Files saved to #{folder_name}")
|
52
55
|
end
|
56
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
53
57
|
|
54
58
|
def gpg_encrypt(filepath, output_filepath)
|
55
59
|
path_to_key = File.open(Rails.root.join("key.gpg"))
|
@@ -69,7 +73,6 @@ module Renalware
|
|
69
73
|
|
70
74
|
def within_new_folder
|
71
75
|
dir = Pathname(File.join("/var", "ukrdc", timestamp))
|
72
|
-
FileUtils.mkdir_p dir
|
73
76
|
FileUtils.mkdir_p File.join(dir, "xml")
|
74
77
|
FileUtils.mkdir_p File.join(dir, "encrypted")
|
75
78
|
yield dir if block_given?
|
@@ -78,6 +81,7 @@ module Renalware
|
|
78
81
|
|
79
82
|
def filepath_for(patient, dir, sub_folder)
|
80
83
|
raise(ArgumentError, "Patient has no ukrdc_external_id") if patient.ukrdc_external_id.blank?
|
84
|
+
|
81
85
|
filename = "#{patient.ukrdc_external_id}.xml"
|
82
86
|
File.join(dir, sub_folder.to_s, filename)
|
83
87
|
end
|
@@ -88,6 +92,26 @@ module Renalware
|
|
88
92
|
results = TransmissionLog.where(request_uuid: request_uuid).group(:status).count(:status)
|
89
93
|
results.to_h.map{ |key, value| logger.info("#{key}: #{value}") }
|
90
94
|
end
|
95
|
+
|
96
|
+
def encrypt_xml_files_in(dir)
|
97
|
+
logger.info "Encrypting..."
|
98
|
+
GpgEncryptFolder.new(folder: dir, options: gpg_options).call
|
99
|
+
end
|
100
|
+
|
101
|
+
def config
|
102
|
+
Renalware.config
|
103
|
+
end
|
104
|
+
|
105
|
+
def gpg_options
|
106
|
+
GpgOptions.new(
|
107
|
+
recipient: config.ukrdc_gpg_recipient,
|
108
|
+
keyring: config.ukrdc_gpg_keyring,
|
109
|
+
homedir: config.ukrdc_gpg_homedir,
|
110
|
+
filename_transform: lambda do |filename|
|
111
|
+
filename.to_s.gsub("/xml/", "/encrypted/") + ".enc"
|
112
|
+
end
|
113
|
+
)
|
114
|
+
end
|
91
115
|
end
|
92
116
|
end
|
93
117
|
end
|