added ending dates of service
[openemr.git] / library / DBC_validations.php
blobeaa34ae9aad0ac323d0df5a4b9b83e198a3cf211
1 <?php
2 /**
3 * DBC DUTCH SYSTEM
4 * Validation functions
5 *
6 * Cristian NAVALICI (lemonsoftware [..] gmail [.] com)
7 * January 2008
8 */
10 // ----------------------------------------------------------------------------
11 /**
12 * VALIDATE CIRCUIT VALUE
14 * validates the circuit code
16 * @param int $circode
17 * @return bool - an integer for true, otherwise FALSE
19 function vl_validate_circuit($circode = 0) {
20 if ( !$circode ) return FALSE;
22 $q = sprintf("SELECT * FROM cl_circuit WHERE cl_circuit_code = %d ", $circode);
23 $r = mysql_query($q) or die (mysql_error());
24 return mysql_num_rows($r);
28 // ----------------------------------------------------------------------------
29 /**
30 * VALIDATE REDENCODE
32 * validates the redensluiten code
34 * @param int $redencode
35 * @return bool - an integer for true, otherwise FALSE
37 function vl_validate_redencode($redencode = 0) {
38 if ( !$redencode ) return FALSE;
40 $q = sprintf("SELECT * FROM cl_redensluiten WHERE cl_redensluiten_code = %d ", $redencode);
41 $r = mysql_query($q) or die (mysql_error());
42 return mysql_num_rows($r);
46 // ----------------------------------------------------------------------------
47 /**
48 * VALIDATE DIAGNOSES
50 * validates the diagnoses from dbc before saving them
52 * @param none
53 * @return bool
55 function vl_validate_diagnoses() {
56 $as1 = $_SESSION['as1']; $as2 = $_SESSION['as2']; $as3 = $_SESSION['as3'];
57 $as4 = $_SESSION['as4']; $as5 = $_SESSION['as5'];
58 // as a caution we check for posas. must be NOT null
59 $posas = ( $_SESSION['posas'] ) ? (int)$_SESSION['posas'] : 1; // default value
61 // we presume that $good is true; one single value of FALSE, and everything blows up! ;)
62 $good = TRUE;
63 // an array with all diagnoses
64 $alldiag = array();
66 // diagnose type 1
67 foreach ( $as1 as $a1 ) {
68 $good &= vl_diagnose_exist($a1);
69 $alldiag[] = $a1;
71 if ( !$good ) return FALSE;
73 // diagnose type 2
74 foreach ( $as2 as $a2 ) {
75 $good &= vl_diagnose_exist($a2['code']);
76 $alldiag[] = $a2['code'];
78 if ( !$good ) return FALSE;
80 if ( vl_main_forbidden($alldiag[$posas-1]) ) return FALSE;
82 // diagnose type 3 + 4
83 $good &= vl_diagnose_exist($as3); $alldiag[] = $as3;
84 $good &= vl_diagnose_exist($as4); $alldiag[] = $as4;
86 // diagnose type 5
87 if ( patient_age($_SESSION['pid']) >= 4 ) {
88 $good &= vl_diagnose_exist($as5['gaf1']);
89 $alldiag[] = $a5['gaf1'];
92 // now we check for unique values
93 // the arrays must be the same if there are no duplicated values
94 $uniqdiag = array_unique($alldiag);
95 if ( count($uniqdiag) != count($alldiag) ) $good &= FALSE;
97 return $good;
102 // ----------------------------------------------------------------------------
104 * SIMPLE CHECK IF A DIAGNOSE EXISTS
106 * check if a diagnose is valid (exists in database)
108 * @access private
109 * @param string $diag - diagnose to check
110 * @return bool
112 function vl_diagnose_exist($diag) {
113 $q = sprintf("SELECT * FROM cl_diagnose WHERE cl_diagnose_code = '%s' ", trim($diag));
114 $r = mysql_query($q) or die (mysql_error());
115 return mysql_num_rows($r);
119 // ----------------------------------------------------------------------------
121 * VALIDATE ZORGCODE
123 * validates the zorg sysid
125 * @param int $zorgsysid
126 * @return bool - an integer for true, otherwise FALSE
128 function vl_validate_zorg($zorgsysid = 0) {
129 if ( !$zorgsysid ) return FALSE;
131 $q = sprintf("SELECT * FROM cl_zorg WHERE cl_zorgtype_sysid = %d ", $zorgsysid);
132 $r = mysql_query($q) or die (mysql_error());
133 return mysql_num_rows($r);
137 // ----------------------------------------------------------------------------
139 * CHECK IF THE MAIN DIAGNOSE IS NOT ON THE FORBIDDEN LIST OF ITEMS
141 * @access private
142 * @param string $diag - diagnose to check
143 * @return bool - true if it's forbidden
145 function vl_main_forbidden($diag) {
147 $forbidden_list = array('as1_18.02', 'as1_18.03', 'as2_18.02', 'as2_18.03', 'as2_17.01', 'as2_01.01.01',
148 'as2_01.01.02', 'as2_01.01.03', 'as2_01.01.04', 'as2_01.01.05');
149 $diag = trim($diag);
151 return in_array($diag, $forbidden_list);
158 // ----------------------------------------------------------------------------
160 * LOG
162 * simple function to log different events
164 * @param string $string
165 * @return
167 function vl_log($string) {
168 $file = TMPDIR_DBC . '/DBC_problems.log';
169 if ( !$h = fopen($file, 'ab') ) {
170 echo "Cannot create file ($filename)";
171 exit;
174 $content = date('d-m-Y') . " $string \r\n";
176 // WRITE DATA TO FILE
177 if ( fwrite($h, $content) === FALSE ) {
178 echo "Cannot write to file ($filename)";
179 exit;
182 fclose($h);
187 // ----------------------------------------------------------------------------
189 * VERIFY PATIENT AGE WHEN CLOSING A DBC
191 * At the moment of closing DBC, if we have ZTC code = 115 | 210 (Ondertoezichtstelling)
192 * the patient must have the age < 18 years at the moment of opening DBC.
193 * We leave $ztcode here because we are sure that this code validation has already take place.
195 * @param int $ztcode - zorg code from the dropdown
196 * @param string $axodate - opening date for the DBC
197 * @param int $pid - patient id
198 * @return bool
200 function vl_ztc_age($ztcode = 0, $axodate = 0, $pid = 0) {
201 if ( !$ztcode || !$axodate || !$pid) return FALSE;
203 // these are the only 2 checked codes
204 if ( ( $ztcode != '180115') && ($ztcode != '180210') ) return TRUE;
206 $age = patient_age($pid);
208 return ( $age < 18 );
212 // ----------------------------------------------------------------------------
214 * VERIFY IF THE CLOSING DATE IS BIGGER THAN LAST ACTIVITY DATE
216 * At the moment of closing DBC, we must have the closing date bigger than
217 * the date of the last activity associated with that DBC.
218 * With other words, the DBC must be closed AFTER all activities.
220 * @param string $eind - closing date
221 * @param int $axid - id for DBC
222 * @param int $pid - patient ID
223 * @return array - bool + string (result and lastdate)
225 function vl_eind_event($eind = 0, $axid = 0, $pid = 0) {
226 if ( !$eind || !$axid || !$pid) return FALSE;
228 // begin date for DBC
229 $cd = content_diagnose($axid);
230 $bd_dbc = $cd['ax_odate'];
232 // find all events between DBC's dates and sum up total times
233 $q = sprintf("SELECT MAX(pc_eventDate) AS pcdate
234 FROM openemr_postcalendar_events
235 WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_apptstatus = '@' ",
236 $pid, $bd_dbc);
237 $r = mysql_query($q) or die(mysql_error());
239 if ( !mysql_num_rows($r) ) return FALSE;
240 $row = mysql_fetch_array($r);
241 $lastdate = strtotime($row['pcdate']);
242 $axdate = strtotime($eind);
244 $result['bool'] = ( $axdate >= $lastdate );
245 $result['date'] = $row['pcdate'];
247 return $result;
250 // ----------------------------------------------------------------------------
252 * VALIDATE THE TIMINGS FOR A SPECIFIC ACTIVITY
254 * if activity is act_1 or act_7% then no times (encounter, travel, indirect must be 0)
255 * NOTE: apparently not used anymore
257 * @param string $ac - activity string
258 * @return bool - true (there are no timings) if activity matches conditions
260 function vl_activity_timing($ac) {
261 return ( $ac == 'act_1' || (strpos($ac, 'act_7') !== FALSE) );
266 // ----------------------------------------------------------------------------
268 * VALIDATE THE TRAVEL TIME FOR A SPECIFIC ACTIVITY
270 * if activity has mag_reistijd code = N (in cl_activiteit table), then no travel time
272 * @param string $ac - activity string
273 * @return bool - true (there are no timings) if activity matches conditions
275 function vl_activity_travel($ac) {
276 $q = sprintf("SELECT cl_activiteit_mag_reistijd AS reis FROM cl_activiteit WHERE cl_activiteit_code = '%s' ", $ac);
277 $r = mysql_query($q) or die (mysql_error());
279 $row = mysql_fetch_array($r);
280 return ( $row['reis'] == 'N' );
283 // ----------------------------------------------------------------------------
285 * CHECK FOR ZORGTYPE CODE VALUE OF 104
287 * if zorgtype code = 104 (sysid 180104), then all activities must have cl_activiteit_mag_groep = N
288 * must be called from within the openemr/dbc closing form
290 * @param none
291 * @return bool - true if all activities meet conditions
293 function vl_zorgtype_104() {
294 $dia = content_diagnose($_SESSION['show_axid']);
295 $odate = $dia['ax_odate'];
296 $pid = (int)$_SESSION['pid'];
298 // find all events from DBC opening and look for activities
299 $q = sprintf("SELECT pc_eid FROM openemr_postcalendar_events
300 WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_apptstatus = '@' ",
301 $pid, $odate);
302 $r = mysql_query($q) or die(mysql_error());
304 $res = TRUE;
305 while ( $row = mysql_fetch_array($r) ) {
306 $qe = sprintf("SELECT cl_activiteit_mag_groep AS cgroep FROM cl_activiteit ca
307 JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
308 WHERE cea.event_id = %d", $row['pc_eid']);
309 $re = mysql_query($qe) or die(mysql_error());
310 $rowe = mysql_fetch_array($re);
312 if ( $rowe['cgroep'] != 'N' ) {
313 $res = FALSE; break;
315 } // while
317 return $res;
321 // ----------------------------------------------------------------------------
323 * CHECK FOR ZORGTYPE CODE VALUE OF 104
325 * if zorgtype code = 104 (sysid 180104), then direct time must be < 180
326 * must be called from within the openemr/dbc closing form
328 * @param none
329 * @return bool - true if all activities meet conditions
331 function vl_zorgtype_880() {
332 $ttime = total_time_spent();
334 return ( $ttime['total_time'] < 180);
338 // ----------------------------------------------------------------------------
340 * CHECK FOR ZORGTYPE CODE VALUE OF 106
342 * if zorgtype code = 106 (sysid 180106), then direct time must be <= 250
343 * must be called from within the openemr/dbc closing form
345 * @param none
346 * @return bool - true if all activities meet conditions
348 function vl_zorgtype_106() {
349 $ttime = total_time_spent();
350 $direct_time = $ttime['total_time'] - $ttime['indirect_time'] - $ttime['travel_time'];
352 return ( $direct_time <= 250);
356 // ----------------------------------------------------------------------------
358 * CHECK FOR ZORGTYPE CODE VALUE OF 102
360 * if zorgtype code = 102 (sysid 180102), then total length of DBC must be < 29 days
361 * must be called from within the openemr/dbc closing form
363 * @param int $axid - DBC id
364 * @param string $eind - ending date
365 * @return bool - true if the conditions are met
367 function vl_zorgtype_102($axid, $eind) {
369 $len = df_dbc_age($axid, $eind);
371 return ( $len < 29);
376 // ----------------------------------------------------------------------------
378 * CHECK FOR ZORGTYPE CODE VALUE OF 111
380 * if zorgtype code = 111 (sysid 180111), then there is at least one provider with
381 * job starting with MB*.
382 * must be called from within the openemr/dbc closing form
384 * @param none
385 * @return bool - true if it's at least one provider with MB
387 function vl_zorgtype_111() {
388 $dia = content_diagnose($_SESSION['show_axid']);
389 $odate = $dia['ax_odate'];
390 $pid = (int)$_SESSION['pid'];
392 // find all events from DBC opening and look for activities
393 $q = sprintf("SELECT pc_aid, pc_eid FROM openemr_postcalendar_events
394 WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_apptstatus = '@' ",
395 $pid, $odate);
396 $r = mysql_query($q) or die(mysql_error());
398 $res = FALSE;
399 while ( $row = mysql_fetch_array($r) ) {
400 $qe = sprintf("SELECT cl_beroep_code AS cbc FROM cl_beroep cb
401 JOIN cl_user_beroep cub ON cub.cl_beroep_sysid = cb.cl_beroep_sysid
402 WHERE cub.cl_beroep_userid = %d ", $row['pc_aid']);
403 $re = mysql_query($qe) or die(mysql_error());
404 $rowe = mysql_fetch_array($re);
406 if ( strpos($rowe['cbc'], 'MB.') === 0 ) {
407 $res = TRUE; break;
409 } // while
411 // as a last resort, we check for the job of the provider who close the DBC
412 if ( !$res ) {
413 $ql = sprintf("SELECT cl_beroep_code AS cbc FROM cl_beroep cb
414 JOIN cl_user_beroep cub ON cub.cl_beroep_sysid = cb.cl_beroep_sysid
415 WHERE cub.cl_beroep_userid = %d ", $_SESSION['authId']);
416 $rl = mysql_query($ql) or die(mysql_error());
417 $rowl = mysql_fetch_array($rl);
418 if ( strpos($rowl['cbc'], 'MB.') === 0 ) {
419 $res = TRUE;
423 return $res;
428 // ----------------------------------------------------------------------------
430 * CHECK FOR REDENSLUITEN CODE 5 IF THERE ARE FORBIDDEN ACTIVITIES
432 * cl_activiteit_code should NOT contain act_3*, act_4*, act_5*, act_9* or act_10*)
433 * must be called from within the openemr/dbc closing form
435 * @param none
436 * @return void
438 function vl_redensluiten_5() {
439 $dia = content_diagnose($_SESSION['show_axid']);
440 $odate = $dia['ax_odate'];
441 $pid = (int)$_SESSION['pid'];
443 // find all events from DBC opening and look for activities
444 $q = sprintf("SELECT pc_eid FROM openemr_postcalendar_events
445 WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_apptstatus = '@' ",
446 $pid, $odate);
447 $r = mysql_query($q) or die(mysql_error());
449 $res = TRUE;
450 while ( $row = mysql_fetch_array($r) ) {
451 $qe = sprintf("SELECT cl_activiteit_code AS acode FROM cl_activiteit ca
452 JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
453 WHERE cea.event_id = %d", $row['pc_eid']);
454 $re = mysql_query($qe) or die(mysql_error());
455 $rowe = mysql_fetch_array($re);
457 $c = $rowe['acode']; // activity code
459 // check for forbidden activities
460 $pos1 = strpos($c, 'act_3');
461 $pos2 = strpos($c, 'act_4');
462 $pos3 = strpos($c, 'act_5');
463 $pos4 = strpos($c, 'act_9');
464 $pos5 = strpos($c, 'act_10');
465 if ( ($pos1 === FALSE) && ($pos2 === FALSE) && ($pos3 === FALSE) && ($pos4 === FALSE) && ($pos5 === FALSE) ) {
466 $res = TRUE;
467 } else {
468 $res = FALSE; break;
470 } // while
472 return $res;
476 // ----------------------------------------------------------------------------
478 * CHECK FOR ALLOWED COMBINATION OF ACTIVITIES FOR A DBC
480 * the following are forbidden:
481 * ONLY act_4.2* or
482 * ONLY act_9* or
483 * act_4.2* in combination with act_1 || act_2 || act_7* || act_9*
485 * @param $dbcid - dbc id
486 * @return bool
488 function vl_validdbc_combinations($dbcid) {
489 $dia = content_diagnose($dbcid);
490 $odate = $dia['ax_odate'];
491 $cdate = $dia['ax_cdate'];
492 $pid = what_patient($dbcid);
494 // find all events from DBC opening to DBC closing and look for activities
495 $q = sprintf("SELECT pc_eid FROM openemr_postcalendar_events
496 WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_eventDate <= '%s' AND pc_apptstatus = '@'
497 AND pc_title != 'Blokkeren' ",
498 $pid, $odate, $cdate);
499 $r = mysql_query($q) or die(mysql_error());
501 $acodes = array();
502 while ( $row = mysql_fetch_array($r) ) {
503 $qe = sprintf("SELECT cl_activiteit_code AS acode FROM cl_activiteit ca
504 JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid
505 WHERE cea.event_id = %d", $row['pc_eid']);
506 $re = mysql_query($qe) or die(mysql_error());
507 $rowe = mysql_fetch_array($re);
509 // for forbidden ones, we use only pattern part
510 $ac = $rowe['acode']; // activity code
511 if ( strpos($ac, 'act_4.2') === 0 ) $acodes[] = 'act_4.2';
512 else if ( strpos($ac, 'act_7') === 0 ) $acodes[] = 'act_7';
513 else if ( strpos($ac, 'act_9') === 0 ) $acodes[] = 'act_9';
514 else $acodes[] = $ac;
516 } // while
518 // now we analyze all the activities codes
519 // check if all values are act_4.2* / act_9 forms
520 $c = array_count_values($acodes);
521 if ( $c['act_4.2'] == count($acodes) ) return FALSE;
522 if ( $c['act_9'] == count($acodes) ) return FALSE;
524 // now we check for combinations for act_4.2
525 if ( in_array('act_4.2', $c) ) {
526 $rez_1 = !( in_array('act_1', $c) || in_array('act_2', $c) || in_array('act_7', $c) || in_array('act_9', $c) );
527 } else $rez_1 = TRUE;
529 // now we check for act_10.2 condition
530 if ( in_array('act_10.2', $c) ) {
531 $rez_2 = in_array('act_3.2', $c);
532 } else $rez_2 = TRUE;
534 /*if ( in_array('act_9', $c) ) {
535 WORK ZONE !!!
538 // combine the results
539 return ($rez_1 && $rez_2);
541 // ----------------------------------------------------------------------------