Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

APPEALS-24998-24999-27763 #19199

Merged
merged 73 commits into from
Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
313b102
APPEALS-24998 added redux props, routers, and history
minhazur9 Aug 9, 2023
dc23803
APPEALS-24999 Merged in frontend changes to CompleteHPRMailTask from …
jefftmarks Aug 9, 2023
7bc6935
APPEALS-24999 Merged in backend changes to HPRMailTask from prototype…
jefftmarks Aug 9, 2023
318b0a0
APPEALS-24998 page now redirects to schedule veterna when selecting t…
minhazur9 Aug 9, 2023
08d66d1
APPEALS-24998 page redirects now only when granted and reschedule imm…
minhazur9 Aug 9, 2023
d89c44c
APPEALS-24997 Changed redirect after submit to case details page
jefftmarks Aug 9, 2023
e26a4ef
APPEALS-24999 Hid parent mail task from case timeline
jefftmarks Aug 9, 2023
23de7e2
APPEALS-24999 Added extra line break in instructions field
jefftmarks Aug 9, 2023
ed95fd7
APPEALS-24999 Formatted markdown for task completion on case timeline
jefftmarks Aug 10, 2023
4933184
APPEALS-24999 Changed margin on hr tag
jefftmarks Aug 10, 2023
f0342f0
APPEALS-24999 Completed markdown styling of case timeline
jefftmarks Aug 10, 2023
a780506
APPEALS-24998 task status updates, new hearing gets created with tasks
minhazur9 Aug 10, 2023
f9b2976
APPEALS-24999 Accounted for HPR mail task when no open hearing
jefftmarks Aug 10, 2023
70ebddc
Merge branch 'feature/APPEALS-21339' into min/APPEALS-24998
minhazur9 Aug 10, 2023
822c688
APPEALS-24998 legacy hearings can now get scheduled with the mail task
minhazur9 Aug 11, 2023
abd7fb5
APPEALS-24999 Made css change to break word for long links in case ti…
jefftmarks Aug 11, 2023
5a06f45
APPEALS-24999 Refactored and renamed methods to dry up HPR mail task …
jefftmarks Aug 11, 2023
83609a6
Merge branch 'feature/APPEALS-21339' of https://github.com/department…
jefftmarks Aug 11, 2023
6d5a697
merged both schedule immediately and schedule later functionality
minhazur9 Aug 11, 2023
8d6cda7
APPEALS-24999 Refactored getPayload
jefftmarks Aug 14, 2023
fe79624
APPEALS-24999 Removed commented out code
jefftmarks Aug 14, 2023
ab7cd7c
APPEALS-24999 Removed taskData
jefftmarks Aug 14, 2023
bf2f6b7
APPEALS-24999 Added denied functionality
jefftmarks Aug 14, 2023
06c3c1e
APPEALS-24999 fixed typo in old spec file
jefftmarks Aug 14, 2023
c9ff95e
APPEALS-24999 Removed unnecessary admin action props
jefftmarks Aug 14, 2023
cc9f9ab
APPEALS-24998-24999 date of ruling now passed in from schedule vetera…
minhazur9 Aug 14, 2023
a3ff34d
Merge branch 'combined-APPEALS-24998-24999' of github.com:department-…
minhazur9 Aug 14, 2023
36c5018
APPEALS-24998-24999 fixed cancel task issues
minhazur9 Aug 14, 2023
8188a0c
APPEALS-24999 refactored HPR mail task
jefftmarks Aug 15, 2023
749e509
APPEALS-24988-24999 working on feature test work and added templates
minhazur9 Aug 15, 2023
01686b3
APPEALS-24999 First pass at feature tests for 24999 and 27763
jefftmarks Aug 15, 2023
7e5b366
Merge remote-tracking branch 'origin/feature/APPEALS-21339' into comb…
ThorntonMatthew Aug 16, 2023
3d551a9
added schedule immediately feature test
minhazur9 Aug 16, 2023
7dac8e8
Merge branch 'combined-APPEALS-24998-24999' of github.com:department-…
minhazur9 Aug 16, 2023
6ae3379
APPEALS-24999 Updated task factory for HPR task to have instructions …
jefftmarks Aug 16, 2023
419c19e
Merge branch 'combined-APPEALS-24998-24999' of https://github.com/dep…
jefftmarks Aug 16, 2023
e5407b6
APPEALS-24998-24999 added fixes for other task actions
minhazur9 Aug 16, 2023
bceec71
APPEALS-24999 Completed tests for 24999 and 27763
jefftmarks Aug 16, 2023
fd66c7f
Merge branch 'combined-APPEALS-24998-24999' of github.com:department-…
minhazur9 Aug 16, 2023
e75aff6
APPEALS-24999 schema comments
jefftmarks Aug 17, 2023
2af13fc
APPEALS-24988-24999 making more feature tests on scheduling imemdiately
minhazur9 Aug 17, 2023
2e9797a
APPEALS-24999 Updated variable in test
jefftmarks Aug 18, 2023
0fd46fb
APPEALS-24998-24999 added AMA appeals feature tests for scheduling im…
minhazur9 Aug 18, 2023
9f52586
APPEALS-24998-24999 finished writing feature tests
minhazur9 Aug 18, 2023
4ea9862
APPEALS-24999 CodeClimate changes
jefftmarks Aug 18, 2023
097c002
APPEALS-24999 Fixed typo
jefftmarks Aug 20, 2023
6051552
APPEALS-24998-2499 refactored tests
minhazur9 Aug 21, 2023
d47f6de
removed commented out code
minhazur9 Aug 21, 2023
48788cb
added scope, documentation, and refactor
minhazur9 Aug 22, 2023
3bbfa83
Merge branch 'feature/APPEALS-21339' into combined-APPEALS-24998-24999
minhazur9 Aug 22, 2023
aaa08fc
added importing alias for common directory
minhazur9 Aug 23, 2023
ce793a9
Merge branch 'combined-APPEALS-24998-24999' of github.com:department-…
minhazur9 Aug 23, 2023
a7cf886
added alias to jest config
minhazur9 Aug 23, 2023
7d844ae
Merge branch 'feature/APPEALS-21339' into combined-APPEALS-24998-24999
minhazur9 Aug 25, 2023
6c04997
Merge branch 'feature/APPEALS-21339' into combined-APPEALS-24998-24999
minhazur9 Aug 25, 2023
bd163a7
APPEALS-24998-24999 fixed task queue test
minhazur9 Aug 30, 2023
1ba859b
Merge branch 'combined-APPEALS-24998-24999' of github.com:department-…
minhazur9 Aug 30, 2023
c210a4b
APPEALS-24999 change test config and refactored task scope
jefftmarks Aug 30, 2023
171df8e
APPEALS-24999 Implement custom styling for HPR mark as complete radio…
jefftmarks Aug 31, 2023
39f7ab4
APPEALS-24999 remove userCanScheduleVirtualHearing prop and check
jefftmarks Aug 31, 2023
58d83f2
APPEALS-24999 refactored 'where' to 'of_type' for consistency
jefftmarks Aug 31, 2023
2e53b30
APPEALS-24998-24999 added postponement notifications
minhazur9 Aug 31, 2023
76719d6
Merge branch 'combined-APPEALS-24998-24999' of github.com:department-…
minhazur9 Aug 31, 2023
ce060f6
APPEALS-24999 Implement send notification on hearing reschedule
jefftmarks Sep 1, 2023
7ff91c6
APPEALS-24999 Added optionsStyling proptype
jefftmarks Sep 5, 2023
d1a8449
APPEALS-24999 work on test files
jefftmarks Sep 5, 2023
895a86b
APPEALS-24998-24999 notification for ama tests
minhazur9 Sep 6, 2023
d3dcd6c
APPEALS-24998-24999 finished legacy appeal tests
minhazur9 Sep 6, 2023
7933e9e
APPEALS-24998-24999 fixed minor issues in feature test
minhazur9 Sep 6, 2023
6b36dbd
Merge branch 'feature/APPEALS-21339' into combined-APPEALS-24998-24999
minhazur9 Sep 6, 2023
54579b7
APPEALS-24998-24999 fixed linting
minhazur9 Sep 6, 2023
3888fa5
Merge branch 'combined-APPEALS-24998-24999' of github.com:department-…
minhazur9 Sep 6, 2023
5ea81ee
APPEALS-24998-24999 refactor of rspec tests
minhazur9 Sep 6, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
# - A child task of the same name is created and assigned to the HearingAdmin organization
##
class HearingPostponementRequestMailTask < HearingRequestMailTask
prepend HearingPostponed
include RunAsyncable
class << self
def label
COPY::HEARING_POSTPONEMENT_REQUEST_MAIL_TASK_LABEL
Expand All @@ -27,10 +29,13 @@ def allow_creation?(*)
Constants.TASK_ACTIONS.CANCEL_TASK.to_h
].freeze

