/** * Process clinic rules via a batching method to improve performance and decrease memory overhead. * * Test the clinic rules of entire clinic and create a report or patient reminders (can also test * on one patient or patients of one provider). The structure of the returned results is dependent on the * $organize_mode and $mode parameters. * <pre>The results are dependent on the $organize_mode parameter settings * 'default' organize_mode: * Returns a two-dimensional array of results organized by rules (dependent on the following $mode settings): * 'reminders-due' mode - returns an array of reminders (action array elements plus a 'pid' and 'due_status') * 'reminders-all' mode - returns an array of reminders (action array elements plus a 'pid' and 'due_status') * 'report' mode - returns an array of rows for the Clinical Quality Measures (CQM) report * 'plans' organize_mode: * Returns similar to default, but organizes by the active plans * </pre> * * @param integer $provider id of a selected provider. If blank, then will test entire clinic. If 'collate_outer' or 'collate_inner', then will test each provider in entire clinic; outer will nest plans inside collated providers, while inner will nest the providers inside the plans (note inner and outer are only different if organize_mode is set to plans). * @param string $type rule filter (active_alert,passive_alert,cqm,amc,patient_reminder). If blank then will test all rules. * @param string/array $dateTarget target date (format Y-m-d H:i:s). If blank then will test with current date as target. If an array, then is holding two dates ('dateBegin' and 'dateTarget'). * @param string $mode choose either 'report' or 'reminders-all' or 'reminders-due' (required) * @param string $plan test for specific plan only * @param string $organize_mode Way to organize the results (default, plans). See above for organization structure of the results. * @param array $options can hold various option (for now, used to hold the manual number of labs for the AMC report) * @param string $pat_prov_rel How to choose patients that are related to a chosen provider. 'primary' selects patients that the provider is set as primary provider. 'encounter' selectes patients that the provider has seen. This parameter is only applicable if the $provider parameter is set to a provider or collation setting. * @param integer $batchSize number of patients to batch (default is 100; plan to optimize this default setting in the future) * @param integer $report_id id of report in database (if already bookmarked) * @return array See above for organization structure of the results. */ function test_rules_clinic_batch_method($provider = '', $type = '', $dateTarget = '', $mode = '', $plan = '', $organize_mode = 'default', $options = array(), $pat_prov_rel = 'primary', $batchSize = '', $report_id = NULL) { // Default to a batchsize, if empty if (empty($batchSize)) { $batchSize = 100; } // Collect total number of pertinent patients (to calculate batching parameters) $totalNumPatients = buildPatientArray('', $provider, $pat_prov_rel, NULL, NULL, TRUE); // Cycle through the batches and collect/combine results if ($totalNumPatients % $batchSize > 0) { // not perfectly divisible $totalNumberBatches = floor($totalNumPatients / $batchSize) + 1; } else { // perfectly divisible $totalNumberBatches = floor($totalNumPatients / $batchSize); } // Fix things in the $options array(). This now stores the number of labs to be used in the denominator in the AMC report. // The problem with this variable is that is is added in every batch. So need to fix it by dividing this number by the number // of planned batches(note the fixed array will go into the test_rules_clinic function, however the original will be used // in the report storing/tracking engine. $options_modified = $options; if (!empty($options_modified['labs_manual'])) { $options_modified['labs_manual'] = $options_modified['labs_manual'] / $totalNumberBatches; } // Prepare the database to track/store results $fields = array('provider' => $provider, 'mode' => $mode, 'plan' => $plan, 'organize_mode' => $organize_mode, 'pat_prov_rel' => $pat_prov_rel); if (is_array($dateTarget)) { $fields = array_merge($fields, array(date_target => $dateTarget['dateTarget'])); $fields = array_merge($fields, array(date_begin => $dateTarget['dateBegin'])); } else { if (empty($dateTarget)) { $fields = array_merge($fields, array(date_target => date("Y-m-d H:i:s"))); } else { $fields = array_merge($fields, array(date_target => $dateTarget)); } } if (!empty($options)) { foreach ($options as $key => $value) { $fields = array_merge($fields, array($key => $value)); } } $report_id = beginReportDatabase($type, $fields, $report_id); setTotalItemsReportDatabase($report_id, $totalNumPatients); for ($i = 0; $i < $totalNumberBatches; $i++) { $dataSheet_batch = test_rules_clinic($provider, $type, $dateTarget, $mode, '', $plan, $organize_mode, $options_modified, $pat_prov_rel, $batchSize * $i + 1, $batchSize); if ($i == 0) { // For first cycle, simply copy it to dataSheet $dataSheet = $dataSheet_batch; } else { //debug //error_log("CDR: ".print_r($dataSheet,TRUE),0); //error_log("CDR: ".($batchSize*$i)." records",0); // Integrate batch results into main dataSheet foreach ($dataSheet_batch as $key => $row) { if (!$row['is_sub']) { //skip this stuff for the sub entries (and use previous main entry in percentage calculation) $total_patients = $dataSheet[$key]['total_patients'] + $row['total_patients']; $dataSheet[$key]['total_patients'] = $total_patients; $excluded = $dataSheet[$key]['excluded'] + $row['excluded']; $dataSheet[$key]['excluded'] = $excluded; $pass_filter = $dataSheet[$key]['pass_filter'] + $row['pass_filter']; $dataSheet[$key]['pass_filter'] = $pass_filter; } $pass_target = $dataSheet[$key]['pass_target'] + $row['pass_target']; $dataSheet[$key]['pass_target'] = $pass_target; $dataSheet[$key]['percentage'] = calculate_percentage($pass_filter, $excluded, $pass_target); } } //Update database to track results updateReportDatabase($report_id, $total_patients); } // Record results in database and send to screen, if applicable. finishReportDatabase($report_id, json_encode($dataSheet)); return $dataSheet; }
/** * Function to update reminders via a batching method to improve performance and decrease memory overhead. * * Function that updates reminders and returns an array with a specific data structure. * <pre>The data structure of the return array includes the following elements * 'total_active_actions' - Number of active actions. * 'total_pre_active_reminders' - Number of active reminders before processing. * 'total_pre_unsent_reminders' - Number of unsent reminders before processing. * 'total_post_active_reminders' - Number of active reminders after processing. * 'total_post_unsent_reminders' - Number of unsent reminders after processing. * 'number_new_reminders' - Number of new reminders * 'number_updated_reminders' - Number of updated reminders (due_status change) * 'number_inactivated_reminders' - Number of inactivated reminders. * 'number_unchanged_reminders' - Number of unchanged reminders. * </pre> * * @param string $dateTarget target date (format Y-m-d H:i:s). If blank then will test with current date as target. * @param integer $batchSize number of patients to batch (default is 25; plan to optimize this default setting in the future) * @param integer $report_id id of report in database (if already bookmarked) * @param boolean $also_send if TRUE, then will also call send_reminder when done * @return array see above for data structure of returned array */ function update_reminders_batch_method($dateTarget = '', $batchSize = 25, $report_id = NULL, $also_send = FALSE) { // Default to a batchsize, if empty if (empty($batchSize)) { $batchSize = 25; } // Collect total number of pertinent patients (to calculate batching parameters) $totalNumPatients = buildPatientArray('', '', '', NULL, NULL, TRUE); // Cycle through the batches and collect/combine results if ($totalNumPatients % $batchSize > 0) { $totalNumberBatches = floor($totalNumPatients / $batchSize) + 1; } else { $totalNumberBatches = floor($totalNumPatients / $batchSize); } // Prepare the database to track/store results if ($also_send) { $report_id = beginReportDatabase("process_send_reminders", '', $report_id); } else { $report_id = beginReportDatabase("process_reminders", '', $report_id); } setTotalItemsReportDatabase($report_id, $totalNumPatients); $patient_counter = 0; for ($i = 0; $i < $totalNumberBatches; $i++) { $patient_counter = $batchSize * ($i + 1); if ($patient_counter > $totalNumPatients) { $patient_counter = $totalNumPatients; } $update_rem_log_batch = update_reminders($dateTarget, '', $batchSize * $i + 1, $batchSize); if ($i == 0) { // For first cycle, simply copy it to update_rem_log $update_rem_log = $update_rem_log_batch; } else { // Debug statements //error_log("CDR: ".print_r($update_rem_log,TRUE),0); //error_log("CDR: ".($batchSize*$i). " records",0); // Integrate batch results into main update_rem_log $update_rem_log['total_active_actions'] = $update_rem_log['total_active_actions'] + $update_rem_log_batch['total_active_actions']; $update_rem_log['total_pre_active_reminders'] = $update_rem_log['total_pre_active_reminders'] + $update_rem_log_batch['total_pre_active_reminders']; $update_rem_log['total_pre_unsent_reminders'] = $update_rem_log['total_pre_unsent_reminders'] + $update_rem_log_batch['total_pre_unsent_reminders']; $update_rem_log['number_new_reminders'] = $update_rem_log['number_new_reminders'] + $update_rem_log_batch['number_new_reminders']; $update_rem_log['number_updated_reminders'] = $update_rem_log['number_updated_reminders'] + $update_rem_log_batch['number_updated_reminders']; $update_rem_log['number_unchanged_reminders'] = $update_rem_log['number_unchanged_reminders'] + $update_rem_log_batch['number_unchanged_reminders']; $update_rem_log['number_inactivated_reminders'] = $update_rem_log['number_inactivated_reminders'] + $update_rem_log_batch['number_inactivated_reminders']; $update_rem_log['total_post_active_reminders'] = $update_rem_log['total_post_active_reminders'] + $update_rem_log_batch['total_post_active_reminders']; $update_rem_log['total_post_unsent_reminders'] = $update_rem_log['total_post_unsent_reminders'] + $update_rem_log_batch['total_post_unsent_reminders']; } //Update database to track results updateReportDatabase($report_id, $patient_counter); } // Create an array for saving to database (allows combining with the send log) $save_log = array(); $save_log[] = $update_rem_log; // Send reminders, if this was selected if ($also_send) { $log_send = send_reminders(); $save_log[] = $log_send; } // Record combo results in database finishReportDatabase($report_id, json_encode($save_log)); // Just return the process reminders array return $update_rem_log; }