renalware-core 2.0.109 → 2.0.110

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.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/renalware/loading-gears-animation.gif +0 -0
  3. data/app/assets/javascripts/renalware/drugs.js +3 -4
  4. data/app/assets/javascripts/renalware/letters.js +47 -2
  5. data/app/assets/pdf/blank_page.pdf +56 -0
  6. data/app/assets/stylesheets/renalware/modules/_letters.scss +46 -0
  7. data/app/assets/stylesheets/renalware/partials/_tables.scss +2 -2
  8. data/app/controllers/renalware/base_controller.rb +9 -2
  9. data/app/controllers/renalware/clinics/appointments_controller.rb +8 -3
  10. data/app/controllers/renalware/letters/batches_controller.rb +106 -0
  11. data/app/controllers/renalware/letters/completed_batches_controller.rb +32 -0
  12. data/app/controllers/renalware/letters/lists_controller.rb +34 -5
  13. data/app/controllers/renalware/pathology/requests/requests_controller.rb +1 -1
  14. data/app/jobs/renalware/hd/update_rolling_patient_statistics_dj_job.rb +38 -0
  15. data/app/jobs/renalware/hd/update_rolling_patient_statistics_job.rb +4 -2
  16. data/app/jobs/renalware/letters/printing/batch_print_job.rb +27 -0
  17. data/app/models/concerns/renalware/patients_ransack_helper.rb +1 -1
  18. data/app/models/concerns/renalware/using_temp_folder.rb +14 -0
  19. data/app/models/renalware/clinics/appointment.rb +2 -3
  20. data/app/models/renalware/clinics/appointment_query.rb +5 -1
  21. data/app/models/renalware/hd/sessions/save_session.rb +5 -1
  22. data/app/models/renalware/hd/update_rolling_patient_statistics.rb +1 -1
  23. data/app/models/renalware/letters/batch.rb +37 -0
  24. data/app/models/renalware/letters/batch_item.rb +17 -0
  25. data/app/models/renalware/letters/lists/form.rb +101 -0
  26. data/app/models/renalware/letters/pdf_letter_cache.rb +1 -1
  27. data/app/models/renalware/letters/printing/batch_compile_pdfs.rb +121 -0
  28. data/app/models/renalware/letters/printing/complete_batch.rb +24 -0
  29. data/app/models/renalware/letters/printing/create_pdf_by_interleaving_address_sheet_and_letter_for_each_recipient.rb.dead +90 -0
  30. data/app/models/renalware/letters/printing/duplex_interleaved_pdf_renderer.rb +1 -1
  31. data/app/models/renalware/letters/printing/pdf_combining.rb +24 -21
  32. data/app/models/renalware/pathology/{consultant.rb → consultant.rb.dead} +0 -0
  33. data/app/models/renalware/pathology/observations_grouped_by_date_query.rb +1 -1
  34. data/app/models/renalware/pathology/relevant_observation_description.rb +1 -1
  35. data/app/models/renalware/pathology/requests/global_rule/transplant_date_within_weeks.rb +1 -1
  36. data/app/models/renalware/pathology/requests/global_rule/transplant_registration_status.rb +3 -1
  37. data/app/models/renalware/pathology/requests/request.rb +1 -1
  38. data/app/models/renalware/pathology/requests/request_params_factory.rb +11 -12
  39. data/app/models/renalware/patient.rb +3 -2
  40. data/app/models/renalware/pd/apd_regime.rb +6 -6
  41. data/app/models/renalware/renal/consultant.rb +16 -0
  42. data/app/models/renalware/transplants/registrations/wait_list_query.rb +4 -10
  43. data/app/models/renalware/ukrdc/treatment_timeline/generator_factory.rb +1 -1
  44. data/app/pdfs/renalware/letters/printing/recipient_address_page_pdf.rb +50 -0
  45. data/app/policies/renalware/letters/batch_policy.rb +13 -0
  46. data/app/presenters/renalware/letters/recipient_presenter.rb +1 -1
  47. data/app/presenters/renalware/pathology/requests/request_presenter.rb +1 -1
  48. data/app/presenters/renalware/transplants/mdm_presenter.rb +1 -1
  49. data/app/presenters/renalware/virology/dashboard_presenter.rb +2 -1
  50. data/app/views/renalware/api/ukrdc/patients/_hd_session_observations.xml.builder +2 -2
  51. data/app/views/renalware/clinics/appointments/index.html.slim +5 -4
  52. data/app/views/renalware/clinics/appointments/new.html.slim +3 -0
  53. data/app/views/renalware/letters/batches/_create.html.slim +27 -0
  54. data/app/views/renalware/letters/batches/create.js.erb +3 -0
  55. data/app/views/renalware/letters/batches/index.html.slim +20 -0
  56. data/app/views/renalware/letters/batches/show.html.slim +7 -0
  57. data/app/views/renalware/letters/completed_batches/create.js.erb +9 -0
  58. data/app/views/renalware/letters/completed_batches/new.html.slim +26 -0
  59. data/app/views/renalware/letters/lists/_table.html.slim +1 -1
  60. data/app/views/renalware/letters/lists/_tabs.html.slim +9 -0
  61. data/app/views/renalware/letters/lists/index.html.slim.dead +101 -0
  62. data/app/views/renalware/letters/lists/index.html.slim.dead1 +90 -0
  63. data/app/views/renalware/letters/lists/show.html.slim +57 -11
  64. data/app/views/renalware/medications/prescriptions/_form.html.slim +1 -0
  65. data/app/views/renalware/navigation/_super_admin.html.slim +1 -0
  66. data/app/views/renalware/pathology/requests/requests/_pdf_header.html.slim +2 -3
  67. data/app/views/renalware/pathology/requests/requests/index.html.slim +1 -1
  68. data/app/views/renalware/pathology/requests/requests/new.html.slim +0 -1
  69. data/config/locales/renalware/letters/letter.en.yml +5 -0
  70. data/config/routes/letters.rb +18 -1
  71. data/db/migrate/20190830153416_create_letter_batches.rb +14 -0
  72. data/db/migrate/20190902085216_create_letter_batch_items.rb +13 -0
  73. data/db/migrate/20190919073410_add_filepath_to_letter_batches.rb +7 -0
  74. data/db/migrate/20190920063447_add_status_to_letter_batch_items.rb +15 -0
  75. data/db/migrate/20190925104902_remove_user_from_appointments.rb +19 -0
  76. data/db/migrate/20190925130052_add_telephone_to_renal_consultants.rb +7 -0
  77. data/db/migrate/20190925161724_change_path_request_consultant_id.rb +19 -0
  78. data/db/migrate/20190925173849_renal_consultants_changes.rb +9 -0
  79. data/db/migrate/20190928131032_add_some_more_missing_indexes.rb +18 -0
  80. data/db/views/pathology_observation_digests_v01.sql +1 -1
  81. data/lib/renalware/configuration.rb +2 -0
  82. data/lib/renalware/engine.rb +1 -0
  83. data/lib/renalware/version.rb +1 -1
  84. data/lib/tasks/demo_data.rake +66 -0
  85. data/lib/tasks/pd.rake +32 -0
  86. data/spec/factories/clinics/appointments.rb +1 -1
  87. data/spec/factories/medications/medication_route.rb +5 -0
  88. data/spec/factories/renal/consultants.rb +9 -0
  89. data/spec/support/pages/medications/prescription_fom.rb +54 -0
  90. metadata +43 -7
  91. data/app/models/renalware/letters/printing/create_pdf_by_interleaving_address_sheet_and_letter_for_each_recipient.rb +0 -140
  92. data/spec/factories/pathology/consultant.rb +0 -5
