4 * Decision Tree - beslisboom
6 * functions used at the moment of closing dbc to choose a productgroep in the end
7 * Cristian Navalici lemonsoftware [ @ ] gmail [ . ] com
11 * int dt_main(int $node) - main function; it's the decision point in our algorithm
12 * string dt_whatparam(string $kmcode) - what param is needed for km* function
13 * string dt_nodefunction(int $node) - what function is associated with a node
14 * int dt_comparison(string $function, int $rval) - compare the values to make a decision
20 * global variables used in script
23 $beslis_table = ''; // we use different tables for 2007/08
24 $rfsum = 0; // remember for sum - this we add all values from the algorithm
26 $enddate = ''; // closing date for dbc (if used from a CLI script)
29 * if you run from a cron script (outside the webserver), use it this way
30 * include_once('library/DBC_cfunctions.php');
31 * include_once('library/DBC_decisiontree.php');
33 * dt_main(1, 365, '2008-04-02');
34 * $z = dt_whatproductgroep($rfsum, '2008-04-02');
35 * 1 - starting node, 365 - dbcid, '2008-04-02' - closing date
39 //-----------------------------------------------------------------------------
43 * calls different functions, in a deadly precise algorithm
45 * @param int $node - in what node we are (default:1)
46 * @param int $dbcid - in case we are calling from a script
47 * @param string $end - closing date for dbc (used in dt_allevents)
48 * @return int $rfsum - remember for sum
50 function dt_main($node = 1, $dbcid = 0, $end = '') {
51 // if it's the first time, run the pre_init function
52 if ( $node == 1 ) dt_preinit($dbcid, $end);
54 $function = dt_nodefunction($node);
57 case 'KMA_001': $r = dt_kma001(); break;
58 case 'KMA_002': $r = dt_kma002(); break;
59 case 'KMA_003': $r = dt_kma003(); break;
60 case 'KMA_004': $r = dt_kma004(); break;
61 case 'KMA_005': $r = dt_kma005(); break;
62 case 'KMT_001': $r = dt_kmt001($node); break;
63 case 'KMT_002': $r = dt_kmt002(); break;
64 case 'KMT_003': $r = dt_kmt003($node); break;
65 case 'KMT_004': $r = dt_kmt004(); break;
66 case 'KMN_001': $r = dt_kmn001($node); break;
67 case 'KMP_001': $r = dt_kmp001(); break;
68 case 'KMC_001': $r = dt_kmc001(); break;
73 $direction = dt_comparison($node, $r);
74 //echo "F:$function R: $r D: $direction SUM: $rfsum <br /> --------------- <br> "; //debug
75 //echo "F:$function R: $r D: $direction SUM: $rfsum \n"; // debug for CLI
77 if ( $direction ) dt_main($direction);
79 global $enddate, $dbcid;
80 if ( !$dbcid ) $enddate = $_SESSION['eind']; // called from webinterface
83 // for a script, we must called this ourselves using global $rfsum and closing date
84 $a = dt_whatproductgroep($rfsum, $enddate);
85 // called from within openemr
86 $_SESSION['pgroep'] = $a['id'];
94 //-----------------------------------------------------------------------------
96 * DECIDES WHAT TABLE WILL BE USED
98 * because the beslisboom has 2 tables (2007/2008), we must decide which one we'll use
100 * @param int $dbcid - in case we called this from a script (and we don't have $_SESSION)
101 * @param string $end - closing date for dbc
104 function dt_preinit($dbc, $end) {
105 // it sets some globals
106 global $beslis_table, $dbcid, $enddate;
109 // we use this _local to obtain info about dbc but *global* dbcid
110 // must remain empty if $dbc is empty; empty means called from webinterface not from a script
111 $dbcid_local = ( $dbc ) ?
$dbc : $_SESSION['show_axid'];
112 $enddate = ( $end ) ?
$end : $_SESSION['eind'];
114 $dbc = content_diagnose($dbcid_local);
115 $odate = $dbc['ax_odate'];
117 if ( $odate <= '2007-12-31' ) {
118 $beslis_table = 'cl_beslisboom_2007';
119 } elseif ( $odate >= '2008-01-01') {
120 $beslis_table = 'cl_beslisboom';
122 // leave room for more versions :)
128 //-----------------------------------------------------------------------------
132 * function for comparison
134 * @param int $node - node to look for (and retrieve the one value)
135 * @param int $value to compare
136 * @return int - next node
138 function dt_comparison($node, $rval) {
139 global $beslis_table;
140 $q = sprintf("SELECT * FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node);
142 $r = mysql_query($q) or die(mysql_error());
144 if ( !mysql_num_rows($r) ) {
147 $row = mysql_fetch_array($r);
149 // compare the values function of the operator
150 switch ( $row['cbe_operator'] ) {
151 case '<=': $rez = ( $rval <= $row['cbe_value1'] ); break;
152 case '<': $rez = ( $rval < $row['cbe_value1'] ); break;
153 case '=': $rez = ( $rval == $row['cbe_value1'] ); break;
154 case '>=': $rez = ( $rval >= $row['cbe_value1'] ); break;
157 // update the remember for sum variable
159 $rfsum +
= ( $rez ) ?
$row['cbe_rfsumT'] : $row['cbe_rfsumF'];
162 $ret = $rez ?
$row['cbe_nodegoal_T'] : $row['cbe_nodegoal_F'];
168 //-----------------------------------------------------------------------------
170 * WHAT FUNCTION IS USED FOR A SPECIFIED NODE
172 * function of node, we call a function
175 * @return string function name (in fact, a code from the tables)
177 function dt_nodefunction($node) {
178 global $beslis_table;
179 $q = sprintf("SELECT cbe_checkKM AS km FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node);
180 $r = mysql_query($q) or die(mysql_error());
182 if ( !mysql_num_rows($r) ) {
185 $row = mysql_fetch_array($r);
190 //-----------------------------------------------------------------------------
192 * WHAT PARAMETER IS NEEDED FOR KM* FUNCTION
194 * some KM* functions work with some parameter; this function retrieves from db
196 * @param int $node - KM node
197 * @param int $par - first or second param (1/2)
198 * @return string $param (empty string for no param)
200 function dt_whatparam($node, $par = 1) {
201 global $beslis_table;
204 $q = sprintf("SELECT cbe_KMpar1 AS param FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node);
205 } else if ( $par == 2) {
206 $q = sprintf("SELECT cbe_KMpar2 AS param FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node);
208 $r = mysql_query($q) or die(mysql_error());
210 if ( !mysql_num_rows($r) ) {
213 $row = mysql_fetch_array($r);
214 return $row['param'];
218 //-----------------------------------------------------------------------------
222 * Number of days in clinic
223 * Days in clinic can be recognised by CL_ACTIVITEIT_SOORT=VERBLIJFSDAG.
224 * Exception: act_8.1.6*
226 * NOTE we don't use it now so it's always 0
231 function dt_kma001() {
235 //-----------------------------------------------------------------------------
239 * ver 1: Sum of all direct time of activities + total time dagbesteding
240 * If CL_ACTIVITEIT_SOORT = TIJDSCHRIJVEN then sum up all DIRECT_PATIENT-GEBONDEN_TIJD. Add time (if CL_ACTIVITEIT_SOORT * = DAGBESTEDING) *60 (because dagbesteding/daycare is registered in hours; not minutes)
242 * ver 2: Sum of all direct time of activities + 15 times the hours spent in dagbesteding
243 * If CL_ACTIVITEIT_SOORT = TIJDSCHRIJVEN then sum up all DIRECT_PATIENT-GEBONDEN_TIJD. Add time (if CL_ACTIVITEIT_SOORT * = DAGBESTEDING) *15 (because dagbesteding/daycare is registered in hours; not minutes)
246 * @return int $totaltime
248 function dt_kma002() {
252 //choose here what $ver we'll use function of a date
253 //$dbc = content_diagnose($_SESSION['show_axid']);
254 //$odate = $dbc['ax_odate'];
255 //$ver = ( $odate <= '2007-12-31') ? 1 : 2;
256 $ver = 2 ; //we'll just use 2 because we don't have dagbestending
258 while ( $row = mysql_fetch_array($r) ) {
259 $qe = sprintf("SELECT cl_activiteit_soort AS cas FROM cl_activiteit ca
260 JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
261 WHERE cea.event_id = %d", $row['pc_eid']);
262 $re = mysql_query($qe) or die(mysql_error());
263 $rowe = mysql_fetch_array($re);
265 $cas = trim($rowe['cas']);
267 // those three times for an event (direct, indirect, travel)
268 $times = dt_times($row['pc_eid']);
271 if ( $cas == 'Verblijfsdag' ) {
273 // because dagbesteding/daycare is registered in hours; not minutes
274 //$totaltime += ( $times['dirtime'] * 60 );
275 } else if ( $ver == 2 ){
276 // 15 times the hours spent in dagbesteding
277 //$totaltime += ( $times['dirtime'] * 15 );
279 } else if ( $cas == 'Tijdschrijven' ) {
280 $totaltime +
= $times['dirtime'];
287 //-----------------------------------------------------------------------------
291 * total minutes total time (Sum of all direct, indirect and travel time of activities + total time dagbesteding)
296 function dt_kma003() {
300 //choose here what $ver we'll use function of a date
301 //$dbc = content_diagnose($_SESSION['show_axid']);
302 //$odate = $dbc['ax_odate'];
303 //$ver = ( $odate <= '2007-12-31') ? 1 : 2;
304 $ver = 2; // it doesn't matter now.
306 while ( $row = mysql_fetch_array($r) ) {
307 $qe = sprintf("SELECT cl_activiteit_soort AS cas FROM cl_activiteit ca
308 JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
309 WHERE cea.event_id = %d", $row['pc_eid']);
310 $re = mysql_query($qe) or die(mysql_error());
311 $rowe = mysql_fetch_array($re);
313 // those three times for an event (direct, indirect, travel)
314 $times = dt_times($row['pc_eid']);
315 $totalt = $times['dirtime'] +
$times['tratime'] +
$times['indtime'];
316 //echo "{$rowe['cas']} TIME KMA003: $totalt <br>"; //debug
318 if ( $rowe['cas'] == 'Verblijfsdag' ) {
320 // because dagbesteding/daycare is registered in hours; not minutes
321 $totaltime += ( $times['dirtime'] * 60 );
322 } else if ( $ver == 2 ) {
323 // 15 times the hours spent in dagbesteding
324 $totaltime += ( $times['dirtime'] * 15 );
326 } else if ( $rowe['cas'] == 'Tijdschrijven' ) {
327 $totaltime +
= $totalt;
329 //echo "TOTALTIME KMA003: $totaltime EV: {$row['pc_eid']}<br>"; //debug
335 //-----------------------------------------------------------------------------
339 * number of separate kinds of jobs (e.g. Psychologist, psychiatrist, nurse, etc.)
340 * Count how many distinct CL_BEROEPEN_CODE values are in this DBC
342 * NOTE: openemr doesn't use it in 2008
345 * @return int - distinct values for cl_beroep_code
347 function dt_kma004() {
351 while ( $row = mysql_fetch_array($r) ) {
352 $qe = sprintf("SELECT cl_beroep_code FROM cl_beroep cb JOIN cl_user_beroep cub ON cb.cl_beroep_sysid = cub.cl_beroep_sysid WHERE cub.cl_beroep_userid = %d ", $row['pc_aid']);
353 $re = mysql_query($qe) or die(mysql_error());
354 $rowe = mysql_fetch_array($re);
356 $beroep[] = $rowe['cl_beroep_code'];
359 // find and return distict values from the jobs array
360 return count(array_unique($beroep));
364 //-----------------------------------------------------------------------------
368 * number of days in clinic without stay overnight
369 * Total number of CL_ACTIVITEIT_SOORT=VERBLIJFSDAG,
370 * but only for act_8.1.6, 8.2.6, 8.3.6, 8.4.6, 8.5.6, 8.6.6
372 * NOTE we don't use it at this moment
377 function dt_kma005() {
381 //-----------------------------------------------------------------------------
385 * total minutes time on activity (parameter1)
386 * old ver - Add up total time (direct, indirect, travel, dagbesteding) for activities that are hierarchically under CL_ACTIVITEIT=parameter1
387 * new ver - Add up total time (direct, indirect, travel, 15*dagbesteding) for activities that are hierarchically under CL_ACTIVITEIT=parameter1, but ONLY activities with CL_ACTIVITEIT_SOORT = tijdschrijven or CL_ACTIVITEIT_SOORT = dagbesteding
389 * @param int $node - node to look parameter for
392 function dt_kmt001($node) {
395 $par = dt_whatparam($node, 1);
398 //echo "PAR KMT001: $par <br>"; //debug
399 // choose here what $ver we'll use function of a date
400 $dbc = content_diagnose($dbcid);
401 $odate = $dbc['ax_odate'];
402 $ver = ( $odate <= '2007-12-31') ?
1 : 2;
404 while ( $row = mysql_fetch_array($r) ) {
405 $qe = sprintf("SELECT cl_activiteit_soort AS cas, cl_activiteit_groepcode AS cag
406 FROM cl_activiteit ca JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
407 WHERE cea.event_id = %d", $row['pc_eid']);
408 $re = mysql_query($qe) or die(mysql_error());
409 $rowe = mysql_fetch_array($re);
411 $cas = trim($rowe['cas']);
412 $cag = trim($rowe['cag']);
414 // under the parameter
415 if ( strpos($cag, $par) === 0 ) {
416 // those three times for an event (direct, indirect, travel)
417 $times = dt_times($row['pc_eid']);
418 $totalt = $times['dirtime'] +
$times['tratime'] +
$times['indtime'];
421 $totaltime +
= $totalt;
422 } else if ( $ver == 2 ) {
423 if ( $cas == 'Tijdschrijven' ||
$cas == 'Dagbesteding' ) $totaltime +
= $totalt;
428 //echo "TOTALTIME KMT001: $totaltime <br>";
432 //-----------------------------------------------------------------------------
436 * NOTE: openemr doesn't use it in 2008
441 function dt_kmt002() {
445 //-----------------------------------------------------------------------------
449 * total minutes direct time on activity (parameter1)
451 * ver 1 - If CL_ACTIVITEIT_SOORT = TIJDSCHRIJVEN then sum up all DIRECT_PATIENT-GEBONDEN_TIJD. Add time (if CL_ACTIVITEIT_SOORT = DAGBESTEDING) *60 (because dagbesteding/daycare is registered in hours; not minutes) BUT ONLY for activities that are hierarchically under parameter1 of CL_ACTIVITEIT
453 * ver 2 - If CL_ACTIVITEIT_SOORT = TIJDSCHRIJVEN then sum up all DIRECT_PATIENT-GEBONDEN_TIJD.
454 * Add time (if CL_ACTIVITEIT_SOORT = DAGBESTEDING) * 15 (because dagbesteding/daycare is registered in hours; not minutes) BUT ONLY for activities that are hierarchically under parameter1 of CL_ACTIVITEIT;
456 * @param int $node- node to look parameter for
459 function dt_kmt003($node) {
462 $par = dt_whatparam($node, 1);
466 //choose here what $ver we'll use function of a date
467 $dbc = content_diagnose($dbcid);
468 $odate = $dbc['ax_odate'];
469 $ver = ( $odate <= '2007-12-31') ?
1 : 2;
471 while ( $row = mysql_fetch_array($r) ) {
472 $qe = sprintf("SELECT cl_activiteit_soort AS cas, cl_activiteit_groepcode AS cag
473 FROM cl_activiteit ca JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
474 WHERE cea.event_id = %d", $row['pc_eid']);
475 $re = mysql_query($qe) or die(mysql_error());
476 $rowe = mysql_fetch_array($re);
478 $cas = trim($rowe['cas']);
479 $cag = trim($rowe['cag']);
481 // under the parameter
482 if ( strpos($cag, $par) === 0 ) {
483 // those three times for an event (direct, indirect, travel)
484 $times = dt_times($row['pc_eid']);
487 if ( $cas == 'Tijdschrijven' ) $totaltime +
= $times['dirtime'];
488 if ( $cas == 'Dagbesteding' ) $totaltime +
= ($times['dirtime'] * 15); // not used yet!
489 } else if ( $ver == 2 ) {
490 //if ( $cas == 'Tijdschrijven' || $cas == 'Dagbesteding' ) $totaltime += $times['dirtime'];
491 if ( $cas == 'Tijdschrijven' ) $totaltime +
= $times['dirtime'];
492 if ( $cas == 'Dagbesteding' ) $totaltime +
= ($times['dirtime'] * 60); // not used yet!
501 //-----------------------------------------------------------------------------
505 * NOTE: openemr doesn't use it in 2008
510 function dt_kmt004() {
514 //-----------------------------------------------------------------------------
518 * The registered primary (main) diagnosis falls under category parameter1 (CL_DIAGNOSE)
520 * Example: if the asked value of CL_DIAGNOSE_CODE is AS1_6 then all CL_DIAGNOSE_CODE
521 * values As1_6* are valid (all values in the same hierarchy)
523 * @param int $node- node to look parameter for
526 function dt_kmn001($node) {
529 $par = dt_whatparam($node, 1);
530 $maindia = df_get_main_diagnose($dbcid);
532 return (strpos($maindia, $par) === 0);
535 //-----------------------------------------------------------------------------
539 * NOTE: not used by us
543 function dt_kmp001() {
547 //-----------------------------------------------------------------------------
551 * NOTE: openemr doesn't use it in 2008
556 function dt_kmc001() {
561 //-----------------------------------------------------------------------------
563 * ALL EVENTS FOR A DBC
565 * between opening date and closing date
568 * @return mysqlresult
570 function dt_allevents() {
571 global $dbcid, $enddate;
573 $dia = content_diagnose($dbcid);
574 $odate = mysql_real_escape_string($dia['ax_odate']);
575 $cdate = ( isset($_SESSION['eind']) && $_SESSION['eind'] ) ?
mysql_real_escape_string($_SESSION['eind']) : $enddate;
576 if ( !$cdate ) $cdate = date('Y-m-d'); //as a precaution
577 $pid = ( $dbcid ) ?
what_patient($dbcid) : $_SESSION['pid'];
579 // find all events from DBC opening 'till closing date
580 $q = sprintf("SELECT pc_eid, pc_aid FROM openemr_postcalendar_events
581 WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_eventDate <= '%s' AND pc_apptstatus = '@' ",
582 $pid, $odate, $cdate);
583 $r = mysql_query($q) or die(mysql_error());
589 //-----------------------------------------------------------------------------
593 * returns direct, indirect and travel time (all in minutes)
595 * @param int $eid - event id
598 function dt_times($eid = 0) {
599 if ( !$eid ) return 0;
601 // for JOIN - if the second table has inconsistency of data (missing record for an events)
602 // a 'bug' occur and the direct time become 0
603 //$qt = sprintf("SELECT ope.pc_duration, cta.indirect_time, cta.travel_time FROM openemr_postcalendar_events ope JOIN cl_time_activiteit cta ON ope.pc_eid = cta.event_id WHERE pc_eid = %d ", $eid);
604 $qt = sprintf("SELECT pc_duration FROM openemr_postcalendar_events WHERE pc_eid = %d ", $eid);
605 $rt = mysql_query($qt) or die(mysql_error());
606 $rowt = mysql_fetch_array($rt);
609 $rez['dirtime'] = $rowt['pc_duration'] / 60;
612 $qi = sprintf("SELECT indirect_time, travel_time FROM cl_time_activiteit WHERE event_id = %d ", $eid);
613 $ri = mysql_query($qi) or die(mysql_error());
615 if ( mysql_num_rows($ri) ) {
616 $rowi = mysql_fetch_array($ri);
618 $rez['indtime'] = $rowi['indirect_time'];
620 $rez['tratime'] = $rowi['travel_time'];
622 $rez['indtime'] = $rez['tratime'] = 0;
628 //-----------------------------------------------------------------------------
632 * after we have a result, we look up the right productgroep
635 * @param string $endate - ending date for the DBC
636 * @return array - two values id|name
638 function dt_whatproductgroep($rfsum, $endate) {
639 // to avoid the bug: first time, it doesn't display properly
642 $dc = content_diagnose($dbcid);
643 $endate = $dc['ax_cdate'];
647 $q = sprintf("SELECT cl_productgroep_sysid as cps, cl_productgroep_beschrijving as cpb
648 FROM cl_productgroep WHERE cl_productgroep_code = %d
649 AND cl_productgroep_begindatum <= '%s' AND cl_productgroep_einddatum >= '%s' ", $rfsum, $endate, $endate);
650 $r = mysql_query($q) or die(mysql_error());
652 $row = mysql_fetch_array($r);
654 $res['id'] = $row['cps']; $res['name'] = $row['cpb'];
659 //-----------------------------------------------------------------------------
663 * last step in the decision tree
664 * if called with $retflag = 1, just return the value
666 * @param int $zsysid - zorg sysid
667 * @param int $pgroep - productgroep sysid
668 * @param int $dbcid - dbcid
669 * @return string|void
671 function dt_prestatiecode($zsysid, $pgroep, $dbcid = 0, $retflag = 0) {
674 // ZORGTYPE ----------------
675 $qz = sprintf("SELECT cl_zorgtype_prestatiecodedeel AS czp FROM cl_zorg WHERE cl_zorgtype_sysid = %d ", $zsysid);
676 $rz = mysql_query($qz) or die(mysql_error());
677 $rowz = mysql_fetch_array($rz);
679 $czp = (int)$rowz['czp']; $czp = str_pad($czp, 3, '0', STR_PAD_LEFT
);
680 $resstr .= substr($rowz['czp'], 0, 3); // only 3 characters allowed
682 // DIAGNOSE ----------------
683 $qd = sprintf("SELECT cl_productgroep_diagnose_blinderen AS cdb, cl_productgroep_code as cpc
684 FROM cl_productgroep WHERE cl_productgroep_sysid = %d ", $pgroep);
685 $rd = mysql_query($qd) or die(mysql_error());
686 $rod = mysql_fetch_array($rd);
688 // posible values 1 - 0
689 if ( $rod['cdb'] == 1 ) {
692 // find CL_DIAGNOSE_PRESTATIECODEDEEL for the main diagnose
693 $maind = df_get_main_diagnose($dbcid);
694 $qpre = sprintf("SELECT cl_diagnose_prestatiecodedeel FROM cl_diagnose WHERE cl_diagnose_code = '%s' ",
696 $rpre = mysql_query($qpre) or die(mysql_error());
697 $rowpre = mysql_fetch_array($rpre);
699 $resstr .= ( $rowpre['cl_diagnose_prestatiecodedeel'] ) ?
$rowpre['cl_diagnose_prestatiecodedeel'] : '000' ;
702 // PRODUCTGROEP CODE ----------------
703 $resstr .= str_pad($rod['cpc'], 6, '0', STR_PAD_LEFT
);
705 // save it to the table only if $dbcid is given
706 // otherwise just return the value
708 $qu = sprintf("UPDATE cl_axes SET ax_pcode='%s' WHERE ax_id = %d ", $resstr, $dbcid);
709 mysql_query($qu) or die(mysql_error());
715 //-----------------------------------------------------------------------------