From 3cb011e11201b48ab5e8c3c912b6313cd72858de Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Tue, 2 Jun 2020 16:36:18 -0400 Subject: [PATCH 1/6] Remove overtime status on judge or attorney reassignment --- app/controllers/legacy_tasks_controller.rb | 3 + app/models/task.rb | 6 ++ app/models/tasks/attorney_task.rb | 4 ++ app/models/tasks/judge_task.rb | 4 ++ .../legacy_tasks_controller_spec.rb | 25 ++++++++ spec/models/task_spec.rb | 58 +++++++++++++++++++ 6 files changed, 100 insertions(+) diff --git a/app/controllers/legacy_tasks_controller.rb b/app/controllers/legacy_tasks_controller.rb index 2f68f438334..96e91c7d542 100644 --- a/app/controllers/legacy_tasks_controller.rb +++ b/app/controllers/legacy_tasks_controller.rb @@ -96,6 +96,9 @@ def assign_to_judge # update the location to the assigned judge. QueueRepository.update_location_to_judge(appeal.vacols_id, assigned_to) + # Remove overtime status of an appeal when reassigning to a judge + appeal.overtime = false if appeal.overtime? + render json: { task: json_task(AttorneyLegacyTask.from_vacols( VACOLS::CaseAssignment.latest_task_for_appeal(appeal.vacols_id), diff --git a/app/models/task.rb b/app/models/task.rb index b137d902b01..eba4790cda3 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -517,6 +517,8 @@ def reassign(reassign_params, current_user) update_with_instructions(status: Constants.TASK_STATUSES.cancelled, instructions: reassign_params[:instructions]) + appeal.overtime = false if appeal.overtime? && reassign_clears_overtime? + [sibling, self, sibling.children].flatten end @@ -593,6 +595,10 @@ def cancelled_by User.find_by_id(record.whodunnit) end + def reassign_clears_overtime? + false + end + private def create_and_auto_assign_child_task(options = {}) diff --git a/app/models/tasks/attorney_task.rb b/app/models/tasks/attorney_task.rb index 9e5c44cfa93..fb371b371dc 100644 --- a/app/models/tasks/attorney_task.rb +++ b/app/models/tasks/attorney_task.rb @@ -48,6 +48,10 @@ def stays_with_reassigned_parent? super || completed? end + def reassign_clears_overtime? + true + end + def send_back_to_judge_assign! transaction do cancelled! diff --git a/app/models/tasks/judge_task.rb b/app/models/tasks/judge_task.rb index 455ec14c704..875138f0b67 100644 --- a/app/models/tasks/judge_task.rb +++ b/app/models/tasks/judge_task.rb @@ -41,4 +41,8 @@ def timeline_title def previous_task children_attorney_tasks.order(:assigned_at).last end + + def reassign_clears_overtime? + true + end end diff --git a/spec/controllers/legacy_tasks_controller_spec.rb b/spec/controllers/legacy_tasks_controller_spec.rb index 13e7e0182c6..e382ffcf5b3 100644 --- a/spec/controllers/legacy_tasks_controller_spec.rb +++ b/spec/controllers/legacy_tasks_controller_spec.rb @@ -448,5 +448,30 @@ end it_behaves_like "judge reassigns case" end + + context "When the appeal has not been marked for overtime" do + before { FeatureToggle.enable!(:overtime_revamp) } + after { FeatureToggle.disable!(:overtime_revamp) } + + it "does not create a new work mode for the appeal" do + expect(appeal.work_mode.nil?).to be true + patch :assign_to_judge, params: { tasks: params } + expect(appeal.work_mode.nil?).to be true + end + end + + context "when the appeal has been marked for overtime" do + before do + FeatureToggle.enable!(:overtime_revamp) + appeal.overtime = true + end + after { FeatureToggle.disable!(:overtime_revamp) } + + it "removes the overtime status of the appeal" do + expect(appeal.overtime?).to be true + patch :assign_to_judge, params: { tasks: params } + expect(appeal.reload.overtime?).to be false + end + end end end diff --git a/spec/models/task_spec.rb b/spec/models/task_spec.rb index c35577e418a..4737df2ed14 100644 --- a/spec/models/task_spec.rb +++ b/spec/models/task_spec.rb @@ -897,6 +897,64 @@ end end end + + context "When the appeal has not been marked for overtime" do + let!(:appeal) { create(:appeal) } + let(:task) { create(:ama_judge_assign_task, appeal: appeal) } + + before { FeatureToggle.enable!(:overtime_revamp) } + after { FeatureToggle.disable!(:overtime_revamp) } + + it "does not create a new work mode for the appeal" do + expect(appeal.work_mode.nil?).to be true + subject + expect(appeal.work_mode.nil?).to be true + end + end + + context "When the appeal has been marked for overtime" do + shared_examples "clears overtime" do + it "sets overtime to false" do + expect(appeal.overtime?).to be true + subject + expect(appeal.overtime?).to be false + end + end + + let!(:appeal) { create(:appeal) } + let(:task) { create(:ama_task, appeal: appeal.reload) } + + before do + appeal.overtime = true + FeatureToggle.enable!(:overtime_revamp) + end + after { FeatureToggle.disable!(:overtime_revamp) } + + context "when the task type is not a judge or attorney task" do + it "does not clear the overtime status" do + expect(appeal.overtime?).to be true + subject + expect(appeal.overtime?).to be true + end + end + + context "when the task is a judge task" do + let(:task) { create(:ama_judge_assign_task, appeal: appeal) } + + it_behaves_like "clears overtime" + end + + context "when the task is an attorney task" do + let(:judge) { create(:user, :judge) } + let(:attorney) { create(:user, :attorney) } + let(:new_assignee) { create(:user, :attorney) } + let(:task) { create(:ama_attorney_rewrite_task, assigned_to: attorney, assigned_by: judge, appeal: appeal) } + + subject { task.reassign(params, judge) } + + it_behaves_like "clears overtime" + end + end end describe ".verify_org_task_unique" do From f0d51c934834a7bee0c0c40ccc17c115240ff45c Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Wed, 3 Jun 2020 14:05:05 -0400 Subject: [PATCH 2/6] Wip --- client/app/queue/AssignToView.jsx | 21 ++++++++++++++++----- client/app/queue/QueueActions.js | 13 ++++++++++++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/client/app/queue/AssignToView.jsx b/client/app/queue/AssignToView.jsx index ca9a09f70e2..7f2408f9f0b 100644 --- a/client/app/queue/AssignToView.jsx +++ b/client/app/queue/AssignToView.jsx @@ -9,7 +9,7 @@ import COPY from '../../COPY'; import { taskById, appealWithDetailSelector } from './selectors'; -import { onReceiveAmaTasks, legacyReassignToJudge } from './QueueActions'; +import { onReceiveAmaTasks, legacyReassignToJudge, setOvertime } from './QueueActions'; import SearchableDropdown from '../components/SearchableDropdown'; import TextareaField from '../components/TextareaField'; @@ -102,7 +102,15 @@ class AssignToView extends React.Component { return this.props. requestSave('/tasks', payload, isPulacCerullo ? pulacCerulloSuccessMessage : assignTaskSuccessMessage). - then((resp) => this.props.onReceiveAmaTasks(resp.body.tasks.data)). + then((resp) => { + this.props.onReceiveAmaTasks(resp.body.tasks.data); + if (taskType === 'JudgeAssignTask') { + this.props.setOvertime({ + appealId: appeal.externalId, + overtime: false + }); + } + }). catch(() => { // handle the error from the frontend }); @@ -241,7 +249,8 @@ class AssignToView extends React.Component { AssignToView.propTypes = { appeal: PropTypes.shape({ - externalId: PropTypes.string + externalId: PropTypes.string, + id: PropTypes.string }), assigneeAlreadySelected: PropTypes.bool, highlightFormItems: PropTypes.bool, @@ -255,7 +264,8 @@ AssignToView.propTypes = { instructions: PropTypes.string, taskId: PropTypes.string, availableActions: PropTypes.arrayOf(PropTypes.object) - }) + }), + setOvertime: PropTypes.func }; const mapStateToProps = (state, ownProps) => { @@ -274,7 +284,8 @@ const mapDispatchToProps = (dispatch) => requestPatch, requestSave, onReceiveAmaTasks, - legacyReassignToJudge + legacyReassignToJudge, + setOvertime }, dispatch ); diff --git a/client/app/queue/QueueActions.js b/client/app/queue/QueueActions.js index c4bc3746936..eab14ba3ded 100644 --- a/client/app/queue/QueueActions.js +++ b/client/app/queue/QueueActions.js @@ -220,7 +220,7 @@ export const setOvertime = (appealId, overtime) => ({ appealId, overtime } -}) +}); export const deleteTask = (taskId) => ({ type: ACTIONS.DELETE_TASK, @@ -534,6 +534,12 @@ export const reassignTasksToUser = ({ dispatch(decrementTaskCountForAttorney({ id: previousAssigneeId })); + + debugger; + dispatch(setOvertime({ + appealId: oldTask.externalAppealId, + overtime: false + })); }); })); @@ -557,6 +563,11 @@ export const legacyReassignToJudge = ({ dispatch(onReceiveTasks(_.pick(allTasks, ['tasks', 'amaTasks']))); dispatch(showSuccessMessage(successMessage)); + + dispatch(setOvertime({ + appealId: oldTask.externalAppealId, + overtime: false + })); }); })); From 970be152dbecbdf7c97028135b43753e5bcf7899 Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Wed, 3 Jun 2020 15:07:50 -0400 Subject: [PATCH 3/6] Properly set overtime to false when reassigning --- client/app/queue/AssignToView.jsx | 9 +++------ client/app/queue/QueueActions.js | 11 ++--------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/client/app/queue/AssignToView.jsx b/client/app/queue/AssignToView.jsx index 7f2408f9f0b..1664f0cac22 100644 --- a/client/app/queue/AssignToView.jsx +++ b/client/app/queue/AssignToView.jsx @@ -104,12 +104,6 @@ class AssignToView extends React.Component { requestSave('/tasks', payload, isPulacCerullo ? pulacCerulloSuccessMessage : assignTaskSuccessMessage). then((resp) => { this.props.onReceiveAmaTasks(resp.body.tasks.data); - if (taskType === 'JudgeAssignTask') { - this.props.setOvertime({ - appealId: appeal.externalId, - overtime: false - }); - } }). catch(() => { // handle the error from the frontend @@ -153,6 +147,9 @@ class AssignToView extends React.Component { return this.props.requestPatch(`/tasks/${task.taskId}`, payload, successMsg).then((resp) => { this.props.onReceiveAmaTasks(resp.body.tasks.data); + if (task.type === 'JudgeAssignTask') { + this.props.setOvertime(task.externalAppealId, false); + } }); }; diff --git a/client/app/queue/QueueActions.js b/client/app/queue/QueueActions.js index eab14ba3ded..227c198486b 100644 --- a/client/app/queue/QueueActions.js +++ b/client/app/queue/QueueActions.js @@ -535,11 +535,7 @@ export const reassignTasksToUser = ({ id: previousAssigneeId })); - debugger; - dispatch(setOvertime({ - appealId: oldTask.externalAppealId, - overtime: false - })); + dispatch(setOvertime(oldTask.externalAppealId, false)); }); })); @@ -564,10 +560,7 @@ export const legacyReassignToJudge = ({ dispatch(showSuccessMessage(successMessage)); - dispatch(setOvertime({ - appealId: oldTask.externalAppealId, - overtime: false - })); + dispatch(setOvertime(oldTask.externalAppealId, false)); }); })); From 9d63a8ac0b32f2c25ec2af99499e007ca7e9859c Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Wed, 3 Jun 2020 15:08:30 -0400 Subject: [PATCH 4/6] Undo changes --- client/app/queue/AssignToView.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/app/queue/AssignToView.jsx b/client/app/queue/AssignToView.jsx index 1664f0cac22..8524bc17871 100644 --- a/client/app/queue/AssignToView.jsx +++ b/client/app/queue/AssignToView.jsx @@ -102,9 +102,7 @@ class AssignToView extends React.Component { return this.props. requestSave('/tasks', payload, isPulacCerullo ? pulacCerulloSuccessMessage : assignTaskSuccessMessage). - then((resp) => { - this.props.onReceiveAmaTasks(resp.body.tasks.data); - }). + then((resp) => this.props.onReceiveAmaTasks(resp.body.tasks.data)). catch(() => { // handle the error from the frontend }); From b0172b44655ae4f8b6d507f4ff49c1d4dbd50ff4 Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Thu, 4 Jun 2020 09:47:15 -0400 Subject: [PATCH 5/6] lint --- client/app/queue/AssignToView.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/app/queue/AssignToView.jsx b/client/app/queue/AssignToView.jsx index 8524bc17871..fb0a8e16696 100644 --- a/client/app/queue/AssignToView.jsx +++ b/client/app/queue/AssignToView.jsx @@ -258,7 +258,9 @@ AssignToView.propTypes = { task: PropTypes.shape({ instructions: PropTypes.string, taskId: PropTypes.string, - availableActions: PropTypes.arrayOf(PropTypes.object) + availableActions: PropTypes.arrayOf(PropTypes.object), + externalAppealId: PropTypes.string, + type: PropTypes.string }), setOvertime: PropTypes.func }; From 1c612cebbe9f5607f8259ec1dc97e7486b1c11c6 Mon Sep 17 00:00:00 2001 From: hschallhorn Date: Tue, 9 Jun 2020 10:29:25 -0400 Subject: [PATCH 6/6] Clear suvccess messages --- client/app/queue/AssignToView.jsx | 10 +++++++--- client/app/queue/components/AssignToAttorneyWidget.jsx | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/client/app/queue/AssignToView.jsx b/client/app/queue/AssignToView.jsx index fb0a8e16696..4452f77e334 100644 --- a/client/app/queue/AssignToView.jsx +++ b/client/app/queue/AssignToView.jsx @@ -15,7 +15,7 @@ import SearchableDropdown from '../components/SearchableDropdown'; import TextareaField from '../components/TextareaField'; import QueueFlowModal from './components/QueueFlowModal'; -import { requestPatch, requestSave } from './uiReducer/uiActions'; +import { requestPatch, requestSave, resetSuccessMessages } from './uiReducer/uiActions'; import { taskActionData } from './utils'; @@ -59,6 +59,8 @@ class AssignToView extends React.Component { }; } + componentDidMount = () => this.props.resetSuccessMessages(); + validateForm = () => { return this.state.selectedValue !== null && this.state.instructions !== ''; }; @@ -262,7 +264,8 @@ AssignToView.propTypes = { externalAppealId: PropTypes.string, type: PropTypes.string }), - setOvertime: PropTypes.func + setOvertime: PropTypes.func, + resetSuccessMessages: PropTypes.func }; const mapStateToProps = (state, ownProps) => { @@ -282,7 +285,8 @@ const mapDispatchToProps = (dispatch) => requestSave, onReceiveAmaTasks, legacyReassignToJudge, - setOvertime + setOvertime, + resetSuccessMessages }, dispatch ); diff --git a/client/app/queue/components/AssignToAttorneyWidget.jsx b/client/app/queue/components/AssignToAttorneyWidget.jsx index fed268e3234..c39ad1cba68 100644 --- a/client/app/queue/components/AssignToAttorneyWidget.jsx +++ b/client/app/queue/components/AssignToAttorneyWidget.jsx @@ -47,6 +47,8 @@ class AssignToAttorneyWidget extends React.PureComponent { }; } + componentDidMount = () => this.props.resetSuccessMessages(); + validAssignee = () => { const { selectedAssignee } = this.props;