Skip to content
Merged
13 changes: 13 additions & 0 deletions app/components/app_import_review_component.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@
<% end %>
<% end %>

<% if @skipped_school_moves.any? %>
<h2 class="nhsuk-heading-m">Records not imported - children at schools in other team areas</h2>
<p class="nhsuk-u-reading-width">
<%= skipped_school_moves_message %>
</p>
<%= render AppDetailsComponent.new(expander: true, sticky: true) do |c| %>
<% c.with_summary do %>
<%= pluralize(@skipped_school_moves.count, "record") %> not imported
<% end %>
<%= render AppImportReviewRecordsSummaryComponent.new(changesets: @skipped_school_moves) %>
<% end %>
<% end %>

<hr class="nhsuk-section-break nhsuk-section-break--visible nhsuk-section-break--l">

<div class="nhsuk-button-group">
Expand Down
11 changes: 10 additions & 1 deletion app/components/app_import_review_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ def initialize(
new_records:,
auto_matched_records:,
import_issues:,
school_moves:
school_moves:,
skipped_school_moves: []
)
@import = import
@inter_team = inter_team.sort_by(&:row_number)
Expand All @@ -18,6 +19,7 @@ def initialize(
@import_issues = import_issues.sort_by(&:row_number)
@school_moves = school_moves
@school_moves_from_file = @school_moves.reject { it.row_number.nil? }
@skipped_school_moves = skipped_school_moves.sort_by(&:row_number)
end

private
Expand Down Expand Up @@ -69,6 +71,13 @@ def school_moves_message
end
end

def skipped_school_moves_message
count = @skipped_school_moves.count
"#{count} #{count > 1 ? "children" : "child"} #{count > 1 ? "are" : "is"} already " \
Comment thread
MartinVanIJcken marked this conversation as resolved.
"registered at a school in another team's area. #{count > 1 ? "These children" : "This child"} " \
"#{count > 1 ? "remain" : "remains"} at their current school."
end

def show_cancel_button?
@new_records.any? || @auto_matched_records.any? || @import_issues.any? ||
@school_moves_from_file.any?
Expand Down
12 changes: 12 additions & 0 deletions app/controllers/cohort_imports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ def show
@cohort_import.changesets.includes(:patient).nhs_number_discrepancies

@cancelled = @cohort_import.changesets.from_file.cancelled
@skipped_school_moves =
@cohort_import
.changesets
.includes(:patient, patient: :school)
.from_file
.skipped_school_move
end

render template: "imports/show",
Expand Down Expand Up @@ -186,5 +192,11 @@ def set_review_records
.includes(:school, patient: :school)
.ready_for_review
.with_school_moves - @inter_team
@skipped_school_moves =
@cohort_import
.changesets
.includes(:patient, patient: :school)
.ready_for_review
.skipped_school_move
end
end
17 changes: 12 additions & 5 deletions app/jobs/commit_import_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,19 @@ def perform(import_global_id)
changesets
.from_file
.includes(:school)
.find_in_batches(batch_size: 100) do |changesets|
increment_column_counts!(import, counts, changesets)
.find_in_batches(batch_size: 100) do |batch|
to_skip, to_process =
batch.partition(&:school_move_to_unknown_school_from_another_team?)

import_patients_and_parents(changesets, import)
import_school_moves(changesets, import)
import_pds_search_results(changesets, import)
if to_process.any?
increment_column_counts!(import, counts, to_process)

import_patients_and_parents(to_process, import)
import_school_moves(to_process, import)
import_pds_search_results(to_process, import)
end

to_skip.each(&:processed!)
end

PatientTeamUpdater.call(patient_scope: import.patients)
Expand Down
7 changes: 6 additions & 1 deletion app/jobs/commit_patient_changesets_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ def perform(patient_changeset_ids)
# Reset patient_ids to avoid stale associations
changesets.update_all(patient_id: nil)

to_process = changesets.select { review_consistent?(it) }
to_skip, to_process =
changesets
.select { review_consistent?(it) }
.partition(&:skipped_school_move?)

if to_process.any?
increment_column_counts!(import, counts, to_process)
Expand All @@ -40,6 +43,8 @@ def perform(patient_changeset_ids)
to_process.each(&:processed!)
end

to_skip.each(&:processed!)

PatientTeamUpdater.call(patient_scope: import.patients)
end

Expand Down
26 changes: 25 additions & 1 deletion app/models/patient_changeset.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,13 @@ class PatientChangeset < ApplicationRecord
validate: true

enum :record_type,
{ auto_match: 0, new_patient: 1, import_issue: 2, not_in_file: 3 },
{
auto_match: 0,
new_patient: 1,
import_issue: 2,
not_in_file: 3,
skipped_school_move: 4
},
validate: true

scope :nhs_number_discrepancies,
Expand Down Expand Up @@ -272,6 +278,10 @@ def school_move
@school_move ||=
begin
return if patient.deceased?
if import_type == "CohortImport" &&
school_move_to_unknown_school_from_another_team?
return
end
if patient.new_record? || patient.school != school ||
patient.home_educated != home_educated ||
patient.not_in_team?(team:, academic_year:) ||
Expand All @@ -287,6 +297,18 @@ def school_move
end
end

def school_move_to_unknown_school_from_another_team?
return false unless patient.persisted?

moving_to_unknown_school =
(patient.school.present? || patient.home_educated?) &&
!(school.present? || home_educated)

from_another_team = !patient.teams_via_patient_locations.include?(team)

moving_to_unknown_school && from_another_team
end

def existing_patients
deserialize_attribute(child_attributes, "date_of_birth", :date)
deserialize_attribute(child_attributes, "invalidated_at", :datetime)
Expand Down Expand Up @@ -443,6 +465,8 @@ def stage_and_handle_pending_changes(existing_patient)
def changeset_type
if patient.id.nil?
:new_patient
elsif school_move_to_unknown_school_from_another_team?
:skipped_school_move
elsif patient.pending_changes.any?
:import_issue
else
Expand Down
22 changes: 22 additions & 0 deletions app/views/imports/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
auto_matched_records: @auto_matched_records,
import_issues: @import_issues,
school_moves: @school_moves,
skipped_school_moves: @skipped_school_moves || [],
) %>
<% end %>

