-
Notifications
You must be signed in to change notification settings - Fork 19
/
appellant_notification.rb
234 lines (218 loc) · 9.13 KB
/
appellant_notification.rb
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
# frozen_string_literal: true
# Module containing Aspect Overrides to Classes used to Track Statuses for Appellant Notification
# rubocop:disable Metrics/ModuleLength
module AppellantNotification
extend ActiveSupport::Concern
class NoParticipantIdError < StandardError
def initialize(appeal_id, message = "There is no participant_id")
super(message + " for appeal with id #{appeal_id}")
end
def status
"No participant_id"
end
end
class NoClaimantError < StandardError
def initialize(appeal_id, message = "There is no claimant")
super(message + " for appeal with id #{appeal_id}")
end
def status
"No claimant"
end
end
class NoAppealError < StandardError; end
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
def self.handle_errors(appeal)
fail NoAppealError if appeal.nil?
message_attributes = {}
message_attributes[:appeal_type] = appeal.class.to_s
message_attributes[:appeal_id] = (appeal.class.to_s == "Appeal") ? appeal.uuid : appeal.vacols_id
message_attributes[:participant_id] = appeal.claimant_participant_id
claimant = get_claimant(appeal)
begin
if claimant.nil?
fail NoClaimantError, message_attributes[:appeal_id]
elsif message_attributes[:participant_id] == "" || message_attributes[:participant_id].nil?
fail NoParticipantIdError, message_attributes[:appeal_id]
elsif appeal.veteran_appellant_deceased?
message_attributes[:status] = "Failure Due to Deceased"
else
message_attributes[:status] = "Success"
end
rescue StandardError => error
Rails.logger.error("#{error.message}\n#{error.backtrace.join("\n")}")
message_attributes[:status] = error.status
end
message_attributes
end
# Public: Updates/creates appeal state based on event type
#
# appeal - appeal that was found in appeal_mapper
# event - The module that is being triggered to send a notification
#
# Examples
#
# AppellantNotification.update_appeal_state(appeal, "hearing_postponed")
# # => A new appeal state is created if it doesn't exist
# or the existing appeal state is updated, then appeal_state.hearing_postponed becomes true
# rubocop:disable Metrics/AbcSize
def self.update_appeal_state(appeal, event)
appeal_type = appeal.class.to_s
appeal_state = AppealState.find_by(appeal_id: appeal.id, appeal_type: appeal_type) ||
AppealState.create!(appeal_id: appeal.id, appeal_type: appeal_type)
case event
when "decision_mailed"
appeal_state.update!(
decision_mailed: true,
appeal_docketed: false,
hearing_postponed: false,
hearing_withdrawn: false,
hearing_scheduled: false,
vso_ihp_pending: false,
vso_ihp_complete: false,
privacy_act_pending: false,
privacy_act_complete: false
)
when "appeal_docketed"
appeal_state.update!(appeal_docketed: true)
when "appeal_cancelled"
appeal_state.update!(
decision_mailed: false,
appeal_docketed: false,
hearing_postponed: false,
hearing_withdrawn: false,
hearing_scheduled: false,
vso_ihp_pending: false,
vso_ihp_complete: false,
privacy_act_pending: false,
privacy_act_complete: false,
scheduled_in_error: false,
appeal_cancelled: true
)
when "hearing_postponed"
appeal_state.update!(hearing_postponed: true, hearing_scheduled: false)
when "hearing_withdrawn"
appeal_state.update!(hearing_withdrawn: true, hearing_postponed: false, hearing_scheduled: false)
when "hearing_scheduled"
appeal_state.update!(hearing_scheduled: true, hearing_postponed: false, scheduled_in_error: false)
when "scheduled_in_error"
appeal_state.update!(scheduled_in_error: true, hearing_scheduled: false)
when "vso_ihp_pending"
appeal_state.update!(vso_ihp_pending: true, vso_ihp_complete: false)
when "vso_ihp_cancelled"
appeal_state.update!(vso_ihp_pending: false, vso_ihp_complete: false)
when "vso_ihp_complete"
# Only updates appeal state if ALL ihp tasks are completed
if appeal.tasks.open.where(type: IhpColocatedTask.name).empty? &&
appeal.tasks.open.where(type: InformalHearingPresentationTask.name).empty?
appeal_state.update!(vso_ihp_complete: true, vso_ihp_pending: false)
end
when "privacy_act_pending"
appeal_state.update!(privacy_act_pending: true, privacy_act_complete: false)
when "privacy_act_complete"
# Only updates appeal state if ALL privacy act tasks are completed
open_tasks = appeal.tasks.open
if open_tasks.where(type: FoiaColocatedTask.name).empty? &&
open_tasks.where(type: PrivacyActTask.name).empty? &&
open_tasks.where(type: HearingAdminActionFoiaPrivacyRequestTask.name).empty? &&
open_tasks.where(type: FoiaRequestMailTask.name).empty? &&
open_tasks.where(type: PrivacyActRequestMailTask.name).empty?
appeal_state.update!(privacy_act_complete: true, privacy_act_pending: false)
end
when "privacy_act_cancelled"
# Only updates appeal state if ALL privacy act tasks are completed
open_tasks = appeal.tasks.open
if open_tasks.where(type: FoiaColocatedTask.name).empty? && open_tasks.where(type: PrivacyActTask.name).empty? &&
open_tasks.where(type: HearingAdminActionFoiaPrivacyRequestTask.name).empty? &&
open_tasks.where(type: FoiaRequestMailTask.name).empty? &&
open_tasks.where(type: PrivacyActRequestMailTask.name).empty?
appeal_state.update!(privacy_act_pending: false)
end
end
end
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity, Metrics/AbcSize
# Public: Finds the appeal based on the id and type, then calls update_appeal_state to create/update appeal state
#
# appeal_id - id of appeal
# appeal_type - string of appeal object's class (e.g. "LegacyAppeal")
# event - The module that is being triggered to send a notification
#
# Examples
#
# AppellantNotification.appeal_mapper(1, "Appeal", "hearing_postponed")
# # => A new appeal state is created if it doesn't exist
# or the existing appeal state is updated, then appeal_state.hearing_postponed becomes true
def self.appeal_mapper(appeal_id, appeal_type, event)
if appeal_type == "Appeal"
appeal = Appeal.find_by(id: appeal_id)
AppellantNotification.update_appeal_state(appeal, event)
elsif appeal_type == "LegacyAppeal"
appeal = LegacyAppeal.find_by(id: appeal_id)
AppellantNotification.update_appeal_state(appeal, event)
else
Rails.logger.error("Appeal type not supported for " + event)
end
end
# Purpose: Method to check appeal state for statuses and send out a notification based on
# which statuses are turned on in the appeal state
#
# Params: appeal object (AMA of Legacy)
# temaplate_name (ex. quarterly_notification, appeal_docketed, etc.)
# appeal_status (only used for quarterly notifications)
#
# Response: Create notification and return it to SendNotificationJob
# rubocop:disable Metrics/CyclomaticComplexity
def self.notify_appellant(
appeal,
template_name,
appeal_status = nil
)
msg_bdy = create_payload(appeal, template_name, appeal_status)
appeal_docketed_event_enabled = FeatureToggle.enabled?(:appeal_docketed_event)
return nil if template_name == "Appeal docketed" &&
!appeal_docketed_event_enabled &&
msg_bdy.appeal_type == "LegacyAppeal"
if template_name == "Appeal docketed" && appeal_docketed_event_enabled && msg_bdy.appeal_type == "LegacyAppeal"
Notification.create!(
appeals_id: msg_bdy.appeal_id,
appeals_type: msg_bdy.appeal_type,
event_type: template_name,
notification_type: notification_type,
participant_id: msg_bdy.participant_id,
event_date: Time.zone.today
)
end
SendNotificationJob.perform_later(msg_bdy.to_json)
end
# rubocop:enable Metrics/CyclomaticComplexity
def self.create_payload(appeal, template_name, appeal_status = nil)
message_attributes = AppellantNotification.handle_errors(appeal)
VANotifySendMessageTemplate.new(message_attributes, template_name, appeal_status)
end
def self.notification_type
notification_type =
if FeatureToggle.enabled?(:va_notify_email) && FeatureToggle.enabled?(:va_notify_sms)
"Email and SMS"
elsif FeatureToggle.enabled?(:va_notify_email)
"Email"
elsif FeatureToggle.enabled?(:va_notify_sms)
"SMS"
else
"None"
end
notification_type
end
def self.get_claimant(appeal)
appeal_type = appeal.class.to_s
participant_id = appeal.claimant_participant_id
claimant =
if appeal_type == "Appeal"
appeal.claimant
elsif appeal_type == "LegacyAppeal"
veteran = Veteran.find_by(participant_id: participant_id)
person = Person.find_by(participant_id: participant_id)
appeal.appellant_is_not_veteran ? person : veteran
end
claimant
end
end
# rubocop:enable Metrics/ModuleLength