diff --git a/app/controllers/decision_reviews_controller.rb b/app/controllers/decision_reviews_controller.rb index 6fd27467dfa..839caeb0dd7 100644 --- a/app/controllers/decision_reviews_controller.rb +++ b/app/controllers/decision_reviews_controller.rb @@ -40,7 +40,8 @@ def index respond_to do |format| format.html { render "index" } format.csv do - jobs_as_csv = BusinessLineReporter.new(business_line).as_csv + filter_params = allowed_params[Constants.QUEUE_CONFIG.FILTER_COLUMN_REQUEST_PARAM.to_sym] + jobs_as_csv = BusinessLineReporter.new(business_line, filter_params).as_csv send_data jobs_as_csv, filename: csv_filename end format.json { queue_tasks } diff --git a/app/models/organizations/business_line.rb b/app/models/organizations/business_line.rb index c65765176fb..7d449e8b56f 100644 --- a/app/models/organizations/business_line.rb +++ b/app/models/organizations/business_line.rb @@ -149,6 +149,7 @@ def build_query .from(combined_decision_review_tasks_query) .includes(*decision_review_task_includes) .where(task_filter_predicate(query_params[:filters])) + .where(closed_at_filter_predicate(query_params[:filters])) .order(order_clause) end @@ -1082,6 +1083,70 @@ def locate_issue_type_filter(filters) def where_clause_from_array(table_class, column, values_array) table_class.arel_table[column].in(values_array) end + + def closed_at_filter_predicate(filters) + return "" if filters.blank? + + closed_at_filter = locate_closed_at_filter(filters) + + return "" unless closed_at_filter + + # ex: "val"=> val=[before,2024-09-08,] + closed_at_params = closed_at_filter["val"].first.split(",") + + build_closed_at_filter_predicate(closed_at_params) || "" + end + + def locate_closed_at_filter(filters) + parsed_filters = parse_filters(filters) + + parsed_filters.find do |filter| + filter["col"].include?("completedDateColumn") + end + end + + def build_closed_at_filter_predicate(closed_at_params) + return "" if closed_at_params.blank? + + mode, start_date, end_date = closed_at_params + operator = date_filter_mode_to_operator(mode) + + # Break early if start date is not present and it's not one of these 3 filter types + return "" if !%w[last_7_days last_30_days last_365_days].include?(operator) && start_date.blank? + + date_filter_lambda_hash(start_date, end_date).fetch(operator, lambda { + Rails.logger.error("Unsupported mode **#{operator}** used for closed at date filtering") + "" + }).call + end + + def date_filter_lambda_hash(start_date, end_date) + { + ">" => -> { "tasks.closed_at::date > '#{start_date}'::date" }, + "<" => -> { "tasks.closed_at::date < '#{start_date}'::date" }, + "=" => -> { "tasks.closed_at::date = '#{start_date}'::date" }, + "between" => lambda { + # Ensure the dates are sorted correctly so either ordering works e.g. start > end or end > start + start_date, end_date = [start_date, end_date].map(&:to_date).sort + end_date ? "tasks.closed_at::date BETWEEN '#{start_date}'::date AND '#{end_date}'::date" : "" + }, + "last_7_days" => -> { { closed_at: 1.week.ago..Time.zone.now } }, + "last_30_days" => -> { { closed_at: 30.days.ago..Time.zone.now } }, + "last_365_days" => -> { { closed_at: 365.days.ago..Time.zone.now } } + } + end + + def date_filter_mode_to_operator(mode) + { + "between" => "between", + "after" => ">", + "before" => "<", + "on" => "=", + "last7" => "last_7_days", + "last30" => "last_30_days", + "last365" => "last_365_days" + }[mode] + end end # rubocop:enable Metrics/ClassLength end diff --git a/app/models/organizations/vha_business_line.rb b/app/models/organizations/vha_business_line.rb index f7d0062b0ed..376e3f5de84 100644 --- a/app/models/organizations/vha_business_line.rb +++ b/app/models/organizations/vha_business_line.rb @@ -13,7 +13,7 @@ def tasks_query_type { incomplete: "on_hold", in_progress: "active", - completed: "recently_completed", + completed: "completed", pending: "active" } end diff --git a/app/services/business_line_reporter.rb b/app/services/business_line_reporter.rb index 92637539d58..23b60361b63 100644 --- a/app/services/business_line_reporter.rb +++ b/app/services/business_line_reporter.rb @@ -1,20 +1,28 @@ # frozen_string_literal: true class BusinessLineReporter - attr_reader :business_line + attr_reader :business_line, :filters BUSINESS_LINE_OPTIONS = %w[business_line appeal_id appeal_type claimant_name request_issues_count decision_issues_count veteran_file_number intake_user_id task_type task_id tasks_url task_assigned_to created_at closed_at].freeze - def initialize(business_line) + def initialize(business_line, filters = nil) @business_line = business_line + @filters = { filters: filters, sort_by: :id, sort_order: :asc } end def tasks - business_line.tasks.completed.includes( - [:assigned_to, appeal: [:request_issues, :decision_issues, intake: [:user]]] - ).order(id: :asc) + # If it is the VhaBusinessLine use the decision review queue task methods since they support the filters + if business_line.is_a?(VhaBusinessLine) + business_line.completed_tasks(filters).includes( + [:assigned_to, appeal: [:request_issues, :decision_issues, intake: [:user]]] + ) + else + business_line.tasks.completed.includes( + [:assigned_to, appeal: [:request_issues, :decision_issues, intake: [:user]]] + ).order(id: :asc) + end end # rubocop:disable Metrics/AbcSize diff --git a/client/COPY.json b/client/COPY.json index 4a523128ee4..bf4bc93d5a9 100644 --- a/client/COPY.json +++ b/client/COPY.json @@ -328,7 +328,8 @@ "ORGANIZATIONAL_QUEUE_PAGE_ASSIGNED_TAB_TITLE": "Assigned (%d)", "ORGANIZATIONAL_QUEUE_PAGE_IN_PROGRESS_TAB_TITLE": "In Progress (%d)", "ORGANIZATIONAL_QUEUE_ON_HOLD_TAB_TITLE": "On Hold (%d)", - "VHA_QUEUE_PAGE_COMPLETE_TASKS_DESCRIPTION": "Cases completed:", + "VHA_QUEUE_PAGE_COMPLETE_TASKS_DESCRIPTION": "Cases completed", + "VHA_QUEUE_PAGE_COMPLETE_TASKS_DESCRIPTION_WITH_FILTER": "Cases completed (%s)", "EDUCATION_RPO_QUEUE_PAGE_COMPLETED_TASKS_DESCRIPTION": "Cases completed in the last 7 days:", "VHA_ORGANIZATIONAL_QUEUE_PAGE_READY_FOR_REVIEW_TAB_TITLE": "Ready for Review", "VHA_ORGANIZATIONAL_QUEUE_PAGE_ON_HOLD_TAB_TITLE": "On Hold", @@ -1615,11 +1616,16 @@ "DATE_PICKER_CLEAR": "Clear filter", "DATE_PICKER_DROPDOWN_LABEL": "Date filter parameters", "DATE_PICKER_QUICK_BUTTON_30": "Last 30 days", + "DATE_PICKER_DROPDOWN_7": "Last 7 days", + "DATE_PICKER_DROPDOWN_30": "Last 30 days", + "DATE_PICKER_DROPDOWN_365": "Last 365 days", + "DATE_PICKER_DROPDOWN_ALL": "View All", + "DATE_PICKER_NO_FUTURE_DATES_ERROR_MESSAGE": "Date cannot be in the future.", + "DATE_PICKER_BETWEEN_DATES_ERROR_MESSAGE": "\"To\" date cannot occur before the \"From\" date", "WORK_ORDER_BANNER_MESSAGE": "Work Order Transcription Package will need to be manually removed from the box.com folder for %s, please inform %s as they may have picked up the Work Order", "HEARING_BANNER_MESSAGE": "All Hearing files have been set back to the UnAssigned state for Dispatching", "UPLOAD_TRANSCRIPTION_VBMS_TEXT": "By uploading to VBMS, you are confirming that you have reviewed the transcript in Caseflow and have found no errors.", "UPLOAD_TRANSCRIPTION_VBMS_TEXT_AREA": "Please provide context and instructions for this action", "UPLOAD_TRANSCRIPTION_VBMS_TITLE": "Upload transcript to VBMS", "UPLOAD_TRANSCRIPTION_VBMS_BUTTON": "Upload to VBMS" - } diff --git a/client/app/components/DatePicker.jsx b/client/app/components/DatePicker.jsx index 971bcbcceb5..b1d7cee9eb9 100644 --- a/client/app/components/DatePicker.jsx +++ b/client/app/components/DatePicker.jsx @@ -6,6 +6,10 @@ import SearchableDropdown from '../components/SearchableDropdown'; import Button from '../components/Button'; import COPY from '../../COPY'; import moment from 'moment-timezone'; +<<<<<<< HEAD +======= +import DateSelector from './DateSelector'; +>>>>>>> origin/feature/APPEALS-49620 const datePickerStyle = css({ paddingLeft: '0.95rem', @@ -67,6 +71,23 @@ const menuStyle = css({ } }); +<<<<<<< HEAD +======= +const defaultOptions = [ + { value: 'between', label: COPY.DATE_PICKER_DROPDOWN_BETWEEN }, + { value: 'before', label: COPY.DATE_PICKER_DROPDOWN_BEFORE }, + { value: 'after', label: COPY.DATE_PICKER_DROPDOWN_AFTER }, + { value: 'on', label: COPY.DATE_PICKER_DROPDOWN_ON } +]; + +const additionalOptions = [ + { value: 'last7', label: COPY.DATE_PICKER_DROPDOWN_7 }, + { value: 'last30', label: COPY.DATE_PICKER_DROPDOWN_30 }, + { value: 'last365', label: COPY.DATE_PICKER_DROPDOWN_365 }, + { value: 'all', label: COPY.DATE_PICKER_DROPDOWN_ALL } +]; + +>>>>>>> origin/feature/APPEALS-49620 /* Custom filter method to pass in a QueueTable column object */ /* This is called for every row of data in the table */ /* rowValue is a date string such as '5/15/2024' */ @@ -100,6 +121,27 @@ export const datePickerFilterValue = (rowValue, filterValues) => { const endDate = moment(`${filterOptions[1]} 23:59:59`).valueOf(); pick = rowDate >= startDate && rowDate <= endDate; +<<<<<<< HEAD +======= + } else if (mode === 'last7') { + const startDate = moment().subtract(7, 'days'). + valueOf(); + const endDate = moment(); + + pick = rowDate >= startDate && rowDate <= endDate; + } else if (mode === 'last30') { + const startDate = moment().subtract(30, 'days'). + valueOf(); + const endDate = moment(); + + pick = rowDate >= startDate && rowDate <= endDate; + } else if (mode === 'last365') { + const startDate = moment().subtract(365, 'days'). + valueOf(); + const endDate = moment().valueOf(); + + pick = rowDate >= startDate && rowDate <= endDate; +>>>>>>> origin/feature/APPEALS-49620 } } } @@ -114,6 +156,10 @@ class DatePicker extends React.PureComponent { const position = (props.settings && props.settings.position) || 'left'; const buttons = (props.settings && props.settings.buttons) || false; const selected = (props.selected && props.selected) || false; +<<<<<<< HEAD +======= + const noFutureDates = (props.settings && props.settings.noFutureDates) || false; +>>>>>>> origin/feature/APPEALS-49620 this.state = { open: false, @@ -122,13 +168,28 @@ class DatePicker extends React.PureComponent { endDate: '', position, buttons, +<<<<<<< HEAD selected +======= + selected, + noFutureDates +>>>>>>> origin/feature/APPEALS-49620 }; } apply() { const { onChange } = this.props; +<<<<<<< HEAD +======= + if (this.state.mode === 'all') { + this.clearFilter(); + this.hideDropdown(); + + return true; + } + +>>>>>>> origin/feature/APPEALS-49620 if (onChange) { onChange(`${this.state.mode },${ this.state.startDate },${ this.state.endDate}`); } @@ -179,11 +240,41 @@ class DatePicker extends React.PureComponent { return this.state.open || this.state.selected; } +<<<<<<< HEAD +======= + isDateInFuture = (date) => { + if (!date) { + return false; + } + + return Boolean(Date.parse(date) > Date.now()); + } + +>>>>>>> origin/feature/APPEALS-49620 buttonDisabled = () => { let disabled = true; if (this.state.mode === 'between') { +<<<<<<< HEAD disabled = this.state.startDate === '' || this.state.endDate === ''; +======= + if (this.state.startDate === '' || this.state.endDate === '') { + disabled = true; + } else if (this.state.noFutureDates && + (this.isDateInFuture(this.state.startDate) || this.isDateInFuture(this.state.endDate))) { + disabled = true; + } else { + const startDate = moment(`${this.state.startDate} 00:00:00`).valueOf(); + const endDate = moment(`${this.state.endDate} 23:59:59`).valueOf(); + + disabled = startDate >= endDate; + } + + } else if (this.state.noFutureDates && this.isDateInFuture(this.state.startDate)) { + disabled = true; + } else if (this.state.mode === 'all') { + disabled = false; +>>>>>>> origin/feature/APPEALS-49620 } else if (this.state.mode !== '') { disabled = this.state.startDate === ''; } @@ -204,10 +295,29 @@ class DatePicker extends React.PureComponent { } updateMode = (mode) => { +<<<<<<< HEAD +======= + const format = 'YYYY-MM-DD'; + +>>>>>>> origin/feature/APPEALS-49620 this.setState({ mode }); if (mode !== 'between') { this.setState({ endDate: '' }); } +<<<<<<< HEAD +======= + + if (mode === 'last7') { + this.setState({ startDate: moment().subtract(7, 'days'). + format(format) }); + } else if (mode === 'last30') { + this.setState({ startDate: moment().subtract(30, 'days'). + format(format) }); + } else if (mode === 'last365') { + this.setState({ startDate: moment().subtract(365, 'days'). + format(format) }); + } +>>>>>>> origin/feature/APPEALS-49620 } quickButtons = (option) => { @@ -231,7 +341,47 @@ class DatePicker extends React.PureComponent { this.hideDropdown(); } +<<<<<<< HEAD + render() { +======= + getOptions = () => { + if (this.props.settings?.additionalOptions) { + const options = defaultOptions.concat(additionalOptions); + + return options; + } + + return defaultOptions; + }; + + startDateErrorMessage = () => { + if (this.state.noFutureDates && this.state.startDate && this.isDateInFuture(this.state.startDate)) { + return COPY.DATE_PICKER_NO_FUTURE_DATES_ERROR_MESSAGE; + } + + return ''; + } + + endDateErrorMessage = () => { + if (this.state.noFutureDates && this.state.endDate && this.isDateInFuture(this.state.endDate)) { + return COPY.DATE_PICKER_NO_FUTURE_DATES_ERROR_MESSAGE; + } + + if (this.state.mode === 'between' && this.state.startDate !== '' && this.state.endDate !== '') { + const startDate = moment(`${this.state.startDate} 00:00:00`).valueOf(); + const endDate = moment(`${this.state.endDate} 23:59:59`).valueOf(); + + if (startDate >= endDate) { + return COPY.DATE_PICKER_BETWEEN_DATES_ERROR_MESSAGE; + } + } + + return ''; + } + render() { + +>>>>>>> origin/feature/APPEALS-49620 return { this.rootElem = rootElem; }}> @@ -257,18 +407,23 @@ class DatePicker extends React.PureComponent {
>>>>>> origin/feature/APPEALS-49620 searchable onChange={(option) => this.updateMode(option.value)} filterOption={() => true} value={this.state.mode} />
+<<<<<<< HEAD {this.state.mode !== '' &&
+
+
+ +
+ +
+
+
@@ -329,34 +357,58 @@ exports[`DatePicker restores input values correctly 1`] = `
- - + +
+ +
+
- - + +
+ +
+
- - + +
+ +
+
- - + +
+ +
+
- - + +
+ +
+
@@ -871,7 +871,7 @@ exports[`TranscriptionFileDispatchTable All Tab loads a table from backend data AOD
, - + Original @@ -1010,7 +1010,7 @@ exports[`TranscriptionFileDispatchTable All Tab loads a table from backend data role="tooltip" > Hearing @@ -1107,7 +1107,7 @@ exports[`TranscriptionFileDispatchTable All Tab loads a table from backend data AOD , - + Original @@ -4487,7 +4487,7 @@ exports[`TranscriptionFileDispatchTable Completed Tab loads a table from backend role="tooltip" > Hearing @@ -4584,7 +4584,7 @@ exports[`TranscriptionFileDispatchTable Completed Tab loads a table from backend AOD , - + Original @@ -4725,7 +4725,7 @@ exports[`TranscriptionFileDispatchTable Completed Tab loads a table from backend role="tooltip" > Hearing @@ -4822,7 +4822,7 @@ exports[`TranscriptionFileDispatchTable Completed Tab loads a table from backend AOD , - + Original @@ -5043,9 +5043,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -5458,9 +5458,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -5497,7 +5497,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -5609,7 +5609,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen AOD , - + Original @@ -5670,9 +5670,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -5709,7 +5709,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -5821,7 +5821,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen AOD , - + Original @@ -5881,9 +5881,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -5920,7 +5920,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -6032,7 +6032,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen AOD , - + Original @@ -6092,9 +6092,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -6131,7 +6131,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -6243,7 +6243,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen AOD , - + Original @@ -6303,9 +6303,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -6342,7 +6342,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -6454,7 +6454,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen AOD , - + Original @@ -6514,9 +6514,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -6553,7 +6553,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -6665,7 +6665,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen AOD , - + Original @@ -6725,9 +6725,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -6764,7 +6764,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -6927,9 +6927,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -6966,7 +6966,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -7129,9 +7129,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -7168,7 +7168,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -7331,9 +7331,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -7370,7 +7370,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -7533,9 +7533,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -7572,7 +7572,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -7735,9 +7735,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -7774,7 +7774,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -7937,9 +7937,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -7976,7 +7976,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -8139,9 +8139,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -8178,7 +8178,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing @@ -8341,9 +8341,9 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen - + - + @@ -8380,7 +8380,7 @@ exports[`TranscriptionFileDispatchTable Unassigned Tab loads a table from backen role="tooltip" > Hearing diff --git a/client/test/app/hearings/components/transcriptionProcessing/__snapshots__/TranscriptionSettings.test.js.snap b/client/test/app/hearings/components/transcriptionProcessing/__snapshots__/TranscriptionSettings.test.js.snap index bd5a67e4bfa..5b177e8f29c 100644 --- a/client/test/app/hearings/components/transcriptionProcessing/__snapshots__/TranscriptionSettings.test.js.snap +++ b/client/test/app/hearings/components/transcriptionProcessing/__snapshots__/TranscriptionSettings.test.js.snap @@ -12,7 +12,7 @@ Object { - < + < Back to Transcription queue   @@ -132,13 +132,13 @@ Object {
  • - Contractor folder name in box.com: + Contractor folder name in box.com: BVA Hearing Transcripts/Genesis Government Solutions, Inc.
  • - POC: + POC: John Doe
  • @@ -157,10 +157,10 @@ Object { data-css-1t9uipm="" > - Hearings sent to Genesis Government Solutions, Inc. this week: + Hearings sent to Genesis Government Solutions, Inc. this week:   - 7 of + 7 of 150
  • - Contractor folder name in box.com: + Contractor folder name in box.com: BVA Hearing Transcripts/Jamison Professional Services
  • - POC: + POC: Jane Doe
  • @@ -325,10 +325,10 @@ Object { data-css-1t9uipm="" > - Hearings sent to Jamison Professional Services this week: + Hearings sent to Jamison Professional Services this week:   - 0 of + 0 of 0
  • - Contractor folder name in box.com: + Contractor folder name in box.com: BVA Hearing Transcripts/The Ravens Group, Inc.
  • - POC: + POC: Johnny Bravo
  • @@ -493,10 +493,10 @@ Object { data-css-1t9uipm="" > - Hearings sent to The Ravens Group, Inc. this week: + Hearings sent to The Ravens Group, Inc. this week:   - 2 of + 2 of 120
    - < + < Back to Transcription queue   @@ -706,13 +706,13 @@ Object {
  • - Contractor folder name in box.com: + Contractor folder name in box.com: BVA Hearing Transcripts/Genesis Government Solutions, Inc.
  • - POC: + POC: John Doe
  • @@ -731,10 +731,10 @@ Object { data-css-1t9uipm="" > - Hearings sent to Genesis Government Solutions, Inc. this week: + Hearings sent to Genesis Government Solutions, Inc. this week:   - 7 of + 7 of 150
  • - Contractor folder name in box.com: + Contractor folder name in box.com: BVA Hearing Transcripts/Jamison Professional Services
  • - POC: + POC: Jane Doe
  • @@ -899,10 +899,10 @@ Object { data-css-1t9uipm="" > - Hearings sent to Jamison Professional Services this week: + Hearings sent to Jamison Professional Services this week:   - 0 of + 0 of 0
  • - Contractor folder name in box.com: + Contractor folder name in box.com: BVA Hearing Transcripts/The Ravens Group, Inc.
  • - POC: + POC: Johnny Bravo
  • @@ -1067,10 +1067,10 @@ Object { data-css-1t9uipm="" > - Hearings sent to The Ravens Group, Inc. this week: + Hearings sent to The Ravens Group, Inc. this week:   - 2 of + 2 of 120
    { - // jest.clearAllMocks(); - // Mock ApiUtil get so the tasks will appear in the queues. ApiUtil.get = jest.fn().mockResolvedValue({ tasks: { data: [] }, @@ -90,7 +89,10 @@ const renderNonCompTabs = (props) => { return render( - + + + + ); }; @@ -177,7 +179,7 @@ describe('NonCompTabsVha', () => { fireEvent.click(tabs[3]); await waitFor(() => { - expect(screen.getByText('Cases completed (last 7 days):')).toBeInTheDocument(); + expect(screen.getByText('Cases completed (Last 7 Days)')).toBeInTheDocument(); }); // Check for the correct completed tasks header values @@ -232,7 +234,6 @@ describe('NonCompTabsGeneric', () => { expect(screen.getAllByText('Completed Tasks')).toBeTruthy(); const tabs = screen.getAllByRole('tab'); - console.log('tabs', tabs) fireEvent.click(tabs[1]); diff --git a/client/test/app/nonComp/pages/ReviewPage.test.js b/client/test/app/nonComp/pages/ReviewPage.test.js index bff1fd250a4..21408da3659 100644 --- a/client/test/app/nonComp/pages/ReviewPage.test.js +++ b/client/test/app/nonComp/pages/ReviewPage.test.js @@ -7,6 +7,7 @@ import ReviewPage from 'app/nonComp/pages/ReviewPage'; import CombinedNonCompReducer, { mapDataToInitialState } from 'app/nonComp/reducers'; import { vhaTaskFilterDetails } from 'test/data/taskFilterDetails'; import ApiUtil from 'app/util/ApiUtil'; +import { MemoryRouter as Router } from 'react-router-dom'; const nonAdminVhaProps = { serverNonComp: { @@ -47,7 +48,9 @@ const renderReviewPage = (storeValues = {}) => { return render( - + + + ); }; diff --git a/client/test/app/queue/components/modalUtils.js b/client/test/app/queue/components/modalUtils.js index 7376d1db7ef..ab25baec391 100644 --- a/client/test/app/queue/components/modalUtils.js +++ b/client/test/app/queue/components/modalUtils.js @@ -1,6 +1,5 @@ import userEvent from '@testing-library/user-event'; -import { fireEvent } from '@testing-library/react'; -import { screen } from '@testing-library/react'; +import { screen, fireEvent, waitFor } from '@testing-library/react'; import * as uiActions from 'app/queue/uiReducer/uiActions'; /** @@ -131,3 +130,14 @@ export const createSpyRequestPatch = (postData) => { } ))); }; + +export const openFilter = async (container) => { + const svg = container.querySelectorAll('svg'); + + const filter = svg[svg.length - 1]; + + fireEvent.click(filter); + await waitFor(() => { + expect(screen.getByText('Date filter parameters')).toBeInTheDocument(); + }); +}; diff --git a/config/initializers/va_box_service.rb b/config/initializers/va_box_service.rb index 4db8623b93e..ca5564aa93c 100644 --- a/config/initializers/va_box_service.rb +++ b/config/initializers/va_box_service.rb @@ -1 +1,3 @@ -VaBoxService = Rails.deploy_env?(:test) ? Fakes::VaBoxService : ExternalApi::VaBoxService +Rails.application.reloader.to_prepare do + VaBoxService = Rails.deploy_env?(:test) ? Fakes::VaBoxService : ExternalApi::VaBoxService +end diff --git a/db/migrate/20240507203310_add_indexes_to_transcriptions.rb b/db/migrate/20240507203310_add_indexes_to_transcriptions.rb index b1b795c186e..d2ada620f8e 100644 --- a/db/migrate/20240507203310_add_indexes_to_transcriptions.rb +++ b/db/migrate/20240507203310_add_indexes_to_transcriptions.rb @@ -1,6 +1,7 @@ class AddIndexesToTranscriptions < ActiveRecord::Migration[6.1] + disable_ddl_transaction! def change - add_safe_index :transcriptions, [:transcription_contractor_id], name: "index_transcriptions_on_transcription_contractor_id" - add_safe_index :transcriptions, [:deleted_at], name: "index_transcriptions_on_deleted_at" + add_index :transcriptions, :transcription_contractor_id, algorithm: :concurrently, name: "index_transcriptions_on_transcription_contractor_id" + add_index :transcriptions, :deleted_at, algorithm: :concurrently, name: "index_transcriptions_on_deleted_at" end end diff --git a/db/migrate/20240621083822_add_locked_by_user_id_and_locked_at_to_transcription_files.rb b/db/migrate/20240621083822_add_locked_by_user_id_and_locked_at_to_transcription_files.rb index c567df42ee5..be59dc1d59c 100644 --- a/db/migrate/20240621083822_add_locked_by_user_id_and_locked_at_to_transcription_files.rb +++ b/db/migrate/20240621083822_add_locked_by_user_id_and_locked_at_to_transcription_files.rb @@ -1,11 +1,11 @@ class AddLockedByUserIdAndLockedAtToTranscriptionFiles < ActiveRecord::Migration[6.1] - include Caseflow::Migrations::AddIndexConcurrently + disable_ddl_transaction! def up add_column :transcription_files, :locked_by_id, :bigint, comment: "ID of user who locked the record" add_column :transcription_files, :locked_at, :datetime, comment: "Locked record timeout field" add_foreign_key :transcription_files, :users, column: "locked_by_id", validate: false - add_safe_index :transcription_files, [:locked_by_id, :locked_at], name: "index_transcription_files_locked_by_id_locked_at" + add_index :transcription_files, [:locked_by_id, :locked_at], algorithm: :concurrently, name: "index_transcription_files_locked_by_id_locked_at" end def down diff --git a/db/migrate/20240825120325_add_transcription_id_to_transcription_files.rb b/db/migrate/20240825120325_add_transcription_id_to_transcription_files.rb index 95190df440d..77d29733106 100644 --- a/db/migrate/20240825120325_add_transcription_id_to_transcription_files.rb +++ b/db/migrate/20240825120325_add_transcription_id_to_transcription_files.rb @@ -1,9 +1,8 @@ class AddTranscriptionIdToTranscriptionFiles < ActiveRecord::Migration[6.1] - include Caseflow::Migrations::AddIndexConcurrently + disable_ddl_transaction! def change add_column :transcription_files, :transcription_id, :bigint, comment: "ID of the associated transcription record" - - add_safe_index :transcription_files, :transcription_id, algorithm: :concurrently + add_index :transcription_files, :transcription_id, algorithm: :concurrently, name: "index_transcription_files_on_transcription_id" end end diff --git a/db/seeds/transcription_contractors.rb b/db/seeds/transcription_contractors.rb index 86af92c4fa8..4d9e98b0610 100644 --- a/db/seeds/transcription_contractors.rb +++ b/db/seeds/transcription_contractors.rb @@ -27,6 +27,11 @@ def seed! directory: "BVA Hearing Transcripts/Actual Contractor, Inc.", poc: "Johnny Cash", email: "actualcontractor@test.com", + phone: "888-888-8888"}, + { name: "Vet Reporting", + directory: "BVA Hearing Transcripts/Vet Reporting", + poc: "Johnny Cash", + email: "vetreporting@test.com", phone: "888-888-8888"} ] diff --git a/spec/feature/hearings/virtual_hearings/daily_docket_spec.rb b/spec/feature/hearings/virtual_hearings/daily_docket_spec.rb index eaf07f3b392..b24f2cddf70 100644 --- a/spec/feature/hearings/virtual_hearings/daily_docket_spec.rb +++ b/spec/feature/hearings/virtual_hearings/daily_docket_spec.rb @@ -42,13 +42,12 @@ def check_email_events(hearing, current_user) let(:expected_central_office_time) do time_str = "#{updated_hearing_time} #{hearing.hearing_day.scheduled_for} America/New_York" tz_abbr = Time.zone.parse(time_str).dst? ? "ET" : "EST" - Time .parse(updated_hearing_time) .strftime("%F %T") .in_time_zone(regional_office_timezone) # cast the updated hearing time to the ro timezone .in_time_zone(HearingTimeService::CENTRAL_OFFICE_TIMEZONE) # convert it to the central office timezone - .strftime("%-l:%M %p #{tz_abbr}") # and render it in the format expected in the modal + .strftime("%-l:%M %p #{tz_abbr}") # and render it in the format expected in end scenario "Virtual hearing time is updated" do diff --git a/spec/feature/non_comp/dispositions_spec.rb b/spec/feature/non_comp/dispositions_spec.rb index 7d270821654..ba441682425 100644 --- a/spec/feature/non_comp/dispositions_spec.rb +++ b/spec/feature/non_comp/dispositions_spec.rb @@ -323,7 +323,8 @@ def find_disabled_disposition(disposition, description = nil) scroll_to(page, align: :bottom) expect(page).to have_button("Complete", disabled: false) click_button("Complete") - expect(page).to have_current_path("/#{business_line_url}?tab=completed&page=1") + expect(page).to have_content("Cases completed (Last 7 Days)") + expect(current_url).to include("#{business_line_url}?tab=completed&page=1") end step "completed Decision review task should have specific decision date provided during completion" do diff --git a/spec/feature/non_comp/individual_claim_history_spec.rb b/spec/feature/non_comp/individual_claim_history_spec.rb index ddfd39e4e5c..13d7b8b213b 100644 --- a/spec/feature/non_comp/individual_claim_history_spec.rb +++ b/spec/feature/non_comp/individual_claim_history_spec.rb @@ -29,6 +29,7 @@ def clear_filter_option(filter_text) sort = find("[aria-label='Filter by Activity. Filtering by #{filter_text}']") sort.click + clear_button_filter = page.first(:css, ".cf-clear-filter-button-wrapper, .clear-wrapper") clear_button_filter = page.find(class: "cf-clear-filter-button-wrapper", wait: 10) clear_button_filter.click end diff --git a/spec/feature/non_comp/reviews_spec.rb b/spec/feature/non_comp/reviews_spec.rb index 1cf36ba917c..702b24eb852 100644 --- a/spec/feature/non_comp/reviews_spec.rb +++ b/spec/feature/non_comp/reviews_spec.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true feature "NonComp Reviews Queue", :postgres do + include DownloadHelpers let(:non_comp_org) { VhaBusinessLine.singleton } let(:user) { create(:intake_user) } @@ -88,7 +89,7 @@ :completed, appeal: hlr_c, assigned_to: non_comp_org, - closed_at: 2.days.ago) + closed_at: 3.days.ago) ] end @@ -428,11 +429,23 @@ def current_table_rows click_button("tasks-organization-queue-tab-3") later_date = Time.zone.now.strftime("%m/%d/%y") - earlier_date = 2.days.ago.strftime("%m/%d/%y") + earlier_date = 3.days.ago.strftime("%m/%d/%y") + + last_seven_days_date_string = 7.days.ago.strftime("%Y-%m-%d") + + params = { + tab: "completed", + page: 1, + sort_by: "completedDateColumn", + order: "desc", + "filter[]" => "col=completedDateColumn&val=last7,#{last_seven_days_date_string}," + } + + query_string = URI.encode_www_form(params) order_buttons[:date_completed].click expect(page).to have_current_path( - "#{BASE_URL}?tab=completed&page=1&sort_by=completedDateColumn&order=desc" + "#{BASE_URL}?#{query_string}" ) table_rows = current_table_rows @@ -440,10 +453,12 @@ def current_table_rows expect(table_rows.last.include?(earlier_date)).to eq true expect(table_rows.first.include?(later_date)).to eq true + params[:order] = "asc" + query_string = URI.encode_www_form(params) # Date Completed desc order_buttons[:date_completed].click expect(page).to have_current_path( - "#{BASE_URL}?tab=completed&page=1&sort_by=completedDateColumn&order=asc" + "#{BASE_URL}?#{query_string}" ) table_rows = current_table_rows @@ -581,7 +596,9 @@ def current_table_rows # Verify the filter counts for the completed tab click_on "Completed Tasks" - expect(page).to have_content(COPY::QUEUE_PAGE_COMPLETE_LAST_SEVEN_DAYS_TASKS_DESCRIPTION) + expect(page).to have_content(COPY::VHA_QUEUE_PAGE_COMPLETE_TASKS_DESCRIPTION) + # Turn this back on after last 7 days prefilter is added + # expect(page).to have_content(COPY::QUEUE_PAGE_COMPLETE_LAST_SEVEN_DAYS_TASKS_DESCRIPTION) find("[aria-label='Filter by issue type']").click expect(page).to have_content("Apportionment (1)") expect(page).to have_content("Camp Lejune Family Member (1)") @@ -985,6 +1002,90 @@ def current_table_rows end end + context "Completed Date filtering" do + it "is filterable by the completed date column" do + visit BASE_URL + expect(page).to have_content("Veterans Health Administration") + click_on "Completed Tasks" + + expect(page).to have_content("Cases completed (Last 7 Days)") + expect(page).to have_content("Date Completed (1)") + expect(page).to have_content("Viewing 1-2 of 2 total") + date_string = 7.days.ago.strftime("%Y-%m-%d") + find("[aria-label='Filter by completed date. Filtering by last7,#{date_string},']").click + expect(page).to have_content("Date filter parameters") + submit_button = find("button", text: "Apply Filter") + + expect(submit_button[:disabled]).to eq "false" + + click_on "Clear all filters" + + expect(page).to have_content("Cases completed") + expect(page).to_not have_content("Date Completed (1)") + expect(page).to have_content("Viewing 1-3 of 3 total") + + find("[aria-label='Filter by completed date']").click + expect(page).to have_content("Date filter parameters") + submit_button = find("button", text: "Apply Filter") + + expect(submit_button[:disabled]).to eq "true" + + page.find(".cf-select__control", match: :first).click + page.all("cf-select__option") + # Verify that all the date picker options are available + all_date_filter_options = [ + "Between these dates", + "Before this date", + "After this date", + "On this date", + "Last 7 days", + "Last 30 days", + "Last 365 days", + "View All" + ] + all_date_filter_options.each do |date_filter_option| + expect(page).to have_content(date_filter_option) + end + find("div", class: "cf-select__option", text: "Before this date", exact_text: true).click + + one_day_ago_date_string = 1.day.ago.strftime("%m/%d/%Y") + fill_in "Date", with: one_day_ago_date_string + expect(submit_button[:disabled]).to eq "false" + submit_button.click + + expect(page).to have_content("Cases completed (Before #{one_day_ago_date_string})") + expect(page).to have_content("Date Completed (1)") + expect(page).to have_content("Viewing 1-2 of 2 total") + find("[aria-label='Filter by completed date. Filtering by before,#{1.day.ago.strftime('%Y-%m-%d')},']").click + page.find(".cf-select__control", match: :first).click + find("div", class: "cf-select__option", text: "After this date", exact_text: true).click + find("button", text: "Apply Filter").click + + expect(page).to have_content("Cases completed (After #{one_day_ago_date_string})") + expect(page).to have_content("Date Completed (1)") + expect(page).to have_content("Viewing 1-1 of 1 total") + + click_on "Clear all filters" + + expect(page).to have_content(COPY::VHA_QUEUE_PAGE_COMPLETE_TASKS_DESCRIPTION) + expect(page).to_not have_content("Date Completed (1)") + expect(page).to have_content("Viewing 1-3 of 3 total") + + find("[aria-label='Filter by completed date']").click + expect(page).to have_content("Date filter parameters") + submit_button = find("button", text: "Apply Filter") + + expect(submit_button[:disabled]).to eq "true" + page.find(".cf-select__control", match: :first).click + find("div", class: "cf-select__option", text: "Last 30 days", exact_text: true).click + submit_button.click + + expect(page).to have_content("Cases completed (Last 30 Days)") + expect(page).to have_content("Date Completed (1)") + expect(page).to have_content("Viewing 1-3 of 3 total") + end + end + context "get params should not get appended to URL when QueueTable is loading and user navigates to Generate report pages." do # rubocop:disable Layout/LineLength before do create_list(:higher_level_review_vha_task, 30, assigned_to: non_comp_org) @@ -1007,17 +1108,45 @@ def current_table_rows end end + context "Download Completed Tasks csv" do + scenario "it should use the filters from the page for the csv response" do + visit BASE_URL + expect(page).to have_content("Veterans Health Administration") + click_on "Completed Tasks" + expect(page).to have_content("2 total") + expect(page).to have_content("Cases completed (Last 7 Days)") + click_button "Download completed tasks" + + # Check the csv to make sure it returns the two task rows within the last week and the header row + completed_tasks_csv_file(3) + + # Filter by Camp Lejune Family Member + find("[aria-label='Filter by issue type']").click + find("label", text: "Camp Lejune Family Member").click + expect(page).to have_content("Camp Lejune Family Member") + + # The completed tasks csv should be filtered by the issue type now + click_button "Download completed tasks" + completed_tasks_csv_file(2) + + # Clear the filters and the csv should contain all completed tasks + find(".cf-clear-filters-link").click + expect(page).to have_content("3 total") + click_button "Download completed tasks" + completed_tasks_csv_file(4) + end + end + context "For a non comp org that is not VHA" do after { FeatureToggle.disable!(:board_grant_effectuation_task) } let(:non_comp_org) { create(:business_line, name: "Non-Comp Org", url: "nco") } - scenario "the Generate task report button does not display for non-vha users" do - visit "/decision_reviews/nco" + scenario "displays tasks page for non VHA" do + visit "/decision_reviews/#{non_comp_org.url}" + + # The generate task report button does not display for non-vha users expect(page).to_not have_content("Generate task report") - end - scenario "displays tasks page for non VHA" do - visit "/decision_reviews/nco" expect(page).to have_content("Non-Comp Org") expect(page).to_not have_content("Incomplete Tasks") expect(page).to_not have_content("Pending Tasks") @@ -1068,5 +1197,50 @@ def current_table_rows expect(page).to have_content("Page not found") end end + + context "Download Completed Tasks csv" do + scenario "it should not use the filters from the page for the csv response" do + visit "/decision_reviews/#{non_comp_org.url}" + expect(page).to have_content("Non-Comp Org") + click_on "Completed Tasks" + expect(page).to have_content(COPY::QUEUE_PAGE_COMPLETE_LAST_SEVEN_DAYS_TASKS_DESCRIPTION) + expect(page).to have_content("2 total") + click_button "Download completed tasks" + + # Check the csv to make sure return all completed task rows and the header row + completed_tasks_csv_file(4) + + # Filter by Camp Lejune Family Member + find("[aria-label='Filter by issue type']").click + find("label", text: "Camp Lejune Family Member").click + expect(page).to have_content("Camp Lejune Family Member") + + # The completed tasks csv should be still have all completed tasks + click_button "Download completed tasks" + completed_tasks_csv_file(4) + + # Clear the filters and the csv should still contain all completed tasks + find(".cf-clear-filters-link").click + expect(page).to have_content("2 total") + click_button "Download completed tasks" + completed_tasks_csv_file(4) + end + end + end + + def latest_download + downloads.max_by { |file| File.mtime(file) } + end + + def download_csv + wait_for_download + CSV.read(latest_download) + end + + def completed_tasks_csv_file(rows) + csv_file = download_csv + expect(csv_file).to_not eq(nil) + expect(csv_file.length).to eq(rows) + clear_downloads end end diff --git a/spec/models/business_line_spec.rb b/spec/models/business_line_spec.rb index ef3205c1c03..a291deec7ba 100644 --- a/spec/models/business_line_spec.rb +++ b/spec/models/business_line_spec.rb @@ -126,47 +126,43 @@ end describe ".in_progress_tasks" do - let!(:hlr_tasks_on_active_decision_reviews) do - create_list(:higher_level_review_vha_task, 5, assigned_to: business_line) - end + before(:all) do + @business_line = VhaBusinessLine.singleton + @veteran = create(:veteran) - let!(:sc_tasks_on_active_decision_reviews) do - create_list(:supplemental_claim_vha_task, 5, assigned_to: business_line) - end + @hlr_tasks_on_active_decision_reviews = + create_list(:higher_level_review_vha_task, 5, assigned_to: @business_line) - let!(:decision_review_tasks_on_inactive_decision_reviews) do - create_list(:higher_level_review_task, 5, assigned_to: business_line) - end + @sc_tasks_on_active_decision_reviews = + create_list(:supplemental_claim_vha_task, 5, assigned_to: @business_line) - let!(:remand_tasks_on_active_decision_reviews) do - create_list(:remand_vha_task, 5, assigned_to: business_line) - end + @decision_review_tasks_on_inactive_decision_reviews = + create_list(:higher_level_review_task, 5, assigned_to: @business_line) - let!(:board_grant_effectuation_tasks) do - tasks = create_list(:board_grant_effectuation_task, 5, assigned_to: business_line) + @board_grant_effectuation_tasks = + create_list(:board_grant_effectuation_task, 5, assigned_to: @business_line) - tasks.each do |task| + @remand_tasks_on_active_decision_reviews = create_list(:remand_vha_task, 5, assigned_to: @business_line) + + @board_grant_effectuation_tasks.each do |task| create( :request_issue, :nonrating, decision_review: task.appeal, - benefit_type: business_line.url, + benefit_type: @business_line.url, closed_at: Time.zone.now, closed_status: "decided" ) end - tasks - end - - let!(:veteran_record_request_on_active_appeals) do - add_veteran_and_request_issues_to_decision_reviews( - create_list(:veteran_record_request_task, 5, assigned_to: business_line) + @veteran_record_request_on_active_appeals = add_veteran_and_request_issues_to_decision_reviews( + create_list(:veteran_record_request_task, 5, assigned_to: @business_line), + @veteran, + @business_line ) - end - let!(:veteran_record_request_on_inactive_appeals) do - create_list(:veteran_record_request_task, 5, assigned_to: business_line) + @veteran_record_request_on_inactive_appeals = + create_list(:veteran_record_request_task, 5, assigned_to: @business_line) end subject { business_line.in_progress_tasks(filters: task_filters) } @@ -182,11 +178,11 @@ it "All tasks associated with active decision reviews and BoardGrantEffectuationTasks are included" do expect(subject.size).to eq 25 expect(subject.map(&:id)).to match_array( - (veteran_record_request_on_active_appeals + - board_grant_effectuation_tasks + - hlr_tasks_on_active_decision_reviews + - sc_tasks_on_active_decision_reviews + - remand_tasks_on_active_decision_reviews + (@veteran_record_request_on_active_appeals + + @board_grant_effectuation_tasks + + @hlr_tasks_on_active_decision_reviews + + @sc_tasks_on_active_decision_reviews + + @remand_tasks_on_active_decision_reviews ).pluck(:id) ) end @@ -200,10 +196,10 @@ it "All tasks associated with active decision reviews are included, but not BoardGrantEffectuationTasks" do expect(subject.size).to eq 20 expect(subject.map(&:id)).to match_array( - (veteran_record_request_on_active_appeals + - hlr_tasks_on_active_decision_reviews + - sc_tasks_on_active_decision_reviews + - remand_tasks_on_active_decision_reviews + (@veteran_record_request_on_active_appeals + + @hlr_tasks_on_active_decision_reviews + + @sc_tasks_on_active_decision_reviews + + @remand_tasks_on_active_decision_reviews ).pluck(:id) ) end @@ -211,22 +207,18 @@ end describe ".incomplete_tasks" do - let!(:hlr_tasks_on_active_decision_reviews) do - tasks = create_list(:higher_level_review_vha_task, 5, assigned_to: business_line) - tasks.each(&:on_hold!) - tasks - end + before(:all) do + @business_line = VhaBusinessLine.singleton + @veteran = create(:veteran) - let!(:sc_tasks_on_active_decision_reviews) do - tasks = create_list(:supplemental_claim_vha_task, 5, assigned_to: business_line) - tasks.each(&:on_hold!) - tasks - end + @hlr_tasks_on_active_decision_reviews = + create_list(:higher_level_review_vha_task, 5, assigned_to: @business_line).each(&:on_hold!) - let!(:decision_review_tasks_on_inactive_decision_reviews) do - tasks = create_list(:higher_level_review_task, 5, assigned_to: business_line) - tasks.each(&:on_hold!) - tasks + @sc_tasks_on_active_decision_reviews = + create_list(:supplemental_claim_vha_task, 5, assigned_to: @business_line).each(&:on_hold!) + + @decision_review_tasks_on_inactive_decision_reviews = + create_list(:higher_level_review_task, 5, assigned_to: @business_line).each(&:on_hold!) end subject { business_line.incomplete_tasks(filters: task_filters) } @@ -239,8 +231,8 @@ it "All tasks associated with active decision reviews and BoardGrantEffectuationTasks are included" do expect(subject.size).to eq 10 expect(subject.map(&:id)).to match_array( - (hlr_tasks_on_active_decision_reviews + - sc_tasks_on_active_decision_reviews + (@hlr_tasks_on_active_decision_reviews + + @sc_tasks_on_active_decision_reviews ).pluck(:id) ) end @@ -248,67 +240,72 @@ end describe ".completed_tasks" do - let!(:open_hlr_tasks) do - add_veteran_and_request_issues_to_decision_reviews( - create_list(:higher_level_review_task, 5, assigned_to: business_line) + before(:all) do + @business_line = VhaBusinessLine.singleton + @veteran = create(:veteran) + + @open_hlr_tasks = add_veteran_and_request_issues_to_decision_reviews( + create_list(:higher_level_review_task, 5, assigned_to: @business_line), + @veteran, + @business_line ) - end - let!(:completed_hlr_tasks) do - add_veteran_and_request_issues_to_decision_reviews( + @completed_hlr_tasks = add_veteran_and_request_issues_to_decision_reviews( complete_all_tasks( - create_list(:higher_level_review_task, 5, assigned_to: business_line) - ) + create_list(:higher_level_review_task, 5, assigned_to: @business_line) + ), + @veteran, + @business_line ) - end - let!(:completed_remand_tasks) do - add_veteran_and_request_issues_to_decision_reviews( - complete_all_tasks( - create_list(:remand_task, 5, assigned_to: business_line) - ) + @open_sc_tasks = add_veteran_and_request_issues_to_decision_reviews( + create_list(:supplemental_claim_task, 5, assigned_to: @business_line), + @veteran, + @business_line ) - end - let!(:open_sc_tasks) do - add_veteran_and_request_issues_to_decision_reviews( - create_list(:supplemental_claim_task, 5, assigned_to: business_line) + @completed_remand_tasks = add_veteran_and_request_issues_to_decision_reviews( + complete_all_tasks( + create_list(:remand_task, 5, assigned_to: @business_line) + ), + @veteran, + @business_line ) - end - let!(:completed_sc_tasks) do - add_veteran_and_request_issues_to_decision_reviews( + @completed_sc_tasks = add_veteran_and_request_issues_to_decision_reviews( complete_all_tasks( - create_list(:supplemental_claim_task, 5, assigned_to: business_line) - ) + create_list(:supplemental_claim_task, 5, assigned_to: @business_line) + ), + @veteran, + @business_line ) - end - let!(:open_board_grant_effectuation_tasks) do - add_veteran_and_request_issues_to_decision_reviews( - create_list(:board_grant_effectuation_task, 5, assigned_to: business_line) + @open_board_grant_effectuation_tasks = add_veteran_and_request_issues_to_decision_reviews( + create_list(:board_grant_effectuation_task, 5, assigned_to: @business_line), + @veteran, + @business_line ) - end - let!(:completed_board_grant_effectuation_tasks) do - add_veteran_and_request_issues_to_decision_reviews( + @completed_board_grant_effectuation_tasks = add_veteran_and_request_issues_to_decision_reviews( complete_all_tasks( - create_list(:board_grant_effectuation_task, 5, assigned_to: business_line) - ) + create_list(:board_grant_effectuation_task, 5, assigned_to: @business_line) + ), + @veteran, + @business_line ) - end - let!(:open_veteran_record_requests) do - add_veteran_and_request_issues_to_decision_reviews( - create_list(:veteran_record_request_task, 5, assigned_to: business_line) + @open_veteran_record_request = add_veteran_and_request_issues_to_decision_reviews( + create_list(:veteran_record_request_task, 5, assigned_to: @business_line), + @veteran, + @business_line ) - end - let!(:completed_veteran_record_requests) do - add_veteran_and_request_issues_to_decision_reviews( + @completed_veteran_record_requests = add_veteran_and_request_issues_to_decision_reviews( complete_all_tasks( - create_list(:veteran_record_request_task, 5, assigned_to: business_line) - ) + create_list(:veteran_record_request_task, 5, assigned_to: @business_line) + ), + @veteran, + @business_line ) end @@ -322,56 +319,256 @@ it "All completed tasks are included in results" do expect(subject.size).to eq 25 expect(subject.map(&:id)).to match_array( - (completed_hlr_tasks + - completed_sc_tasks + - completed_board_grant_effectuation_tasks + - completed_veteran_record_requests + - completed_remand_tasks + (@completed_hlr_tasks + + @completed_sc_tasks + + @completed_board_grant_effectuation_tasks + + @completed_veteran_record_requests + + @completed_remand_tasks ).pluck(:id) ) end end - end - describe ".pending_tasks" do - let!(:requestor) { create(:user) } - let!(:decider) { create(:user) } - let!(:hlr_pending_tasks) do - create_list(:issue_modification_request, - 3, - :with_higher_level_review, - status: "assigned", - requestor: requestor, - decider: decider) - end + context "With closed at filters" do + context "with a before filter" do + # Create some closed tasks that should match the before filter + let!(:tasks_for_closed_at_filter) do + tasks = add_veteran_and_request_issues_to_decision_reviews( + complete_all_tasks( + create_list(:supplemental_claim_task, 5, assigned_to: @business_line) + ), + @veteran, + @business_line + ) + tasks.each do |task| + task.closed_at = 5.days.ago + task.save + end + tasks + end - let!(:sc_pending_tasks) do - create_list(:issue_modification_request, - 3, - :with_supplemental_claim, - status: "assigned", - requestor: requestor, - decider: decider) - end + let(:task_filters) do + ["col=completedDateColumn&val=before,#{3.days.ago.strftime('%Y-%m-%d')},"] + end - let!(:extra_modification_request) do - create(:issue_modification_request, - :with_higher_level_review, - status: "assigned", - requestor: requestor, - decider: decider) - end + it "should filter the tasks for a date before the closed at date" do + expect(subject.size).to eq 5 + expect(subject.map(&:id)).to match_array(tasks_for_closed_at_filter.pluck(:id)) + end + end + + context "with an after filter" do + # Create some closed tasks that should not match the after filter + let!(:tasks_for_closed_at_filter) do + tasks = add_veteran_and_request_issues_to_decision_reviews( + complete_all_tasks( + create_list(:supplemental_claim_task, 5, assigned_to: @business_line) + ), + @veteran, + @business_line + ) + tasks.each do |task| + task.closed_at = 5.days.ago + task.save + end + tasks + end + + let(:task_filters) do + ["col=completedDateColumn&val=after,#{3.days.ago.strftime('%Y-%m-%d')},"] + end + + it "should filter the tasks for a date after the closed at date" do + expect(subject.size).to eq 25 + expect(subject.map(&:id)).to match_array( + (@completed_hlr_tasks + + @completed_sc_tasks + + @completed_board_grant_effectuation_tasks + + @completed_veteran_record_requests + + @completed_remand_tasks + ).pluck(:id) + ) + end + end + + context "with a between filter" do + # Create some closed tasks that should match the between filter + let!(:tasks_for_closed_at_filter) do + tasks = add_veteran_and_request_issues_to_decision_reviews( + complete_all_tasks( + create_list(:supplemental_claim_task, 3, assigned_to: @business_line) + ), + @veteran, + @business_line + ) + # Set two tasks to fit into the between range + tasks[0].closed_at = 5.days.ago + tasks[1].closed_at = 1.day.ago + tasks[2].closed_at = 8.days.ago + tasks[0].save + tasks[1].save + tasks[2].save + tasks + end + + let(:task_filters) do + start_date = 3.days.ago.strftime("%Y-%m-%d") + end_date = 10.days.ago.strftime("%Y-%m-%d") + ["col=completedDateColumn&val=between,#{start_date},#{end_date}"] + end + + it "should filter the tasks for a closed at date between two dates" do + expect(subject.size).to eq 2 + expect(subject.map(&:id)).to match_array( + [ + tasks_for_closed_at_filter[0].id, + tasks_for_closed_at_filter[2].id + ] + ) + end + end + + context "with last 7 days filter" do + # Create some closed tasks that should not match the last 7 days filter + let!(:tasks_for_closed_at_filter) do + tasks = add_veteran_and_request_issues_to_decision_reviews( + complete_all_tasks( + create_list(:supplemental_claim_task, 3, assigned_to: @business_line) + ), + @veteran, + @business_line + ) + tasks.each do |task| + task.closed_at = 10.days.ago + task.save + end + tasks + end + + let(:task_filters) do + ["col=completedDateColumn&val=last7,,"] + end + + it "should filter the tasks for a closed at in the last 7 days" do + expect(subject.size).to eq 25 + expect(subject.map(&:id)).to match_array( + (@completed_hlr_tasks + + @completed_sc_tasks + + @completed_board_grant_effectuation_tasks + + @completed_veteran_record_requests + + @completed_remand_tasks + ).pluck(:id) + ) + end + end + + context "with last 30 days filter" do + # Create some closed tasks that should match the last 30 days filter and one that does not + let!(:tasks_for_closed_at_filter) do + tasks = add_veteran_and_request_issues_to_decision_reviews( + complete_all_tasks( + create_list(:supplemental_claim_task, 3, assigned_to: @business_line) + ), + @veteran, + @business_line + ) + tasks.first(2) do |task| + task.closed_at = 10.days.ago + task.save + end + tasks.last.closed_at = 31.days.ago + tasks.last.save + tasks + end + + let(:task_filters) do + ["col=completedDateColumn&val=last30,,"] + end + + it "should filter the tasks for a closed at in the last 30 days" do + expect(subject.size).to eq 27 + expect(subject.map(&:id)).to match_array( + (@completed_hlr_tasks + + @completed_sc_tasks + + @completed_board_grant_effectuation_tasks + + @completed_veteran_record_requests + + @completed_remand_tasks + + tasks_for_closed_at_filter.first(2) + ).pluck(:id) + ) + end + end + + context "with last 365 days filter" do + # Create some closed tasks that should match the last 365 days filter and one that does not + let!(:tasks_for_closed_at_filter) do + tasks = add_veteran_and_request_issues_to_decision_reviews( + complete_all_tasks( + create_list(:supplemental_claim_task, 3, assigned_to: @business_line) + ), + @veteran, + @business_line + ) + tasks.first(2) do |task| + task.closed_at = 200.days.ago + task.save + end + tasks.last.closed_at = 400.days.ago + tasks.last.save + tasks + end - let(:extra_decision_review) do - extra_modification_request.decision_review + let(:task_filters) do + ["col=completedDateColumn&val=last365,,"] + end + + it "should filter the tasks for a closed at in the last 365 days" do + expect(subject.size).to eq 27 + expect(subject.map(&:id)).to match_array( + (@completed_hlr_tasks + + @completed_sc_tasks + + @completed_board_grant_effectuation_tasks + + @completed_veteran_record_requests + + @completed_remand_tasks + + tasks_for_closed_at_filter.first(2) + ).pluck(:id) + ) + end + end end + end - let!(:extra_modification_request2) do - create(:issue_modification_request, - status: "assigned", - requestor: requestor, - decider: decider, - decision_review: extra_decision_review) + describe ".pending_tasks" do + before(:all) do + @requestor = create(:user) + @decider = create(:user) + @hlr_pending_tasks = create_list(:issue_modification_request, + 3, + :with_higher_level_review, + status: "assigned", + requestor: @requestor, + decider: @decider) + + @sc_pending_tasks = create_list(:issue_modification_request, + 3, + :with_supplemental_claim, + status: "assigned", + requestor: @requestor, + decider: @decider) + + @extra_modification_request = create(:issue_modification_request, + :with_higher_level_review, + status: "assigned", + requestor: @requestor, + decider: @decider) + + @extra_decision_review = @extra_modification_request.decision_review + + @extra_modification_request2 = create(:issue_modification_request, + status: "assigned", + requestor: @requestor, + decider: @decider, + decision_review: @extra_decision_review) end subject { business_line.pending_tasks(filters: task_filters) } @@ -385,12 +582,12 @@ expect(subject.size).to eq(7) expect(subject.map(&:appeal_id)).to match_array( - (hlr_pending_tasks + sc_pending_tasks + [extra_modification_request]).pluck(:decision_review_id) + (@hlr_pending_tasks + @sc_pending_tasks + [@extra_modification_request]).pluck(:decision_review_id) ) # Verify the issue count and issue modfication count is correct for the extra task extra_task = subject.find do |task| - task.appeal_id == extra_modification_request.decision_review_id && + task.appeal_id == @extra_modification_request.decision_review_id && task.appeal_type == "HigherLevelReview" end expect(extra_task[:issue_count]).to eq(1) @@ -411,58 +608,53 @@ end describe ".in_progress_tasks" do - let(:current_time) { Time.zone.now } - let!(:hlr_tasks_on_active_decision_reviews) do - create_list(:higher_level_review_vha_task, 5, assigned_to: business_line) - end + before(:all) do + @current_time = Time.zone.now + # Use a different url and name since the let variable can't be used in before all setup + @business_line = create(:business_line, name: "NONCOMPORG2", url: "nco2") - let!(:sc_tasks_on_active_decision_reviews) do - create_list(:supplemental_claim_vha_task, 5, assigned_to: business_line) - end + @veteran = create(:veteran) - let!(:remand_tasks_on_active_decision_reviews) do - create_list(:remand_vha_task, 5, assigned_to: business_line) - end + @hlr_tasks_on_active_decision_reviews = + create_list(:higher_level_review_vha_task, 5, assigned_to: @business_line) - # Set some on hold tasks as well - let!(:on_hold_sc_tasks_on_active_decision_reviews) do - tasks = create_list(:supplemental_claim_vha_task, 5, assigned_to: business_line) - tasks.each(&:on_hold!) - tasks - end + @remand_tasks_on_active_decision_reviews = create_list(:remand_vha_task, 5, assigned_to: @business_line) - let!(:decision_review_tasks_on_inactive_decision_reviews) do - create_list(:higher_level_review_task, 5, assigned_to: business_line) - end + @sc_tasks_on_active_decision_reviews = + create_list(:supplemental_claim_vha_task, 5, assigned_to: @business_line) + + @on_hold_sc_tasks_on_active_decision_reviews = + create_list(:supplemental_claim_vha_task, 5, assigned_to: @business_line).each(&:on_hold!) - let!(:board_grant_effectuation_tasks) do - tasks = create_list(:board_grant_effectuation_task, 5, assigned_to: business_line) + @decision_review_tasks_on_inactive_decision_reviews = + create_list(:higher_level_review_task, 5, assigned_to: @business_line) - tasks.each do |task| + @board_grant_effectuation_tasks = + create_list(:board_grant_effectuation_task, 5, assigned_to: @business_line) + + @board_grant_effectuation_tasks.each do |task| create( :request_issue, :nonrating, decision_review: task.appeal, - benefit_type: business_line.url, - closed_at: current_time, + benefit_type: @business_line.url, + closed_at: @current_time, closed_status: "decided" ) end - tasks - end - - let!(:veteran_record_request_on_active_appeals) do - add_veteran_and_request_issues_to_decision_reviews( - create_list(:veteran_record_request_task, 5, assigned_to: business_line) - ) - end + @veteran_record_request_on_active_appeals = + add_veteran_and_request_issues_to_decision_reviews( + create_list(:veteran_record_request_task, 5, assigned_to: @business_line), + @veteran, + @business_line + ) - let!(:veteran_record_request_on_inactive_appeals) do - create_list(:veteran_record_request_task, 5, assigned_to: business_line) + @veteran_record_request_on_inactive_appeals = + create_list(:veteran_record_request_task, 5, assigned_to: @business_line) end - subject { business_line.in_progress_tasks(filters: task_filters) } + subject { @business_line.in_progress_tasks(filters: task_filters) } include_examples "task filtration" @@ -475,12 +667,12 @@ it "All tasks associated with active decision reviews and BoardGrantEffectuationTasks are included" do expect(subject.size).to eq 30 expect(subject.map(&:id)).to match_array( - (veteran_record_request_on_active_appeals + - board_grant_effectuation_tasks + - hlr_tasks_on_active_decision_reviews + - sc_tasks_on_active_decision_reviews + - on_hold_sc_tasks_on_active_decision_reviews + - remand_tasks_on_active_decision_reviews + (@veteran_record_request_on_active_appeals + + @board_grant_effectuation_tasks + + @hlr_tasks_on_active_decision_reviews + + @sc_tasks_on_active_decision_reviews + + @on_hold_sc_tasks_on_active_decision_reviews + + @remand_tasks_on_active_decision_reviews ).pluck(:id) ) end @@ -494,11 +686,11 @@ it "All tasks associated with active decision reviews are included, but not BoardGrantEffectuationTasks" do expect(subject.size).to eq 25 expect(subject.map(&:id)).to match_array( - (veteran_record_request_on_active_appeals + - hlr_tasks_on_active_decision_reviews + - sc_tasks_on_active_decision_reviews + - on_hold_sc_tasks_on_active_decision_reviews + - remand_tasks_on_active_decision_reviews + (@veteran_record_request_on_active_appeals + + @hlr_tasks_on_active_decision_reviews + + @sc_tasks_on_active_decision_reviews + + @on_hold_sc_tasks_on_active_decision_reviews + + @remand_tasks_on_active_decision_reviews ).pluck(:id) ) end @@ -508,59 +700,23 @@ describe ".change_history_rows" do let(:change_history_filters) { {} } - let!(:hlr_task) { create(:higher_level_review_vha_task_with_decision) } - let!(:hlr_task2) { create(:higher_level_review_vha_task) } - let!(:sc_task) do - create(:supplemental_claim_vha_task, - appeal: create(:supplemental_claim, - :with_vha_issue, - :with_intake, - benefit_type: "vha", - claimant_type: :dependent_claimant)) - end - let!(:hlr_task_with_imr) do - create(:issue_modification_request, - :with_higher_level_review, - :edit_of_request, - nonrating_issue_category: "Medical and Dental Care Reimbursement", - nonrating_issue_description: "Reimbursement note description") - end - - let!(:sc_task_with_imr) do - create(:issue_modification_request, - :with_supplemental_claim, - :edit_of_request, - nonrating_issue_category: "Medical and Dental Care Reimbursement", - nonrating_issue_description: "Reimbursement note description") - end - - let!(:remand_task) do - create(:remand_vha_task, - appeal: create(:remand, - benefit_type: "vha", - claimant_type: :dependent_claimant)) - end - - let(:decision_issue) { create(:decision_issue, disposition: "denied", benefit_type: hlr_task.appeal.benefit_type) } - let(:intake_user) { create(:user, full_name: "Alexander Dewitt", css_id: "ALEXVHA", station_id: "103") } - let(:decision_user) { create(:user, full_name: "Gaius Baelsar", css_id: "GAIUSVHA", station_id: "104") } # Reusable expectations let(:hlr_task_1_ri_1_expectation) do a_hash_including( "nonrating_issue_category" => "Caregiver | Other", "nonrating_issue_description" => "VHA - Caregiver", - "task_id" => hlr_task.id, - "veteran_file_number" => hlr_task.appeal.veteran_file_number, - "intake_user_name" => hlr_task.appeal.intake.user.full_name, - "intake_user_css_id" => hlr_task.appeal.intake.user.css_id, - "intake_user_station_id" => hlr_task.appeal.intake.user.station_id, + "task_id" => @hlr_task.id, + "veteran_file_number" => @hlr_task.appeal.veteran_file_number, + "intake_user_name" => @hlr_task.appeal.intake.user.full_name, + "intake_user_css_id" => @hlr_task.appeal.intake.user.css_id, + "intake_user_station_id" => @hlr_task.appeal.intake.user.station_id, "disposition" => "Granted", - "decision_user_name" => decision_user.full_name, - "decision_user_css_id" => decision_user.css_id, - "decision_user_station_id" => decision_user.station_id, - "claimant_name" => hlr_task.appeal.claimant.name, - "task_status" => hlr_task.status, + "decision_user_name" => @decision_user.full_name, + "decision_user_css_id" => @decision_user.css_id, + "decision_user_station_id" => @decision_user.station_id, + "claimant_name" => @hlr_task.appeal.claimant.name, + "task_status" => @hlr_task.status, "request_issue_benefit_type" => "vha", "days_waiting" => 10 ) @@ -569,17 +725,17 @@ a_hash_including( "nonrating_issue_category" => "CHAMPVA", "nonrating_issue_description" => "This is a CHAMPVA issue", - "task_id" => hlr_task.id, - "veteran_file_number" => hlr_task.appeal.veteran_file_number, - "intake_user_name" => hlr_task.appeal.intake.user.full_name, - "intake_user_css_id" => hlr_task.appeal.intake.user.css_id, - "intake_user_station_id" => hlr_task.appeal.intake.user.station_id, + "task_id" => @hlr_task.id, + "veteran_file_number" => @hlr_task.appeal.veteran_file_number, + "intake_user_name" => @hlr_task.appeal.intake.user.full_name, + "intake_user_css_id" => @hlr_task.appeal.intake.user.css_id, + "intake_user_station_id" => @hlr_task.appeal.intake.user.station_id, "disposition" => "denied", - "decision_user_name" => decision_user.full_name, - "decision_user_css_id" => decision_user.css_id, - "decision_user_station_id" => decision_user.station_id, - "claimant_name" => hlr_task.appeal.claimant.name, - "task_status" => hlr_task.status, + "decision_user_name" => @decision_user.full_name, + "decision_user_css_id" => @decision_user.css_id, + "decision_user_station_id" => @decision_user.station_id, + "claimant_name" => @hlr_task.appeal.claimant.name, + "task_status" => @hlr_task.status, "request_issue_benefit_type" => "vha", "days_waiting" => 10 ) @@ -588,17 +744,17 @@ a_hash_including( "nonrating_issue_category" => "Caregiver | Other", "nonrating_issue_description" => "VHA - Caregiver", - "task_id" => hlr_task2.id, - "veteran_file_number" => hlr_task2.appeal.veteran_file_number, - "intake_user_name" => intake_user.full_name, - "intake_user_css_id" => intake_user.css_id, - "intake_user_station_id" => intake_user.station_id, + "task_id" => @hlr_task2.id, + "veteran_file_number" => @hlr_task2.appeal.veteran_file_number, + "intake_user_name" => @intake_user.full_name, + "intake_user_css_id" => @intake_user.css_id, + "intake_user_station_id" => @intake_user.station_id, "disposition" => nil, "decision_user_name" => nil, "decision_user_css_id" => nil, "decision_user_station_id" => nil, - "claimant_name" => hlr_task2.appeal.claimant.name, - "task_status" => hlr_task2.status, + "claimant_name" => @hlr_task2.appeal.claimant.name, + "task_status" => @hlr_task2.status, "request_issue_benefit_type" => "vha", "days_waiting" => 5 ) @@ -607,17 +763,17 @@ a_hash_including( "nonrating_issue_category" => "Camp Lejune Family Member", "nonrating_issue_description" => "This is a Camp Lejune issue", - "task_id" => hlr_task2.id, - "veteran_file_number" => hlr_task2.appeal.veteran_file_number, - "intake_user_name" => intake_user.full_name, - "intake_user_css_id" => intake_user.css_id, - "intake_user_station_id" => intake_user.station_id, + "task_id" => @hlr_task2.id, + "veteran_file_number" => @hlr_task2.appeal.veteran_file_number, + "intake_user_name" => @intake_user.full_name, + "intake_user_css_id" => @intake_user.css_id, + "intake_user_station_id" => @intake_user.station_id, "disposition" => nil, "decision_user_name" => nil, "decision_user_css_id" => nil, "decision_user_station_id" => nil, - "claimant_name" => hlr_task2.appeal.claimant.name, - "task_status" => hlr_task2.status, + "claimant_name" => @hlr_task2.appeal.claimant.name, + "task_status" => @hlr_task2.status, "request_issue_benefit_type" => "vha", "days_waiting" => 5 ) @@ -626,19 +782,19 @@ a_hash_including( "nonrating_issue_category" => "Beneficiary Travel", "nonrating_issue_description" => "VHA issue description ", - "task_id" => sc_task.id, - "veteran_file_number" => sc_task.appeal.veteran_file_number, - "intake_user_name" => sc_task.appeal.intake.user.full_name, - "intake_user_css_id" => sc_task.appeal.intake.user.css_id, - "intake_user_station_id" => sc_task.appeal.intake.user.station_id, + "task_id" => @sc_task.id, + "veteran_file_number" => @sc_task.appeal.veteran_file_number, + "intake_user_name" => @sc_task.appeal.intake.user.full_name, + "intake_user_css_id" => @sc_task.appeal.intake.user.css_id, + "intake_user_station_id" => @sc_task.appeal.intake.user.station_id, "disposition" => nil, "decision_user_name" => nil, "decision_user_css_id" => nil, "decision_user_station_id" => nil, - "claimant_name" => sc_task.appeal.claimant.name, - "task_status" => sc_task.status, + "claimant_name" => @sc_task.appeal.claimant.name, + "task_status" => @sc_task.status, "request_issue_benefit_type" => "vha", - "days_waiting" => (Time.zone.today - Date.parse(sc_task.assigned_at.iso8601)).to_i + "days_waiting" => (Time.zone.today - Date.parse(@sc_task.assigned_at.iso8601)).to_i ) end let(:imr_hlr_expectation) do @@ -668,8 +824,8 @@ a_hash_including( "nonrating_issue_category" => "Clothing Allowance", "nonrating_issue_description" => "This is a Clothing Allowance issue", - "task_id" => remand_task.id, - "veteran_file_number" => remand_task.appeal.veteran_file_number, + "task_id" => @remand_task.id, + "veteran_file_number" => @remand_task.appeal.veteran_file_number, "intake_user_name" => nil, "intake_user_css_id" => nil, "intake_user_station_id" => nil, @@ -677,10 +833,10 @@ "decision_user_name" => nil, "decision_user_css_id" => nil, "decision_user_station_id" => nil, - "claimant_name" => remand_task.appeal.claimant.name, - "task_status" => remand_task.status, + "claimant_name" => @remand_task.appeal.claimant.name, + "task_status" => @remand_task.status, "request_issue_benefit_type" => "vha", - "days_waiting" => (Time.zone.today - Date.parse(remand_task.assigned_at.iso8601)).to_i + "days_waiting" => (Time.zone.today - Date.parse(@remand_task.assigned_at.iso8601)).to_i ) end @@ -695,7 +851,34 @@ ] end - before do + before(:all) do + # Make sure the previous data from the before alls is cleaned up. + Task.delete_all + + @hlr_task = create(:higher_level_review_vha_task_with_decision) + @hlr_task2 = create(:higher_level_review_vha_task) + @sc_task = create(:supplemental_claim_vha_task, appeal: create(:supplemental_claim, + :with_vha_issue, + :with_intake, + benefit_type: "vha", + claimant_type: :dependent_claimant)) + @remand_task = create(:remand_vha_task, + appeal: create(:remand, benefit_type: "vha", claimant_type: :dependent_claimant)) + @hlr_task_with_imr = create(:issue_modification_request, + :with_higher_level_review, + :edit_of_request, + nonrating_issue_category: "Medical and Dental Care Reimbursement", + nonrating_issue_description: "Reimbursement note description") + @sc_task_with_imr = create(:issue_modification_request, + :with_supplemental_claim, + :edit_of_request, + nonrating_issue_category: "Medical and Dental Care Reimbursement", + nonrating_issue_description: "Reimbursement note description") + + @decision_issue = create(:decision_issue, disposition: "denied", benefit_type: @hlr_task.appeal.benefit_type) + @intake_user = create(:user, full_name: "Alexander Dewitt", css_id: "ALEXVHA", station_id: "103") + @decision_user = create(:user, full_name: "Gaius Baelsar", css_id: "GAIUSVHA", station_id: "104") + issue = create(:request_issue, nonrating_issue_category: "CHAMPVA", nonrating_issue_description: "This is a CHAMPVA issue", @@ -704,42 +887,38 @@ nonrating_issue_category: "Camp Lejune Family Member", nonrating_issue_description: "This is a Camp Lejune issue", benefit_type: "vha") - remand_issue = create(:request_issue, - nonrating_issue_category: "Clothing Allowance", - nonrating_issue_description: "This is a Clothing Allowance issue", - benefit_type: "vha", - decision_review: remand_task.appeal) - hlr_task.appeal.request_issues << issue - hlr_task2.appeal.request_issues << issue2 - remand_task.appeal.request_issues << remand_issue - remand_task.save - remand_task.reload + @hlr_task.appeal.request_issues << issue + @hlr_task2.appeal.request_issues << issue2 + # Create a request issue for the remand task + create(:request_issue, + nonrating_issue_category: "Clothing Allowance", + nonrating_issue_description: "This is a Clothing Allowance issue", + benefit_type: "vha", + decision_review: @remand_task.appeal) # Add a different intake user to the second hlr task for data differences - second_intake = hlr_task2.appeal.intake - second_intake.user = intake_user + second_intake = @hlr_task2.appeal.intake + second_intake.user = @intake_user second_intake.save # Add a couple of dispostions one here and one through the factory, to the first hlr task - decision_issue.request_issues << issue - hlr_task.appeal.decision_issues << decision_issue - hlr_task.appeal.save + @decision_issue.request_issues << issue + @hlr_task.appeal.decision_issues << @decision_issue + @hlr_task.appeal.save # Set the assigned at for days waiting filtering for hlr_task2 - hlr_task2.assigned_at = 5.days.ago - hlr_task2.save + @hlr_task2.assigned_at = 5.days.ago + @hlr_task2.save # Set up assigned at for days waiting filtering for hlr_task1 PaperTrail.request(enabled: false) do - # This uses the task versions whodunnit field now instead of completed by - # hlr_task.completed_by = decision_user - hlr_task.assigned_at = 10.days.ago - hlr_task.save + @hlr_task.assigned_at = 10.days.ago + @hlr_task.save end # Set the whodunnnit of the completed version status to the decision user - version = hlr_task.versions.first - version.whodunnit = decision_user.id.to_s + version = @hlr_task.versions.first + version.whodunnit = @decision_user.id.to_s version.save end @@ -754,7 +933,7 @@ context "with task_id filter" do context "with multiple task ids" do - let(:change_history_filters) { { task_id: [hlr_task.id, sc_task.id, remand_task.id] } } + let(:change_history_filters) { { task_id: [@hlr_task.id, @sc_task.id, @remand_task.id] } } it "should return rows for all matching ids" do expect(subject.entries.count).to eq(4) @@ -767,7 +946,7 @@ end end - let(:change_history_filters) { { task_id: hlr_task.id } } + let(:change_history_filters) { { task_id: @hlr_task.id } } it "should only return rows for that task" do expect(subject.entries.count).to eq(2) @@ -1037,7 +1216,7 @@ end context "when filtering by multiple user css ids" do - let(:change_history_filters) { { personnel: [intake_user.css_id, decision_user.css_id] } } + let(:change_history_filters) { { personnel: [@intake_user.css_id, @decision_user.css_id] } } it "only return rows where either an intake, decisions, or updates user matches the css_ids" do expect(subject.entries.count).to eq(4) @@ -1048,7 +1227,7 @@ end context "when filtering by a single css id" do - let(:change_history_filters) { { personnel: [intake_user.css_id] } } + let(:change_history_filters) { { personnel: [@intake_user.css_id] } } it "only return rows where either an intake, decisions, or updates user matches the user css id" do expect(subject.entries.count).to eq(2) @@ -1062,7 +1241,7 @@ context "when filtering by multiple filters at the same time" do context "task_id and issue_type" do - let(:change_history_filters) { { issue_types: ["Caregiver | Other"], task_id: hlr_task.id } } + let(:change_history_filters) { { issue_types: ["Caregiver | Other"], task_id: @hlr_task.id } } it "should only return rows that match both filters" do expect(subject.entries.count).to eq(1) @@ -1094,7 +1273,7 @@ end end - def add_veteran_and_request_issues_to_decision_reviews(tasks) + def add_veteran_and_request_issues_to_decision_reviews(tasks, veteran, business_line) tasks.each do |task| task.appeal.update!(veteran_file_number: veteran.file_number) rand(1..4).times do diff --git a/spec/models/hearings/transcription_contractor_spec.rb b/spec/models/hearings/transcription_contractor_spec.rb index d9e5c3d5940..992eb14a736 100644 --- a/spec/models/hearings/transcription_contractor_spec.rb +++ b/spec/models/hearings/transcription_contractor_spec.rb @@ -5,6 +5,7 @@ RSpec.describe TranscriptionContractor, type: :model do let!(:transcription_contractor_1) { create(:transcription_contractor, name: "The Ravens Group, Inc.") } let!(:transcription_contractor_2) { create(:transcription_contractor, name: "Genesis Government Solutions, Inc.") } + let!(:transcription_contractor_3) { create(:transcription_contractor, name: "Vet Reporting") } let!(:transcription_1) { create(:transcription, transcription_contractor_id: transcription_contractor_1.id) } let!(:transcription_2) { create(:transcription, transcription_contractor_id: transcription_contractor_1.id) } @@ -24,7 +25,7 @@ describe ".all_contractors" do it "returns all contractors ordered alphabetically" do expect(described_class.all_contractors).to eq( - [transcription_contractor_2, transcription_contractor_1] + [transcription_contractor_2, transcription_contractor_1, transcription_contractor_3] ) end end diff --git a/spec/models/hearings/transcription_contractors_model_spec.rb b/spec/models/hearings/transcription_contractors_model_spec.rb index e669118ea97..f2e2a04e9fd 100644 --- a/spec/models/hearings/transcription_contractors_model_spec.rb +++ b/spec/models/hearings/transcription_contractors_model_spec.rb @@ -5,8 +5,8 @@ RSpec.describe TranscriptionContractor, type: :model do before do @transcription_contractor = TranscriptionContractor.new( - name: "Genesis Government Solutions, Inc.", - directory: "BVA Hearing Transcripts/Genesis Government Solutions, Inc.", + name: "Vet Reporting", + directory: "BVA Hearing Transcripts/Vet Reporting", poc: "Example POC", phone: "888-888-8888", email: "test_email@bah.com" diff --git a/spec/models/vha_business_line_spec.rb b/spec/models/vha_business_line_spec.rb index ec19cd33756..bb14aec399f 100644 --- a/spec/models/vha_business_line_spec.rb +++ b/spec/models/vha_business_line_spec.rb @@ -22,7 +22,7 @@ expect(subject.tasks_query_type).to eq( incomplete: "on_hold", in_progress: "active", - completed: "recently_completed", + completed: "completed", pending: "active" ) end diff --git a/spec/services/business_line_reporter_spec.rb b/spec/services/business_line_reporter_spec.rb index 1a5604e3501..b3cd2aeb26d 100644 --- a/spec/services/business_line_reporter_spec.rb +++ b/spec/services/business_line_reporter_spec.rb @@ -4,6 +4,7 @@ describe "BusinessLineReporter" do let(:business_line) { create(:business_line) } + let(:filters) {} let(:first_appeal) { create(:appeal, :with_post_intake_tasks) } let(:first_ama_task) { create(:ama_task, appeal: first_appeal, assigned_to: business_line) } @@ -39,7 +40,7 @@ end describe "#tasks" do - subject { BusinessLineReporter.new(business_line).tasks } + subject { BusinessLineReporter.new(business_line, filters).tasks } it "returns the completed tasks" do expect(subject).to include(first_ama_task, second_ama_task, remand_task, hlr_task, sc_task) @@ -48,6 +49,24 @@ it "does not return an open task" do expect(subject).to_not include(third_ama_task) end + + context "vha_business_line" do + let(:mocked_business_line) { double(VhaBusinessLine) } + before do + allow(mocked_business_line).to receive(:is_a?).with(VhaBusinessLine).and_return(true) + allow(mocked_business_line).to receive(:completed_tasks).and_return(VhaBusinessLine.none) + end + + context "with filtering" do + let(:filters) { { my_filters: { test1: :test2 } } } + it "should use the business line model completed tasks method for filtering" do + expect(mocked_business_line).to receive(:completed_tasks).with({ filters: filters, + sort_by: :id, + sort_order: :asc }) + BusinessLineReporter.new(mocked_business_line, filters).tasks + end + end + end end describe "#as_csv" do diff --git a/spec/support/download_helper.rb b/spec/support/download_helper.rb index 0fe587db62f..33ce8f63bac 100644 --- a/spec/support/download_helper.rb +++ b/spec/support/download_helper.rb @@ -35,7 +35,7 @@ def downloaded? end def downloading? - downloads.grep(/\.part$/).any? + downloads.grep(/\.(part|crdownload|download)$/).any? end def clear_downloads