From 8618595898f637d2c37781e19b7713262942e8c9 Mon Sep 17 00:00:00 2001 From: YUE YU Date: Tue, 27 Aug 2024 09:19:32 +0800 Subject: [PATCH] Validation assigned to other reviewer --- relis_app/controllers/Screening.php | 186 +++++++++++++++--- relis_app/models/Screening_dataAccess.php | 8 + .../assign_papers_screen_validation.php | 8 +- 3 files changed, 174 insertions(+), 28 deletions(-) diff --git a/relis_app/controllers/Screening.php b/relis_app/controllers/Screening.php index 4be5b61..e5e7f43 100644 --- a/relis_app/controllers/Screening.php +++ b/relis_app/controllers/Screening.php @@ -2104,6 +2104,14 @@ public function validate_screen_set($data = array()) } } // print_test($users); + if (get_appconfig_element('assign_to_non_screened_validator_on')){ + // Get assignable papers + $user_papers_map = array(); + foreach ($_assign_user as $user_id => $user_name) { + $user_papers_map[$user_id] = $this->get_assignable_papers($user_id, $screening_phase_id, $papers['to_assign']); + } + $data['user_papers_map'] = $user_papers_map; + } $data['users'] = $_assign_user; $data['number_papers'] = count($papers['to_assign']); $data['number_papers_assigned'] = count($papers['assigned']); @@ -2123,6 +2131,22 @@ public function validate_screen_set($data = array()) $this->load->view('shared/body', $data); } + function get_assignable_papers($user_id, $screen_phase_id, $papers) { + // Gets a list of papers that the user has screened + $screened_papers = $this->Screening_dataAccess->get_user_screened_papers($user_id, $screen_phase_id); + $screened_paper_ids = array_column($screened_papers, 'paper_id'); + + // Filter out papers that the user has not screened + $assignable_papers = array(); + foreach ($papers as $paper) { + if (!in_array($paper['id'], $screened_paper_ids)) { + $assignable_papers[] = $paper; + } + } + + return $assignable_papers; + } + public function get_papers_by_criteria($data = array()) { header('Content-Type: application/json'); $validation_by_criteria = $this->input->post('validation_by_criteria'); @@ -2288,6 +2312,7 @@ function save_assign_screen_validation() $papers_sources = $post_arr['papers_sources']; $paper_source_status = $post_arr['paper_source_status']; $screening_phase_info = active_screening_phase_info(); + $screen_phase_id = $screening_phase_info['screen_phase_id']; $phase_title = $screening_phase_info['phase_title']; $reviews_per_paper = 1; if ($validation_by_exclusion_criteria_toggle == 'on'){ @@ -2303,39 +2328,148 @@ function save_assign_screen_validation() $papers = $papers_all['to_assign']; } $papers_to_validate_nbr = round(count($papers) * $percentage / 100); + if ($papers_to_validate_nbr <= 0) { + $data['err_msg'] = " No papers selected for assignment. Please increase the percentage of papers to be assigned."; + $this->validate_screen_set($data); + return; + } $operation_description = "Assign $percentage % ($papers_to_validate_nbr) of " . $paper_source_status . " papers for $phase_title"; // print_test($papers); shuffle($papers); // randomize the list $assign_papers = array(); $this->db2 = $this->load->database(project_db(), TRUE); $operation_code = active_user_id() . "_" . time(); - foreach ($papers as $key => $value) { - if ($key < $papers_to_validate_nbr) { - $assign_papers[$key]['paper'] = $value['id']; - $assign_papers[$key]['users'] = array(); - $assignment_save = array( - 'paper_id' => $value['id'], - 'user_id' => '', - 'assignment_note' => '', - 'assignment_type' => screening_validator_assignment_type(), - 'operation_code' => $operation_code, - 'assignment_mode' => 'auto', - 'assignment_role' => 'Validation', - 'screening_phase' => $currect_screening_phase, - 'assigned_by' => $this->session->userdata('user_id') - ); - $j = 1; - //the table to save assignments + if (get_appconfig_element('assign_to_non_screened_validator_on')){ + // Get assignable papers for each user + $user_papers_map = array(); + foreach ($users as $user) { + $user_papers_map[$user] = $this->get_assignable_papers($user, $screen_phase_id, $papers); + + } + + // Sort users by the number of assignable papers from low to high + uasort($user_papers_map, function($a, $b) { + return count($a) > count($b); + }); + + // Get all assignable papers + $all_assignable_papers = array(); + foreach ($user_papers_map as $user_papers) { + foreach ($user_papers as $paper) { + $all_assignable_papers[$paper['id']] = $paper; + } + } + $all_assignable_papers = array_values($all_assignable_papers); + +// print_test('papers_to_validate_nbr: '.$papers_to_validate_nbr); + + if (count($all_assignable_papers) < $papers_to_validate_nbr) { + $data['err_msg'] = " Selected users cannot be assigned the required number of papers. Please select more users or reduce the percentage of papers to be assigned."; + $this->validate_screen_set($data); + return; + } + + // The number of papers each user has been assigned + $assigned_papers = array(); + foreach ($users as $user) { + $assigned_papers[$user] = 0; + } + + foreach ($all_assignable_papers as $paper) { + // Get validators who can be assigned this paper + $eligible_users = array(); + foreach ($user_papers_map as $user => $user_papers) { + if (in_array($paper, $user_papers)) { + if (!isset($assign_papers[$user])) { + $assign_papers[$user] = []; + } + $eligible_users[$user] = count($assign_papers[$user]); + } + } + + // Sort in ascending order according to the number of papers assigned + asort($eligible_users); + + $final_user = null; + foreach ($eligible_users as $user => $assigned_count) { + if (is_null($final_user)) { + $final_user = $user; + } elseif ($assigned_count == $assigned_papers[$final_user]) { + // If the number of assigned papers is the same, select validators with fewer papers to be assigned + if (count($user_papers_map[$user]) < count($user_papers_map[$final_user])) { + $final_user = $user; + } + } else { + break; + } + } + + $assign_papers[$final_user][] = $paper; // papers assigned under best average + $assigned_papers[$final_user]++; // number of papers assigned + + } + + // Assign papers as expected number + for ($i = 0, $j =0; $j < $papers_to_validate_nbr; $i++){ + foreach ($users as $user){ + if ($j >= $papers_to_validate_nbr){ + break; + } + if ($assigned_papers[$user] > 0) { + $assignments_to_save[] = array( + 'paper_id' => $assign_papers[$user][$i]['id'], + 'user_id' => $user, + 'assignment_note' => '', + 'assignment_type' => screening_validator_assignment_type(), + 'operation_code' => $operation_code, + 'assignment_mode' => 'auto', + 'assignment_role' => 'Validation', + 'screening_phase' => $currect_screening_phase, + 'assigned_by' => $this->session->userdata('user_id') + ); + $assigned_papers[$user]--; + $j++; + } + } + } + +// print_test($assignments_to_save);exit(); + + if (!empty($assignments_to_save)) { $table_name = get_table_configuration('screening', 'current', 'table_name'); - while ($j <= $reviews_per_paper) { - $temp_user = ($key % count($users)) + $j; - if ($temp_user >= count($users)) - $temp_user = $temp_user - count($users); - array_push($assign_papers[$key]['users'], $users[$temp_user]); - $assignment_save['user_id'] = $users[$temp_user]; - //print_test($assignment_save); - $this->db2->insert($table_name, $assignment_save); - $j++; + $this->db2->insert_batch($table_name, $assignments_to_save); + } + + } + else { + foreach ($papers as $key => $value) { + if ($key < $papers_to_validate_nbr) { + $assign_papers[$key]['paper'] = $value['id']; + $assign_papers[$key]['users'] = array(); + $assignment_save = array( + 'paper_id' => $value['id'], + 'user_id' => '', + 'assignment_note' => '', + 'assignment_type' => screening_validator_assignment_type(), + 'operation_code' => $operation_code, + 'assignment_mode' => 'auto', + 'assignment_role' => 'Validation', + 'screening_phase' => $currect_screening_phase, + 'assigned_by' => $this->session->userdata('user_id') + ); + $j = 1; + //the table to save assignments + $table_name = get_table_configuration('screening', 'current', 'table_name'); + while ($j <= $reviews_per_paper) { + $temp_user = ($key % count($users)) + $j; + if ($temp_user >= count($users)) + $temp_user = $temp_user - count($users); + array_push($assign_papers[$key]['users'], $users[$temp_user]); + $assignment_save['user_id'] = $users[$temp_user]; + //print_test($assignment_save); + $this->db2->insert($table_name, $assignment_save); + $j++; + } } } } diff --git a/relis_app/models/Screening_dataAccess.php b/relis_app/models/Screening_dataAccess.php index 89bf9c0..e2c359a 100755 --- a/relis_app/models/Screening_dataAccess.php +++ b/relis_app/models/Screening_dataAccess.php @@ -81,6 +81,14 @@ function select_screening_paper_by_criteria($source_status, $exclusion_criteria_ return $all_papers; } + function get_user_screened_papers($user_id, $screening_phase) { + $sql = "SELECT paper_id FROM screening_paper WHERE assignment_role='Screening' AND screening_phase = $screening_phase AND screening_status='Done' AND screening_active=1 + AND user_id = ? AND screening_phase = ? "; + + $user_screenings = $this->db_current->query($sql, array($user_id, $screening_phase))->result_array(); + return $user_screenings; + } + function get_all_screenings($screening_phase) { $sql = "select * from screening_paper where assignment_role='Screening' AND screening_phase = $screening_phase AND screening_status='Done' AND screening_active=1 "; diff --git a/relis_app/views/screening/assign_papers_screen_validation.php b/relis_app/views/screening/assign_papers_screen_validation.php index 57d11b0..4a4028b 100755 --- a/relis_app/views/screening/assign_papers_screen_validation.php +++ b/relis_app/views/screening/assign_papers_screen_validation.php @@ -64,8 +64,12 @@ echo '

Select validator(s)

'; $i=1; foreach ($users as $user_id => $user_name) { - echo checkbox_form_bm($user_name,'user_'.$i,'user_'.$user_id,$user_id); - $i++; + if (get_appconfig_element('assign_to_non_screened_validator_on')){ + echo checkbox_form_bm($user_name.' (papers available to assign: ' . count($user_papers_map[$user_id]) . ')','user_'.$i,'user_'.$user_id,$user_id); + }else { + echo checkbox_form_bm($user_name, 'user_' . $i, 'user_' . $user_id, $user_id); + } + $i++; }