Expand All @@ -86,6 +87,27 @@
</details>
<% end %>

<% if @skipped_school_moves.present? %>
<h3 class="nhsuk-u-reading-width">
Records not imported - children at schools in other team areas
</h3>
<p class="nhsuk-hint">
This upload included <%= @skipped_school_moves.count > 1 ? "children" : "a child" %> who <%= @skipped_school_moves.count == 1 ? "was" : "were" %> already
Comment thread
MartinVanIJcken marked this conversation as resolved.
registered at a school in another team's area. <%= @skipped_school_moves.count == 1 ? "This child remains" : "These children remain" %>
at their current school.
</p>
<details class="nhsuk-details nhsuk-expander">
<summary class="nhsuk-details__summary" data-module="app-sticky">
<span class="nhsuk-details__summary-text">
<%= pluralize(@skipped_school_moves.count, "record") %> not imported
</span>
</summary>
<div class="nhsuk-details__text">
<%= render AppImportReviewRecordsSummaryComponent.new(changesets: @skipped_school_moves) %>
</div>
</details>
<% end %>

<% if @nhs_discrepancies.present? %>
<h3 class="nhsuk-u-reading-width">
NHS numbers updated from PDS
Expand Down
49 changes: 48 additions & 1 deletion spec/components/app_import_review_component_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
new_records:,
auto_matched_records:,
import_issues:,
school_moves:
school_moves:,
skipped_school_moves:
)
end

Expand All @@ -37,6 +38,7 @@
let(:import_issues) { [] }
let(:inter_team) { [] }
let(:school_moves) { [] }
let(:skipped_school_moves) { [] }

shared_examples "section with details" do |title:, summary:, count:|
it "renders section '#{title}'" do
Expand Down Expand Up @@ -255,6 +257,51 @@
end
end

describe "with skipped school moves" do
let(:other_team_school) do
create(:school, team: other_team, name: "School in Other Team")
end
let(:skipped_patient) do
create(:patient, school: other_team_school, team: other_team)
end
let(:skipped_school_moves) do
[
create(
:patient_changeset,
import:,
patient: skipped_patient,
school: nil
)
]
end

before do
skipped_school_moves.first.data["upload"]["home_educated"] = false
skipped_school_moves.first.save!

create(
:patient_location,
patient: skipped_patient,
location: other_team_school
)
end

include_examples "section with details",
title:
"Records not imported - children at schools in other team areas",
summary: "1 record not imported",
count: 1

it "shows the section description" do
expect(rendered).to have_content(
"1 child is already registered at a school in another team's area"
)
expect(rendered).to have_content(
"This child remains at their current school."
)
end
end

describe "buttons" do
context "with records to import" do
let(:new_records) do
Expand Down
11 changes: 11 additions & 0 deletions spec/factories/patients.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,17 @@
trait :home_educated do
school { nil }
home_educated { true }

after(:create) do |patient, evaluator|
clinic = create(:generic_clinic, team: evaluator.team)

create(
:patient_location,
patient:,
location: clinic,
academic_year: evaluator.academic_year
)
end
end

trait :deceased do
Expand Down
Loading