From 29c9e0cf8fa3b1377e3b2a86c9fa5b76a8059411 Mon Sep 17 00:00:00 2001 From: bradymiller Date: Sun, 14 Aug 2011 02:13:08 -0700 Subject: [PATCH] CDR engine updates: -Now will support procedures as filters -Changed the adult weight rule to only require one weight recording rather than two. -Changed the adult weight rule to have a mininum age filter of 18. -Fixed a bug that involved rules with multiple target group ids. --- library/clinical_rules.php | 168 +++++++++++++++++++++-------------------- sql/4_0_0-to-4_1_0_upgrade.sql | 20 +++++ sql/database.sql | 7 +- version.php | 2 +- 4 files changed, 111 insertions(+), 86 deletions(-) diff --git a/library/clinical_rules.php b/library/clinical_rules.php index d4e42493a..78e5d52ff 100644 --- a/library/clinical_rules.php +++ b/library/clinical_rules.php @@ -351,91 +351,97 @@ function test_rules_clinic($provider='',$type='',$dateTarget='',$mode='',$patien $exclude_filter = 0; $pass_target = 0; - foreach( $patientData as $rowPatient ) { + // Find the number of target groups + $targetGroups = returnTargetGroups($rowRule['id']); - // Count the total patients - $total_patients++; + if ( (count($targetGroups) == 1) || ($mode == "report") ) { + //skip this section if not report and more than one target group + foreach( $patientData as $rowPatient ) { - $dateCounter = 1; // for reminder mode to keep track of which date checking - foreach ( $target_dates as $dateFocus ) { + // Count the total patients + $total_patients++; - //Skip if date is set to SKIP - if ($dateFocus == "SKIP") { - $dateCounter++; - continue; - } + $dateCounter = 1; // for reminder mode to keep track of which date checking + foreach ( $target_dates as $dateFocus ) { - //Set date counter and reminder token (applicable for reminders only) - if ($dateCounter == 1) { - $reminder_due = "soon_due"; - } - else if ($dateCounter == 2) { - $reminder_due = "due"; - } - else { // $dateCounter == 3 - $reminder_due = "past_due"; - } + //Skip if date is set to SKIP + if ($dateFocus == "SKIP") { + $dateCounter++; + continue; + } - // First, deal with deceased patients - // (for now will simply not pass the filter, but can add a database item - // if ever want to create rules for dead people) - // Could also place this function at the total_patients level if wanted. - // (But then would lose the option of making rules for dead people) - // Note using the dateTarget rather than dateFocus - if (is_patient_deceased($rowPatient['pid'],$dateTarget)) { - continue; - } + //Set date counter and reminder token (applicable for reminders only) + if ($dateCounter == 1) { + $reminder_due = "soon_due"; + } + else if ($dateCounter == 2) { + $reminder_due = "due"; + } + else { // $dateCounter == 3 + $reminder_due = "past_due"; + } - // Check if pass filter - $passFilter = test_filter($rowPatient['pid'],$rowRule['id'],$dateFocus); - if ($passFilter === "EXCLUDED") { - // increment EXCLUDED and pass_filter counters - // and set as FALSE for reminder functionality. - $pass_filter++; - $exclude_filter++; - $passFilter = FALSE; - } - if ($passFilter) { - // increment pass filter counter - $pass_filter++; - } - else { - $dateCounter++; - continue; - } + // First, deal with deceased patients + // (for now will simply not pass the filter, but can add a database item + // if ever want to create rules for dead people) + // Could also place this function at the total_patients level if wanted. + // (But then would lose the option of making rules for dead people) + // Note using the dateTarget rather than dateFocus + if (is_patient_deceased($rowPatient['pid'],$dateTarget)) { + continue; + } + + // Check if pass filter + $passFilter = test_filter($rowPatient['pid'],$rowRule['id'],$dateFocus); + if ($passFilter === "EXCLUDED") { + // increment EXCLUDED and pass_filter counters + // and set as FALSE for reminder functionality. + $pass_filter++; + $exclude_filter++; + $passFilter = FALSE; + } + if ($passFilter) { + // increment pass filter counter + $pass_filter++; + } + else { + $dateCounter++; + continue; + } - // Check if pass target - $passTarget = test_targets($rowPatient['pid'],$rowRule['id'],'',$dateFocus); - if ($passTarget) { - // increment pass target counter - $pass_target++; - // send to reminder results - if ($mode == "reminders-all") { - // place the completed actions into the reminder return array - $actionArray = resolve_action_sql($rowRule['id'],'1'); - foreach ($actionArray as $action) { - $action_plus = $action; - $action_plus['due_status'] = "not_due"; - $action_plus['pid'] = $rowPatient['pid']; - $results = reminder_results_integrate($results, $action_plus); + // Check if pass target + $passTarget = test_targets($rowPatient['pid'],$rowRule['id'],'',$dateFocus); + if ($passTarget) { + // increment pass target counter + $pass_target++; + // send to reminder results + if ($mode == "reminders-all") { + // place the completed actions into the reminder return array + $actionArray = resolve_action_sql($rowRule['id'],'1'); + foreach ($actionArray as $action) { + $action_plus = $action; + $action_plus['due_status'] = "not_due"; + $action_plus['pid'] = $rowPatient['pid']; + $results = reminder_results_integrate($results, $action_plus); + } } + break; } - break; - } - else { - // send to reminder results - if ($mode != "report") { - // place the uncompleted actions into the reminder return array - $actionArray = resolve_action_sql($rowRule['id'],'1'); - foreach ($actionArray as $action) { - $action_plus = $action; - $action_plus['due_status'] = $reminder_due; - $action_plus['pid'] = $rowPatient['pid']; - $results = reminder_results_integrate($results, $action_plus); + else { + // send to reminder results + if ($mode != "report") { + // place the uncompleted actions into the reminder return array + $actionArray = resolve_action_sql($rowRule['id'],'1'); + foreach ($actionArray as $action) { + $action_plus = $action; + $action_plus['due_status'] = $reminder_due; + $action_plus['pid'] = $rowPatient['pid']; + $results = reminder_results_integrate($results, $action_plus); + } } } + $dateCounter++; } - $dateCounter++; } } @@ -447,19 +453,10 @@ function test_rules_clinic($provider='',$type='',$dateTarget='',$mode='',$patien array_push($results, $newRow); } - // Find the number of target groups, and go through each one if more than one - $targetGroups = returnTargetGroups($rowRule['id']); + // Now run through the target groups if more than one if (count($targetGroups) > 1) { - $firstGroup = true; foreach ($targetGroups as $i) { - // skip first group if not in report mode - // (this is because first group was already queried above) - if ($mode != "report" && $firstGroup) { - $firstGroup = false; - continue; - } - //Reset the target counter $pass_target = 0; @@ -635,6 +632,11 @@ function test_filter($patient_id,$rule,$dateTarget) { $filter = resolve_filter_sql($rule,'filt_lists'); if ((!empty($filter)) && !lists_check($patient_id,$filter,$dateTarget)) return false; + // -------- Procedure (labs,imaging,test,procedures,etc) Filter (inlcusion) ---- + // Procedure Target (includes) (may need to include an interval in the future) + $filter = resolve_filter_sql($rule,'filt_proc'); + if ((!empty($filter)) && !procedure_check($patient_id,$filter,'',$dateTarget)) return false; + // // ----------------- EXCLUSIONS ----------------- // diff --git a/sql/4_0_0-to-4_1_0_upgrade.sql b/sql/4_0_0-to-4_1_0_upgrade.sql index b008bcff7..f4dab542a 100644 --- a/sql/4_0_0-to-4_1_0_upgrade.sql +++ b/sql/4_0_0-to-4_1_0_upgrade.sql @@ -1514,3 +1514,23 @@ ALTER TABLE openemr_postcalendar_events ADD pc_sendalertemail VARCHAR(3) NOT NUL UPDATE `rule_target` SET `value` = 'INR::CPT4:85610::::::ge::1' WHERE `id` = 'rule_inr_monitor' AND `group_id` = 1 AND `method` = 'target_proc' AND `value` = 'INR::::::::ge::1'; #EndIf +#IfNotRow2D list_options list_id rule_targets option_id target_appt +INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_targets' ,'target_appt', 'Appointment', 30, 0); +#EndIf + +#IfNotRow2D list_options list_id rule_filters option_id filt_proc +INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_filters', 'filt_proc', 'Procedure', 60, 0); +#EndIf + +#IfNotRow2D list_options list_id rule_filters option_id filt_lists +INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_filters', 'filt_lists', 'Lists', 70, 0); +#EndIf + +#IfNotRow4D rule_target id rule_adult_wt_screen_fu group_id 1 method target_database value ::form_vitals::weight::::::ge::1 +UPDATE `rule_target` SET `value` = '::form_vitals::weight::::::ge::1' WHERE `id` = 'rule_adult_wt_screen_fu' AND `group_id` = 1 AND `method` = 'target_database' AND `value` = '::form_vitals::weight::::::ge::2'; +#EndIf + +#IfNotRow2D rule_filter id rule_adult_wt_screen_fu method filt_age_min +INSERT INTO `rule_filter` ( `id`, `include_flag`, `required_flag`, `method`, `method_detail`, `value` ) VALUES ('rule_adult_wt_screen_fu', 1, 1, 'filt_age_min', 'year', '18'); +#EndIf + diff --git a/sql/database.sql b/sql/database.sql index 696a2618c..0f228d0bb 100644 --- a/sql/database.sql +++ b/sql/database.sql @@ -2770,6 +2770,7 @@ INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_targets' ,'target_database', 'Database', 10, 0); INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_targets' ,'target_interval', 'Interval', 20, 0); INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_targets' ,'target_proc', 'Procedure', 20, 0); +INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_targets' ,'target_appt', 'Appointment', 30, 0); -- Clinical Rule Target Intervals INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('lists' ,'rule_target_intervals', 'Clinical Rules Target Intervals', 3, 0); @@ -2797,6 +2798,8 @@ INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_filters', 'filt_sex', 'Gender', 30, 0); INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_filters', 'filt_age_max', 'Maximum Age', 40, 0); INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_filters', 'filt_age_min', 'Minimum Age', 50, 0); +INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_filters', 'filt_proc', 'Procedure', 60, 0); +INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('rule_filters', 'filt_lists', 'Lists', 70, 0); -- Clinical Rule Age Intervals INSERT INTO `list_options` ( `list_id`, `option_id`, `title`, `seq`, `is_default` ) VALUES ('lists' ,'rule_age_intervals', 'Clinical Rules Age Intervals', 3, 0); @@ -3783,7 +3786,7 @@ INSERT INTO `rule_filter` ( `id`, `include_flag`, `required_flag`, `method`, `me -- Tobacco Cessation Intervention INSERT INTO `rule_filter` ( `id`, `include_flag`, `required_flag`, `method`, `method_detail`, `value` ) VALUES ('rule_tob_cess_inter', 1, 1, 'filt_database', '', 'LIFESTYLE::tobacco::current'); -- Adult Weight Screening and Follow-Up --- no filters +INSERT INTO `rule_filter` ( `id`, `include_flag`, `required_flag`, `method`, `method_detail`, `value` ) VALUES ('rule_adult_wt_screen_fu', 1, 1, 'filt_age_min', 'year', '18'); -- Weight Assessment and Counseling for Children and Adolescents INSERT INTO `rule_filter` ( `id`, `include_flag`, `required_flag`, `method`, `method_detail`, `value` ) VALUES ('rule_wt_assess_couns_child', 1, 1, 'filt_age_max', 'year', '18'); INSERT INTO `rule_filter` ( `id`, `include_flag`, `required_flag`, `method`, `method_detail`, `value` ) VALUES ('rule_wt_assess_couns_child', 1, 1, 'filt_age_min', 'year', '2'); @@ -4204,7 +4207,7 @@ INSERT INTO `rule_target` ( `id`, `group_id`, `include_flag`, `required_flag`, ` INSERT INTO `rule_target` ( `id`, `group_id`, `include_flag`, `required_flag`, `method`, `value`, `interval` ) VALUES ('rule_tob_cess_inter', 1, 1, 1, 'target_interval', 'year', 1); INSERT INTO `rule_target` ( `id`, `group_id`, `include_flag`, `required_flag`, `method`, `value`, `interval` ) VALUES ('rule_tob_cess_inter', 1, 1, 1, 'target_database', 'CUSTOM::act_cat_inter::act_tobacco::YES::ge::1', 0); -- Adult Weight Screening and Follow-Up -INSERT INTO `rule_target` ( `id`, `group_id`, `include_flag`, `required_flag`, `method`, `value`, `interval` ) VALUES ('rule_adult_wt_screen_fu', 1, 1, 1, 'target_database', '::form_vitals::weight::::::ge::2', 0); +INSERT INTO `rule_target` ( `id`, `group_id`, `include_flag`, `required_flag`, `method`, `value`, `interval` ) VALUES ('rule_adult_wt_screen_fu', 1, 1, 1, 'target_database', '::form_vitals::weight::::::ge::1', 0); -- Weight Assessment and Counseling for Children and Adolescents INSERT INTO `rule_target` ( `id`, `group_id`, `include_flag`, `required_flag`, `method`, `value`, `interval` ) VALUES ('rule_wt_assess_couns_child', 1, 1, 1, 'target_database', '::form_vitals::weight::::::ge::1', 0); INSERT INTO `rule_target` ( `id`, `group_id`, `include_flag`, `required_flag`, `method`, `value`, `interval` ) VALUES ('rule_wt_assess_couns_child', 1, 1, 1, 'target_interval', 'year', 3); diff --git a/version.php b/version.php index 40f5f8898..d59b223d2 100644 --- a/version.php +++ b/version.php @@ -12,5 +12,5 @@ $v_tag = '-dev'; // minor revision number, should be empty for production rele // is a database change in the course of development. It is used // internally to determine when a database upgrade is needed. // -$v_database = 40; +$v_database = 41; ?> -- 2.11.4.GIT