@@ -0,0 +1,24 @@
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
+ # Marks as completed a Batch and all Letters within it.
10
+ class CompleteBatch
11
+ pattr_initialize [:batch!, :user!]
12
+
13
+ # TOD: Avoid loading all letters into memory
14
+ def call
15
+ Batch.transaction do
16
+ batch.letters.each { |letter| CompleteLetter.build(letter).call(by: user) }
17
+ batch.update_by(user, status: :success)
18
+ batch.reload
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,90 @@
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
+ # Build PDF for printing. We are targetting an envelope stuffer so there will be an address
10
+ # cover sheet in front of each letter.
11
+ # So for a letter where the patient is the main recipient, and we CC to the GP (no practice
12
+ # email address so snail mailing) and 1 extra CC (a contact) the output will look like
13
+ # this:
14
+ #
15
+ # 1. Patient address cover sheet
16
+ # 2. Letter
17
+ # 3. GP address cover sheet
18
+ # 2. Letter
19
+ # 5. Contact address cover sheet
20
+ # 2. Letter
21
+ #
22
+ # Note however the we always pad each item (address sheet, letter) with blank pages to make
23
+ # sure duplex printing does not cause the next page recipient's content to be rendered on the
24
+ # back of the ast page of the previous letter for example/
25
+ #
26
+ # Compiles print content for all input letters and outputs the merged PDF to output_file.
27
+ # Allows batch printing if you want to print say all 2 page letters together.
28
+ # The caller may choose for example to send the output_file could be sent back to the browser
29
+ # for manual printing using (eg using send_file) or copy the merged PDF to a folder for
30
+ # automated printing.
31
+ # class CreatePdfByInterleavingAddressSheetAndLetterForEachRecipient
32
+ # pattr_initialize [:letters!, :output_file!]
33
+
34
+ # def call
35
+ # # There is a choice of two methods of building the merged PDF. See pros and cons.
36
+ # # The other is UsingSeparatePdfForEachLetterSection.
37
+ # UsingOnePdfForAllLetterSections.new(
38
+ # letters: letters,
39
+ # output_file: output_file
40
+ # ).call
41
+ # end
42
+
43
+ # # For each letter, uses whkhtmltopdf to build the entire print content, ie all address
44
+ # # sheets and required instance of the letter are created as one fresh pdf (no cache will be
45
+ # # used).
46
+ # #
47
+ # # Pros:
48
+ # # - Quicker: For each letter only one PDF is generated, and although the generation is slow
49
+ # # as it does not use the previously cached letter PDF, and it has to render all the letter
50
+ # # sections, including the letter itself, for every recipient, its stil faster then
51
+ # # rendering separate PDFs for each section.
52
+ # # Cons:
53
+ # # - wastes some resources because it does not use the cache and renders same letter
54
+ # # multiple times in the views
55
+ # # - cannot be 100% sure the number of pages in the final PDF will be extactly what we
56
+ # # predict, so requires a check to load the pdf into a reader and validate the page_count
57
+ # class UsingOnePdfForAllLetterSections
58
+ # include PdfCombining
59
+ # pattr_initialize [:letters!, :output_file!]
60
+
61
+ # def call
62
+ # in_a_temporary_folder do |dir|
63
+ # Array(letters).each do |letter|
64
+ # if letter.page_count.to_i < 1
65
+ # raise(ArgumentError, "letter.page_count not set on letter.id=#{letter.id}")
66
+ # end
67
+
68
+ # letter_filename = create_letter_pdf_in(dir, letter)
69
+ # files << letter_filename
70
+ # end
71
+ # combine_multiple_pdfs_into_one(dir, output_file)
72
+ # # For debuging:
73
+ # # FileUtils.cp output_file, "/Users/tim/Desktop/x.pdf"
74
+ # # `open /Users/tim/Desktop/x.pdf`
75
+ # end
76
+ # end
77
+
78
+ # private
79
+
80
+ # def create_letter_pdf_in(dir, letter)
81
+ # filename = "letter_#{letter.id}.pdf"
82
+ # path = dir.join(filename)
83
+ # File.open(path, "wb") { |file| file.write(DuplexInterleavedPdfRenderer.call(letter)) }
84
+ # filename
85
+ # end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -21,7 +21,7 @@ module Renalware
21
21
  end
