renalware-core 2.0.109 → 2.0.110
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/images/renalware/loading-gears-animation.gif +0 -0
- data/app/assets/javascripts/renalware/drugs.js +3 -4
- data/app/assets/javascripts/renalware/letters.js +47 -2
- data/app/assets/pdf/blank_page.pdf +56 -0
- data/app/assets/stylesheets/renalware/modules/_letters.scss +46 -0
- data/app/assets/stylesheets/renalware/partials/_tables.scss +2 -2
- data/app/controllers/renalware/base_controller.rb +9 -2
- data/app/controllers/renalware/clinics/appointments_controller.rb +8 -3
- data/app/controllers/renalware/letters/batches_controller.rb +106 -0
- data/app/controllers/renalware/letters/completed_batches_controller.rb +32 -0
- data/app/controllers/renalware/letters/lists_controller.rb +34 -5
- data/app/controllers/renalware/pathology/requests/requests_controller.rb +1 -1
- data/app/jobs/renalware/hd/update_rolling_patient_statistics_dj_job.rb +38 -0
- data/app/jobs/renalware/hd/update_rolling_patient_statistics_job.rb +4 -2
- data/app/jobs/renalware/letters/printing/batch_print_job.rb +27 -0
- data/app/models/concerns/renalware/patients_ransack_helper.rb +1 -1
- data/app/models/concerns/renalware/using_temp_folder.rb +14 -0
- data/app/models/renalware/clinics/appointment.rb +2 -3
- data/app/models/renalware/clinics/appointment_query.rb +5 -1
- data/app/models/renalware/hd/sessions/save_session.rb +5 -1
- data/app/models/renalware/hd/update_rolling_patient_statistics.rb +1 -1
- data/app/models/renalware/letters/batch.rb +37 -0
- data/app/models/renalware/letters/batch_item.rb +17 -0
- data/app/models/renalware/letters/lists/form.rb +101 -0
- data/app/models/renalware/letters/pdf_letter_cache.rb +1 -1
- data/app/models/renalware/letters/printing/batch_compile_pdfs.rb +121 -0
- data/app/models/renalware/letters/printing/complete_batch.rb +24 -0
- data/app/models/renalware/letters/printing/create_pdf_by_interleaving_address_sheet_and_letter_for_each_recipient.rb.dead +90 -0
- data/app/models/renalware/letters/printing/duplex_interleaved_pdf_renderer.rb +1 -1
- data/app/models/renalware/letters/printing/pdf_combining.rb +24 -21
- data/app/models/renalware/pathology/{consultant.rb → consultant.rb.dead} +0 -0
- data/app/models/renalware/pathology/observations_grouped_by_date_query.rb +1 -1
- data/app/models/renalware/pathology/relevant_observation_description.rb +1 -1
- data/app/models/renalware/pathology/requests/global_rule/transplant_date_within_weeks.rb +1 -1
- data/app/models/renalware/pathology/requests/global_rule/transplant_registration_status.rb +3 -1
- data/app/models/renalware/pathology/requests/request.rb +1 -1
- data/app/models/renalware/pathology/requests/request_params_factory.rb +11 -12
- data/app/models/renalware/patient.rb +3 -2
- data/app/models/renalware/pd/apd_regime.rb +6 -6
- data/app/models/renalware/renal/consultant.rb +16 -0
- data/app/models/renalware/transplants/registrations/wait_list_query.rb +4 -10
- data/app/models/renalware/ukrdc/treatment_timeline/generator_factory.rb +1 -1
- data/app/pdfs/renalware/letters/printing/recipient_address_page_pdf.rb +50 -0
- data/app/policies/renalware/letters/batch_policy.rb +13 -0
- data/app/presenters/renalware/letters/recipient_presenter.rb +1 -1
- data/app/presenters/renalware/pathology/requests/request_presenter.rb +1 -1
- data/app/presenters/renalware/transplants/mdm_presenter.rb +1 -1
- data/app/presenters/renalware/virology/dashboard_presenter.rb +2 -1
- data/app/views/renalware/api/ukrdc/patients/_hd_session_observations.xml.builder +2 -2
- data/app/views/renalware/clinics/appointments/index.html.slim +5 -4
- data/app/views/renalware/clinics/appointments/new.html.slim +3 -0
- data/app/views/renalware/letters/batches/_create.html.slim +27 -0
- data/app/views/renalware/letters/batches/create.js.erb +3 -0
- data/app/views/renalware/letters/batches/index.html.slim +20 -0
- data/app/views/renalware/letters/batches/show.html.slim +7 -0
- data/app/views/renalware/letters/completed_batches/create.js.erb +9 -0
- data/app/views/renalware/letters/completed_batches/new.html.slim +26 -0
- data/app/views/renalware/letters/lists/_table.html.slim +1 -1
- data/app/views/renalware/letters/lists/_tabs.html.slim +9 -0
- data/app/views/renalware/letters/lists/index.html.slim.dead +101 -0
- data/app/views/renalware/letters/lists/index.html.slim.dead1 +90 -0
- data/app/views/renalware/letters/lists/show.html.slim +57 -11
- data/app/views/renalware/medications/prescriptions/_form.html.slim +1 -0
- data/app/views/renalware/navigation/_super_admin.html.slim +1 -0
- data/app/views/renalware/pathology/requests/requests/_pdf_header.html.slim +2 -3
- data/app/views/renalware/pathology/requests/requests/index.html.slim +1 -1
- data/app/views/renalware/pathology/requests/requests/new.html.slim +0 -1
- data/config/locales/renalware/letters/letter.en.yml +5 -0
- data/config/routes/letters.rb +18 -1
- data/db/migrate/20190830153416_create_letter_batches.rb +14 -0
- data/db/migrate/20190902085216_create_letter_batch_items.rb +13 -0
- data/db/migrate/20190919073410_add_filepath_to_letter_batches.rb +7 -0
- data/db/migrate/20190920063447_add_status_to_letter_batch_items.rb +15 -0
- data/db/migrate/20190925104902_remove_user_from_appointments.rb +19 -0
- data/db/migrate/20190925130052_add_telephone_to_renal_consultants.rb +7 -0
- data/db/migrate/20190925161724_change_path_request_consultant_id.rb +19 -0
- data/db/migrate/20190925173849_renal_consultants_changes.rb +9 -0
- data/db/migrate/20190928131032_add_some_more_missing_indexes.rb +18 -0
- data/db/views/pathology_observation_digests_v01.sql +1 -1
- data/lib/renalware/configuration.rb +2 -0
- data/lib/renalware/engine.rb +1 -0
- data/lib/renalware/version.rb +1 -1
- data/lib/tasks/demo_data.rake +66 -0
- data/lib/tasks/pd.rake +32 -0
- data/spec/factories/clinics/appointments.rb +1 -1
- data/spec/factories/medications/medication_route.rb +5 -0
- data/spec/factories/renal/consultants.rb +9 -0
- data/spec/support/pages/medications/prescription_fom.rb +54 -0
- metadata +43 -7
- data/app/models/renalware/letters/printing/create_pdf_by_interleaving_address_sheet_and_letter_for_each_recipient.rb +0 -140
- data/spec/factories/pathology/consultant.rb +0 -5
@@ -38,7 +38,7 @@ module Renalware
|
|
38
38
|
layout: false,
|
39
39
|
locals: local_vars.merge(
|
40
40
|
all_clinics: Renalware::Pathology::Clinic.for_algorithm,
|
41
|
-
all_consultants: Renalware::
|
41
|
+
all_consultants: Renalware::Renal::Consultant.ordered,
|
42
42
|
all_templates: Renalware::Pathology::Requests::Request::TEMPLATES
|
43
43
|
)
|
44
44
|
)
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# When executed this job updates rolling statistics for a patient's
|
4
|
+
# last past 12 HD sessions.
|
5
|
+
# Because this job will be triggered again the next time an HD Sessions is
|
6
|
+
# created, it is not crucial to keep each event around - ie they have a short
|
7
|
+
# shelf-life. For this reason we only retry 3 times then delete failed jobs.
|
8
|
+
module Renalware
|
9
|
+
module HD
|
10
|
+
UpdateRollingPatientStatisticsDjJob = Struct.new(:patient_id) do
|
11
|
+
def perform
|
12
|
+
patient = Renalware::HD::Patient.find(patient_id)
|
13
|
+
UpdateRollingPatientStatistics.new(patient: patient).call
|
14
|
+
end
|
15
|
+
|
16
|
+
def max_attempts
|
17
|
+
3
|
18
|
+
end
|
19
|
+
|
20
|
+
def queue_name
|
21
|
+
"hd_patient_statistics"
|
22
|
+
end
|
23
|
+
|
24
|
+
def priority
|
25
|
+
4
|
26
|
+
end
|
27
|
+
|
28
|
+
def destroy_failed_jobs?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
# Retry at intervals of 1, 2, 3 hours
|
33
|
+
def reschedule_at(current_time, attempts)
|
34
|
+
current_time + attempts.hours
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -2,12 +2,14 @@
|
|
2
2
|
|
3
3
|
# When executed this job updates rolling statistics for a patient's
|
4
4
|
# last past 12 HD sessions.
|
5
|
-
|
5
|
+
# Because this job will be triggered again the next time an HD Sessions is
|
6
|
+
# created, it is not crucial to keep each event around - ie they have a short
|
7
|
+
# shelf-life. For this reason we only retry 3 times then delete failed jobs.
|
6
8
|
module Renalware
|
7
9
|
module HD
|
8
10
|
class UpdateRollingPatientStatisticsJob < ApplicationJob
|
9
11
|
queue_as :hd_patient_statistics
|
10
|
-
queue_with_priority
|
12
|
+
queue_with_priority 4
|
11
13
|
|
12
14
|
# :reek:UtilityFunction
|
13
15
|
def perform(patient)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/letters"
|
4
|
+
require "attr_extras"
|
5
|
+
|
6
|
+
module Renalware
|
7
|
+
module Letters
|
8
|
+
module Printing
|
9
|
+
class BatchPrintJob < ApplicationJob
|
10
|
+
include UsingTempFolder
|
11
|
+
|
12
|
+
# Returns the name of a temp file containing the pdf data
|
13
|
+
def perform(batch, user)
|
14
|
+
in_a_temporary_folder do |dir|
|
15
|
+
Dir.chdir(dir) do
|
16
|
+
BatchCompilePdfs.call(batch, user)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def max_attempts
|
22
|
+
2
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -6,7 +6,7 @@ module Renalware
|
|
6
6
|
module PatientsRansackHelper
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
UUID_REGEXP = /[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}
|
9
|
+
UUID_REGEXP = /[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}/.freeze
|
10
10
|
|
11
11
|
included do
|
12
12
|
class_eval do
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module UsingTempFolder
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
def in_a_temporary_folder
|
8
|
+
Dir.mktmpdir(nil, Rails.root.join("tmp").to_s) do |dir|
|
9
|
+
yield Pathname(dir)
|
10
|
+
# temp dir removed here
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -5,15 +5,14 @@ require_dependency "renalware/clinics"
|
|
5
5
|
module Renalware
|
6
6
|
module Clinics
|
7
7
|
class Appointment < ApplicationRecord
|
8
|
+
include Accountable
|
8
9
|
belongs_to :patient, touch: true
|
9
10
|
belongs_to :clinic
|
10
|
-
belongs_to :
|
11
|
+
belongs_to :consultant, class_name: "Renal::Consultant"
|
11
12
|
|
12
13
|
validates :starts_at, presence: true
|
13
14
|
validates :patient_id, presence: true
|
14
15
|
validates :clinic_id, presence: true
|
15
|
-
validates :user, presence: true
|
16
|
-
|
17
16
|
validates :starts_at, timeliness: { type: :datetime }
|
18
17
|
|
19
18
|
def starts_on
|
@@ -13,7 +13,11 @@ module Renalware
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def call
|
16
|
-
search.result.includes(
|
16
|
+
search.result.includes(
|
17
|
+
:clinic,
|
18
|
+
:consultant,
|
19
|
+
patient: [current_modality: [:description]]
|
20
|
+
)
|
17
21
|
end
|
18
22
|
|
19
23
|
def search
|
@@ -35,7 +35,11 @@ module Renalware
|
|
35
35
|
|
36
36
|
if session.save
|
37
37
|
# Might be cleaner if something listened for this event and created this job there?
|
38
|
-
UpdateRollingPatientStatisticsJob.perform_later(patient) unless session.open?
|
38
|
+
# UpdateRollingPatientStatisticsJob.perform_later(patient) unless session.open?
|
39
|
+
unless session.open?
|
40
|
+
Delayed::Job.enqueue UpdateRollingPatientStatisticsDjJob.new(patient.id)
|
41
|
+
end
|
42
|
+
|
39
43
|
broadcast(:save_success, session)
|
40
44
|
else
|
41
45
|
session.type = session_type # See method comment
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/letters"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module Letters
|
7
|
+
class Batch < ApplicationRecord
|
8
|
+
include Accountable
|
9
|
+
attr_accessor(
|
10
|
+
:url,
|
11
|
+
:enclosures_present,
|
12
|
+
:state_eq,
|
13
|
+
:author_id_eq,
|
14
|
+
:created_by_id_eq,
|
15
|
+
:letterhead_id_eq,
|
16
|
+
:page_count_in_array,
|
17
|
+
:s
|
18
|
+
)
|
19
|
+
|
20
|
+
enum status: { queued: 0, processing: 10, awaiting_printing: 15, failure: 20, success: 30 }
|
21
|
+
has_many(
|
22
|
+
:items,
|
23
|
+
dependent: :restrict_with_exception,
|
24
|
+
class_name: "Renalware::Letters::BatchItem"
|
25
|
+
)
|
26
|
+
has_many(
|
27
|
+
:letters,
|
28
|
+
through: :items,
|
29
|
+
class_name: "Renalware::Letters::Letter"
|
30
|
+
)
|
31
|
+
|
32
|
+
def percent_complete
|
33
|
+
((items.where(status: :compiled).count.to_f / batch_items_count) * 100).ceil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/letters"
|
4
|
+
|
5
|
+
module Renalware
|
6
|
+
module Letters
|
7
|
+
class BatchItem < ApplicationRecord
|
8
|
+
belongs_to :letter
|
9
|
+
belongs_to :batch, counter_cache: true
|
10
|
+
enum status: { queued: 0, compiled: 10 }
|
11
|
+
|
12
|
+
def self.policy_class
|
13
|
+
BasePolicy
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Renalware
|
4
|
+
module Letters
|
5
|
+
module Lists
|
6
|
+
# Form object to help us build and parse the appropriate filters for the
|
7
|
+
# letters_lists controller #show action, where we display all/batch_printable letters etc.
|
8
|
+
# For example, when displaying batchprintable letters we need to disable the enclosures
|
9
|
+
# filter (setting it to No), and restrict the optionsin the letter states dropdown so only
|
10
|
+
# Approved or Completed letters can be batch printed.
|
11
|
+
# We delegate logic to an instance of a private class which is (or is a subclass of)
|
12
|
+
# AllLetters.
|
13
|
+
# If we need to add another filter type, create another sub class of AllLetters.
|
14
|
+
class Form
|
15
|
+
delegate_missing_to :@handler
|
16
|
+
|
17
|
+
def initialize(named_filter:, params: {})
|
18
|
+
@handler = create_filter_specific_object_to_handle_all_requests(named_filter, params)
|
19
|
+
end
|
20
|
+
|
21
|
+
def create_filter_specific_object_to_handle_all_requests(named_filter, params)
|
22
|
+
handler_klass = "#{self.class.name}::#{named_filter.to_s.classify}Letters"
|
23
|
+
handler_klass.constantize.new(params)
|
24
|
+
end
|
25
|
+
|
26
|
+
class AllLetters
|
27
|
+
include ActiveModel::Model
|
28
|
+
include Virtus::Model
|
29
|
+
|
30
|
+
attribute :s, String # sort order, not really part of the form
|
31
|
+
attribute :enclosures_present, Boolean
|
32
|
+
attribute :state_eq, Integer
|
33
|
+
attribute :author_id_eq, Integer
|
34
|
+
attribute :created_by_id_eq, Integer
|
35
|
+
attribute :letterhead_id_eq, Integer
|
36
|
+
attribute :page_count_in_array, Integer
|
37
|
+
|
38
|
+
def letter_state_options(states = Letters::Letter.states)
|
39
|
+
states.map do |state|
|
40
|
+
label = I18n.t(state.to_sym, scope: "enums.letter.for_receptionists.state")
|
41
|
+
[label, state]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def author_options
|
46
|
+
@author_options ||= User.author.ordered
|
47
|
+
end
|
48
|
+
|
49
|
+
def typist_options
|
50
|
+
@typist_options ||= User.ordered
|
51
|
+
end
|
52
|
+
|
53
|
+
def letterhead_options
|
54
|
+
@letterhead_options ||= Letters::Letterhead.ordered
|
55
|
+
end
|
56
|
+
|
57
|
+
def page_count_options
|
58
|
+
[["1 or 2", "[1,2]"], ["3 or 4", "[3,4]"], ["5 or 6", "[5,6]"]]
|
59
|
+
end
|
60
|
+
|
61
|
+
def disabled_inputs
|
62
|
+
[]
|
63
|
+
end
|
64
|
+
|
65
|
+
def allow_blank_inputs
|
66
|
+
[:state_eq, :page_count_in_array]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class BatchPrintableLetters < AllLetters
|
71
|
+
def initialize(params)
|
72
|
+
super
|
73
|
+
# These are the default values that must match the filters when the page is first
|
74
|
+
# loaded, so the right results are displayed
|
75
|
+
self.page_count_in_array ||= "[1,2]"
|
76
|
+
end
|
77
|
+
|
78
|
+
def letter_state_options
|
79
|
+
super([:approved])
|
80
|
+
end
|
81
|
+
|
82
|
+
def disabled_inputs
|
83
|
+
[:enclosures_present, :state_eq]
|
84
|
+
end
|
85
|
+
|
86
|
+
def allow_blank_inputs
|
87
|
+
[]
|
88
|
+
end
|
89
|
+
|
90
|
+
def enclosures_present
|
91
|
+
false
|
92
|
+
end
|
93
|
+
|
94
|
+
def state_eq
|
95
|
+
@state_eq || :approved
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -44,7 +44,7 @@ module Renalware
|
|
44
44
|
end
|
45
45
|
|
46
46
|
# Note the letter must be a LetterPresenter which has a #to_html method
|
47
|
-
# The to_html method should (and does on the
|
47
|
+
# The to_html method should (and does on the LetterPresenter class) render the complete
|
48
48
|
# html including surrounding layout with inline css and images. This way if the
|
49
49
|
# layout changes or the image is changed for example, the cache for the pdf is no longer
|
50
50
|
# valid and a new key and cache entry will be created.
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_dependency "renalware/letters"
|
4
|
+
require "attr_extras"
|
5
|
+
|
6
|
+
module Renalware
|
7
|
+
module Letters
|
8
|
+
module Printing
|
9
|
+
# - takes a batch of letters
|
10
|
+
# - compiles each letter along with its recipient cover sheets
|
11
|
+
# - adds blank pages to make sure the letter always starts on an odd page
|
12
|
+
# - appends all PDF letters
|
13
|
+
# 2-page documents (from the contents of the /2 folder)
|
14
|
+
# - moves these compiled PDFs to a network share.
|
15
|
+
# - removes the temp folder structure - auto
|
16
|
+
class BatchCompilePdfs
|
17
|
+
include PdfCombining
|
18
|
+
PAGE_COUNTS = %w(2 3 4 5 6 7 8 9 10).freeze
|
19
|
+
|
20
|
+
def self.call(batch, user)
|
21
|
+
new(batch, user).call
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(batch, user)
|
25
|
+
@batch = batch
|
26
|
+
@user = user
|
27
|
+
@dir = Pathname(Dir.pwd)
|
28
|
+
Rails.logger.info "Compiling letter PDFs for batch #{batch.id} in folder #{dir}"
|
29
|
+
end
|
30
|
+
|
31
|
+
# rubocop:disable Metrics/AbcSize
|
32
|
+
def call
|
33
|
+
batch.status = :processing
|
34
|
+
batch.save_by!(user)
|
35
|
+
batch.items.each do |item|
|
36
|
+
validate_letter(item.letter)
|
37
|
+
assemble_letter_pdfs(item.letter, dir)
|
38
|
+
item.update(status: :compiled)
|
39
|
+
end
|
40
|
+
batch.filepath = append_files
|
41
|
+
batch.status = :awaiting_printing
|
42
|
+
batch.save_by!(user)
|
43
|
+
end
|
44
|
+
# rubocop:enable Metrics/AbcSize
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
attr_reader :batch, :dir, :user
|
49
|
+
|
50
|
+
def append_files
|
51
|
+
folder = Rails.root.join("tmp", "batched_letters")
|
52
|
+
FileUtils.mkdir_p folder
|
53
|
+
pdf_file = folder.join("#{batch.id}.pdf")
|
54
|
+
glob = Dir.glob(dir.join("*.pdf"))
|
55
|
+
combine_multiple_pdfs_into_file(filepath: pdf_file, glob: glob) if glob.any?
|
56
|
+
Pathname(pdf_file).to_s
|
57
|
+
end
|
58
|
+
|
59
|
+
def page_count_allowing_for_cover_sheet(letter)
|
60
|
+
(letter.page_count + 1).to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
def validate_letter(letter)
|
64
|
+
raise "Letter has no page_count" if letter.page_count.to_i.zero?
|
65
|
+
if letter.page_count.to_i > PAGE_COUNTS.last.to_i
|
66
|
+
raise "Letter page count (#{letter.page_count}) unexpected"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
71
|
+
# TODO: refactor
|
72
|
+
def assemble_letter_pdfs(letter, dir)
|
73
|
+
Rails.logger.info "Interleaving address sheets and letters for letter #{letter.id}"
|
74
|
+
letter_has_an_odd_number_of_pages = letter.page_count.odd?
|
75
|
+
filenames = []
|
76
|
+
working_folder = dir.join("letter_#{letter.id}")
|
77
|
+
FileUtils.mkdir_p working_folder
|
78
|
+
|
79
|
+
output_filepath = dir.join("compiled_letter_#{letter.id}.pdf")
|
80
|
+
|
81
|
+
Dir.chdir(working_folder) do
|
82
|
+
letter_filename = write_letter_to_pdf_file(letter)
|
83
|
+
letter.recipients.each do |recipient|
|
84
|
+
Rails.logger.info " Recipient #{recipient.id}"
|
85
|
+
filenames << write_recipient_cover_sheet_pdf(letter, recipient)
|
86
|
+
filenames << letter_filename
|
87
|
+
filenames << blank_page_filename if letter_has_an_odd_number_of_pages
|
88
|
+
end
|
89
|
+
combine_multiple_pdfs_using_filenames(filenames, working_folder, output_filepath)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
93
|
+
|
94
|
+
# Remove letter and recipient working files
|
95
|
+
def remove_working_files
|
96
|
+
FileUtils.rm Dir.glob(dir.join("*.pdf"))
|
97
|
+
end
|
98
|
+
|
99
|
+
def write_letter_to_pdf_file(letter)
|
100
|
+
filename = "original_letter_#{letter.id}.pdf"
|
101
|
+
File.open(filename, "wb") do |file|
|
102
|
+
file.write(PdfRenderer.call(letter))
|
103
|
+
end
|
104
|
+
filename
|
105
|
+
end
|
106
|
+
|
107
|
+
def write_recipient_cover_sheet_pdf(letter, recipient)
|
108
|
+
filename = "letter_#{letter.id}_address_sheet_for_recipient_#{recipient.id}.pdf"
|
109
|
+
RecipientAddressPagePdf.new(recipient).render_file filename
|
110
|
+
filename
|
111
|
+
end
|
112
|
+
|
113
|
+
def blank_page_filename
|
114
|
+
@blank_page_filename ||= begin
|
115
|
+
Renalware::Engine.root.join("app", "assets", "pdf", "blank_page.pdf").to_s
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|