Skip to content

Commit 34f2174

Browse files
authored
Merge pull request #5294 from nhsuk/create-import-concern
Polymorphic import interface
2 parents ae4ef00 + a7b9a88 commit 34f2174

8 files changed

Lines changed: 177 additions & 166 deletions

app/components/app_import_summary_component.html.erb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
<%= row.with_value { import.uploaded_by.full_name } %>
88
<% end %>
99

10-
<% if show_approved_reviewers? %>
10+
<% if import.show_approved_reviewers? %>
1111
<%= summary_list.with_row do |row| %>
1212
<%= row.with_key { "Approved by" } %>
1313
<%= row.with_value { approved_reviewers_text } %>
1414
<% end %>
1515
<% end %>
1616

17-
<% if show_cancelled_reviewer? %>
17+
<% if import.show_cancelled_reviewer? %>
1818
<%= summary_list.with_row do |row| %>
1919
<%= row.with_key { cancelled_reviewer_label } %>
2020
<%= row.with_value { cancelled_reviewer_text } %>
@@ -28,7 +28,7 @@
2828

2929
<%= summary_list.with_row do |row| %>
3030
<%= row.with_key { "Type" } %>
31-
<%= row.with_value { import_type_label } %>
31+
<%= row.with_value { import.type_label } %>
3232
<% end %>
3333

3434
<%= summary_list.with_row do |row| %>
@@ -48,10 +48,10 @@
4848
<% end %>
4949
<% end %>
5050

51-
<% if !records_count.zero? %>
51+
<% if import.records_count && import.records_count.positive? %>
5252
<%= summary_list.with_row do |row| %>
5353
<%= row.with_key { "Records" } %>
54-
<%= row.with_value { records_count.to_s } %>
54+
<%= row.with_value { import.records_count.to_s } %>
5555
<% end %>
5656
<% end %>
5757
<% end %>

app/components/app_import_summary_component.rb

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -7,39 +7,10 @@ def initialize(import:)
77
@import = import
88
end
99

10-
def import_type_label
11-
{
12-
"ClassImport" => "Class list records",
13-
"CohortImport" => "Child records",
14-
"ImmunisationImport" => "Vaccination records"
15-
}[
16-
import.class.name
17-
]
18-
end
19-
20-
def show_approved_reviewers?
21-
return false unless import.is_a?(PatientImport)
22-
(import.processed? || import.partially_processed?) &&
23-
import.reviewed_by_user_ids.present?
24-
end
25-
26-
def show_cancelled_reviewer?
27-
(import.cancelled? || import.partially_processed?) &&
28-
import.reviewed_by_user_ids.present?
29-
end
30-
3110
def approved_reviewers_text
3211
import.partially_processed? ? approvers_text : all_reviewers_text
3312
end
3413

35-
def records_count
36-
if import.is_a?(PatientImport)
37-
import.changesets.from_file.count
38-
else
39-
import.vaccination_records.count
40-
end
41-
end
42-
4314
private
4415

4516
def cancelled_reviewer_label

app/models/class_import.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ class ClassImport < PatientImport
5050
dependent: :destroy
5151
has_many :pds_search_results
5252

53+
def type_label
54+
"Class list records"
55+
end
56+
5357
def postprocess_rows!
5458
# Remove patients already in the sessions but not in the class list.
5559
patients_in_import =

app/models/cohort_import.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ class CohortImport < PatientImport
4444
dependent: :destroy
4545
has_many :pds_search_results
4646

47+
def type_label
48+
"Child records"
49+
end
50+
4751
def postprocess_rows!
4852
ids = changesets.pluck(:school_id).uniq.compact
4953
PatientsAgedOutOfSchoolJob.perform_bulk(ids.zip)

app/models/concerns/csv_importable.rb

Lines changed: 20 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,25 @@ module CSVImportable
2121
scope :csv_not_removed, -> { where(csv_removed_at: nil) }
2222
scope :processed, -> { where.not(processed_at: nil) }
2323