# Purpose: Determines the actions a user can take depending on their permissions and the state of the appeal
# Params: user - The current user object
# Return: The task actions array of objects
def available_actions(user)
return [] unless user.in_hearing_admin_team?

if active_schedule_hearing_task? || open_assign_hearing_disposition_task?
if active_schedule_hearing_task || hearing_scheduled_and_awaiting_disposition?
TASK_ACTIONS
else
[
Expand All @@ -40,20 +45,243 @@ def available_actions(user)
end
end

# Purpose: Updates the current state of the appeal
# Params: params - The update params object
# user - The current user object
# Return: The current hpr task and newly created tasks
def update_from_params(params, user)
payload_values = params.delete(:business_payloads)&.dig(:values) || params

# If the request is to mark HPR mail task complete
if payload_values[:granted]&.to_s.present?
# If request to postpone hearing is granted
if payload_values[:granted]
created_tasks = update_hearing_and_create_tasks(payload_values[:after_disposition_update])
end
update_self_and_parent_mail_task(user: user, payload_values: payload_values)

[self] + (created_tasks || [])
else
super(params, user)
end
end

# Purpose: Only show HPR mail task assigned to "HearingAdmin" on the Case Timeline
# Params: None
# Return: boolean if task is assigned to MailTeam
def hide_from_case_timeline
assigned_to.is_a?(MailTeam)
end

# Purpose: Determines if there is an open hearing
# Params: None
# Return: The hearing if one exists
def open_hearing
@open_hearing ||= open_assign_hearing_disposition_task&.hearing
end

# Purpose: Gives the latest hearing task
# Params: None
# Return: The hearing task
def hearing_task
@hearing_task ||= open_hearing&.hearing_task || active_schedule_hearing_task.parent
end

private

def active_schedule_hearing_task?
appeal.tasks.where(type: ScheduleHearingTask.name).active.any?
# Purpose: Gives the latest active hearing task
# Params: None
# Return: The latest active hearing task
def active_schedule_hearing_task
minhazur9 marked this conversation as resolved.
Show resolved Hide resolved
appeal.tasks.of_type(ScheduleHearingTask.name).active.first
end

# ChangeHearingDispositionTask is a subclass of AssignHearingDispositionTask
ASSIGN_HEARING_DISPOSITION_TASKS = [
AssignHearingDispositionTask.name,
ChangeHearingDispositionTask.name
].freeze

# Purpose: Gives the latest active assign hearing disposition task
# Params: None
# Return: The latest active assign hearing disposition task
def open_assign_hearing_disposition_task
@open_assign_hearing_disposition_task ||= appeal.tasks.of_type(ASSIGN_HEARING_DISPOSITION_TASKS).open&.first
end

# Purpose: Associated appeal has an upcoming hearing with an open status
# Params: None
# Return: Returns a boolean if the appeal has an upcoming hearing
def hearing_scheduled_and_awaiting_disposition?
return false unless open_hearing

# Ensure associated hearing is not scheduled for the past
!open_hearing.scheduled_for_past?
end

# Purpose: Sets the previous hearing's disposition to postponed
# Params: None
# Return: Returns a boolean for if the hearing has been updated
def postpone_previous_hearing
update_hearing(disposition: Constants.HEARING_DISPOSITION_TYPES.postponed)
end

# Purpose: Wrapper for updating hearing and creating new hearing tasks
# Params: Params object for additional tasks or updates after updating the hearing
# Return: Returns the newly created tasks
def update_hearing_and_create_tasks(after_disposition_update)
multi_transaction do
# If hearing exists, postpone previous hearing and handle conference links

if open_hearing
postpone_previous_hearing
clean_up_virtual_hearing
end
# Schedule hearing or create new ScheduleHearingTask depending on after disposition action
reschedule_or_schedule_later(after_disposition_update)
end
end

# Purpose: Sets the previous hearing's disposition
# Params: None
# Return: Returns a boolean for if the hearing has been updated
def update_hearing(hearing_hash)
if open_hearing.is_a?(LegacyHearing)
open_hearing.update_caseflow_and_vacols(hearing_hash)
else
open_hearing.update(hearing_hash)
end
end

# Purpose: Deletes the old scheduled virtual hearings
# Params: None
# Return: Returns nil
def clean_up_virtual_hearing
if open_hearing.virtual?
perform_later_or_now(VirtualHearings::DeleteConferencesJob)
jefftmarks marked this conversation as resolved.
Show resolved Hide resolved
end
end

# Purpose: Either reschedule or send to schedule veteran list
# Params: None
# Return: Returns newly created tasks
def reschedule_or_schedule_later(after_disposition_update)
case after_disposition_update[:action]
when "reschedule"
new_hearing_attrs = after_disposition_update[:new_hearing_attrs]
reschedule(
hearing_day_id: new_hearing_attrs[:hearing_day_id],
scheduled_time_string: new_hearing_attrs[:scheduled_time_string],
hearing_location: new_hearing_attrs[:hearing_location],
virtual_hearing_attributes: new_hearing_attrs[:virtual_hearing_attributes],
notes: new_hearing_attrs[:notes],
email_recipients_attributes: new_hearing_attrs[:email_recipients]
)
when "schedule_later"
schedule_later
else
fail ArgumentError, "unknown disposition action"
end
end

def open_assign_hearing_disposition_task?
# ChangeHearingDispositionTask is a subclass of AssignHearingDispositionTask
disposition_task_names = [AssignHearingDispositionTask.name, ChangeHearingDispositionTask.name]
open_task = appeal.tasks.where(type: disposition_task_names).open.first
# rubocop:disable Metrics/ParameterLists
# Purpose: Reschedules the hearings
# Params: hearing_day_id - The ID of the hearing day that its going to be scheduled
# scheduled_time_string - The string for the scheduled time
# hearing_location - The hearing location string
# virtual_hearing_attributes - object for virtual hearing attributes
# notes - additional notes for the hearing string
# email_recipients_attributes - the object for the email recipients
# Return: Returns new hearing and assign disposition task
def reschedule(
hearing_day_id:,
scheduled_time_string:,
hearing_location: nil,
virtual_hearing_attributes: nil,
notes: nil,
email_recipients_attributes: nil
)
multi_transaction do
new_hearing_task = hearing_task.cancel_and_recreate

new_hearing = HearingRepository.slot_new_hearing(hearing_day_id: hearing_day_id,
appeal: appeal,
hearing_location_attrs: hearing_location&.to_hash,
scheduled_time_string: scheduled_time_string,
notes: notes)
if virtual_hearing_attributes.present?
@alerts = VirtualHearings::ConvertToVirtualHearingService
.convert_hearing_to_virtual(new_hearing, virtual_hearing_attributes)
elsif email_recipients_attributes.present?
create_or_update_email_recipients(new_hearing, email_recipients_attributes)
end

disposition_task = AssignHearingDispositionTask
.create_assign_hearing_disposition_task!(appeal, new_hearing_task, new_hearing)

AppellantNotification.notify_appellant(appeal, "Hearing scheduled")

[new_hearing_task, disposition_task]
end
end
# rubocop:enable Metrics/ParameterLists

# Purpose: Sends the appeal back to the scheduling list
# Params: None
# Return: Returns the new hearing task and schedule task
def schedule_later
new_hearing_task = hearing_task.cancel_and_recreate
schedule_task = ScheduleHearingTask.create!(appeal: appeal, parent: new_hearing_task)

[new_hearing_task, schedule_task].compact
end

# Purpose: Completes the Mail task assigned to the MailTeam and the one for HearingAdmin
# Params: user - The current user object
# payload_values - The attributes needed for the update
# Return: Boolean for if the tasks have been updated
def update_self_and_parent_mail_task(user:, payload_values:)
# Append instructions/context provided by HearingAdmin to original details from MailTeam
updated_instructions = format_instructions_on_completion(
admin_context: payload_values[:instructions],
ruling: payload_values[:granted] ? "GRANTED" : "DENIED",
date_of_ruling: payload_values[:date_of_ruling]
)

# Complete HPR mail task assigned to HearingAdmin
update!(
completed_by: user,
status: Constants.TASK_STATUSES.completed,
instructions: updated_instructions
)
# Complete parent HPR mail task assigned to MailTeam
update_parent_status
end

# Purpose: Appends instructions on to the instructions provided in the mail task
# Params: admin_context - String for instructions
# ruling - string for granted or denied
# date_of_ruling - string for the date of ruling
# Return: instructions string
def format_instructions_on_completion(admin_context:, ruling:, date_of_ruling:)
formatted_date = date_of_ruling.to_date&.strftime("%m/%d/%Y")

markdown_to_append = <<~EOS

***

###### Marked as complete:

**DECISION**
Motion to postpone #{ruling}

**DATE OF RULING**
#{formatted_date}

return false unless open_task&.hearing
**DETAILS**
#{admin_context}
EOS

# Ensure hearing associated with AssignHearingDispositionTask is not scheduled in the past
!open_task.hearing.scheduled_for_past?
[instructions[0] + markdown_to_append]
end
end
11 changes: 7 additions & 4 deletions app/models/tasks/hearing_mail_tasks/hearing_request_mail_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,17 @@
# HearingRequestMailTask is itself not an assignable task type
##
class HearingRequestMailTask < MailTask
include RunAsyncable
validates :parent, presence: true, on: :create

before_validation :verify_request_type_designated

class HearingAssociationMissing < StandardError
def initialize
super(format(COPY::HEARING_TASK_ASSOCIATION_MISSING_MESSAGE, hearing_task_id))
end
end

class << self
def allow_creation?(*)
false
Expand All @@ -26,10 +33,6 @@ def available_actions(_user)
[]
end

def update_from_params(params, current_user)
super(params, current_user)
end

private

# Ensure create is called on a descendant mail task and not directly on the HearingRequestMailTask class
Expand Down
8 changes: 5 additions & 3 deletions client/app/components/RadioField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export const RadioField = (props) => {
strongLabel,
hideLabel,
styling,
vertical
vertical,
optionsStyling
} = props;

const isVertical = useMemo(() => props.vertical || props.options.length > 2, [
Expand Down Expand Up @@ -99,7 +100,7 @@ export const RadioField = (props) => {
<span className="usa-input-error-message" tabIndex={0}>{errorMessage}</span>
)}

<div className="cf-form-radio-options">
<div className="cf-form-radio-options" style={optionsStyling}>
{options.map((option, i) => {
const optionDisabled = isDisabled(option);

Expand Down Expand Up @@ -213,7 +214,8 @@ RadioField.propTypes = {
errorMessage: PropTypes.string,
strongLabel: PropTypes.bool,
hideLabel: PropTypes.bool,
styling: PropTypes.object
styling: PropTypes.object,
optionsStyling: PropTypes.object
};

export default RadioField;
5 changes: 5 additions & 0 deletions client/app/hearings/components/ScheduleVeteran.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,11 @@ export const ScheduleVeteran = ({
},
...(prevHearingDisposition === HEARING_DISPOSITION_TYPES.scheduled_in_error && {
hearing_notes: scheduledHearing?.notes
}),
...('rulingDate' in scheduledHearing && {
date_of_ruling: scheduledHearing?.rulingDate.value,
instructions: scheduledHearing?.instructions,
granted: scheduledHearing?.granted
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion client/app/queue/CreateMailTaskDialog.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export class CreateMailTaskDialog extends React.Component {
prependUrlToInstructions = () => {

if (this.isHearingRequestMailTask()) {
return (`**LINK TO DOCUMENT:** \n ${this.state.eFolderUrl} \n **DETAILS:** \n ${this.state.instructions}`);
return (`**LINK TO DOCUMENT:** \n ${this.state.eFolderUrl} \n\n **DETAILS:** \n ${this.state.instructions}`);
}

return this.state.instructions;
Expand Down
Loading
Loading