renalware-core 2.0.145 → 2.0.146

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/stylesheets/renalware/modules/_letters.scss +17 -0
  3. data/app/components/renalware/system/admin_menu_component.html.slim +1 -0
  4. data/app/controllers/renalware/letters/mailshots/mailshots_controller.rb +53 -0
  5. data/app/controllers/renalware/letters/mailshots/patient_previews_controller.rb +41 -0
  6. data/app/jobs/renalware/letters/mailshots/create_mailshot_letters_job.rb +27 -0
  7. data/app/models/renalware/letters/draft_letter.rb +1 -0
  8. data/app/models/renalware/letters/letter_factory.rb +1 -1
  9. data/app/models/renalware/letters/mailshots/data_source.rb +20 -0
  10. data/app/models/renalware/letters/mailshots/item.rb +17 -0
  11. data/app/models/renalware/letters/mailshots/mailshot.rb +117 -0
  12. data/app/models/renalware/letters.rb +6 -0
  13. data/app/policies/renalware/letters/mailshots/mailshot_policy.rb +21 -0
  14. data/app/views/renalware/letters/mailshots/mailshots/_form.html.slim +60 -0
  15. data/app/views/renalware/letters/mailshots/mailshots/index.html.slim +31 -0
  16. data/app/views/renalware/letters/mailshots/mailshots/new.html.slim +2 -0
  17. data/app/views/renalware/letters/mailshots/patient_previews/_index.html.slim +26 -0
  18. data/app/views/renalware/letters/mailshots/patient_previews/index.js.erb +1 -0
  19. data/config/routes/letters.rb +5 -0
  20. data/db/migrate/20200318134807_create_letter_mailshots.rb +50 -0
  21. data/db/migrate/20200320103052_add_status_to_letter_mailshot_mailshots.rb +14 -0
  22. data/lib/renalware/version.rb +1 -1
  23. data/spec/support/pages/letters/mailshots/form.rb +58 -0
  24. metadata +17 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 264987f5d8be265da2a90a036b68107e57d56799d4ead8c1b40e11a351a9d65a
4
- data.tar.gz: db66496b53c89e79e7ba629ba799ef891abd739b3097eeec89aedfcba2b21155
3
+ metadata.gz: ea66f0da3fb417c2ff7f515964db415e68e61f447fdf742c97906d635aecb7a6
4
+ data.tar.gz: a1f6203e5b3f637bd9a85413ddbfe25739916e1ac33dc1f44e080acb4303f533
5
5
  SHA512:
6
- metadata.gz: be45e35ef297c5b1f031cdbbebdf0fa3579dbcc32c31b1d5786efaa96dd520328aff549ed7513cbf3d4a2599ae906595efecf93cc6d0c62cb56c8652ece29f7c
7
- data.tar.gz: 9bf397ab6768aa9ef420077804f457865959f906ebac530e6149ab3cc68d3c7e5d4af60aed095a6e5deb1748c13abdf263faa243b9e74bfed729f77514675306
6
+ metadata.gz: d0269f2b3d9fdda86ea868fdf074314cce11f647030768d922ebfe1650eaf67fcd8f22bf321bd4f409daf2e4c1f991934b1e817e4ef213ccf37d873ced1fe797
7
+ data.tar.gz: 740773f49f38ab01bfea92f1a06dc0c1cc83af18ccc8a7d483bb1ea01aaff2a71501df866f28de44c21d178b81d59e204660dc7c9d7a7a085b33b7b9fbfc2eb9
@@ -158,3 +158,20 @@ table.letters {
158
158
  }
159
159
  }
160
160
  }
161
+
162
+ .mailshot-status {
163
+ text-align: center;
164
+ text-transform: uppercase;
165
+
166
+ &.mailshot-status--failure,
167
+ &.mailshot-status--failure:hover {
168
+ background-color: red;
169
+ color: $white;
170
+ }
171
+
172
+ &.mailshot-status--success,
173
+ &.mailshot-status--success:hover {
174
+ background-color: $nhs-green;
175
+ color: $white;
176
+ }
177
+ }
@@ -22,4 +22,5 @@ ul.side-nav.side-nav--admin
22
22
  = super_admin_menu_item "HD Dialysers", renalware.hd_dialysers_path, %r{hd/dialysers}