22
22
  # NB not caching the pdf for now until we can find a more standard way of using the
23
23
  # letter cache across adhoc and env stuffer renderers. Here for example we should be
24
- # using a hex digest of the interleaved letter but currentlt would not be.
24
+ # using a hex digest of the interleaved letter but currently would not be.
25
25
  # PdfLetterCache.fetch(letter) do
26
26
  WickedPdf.new.pdf_from_string(
27
27
  LettersController.new.render_to_string(
@@ -11,43 +11,46 @@ module Renalware
11
11
  module PdfCombining
12
12
  extend ActiveSupport::Concern
13
13
 
14
- def combine_multiple_pdfs_into_one(dir, output_filepath)
14
+ def combine_multiple_pdfs_into_file(filepath:, glob:)
15
+ filepath = Pathname(filepath)
16
+ Rails.logger.info " Compiling PDFs #{glob.join(',')} into #{filepath}"
17
+ shell_to_ghostscript_to_combine_files(glob, dir, filepath)
18
+ filepath
19
+ end
20
+
21
+ def combine_multiple_pdfs_using_filenames(filenames, dir, output_filepath)
22
+ filenames = Array(filenames)
23
+ Rails.logger.info " Compiling PDFs #{filenames.join(',')} into #{output_filepath}"
15
24
  using_a_temporary_output_file do |tmp_outfile|
16
- shell_to_ghostscript_to_combine_files_into(tmp_outfile, dir)
17
- copy_tempfile_to_output_file(tmp_outfile, output_filepath)
25
+ shell_to_ghostscript_to_combine_files(filenames, dir, tmp_outfile)
26
+ move_tempfile_to_output_file(tmp_outfile, output_filepath)
18
27
  end
19
28
  end
20
29
 
21
30
  # rubocop:disable Metrics/LineLength
22
- def shell_to_ghostscript_to_combine_files_into(outfile, dir)
23
- cmd = "gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=#{outfile.path} -dBATCH #{files.join(' ')}"
24
- err = Open3.popen3(cmd, chdir: dir.to_s) do |_stdin, _stdout, stderr|
25
- stderr.read
31
+ def shell_to_ghostscript_to_combine_files(filenames, dir, outputfile)
32
+ outputfile = Pathname(outputfile)
33
+ cmd = "gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=#{outputfile} -dBATCH #{filenames.join(' ')}"
34
+ err = msg = nil
35
+ Open3.popen3(cmd, chdir: dir.to_s) do |_stdin, stdout, stderr|
36
+ err = stderr.read
37
+ msg = stdout.read
38
+ end
39
+ if err.present?
40
+ raise "Error combining PDFs: #{[err, msg].join(' ')} command: #{cmd}"
26
41
  end
27
- raise "Error combining PDFs: #{err}" unless err.empty?
28
42
  end
29
43
  # rubocop:enable Metrics/LineLength
30
44
 
31
- def copy_tempfile_to_output_file(tmp_outfile, output_file)
32
- FileUtils.cp tmp_outfile.path, output_file
45
+ def move_tempfile_to_output_file(tmp_outfile, output_file)
46
+ FileUtils.mv tmp_outfile.path, output_file
33
47
  output_file
34
48
  end
35
49
 
36
- def files
37
- @files ||= []
38
- end
39
-
40
50
  def rails_tmp_folder
41
51
  Rails.root.join("tmp").to_s
42
52
  end
43
53
 
44
- def in_a_temporary_folder
45
- Dir.mktmpdir(nil, rails_tmp_folder) do |dir|
46
- yield Pathname(dir)
47
- # temp dir removed here!
48
- end
49
- end
50
-
51
54
  # Create a tempfile outside the temp dir as dir will be destroyed when outside block closes.
52
55
  def using_a_temporary_output_file
53
56
  file = Tempfile.new("pdf_combined", rails_tmp_folder)
@@ -26,7 +26,7 @@ module Renalware
26
26
  # patient_id observation_date observations
27
27
  # ------------------------------------------
28
28
  # 1 2018-02-02 {"CYA": "14"}
29
- # 1 2016-06-15 {"CMVDNA": "0.10"}
29
+ # 1 2016-06-15 {"CMVD": "0.10"}
30
30
  # 1 2016-03-15 {"NA": "137", "TP": "74", "ALB": "48", "ALP": "71", ...
31
31
  # 1 2016-02-29 {"NA": "136", "TP": "78", "ALB": "47", "ALP": "71", ...
32
32
  #
@@ -25,7 +25,7 @@ module Renalware
25
25
  CRP FER FOL B12 URE CRE EGFR NA POT BIC
26
26
  CCA PHOS PTHI TP GLO ALB URAT BIL ALT AST
27
27
  ALP GGT BGLU HBA HBAI CHOL HDL LDL TRIG TSH
28
- CK URR CRCL UREP AL
28
+ CK URR CRCL UREP AL CICLOMS TACROMS SIROMS CMVD TROP
29
29
  )
30
30
  end
31
31
  end
@@ -20,7 +20,7 @@ module Renalware
20
20
  end
21
21
 
22
22
  def to_s
23
- "transplant date within #{@param_comparison_value} weeks ago"
23
+ "transplant date within #{param_comparison_value} weeks ago"
24
24
  end
25
25
  end
26
26
  end
@@ -14,11 +14,13 @@ module Renalware
14
14
  return false if registration.blank?
15
15
 
16
16
  registration_status = registration.current_status
17
+ return false if registration_status.blank?
18
+
17
19
  registration_status.description.code == param_comparison_value
18
20
  end
19
21
 
20
22
  def to_s
21
- "transplant registration status is #{@param_comparison_value}"
23
+ "transplant registration status is #{param_comparison_value}"
22
24
  end
23
25
  end
24
26
  end
@@ -12,7 +12,7 @@ module Renalware
12
12
 
13
13
  belongs_to :patient, class_name: "::Renalware::Pathology::Patient", touch: true
14
14
  belongs_to :clinic, class_name: "::Renalware::Clinics::Clinic"
15
- belongs_to :consultant, class_name: "::Renalware::Pathology::Consultant"
15
+ belongs_to :consultant, class_name: "::Renalware::Renal::Consultant"
16
16
  has_and_belongs_to_many :request_descriptions,
17
17
  class_name: "::Renalware::Pathology::RequestDescription"
18
18
  has_and_belongs_to_many :patient_rules,
@@ -1,14 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_dependency "renalware/pathology"
4
+ require "attr_extras"
4
5
 
5
6
  module Renalware
6
7
  module Pathology
7
8
  module Requests
8
9
  class RequestParamsFactory
9
- def initialize(params)
10
- @params = params
11
- end
10
+ pattr_initialize :params
12
11
 
13
12
  def build
14
13
  {
@@ -16,7 +15,7 @@ module Renalware
16
15
  consultant: consultant,
17
16
  telephone: telephone,
18
17
  template: template,
19
- by: @params[:by]
18
+ by: params[:by]
20
19
  }
21
20
  end
22
21
 
@@ -39,9 +38,9 @@ module Renalware
39
38
  end
40
39
 
41
40
  def requested_clinic
42
- return if @params[:clinic_id].blank?
41
+ return if params[:clinic_id].blank?
43
42
 
44
- Renalware::Clinics::Clinic.find(@params[:clinic_id])
43
+ Renalware::Clinics::Clinic.find(params[:clinic_id])
45
44
  end
46
45
 
47
46
  def default_clinic
@@ -49,25 +48,25 @@ module Renalware
49
48
  end
50
49
 
51
50
  def requested_consultant
52
- return if @params[:consultant_id].blank?
51
+ return if params[:consultant_id].blank?
53
52
 
54
- Renalware::Pathology::Consultant.find(@params[:consultant_id])
53
+ Renalware::Renal::Consultant.find(params[:consultant_id])
55
54
  end
56
55
 
57
56
  def default_consultant
58
- Renalware::Pathology::Consultant.ordered.first
57
+ Renalware::Renal::Consultant.ordered.first
59
58
  end
60
59
 
61
60
  def requested_telephone
62
- @params[:telephone]
61
+ params[:telephone]
63
62
  end
64
63
 
65
64
  def default_telephone
66
- consultant.telephone
65
+ consultant&.telephone
67
66
  end
68
67
 
69
68
  def requested_template
70
- @params[:template]
69
+ params[:template]
71
70
  end
72
71
 
73
72
  def default_template
@@ -180,11 +180,12 @@ module Renalware
180
180
  end
181
181
 
182
182
  def must_have_at_least_one_identifier
183
- if hospital_identifiers.all.empty?
183
+ if hospital_identifiers.all.empty? && external_patient_id.blank?
184
184
  errors.add(
185
185
  :base,
186
186
  "The patient must have at least one of these numbers: "\
187
- "#{Renalware.config.patient_hospital_identifiers.keys.join(', ')}"
187
+ "#{Renalware.config.patient_hospital_identifiers.keys.join(', ')}, "\
188
+ "Other Hospital Number"
188
189
  )
189
190
  end
190
191
  end
@@ -78,16 +78,16 @@ module Renalware
78
78
  validates :no_cycles_per_apd, presence: true
79
79
  validates :fill_volume, presence: true
80
80
 
81
- with_options if: :has_additional_manual_exchange_bag?, on: [:create, :update] do |regime|
82
- regime.validates :additional_manual_exchange_volume, presence: true
81
+ with_options if: :has_additional_manual_exchange_bag?, on: [:create, :update] do
82
+ validates :additional_manual_exchange_volume, presence: true
83
83
  end
84
84
 
85
- with_options if: :has_last_fill_bag?, on: [:create, :update] do |regime|
86
- regime.validates :last_fill_volume, presence: true
85
+ with_options if: :has_last_fill_bag?, on: [:create, :update] do
86
+ validates :last_fill_volume, presence: true
87
87
  end
88
88
 
89
- with_options if: :tidal?, on: [:create, :update] do |regime|
90
- regime.validates :tidal_percentage, presence: true
89
+ with_options if: :tidal?, on: [:create, :update] do
90
+ validates :tidal_percentage, presence: true
91
91
  end
92
92
 
93
93
  def pd_type
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "renalware/renal"
4
+
5
+ module Renalware
6
+ module Renal
7
+ class Consultant < ApplicationRecord
8
+ validates :name, presence: true
9
+ scope :ordered, -> { order(name: :asc) }
10
+
11
+ def to_s
12
+ name
13
+ end
14
+ end
15
+ end
16
+ end
@@ -46,24 +46,18 @@ module Renalware
46
46
  .where(
47
47
  <<-SQL.squish
48
48
  (
49
- transplant_registration_status_descriptions.code in ('active','suspended')
49
+ transplant_registration_status_descriptions.code in ('active')
50
50
  and
51
51
  (
52
- transplant_registrations.document -> 'uk_transplant_centre' ->> 'status' not ilike '%' || transplant_registration_status_descriptions.code || '%'
53
- or
54
- transplant_registrations.document -> 'uk_transplant_centre' ->> 'status' = ''
55
- or
56
- transplant_registrations.document -> 'uk_transplant_centre' ->> 'status' IS NULL
52
+ transplant_registrations.document -> 'uk_transplant_centre' ->> 'status' not ilike 'A'
57
53
  )
58
54
  )
59
55
  or
60
56
  (
61
- transplant_registration_status_descriptions.code not in ('active','suspended')
57
+ transplant_registration_status_descriptions.code not in ('active')
62
58
  and
63
59
  (
64
- transplant_registrations.document -> 'uk_transplant_centre' ->> 'status' ilike '%active%'
65
- or
66
- transplant_registrations.document -> 'uk_transplant_centre' ->> 'status' ilike '%suspended%'
60
+ transplant_registrations.document -> 'uk_transplant_centre' ->> 'status' ilike 'A'
67
61
  )
68
62
  )
69
63
  SQL
@@ -14,7 +14,7 @@ module Renalware
14
14
  def self.call(modality)
15
15
  type = modality.description.code&.to_s&.camelize
16
16
  klass = (klass_for(type) || klass_for(DEFAULT_TYPE)).new(modality)
17
- Rails.logger.info "GeneratorFactory type = #{type} class = #{klass}"
17
+ Rails.logger.debug "GeneratorFactory type = #{type} class = #{klass}"
18
18
  klass
19
19
  end
20
20
 
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "renalware/letters"
4
+
5
+ module Renalware
6
+ module Letters
7
+ module Printing
8
+ # Creates a letter addressee/recipient cover sheet PDF that will be inserted in front
9
+ # of each copy of the letter. Page 2 is always blank because we as are duplex printing.
10
+ class RecipientAddressPagePdf
11
+ include Prawn::View
12
+ attr_reader :recipient
13
+
14
+ def initialize(recipient)
15
+ @recipient = recipient
16
+ build
17
+ end
18
+
19
+ def document
20
+ @document ||= Prawn::Document.new(
21
+ page_size: "A4",
22
+ page_layout: :portrait,
23
+ left_margin: 65,
24
+ top_margin: 109
25
+ )
26
+ end
27
+
28
+ private
29
+
30
+ def build
31
+ render_recipient_address
32
+ render_blank_second_page
33
+ self
34
+ end
35
+
36
+ def render_recipient_address
37
+ presenter = RecipientPresenter.new(recipient)
38
+ font_size 9
39
+ text "PRIVATE AND CONFIDENTIAL"
40
+ text " "
41
+ presenter.address.to_a.each { |line| text line }
42
+ end
43
+
44
+ def render_blank_second_page
45
+ start_new_page
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end