24+
scope :status_for_uploaded_files,
25+
-> do
26+
where(
27+
status: %i[
28+
pending_import
29+
rows_are_invalid
30+
low_pds_match_rate
31+
changesets_are_invalid
32+
in_review
33+
calculating_re_review
34+
in_re_review
35+
committing
36+
cancelled
37+
]
38+
)
39+
end
40+
scope :status_for_imported_records,
41+
-> { where(status: %i[processed partially_processed]) }
42+
2443
enum :status,
2544
{
2645
pending_import: 0,
@@ -143,101 +162,7 @@ def process!
143162
parse_rows! if rows.nil?
144163
return if invalid?
145164

146-
if is_a?(PatientImport)
147-
process_patient_import!
148-
else
149-
process_immunisation_import!
150-
end
151-
end
152-
153-
def process_patient_import!
154-
changesets =
155-
rows.each_with_index.map do |row, row_number|
156-
PatientChangeset.from_import_row(row:, import: self, row_number:)
157-
end
158-
159-
if Flipper.enabled?(:import_search_pds)
160-
process_no_postcode_changesets(self.changesets.without_postcode)
161-
if self.changesets.with_postcode.any?
162-
enqueue_pds_cascading_searches(self.changesets.with_postcode)
163-
return
164-
end
165-
end
166-
167-
changesets.each(&:assign_patient_id)
168-
169-
validate_changeset_uniqueness!
170-
return if changesets_are_invalid?
171-
172-
if Flipper.enabled?(:import_review_screen)
173-
enqueue_review_jobs(self.changesets)
174-
else
175-
changesets.each(&:committing!)
176-
177-
CommitImportJob.perform_async(to_global_id.to_s)
178-
end
179-
end
180-
181-
def process_immunisation_import!
182-
counts = COUNT_COLUMNS.index_with(0)
183-
184-
ActiveRecord::Base.transaction do
185-
rows.each do |row|
186-
count_column_to_increment = process_row(row)
187-
counts[count_column_to_increment] += 1
188-
bulk_import(rows: 100)
189-
end
190-
191-
bulk_import(rows: :all)
192-
193-
postprocess_rows!
194-
195-
update_columns(processed_at: Time.zone.now, status: :processed, **counts)
196-
end
197-
198-
post_commit!
199-
UpdatePatientsFromPDS.call(patients, queue: :imports)
200-
end
201-
202-
def process_no_postcode_changesets(changesets)
203-
changesets.find_each do |cs|
204-
cs.search_results << {
205-
step: :no_fuzzy_with_history,
206-
result: :no_postcode,
207-
nhs_number: nil,
208-
created_at: Time.current
209-
}
210-
if Flipper.enabled?(:import_review_screen)
211-
cs.calculating_review!
212-
ReviewPatientChangesetJob.perform_later(cs.id)
213-
else
214-
cs.assign_patient_id
215-
cs.committing!
216-
end
217-
end
218-
end
219-
220-
def enqueue_review_jobs(changesets)
221-
review_changesets =
222-
if Flipper.enabled?(:import_search_pds)
223-
changesets.with_postcode
224-
else
225-
changesets
226-
end
227-
228-
review_changesets.each do |cs|
229-
cs.calculating_review!
230-
ReviewPatientChangesetJob.perform_later(cs.id)
231-
end
232-
end
233-
234-
def enqueue_pds_cascading_searches(changesets)
235-
changesets.find_each do |cs|
236-
PDSCascadingSearchJob.set(queue: :imports).perform_later(
237-
cs,
238-
queue: :imports
239-
)
240-
end
165+
process_import!
241166
end
242167

243168
def remove!

app/models/concerns/importable.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# frozen_string_literal: true
2+
3+
module Importable
4+
extend ActiveSupport::Concern
5+
6+
def show_approved_reviewers?
7+
raise NotImplementedError,
8+
"#{self.class.name} must implement #show_approved_reviewers?"
9+
end
10+
11+
def show_cancelled_reviewer?
12+
raise NotImplementedError,
13+
"#{self.class.name} must implement #show_cancelled_reviewer?"
14+
end
15+
16+
def records_count
17+
raise NotImplementedError,
18+
"#{self.class.name} must implement #records_count"
19+
end
20+
21+
def type_label
22+
raise NotImplementedError, "#{self.class.name} must implement #type_label"
23+
end
24+
end

app/models/immunisation_import.rb

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,28 @@
3232
#
3333
class ImmunisationImport < ApplicationRecord
3434
include CSVImportable
35+
include Importable
3536

3637
has_and_belongs_to_many :batches
3738
has_and_belongs_to_many :patient_locations
3839
has_and_belongs_to_many :sessions
3940
has_and_belongs_to_many :vaccination_records
4041

41-
scope :status_for_uploaded_files,
42-
-> do
43-
where(
44-
status: %i[
45-
pending_import
46-
rows_are_invalid
47-
low_pds_match_rate
48-
changesets_are_invalid
49-
in_review
50-
calculating_re_review
51-
in_re_review
52-
committing
53-
cancelled
54-
]
55-
)
56-
end
57-
scope :status_for_imported_records,
58-
-> { where(status: %i[processed partially_processed]) }
42+
def type_label
43+
"Vaccination records"
44+
end
45+
46+
def show_approved_reviewers?
47+
false
48+
end
49+
50+
def show_cancelled_reviewer?
51+
false
52+
end
53+
54+
def records_count
55+
vaccination_records.count
56+
end
5957

6058
private
6159

@@ -94,6 +92,27 @@ def process_row(row)
9492
count_column_to_increment
9593
end
9694

95+
def process_import!
96+
counts = COUNT_COLUMNS.index_with(0)
97+
98+
ActiveRecord::Base.transaction do
99+
rows.each do |row|
100+
count_column_to_increment = process_row(row)
101+
counts[count_column_to_increment] += 1
102+
bulk_import(rows: 100)
103+
end
104+
105+
bulk_import(rows: :all)
106+
107+
postprocess_rows!
108+
109+
update_columns(processed_at: Time.zone.now, status: :processed, **counts)
110+
end
111+
112+
post_commit!
113+
UpdatePatientsFromPDS.call(patients, queue: :imports)
114+
end
115+
97116
def bulk_import(rows: 100)
98117
return if rows != :all && @vaccination_records_batch.size < rows
99118

0 commit comments

Comments
 (0)