23
23
  = super_admin_menu_item "HD Cannulation Types", renalware.hd_cannulation_types_path, %r{hd/cannulation_types}
24
24
  = super_admin_menu_item "Print batches", renalware.letters_batches_path, %r{letters/batches}
25
+ = admin_menu_item "Mailshots", renalware.letters_mailshots_path, %r{letters/mailshots}
25
26
  = developer_menu_item "HL7 Test", renalware.new_feeds_hl7_test_message_path
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "renalware/letters"
4
+
5
+ module Renalware
6
+ module Letters
7
+ module Mailshots
8
+ class MailshotsController < BaseController
9
+ include Pagy::Backend
10
+
11
+ def index
12
+ pagy, mailshots = pagy(Mailshot.includes(:author).order(created_at: :desc))
13
+ authorize mailshots
14
+ render locals: { mailshots: mailshots, pagy: pagy }
15
+ end
16
+
17
+ def new
18
+ mailshot = Mailshot.new
19
+ authorize mailshot
20
+ render_new(mailshot)
21
+ end
22
+
23
+ def create
24
+ mailshot = Mailshot.new(mailshot_params)
25
+ authorize mailshot, :create?
26
+ mailshot.letters_count = mailshot.recipient_patients.length
27
+ mailshot.status = "queued"
28
+
29
+ if mailshot.save_by(current_user)
30
+ CreateMailshotLettersJob.perform_later(mailshot)
31
+ redirect_to letters_mailshots_path, notice: "Mailshot queued for background processing"
32
+ else
33
+ render_new(mailshot)
34
+ end
35
+ end
36
+
37
+ private
38
+
39
+ def render_new(mailshot)
40
+ render :new, locals: { mailshot: mailshot }
41
+ end
42
+
43
+ def mailshot_params
44
+ params
45
+ .require(:mailshot)
46
+ .permit(
47
+ :letterhead_id, :description, :author_id, :body, :sql_view_name
48
+ )
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "renalware/letters"
4
+
5
+ module Renalware
6
+ module Letters
7
+ module Mailshots
8
+ # Called via ajax from the new mailshot form, and responsible for taking the
9
+ # SQL view the user has chosen as the mailshot datasource, and returning a list of
10
+ # patients that the user can see and check before going on to create the mailshot.
11
+ class PatientPreviewsController < BaseController
12
+ include Pagy::Backend
13
+
14
+ # Note we use data-remote as we want the table where the previewed patients are
15
+ # displayed to have pagination links that work via ajax and do not refresh the page.
16
+ def index
17
+ authorize Patient, :index?
18
+ pagy, patients = pagy(
19
+ Mailshot.new(sql_view_name: sql_view_name).recipient_patients,
20
+ link_extra: "data-remote='true'"
21
+ )
22
+ render locals: {
23
+ patients: patients,
24
+ pagy: pagy,
25
+ datasource: DataSource.find_by(viewname: sql_view_name)
26
+ }
27
+ end
28
+
29
+ private
30
+
31
+ # The user will have selected a view name from the dropdown onm the form.
32
+ # This is the name of a SQL view in the database in the format
33
+ # letter_mailshot_xxxxxx eg letter_mailshot_tx_patients.
34
+ # See help text on the html form for an example of a SQL view.
35
+ def sql_view_name
36
+ params.dig(:mailshot, :sql_view_name)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -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 Mailshots
9
+ # A background job to create letter records for a mailshot.
10
+ # More than 1000 letters in a mailshot could cause a timeout if executed
11
+ # while the user waits, which is why processing is done in the background.
12
+ class CreateMailshotLettersJob < ApplicationJob
13
+ def perform(mailshot)
14
+ mailshot.update_column(:status, :processing)
15
+ mailshot.create_letters
16
+ mailshot.update_columns(status: :success, last_error: nil)
17
+ rescue StandardError => e
18
+ mailshot.update_columns(
19
+ last_error: "#{$ERROR_INFO}\nBacktrace:\n\t#{e.backtrace.join("\n\t")}",
20
+ status: :failure
21
+ )
22
+ raise e
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -18,6 +18,7 @@ module Renalware
18
18
  letter.save!
