-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathdeduplicate_patients_controller.rb
More file actions
98 lines (81 loc) · 3.45 KB
/
deduplicate_patients_controller.rb
File metadata and controls
98 lines (81 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
class Admin::DeduplicatePatientsController < AdminController
skip_before_action :verify_authenticity_token
before_action :set_filter_options, only: [:show], if: :filter_enabled?
DUPLICATE_LIMIT = 250
def show
facilities = current_admin.accessible_facilities(:manage)
authorize { facilities.any? }
# Apply facility filter if selected and feature flag is enabled
filtered_facilities = if filter_enabled? && @selected_facility.present?
facilities.where(id: @selected_facility.id)
elsif filter_enabled? && @selected_district.present?
facilities.where(id: @selected_district.facilities)
else
facilities
end
# Scoping by facilities is costly for users who have a lot of facilities
use_all_organizations = current_admin.accessible_organizations(:manage).any? &&
(!filter_enabled? || (!@selected_district.present? && !@selected_facility.present?))
duplicate_patient_ids = if use_all_organizations
PatientDeduplication::Strategies.identifier_excluding_full_name_match(limit: DUPLICATE_LIMIT)
else
PatientDeduplication::Strategies.identifier_excluding_full_name_match_for_facilities(
limit: DUPLICATE_LIMIT,
facilities: filtered_facilities
)
end
@duplicate_count = duplicate_patient_ids.count
@patients = Patient.where(id: duplicate_patient_ids.sample).order(recorded_at: :asc)
end
def merge
authorize { current_admin.accessible_facilities(:manage).any? }
duplicate_patients = Patient.where(id: params[:duplicate_patients])
return head :unauthorized unless can_admin_deduplicate_patients?(duplicate_patients)
deduplicator = PatientDeduplication::Deduplicator.new(duplicate_patients, user: current_admin)
merged_patient = deduplicator.merge
if deduplicator.errors.present?
PatientDeduplication::Stats.report("manual", duplicate_patients.count, 0, duplicate_patients.count)
redirect_to admin_deduplication_path, alert: "Error in merging patients: #{deduplicator.errors.join(", ")}"
else
PatientDeduplication::Stats.report("manual", duplicate_patients.count, duplicate_patients.count, 0)
redirect_to admin_deduplication_path, notice: "Patients merged into #{merged_patient.full_name}."
end
end
def can_admin_deduplicate_patients?(patients)
current_admin
.accessible_facilities(:manage)
.where(id: patients.pluck(:assigned_facility_id))
.any?
end
private
def set_filter_options
@accessible_facilities = current_admin.accessible_facilities(:manage)
populate_districts
set_selected_district
populate_facilities
set_selected_facility
end
def populate_districts
@districts = Region.district_regions
.joins("INNER JOIN regions facility_region ON regions.path @> facility_region.path")
.where("facility_region.source_id" => @accessible_facilities.map(&:id))
.distinct(:slug)
.order(:name)
end
def set_selected_district
@selected_district = if params[:district_slug].present?
@districts.find_by(slug: params[:district_slug])
elsif @districts.present?
@districts.first
end
end
def populate_facilities
@facilities = @accessible_facilities.where(id: @selected_district&.facilities).order(:name)
end
def set_selected_facility
@selected_facility = @facilities.find_by(id: params[:facility_id]) if params[:facility_id].present?
end
def filter_enabled?
Flipper.enabled?(:patient_deduplication_filter, current_admin)
end
end