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;
110 $dbc = content_diagnose($dbcid);
111 $odate = $dbc['ax_odate'];
113 if ( $odate <= '2007-12-31' ) {
114 $beslis_table = 'cl_beslisboom_2007';
115 } elseif ( $odate >= '2008-01-01') {
116 $beslis_table = 'cl_beslisboom';
118 // leave room for more versions :)
124 //-----------------------------------------------------------------------------
128 * function for comparison
130 * @param int $node - node to look for (and retrieve the one value)
131 * @param int $value to compare
132 * @return int - next node
134 function dt_comparison($node, $rval) {
135 global $beslis_table;
136 $q = sprintf("SELECT * FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node);
138 $r = mysql_query($q) or die(mysql_error());
140 if ( !mysql_num_rows($r) ) {
143 $row = mysql_fetch_array($r);
145 // compare the values function of the operator
146 switch ( $row['cbe_operator'] ) {
147 case '<=': $rez = ( $rval <= $row['cbe_value1'] ); break;
148 case '<': $rez = ( $rval < $row['cbe_value1'] ); break;
149 case '=': $rez = ( $rval == $row['cbe_value1'] ); break;
150 case '>=': $rez = ( $rval >= $row['cbe_value1'] ); break;
153 // update the remember for sum variable
155 $rfsum +
= ( $rez ) ?
$row['cbe_rfsumT'] : $row['cbe_rfsumF'];
158 $ret = $rez ?
$row['cbe_nodegoal_T'] : $row['cbe_nodegoal_F'];
164 //-----------------------------------------------------------------------------
166 * WHAT FUNCTION IS USED FOR A SPECIFIED NODE
168 * function of node, we call a function
171 * @return string function name (in fact, a code from the tables)
173 function dt_nodefunction($node) {
174 global $beslis_table;
175 $q = sprintf("SELECT cbe_checkKM AS km FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node);
176 $r = mysql_query($q) or die(mysql_error());
178 if ( !mysql_num_rows($r) ) {
181 $row = mysql_fetch_array($r);
186 //-----------------------------------------------------------------------------
188 * WHAT PARAMETER IS NEEDED FOR KM* FUNCTION
190 * some KM* functions work with some parameter; this function retrieves from db
192 * @param int $node - KM node
193 * @param int $par - first or second param (1/2)
194 * @return string $param (empty string for no param)
196 function dt_whatparam($node, $par = 1) {
197 global $beslis_table;
200 $q = sprintf("SELECT cbe_KMpar1 AS param FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node);
201 } else if ( $par == 2) {
202 $q = sprintf("SELECT cbe_KMpar2 AS param FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node);
204 $r = mysql_query($q) or die(mysql_error());
206 if ( !mysql_num_rows($r) ) {
209 $row = mysql_fetch_array($r);
210 return $row['param'];
214 //-----------------------------------------------------------------------------
218 * Number of days in clinic
219 * Days in clinic can be recognised by CL_ACTIVITEIT_SOORT=VERBLIJFSDAG.
220 * Exception: act_8.1.6*
222 * NOTE we don't use it now so it's always 0
227 function dt_kma001() {
231 //-----------------------------------------------------------------------------
235 * ver 1: Sum of all direct time of activities + total time dagbesteding
236 * 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)
238 * ver 2: Sum of all direct time of activities + 15 times the hours spent in dagbesteding
239 * 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)
242 * @return int $totaltime
244 function dt_kma002() {
248 //choose here what $ver we'll use function of a date
249 //$dbc = content_diagnose($_SESSION['show_axid']);
250 //$odate = $dbc['ax_odate'];
251 //$ver = ( $odate <= '2007-12-31') ? 1 : 2;
252 $ver = 2 ; //we'll just use 2 because we don't have dagbestending
254 while ( $row = mysql_fetch_array($r) ) {
255 $qe = sprintf("SELECT cl_activiteit_soort AS cas FROM cl_activiteit ca
256 JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
257 WHERE cea.event_id = %d", $row['pc_eid']);
258 $re = mysql_query($qe) or die(mysql_error());
259 $rowe = mysql_fetch_array($re);
261 $cas = trim($rowe['cas']);
263 // those three times for an event (direct, indirect, travel)
264 $times = dt_times($row['pc_eid']);
267 if ( $cas == 'Verblijfsdag' ) {
269 // because dagbesteding/daycare is registered in hours; not minutes
270 //$totaltime += ( $times['dirtime'] * 60 );
271 } else if ( $ver == 2 ){
272 // 15 times the hours spent in dagbesteding
273 //$totaltime += ( $times['dirtime'] * 15 );
275 } else if ( $cas == 'Tijdschrijven' ) {
276 $totaltime +
= $times['dirtime'];
283 //-----------------------------------------------------------------------------
287 * total minutes total time (Sum of all direct, indirect and travel time of activities + total time dagbesteding)
292 function dt_kma003() {
296 //choose here what $ver we'll use function of a date
297 //$dbc = content_diagnose($_SESSION['show_axid']);
298 //$odate = $dbc['ax_odate'];
299 //$ver = ( $odate <= '2007-12-31') ? 1 : 2;
300 $ver = 2; // it doesn't matter now.
302 while ( $row = mysql_fetch_array($r) ) {
303 $qe = sprintf("SELECT cl_activiteit_soort AS cas FROM cl_activiteit ca
304 JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
305 WHERE cea.event_id = %d", $row['pc_eid']);
306 $re = mysql_query($qe) or die(mysql_error());
307 $rowe = mysql_fetch_array($re);
309 // those three times for an event (direct, indirect, travel)
310 $times = dt_times($row['pc_eid']);
311 $totalt = $times['dirtime'] +
$times['tratime'] +
$times['indtime'];
312 //echo "{$rowe['cas']} TIME KMA003: $totalt <br>"; //debug
314 if ( $rowe['cas'] == 'Verblijfsdag' ) {
316 // because dagbesteding/daycare is registered in hours; not minutes
317 $totaltime += ( $times['dirtime'] * 60 );
318 } else if ( $ver == 2 ) {
319 // 15 times the hours spent in dagbesteding
320 $totaltime += ( $times['dirtime'] * 15 );
322 } else if ( $rowe['cas'] == 'Tijdschrijven' ) {
323 $totaltime +
= $totalt;
325 //echo "TOTALTIME KMA003: $totaltime EV: {$row['pc_eid']}<br>"; //debug
331 //-----------------------------------------------------------------------------
335 * number of separate kinds of jobs (e.g. Psychologist, psychiatrist, nurse, etc.)
336 * Count how many distinct CL_BEROEPEN_CODE values are in this DBC
338 * NOTE: openemr doesn't use it in 2008
341 * @return int - distinct values for cl_beroep_code
343 function dt_kma004() {
347 while ( $row = mysql_fetch_array($r) ) {
348 $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']);
349 $re = mysql_query($qe) or die(mysql_error());
350 $rowe = mysql_fetch_array($re);
352 $beroep[] = $rowe['cl_beroep_code'];
355 // find and return distict values from the jobs array
356 return count(array_unique($beroep));
360 //-----------------------------------------------------------------------------
364 * number of days in clinic without stay overnight
365 * Total number of CL_ACTIVITEIT_SOORT=VERBLIJFSDAG,
366 * but only for act_8.1.6, 8.2.6, 8.3.6, 8.4.6, 8.5.6, 8.6.6
368 * NOTE we don't use it at this moment
373 function dt_kma005() {
377 //-----------------------------------------------------------------------------
381 * total minutes time on activity (parameter1)
382 * old ver - Add up total time (direct, indirect, travel, dagbesteding) for activities that are hierarchically under CL_ACTIVITEIT=parameter1
383 * 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
385 * @param int $node - node to look parameter for
388 function dt_kmt001($node) {
391 $par = dt_whatparam($node, 1);
394 //echo "PAR KMT001: $par <br>"; //debug
395 // choose here what $ver we'll use function of a date
396 $dbc = content_diagnose($dbcid);
397 $odate = $dbc['ax_odate'];
398 $ver = ( $odate <= '2007-12-31') ?
1 : 2;
400 while ( $row = mysql_fetch_array($r) ) {
401 $qe = sprintf("SELECT cl_activiteit_soort AS cas, cl_activiteit_groepcode AS cag
402 FROM cl_activiteit ca JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
403 WHERE cea.event_id = %d", $row['pc_eid']);
404 $re = mysql_query($qe) or die(mysql_error());
405 $rowe = mysql_fetch_array($re);
407 $cas = trim($rowe['cas']);
408 $cag = trim($rowe['cag']);
410 // under the parameter
411 if ( strpos($cag, $par) === 0 ) {
412 // those three times for an event (direct, indirect, travel)
413 $times = dt_times($row['pc_eid']);
414 $totalt = $times['dirtime'] +
$times['tratime'] +
$times['indtime'];
417 $totaltime +
= $totalt;
418 } else if ( $ver == 2 ) {
419 if ( $cas == 'Tijdschrijven' ||
$cas == 'Dagbesteding' ) $totaltime +
= $totalt;
424 //echo "TOTALTIME KMT001: $totaltime <br>";
428 //-----------------------------------------------------------------------------
432 * NOTE: openemr doesn't use it in 2008
437 function dt_kmt002() {
441 //-----------------------------------------------------------------------------
445 * total minutes direct time on activity (parameter1)
447 * 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
449 * ver 2 - If CL_ACTIVITEIT_SOORT = TIJDSCHRIJVEN then sum up all DIRECT_PATIENT-GEBONDEN_TIJD.
450 * 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;
452 * @param int $node- node to look parameter for
455 function dt_kmt003($node) {
458 $par = dt_whatparam($node, 1);
462 //choose here what $ver we'll use function of a date
463 $dbc = content_diagnose($dbcid);
464 $odate = $dbc['ax_odate'];
465 $ver = ( $odate <= '2007-12-31') ?
1 : 2;
467 while ( $row = mysql_fetch_array($r) ) {
468 $qe = sprintf("SELECT cl_activiteit_soort AS cas, cl_activiteit_groepcode AS cag
469 FROM cl_activiteit ca JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
470 WHERE cea.event_id = %d", $row['pc_eid']);
471 $re = mysql_query($qe) or die(mysql_error());
472 $rowe = mysql_fetch_array($re);
474 $cas = trim($rowe['cas']);
475 $cag = trim($rowe['cag']);
477 // under the parameter
478 if ( strpos($cag, $par) === 0 ) {
479 // those three times for an event (direct, indirect, travel)
480 $times = dt_times($row['pc_eid']);
483 if ( $cas == 'Tijdschrijven' ) $totaltime +
= $times['dirtime'];
484 if ( $cas == 'Dagbesteding' ) $totaltime +
= ($times['dirtime'] * 15); // not used yet!
485 } else if ( $ver == 2 ) {
486 //if ( $cas == 'Tijdschrijven' || $cas == 'Dagbesteding' ) $totaltime += $times['dirtime'];
487 if ( $cas == 'Tijdschrijven' ) $totaltime +
= $times['dirtime'];
488 if ( $cas == 'Dagbesteding' ) $totaltime +
= ($times['dirtime'] * 60); // not used yet!
497 //-----------------------------------------------------------------------------
501 * NOTE: openemr doesn't use it in 2008
506 function dt_kmt004() {
510 //-----------------------------------------------------------------------------
514 * The registered primary (main) diagnosis falls under category parameter1 (CL_DIAGNOSE)
516 * Example: if the asked value of CL_DIAGNOSE_CODE is AS1_6 then all CL_DIAGNOSE_CODE
517 * values As1_6* are valid (all values in the same hierarchy)
519 * @param int $node- node to look parameter for
522 function dt_kmn001($node) {
525 $par = dt_whatparam($node, 1);
526 $maindia = df_get_main_diagnose($dbcid);
528 return (strpos($maindia, $par) === 0);
531 //-----------------------------------------------------------------------------
535 * NOTE: not used by us
539 function dt_kmp001() {
543 //-----------------------------------------------------------------------------
547 * NOTE: openemr doesn't use it in 2008
552 function dt_kmc001() {
557 //-----------------------------------------------------------------------------
559 * ALL EVENTS FOR A DBC
561 * between opening date and closing date
564 * @return mysqlresult
566 function dt_allevents() {
567 global $dbcid, $enddate;
569 $dia = content_diagnose($dbcid);
570 $odate = mysql_real_escape_string($dia['ax_odate']);
571 $cdate = ( isset($_SESSION['eind']) && $_SESSION['eind'] ) ?
mysql_real_escape_string($_SESSION['eind']) : $enddate;
572 if ( !$cdate ) $cdate = date('Y-m-d'); //as a precaution
573 $pid = ( $dbcid ) ?
what_patient($dbcid) : $_SESSION['pid'];
575 // find all events from DBC opening 'till closing date
576 $q = sprintf("SELECT pc_eid, pc_aid FROM openemr_postcalendar_events
577 WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_eventDate <= '%s' AND pc_apptstatus = '@' ",
578 $pid, $odate, $cdate);
579 $r = mysql_query($q) or die(mysql_error());
585 //-----------------------------------------------------------------------------
589 * returns direct, indirect and travel time (all in minutes)
591 * @param int $eid - event id
594 function dt_times($eid = 0) {
595 if ( !$eid ) return 0;
597 // for JOIN - if the second table has inconsistency of data (missing record for an events)
598 // a 'bug' occur and the direct time become 0
599 //$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);
600 $qt = sprintf("SELECT pc_duration FROM openemr_postcalendar_events WHERE pc_eid = %d ", $eid);
601 $rt = mysql_query($qt) or die(mysql_error());
602 $rowt = mysql_fetch_array($rt);
605 $rez['dirtime'] = $rowt['pc_duration'] / 60;
608 $qi = sprintf("SELECT indirect_time, travel_time FROM cl_time_activiteit WHERE event_id = %d ", $eid);
609 $ri = mysql_query($qi) or die(mysql_error());
611 if ( mysql_num_rows($ri) ) {
612 $rowi = mysql_fetch_array($ri);
614 $rez['indtime'] = $rowi['indirect_time'];
616 $rez['tratime'] = $rowi['travel_time'];
622 //-----------------------------------------------------------------------------
626 * after we have a result, we look up the right productgroep
629 * @param string $endate - ending date for the DBC
630 * @return array - two values id|name
632 function dt_whatproductgroep($rfsum, $endate) {
635 // to avoid the bug: first time, it doesn't display properly
637 $dc = content_diagnose($dbcid);
638 $endate = $dc['ax_cdate'];
641 $q = sprintf("SELECT cl_productgroep_sysid as cps, cl_productgroep_beschrijving as cpb
642 FROM cl_productgroep WHERE cl_productgroep_code = %d
643 AND cl_productgroep_begindatum <= '%s' AND cl_productgroep_einddatum >= '%s' ", $rfsum, $endate, $endate);
644 $r = mysql_query($q) or die(mysql_error());
646 $row = mysql_fetch_array($r);
648 $res['id'] = $row['cps']; $res['name'] = $row['cpb'];
653 //-----------------------------------------------------------------------------
657 * last step in the decision tree
659 * @param int $zsysid - zorg sysid
660 * @param int $pgroep - productgroep sysid
661 * @param int $dbcid - dbcid
664 function dt_prestatiecode($zsysid, $pgroep, $dbcid) {
667 // ZORGTYPE ----------------
668 $qz = sprintf("SELECT cl_zorgtype_prestatiecodedeel AS czp FROM cl_zorg WHERE cl_zorgtype_sysid = %d ", $zsysid);
669 $rz = mysql_query($qz) or die(mysql_error());
670 $rowz = mysql_fetch_array($rz);
672 $czp = (int)$rowz['czp']; $czp = str_pad($czp, 3, '0', STR_PAD_LEFT
);
673 $resstr .= substr($rowz['czp'], 0, 3); // only 3 characters allowed
675 // DIAGNOSE ----------------
676 $qd = sprintf("SELECT cl_productgroep_diagnose_blinderen AS cdb, cl_productgroep_code as cpc
677 FROM cl_productgroep WHERE cl_productgroep_sysid = %d ", $pgroep);
678 $rd = mysql_query($qd) or die(mysql_error());
679 $rod = mysql_fetch_array($rd);
681 // posible values 1 - 0
682 if ( $rod['cdb'] == 1 ) {
685 // find CL_DIAGNOSE_PRESTATIECODEDEEL for the main diagnose
686 $maind = df_get_main_diagnose($dbcid);
687 $qpre = sprintf("SELECT cl_diagnose_prestatiecodedeel FROM cl_diagnose WHERE cl_diagnose_code = '%s' ",
689 $rpre = mysql_query($qpre) or die(mysql_error());
690 $rowpre = mysql_fetch_array($rpre);
692 $resstr .= ( $rowpre['cl_diagnose_prestatiecodedeel'] ) ?
$rowpre['cl_diagnose_prestatiecodedeel'] : '000' ;
695 // PRODUCTGROEP CODE ----------------
696 $resstr .= str_pad($rod['cpc'], 6, '0', STR_PAD_LEFT
);
698 // save it to the table
699 $qu = sprintf("UPDATE cl_axes SET ax_pcode='%s' WHERE ax_id = %d ", $resstr, $dbcid);
700 mysql_query($qu) or die(mysql_error());
703 //-----------------------------------------------------------------------------