19
19
  letter.reload
20
20
  broadcast(:draft_letter_successful, letter)
21
+ letter
21
22
  rescue ActiveRecord::RecordInvalid
22
23
  broadcast(:draft_letter_failed, letter)
23
24
  end
@@ -54,7 +54,7 @@ module Renalware
54
54
  Letter::Draft.new(params.merge!(type: Letter::Draft.name, patient: patient))
55
55
  end
56
56
 
57
- # note both practice and gp need to be present before we can the pcp - we'll use the
57
+ # note both practice and gp need to be present before we can send to the pcp - we'll use the
58
58
  # practice address but the GP's name as the salutation.
59
59
  def include_primary_care_physician_as_default_main_recipient
60
60
  return if letter.main_recipient.present?
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "renalware/letters"
4
+
5
+ module Renalware
6
+ module Letters
7
+ module Mailshots
8
+ # A list of SQL views with a name startingwith "letters_mailshot_"
9
+ # along with some metadata about the view
10
+ class DataSource < ApplicationRecord
11
+ self.table_name = "pg_catalog.pg_views"
12
+
13
+ default_scope lambda {
14
+ where(Arel.sql("schemaname like 'renalware%'"))
15
+ .where(Arel.sql("viewname like 'letter_mailshot_%'"))
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "renalware/letters"
4
+
5
+ module Renalware
6
+ module Letters
7
+ module Mailshots
8
+ class Item < ApplicationRecord
9
+ belongs_to :letter
10
+ belongs_to :mailshot
11
+
12
+ validates :letter, presence: true
13
+ validates :mailshot, presence: true
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_dependency "renalware/letters"
4
+
5
+ module Renalware
6
+ module Letters
7
+ module Mailshots
8
+ class Mailshot < ApplicationRecord
9
+ include Accountable
10
+ # This maps to a PG enum called background_job_status
11
+ enum status: {
12
+ queued: "queued",
13
+ processing: "processing",
14
+ success: "success",
15
+ failure: "failure"
16
+ }
17
+
18
+ belongs_to :author, class_name: "User"
19
+ belongs_to :letterhead
20
+ has_many :items, dependent: :destroy
21
+ has_many :letters, through: :items
22
+
23
+ validates :description, presence: true
24
+ validates :sql_view_name, presence: true
25
+ validates :body, presence: true
26
+ validates :author, presence: true
27
+ validates :letterhead, presence: true
28
+
29
+ # The sql view should ideally only have one column - 'patient_id' because we use this
30
+ # to filter the patients we want.
31
+ def recipient_patients
32
+ @recipient_patients ||= begin
33
+ return Patient.none if sql_view_name.blank?
34
+
35
+ Patient
36
+ .where(Arel.sql("id in (select distinct patient_id from #{sql_view_name})"))
37
+ .order(:family_name, :given_name)
38
+ end
39
+ end
40
+
41
+ # Called usually by a background job, creates all the letters in the mailshot.
42
+ # The patients to create letters for are defined by the SQL view output.
43
+ # The other data items required for creating the letters are stored in the mailshot
44
+ # object
45
+ def create_letters
46
+ Mailshot.transaction do
47
+ recipient_patients.each do |patient|
48
+ letter = MailshotLetterFactory.new(
49
+ patient: patient,
50
+ current_user: created_by,
51
+ letter_attributes: common_letter_attributes
52
+ ).create
53
+ items.create!(letter: letter)
54
+ end
55
+ end
56
+ end
57
+
58
+ # These attributes apply to all letters in the mailshot
59
+ # rubocop:disable Metrics/MethodLength
60
+ def common_letter_attributes
61
+ @common_letter_attributes ||= begin
62
+ {
63
+ letterhead_id: letterhead_id,
64
+ description: description,
65
+ body: body,
66
+ author_id: author_id,
67
+ issued_on: Time.zone.now,
68
+ main_recipient_attributes: {
69
+ person_role: :patient,
70
+ id: nil,
71
+ addressee_id: nil
72
+ }
73
+ }
74
+ end
75
+ end
76
+ # rubocop:enable Metrics/MethodLength
77
+ end
78
+
79
+ # Factory class responsible for creating a mailshot letter by moving it
80
+ # through its 'state machine' states until it is approved and ready to print.
81
+ # Doing it this ways ensures all pub/sub events, callbacks etc happen in
82
+ # correctly and in order.
83
+ class MailshotLetterFactory
84
+ pattr_initialize [:patient!, :current_user!, :letter_attributes!]
85
+ attr_reader :letter
86
+
87
+ def create
88
+ draft
89
+ submit_for_review
90
+ approve
91
+ letter
92
+ end
93
+
94
+ def draft
95
+ @letter = LetterFactory
96
+ .new(patient, letter_attributes)
97
+ .with_contacts_as_default_ccs
98
+ .build
99
+ letter.save_by!(current_user)
100
+ end
101
+
102
+ def submit_for_review
103
+ letter.submit(by: current_user) # now pending review
104
+ letter.save!
105
+ @letter = Letters::Letter::PendingReview.find(letter.id)
106
+ end
107
+
108
+ def approve
109
+ ApproveLetter
110
+ .build(letter)
111
+ .broadcasting_to_configured_subscribers
112
+ .call(by: current_user)
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -27,5 +27,11 @@ module Renalware
27
27
 
28
28
  module Delivery
29
29
  end
30
+
31
+ module Mailshots
32
+ def self.table_name_prefix
33
+ "letter_mailshot_"
34
+ end
35
+ end
30
36
  end
31
37
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Renalware
4
+ module Letters
5
+ module Mailshots
6
+ class MailshotPolicy < BasePolicy
7
+ def new?
8
+ user_is_super_admin?
9
+ end
10
+
11
+ def create?
12
+ new?
13
+ end
14
+
15
+ def index?
16
+ user_is_super_admin? || user_is_admin?
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,60 @@
1
+ .row
2
+ = simple_form_for(mailshot,
3
+ as: :mailshot,
4
+ url: letters_mailshots_path,
5
+ html: { id: "mailshot-form" }) do |form|
6
+ .columns.small-12
7
+ = form.input :description, placeholder: "A description of the mailshot purpose."
8
+ .columns.small-12
9
+ = form.input(:sql_view_name,
10
+ collection: Renalware::Letters::Mailshots::DataSource.all.map(&:viewname),
11
+ input_html: { data: { remote:"true", url: renalware.letters_mailshots_patient_previews_path }})
12
+
13
+ .columns.medium-6
14
+ = form.association :letterhead
15
+ .columns.medium-6
16
+ = form.association :author,
17
+ as: :user_picker,
18
+ collection: Renalware::System::UsersPresenter.new.list_for_dropdown( \
19
+ user_to_promote_to_top: current_user \
20
+ )
21
+ .columns.small-12
22
+ = form.input :body, as: :trix_editor
23
+ br
24
+ = form.submit "Create letters",
25
+ class: :button,
26
+ data: { confirm: "Are you sure you want to this mailshot?",
27
+ disable_with: "Creating letters..." }
28
+ .columns.small-12
29
+ / When the SQL view name dropdown changes we will populate this div with a
30
+ / table containing name of the patients to whom the mailshot will be sent.
31
+ / See data-url on the sql_view_name dropdown for the rails route that will be
32
+ / called. It will render a ujs template eg index.js.erb to insert the list of
33
+ / patients into this view.
34
+ #mailshot-patients-preview
35
+
36
+ .columns.small-12
37
+ br
38
+ .panel
39
+ h2
40
+ i.fas.fa-info-circle style="color: #00a499"
41
+ span(style="padding-left: 5px") Tips
42
+ p
43
+ | The list of patients to include in a mailshot it determined by the SQL View chosen above.
44
+ | &nbsp;It is intended that a systems or database administrator create this view for you in the
45
+ | &nbsp;renalware database. The view should have one column called 'patient_id' and return the ids
46
+ | &nbsp;of all the patients you want to send this letter to.
47
+ | &nbsp;You should ideally create the view in the hospital's
48
+ | &nbsp;own postgres schema eg 'renalware_kch' in the case of Kings College Hospital.
49
+ p Here is a (somewhat pointless) example of a compatible SQL view definition:
50
+ p
51
+ code
52
+ | CREATE OR REPLACE VIEW
53
+ br
54
+ | renalware_kch.letter_mailshot_patients_where_surname_starts_with_r AS
55
+ br
56
+ | SELECT id as patient_id
57
+ br
58
+ | FROM patients
59
+ br
60
+ | WHERE family_name like 'R%';
@@ -0,0 +1,31 @@
1
+ - content_for(:actions) do
2
+ - if policy(Renalware::Letters::Mailshots::Mailshot).new?
3
+ = link_to "Add", new_letters_mailshot_path, class: :button
4
+
5
+ = within_new_admin_layout(title: "Mailshots") do
6
+ table.toggleable.mailshots data-controller="toggle"
7
+ thead
8
+ th.togglers.noprint= rows_toggler
9
+ th.col-width-date-time Created
10
+ th.col-width-medium Description
11
+ th.col-width-medium Author
12
+ th.col-width-tiny Letter Count
13
+ th Status
14
+ th Last Error
15
+ - mailshots.each do |mailshot|
16
+ tbody
17
+ tr
18
+ td= row_toggler
19
+ td= l(mailshot.created_at)
20
+ td= mailshot.description
21
+ td= mailshot.author
22
+ td= mailshot.letters_count
23
+ td class="mailshot-status mailshot-status--#{mailshot.status}"
24
+ = mailshot.status
25
+ td
26
+ - if mailshot.last_error
27
+ = mailshot.last_error&.gsub("\n", "<br>").truncate(1000).html_safe
28
+ tr
29
+ td(colspan=7)
30
+ | Body:
31
+ = mailshot.body.html_safe
@@ -0,0 +1,2 @@
1
+ = within_new_admin_layout(title: "New mailshot") do
2
+ = render "form", mailshot: mailshot
@@ -0,0 +1,26 @@
1
+ - if patients.none?
2
+ .panel
3
+ b No patients
4
+ - else
5
+ .panel
6
+ p
7
+ b #{pagy.count} patients will be included in the mailshot
8
+ p
9
+ | The SQL for
10
+ i= " #{datasource&.viewname}:"
11
+ p
12
+ code= datasource&.definition
13
+ table.mailshot-patient-previews
14
+ thead
15
+ th.col-width-large Patient name
16
+ th.col-width-nhs-no NHS number
17
+ th.col-width-reference-no Hospital nos
18
+ th
19
+ tbody
20
+ - patients.each do |patient|
21
+ tr
22
+ td= patient
23
+ td= patient.nhs_number
24
+ td= patient.hospital_identifiers
25
+ td
26
+ == pagy_foundation_nav pagy
@@ -0,0 +1 @@
1
+ $("#mailshot-patients-preview").html("<%= j(render 'index', patients: patients, datasource: datasource, pagy: pagy) %>");
@@ -22,6 +22,11 @@ resources :patients, only: [] do
22
22
  end
23
23
 
24
24
  namespace :letters do
25
+ resources :mailshots, only: [:create, :new, :index], controller: "mailshots/mailshots"
26
+ namespace :mailshots do
27
+ resources :patient_previews, only: :index
28
+ end
29
+
25
30
  resources :batches, only: [:create, :index, :show] do
26
31
  get :status, constraints: { format: :json }, defaults: { format: :json }
27
32
  resources :completions, only: [:new, :create], controller: "completed_batches"
@@ -0,0 +1,50 @@
1
+ class CreateLetterMailshots < ActiveRecord::Migration[5.2]
2
+ def change
3
+ within_renalware_schema do
4
+ create_table(
5
+ :letter_mailshot_mailshots,
6
+ comment: "A mailshot is an adhoc letter sent to a group of patients"
7
+ ) do |t|
8
+ t.string(
9
+ :description,
10
+ null: false,
11
+ comment: "Some text to identify the mailshot purpose. "\
12
+ "Will be written to letter_letters.description column when letter created"
13
+ )
14
+ t.string(
15
+ :sql_view_name,
16
+ null: false,
17
+ comment: "The name of the SQL view chosen as the data source"
18
+ )
19
+ t.text(
20
+ :body,
21
+ null: false,
22
+ comment: "The body text that will be inserted into each letter"
23
+ )
24
+ t.references :letterhead, foreign_key: { to_table: :letter_letterheads }, null: false
25
+ t.references :author, foreign_key: { to_table: :users }, index: true, null: false
26
+ t.integer :letters_count, comment: "Counter cache column which Rails will update"
27
+ t.references :created_by, foreign_key: { to_table: :users }, null: false
28
+ t.references :updated_by, foreign_key: { to_table: :users }, null: false
29
+ t.timestamps null: false
30
+ end
31
+
32
+ # rubocop:disable Rails/CreateTableWithTimestamps
33
+ create_table(
34
+ :letter_mailshot_items,
35
+ comment: "A record of the letters sent in a mailshot"
36
+ ) do |t|
37
+ t.references :mailshot, foreign_key: { to_table: :letter_mailshot_mailshots }, null: false
38
+ t.references :letter, foreign_key: { to_table: :letter_letters }, null: false
39
+ end
40
+ # rubocop:enable Rails/CreateTableWithTimestamps
41
+
42
+ add_index(
43
+ :letter_mailshot_items,
44
+ [:mailshot_id, :letter_id],
45
+ unique: true,
46
+ comment: "A sanity check that a letter appears only once in a mailshot"
47
+ )
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,14 @@
1
+ class AddStatusToLetterMailshotMailshots < ActiveRecord::Migration[5.2]
2
+ def change
3
+ within_renalware_schema do
4
+ create_enum(
5
+ :background_job_status,
6
+ %w(queued processing success failure)
7
+ )
8
+ change_table :letter_mailshot_mailshots do |t|
9
+ t.enum :status, enum_name: :background_job_status
10
+ t.text :last_error
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Renalware
4
- VERSION = "2.0.145"
4
+ VERSION = "2.0.146"
5
5
  end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails_helper"
4
+ require_relative "../../page_object"
5
+ require "capybara-select-2"
6
+
7
+ module Pages
8
+ module Letters
9
+ module Mailshots
10
+ class Form < PageObject
11
+ include CapybaraSelect2
12
+ include TextEditorHelpers
13
+
14
+ def navigate_here_from_admin_dashboard
15
+ visit admin_dashboard_path
16
+
17
+ within ".side-nav--admin" do
18
+ click_on "Mailshots"
19
+ end
20
+
21
+ within ".page-actions" do
22
+ click_on "Add"
23
+ end
24
+ end
25
+
26
+ def letterhead=(letterhead)
27
+ select letterhead, from: "Letterhead"
28
+ end
29
+
30
+ def author=(user)
31
+ select user.to_s, from: "Author"
32
+ end
33
+
34
+ def description=(value)
35
+ fill_in "Description", with: value
36
+ end
37
+
38
+ def sql_view_name=(value)
39
+ select value, from: "Sql view name"
40
+ end
41
+
42
+ def body=(value)
43
+ fill_trix_editor with: value
44
+ end
45
+
46
+ def patient_preview_table
47
+ "#mailshot-patients-preview"
48
+ end
49
+
50
+ def submit
51
+ accept_alert do
52
+ click_on "Create letters"
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: renalware-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.145
4
+ version: 2.0.146
5
5
  platform: ruby
6
6
  authors:
7
7
  - Airslie
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-17 00:00:00.000000000 Z
11
+ date: 2020-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionview-component
@@ -1290,6 +1290,8 @@ files:
1290
1290
  - app/controllers/renalware/letters/formatted_letters_controller.rb
1291
1291
  - app/controllers/renalware/letters/letters_controller.rb
1292
1292
  - app/controllers/renalware/letters/lists_controller.rb
1293
+ - app/controllers/renalware/letters/mailshots/mailshots_controller.rb
1294
+ - app/controllers/renalware/letters/mailshots/patient_previews_controller.rb
1293
1295
  - app/controllers/renalware/letters/pdf_letter_cache_controller.rb
1294
1296
  - app/controllers/renalware/letters/pending_review_letters_controller.rb
1295
1297
  - app/controllers/renalware/letters/printable_letters_controller.rb
@@ -1490,6 +1492,7 @@ files:
1490
1492
  - app/jobs/renalware/hd/update_rolling_patient_statistics_dj_job.rb
1491
1493
  - app/jobs/renalware/hd/update_rolling_patient_statistics_job.rb
1492
1494
  - app/jobs/renalware/letters/calculate_page_count_job.rb
1495
+ - app/jobs/renalware/letters/mailshots/create_mailshot_letters_job.rb
1493
1496
  - app/jobs/renalware/letters/printing/batch_print_job.rb
1494
1497
  - app/jobs/renalware/letters/save_pdf_letter_to_file_job.rb
1495
1498
  - app/jobs/renalware/letters/save_rtf_letter_to_file_job.rb
@@ -1718,6 +1721,9 @@ files:
1718
1721
  - app/models/renalware/letters/letter_query.rb
1719
1722
  - app/models/renalware/letters/letterhead.rb
1720
1723
  - app/models/renalware/letters/lists/form.rb
1724
+ - app/models/renalware/letters/mailshots/data_source.rb
1725
+ - app/models/renalware/letters/mailshots/item.rb
1726
+ - app/models/renalware/letters/mailshots/mailshot.rb
1721
1727
  - app/models/renalware/letters/part.rb
1722
1728
  - app/models/renalware/letters/part/allergies.rb
1723
1729
  - app/models/renalware/letters/part/clinical_observations.rb
@@ -2134,6 +2140,7 @@ files:
2134
2140
  - app/policies/renalware/letters/draft_letter_policy.rb
2135
2141
  - app/policies/renalware/letters/electronic_receipt_policy.rb
2136
2142
  - app/policies/renalware/letters/letter_policy.rb
2143
+ - app/policies/renalware/letters/mailshots/mailshot_policy.rb
2137
2144
  - app/policies/renalware/letters/pending_review_letter_policy.rb
2138
2145
  - app/policies/renalware/low_clearance/profile_policy.rb
2139
2146
  - app/policies/renalware/messaging/internal/message_policy.rb
@@ -2678,6 +2685,11 @@ files:
2678
2685
  - app/views/renalware/letters/lists/_tabs.html.slim
2679
2686
  - app/views/renalware/letters/lists/show.html.slim
2680
2687
  - app/views/renalware/letters/lists/show.js.erb
2688
+ - app/views/renalware/letters/mailshots/mailshots/_form.html.slim
2689
+ - app/views/renalware/letters/mailshots/mailshots/index.html.slim
2690
+ - app/views/renalware/letters/mailshots/mailshots/new.html.slim
2691
+ - app/views/renalware/letters/mailshots/patient_previews/_index.html.slim
2692
+ - app/views/renalware/letters/mailshots/patient_previews/index.js.erb
2681
2693
  - app/views/renalware/letters/parts/_allergies.html.slim
2682
2694
  - app/views/renalware/letters/parts/_clinical_observations.html.slim
2683
2695
  - app/views/renalware/letters/parts/_prescriptions.html.slim
@@ -3860,6 +3872,8 @@ files:
3860
3872
  - db/migrate/20200301124300_create_medication_delivery_event_prescriptions.rb
3861
3873
  - db/migrate/20200306183423_add_next_delivery_date_to_prescriptions.rb
3862
3874
  - db/migrate/20200316131136_add_covid_19_to_patient_alerts.rb
3875
+ - db/migrate/20200318134807_create_letter_mailshots.rb
3876
+ - db/migrate/20200320103052_add_status_to_letter_mailshot_mailshots.rb
3863
3877
  - db/seeds.rb
3864
3878
  - db/seeds/default/accesses/access_pd_catheter_insertion_techniques.csv
3865
3879
  - db/seeds/default/accesses/access_pd_catheter_insertion_techniques.rb
@@ -4239,6 +4253,7 @@ files:
4239
4253
  - spec/support/pages/clinical/profile_page.rb
4240
4254
  - spec/support/pages/hd/prescription_administration_dialog.rb
4241
4255
  - spec/support/pages/letters/form.rb
4256
+ - spec/support/pages/letters/mailshots/form.rb
4242
4257
  - spec/support/pages/letters/patient_letters.rb
4243
4258
  - spec/support/pages/low_clearance/profile_page.rb
4244
4259
  - spec/support/pages/medications/home_delivery_dialog.rb