-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathdraft_vaccination_records_controller.rb
More file actions
295 lines (244 loc) · 7.88 KB
/
draft_vaccination_records_controller.rb
File metadata and controls
295 lines (244 loc) · 7.88 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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# frozen_string_literal: true
class DraftVaccinationRecordsController < ApplicationController
include TodaysBatchConcern
skip_after_action :verify_policy_scoped
before_action :set_draft_vaccination_record
before_action :set_patient
before_action :set_session
before_action :set_programme
before_action :set_vaccination_record
include WizardControllerConcern
before_action :validate_params, only: :update
before_action :set_batches, if: -> { current_step == :batch }
before_action :set_locations, if: -> { current_step == :location }
before_action :set_supplied_by_users, if: -> { current_step == :supplier }
before_action :set_back_link_path
def show
authorize @vaccination_record,
@vaccination_record.new_record? ? :new? : :edit?
render_wizard
end
def update
authorize @vaccination_record,
@vaccination_record.new_record? ? :create? : :update?
@draft_vaccination_record.assign_attributes(update_params)
case current_step
when :date_and_time
handle_date_and_time
when :outcome
handle_outcome
when :location
handle_location
when :batch
handle_batch
when :confirm
handle_confirm
end
if @draft_vaccination_record.editing? && current_step != :confirm
jump_to("confirm")
end
reload_steps
render_wizard @draft_vaccination_record
end
private
def validate_params
if current_step == :date_and_time
validator =
DateParamsValidator.new(
field_name: :performed_at,
object: @draft_vaccination_record,
params: update_params
)
hour = Integer(update_params["performed_at(4i)"], exception: false)
minute = Integer(update_params["performed_at(5i)"], exception: false)
time_valid = hour&.between?(0, 23) && minute&.between?(0, 59)
unless validator.date_params_valid? && time_valid
@draft_vaccination_record.errors.add(:performed_at, :invalid)
render_wizard nil, status: :unprocessable_content
end
end
end
def handle_date_and_time
if @draft_vaccination_record.performed_at.nil?
@draft_vaccination_record.errors.add(:performed_at, :blank)
end
end
def handle_outcome
if !@draft_vaccination_record.administered? &&
@draft_vaccination_record.location_id.present?
# If not administered and location is set, we can skip to confirm.
# Otherwise, we need to get the location information from the user.
jump_to("confirm")
end
end
def handle_batch
if params.dig(:draft_vaccination_record, :todays_batch).present? &&
update_params[:batch_id].in?(
params[:draft_vaccination_record][:todays_batch]
)
self.todays_batch = policy_scope(Batch).find(update_params[:batch_id])
end
end
def handle_location
if @draft_vaccination_record.bulk_upload_user_and_record?
parsed_location_id =
(
if update_params[:location_id] == "unknown"
nil
else
update_params[:location_id]
end
)
@draft_vaccination_record.location_id = parsed_location_id
@draft_vaccination_record.location_name =
(@draft_vaccination_record.location_id.present? ? nil : "Unknown")
end
end
def handle_confirm
return unless @draft_vaccination_record.save
is_new_record = @vaccination_record.new_record?
performed_at_date_changed =
@vaccination_record.performed_at&.to_date !=
@draft_vaccination_record.performed_at.to_date
@draft_vaccination_record.write_to!(@vaccination_record)
should_notify_parents =
@vaccination_record.confirmation_sent? &&
(
@vaccination_record.outcome_changed? ||
@vaccination_record.batch_id_changed? || performed_at_date_changed
)
if is_new_record
@vaccination_record.notify_parents =
VaccinationNotificationCriteria.call(
vaccination_record: @vaccination_record
)
end
@vaccination_record.save!
NextDoseTriageFactory.call(vaccination_record: @vaccination_record)
StatusUpdater.call(patient: @patient)
if should_notify_parents
@vaccination_record.notifier.send_confirmation(sent_by: current_user)
end
# In case the user navigates back to try and edit the newly created
# vaccination record.
@draft_vaccination_record.update!(editing_id: @vaccination_record.id)
flash[
:success
] = "Vaccination outcome recorded for #{@programme.name_in_sentence}"
end
def finish_wizard_path
if @session&.today?
session_patient_programme_path(
@session,
@patient,
@programme,
return_to: "record"
)
else
vaccination_record_path(@vaccination_record)
end
end
def update_params
permitted_attributes = {
batch: %i[batch_id],
confirm: @draft_vaccination_record.editing? ? [] : %i[notes],
date_and_time: %i[performed_at],
delivery: %i[delivery_site delivery_method],
dose: %i[full_dose],
dose_sequence: %i[dose_sequence],
identity: %i[
identity_check_confirmed_by_patient
identity_check_confirmed_by_other_name
identity_check_confirmed_by_other_relationship
],
location: %i[location_id],
notes: %i[notes],
outcome: %i[outcome],
supplier: %i[supplied_by_user_id],
vaccinator: %i[performed_by_given_name performed_by_family_name]
}.fetch(current_step)
params
.fetch(:draft_vaccination_record, {})
.permit(permitted_attributes)
.merge(wizard_step: current_step)
end
def set_draft_vaccination_record
@draft_vaccination_record =
DraftVaccinationRecord.new(request_session: session, current_user:)
end
def set_patient
@patient = @draft_vaccination_record.patient
end
def set_session
@session = @draft_vaccination_record.session
end
def set_programme
@programme = @draft_vaccination_record.programme
end
def set_vaccination_record
@vaccination_record =
@draft_vaccination_record.vaccination_record ||
VaccinationRecord.new(
patient: @patient,
session: @session,
programme: @programme
)
end
def set_steps
self.steps = @draft_vaccination_record.wizard_steps
end
def set_batches
vaccines = vaccine_criteria.apply(@programme.vaccines)
scope = policy_scope(Batch).includes(:vaccine)
@batches =
scope
.where(id: @draft_vaccination_record.batch_id)
.or(scope.not_archived.not_expired.where(vaccine: vaccines))
.order_by_name_and_expiration
end
def set_locations
@locations =
if @draft_vaccination_record.bulk_upload_user_and_record?
Location.school.where(status: "open").order(:name)
else
policy_scope(Location).community_clinic
end
end
def set_supplied_by_users
@supplied_by_users = current_team.users.show_in_suppliers
end
def set_back_link_path
@back_link_path =
if @draft_vaccination_record.editing?
if current_step == :confirm
vaccination_record_path(@vaccination_record)
else
wizard_path("confirm")
end
elsif first_step_of_flow?
session_patient_programme_path(@session, @patient, @programme)
else
previous_wizard_path
end
end
def first_step_of_flow?
current_step.to_s == @draft_vaccination_record.first_active_wizard_step ||
current_step == @draft_vaccination_record.wizard_steps.first
end
def vaccine_criteria
vaccine_method =
Vaccine.delivery_method_to_vaccine_method(
@draft_vaccination_record.delivery_method
)
without_gelatine =
@patient.vaccine_criteria(
programme: @programme,
academic_year: @session.academic_year
).without_gelatine
VaccineCriteria.new(
programme: @programme,
vaccine_methods: [vaccine_method].compact,
without_gelatine:
)
end
end