From 9cf392cab3db049e03a17879147fc0c6ead0bacf Mon Sep 17 00:00:00 2001 From: lemonsoftwarero Date: Wed, 16 Apr 2008 10:10:53 +0000 Subject: [PATCH] DBC Dutch System --- library/DBC_Vektis.php | 1522 +++++++++++++++++++++++++++++++++ library/DBC_Vektis_constants.php | 75 ++ library/DBC_cfunctions.php | 217 +++++ library/DBC_cron.php | 56 ++ library/DBC_decisiontree.php | 705 +++++++++++++++ library/DBC_files.php | 1204 ++++++++++++++++++++++++++ library/DBC_functions.php | 1758 ++++++++++++++++++++++++++++++++++++++ library/DBC_include.php | 22 + library/DBC_validations.php | 540 ++++++++++++ library/js/add_edit_event.js | 155 ++++ library/js/jquery-calendar.css | 167 ++++ library/js/jquery-calendar.js | 814 ++++++++++++++++++ library/js/jquery.js | 31 + library/translation.inc.php | 56 ++ 14 files changed, 7322 insertions(+) create mode 100644 library/DBC_Vektis.php create mode 100644 library/DBC_Vektis_constants.php create mode 100644 library/DBC_cfunctions.php create mode 100644 library/DBC_cron.php create mode 100644 library/DBC_decisiontree.php create mode 100644 library/DBC_files.php create mode 100644 library/DBC_functions.php create mode 100644 library/DBC_include.php create mode 100644 library/DBC_validations.php create mode 100644 library/js/add_edit_event.js create mode 100644 library/js/jquery-calendar.css create mode 100644 library/js/jquery-calendar.js create mode 100644 library/js/jquery.js diff --git a/library/DBC_Vektis.php b/library/DBC_Vektis.php new file mode 100644 index 000000000..3648f4bc9 --- /dev/null +++ b/library/DBC_Vektis.php @@ -0,0 +1,1522 @@ +'; + } + + $bigline .= $_280; + + // count the total lines + global $lines2; + $lines2++; + + return $bigline; +} + + +//----------------------------------------------------------------------------- +/** + * GENERATE DEBTOR RECORD + * + * line 03 + * NOTE: we don't use it yet! + * + * @param none + * @return string + */ +function vk_generate_debtor() { + //0301 ATTRIBUTE RECORD + $_301 = '03'; + + // the total lenght for this line is 310 + $line = str_repeat(' ', 308); + + // count the total lines + global $lines3; + $lines3++; + + $bigline = $_301 . $line; + + return $bigline; +} + + +//----------------------------------------------------------------------------- +/** + * GENERATE SERVICE RECORD + * + * line 04 + * + * @param none + * @return string + */ +function vk_generate_service() { + // 0401 ATTRIBUTE RECORD + $_401 = '04'; + + // 0402 IDENTIFICATION DETAIL RECORD + $_402 = vk_unique_line_record(); + + // 0403 CIVILIAN SERVICE NUMBER (BSN) INSURED + $_403 = vk_patientdata('ssn'); + + // 0404 UZOVI-NUMBER + $_404 = vk_whatinsurance(1); + + // 0405 INSURED NUMBER (REGISTRATION NUMBER, RELATION NUMBER) + $_405 = vk_whatinsurance(2); + + // 0406 AUTOMATIC PAYMENT NUMBER + $_406 = str_repeat(' ', 15); + + // 0407 FORWARDING ALLOWED + $_407 = C407; + + // 0408 INDICATION SERVICE CODE LIST + $_408 = C408; + + // 0409 CLAIM CODE + $_409 = vk_claimcode('declaratie'); + + // 0410 START DATE + $_410 = vk_dbcdates(1); + + // 0411 END DATE + $_411 = vk_dbcdates(2); + + // 0412 DBC SERVICE CODE + $_412 = vk_claimcode('prestatie'); + + // 0413 NUMBER OF SERVICES PERFORMED + $_413 = C413; + + // 0414 HEALTHCARE TRAJECTORY NUMBER + $_414 = vk_dbcinfo('ztn'); + global $arr_database, $dbcidglobal; + $arr_database['cvd_ztn'][] = $_414; + $arr_database['cvd_dbcid'][] = $dbcidglobal; // we save also dbc id for db + + // 0415 TYPE OF SPECIALIST + $_415 = C415; + + // 0416 HEALTHCARE PROVIDER CODE + $_416 = C112; // agb code + + // 0417 CALCULATION PERCENTAGE + $_417 = C417; + + // 0418 TARIFF DBC/SERVICE (VAT INCL.) + $_418 = vk_dbcinfo('tariff'); + + if ( vk_is_overloop_dbc($dbcidglobal) ) { + // 0419 DEDUCTION TYPE + $_419 = '04'; + + // 0420 DEDUCTION AMOUNT + $dedamo = vk_deduction($dbcidglobal); + $_420 = str_pad($dedamo, 8, '0', STR_PAD_LEFT); + } else { + // 0419 DEDUCTION TYPE + $_419 = C419; + + // 0420 DEDUCTION AMOUNT + $_420 = str_pad(C420, 8, '0', STR_PAD_LEFT); + + } + + // 0421 AMOUNT CHARGED (VAT INCL.) + $_421i = round (((int)$_418 * $_417) / 10000); + $_421 = str_pad($_421i, 8, '0', STR_PAD_LEFT); + + // 0422 INDICATION DEBIT/CREDIT (01) + $_422 = C422; + + // 0423 VAT-PERCENTAGE CLAIM AMOUNT + $_423 = str_pad(C423, 4, '0', STR_PAD_LEFT); + + // 0424 CLAIM AMOUNT (VAT INCL.) + $_424i = $_421i - $dedamo; + if ( $_424i < 0 ) $_424i = 0; + $arr_database['cvd_tariff'][] = $_424i; + $_424 = str_pad($_424i, 8, '0', STR_PAD_LEFT); + + // 0425 INDICATION DEBIT/CREDIT (02) + $_425 = C422; + + // 0426 REFERENCE NUMBER THIS SERVICE RECORD + $_426 = vk_invoice_service(); + $arr_database['cvd_426'][] = $_426; + + // 0427 REFERENCE NUMBER PRECEDING RELATED SERVICE RECORD + $_427 = str_pad(C427, 20, ' ', STR_PAD_LEFT); + + // 0480 RESERVE + $_480 = str_repeat(' ', 94); // 94 chars empty string + + // concatenate the big string + $bigline = ''; + for ( $i = 1 ; $i <= 27 ; $i++ ) { + $avar = sprintf('_4%02s', $i); + $bigline .= ${$avar}; + } + + $bigline .= $_480; + + // count the total lines + global $lines4, $totalclaim; + $lines4++; + $totalclaim += $_424i; + + return $bigline; +} + + +//----------------------------------------------------------------------------- +/** + * GENERATE COMMENT + * + * line 05 + * NOTE: we don't use it yet! + * + * @param none + * @return string +*/ +function vk_generate_comment() { + //9801 ATTRIBUTE RECORD + $_9801 = '98'; + + // the total lenght for this line is 310 + $line = str_repeat(' ', 308); + + $bigline = $_9801 . $line; + + return $bigline; +} + + +//----------------------------------------------------------------------------- +/** + * GENERATE CLOSING RECORD + * + * line 06 + * + * @param none + * @return string + */ +function vk_generate_closing() { + global $lines2, $lines3, $lines4, $totalclaim; + + //9901 ATTRIBUTE RECORD + $_9901 = '99'; + + //9902 NUMBER OF INSURED RECORDS + $_9902 = str_pad($lines2, 6, '0', STR_PAD_LEFT); + + //9903 NUMBER OF DEBTOR RECORDS + $_9903 = str_pad($lines3, 6, '0', STR_PAD_LEFT); + + //9904 NUMBER OF SERVICE RECORDS + $_9904 = str_pad($lines4, 6, '0', STR_PAD_LEFT); + + //9905 NUMBER OF COMMENT RECORDS + $_9905 = '000000'; + + //9906 TOTAL NUMBER OF DETAIL RECORDS + $sumrow = (int)($_9902 + $_9903 + $_9904 + $_9905); + $_9906 = str_pad($sumrow, 7, '0', STR_PAD_LEFT); + + //9907 TOTAL CLAIM AMOUNT + $_9907 = str_pad($totalclaim, 11, '0', STR_PAD_LEFT); + + //9908 INDICATION DEBIT/CREDIT + $_9908 = 'D'; + + // 9980 RESERVE + $_9980 = str_repeat(' ', 265); // 265 chars empty string + + // concatenate the big string + $bigline = ''; + for ( $i = 1 ; $i <= 8 ; $i++ ) { + $avar = sprintf('_99%02s', $i); + $bigline .= ${$avar}; + } + + $bigline .= $_9980. "\r\n"; + vk_write_file($bigline); // this is written just once per file +} + + + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +/** + * FIND UZOVI CODE / POLICY NUMBER FOR THIS DBC + * + * @param int $uzflag = 1 returns uzovi code; $uzflag != 1 returns policy code + * @return string + */ +function vk_whatinsurance($uzflag = 1) { + global $patientglobal; + $insurer = get_insurers_nl($patientglobal, 1); + $uzovi = $insurer['pin_provider']; + $policy = $insurer['pin_policy']; + + if ( !$uzovi ) { + global $_407global; + $_407global = 2; + $policy = ''; + } + + $retval = ( $uzflag == 1 ) ? str_pad($uzovi, 4, '0', STR_PAD_LEFT) : str_pad($policy, 15, ' ', STR_PAD_LEFT); + return $retval; +} + + +//----------------------------------------------------------------------------- +/** + * GENERATE INVOICE NUMBER + * + * unique invoice number format YYYYMMDD0001 + * It permits max 9999 invoice / day ! + * + * @param none + * @return string + */ +function vk_invoice_number() { + $date = date('Ymd'); + + // retrieve auxiliary values + $rd = mysql_query("SELECT * FROM cl_aux WHERE aux_id = 'vk_0116_invoice'") or die(mysql_error()); + $rez = mysql_fetch_array($rd); + + // if date strings are NOT equal, then we must update the date field with today value + // and reset the counter (aux_varn) to 0 + if ( $date !== trim($rez['aux_varc']) ) { + $current_number = 1; + } else { + // we are in the same day, so we'll use the value from aux_varn (numeric) + $current_number = $rez['aux_varn'] + 1; + } // if else + + // update the auxiliary tables with the new values + $qu = sprintf("UPDATE cl_aux SET aux_varc = '%s', aux_varn = %d WHERE aux_id = 'vk_0116_invoice'", $date, $current_number); + mysql_query($qu) or die(mysql_error()); + + $uniqID = $date . str_pad($current_number, 4, '0', STR_PAD_LEFT); + return $uniqID; +} + +//----------------------------------------------------------------------------- +/** + * GENERATE INVOICE NUMBER FOR EVERY DBC (SERVICE) + * + * unique invoice number format 253-0001 (patient id from openemr + unique number) + * the last number is kept into auxiliary table + * + * @param none + * @return string + */ +function vk_invoice_service() { + global $patientglobal; + + // retrieve auxiliary values + $rd = mysql_query("SELECT * FROM cl_aux WHERE aux_id = 'vk_0426_invoice'") or die(mysql_error()); + $rez = mysql_fetch_array($rd); + + $uninum = $rez['aux_varn'] + 1; + + // update the auxiliary tables with the new values + $qu = sprintf("UPDATE cl_aux SET aux_varn = %d WHERE aux_id = 'vk_0426_invoice'", $uninum); + mysql_query($qu) or die(mysql_error()); + + $invoice_service = sprintf("%s-%04s", $patientglobal, $uninum); + + // padding as required + return str_pad($invoice_service, 20, ' ', STR_PAD_LEFT); +} + +//----------------------------------------------------------------------------- +/** + * GENERATE LINE IDENTIFICATION RECORD + * + * unique number for every generated line + * begins with 1 and the add 1 unit at a time + * + * @param none + * @return string + */ +function vk_unique_line_record() { + global $uniqueid; + + // add one unit to the global var + $uninum = $uniqueid + 1; + + // update the global var with the new value + $uniqueid = $uninum; + + // padding as required + $id = str_pad($uninum, 12, '0', STR_PAD_LEFT); + + return $id; +} + + +//----------------------------------------------------------------------------- +/** + * GET PATIENT DATA + * + * returns different informations about patient + * it works with multibyte strings, so mb extension must be enabled! + * + * @param string $param + * @return string + */ +function vk_patientdata($param = 'pid') { + mb_internal_encoding('UTF-8'); + + global $patientglobal; + $pat = getPatientData($patientglobal); + $patnl = getPatientDataNL($patientglobal); + + switch ( $param ) { + case 'pid': $retval = str_pad($patientglobal, 11, ' ', STR_PAD_RIGHT); break; + case 'ssn': $retval = ( $pat['ss'] ) ? str_pad($pat['ss'], 9, '0', STR_PAD_LEFT) : '999999999'; break; + case 'dob': $retval = str_replace('-', '', $pat['DOB']); break; + + case 'sex': if ( $pat['sex'] == 'Male' ) $retval = 1; else if ( $pat['sex'] == 'Female' ) $retval = 2; + else $retval = 1; break; + + case 'namecode_patient': + // there are four codes but we use only 1-3. no 4 + /*$pname = $patnl['pdn_pxlast'] .' '. $pat['lname']; // patient's name + $parname = $patnl['pdn_pxlastpar'] .' '. $patnl['pdn_lastpar']; // partner's name + $pname = trim($pname); $parname = trim($parname); + + if ( $pname && $parname) $code = 3; + else if ( $pname && !$parname) $code = 1; + else if ( !$pname && $parname ) $code = 2; + $retval = $code;*/ + $retval = 1; + break; + + case 'namepat': + $inival = mb_strpad($pat['lname'], 25, ' ', STR_PAD_RIGHT); + $retval = mb_strtoupper($inival, 'UTF-8'); + break; + case 'pxnamepat': + $inival = str_pad($patnl['pdn_pxlast'], 10, ' ', STR_PAD_RIGHT); + $retval = mb_strtoupper($inival, 'UTF-8'); + break; + + case 'namecode_partner': + $par = trim($patnl['pdn_lastpar']); + return ( $par ? 2 : 0 ); + break; + + case 'nameusage': + $_209 = 1 ; // for us always 1 otherwise vk_patientdata('namecode_patient'); + $_212 = vk_patientdata('namecode_partner'); + $retval = ( $_212 ) ? 3 : 0; + break; + + case 'namepar': + $inival = mb_strpad($patnl['pdn_lastpar'], 25, ' ', STR_PAD_RIGHT); + $retval = mb_strtoupper($inival, 'UTF-8'); + break; + case 'pxnamepar': + $inival = str_pad($patnl['pdn_pxlastpar'], 10, ' ', STR_PAD_RIGHT); + $retval = mb_strtoupper($inival, 'UTF-8'); + break; + + case 'initials': + $ini = trim($patnl['pdn_initials']); + $ini_new = ( $ini ) ? preg_replace('/[^a-zA-Z]*/','', $ini) : ''; + $retval = str_pad($ini_new, 6, ' ', STR_PAD_RIGHT); + break; + + case 'postalcode': + // check for country code + $pcode = ( $pat['country_code'] == CNLCODE ) ? $pat['postal_code'] : '' ; + $retval = str_pad($pcode, 6, ' ', STR_PAD_LEFT); + break; + case 'foreignpostalcode': + // check for country code + $pcode = ( $pat['country_code'] != CNLCODE ) ? $pat['postal_code'] : '' ; + $retval = str_pad($pcode, 9, ' ', STR_PAD_LEFT); + break; + + case 'stnumber': $retval = str_pad($patnl['pdn_number'], 5, '0', STR_PAD_LEFT); break; + case 'stnumberaffix': $retval = str_pad($patnl['pdn_addition'], 6, ' ', STR_PAD_LEFT); break; + + case 'countrycode': + $ccode = ( $pat['country_code'] != CNLCODE ) ? $pat['country_code'] : ''; + $twocode = ( $ccode ) ? vk_countrycode($ccode) : ''; + $retval = str_pad($twocode, 2, ' ', STR_PAD_LEFT); + break; + } + + return $retval; + +} + +//----------------------------------------------------------------------------- +/** + * FIND THE ISOCODE FOR A COUNTRY CODE + * + * the two digits code + * + * @param int $cid - country id + * @return string + */ +function vk_countrycode($cid) { + $q = sprintf("SELECT * FROM geo_country_reference WHERE countries_id = %d ", $cid); + $r = mysql_query($q); + $row = mysql_fetch_array($r); + return $row['countries_iso_code_2']; +} + +//----------------------------------------------------------------------------- +/** + * PRESTATIE CODE TABLE + * + * get values from it + * + * @param string $flag prestatie - cl_dbc_prestatiecode | declaratie for cl_declaratiecode + * @return string + */ +function vk_claimcode($flag = 'prestatie') { + global $dbcidglobal; + $cdbc = content_diagnose($dbcidglobal); + $pcode = $cdbc['ax_pcode']; + $cdate = $cdbc['ax_cdate']; + + switch ( $flag ) { + case 'prestatie': $retval = str_pad($pcode, 12, ' ', STR_PAD_LEFT); break; + case 'declaratie': + $q = sprintf("SELECT cl_declaratiecode AS cd FROM cl_prestatiecode WHERE cl_dbc_prestatiecode = '%s' + AND cl_prestatiecode_begindatum <= '%s' AND cl_prestatiecode_einddatum >= '%s' ", $pcode, $cdate, $cdate); + $r = mysql_query($q) or die(mysql_error()); + + if ( $row = mysql_fetch_array($r) ) $retval = str_pad($row['cd'], 6, ' ', STR_PAD_LEFT); + else $retval = str_pad('', 6, ' ', STR_PAD_LEFT); + break; + } + + return $retval; +} + +//----------------------------------------------------------------------------- +/** + * DBC DATES + * + * return the start/end dates for a DBC + * + * @param int $flag 1-opening date 2-closing date + * @return string + */ +function vk_dbcdates($flag = 1) { + global $dbcidglobal; + $cdbc = content_diagnose($dbcidglobal); + $odate = $cdbc['ax_odate']; + $cdate = $cdbc['ax_cdate']; + + // put them in vektis form YYYYMMDD + $od = str_replace('-','', $odate); + $cd = str_replace('-','', $cdate); + + return (( $flag == 1 ) ? $od : $cd); + +} + +//----------------------------------------------------------------------------- +/** + * DBC INFO + * + * return different informations about a DBC + * + * @param string $info + * @return + */ +function vk_dbcinfo($info = 'ztn') { + global $dbcidglobal; + $cdbc = content_diagnose($dbcidglobal); + + switch ( $info ) { + case 'ztn' : $ztn = $cdbc['ax_ztn']; $retval = str_pad($ztn, 20, ' ', STR_PAD_LEFT); break; + case 'tariff': + $decode = trim(vk_claimcode('declaratie')); + $date = trim(vk_dbcdates(2)); // closing date? + + $q = sprintf("SELECT cl_dbc_tarief FROM cl_dbc_tarief WHERE cl_declaratiecode = '%s' + AND cl_dbc_tarief_begindatum <= '%s' AND cl_dbc_tarief_einddatum >= '%s' ", $decode, $date, $date); + $r = mysql_query($q) or die(mysql_error()); + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); $val = $row['cl_dbc_tarief']; + } else { + $val = 0; + } + $retval = str_pad($val, 8, '0', STR_PAD_LEFT); + break; + } + + return $retval; +} + +//----------------------------------------------------------------------------- +/** + * WRITE THE DATA INTO THE FILE + * + * write the provided date into the file + * + * @param string $data + * @return + */ +function vk_write_file($data) { + global $filepointer; + if ( !$filepointer ) return FALSE; + + flock($filepointer, LOCK_EX); + fwrite($filepointer, $data); + flock($filepointer, LOCK_UN); + +} + +//----------------------------------------------------------------------------- +/** + * COUNT THE TOTAL NUMBER OF DBC READY FOR VEKTIS GENERATION + * + * @param int $type - the vektis records type (new; old - to be resubmited) + * @return int + */ +function vk_number_ready($type = 1) { + switch ( $type ) { + case '1': $type = 1; break; + case '3': $type = 3; break; + default: $type = 1; + } + + $q = sprintf("SELECT COUNT(*) AS c FROM cl_axes WHERE ax_vkstatus = $type "); + + $r = mysql_query($q) or die(mysql_error()); + $row = mysql_fetch_array($r); + return (int)$row['c']; +} + +//----------------------------------------------------------------------------- +/** + * RETURN DBCs READY FOR VEKTIS GENERATION + * + * statuses 0 - DBC open, nothing to do + * 1 - DBC closed; to be sent to VK + * 2 - DBC closed; sent to VK but w/out returning codes + * 3 - DBC closed; sent to VK and invalid; to be resubmited + * 4 - DBC closed; sent to VK and validated. + * @param int $status - what status do you want + * @return array + */ +function vk_vektis_ready($status = 1) { + $q = sprintf("SELECT ax_id FROM cl_axes WHERE ax_vkstatus = %d", $status); + $r = mysql_query($q) or die(mysql_error()); + + $result = array(); + if ( mysql_num_rows($r) ) { + while ( $row = mysql_fetch_array($r) ) { + $result[] = content_diagnose($row['ax_id']); + } // while + } else { + return FALSE; + } + + return $result; +} + + +//----------------------------------------------------------------------------- +/** + * GENERATE AN UNIQUE SESSION ID + * + * it's about vektis session - the generating for file stage + * an unique number for a moment in time + * + * @param none + * @return string + */ +function vk_vektis_session() { + return date('dmYHis'); +} + +//----------------------------------------------------------------------------- +/** + * DISPLAY THE GENERATED FILE + * + * + * @param none + * @return none + */ +function vk_display_file() { + global $filename; + + $link_filename = basename($filename); + echo "

The file $filename was generated.

"; + + $filepointer = @fopen($filename, "rb"); + $buffer = ''; + + if ( $filepointer ) { + while ( !feof($filepointer) ) { + $buffer .= fgets($filepointer, 1024); + } + } + + echo ""; +} + +//----------------------------------------------------------------------------- +/** + * COMMIT TO DB THE VEKTIS + * + * save to db the content of the newly generates Vektis file. + * + * @param none + * @return none + */ +function vk_db_commit() { + $arr_database = $_SESSION['arrdb']; + mysql_query("START TRANSACTION"); + mysql_query("BEGIN"); + + if ( $arr_database ) { + $data = date('Y-m-d', strtotime($arr_database['cvd_date'])); + // prepate the sql insert statements + foreach ( $arr_database['cvd_pid'] as $ak => $av ) { + $query = sprintf("INSERT INTO cl_vektis_data + (cvd_session, + cvd_pid, + cvd_date, + cvd_116, + cvd_uzovi, + cvd_ztn, + cvd_tariff, + cvd_426, + cvd_dbcid) + VALUES ('%s', %d, '%s', '%s', '%s', '%s', %d, '%s', %d)", + $arr_database['cvd_session'], + $av, + $data, + $arr_database['cvd_116'], + $arr_database['cvd_uzovi'][$ak], + trim($arr_database['cvd_ztn'][$ak]), + $arr_database['cvd_tariff'][$ak], + trim($arr_database['cvd_426'][$ak]), + $arr_database['cvd_dbcid'][$ak] + ); // $query + + // saving to the table + mysql_query($query) or die(mysql_error()); + + //echo '
'.print_r($query, true).'
'; // debug + } // foreach + + // marked the DBC's as sent to vektis + foreach ( $arr_database['cvd_dbcid'] as $dbcid) { + $queryupdate = sprintf("UPDATE cl_axes SET ax_vkstatus = 2 WHERE ax_id = %d ", $dbcid); + mysql_query($queryupdate) or die(mysql_error()); + } + } + + mysql_query("COMMIT"); +} + +//----------------------------------------------------------------------------- +/** + * PARSE THE UPLOADED FILE + * + * + * @param string $file + * @param int $state - 1 for simulation, 2 for real situation + * @return none + */ +function vk_parse_returning_file($file = '', $state = 1) { + if ( !$file ) return FALSE; + + $filepath = realpath($file); + $fp = @fopen($filepath, "rb"); + $buffer = ''; + $_SESSION['vk_retfile'] = $filepath; + + if ( $fp ) { + while ( !feof($fp) ) { + $buffer = fgets($fp); + + // we get the type of line from the first two digits + $f2 = substr($buffer, 0, 2); + switch ( $f2 ) { + case '01': + $extarr = vk_process_extra($buffer, 1); $com = vk_process_common($buffer, 1); + vk_shows_line($buffer, $extarr, $com, 1, $state); + break; + case '02': + $extarr = vk_process_extra($buffer, 2); $com = vk_process_common($buffer, 2); + vk_shows_line($buffer, $extarr, $com, 2, $state); + break; + case '04': + $extarr = vk_process_extra($buffer, 4); $com = vk_process_common($buffer, 4); + vk_shows_line($buffer, $extarr, $com, 4, $state); + break; + case '99': + $extarr = vk_process_extra($buffer, 99); $com = vk_process_common($buffer, 99); + vk_shows_line($buffer, $extarr, $com, 99); + break; + } + + } + } // if $fp + +} + +//----------------------------------------------------------------------------- +/** + * PROCESS EXTRA INFORMATIONS + * + * process extra informations from every line in returning file + * + * @param string $line - whole line (sent line + returning info) + * @param int $case - the line type + * @return array + */ +function vk_process_extra($line = '', $case = 1) { + if ( !$line ) return FALSE; + + // the start and len values are taken from the vektis documentation + switch ( $case ) { + case 1: + $start = 310; $len = 44; + $extrastr = mb_substr($line, $start, $len); + $_181 = mb_substr($extrastr, 0, 24); + $_182 = mb_substr($extrastr, 24, 8); + $_196 = mb_substr($extrastr, 32, 4); + $_197 = mb_substr($extrastr, 36, 4); + $_198 = mb_substr($extrastr, 40, 4); + $retarr = array('s181' => $_181, 's182' => $_182, 's196' => $_196, 's197' => $_197, 's198' => $_198); + break; + case 2: + $start = 310; $len = 12; + $extrastr = mb_substr($line, $start, $len); + $_296 = mb_substr($extrastr, 0, 4); + $_297 = mb_substr($extrastr, 4, 4); + $_298 = mb_substr($extrastr, 8, 4); + $retarr = array('s296' => $_296, 's297' => $_297, 's298' => $_298); + break; + case 4: + $start = 310; $len = 30; + $extrastr = mb_substr($line, $start, $len); + $_481 = mb_substr($extrastr, 0, 8); + $_482 = mb_substr($extrastr, 8, 1); + $_483 = mb_substr($extrastr, 9, 8); + $_484 = mb_substr($extrastr, 17, 1); + $_496 = mb_substr($extrastr, 18, 4); + $_497 = mb_substr($extrastr, 22, 4); + $_498 = mb_substr($extrastr, 26, 4); + $retarr = array('s481' => $_481, 's482' => $_482, 's483' => $_483, 's484' => $_484, 's496' => $_496, 's497' => $_497, 's498' => $_498); + break; + case 99: + $start = 45; $len = 12; + $extrastr = mb_substr($line, $start, $len); + $_9909 = mb_substr($extrastr, 0, 11); + $_9910 = mb_substr($extrastr, 11, 1); + $retarr = array('s9909' => $_9909, 's9910' => $_9910); + break; + default : return FALSE; + } // switch + + return $retarr; + +} + + +//----------------------------------------------------------------------------- +/** + * PROCESS COMMON INFORMATIONS + * + * common informations are the common elements from the file and already saved database + * there are the links between db saved info and returning file + * + * @param string $line - whole line (sent line + returning info) + * @param int $case - the line type + * @return none + */ +function vk_process_common($line = '', $case = 1) { + if ( !$line ) return FALSE; + + // the start and len values are taken from the vektis documentation + switch ( $case ) { + case 1: + $_116 = mb_substr($line, 80, 12); + $_117 = mb_substr($line, 92, 8); + $retarr = array('s116' => $_116, 's117' => $_117); + break; + case 2: + $_204 = mb_substr($line, 23, 4); + $_206 = mb_substr($line, 42, 11); + $retarr = array('s204' => $_204, 's206' => $_206); + break; + case 4: + $_414 = mb_substr($line, 99, 20); + $_418 = mb_substr($line, 136, 8); + $_426 = mb_substr($line, 176, 20); + $retarr = array('s414' => $_414, 's418' => $_418, 's426' => $_426); + break; + } // switch + + return $retarr; + +} + +//----------------------------------------------------------------------------- +/** + * VALIDATE THE RETURNING FILE + * + * + * + * + * @param string $errcode + * @return bool|array('valid' => true|false, 'letter' => 'X|T|D|space', 'expl' => explanation, 'code' => code) + */ +function vk_validate_vektis($errcode) { + // if we don't have a retcode, then return valid (aka do nothing) + if ( $errcode == '0000') return array('valid' => TRUE, 'letter' => '', 'expl' => '', 'code' => ''); + + $earr = vk_error_code($errcode); + $retarr = array(); + + if ( $earr ) { + switch ( $earr['cvr_content'] ) { + case 'X': + case 'T': + case 'D': $retarr['valid'] = FALSE; break; + default: $retarr['valid'] = TRUE; + } + $retarr['letter'] = $earr['cvr_content']; + $retarr['expl'] = $earr['cvr_expl']; + $retarr['code'] = $earr['cvr_code']; + } + + return $retarr; +} + +//----------------------------------------------------------------------------- +/** + * RETURN THE ERROR DESCRIPTION FOR A CODE + * + * works with cl_vektis_retcodes table + * + * @param string $retcode + * @return array + */ +function vk_error_code($retcode) { + $q = sprintf("SELECT * FROM cl_vektis_retcodes WHERE cvr_code = '%s' ", $retcode); + $r = mysql_query($q) or die(mysql_error()); + return mysql_fetch_array($r); +} + +//----------------------------------------------------------------------------- +/** + * SHOWS A LINE FROM THE VALIDATION FILE + * + * shows the validation result + * if in 'real' mode it saves also into db + * + * @param string $buffer - whole line + * @param array $extarr - extra fields + * @param array $com - common fields + * @param int $line - line type (e.g. 01, 04, 99) + * @param int $state - 1 simulation, 2 real + * @return + */ +function vk_shows_line($buffer, $extarr, $com, $line, $state = 1) { + + switch ( $line ) { + case 1: + $e1 = vk_validate_vektis($extarr['s196']); + $e2 = vk_validate_vektis($extarr['s197']); + $e3 = vk_validate_vektis($extarr['s198']); + break; + case 2: + $e1 = vk_validate_vektis($extarr['s296']); + $e2 = vk_validate_vektis($extarr['s297']); + $e3 = vk_validate_vektis($extarr['s298']); + break; + case 4: + $e1 = vk_validate_vektis($extarr['s496']); + $e2 = vk_validate_vektis($extarr['s497']); + $e3 = vk_validate_vektis($extarr['s498']); + break; + case 99: + $lastline = vk_format_msg($extarr, 1); + break; + } + + // common part + if ( $line != 99 ) { + if ( !$e1['valid'] || !$e2['valid'] || !$e3['valid'] ) { + $class = 'vk_error'; + $e = array($e1, $e2, $e3); + if ( $state == 2 ) vk_mod_vkstatus($line, $com, $e); + } else { + $class = 'vk_expl'; + } + } + + $e1str = ( $e1['expl'] ) ? vk_format_msg($e1) : ''; + $e2str = ( $e2['expl'] ) ? vk_format_msg($e2) : ''; + $e3str = ( $e3['expl'] ) ? vk_format_msg($e3) : ''; + + $msgline = ( $lastline ) ? $lastline : $e1str . $e2str . $e3str; + if ( $lastline ) $class = 'vk_expl'; + $shstr = "
$buffer
$msgline
"; + + // display the built string + echo $shstr; +} + +//----------------------------------------------------------------------------- +/** + * FORMATS THE MESSAGE FOR RETURNING CODES + * + * for the last line there is a special format + * + * @param array $e - all infos about a retcode + * @param bool $lastline - is the last line? (default:false) + * @return string + */ +function vk_format_msg($e, $lastline = 0) { + if ( $lastline ) { + $str = "TOTAL ASSIGNED AMOUNT: {$e['s9909']} D/C: {$e['s9910']}
"; + } else { + // common line format + $content = ( $e['letter'] != 'O') ? $e['letter'] : 'OK'; + $str = "CODE: {$e['code']} - {$e['expl']} ($content)
"; + } + + return $str; +} + +//----------------------------------------------------------------------------- +/** + * MODIFY THE VEKTIS STATUS + * + * + * @param int $line - in what line the error appeared + * @param array $com - common part (sent/returned files) + * @param array $ee - those three array errors + * @return + */ +function vk_mod_vkstatus($line, $com, $ee) { + // function of the line, we treat different the errors + switch ( $line ) { + case 1: + foreach ( $ee as $e) { + // for X-T letters on the first level we invalidate all the file + if ( $e['letter'] == 'X' || $e['letter'] == 'T' ) { + vk_file_invalidatevektis(); + } //if + } + break; + case 2: + $pid = $com['s206']; + foreach ( $ee as $e) { + // for X-T letters on the first level we invalidate all the file ?? + if ( $e['letter'] == 'D' ) { + vk_file_invalidatedbc($pid, 2); + } else if ( $e['letter'] == 'O' ){ + // make it valid + } + } + break; + case 4: + foreach ( $ee as $e) { + // for X-T letters on the first level we invalidate all the file ?? + if ( $e['letter'] == 'D' ) { + vk_file_invalidatedbc($com, 4); // we send as pid the common elements + } else if ( $e['letter'] == 'O' ){ + // make it valid + } + } + break; + default: return FALSE; + } // switch +} + + +//----------------------------------------------------------------------------- +/** + * RETURNS SOME FIELDS FROM THE FILE + * + * 116 - vektis invoice number for all the file + * + * + * @param string $var - what field + * @param string $ztn - what ztn to look for (needed only for 426 or so, because there are many lines) + * @return string|bool - the invoice number + */ +function vk_file_getvar($var = '116', $ztn = 0) { + + if ( !isset($_SESSION['vk_retfile']) || empty($_SESSION['vk_retfile']) ) { + return FALSE; + } + + // array that containts lines where are the requested var + $elemarr = array('116' => '01', '426' => '04'); + + $fp = @fopen($_SESSION['vk_retfile'], "rb"); + if ( $fp ) { + while ( !feof($fp) ) { + $buffer = fgets($fp); + // we get the type of line from the first two digits + $f2 = substr($buffer, 0, 2); + + // we parse all the lines looking for our line type + if ( $f2 == $elemarr[$var] ) { + // different cases + if ( $var = '116' ) { + $varfield = mb_substr($buffer, 80, 12); + } + + if ( $var = '426' ) { + // not needed in this moment + } + } + } + } else return FALSE; + + return trim($varfield); +} + + +//----------------------------------------------------------------------------- +/** + * INVALIDATE ALL VEKTIS FILE + * + * look for dbcs after unique vektis invoice number + * + * @param none + * @return void + */ +function vk_file_invalidatevektis() { + $inv = vk_file_getvar('116'); + + $q = sprintf("SELECT * FROM cl_vektis_data WHERE cvd_116 = '%s' ", $inv); + $r = mysql_query($q) or die(mysql_error()); + while ( $row = mysql_fetch_array($r) ) { + // 3 - means 'to be resubmitted' + $q2 = sprintf("UPDATE cl_axes SET ax_vkstatus = 3 WHERE ax_id = %d ", $row['cvd_dbcid']); + $r2 = mysql_query($q2) or die(mysql_error()); + } +} + +//----------------------------------------------------------------------------- +/** + * INVALIDATE ALL DBC FROM VEKTIS FILE + * + * for a specified patient + * + * @param int $pid - patient id + * @param int $case - what situation? row type 02 or 04 ? + * @return void + */ +function vk_file_invalidatedbc($pid, $case) { + + if ( $case == 2 ) { + $inv = vk_file_getvar('116'); + $q = sprintf("SELECT * FROM cl_vektis_data WHERE cvd_116 = '%s' AND cvd_pid = %d", $inv, $pid); + } else if ( $case == 4) { + // here we don't need the patient id but we use this var to retrieve the common elements + // so here, $pid means actually $com array + $q = sprintf("SELECT * FROM cl_vektis_data WHERE cvd_426 = '%s' ", trim($pid['s426'])); + } + + $r = mysql_query($q) or die(mysql_error()); + if ( mysql_num_rows($r) ) { + while ( $row = mysql_fetch_array($r) ) { + // 3 - means 'to be resubmitted' + $q2 = sprintf("UPDATE cl_axes SET ax_vkstatus = 3 WHERE ax_id = %d ", $row['cvd_dbcid']); + $r2 = mysql_query($q2) or die(mysql_error()); + } + } // if +} + +//----------------------------------------------------------------------------- +/** + * CHANGE DBC STATUS FROM 'WRONG TO RIGHT' + * + * wrong means it's 3 (to be resubmitted), right means it's 1 (to be sent) + * + * @param int $dbcid + * @return void + */ +function vk_dbc_resubmit($dbcid = 0) { + if ( !$dbcid ) return FALSE; + + // ax_vkstatus = 3 -> supplementary caution measure + $q = sprintf("UPDATE cl_axes SET ax_vkstatus = 1 WHERE ax_id = %d AND ax_vkstatus = 3 ", $dbcid); + mysql_query($q) or die(mysql_error()); + +} + +//----------------------------------------------------------------------------- +/** + * CUSTOM FUNCTION TO FIND SPECIAL DBC + * + * condition: Overloop DBCs (all DBCs with encounters both in 2007 and 2008): + * + * @param int $dbcid + * @return void + */ +function vk_is_overloop_dbc($dbcid = 0) { + if ( !$dbcid ) return FALSE; + + $dbc = content_diagnose($dbcid); + $odate = $dbc['ax_odate']; + $cdate = $dbc['ax_cdate']; + + global $patientglobal; + $pid = $patientglobal; + + // 2007 encounters + $q1 = mysql_query("SELECT COUNT(*) AS a FROM openemr_postcalendar_events WHERE pc_pid = $pid AND pc_apptstatus = '@' + AND pc_eventDate >= '$odate' AND pc_eventDate <= '2007-12-31' ") or die(mysql_error()); + $r1 = mysql_fetch_array($q1); + $enc2007 = $r1['a']; + + if ( $enc2007 ) { + // 2008 encounters + $q2 = mysql_query("SELECT COUNT(*) AS a FROM openemr_postcalendar_events WHERE pc_pid = $pid + AND pc_apptstatus = '@' + AND pc_eventDate >= '2008-01-01' AND pc_eventDate <= '$cdate' ") or die(mysql_error()); + $r2 = mysql_fetch_array($q2); + $enc2008 = $r2['a']; + } else { + $enc2008 = 0; + } //if $enc2007 + + return ($enc2007 && $enc2008); + +} + + +//----------------------------------------------------------------------------- +/** + * CUSTOM FUNCTION TO CALCULATE DEDUCTION FOR DBC's + * + * function of F* codes in 2007 (not 2008!) + * + * @param int $dbcid + * @return int + */ +function vk_deduction($dbcid = 0) { + global $patientglobal; + $pid = $patientglobal; + + $enarr = array( 'F101' => '2090', 'F102' => '20040', 'F103' => '41610', 'F104' => '10160', + 'F105' => '6840', 'F106' => '8550' , 'F221' => '4750', 'F151' => '2090', + 'F152' => '16150','F153' => '44170', 'F154' => '15290', 'F155' => '9780', + 'F156' => '9210', 'F224' => '4940'); + $total_sum = 0; + foreach ( $enarr as $ek => $ev ) { + $q = mysql_query("SELECT COUNT(*) AS a FROM openemr_postcalendar_events WHERE pc_pid = $pid AND pc_apptstatus = '@' AND pc_eventDate >= '2007-01-01' AND pc_eventDate <= '2007-12-31' AND pc_title LIKE '$ek%'"); + $r = mysql_fetch_array($q); + $total_sum += $r['a'] * $ev; + } + + $total_sum = round($total_sum); + + return $total_sum; +} + +//----------------------------------------------------------------------------- +?> diff --git a/library/DBC_Vektis_constants.php b/library/DBC_Vektis_constants.php new file mode 100644 index 000000000..10875368d --- /dev/null +++ b/library/DBC_Vektis_constants.php @@ -0,0 +1,75 @@ + \ No newline at end of file diff --git a/library/DBC_cfunctions.php b/library/DBC_cfunctions.php new file mode 100644 index 000000000..9e036beda --- /dev/null +++ b/library/DBC_cfunctions.php @@ -0,0 +1,217 @@ + diff --git a/library/DBC_cron.php b/library/DBC_cron.php new file mode 100644 index 000000000..c3e4f52a9 --- /dev/null +++ b/library/DBC_cron.php @@ -0,0 +1,56 @@ += 365 ) { + $newid = duplicate_dbc($row['ax_id']); + df_cronlog("DBC id: {$row['ax_id']} was duplicated with DBC id: $newid "); + } + } +} + +//----------------------------------------------------------------------------- +/** +CONNECT TO DATABASE + +make the connections to openemr database +the variables are taken from sqlconf.php + +@param none +@return void +*/ +function dc_connect() { + require_once(dirname(__FILE__) . '/sqlconf.php'); + global $host, $login, $pass, $dbase; + + $link = mysql_connect($host, $login, $pass); + if (!$link) { + die('Could not connect: ' . mysql_error()); + } + + mysql_query("USE " . $dbase); +} +?> \ No newline at end of file diff --git a/library/DBC_decisiontree.php b/library/DBC_decisiontree.php new file mode 100644 index 000000000..bc47c4629 --- /dev/null +++ b/library/DBC_decisiontree.php @@ -0,0 +1,705 @@ + ---------------
"; //debug + //echo "F:$function R: $r D: $direction SUM: $rfsum \n"; // debug for CLI + + if ( $direction ) dt_main($direction); + else { + global $enddate, $dbcid; + if ( !$dbcid ) $enddate = $_SESSION['eind']; // called from webinterface + + if ( !$dbcid ) { + // for a script, we must called this ourselves using global $rfsum and closing date + $a = dt_whatproductgroep($rfsum, $enddate); + // called from within openemr + $_SESSION['pgroep'] = $a['id']; + echo $a['name']; + } + } + + +} + +//----------------------------------------------------------------------------- +/** + * DECIDES WHAT TABLE WILL BE USED + * + * because the beslisboom has 2 tables (2007/2008), we must decide which one we'll use + * + * @param int $dbcid - in case we called this from a script (and we don't have $_SESSION) + * @param string $end - closing date for dbc + * @return void + */ +function dt_preinit($dbc, $end) { + // it sets some globals + global $beslis_table, $dbcid, $enddate; + $dbcid = $dbc; + $enddate = $end; + + $dbc = content_diagnose($dbcid); + $odate = $dbc['ax_odate']; + + if ( $odate <= '2007-12-31' ) { + $beslis_table = 'cl_beslisboom_2007'; + } elseif ( $odate >= '2008-01-01') { + $beslis_table = 'cl_beslisboom'; + } else { + // leave room for more versions :) + } + +} + + +//----------------------------------------------------------------------------- +/** + * COMPARISON + * + * function for comparison + * + * @param int $node - node to look for (and retrieve the one value) + * @param int $value to compare + * @return int - next node + */ +function dt_comparison($node, $rval) { + global $beslis_table; + $q = sprintf("SELECT * FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node); + + $r = mysql_query($q) or die(mysql_error()); + + if ( !mysql_num_rows($r) ) { + return 0; + } else { + $row = mysql_fetch_array($r); + + // compare the values function of the operator + switch ( $row['cbe_operator'] ) { + case '<=': $rez = ( $rval <= $row['cbe_value1'] ); break; + case '<': $rez = ( $rval < $row['cbe_value1'] ); break; + case '=': $rez = ( $rval == $row['cbe_value1'] ); break; + case '>=': $rez = ( $rval >= $row['cbe_value1'] ); break; + } + + // update the remember for sum variable + global $rfsum; + $rfsum += ( $rez ) ? $row['cbe_rfsumT'] : $row['cbe_rfsumF']; + + // next hop (node) + $ret = $rez ? $row['cbe_nodegoal_T'] : $row['cbe_nodegoal_F']; + + return $ret; + } +} + +//----------------------------------------------------------------------------- +/** + * WHAT FUNCTION IS USED FOR A SPECIFIED NODE + * + * function of node, we call a function + * + * @param int node + * @return string function name (in fact, a code from the tables) + */ +function dt_nodefunction($node) { + global $beslis_table; + $q = sprintf("SELECT cbe_checkKM AS km FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node); + $r = mysql_query($q) or die(mysql_error()); + + if ( !mysql_num_rows($r) ) { + return 0; + } else { + $row = mysql_fetch_array($r); + return $row['km']; + } +} + +//----------------------------------------------------------------------------- +/** + * WHAT PARAMETER IS NEEDED FOR KM* FUNCTION + * + * some KM* functions work with some parameter; this function retrieves from db + * + * @param int $node - KM node + * @param int $par - first or second param (1/2) + * @return string $param (empty string for no param) + */ +function dt_whatparam($node, $par = 1) { + global $beslis_table; + + if ( $par == 1 ) { + $q = sprintf("SELECT cbe_KMpar1 AS param FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node); + } else if ( $par == 2) { + $q = sprintf("SELECT cbe_KMpar2 AS param FROM %s WHERE cbe_nodeorigin = %d ", $beslis_table, $node); + } + $r = mysql_query($q) or die(mysql_error()); + + if ( !mysql_num_rows($r) ) { + return ''; + } else { + $row = mysql_fetch_array($r); + return $row['param']; + } +} + +//----------------------------------------------------------------------------- +/** + * KMA001 + * + * Number of days in clinic + * Days in clinic can be recognised by CL_ACTIVITEIT_SOORT=VERBLIJFSDAG. + * Exception: act_8.1.6* + * + * NOTE we don't use it now so it's always 0 + * + * @param none + * @return int + */ +function dt_kma001() { + return 0; +} + +//----------------------------------------------------------------------------- +/** + * KMA002 + * + * ver 1: Sum of all direct time of activities + total time dagbesteding + * 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) + * + * ver 2: Sum of all direct time of activities + 15 times the hours spent in dagbesteding + * 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) + * + * @param none + * @return int $totaltime + */ +function dt_kma002() { + $r = dt_allevents(); + $totaltime = 0; + + //choose here what $ver we'll use function of a date + //$dbc = content_diagnose($_SESSION['show_axid']); + //$odate = $dbc['ax_odate']; + //$ver = ( $odate <= '2007-12-31') ? 1 : 2; + $ver = 2 ; //we'll just use 2 because we don't have dagbestending + + while ( $row = mysql_fetch_array($r) ) { + $qe = sprintf("SELECT cl_activiteit_soort AS cas FROM cl_activiteit ca + JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid + WHERE cea.event_id = %d", $row['pc_eid']); + $re = mysql_query($qe) or die(mysql_error()); + $rowe = mysql_fetch_array($re); + + $cas = trim($rowe['cas']); + + // those three times for an event (direct, indirect, travel) + $times = dt_times($row['pc_eid']); + + // SUM UP TIMES + if ( $cas == 'Verblijfsdag' ) { + /*if ( $ver == 1) { + // because dagbesteding/daycare is registered in hours; not minutes + //$totaltime += ( $times['dirtime'] * 60 ); + } else if ( $ver == 2 ){ + // 15 times the hours spent in dagbesteding + //$totaltime += ( $times['dirtime'] * 15 ); + }*/ + } else if ( $cas == 'Tijdschrijven' ) { + $totaltime += $times['dirtime']; + } + } // while + + return $totaltime; +} + +//----------------------------------------------------------------------------- +/** + * KMA003 + * + * total minutes total time (Sum of all direct, indirect and travel time of activities + total time dagbesteding) + * + * @param none + * @return int + */ +function dt_kma003() { + $r = dt_allevents(); + $totaltime = 0; + + //choose here what $ver we'll use function of a date + //$dbc = content_diagnose($_SESSION['show_axid']); + //$odate = $dbc['ax_odate']; + //$ver = ( $odate <= '2007-12-31') ? 1 : 2; + $ver = 2; // it doesn't matter now. + + while ( $row = mysql_fetch_array($r) ) { + $qe = sprintf("SELECT cl_activiteit_soort AS cas FROM cl_activiteit ca + JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid + WHERE cea.event_id = %d", $row['pc_eid']); + $re = mysql_query($qe) or die(mysql_error()); + $rowe = mysql_fetch_array($re); + + // those three times for an event (direct, indirect, travel) + $times = dt_times($row['pc_eid']); + $totalt = $times['dirtime'] + $times['tratime'] + $times['indtime']; +//echo "{$rowe['cas']} TIME KMA003: $totalt
"; //debug + // SUM UP TIMES + if ( $rowe['cas'] == 'Verblijfsdag' ) { + /*if ( $ver == 1) { + // because dagbesteding/daycare is registered in hours; not minutes + $totaltime += ( $times['dirtime'] * 60 ); + } else if ( $ver == 2 ) { + // 15 times the hours spent in dagbesteding + $totaltime += ( $times['dirtime'] * 15 ); + }*/ + } else if ( $rowe['cas'] == 'Tijdschrijven' ) { + $totaltime += $totalt; + } +//echo "TOTALTIME KMA003: $totaltime EV: {$row['pc_eid']}
"; //debug + } // while + + return $totaltime; +} + +//----------------------------------------------------------------------------- +/** + * KMA004 + * + * number of separate kinds of jobs (e.g. Psychologist, psychiatrist, nurse, etc.) + * Count how many distinct CL_BEROEPEN_CODE values are in this DBC + * + * NOTE: openemr doesn't use it in 2008 + * + * @param none + * @return int - distinct values for cl_beroep_code + */ +function dt_kma004() { + $r = dt_allevents(); + $beroep = array(); + + while ( $row = mysql_fetch_array($r) ) { + $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']); + $re = mysql_query($qe) or die(mysql_error()); + $rowe = mysql_fetch_array($re); + + $beroep[] = $rowe['cl_beroep_code']; + } // while + + // find and return distict values from the jobs array + return count(array_unique($beroep)); + +} + +//----------------------------------------------------------------------------- +/** + * KMA005 + * + * number of days in clinic without stay overnight + * Total number of CL_ACTIVITEIT_SOORT=VERBLIJFSDAG, + * but only for act_8.1.6, 8.2.6, 8.3.6, 8.4.6, 8.5.6, 8.6.6 + * + * NOTE we don't use it at this moment + * + * @param none + * @return int + */ +function dt_kma005() { + return 0; +} + +//----------------------------------------------------------------------------- +/** + * KMT001 + * + * total minutes time on activity (parameter1) + * old ver - Add up total time (direct, indirect, travel, dagbesteding) for activities that are hierarchically under CL_ACTIVITEIT=parameter1 + * 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 + * + * @param int $node - node to look parameter for + * @return int +*/ +function dt_kmt001($node) { + global $dbcid; + + $par = dt_whatparam($node, 1); + $r = dt_allevents(); + $totaltime = 0; +//echo "PAR KMT001: $par
"; //debug + // choose here what $ver we'll use function of a date + $dbc = content_diagnose($dbcid); + $odate = $dbc['ax_odate']; + $ver = ( $odate <= '2007-12-31') ? 1 : 2; + + while ( $row = mysql_fetch_array($r) ) { + $qe = sprintf("SELECT cl_activiteit_soort AS cas, cl_activiteit_groepcode AS cag + FROM cl_activiteit ca JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid + WHERE cea.event_id = %d", $row['pc_eid']); + $re = mysql_query($qe) or die(mysql_error()); + $rowe = mysql_fetch_array($re); + + $cas = trim($rowe['cas']); + $cag = trim($rowe['cag']); + + // under the parameter + if ( strpos($cag, $par) === 0 ) { + // those three times for an event (direct, indirect, travel) + $times = dt_times($row['pc_eid']); + $totalt = $times['dirtime'] + $times['tratime'] + $times['indtime']; + + if ( $ver == 1 ) { + $totaltime += $totalt; + } else if ( $ver == 2 ) { + if ( $cas == 'Tijdschrijven' || $cas == 'Dagbesteding' ) $totaltime += $totalt; + } + } // if + + } // while +//echo "TOTALTIME KMT001: $totaltime
"; + return $totaltime; +} + +//----------------------------------------------------------------------------- +/** + * KMT002 + * + * NOTE: openemr doesn't use it in 2008 + * + * @param none + * @return int + */ +function dt_kmt002() { + // TO BE IMPLEMENTED +} + +//----------------------------------------------------------------------------- +/** + * KMT003 + * + * total minutes direct time on activity (parameter1) + * + * 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 + * + * ver 2 - 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) BUT ONLY for activities that are hierarchically under parameter1 of CL_ACTIVITEIT; + * + * @param int $node- node to look parameter for + * @return int + */ +function dt_kmt003($node) { + global $dbcid; + + $par = dt_whatparam($node, 1); + $r = dt_allevents(); + $totaltime = 0; + + //choose here what $ver we'll use function of a date + $dbc = content_diagnose($dbcid); + $odate = $dbc['ax_odate']; + $ver = ( $odate <= '2007-12-31') ? 1 : 2; + + while ( $row = mysql_fetch_array($r) ) { + $qe = sprintf("SELECT cl_activiteit_soort AS cas, cl_activiteit_groepcode AS cag + FROM cl_activiteit ca JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid + WHERE cea.event_id = %d", $row['pc_eid']); + $re = mysql_query($qe) or die(mysql_error()); + $rowe = mysql_fetch_array($re); + + $cas = trim($rowe['cas']); + $cag = trim($rowe['cag']); + + // under the parameter + if ( strpos($cag, $par) === 0 ) { + // those three times for an event (direct, indirect, travel) + $times = dt_times($row['pc_eid']); + + if ( $ver == 1 ) { + if ( $cas == 'Tijdschrijven' ) $totaltime += $times['dirtime']; + if ( $cas == 'Dagbesteding' ) $totaltime += ($times['dirtime'] * 15); // not used yet! + } else if ( $ver == 2 ) { + //if ( $cas == 'Tijdschrijven' || $cas == 'Dagbesteding' ) $totaltime += $times['dirtime']; + if ( $cas == 'Tijdschrijven' ) $totaltime += $times['dirtime']; + if ( $cas == 'Dagbesteding' ) $totaltime += ($times['dirtime'] * 60); // not used yet! + } + + } // if + } // while + + return $totaltime; +} + +//----------------------------------------------------------------------------- +/** + * KMT004 + * + * NOTE: openemr doesn't use it in 2008 + * + * @param none + * @return void + */ +function dt_kmt004() { + // TO BE IMPLEMENTED +} + +//----------------------------------------------------------------------------- +/** + * KMN001 + * + * The registered primary (main) diagnosis falls under category parameter1 (CL_DIAGNOSE) + * + * Example: if the asked value of CL_DIAGNOSE_CODE is AS1_6 then all CL_DIAGNOSE_CODE + * values As1_6* are valid (all values in the same hierarchy) + * + * @param int $node- node to look parameter for + * @return bool + */ +function dt_kmn001($node) { + global $dbcid; + + $par = dt_whatparam($node, 1); + $maindia = df_get_main_diagnose($dbcid); + + return (strpos($maindia, $par) === 0); +} + +//----------------------------------------------------------------------------- +/** + * KMP001 + * + * NOTE: not used by us + * @param none + * @return int + */ +function dt_kmp001() { + return 0; +} + +//----------------------------------------------------------------------------- +/** + * KMC001 + * + * NOTE: openemr doesn't use it in 2008 + * + * @param none + * @return void + */ +function dt_kmc001() { + // TO BE IMPLEMENTED +} + + +//----------------------------------------------------------------------------- +/** + * ALL EVENTS FOR A DBC + * + * between opening date and closing date + * + * @param none + * @return mysqlresult + */ +function dt_allevents() { + global $dbcid, $enddate; + + $dia = content_diagnose($dbcid); + $odate = mysql_real_escape_string($dia['ax_odate']); + $cdate = ( isset($_SESSION['eind']) && $_SESSION['eind'] ) ? mysql_real_escape_string($_SESSION['eind']) : $enddate; + if ( !$cdate ) $cdate = date('Y-m-d'); //as a precaution + $pid = ( $dbcid ) ? what_patient($dbcid) : $_SESSION['pid']; + + // find all events from DBC opening 'till closing date + $q = sprintf("SELECT pc_eid, pc_aid FROM openemr_postcalendar_events + WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_eventDate <= '%s' AND pc_apptstatus = '@' ", + $pid, $odate, $cdate); + $r = mysql_query($q) or die(mysql_error()); + + return $r; +} + + +//----------------------------------------------------------------------------- +/** + * TIMES FOR AN EVENT + * + * returns direct, indirect and travel time (all in minutes) + * + * @param int $eid - event id + * @return array + */ +function dt_times($eid = 0) { + if ( !$eid ) return 0; + + // for JOIN - if the second table has inconsistency of data (missing record for an events) + // a 'bug' occur and the direct time become 0 + //$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); + $qt = sprintf("SELECT pc_duration FROM openemr_postcalendar_events WHERE pc_eid = %d ", $eid); + $rt = mysql_query($qt) or die(mysql_error()); + $rowt = mysql_fetch_array($rt); + + // direct time + $rez['dirtime'] = $rowt['pc_duration'] / 60; + + + $qi = sprintf("SELECT indirect_time, travel_time FROM cl_time_activiteit WHERE event_id = %d ", $eid); + $ri = mysql_query($qi) or die(mysql_error()); + + if ( mysql_num_rows($ri) ) { + $rowi = mysql_fetch_array($ri); + // indirect time + $rez['indtime'] = $rowi['indirect_time']; + // travel time + $rez['tratime'] = $rowi['travel_time']; + } + + return $rez; +} + +//----------------------------------------------------------------------------- +/** + * WHAT PRODUCTGROEP + * + * after we have a result, we look up the right productgroep + * + * @param int $rfsum + * @param string $endate - ending date for the DBC + * @return array - two values id|name + */ +function dt_whatproductgroep($rfsum, $endate) { + global $dbcid; + + // to avoid the bug: first time, it doesn't display properly + if ( !$endate ) { + $dc = content_diagnose($dbcid); + $endate = $dc['ax_cdate']; + } + + $q = sprintf("SELECT cl_productgroep_sysid as cps, cl_productgroep_beschrijving as cpb + FROM cl_productgroep WHERE cl_productgroep_code = %d + AND cl_productgroep_begindatum <= '%s' AND cl_productgroep_einddatum >= '%s' ", $rfsum, $endate, $endate); + $r = mysql_query($q) or die(mysql_error()); + + $row = mysql_fetch_array($r); + $res = array(); + $res['id'] = $row['cps']; $res['name'] = $row['cpb']; + + return $res; +} + +//----------------------------------------------------------------------------- +/** + * SET PRESTATIECODE + * + * last step in the decision tree + * + * @param int $zsysid - zorg sysid + * @param int $pgroep - productgroep sysid + * @param int $dbcid - dbcid + * @return + */ +function dt_prestatiecode($zsysid, $pgroep, $dbcid) { + $resstr = ''; + + // ZORGTYPE ---------------- + $qz = sprintf("SELECT cl_zorgtype_prestatiecodedeel AS czp FROM cl_zorg WHERE cl_zorgtype_sysid = %d ", $zsysid); + $rz = mysql_query($qz) or die(mysql_error()); + $rowz = mysql_fetch_array($rz); + + $czp = (int)$rowz['czp']; $czp = str_pad($czp, 3, '0', STR_PAD_LEFT); + $resstr .= substr($rowz['czp'], 0, 3); // only 3 characters allowed + + // DIAGNOSE ---------------- + $qd = sprintf("SELECT cl_productgroep_diagnose_blinderen AS cdb, cl_productgroep_code as cpc + FROM cl_productgroep WHERE cl_productgroep_sysid = %d ", $pgroep); + $rd = mysql_query($qd) or die(mysql_error()); + $rod = mysql_fetch_array($rd); + + // posible values 1 - 0 + if ( $rod['cdb'] == 1 ) { + $resstr .= '000'; + } else { + // find CL_DIAGNOSE_PRESTATIECODEDEEL for the main diagnose + $maind = df_get_main_diagnose($dbcid); + $qpre = sprintf("SELECT cl_diagnose_prestatiecodedeel FROM cl_diagnose WHERE cl_diagnose_code = '%s' ", + $maind); + $rpre = mysql_query($qpre) or die(mysql_error()); + $rowpre = mysql_fetch_array($rpre); + + $resstr .= ( $rowpre['cl_diagnose_prestatiecodedeel'] ) ? $rowpre['cl_diagnose_prestatiecodedeel'] : '000' ; + } + + // PRODUCTGROEP CODE ---------------- + $resstr .= str_pad($rod['cpc'], 6, '0', STR_PAD_LEFT); + + // save it to the table + $qu = sprintf("UPDATE cl_axes SET ax_pcode='%s' WHERE ax_id = %d ", $resstr, $dbcid); + mysql_query($qu) or die(mysql_error()); + +} +//----------------------------------------------------------------------------- + +?> \ No newline at end of file diff --git a/library/DBC_files.php b/library/DBC_files.php new file mode 100644 index 000000000..6351a9a16 --- /dev/null +++ b/library/DBC_files.php @@ -0,0 +1,1204 @@ += $mainpos) { + $_1058 = ' '; + $_948 = $as1['content'][$mainpos - 1]; + } else { + $nr = $mainpos - count($as1['content']); + $record = $as2[$nr-1]; + $_1058 = ( $record['trekken']) ? 'J' : ' '; + $_948 = $record['code']; + } + + $_948 = str_pad($_948, 20, ' '); + $_949 = str_replace('-','', $dbc['ax_odate']); + + $content = $_1000 . $_1001 . $_1007 . $_1255 . $_998 . $_999 . $_1252 . $_1056 . $_1057 . $_948 . $_1058 . $_949 ."\r\n"; + //$content = $_1000 .'|'. $_1001 .'|'. $_1007 .'|'. $_1255 .'|'. $_998 .'|'. $_999 .'|'. $_1252 .'|'. $_1056 .'|'. $_1057 .'|'. $_948 .'|'. $_1058 .'|'. $_949 ."\r\n"; + + $GLOBALS['pk_careroutes']++; + + // WRITE DATA TO FILE + if ( fwrite($h, $content) === FALSE ) { + echo "Cannot write to file ($filename)"; + exit; + } + } + } + + fclose($h); +} + + +//----------------------------------------------------------------------------- +/** +PATIENT + +generate patient.txt file + +@param +@return +*/ +function gf_patient() { + dbc_message('PATIENT GENERATING'); + + $file = DBC_WORKINGDIR . '/patient.txt'; + if ( !$h = fopen($file, 'wb') ) { + echo "Cannot create file ($filename)"; + exit; + } + + // select all patients for ready-to-be-sent DBCs + //$q = sprintf("SELECT DISTINCT cn_pid FROM cl_careroute_numbers JOIN cl_axes ON cl_axes.ax_ztn = cl_careroute_numbers.cn_ztn WHERE cl_axes.ax_sti = 0 and cl_axes.ax_open = 0"); + $q = sprintf("SELECT DISTINCT cn_pid FROM cl_careroute_numbers JOIN cl_axes ON cl_axes.ax_ztn = cl_careroute_numbers.cn_ztn WHERE cl_axes.ax_sti = 0 and cl_axes.ax_open = 99"); + $r = mysql_query($q) or die(mysql_error()); + + if ( mysql_num_rows($r) ) { + while ( $row = mysql_fetch_array($r) ) { + // prepare data + $infopatient = info_patient($row['cn_pid']); + switch ((int)$infopatient['sex']) { + case 0: $sex = 0; break; // unknown + case 1: $sex = 1; break; // male + case 2: $sex = 2; break; // female + case 9: $sex = 9; break; // not specified + default: $sex = 9; + } + + $names = names($row['cn_pid']); + + $_7 = DECLINST; + $_8 = LOCATION; + $_1250 = str_pad(what_joining_number($row['cn_pid']), 15, ' '); + $_10 = str_pad('', 25, 'X'); // for now, we just anonimise; otherwise use $names array + $_11 = str_pad('', 10, 'X'); + $_12 = $names['code_fpn']; + $_13 = str_pad('', 25, 'X'); // for now, we just anonimise; otherwise use $names array + $_14 = str_pad('', 10, 'X'); + $_15 = $names['code_lpn']; + $_16 = str_pad('', 6, 'X'); + $_17 = substr($infopatient['postal_code'], 0, 4) . 'AA'; // anonimise postalcode (first 4 char + 2 A's) + //$_18 = str_pad($infopatient['pdn_number'], 5, ' ', STR_PAD_LEFT); // house number + $_18 = str_pad('1', 5, ' ', STR_PAD_LEFT); + $_19 = str_pad('', 4, 'X'); + $_20 = substr(vk_countrycode($infopatient['country_code']), 0, 2); // assure there's only 2 chars here + if ( !$_20 ) $_20 = 'XX'; // default value in case of blank values + + $_21 = str_replace('-','', $infopatient['DOB']); + if ( 0 == $_21 ) fl_log("Patient with ID: {$infopatient['id']} doesn't have DOB!"); + + $_22 = $sex; + $_804 = str_pad($infopatient['ss'], 9, ' '); + + $content = $_7 . $_8 . $_1250 . $_10 . $_11 . $_12 . $_13 . $_14 . $_15 . $_16 . $_17 . $_18 . $_19 . $_20 . $_21 . $_22 . $_804 . "\r\n"; + //$content = $_7 .'|'. $_8 .'|'. $_1250 .'|'. $_10 .'|'. $_11 .'|'. $_12 .'|'. $_13 .'|'. $_14 .'|'. $_15 .'|'. $_16 .'|'. $_17 .'|'. $_18 .'|'. $_19 .'|'. $_20 .'|'. $_21 .'|'. $_22 .'|'. $_804 . "\r\n"; + $GLOBALS['pk_patients']++; // count for pakbon + + // WRITE DATA TO FILE + if ( fwrite($h, $content) === FALSE ) { + echo "Cannot write to file ($filename)"; + exit; + } + } + } + + fclose($h); +} + + + +//----------------------------------------------------------------------------- +/** +DIAGNOSE + +@param +@return +*/ +function gf_diagnose() { + dbc_message('DIAGNOSE GENERATING'); + + $file = DBC_WORKINGDIR . '/diagnose.txt'; + if ( !$h = fopen($file, 'wb') ) { + echo "Cannot create file ($filename)"; + exit; + } + + //$q = sprintf("SELECT * FROM cl_axes WHERE ax_sti = 0 and ax_open = 0"); + $q = sprintf("SELECT * FROM cl_axes WHERE ax_sti = 0 and ax_open = 99"); + $r = mysql_query($q) or die(mysql_error()); + + if ( mysql_num_rows($r) ) { + while ( $row = mysql_fetch_array($r) ) { + // prepare data + $_950 = DECLINST; + $_951 = LOCATION; + + $as1 = unserialize($row['ax_as1']); + $as2 = unserialize($row['ax_as2']); + $as3 = unserialize($row['ax_as3']); + $as4 = unserialize($row['ax_as4']); + $as5 = unserialize($row['ax_as5']); + $as1c = $as1['content']; $mainpos = (int)$as1['mainpos']; // mainpos is written in both places + $as2c = $as2['content']; + + $_882 = str_pad($row['ax_id'], 20, ' '); + $_887 = str_replace('-','', $row['ax_odate']);; + + // we must avoid MAIN DIAGNOSE (mainpos); this is written in zorgtraject + + $partial_content = ''; // represents all the lines associated with a single DBC + $counter = 1; + $GLOBALS['pk_diagnoses'] = 0; + + foreach ( $as1c as $a) { + if ( $counter != $mainpos ) { + $_883 = str_pad($a, 20, ' '); + $_885 = ' '; + $partial_content .= $_950 . $_951 . $_882 . $_887 . $_883 . $_885 ."\r\n"; + //$partial_content .= $_950 .'|'. $_951 .'|'. $_882 .'|'. $_887 .'|'. $_883 .'|'. $_885 ."\r\n"; + $GLOBALS['pk_diagnoses']++; + } + $counter++; + } + + if ( $as2c ) { + foreach ( $as2c as $a) { + if ( $counter != $mainpos ) { + $_883 = str_pad($a['code'], 20, ' '); + $_885 = ( $a['trekken'] ) ? 'J' : ''; + $partial_content .= $_950 . $_951 . $_882 . $_887 . $_883 . $_885 ."\r\n"; + //$partial_content .= $_950 .'|'. $_951 .'|'. $_882 .'|'. $_887 .'|'. $_883 .'|'. $_885 ."\r\n"; + $GLOBALS['pk_diagnoses']++; + } + $counter++; + } + } // if $as2c + + + $_883 = str_pad($as3, 20, ' '); $_885 = ' '; + $partial_content .= $_950 . $_951 . $_882 . $_887 . $_883 . $_885 ."\r\n"; + //$partial_content .= $_950 .'|'. $_951 .'|'. $_882 .'|'. $_887 .'|'. $_883 .'|'. $_885 ."\r\n"; + $GLOBALS['pk_diagnoses']++; + + $_883 = str_pad($as4, 20, ' '); $_885 = ' '; + $partial_content .= $_950 . $_951 . $_882 . $_887 . $_883 . $_885 ."\r\n"; + //$partial_content .= $_950 .'|'. $_951 .'|'. $_882 .'|'. $_887 .'|'. $_883 .'|'. $_885 ."\r\n"; + $GLOBALS['pk_diagnoses']++; + + + // if we don't have the second and last GAF, we fill them with gaf1 value + // for official validation purposes + if ( empty($as5['gaf2']) ) $as5['gaf2'] = $as5['gaf1']; + if ( empty($as5['gaf3']) ) $as5['gaf3'] = $as5['gaf1']; + foreach ( $as5 as $a) { + $_883 = str_pad($a, 20, ' '); $_885 = ' '; + $partial_content .= $_950 . $_951 . $_882 . $_887 . $_883 . $_885 ."\r\n"; + //$partial_content .= $_950 .'|'. $_951 .'|'. $_882 .'|'. $_887 .'|'. $_883 .'|'. $_885 ."\r\n"; + $GLOBALS['pk_diagnoses']++; + } + + // WRITE DATA TO FILE + if ( fwrite($h, $partial_content) === FALSE ) { + echo "Cannot write to file ($filename)"; + exit; + } + + } // while + } // if + + fclose($h); + +} + + +//----------------------------------------------------------------------------- +/** +GELEVERD ZORGPROFIEL TIJDSCHRIJVEN + +@param +@return +*/ +function gf_tijdschrijven() { + dbc_message('TIJDSCHRIJVEN GENERATING'); + + + $file = DBC_WORKINGDIR . '/geleverd_zorgprofiel_tijdschrijven.txt'; + if ( !$h = fopen($file, 'wb') ) { + echo "Cannot create file ($filename)"; + exit; + } + + $content = ''; + + // for every DBC we find events associated + //$q = sprintf("SELECT * FROM cl_axes WHERE ax_sti = 0"); + //$q = sprintf("SELECT * FROM cl_axes WHERE ax_sti = 0 and ax_open = 0"); + $q = sprintf("SELECT * FROM cl_axes WHERE ax_sti = 0 and ax_open = 99"); + $r = mysql_query($q) or die(mysql_error()); + + if ( mysql_num_rows($r) ) { + while ( $row = mysql_fetch_array($r) ) { + // prepare data + $_919 = DECLINST; + $_920 = LOCATION; + $_921 = str_pad($row['ax_id'], 20, ' '); + + // set begin and end date(if exists - for closed but not sent DBC) + // begin date is ax_odate only for the first DBC in ZTN + // the followers take the beginning date from the previous DBC - closing date + $sign = '>'; + if ( first_dbc_2($row['ax_id'], $row['ax_ztn']) ) { + $bd_dbc = $row['ax_odate']; $sign = '>='; + } else { + $bd_dbc = previous_dbc($row['ax_id'], $row['ax_ztn']); + } + + $ed_dbc = ( ($row['ax_cdate'] !== '0000-00-00') && (!empty($row['ax_cdate'])) ) ? $row['ax_cdate'] : date('Y-m-d'); + $pid = what_patient($row['ax_id']); + + // find all events between DBC's dates and sum up total times + $qevent = sprintf("SELECT * FROM openemr_postcalendar_events + WHERE pc_pid = '%s' AND pc_eventDate $sign '%s' AND pc_eventDate <= '%s' AND pc_apptstatus = '@'", + $pid, $bd_dbc, $ed_dbc); + $revent = mysql_query($qevent) or die(mysql_error()); + + + // we are doing this because in the case of enabled multiple providers option, + // there are some events duplicated but with the same content (except for providers field) + $m_arr = array(); // array with distinct values for pc_multiple + $revent_good = array(); + while ( $rowe = mysql_fetch_array($revent) ) { + // MULTIPLE PROVIDERS CASE + if ( $rowe['pc_multiple'] ) { + if ( !in_array($rowe['pc_multiple'], $m_arr) ) { + $revent_good[] = $rowe; + $m_arr[] = $rowe['pc_multiple']; + } + // SINGLE PROVIDERS CASE + } else { + $revent_good[] = $rowe; + } + } + + + // we build for every event a $content + foreach ( $revent_good as $rg ) { + $_922 = str_pad($rg['pc_eid'], 20, ' '); + $_873 = str_pad(what_activity_event($rg['pc_eid']), 20, ' '); + + if ( empty($rg['pc_eventDate']) ) + fl_log("Event eid = {$rg['eid']} has an empty date for pc_eventDate!"); + $_874 = str_replace('-','', $rg['pc_eventDate']); + + $_877 = str_pad(what_profession_provider($rg['pc_aid']), 20, ' '); + + if ( empty($rg['pc_duration']) ) $rg['pc_duration'] = 0; + $_880 = str_pad($rg['pc_duration']/60, 6, ' '); + + // get indirect+travel time + $time = what_time_event($rg['pc_eid']); + if ( empty($time['indirect_time']) ) $time['indirect_time'] = 0; + if ( empty($time['travel_time']) ) $time['travel_time'] = 0; + $_954 = str_pad($time['indirect_time'], 6, ' '); + $_955 = str_pad($time['travel_time'], 6, ' '); + + // time validation + if ( fl_sumup_time(trim($_880), $time['indirect_time'], $time['travel_time'], $_921, $_922) ) { + $content .= $_919 . $_920 . $_921 . $_922 . $_873 . $_874 . $_877 . $_880 . $_954 . $_955 ."\r\n"; + //$content .= $_919 .'|'. $_920 .'|'. $_921 .'|'. $_922 .'|'. $_873 .'|'. $_874 .'|'. $_877 .'|'. $_880 .'|'. $_954 .'|'. $_955 ."\r\n"; + $GLOBALS['pk_tijdschrijven']++; + } + } // for each + } // while + } // if + + + + // WRITE DATA TO FILE + if ( fwrite($h, $content) === FALSE ) { + echo "Cannot write to file ($filename)"; + exit; + } + + fclose($h); + +} + +//----------------------------------------------------------------------------- +/** +PAKBON + +generate pakbon.txt file + +@param +@return +*/ +function gf_pakbon() { + dbc_message('PAKBON GENERATING'); + + $file = DBC_WORKINGDIR . '/pakbon.txt'; + if ( !$h = fopen($file, 'wb') ) { + echo "Cannot create file ($filename)"; + exit; + } + + //$q = sprintf("SELECT * FROM cl_axes WHERE ax_sti = 0"); + //$r = mysql_query($q) or die(mysql_error()); + + // prepare data128 + $_996 = DECLINST; + $_997 = LOCATION; + $_995 = '03.0'; + $_980 = date('Ymd'); + $_981 = 'DIS_GGZ_DBC_' .TEPR. '_030_' .DECLINST. '_' .LOCATION. '_' .date('Ym'). '01.zip'; + + // TESTS | PROD + $_1233 = str_pad('OpenEMR-DBC01', 15, ' '); + $_982 = str_pad($GLOBALS['pk_patients'], 7, ' ', STR_PAD_LEFT); + $_1013 = str_pad($GLOBALS['pk_careroutes'], 7, ' ', STR_PAD_LEFT); + $_987 = str_pad($GLOBALS['pk_dbcs'], 7, ' ', STR_PAD_LEFT); + $_988 = str_pad($GLOBALS['pk_diagnoses'], 7, ' ', STR_PAD_LEFT); + $_990 = str_pad($GLOBALS['pk_tijdschrijven'], 7, ' ', STR_PAD_LEFT); + $_991 = str_pad(0, 7, ' ', STR_PAD_LEFT); + $_992 = str_pad(0, 7, ' ', STR_PAD_LEFT); + $_1234 = str_pad(0, 7, ' ', STR_PAD_LEFT); + $_994 = str_pad(0, 7, ' ', STR_PAD_LEFT); + $content = $_996 . $_997 . $_995 . $_980 . $_981 . $_1233 . $_982 . $_1013 . $_987 . $_988 . $_990 . + $_991 . $_992 . $_1234 . $_994 ."\r\n"; + //$content = $_996 .'|'. $_997 .'|'. $_995 .'|'. $_980 .'|'. $_981 .'|'. $_1233 .'|'. $_982 .'|'. $_1013 .'|'. $_987 .'|'. $_988 .'|'. $_990 .'|'. $_991 .'|'. $_992 .'|'. $_1234 .'|'. $_994 ."\r\n"; + + // WRITE DATA TO FILE + if ( fwrite($h, $content) === FALSE ) { + echo "Cannot write to file ($filename)"; + exit; + } + fclose($h); +} + + +//----------------------------------------------------------------------------- +/** +EMPTY + +generate empties files + +@param +@return +*/ +function gf_empty() { + // array with empties files + $empties = array('overige_verrichting.txt', 'geleverd_zorgprofiel_verblijfsdagen.txt', 'geleverd_zorgprofiel_verrichtingen.txt', + 'geleverd_zorgprofiel_dagbesteding.txt'); + + foreach ( $empties as $e ) { + $file = DBC_WORKINGDIR . '/' . $e; + if ( !$h = fopen($file, 'wb') ) { + echo "Cannot create file ($filename)"; + exit; + } + fclose($h); + } + +} + + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +/** +CONNECT TO DATABASE + +make the connections to openemr database + +@param none +@return void +*/ +function db_connect() { + $link = mysql_connect(HOST, USER, PASS); + if (!$link) { + die('Could not connect: ' . mysql_error()); + } + + mysql_query("USE " . DATABASE); +} + + +//----------------------------------------------------------------------------- +/** +RETURN THE CODE FOR A ZORG IDENTIFIED BY SYSID + +@param int sysid - zorg sysid +@param int dbc sysid - return the code for ASSOCIATED zorg with this dbc +@return string +*/ +function what_zorg($id = 0, $dbc = 0) { + if ( !$id && !$dbc) return FALSE; + + if ( $dbc ) { + $q = sprintf("SELECT * FROM cl_zorg_dbc WHERE zd_dbc = %d ", $dbc); + $r = mysql_query($q) or die( mysql_error() ); + $row = mysql_fetch_array($r); + $id = (int)$row['zd_zorg']; if ( !$id ) return FALSE; + } + + $q = sprintf("SELECT * FROM cl_zorg WHERE cl_zorgtype_sysid = %d ", $id); + $r = mysql_query($q) or die( mysql_error() ); + + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); + return $row['cl_zorgtype_code']; + } else { + fl_log("DBC with ID: $id doesn't have a zorg code in cl_zorg_dbc!"); + return 0; + } +} + + +//----------------------------------------------------------------------------- +/** +RETURN THE CODE FOR REDENSLUITEN + +@param int $dbcid +@return int +*/ +function what_reden($dbcid) { + if ( !$dbcid ) return FALSE; + + $q = sprintf("SELECT * FROM cl_redensluiten_dbc WHERE rd_dbc = %d ", $dbcid); + $r = mysql_query($q) or die( mysql_error() ); + + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); + return $row['rd_redencode']; + } else { + fl_log("DBC with ID: $dbcid doesn't have a redensluiten code in cl_redensluiten_dbc!"); + return 0; + } +} + + +//----------------------------------------------------------------------------- +/** +RETURN THE CODE FOR CIRCUIT + +NEW VERSION !!!! + +@param int $ztnid - we based our search on ztn id +@return int +*/ +function what_circuit_new($dbcid) { + if ( !$dbcid ) return FALSE; + + // find patient id + $qs = sprintf("SELECT ccd_circuitcode FROM cl_circuit_dbc WHERE ccd_dbcid = %d", $dbcid); + $rs = mysql_query($qs) or die(mysql_error()); + $row = mysql_fetch_array($rs); + $pid = $row['ccd_circuitcode']; + + return $pid; + +} + +//----------------------------------------------------------------------------- +/** +RETURN THE CODE FOR PRODUCTGROEP + +@param int sysid - productgroep sysid +@param int dbc sysid - return the code for ASSOCIATED zorg with this dbc +@return string +*/ +function what_stoornis($id = 0, $dbcid = 0) { + if ( !$id && !$dbcid) return FALSE; + + if ( $dbcid ) { + $q = sprintf("SELECT * FROM cl_productgroep_dbc WHERE pc_dbc = %d ", $dbcid); + $r = mysql_query($q) or die( mysql_error() ); + $row = mysql_fetch_array($r); + $id = (int)$row['pc_productcode']; if ( !$id ) return FALSE; + } + + $q = sprintf("SELECT * FROM cl_productgroep WHERE cl_productgroep_sysid = %d ", $id); + $r = mysql_query($q) or die( mysql_error() ); + $row = mysql_fetch_array($r); + return $row['cl_productgroep_code']; +} + + +//----------------------------------------------------------------------------- +/** +RETURN THE UNIQUE GENERATED CODE FOR A PATIENT + +return the id1250 for patient.txt file + +@param int $patientid - patient id as in OpenEMR tables +@return string +*/ +function what_joining_number($patientid = 0) { + if ( !$patientid ) return FALSE; + + $patq = sprintf("SELECT * FROM cl_patient_number WHERE pn_oemrid = %d", $patientid); + $r = mysql_query($patq) or die( mysql_error() ); + + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); + return $row['pn_id1250']; + } else { + fl_log("Patient with ID: $patientid doesn't have a unique number in cl_patient_number!"); + return 0; + } +} + +//----------------------------------------------------------------------------- +/** +RETURN ALL INFOS ABOUT A PATIENT + +query patient_data original database + +@param int $patientid - patient id as in OpenEMR tables +@return array +*/ +function info_patient($patientid = 0) { + if ( !$patientid ) return FALSE; + + $patq = sprintf("SELECT * FROM patient_data pd, patient_data_NL pdn JOIN patient_data_NL ON + pdn.pdn_id = pd.id WHERE pd.id = %d", $patientid); + $r = mysql_query($patq) or die( mysql_error() ); + $row = mysql_fetch_array($r); + + return $row; +} + +//----------------------------------------------------------------------------- +/** +RETURN ACTIVITY CODE + +query cl_event_activiteit for activity id + +@param int $eid - eventid +@return string +*/ +function what_activity_event($eid = 0) { + if ( !$eid ) return FALSE; + + $eidq = sprintf("SELECT cl_activiteit_code FROM cl_activiteit ca JOIN cl_event_activiteit cea + ON ca.cl_activiteit_sysid = cea.activity_sysid WHERE cea.event_id = %d", $eid); + //$eidq = sprintf("SELECT activity_sysid FROM cl_event_activiteit WHERE event_id = %d", $eid); + $r = mysql_query($eidq) or die( mysql_error() ); + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); + //return (int)$row['activity_sysid']; + return $row['cl_activiteit_code']; + } else { + fl_log("Event with eid = $eid don't have an associated activity code in cl_event_activiteit"); + return 0; + } +} + +//----------------------------------------------------------------------------- +/** +RETURN PROFESSION CODE + +query cl_user_beroep for profession id + +@param int $pid - provider id +@return int +*/ +function what_profession_provider($pid = 0) { + if ( !$pid ) return FALSE; + + //$pidq = sprintf("SELECT * FROM cl_user_beroep WHERE cl_beroep_userid = %d", $pid); + $pidq = 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", $pid); + $r = mysql_query($pidq) or die( mysql_error() ); + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); + return $row['cl_beroep_code']; + //return $row['cl_beroep_sysid']; + } else { + fl_log("Provider with $pid don't have an associated beroep (job) code in cl_user_beroep"); + return 0; + } +} + +//----------------------------------------------------------------------------- +/** +RETURN TIMES FOR AN EVENT + +query cl_time_activiteit for an event + +@param int $eid - activity id +@return array +*/ +function what_time_event($eid = 0) { + if ( !$eid ) return FALSE; + + // check if this id is part of a multiple providers record + // what is multiple key around this $eid? + $rq = sprintf("SELECT pc_multiple FROM openemr_postcalendar_events WHERE pc_eid = %d", $eid); + $rezq = mysql_query($rq) or die( mysql_error() ); + $rowmulti = mysql_fetch_array($rezq); + + if ( $rowmulti['pc_multiple'] ) { + // --------------- MULTIPLE PROVIDERS CASE ---------------- + // what are all pc_eid's grouped by multiple key + $eventsrow = array(); + $rezev = mysql_query("SELECT pc_eid FROM openemr_postcalendar_events WHERE pc_multiple = {$rowmulti['pc_multiple']}"); + while ( $row = mysql_fetch_array($rezev) ) { + $eventsrow[] = $row['pc_eid']; + } + + // we look in cl_time_activiteit for a matching record + $timerow = ''; + foreach ( $eventsrow as $ev) { + $time = mysql_query("SELECT * FROM cl_time_activiteit WHERE event_id = $ev"); + if ( mysql_num_rows($time) ) { + $timeres = mysql_fetch_array($time); + $timerow = ( $timeres ) ? $timeres : ''; + } else { + $timerow = array('indirect_time' => 0, 'travel_time' => 0); // as a last solution, return an empty array + } + } + // --------------- EOS MULTIPLE PROVIDERS CASE ---------------- + } else { + // --------------- SINGLE PROVIDERS CASE ---------------- + $time = mysql_query("SELECT * FROM cl_time_activiteit WHERE event_id = $eid"); + if ( mysql_num_rows($time) ) { + $timerow = mysql_fetch_array($time); + } else { + $timerow = array('indirect_time' => 0, 'travel_time' => 0); // as a last solution, return an empty array + } + // --------------- EOS SINGLE PROVIDERS CASE ---------------- + } + + return $timerow; +} + + +//----------------------------------------------------------------------------- +/** +UPDATE DATABASE + + +@param none +@return void +*/ +function update_db() { + // for every open DBC generate a duplicate one; the older one + // will be marked as sent_to_insurer and closed + + $date = date('Y-m-d'); + mysql_query('START TRANSACTION'); + + // look for openened dbc + $q = sprintf("SELECT * FROM cl_axes WHERE ax_open = 1 AND ax_sti = 0"); + $r = mysql_query($q) or die(mysql_error()); + + if ( !mysql_num_rows($r) ) return; + + while ( $row = mysql_fetch_array($r) ) { + transform_dbc($row['ax_id']); + } // while + + mysql_query('COMMIT'); + +} + +//----------------------------------------------------------------------------- +/** +UPDATE DATABASE + +FUNCTION ONLY FOR DIRTY TRICKS: CLOSING PER MONTHS IN 2007!!!! +DON'T USE IT IN A REGULAR PRODUCTION ENV + +@param none +@return void +*/ +function update_db_2007() { + global $dbcid_arr; + + foreach ( $dbcid_arr as $dbc ) { + $q = sprintf("UPDATE cl_axes SET ax_sti = 1, ax_open = 0 WHERE ax_id = %d", $dbc); + echo $q . '
'; + mysql_query($q) or die(mysql_error()); + } +} + +//----------------------------------------------------------------------------- +/** +TRANSFORM DBC + +duplicate a DBC and then mark the older one with sent to insurer flag + +@param int $dbc id +@return void +*/ +function transform_dbc($dbcid = 0) { + + if ( !$dbcid ) return FALSE; + + mysql_query("START TRANSACTION"); + + $date = date('Y-m-d'); + + // read the current dbc + $q = sprintf("SELECT * FROM cl_axes WHERE ax_id = %d", $dbcid); + $r = mysql_query($q) or die(mysql_error()); + $dbc = mysql_fetch_array($r); + + // duplicate it (sent to insurer flag = 0 for the new one, 1 for the older one) + $qi = sprintf("INSERT INTO cl_axes (ax_ztn, ax_open, ax_as1, ax_as2, ax_as3, ax_as4, ax_as5, ax_odate, ax_cdate, ax_sti) + VALUES ('%s', %d,'%s','%s','%s','%s','%s','%s','%s','%s')", $dbc['ax_ztn'], 1, $dbc['ax_as1'], $dbc['ax_as2'], + $dbc['ax_as3'],$dbc['ax_as4'],$dbc['ax_as5'], $date, 0, 0); + mysql_query($qi) or die (mysql_error()); + + // close the old one + $qu = sprintf("UPDATE cl_axes SET ax_open = 0, ax_cdate = '%s', ax_sti = 1 WHERE ax_id = %d", $date, $dbcid); + mysql_query($qu) or die(mysql_error()); + + // update the related tables (cl_circuit_dbc) + $qc = sprintf("SELECT ccd_circuitcode FROM cl_circuit_dbc WHERE ccd_dbcid = %d ", $dbcid); + $rc = mysql_query($qc) or die(mysql_error()); + $circuit = mysql_fetch_array($rc); + + mysql_query("INSERT INTO cl_circuit_dbc(ccd_circuitcode, ccd_dbcid) VALUES (%d, %d)", $circuit['ccd_circuitcode'], $dbcid); + + mysql_query("COMMIT"); +} + +//----------------------------------------------------------------------------- +/** +NAAMCODE + +1 then naam_1 is the name of the married partner; 2 - name of the patient + +@param int $pid +@return int (1 or 2) +*/ +function naamcode_1($pid = 0) { + if (!$pid) return 0; + + $qp = sprintf("SELECT fname FROM patient_data WHERE id = %d ", $pid); + $rp = mysql_query($qp) or die(mysql_error()); + $row = mysql_fetch_array($rp); + + return ( $row['fname'] ) ? 2 : 1; + +} + +//----------------------------------------------------------------------------- +/** +NAMES + +return the names for patient +(we use patient names or if we don't have, partner name) + +@param int $pid - patient id +@return array +*/ +function names($pid = 0) { + if (!$pid) return 0; + + $qp1 = sprintf("SELECT fname, lname FROM patient_data WHERE id = %d ", $pid); + $rp1 = mysql_query($qp1) or die(mysql_error()); + $row1 = mysql_fetch_array($rp1); + + $qp2 = sprintf("SELECT pdn_pxlast, pdn_pxlastpar,pdn_lastpar FROM patient_data_NL WHERE pdn_id = %d ", $pid); + $rp2 = mysql_query($qp2) or die(mysql_error()); + $row2 = mysql_fetch_array($rp2); + + $ret = array(); + + // first part of the name (if we don't have it, the pad just 25X) + // first part = firstname + lastname patient + // second part = lastname partner (if any) + $firstpart = $row1['fname'] .' '. $row1['lname']; + $ret['firstpname'] = str_pad($firstpart, 25, ' ', STR_PAD_RIGHT); + $ret['prefix_fpn'] = ( $row2['pdn_pxlast'] ) ? str_pad($row2['pdn_pxlast'], 10, ' ') : str_pad('', 10, 'X'); + $ret['code_fpn'] = '2'; // name of the patient + + // last part of the name (partner ones) + if ( $row2['pdn_lastpar'] ) { + $ret['lastpname'] = str_pad($row2['pdn_lastpar'], 25, ' ', STR_PAD_RIGHT); + $ret['prefix_lpn'] = str_pad($row2['pdn_pxlastpar'], 10, ' ', STR_PAD_RIGHT); + $ret['code_lpn'] = '1'; // name of the patient + } else { + // empty values + $ret['lastnpame'] = str_pad('', 25, ' ', STR_PAD_RIGHT); + $ret['prefix_lpn'] = str_pad('', 10, ' ', STR_PAD_RIGHT); + $ret['code_lpn'] = ' '; + } + + return $ret; +} + +//----------------------------------------------------------------------------- +/** +FIRST DBC? + +find if a dbc is the first or a 'follow-up' or there is no DBC yet. +(the same function is in DBC_functions with a small modification here --> ztn arg) + +@param int - ax_id - the DBC id +@param int - ztn id +@return bool | int +*/ +function first_dbc_2($ax_id, $ztn_id) { + // to be the first means there is only one DBC per open ZTN + $qz = sprintf("SELECT * FROM cl_axes WHERE ax_ztn='%s' AND ax_id < %d", $ztn_id, $ax_id); + $rez = mysql_query($qz) or die(mysql_error()); + + return ( !mysql_num_rows($rez) ); +} + +//----------------------------------------------------------------------------- +/** +PREVIOUS DBC + +find the previous dbc for a given one and return its closing date + +@param int - ax id +@param int $ztn_id - ztn id +@return string +*/ +function previous_dbc($ax_id, $ztn_id) { + $qp = sprintf("SELECT ax_cdate FROM cl_axes WHERE ax_ztn='%s' AND ax_id < %d ORDER BY ax_id DESC", $ztn_id, $ax_id); + $rez = mysql_query($qp) or die(mysql_error()); + $r = mysql_fetch_array($rez); + + return $r['ax_cdate']; + +} + +// ---------------------------------------------------------------------------- +/** +SIMILAR LOG FUNCTION WITH THE ONE FROM DBC_VALIDATIONS + +simple function to log different events + +@param string $string +@return +*/ +function fl_log($string) { + $file = TMPDIR_DBC . '/DBC_problems.log'; + if ( !$h = fopen($file, 'ab') ) { + echo "Cannot create file ($file)"; + exit; + } + + $content = date('d-m-Y') . " $string \r\n"; + + // WRITE DATA TO FILE + if ( fwrite($h, $content) === FALSE ) { + echo "Cannot write to file ($file)"; + exit; + } + + fclose($h); + +} + +// ---------------------------------------------------------------------------- +/** +VERIFY IF THE TOTAL TIME IF GREATER THAN 0 +AND ALSO IF INDIRECT TIME>0 AND DIRECT TIME = 0 + +@param int $duration - encounter duration +@param int $indirect - indirect time +@param int $travel - travel time +@param int $axid - id for DBC +@param int $eid - event id +@return bool +*/ +function fl_sumup_time($duration, $indirect = 0, $travel = 0, $axid = 0, $eid = 0) { + $sum = (int)$duration + (int)$indirect + (int)$travel; + + if ( !$sum ) { + fl_log("DBC id:$axid EVENT: $eid has total time = 0 (E:$duration/I:$indirect/T:$travel)"); + return FALSE; + } else if ( $indirect > 0 && ($duration == 0 && $travel == 0) ) { + fl_log("DBC id:$axid has indirect time = $indirect but direct and travel time = 0."); + return FALSE; + } + + return TRUE; + +} + + +// ---------------------------------------------------------------------------- +/** +VERIFY IF THE PATIENT HAS SOME REQUIRED PROVIDERS WITH THE RIGHT JOBS + +@param string $zorg +@param string $odate - opening date for dbc +@param string $cdate - closing date for dbc +@param string $ztn - ztn id + +*/ +function fl_mb_beroep($zorg, $odate, $cdate, $ztn) { + // the zorg values who'll be checked for beroep + $checklist = array(110, 206, 116, 211); + + $zo = (int)trim($zorg); + if ( !in_array($zo, $checklist) ) { + return TRUE; + } else { + // find the id for the user + $qu = sprintf("SELECT cn_pid FROM cl_careroute_numbers WHERE cn_ztn = '%s'", trim($ztn)); + $ru = mysql_query($qu) or die(mysql_error()); + $rowu = mysql_fetch_array($ru); + $user = $rowu['cn_pid']; + + // find all events between the opening and closing of the DBC + // and look for every provider's job + $qe = sprintf("SELECT * FROM openemr_postcalendar_events WHERE pc_pid = '%s' AND pc_apptstatus = '@' + AND pc_eventDate >= '%s' AND pc_eventDate <= '%s' ", $user, $odate, $cdate); + $re = mysql_query($qe) or die(mysql_error()); + + $has = FALSE; + if ( mysql_num_rows($re) ) { + while ( $row = mysql_fetch_array($re) ) { + $job = what_beroep($row['pc_aid'], 1); + if ( preg_match('/^MB\./', $job) ) $has |= TRUE; + } + } // if num_rows + + if ( !$has ) fl_log("USER/ZTN: $user/$ztn doesn't have at least one provider with job (MB.%)"); + + } // if else + +// +} + +// ---------------------------------------------------------------------------- +/** + * DISPLAY A MESSAGE + * + * used to display messages in DBC generation phase + * must be called only with hardcoded (and safe) strings! + * + * @param string $msg + */ +function dbc_message($msg) { + $str = "$msg
"; + echo $str; +} + + +// ---------------------------------------------------------------------------- + +?> \ No newline at end of file diff --git a/library/DBC_functions.php b/library/DBC_functions.php new file mode 100644 index 000000000..1371be794 --- /dev/null +++ b/library/DBC_functions.php @@ -0,0 +1,1758 @@ + '%s' + AND cl_activiteit_begindatum < '%s'", $parent_code, $_SESSION['event_date'], $_SESSION['event_date']); + $r = mysql_query($q) or die(mysql_error()); + if ( mysql_num_rows($r) ) { + while ( $row = mysql_fetch_array($r) ) { + $a .=""; + } + } else { + $a .= ''; + } + + echo $a; + //echo dirname(__FILE__).'/../interface/globals.php'; +} + + + +//----------------------------------------------------------------------------- +/** + * VERIFY SELECTEERBAAR + * + * this field must be equal to 1 for saving into table + * @param int $vcode - element code + */ +function verify_code($vcode, $where = 1) { + if ( $where == 1) { + $q = sprintf("SELECT cl_activiteit_selecteerbaar AS slbar, cl_activiteit_sysid AS sysid + FROM cl_activiteit WHERE cl_activiteit_code = '%s'", $vcode); + } elseif ( $where == 2) { + $q = sprintf("SELECT cl_diagnose_selecteerbaar AS slbar, cl_diagnose_sysid AS sysid + FROM cl_diagnose WHERE cl_diagnose_code = '%s'", $vcode); + } + + $r = mysql_query($q) or die(mysql_error()); + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); + return ( $row['slbar'] == 0 ) ? FALSE : TRUE; + } else { + return FALSE; + } +} + +//----------------------------------------------------------------------------- +/** + * WHAT SYSID/NAME + * + * find the sysid for a code in activiteit table + * OR the name based on a known sysid + * sysid must be unique in this table + * + * @param string $code - activity's code + * @param string $sysid - activity's sysid + * @return int|string|bool(false) + */ +function what_sysid($code = 0, $sysid = 0) { + if (!$code && !$sysid) return FALSE; + + if ( isset($_SESSION['event_date']) && $_SESSION['event_date']) { + $today = $_SESSION['event_date']; + } else { + $today = date('Y-m-d'); + } + + if ( $code ) { + $q = sprintf("SELECT cl_activiteit_sysid AS sysid + FROM cl_activiteit WHERE cl_activiteit_code = '%s' AND + cl_activiteit_einddatum > '%s' AND cl_activiteit_begindatum < '%s'", $code, $today, $today); + } elseif ( $sysid ) { + $q = sprintf("SELECT cl_activiteit_beschrijving AS besc + FROM cl_activiteit WHERE cl_activiteit_sysid = %d AND + cl_activiteit_einddatum > '%s' AND cl_activiteit_begindatum < '%s'", $sysid, $today, $today); + } + + $r = mysql_query($q) or die(mysql_error()); + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); + if ( $code ) return $row['sysid']; + else if ($sysid) return $row['besc']; + } else { + return false; + } + +} + + +//----------------------------------------------------------------------------- +/** + * FULL NAME FOR A SYSID + * + * @param int $sysid (cl_activiteit_sysid) + * @return + */ +function what_full_sysid($sysid) { + if ( !$sysid ) return FALSE; + $full_str = ''; + + $parent = what_groepcode_activiteit($sysid); + + if ( $parent['parent'] ) { + $full_str .= what_sysid(0, $sysid) .' - '; // first sysid (not included in reccursive) + rec_parent_activiteit($parent['parent']); // produce the rest of the string + $full_str .= $GLOBALS['full_name_activity']; // concatenate the above 2 parts + } else { + // NO PARENT; THIS IS THE FIRST IN LINE + $full_str = what_sysid(0, $parent['sysid']); + } + + return $full_str; +} + + +//----------------------------------------------------------------------------- +/** + * WHAT CODE FOR AN ACTIVITY + * + * find the code for an activity + * + * @param string $sysid - activity's code + * @return string + */ +function what_code_activity($sysid = 0) { + if ( !$sysid ) return FALSE; + + $q = sprintf("SELECT * FROM cl_activiteit WHERE cl_activiteit_sysid = %d", $sysid); + $r = mysql_query($q) or die(mysql_error()); + + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); + return $row['cl_activiteit_code']; + } else { + return ''; + } +} + + +//----------------------------------------------------------------------------- +/** + * THE PARENT RECORD CODE FOR A SYSID + * + * Look for the record with code / sysid + * + * @param int $sysid (cl_activiteit_sysid) + * @param string $code (cl_activiteit_code) + * @return array - contains the parent code and its sysid + */ +function what_groepcode_activiteit($sysid = 0, $code = '') { + if ( !$sysid && !$code ) return FALSE; + $today = date('Y-m-d'); + $rez = array('parent' => '', 'sysid' => ''); + + if ( $sysid ) { + $q = sprintf("SELECT cl_activiteit_groepcode AS clag + FROM cl_activiteit + WHERE cl_activiteit_sysid = %d AND cl_activiteit_begindatum < '%s' AND cl_activiteit_einddatum > '%s'", $sysid, $today, $today); + } else if ( $code ) { + $q = sprintf("SELECT cl_activiteit_groepcode AS clac, cl_activiteit_sysid AS clsy + FROM cl_activiteit + WHERE cl_activiteit_code = '%s' AND cl_activiteit_begindatum < '%s' AND cl_activiteit_einddatum > '%s' ", $code, $today, $today); + } + + $r = mysql_query($q) or die(mysql_error()); + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); + if ( $sysid) { + $rez['parent'] = trim($row['clag']); $rez['sysid'] = (int)$sysid; + } else { + // array who contains 1 - the parent code 2 - the record sysid (used to find its name) + $rez['parent'] = trim($row['clac']); $rez['sysid'] = $row['clsy']; + } + + return $rez; + } else { + return false; + } + +} + + +//----------------------------------------------------------------------------- +/** + * RECURSIVE FUNCTION + * + * @param string $parent - groepcode + * @return void + */ +function rec_parent_activiteit($parent, $string = '') { + $next = what_groepcode_activiteit(0, $parent); + $string .= what_sysid(0, $next['sysid']) .' - '; + + if ( $next['parent'] ) { + rec_parent_activiteit($next['parent'], $string); + } else { + // write the result in a SESSION VARIABLE + $GLOBALS['full_name_activity'] = $string; return 1; + } + +} + +//----------------------------------------------------------------------------- +/** + * RETURNS THE RECORDS FOR LEVEL 1 (main activities) + * + * @param string $what ev - addeditevent, as - axes selection + * @param integer $gaf - used only for AS5 + * @return array $result - contains arrays + */ +function records_level1 ($what = 'ev', $gaf = 0) { + $result = array(); + $today = date('Y-m-d'); + mysql_query("SET NAMES utf8"); + + + switch ( $what ) { + case 'ev' : // ADD EDIT EVENT + $q = sprintf("SELECT cl_activiteit_beschrijving, cl_activiteit_sysid, cl_activiteit_code, cl_activiteit_element + FROM cl_activiteit + WHERE cl_activiteit_hierarchieniveau = 1 + AND cl_activiteit_einddatum > '%s' AND cl_activiteit_begindatum < '%s'", + $_SESSION['event_date'], $_SESSION['event_date']); + break; + + case 'as1' : // AXES CASE + $q = sprintf("SELECT cl_diagnose_beschrijving, cl_diagnose_sysid, cl_diagnose_code, cl_diagnose_element + FROM cl_diagnose + WHERE cl_diagnose_as = 1 AND cl_diagnose_hierarchieniveau = 2 + AND cl_diagnose_einddatum > '%s' AND cl_diagnose_begindatum < '%s' + ORDER BY cl_diagnose_element", + $today, $today); + break; + + case 'as2' : // AXES CASE + $q = sprintf("SELECT cl_diagnose_beschrijving, cl_diagnose_sysid, cl_diagnose_code, cl_diagnose_element + FROM cl_diagnose + WHERE cl_diagnose_as = 2 AND cl_diagnose_hierarchieniveau = 2 + AND cl_diagnose_einddatum > '%s' AND cl_diagnose_begindatum < '%s' + ORDER BY cl_diagnose_element", + $today, $today); + break; + + case 'as3' : // AXES CASE + $q = sprintf("SELECT cl_diagnose_beschrijving, cl_diagnose_sysid, cl_diagnose_code, cl_diagnose_element + FROM cl_diagnose + WHERE cl_diagnose_as = 3 + AND cl_diagnose_einddatum > '%s' AND cl_diagnose_begindatum < '%s'", + $today, $today); // cl_dia..._hierarchieniveau is 1 in this case, not 2 + break; + + case 'as4' : // AXES CASE + $q = sprintf("SELECT cl_diagnose_beschrijving, cl_diagnose_sysid, cl_diagnose_code, cl_diagnose_element + FROM cl_diagnose + WHERE cl_diagnose_as = 4 + AND cl_diagnose_einddatum > '%s' AND cl_diagnose_begindatum < '%s' + ORDER BY cl_diagnose_element", + $today, $today); // cl_dia..._hierarchieniveau is 1 in this case, not 2 + break; + + case 'as5' : // AXES CASE + $groepcode = 'as5_0' . (int)$gaf; + $q = sprintf("SELECT cl_diagnose_beschrijving, cl_diagnose_sysid, cl_diagnose_code, cl_diagnose_element + FROM cl_diagnose + WHERE cl_diagnose_as = 5 AND cl_diagnose_groepcode = '%s' + AND cl_diagnose_einddatum > '%s' AND cl_diagnose_begindatum < '%s'", + $groepcode, $today, $today); // cl_dia..._hierarchieniveau is 1 in this case, not 2 + break; + } + + $result[] = ''; + $r = mysql_query($q) or die( mysql_error() ); + while ( $row = mysql_fetch_array($r) ) { + $result[] = $row; + } + + //echo "
" . print_r($result, true) . "
"; // debug + return $result; +} + +//----------------------------------------------------------------------------- +/** + * FIND SAVED ACTIVITY FOR AN EVENT + * + * @param $eid - event id + * @return string|bool(false) - sysid for that event|false + */ +function what_activity($eid) { + $q = sprintf("SELECT activity_sysid FROM cl_event_activiteit WHERE event_id= %d ", $eid); + $r = mysql_query($q) or die(mysql_error()); + if ( $r ) { + $row = mysql_fetch_array($r); + return $row['activity_sysid']; + } else { + return FALSE; + } +} + +//----------------------------------------------------------------------------- +/** + * RETURN THE NAME OF A DIAGNOSE + * + * @param string $ascode + * @return string + */ +function what_as($ascode) { + mysql_query("SET NAMES utf8"); + $q = sprintf("SELECT cl_diagnose_beschrijving FROM cl_diagnose WHERE cl_diagnose_code = '%s'", $ascode); + $r = mysql_query($q) or die( mysql_error() ); + $row = mysql_fetch_array($r); + return $row['cl_diagnose_beschrijving']; +} + + +//----------------------------------------------------------------------------- +/** + * GENERATE AN UNIQUE PATIENT NUMBER + * + * number user in DBC is generated at a new client + * + * @param int $pid - patient id + * @return none + */ +function generate_id1250($pid) { +if ($pid) { + mysql_query("START TRANSACTION"); + $date = date('Ymd'); + // retrieve last allocated number for this day + // let's check if for today there is record + $qd = sprintf("SELECT aux_varc FROM cl_aux WHERE aux_id='dn_id1250'"); + $rd = mysql_query($qd) or die(mysql_error()); + $rez = mysql_fetch_array($rd); + + // if strings are NOT equal, then we must update the date field with today value + // and reset the counter (aux_varn) to 0 + if ( $date !== trim($rez['aux_varc']) ) { + $qc = sprintf("UPDATE cl_aux SET aux_varc = '%s', aux_varn = 0 WHERE aux_id='dn_id1250'", $date); + mysql_query($qc) or die(mysql_error()); + } + + $nq = mysql_query("SELECT aux_varn FROM cl_aux WHERE aux_id='dn_id1250'") or die(mysql_error()); + $nrow = mysql_fetch_array($nq); + $current_number = $nrow['aux_varn'] + 1; + $current_number = strval($current_number); + + // prepare new ID1250 number (date + 6 digits) + $np = str_pad($current_number, 6, '0', STR_PAD_LEFT); + $ns = $date . $np; + + // as an extra caution measure, we check for openemrid and newly generated number + // in table; these must be unique + $check = sprintf("SELECT * FROM cl_patient_number WHERE pn_oemrid = %d OR pn_id1250 = '%s'", + $pid, $ns); + $rezcheck = mysql_query($check) or die(mysql_error()); + if ( !mysql_num_rows($rezcheck) ) { + // insert into db + $q = sprintf("INSERT INTO cl_patient_number VALUES ('%d', '%s')", $pid, $ns); + mysql_query($q) or die(mysql_error()); + + // update auxiliary table + $qu = sprintf("UPDATE cl_aux SET aux_varn = aux_varn + 1 WHERE aux_id='dn_id1250'"); + mysql_query($qu) or die(mysql_error()); + } else { + echo ''; + } + mysql_query("COMMIT"); +}//if pid + +} + +//----------------------------------------------------------------------------- +/** + * GET AN ID FOR A PATIENT + * + * @param string $whatid + * @param int $pid + */ +function get_id($whatid, $pid) { + $q = FALSE; + switch ($whatid) { + case 'id1250': + $q = sprintf("SELECT pn_id1250 FROM cl_patient_number WHERE pn_oemrid = %d", $pid); + break; + } + + if ( $q ) { + $res = mysql_query($q) or die(mysql_error()); + $row = mysql_fetch_row($res); + return $row[0]; + } else { + return FALSE; + } +} + +//----------------------------------------------------------------------------- +/** + * GENERATE A CARE ROUTE NUMBER - ID 1007 + * (ZORGTRAJECTNUMMER) + * + * this function actually checks for an opened CRN (ZTN - zorgtrajectnummer), + * and returns it; only if it doesn't exist generate a new one + * + * @param int $pid + * @param string $eventdate + * @return string - CRN(ZTN) if exists; new CRN(ZTN) + */ +function generate_id1007($pid, $eventdate) { +if ($pid) { + mysql_query("START TRANSACTION"); + // check for previous opened CRN + $qc = sprintf("SELECT * FROM cl_careroute_numbers WHERE cn_pid = %d AND cn_open = '1'", $pid); + $rez = mysql_query($qc) or die(mysql_error()); + if ( mysql_num_rows($rez) ) { + $row = mysql_fetch_array($rez); + return $row['cn_ztn']; + } else { + // generate a new one + // get last value from auxiliary table + $raux = mysql_query("SELECT aux_varn FROM cl_aux WHERE aux_id='dn_id1007'") or die(mysql_error()); + $rez = mysql_fetch_array($raux); + $current_val = strval($rez['aux_varn'] + 1); + $ztn = str_pad($current_val, 7, '0', STR_PAD_LEFT); + + // insert new values into cl_careroute_numbers table and set it to opened + $qi = sprintf("INSERT INTO cl_careroute_numbers(cn_ztn, cn_pid, cn_dopen, cn_open) + VALUES('%s', %d, '%s', %d)", $ztn, $pid, $eventdate, 1); + mysql_query($qi); + $newid = mysql_insert_id(); + + // update value from aux table + $qu = sprintf("UPDATE cl_aux SET aux_varn = aux_varn + 1 WHERE aux_id='dn_id1007'"); + mysql_query($qu) or die(mysql_error()); + + return $newid; + } + mysql_query("COMMIT"); +} // if pid +} + +//----------------------------------------------------------------------------- +/** + * SAVE DBC RECORDS + * + * @param none + * @return void + */ +function save_dbc() { +if ( !vl_validate_diagnoses() ) { + echo ''; + return FALSE; +} + +if ( $_SESSION['save'] ) { + + mysql_query("START TRANSACTION"); + + // check for an opened ztn + $opened_ztn = verify_ztn(); + + if ( !$opened_ztn ) $opened_ztn = generate_id1007($_SESSION['pid'], date('Y-m-d')); // if it's close, create a new one + + // insert a new DBC Route + $today = date('Y-m-d'); + if ( $opened_ztn ) { + // as a caution we check for posas. must be NOT null + if ( !$_SESSION['posas'] ) $_SESSION['posas'] = 1; // default value + + // at as1 and as2 we must add radio postion for Main Diagnose + $as1arr['content'] = $_SESSION['as1']; + $as1arr['mainpos'] = (int)$_SESSION['posas']; + $as2arr['content'] = $_SESSION['as2']; + $as2arr['mainpos'] = (int)$_SESSION['posas']; + $circode = (int)$_SESSION['circuitcode']; + + if ( $_SESSION['show_axid'] ) { + // ---------------------- + // edit case + $q = sprintf("UPDATE cl_axes + SET ax_as1 = '%s', ax_as2 = '%s', ax_as3 = '%s', ax_as4 = '%s', ax_as5 = '%s' WHERE ax_id = %d", + serialize($as1arr), serialize($as2arr), serialize($_SESSION['as3']), serialize($_SESSION['as4']), + serialize($_SESSION['as5']), $_SESSION['show_axid'] ); + mysql_query($q) or die(mysql_error()); + + // edit circuit-dbc connection + $icircode = ( vl_validate_circuit($circode) ) ? $circode : '1' ; // validate the circuit + $qcir = sprintf("INSERT INTO cl_circuit_dbc(ccd_dbcid, ccd_circuitcode) VALUES(%d, %d) ON DUPLICATE KEY + UPDATE ccd_circuitcode = %d", $_SESSION['show_axid'], $icircode, $icircode); + mysql_query($qcir) or die(mysql_error()); + + } else { + // ---------------------- + // new case + + // if it's the first DBC, open date is given by the event with @ flag (pc_apptstatus) after ZTN was opened) + if ( first_dbc($_SESSION['show_axid']) ) { + // open date for ztn + $qztn = sprintf("SELECT cn_dopen FROM cl_careroute_numbers WHERE cn_ztn = '%s' ", $opened_ztn); + $rztn = mysql_query($qztn) or die (mysql_error()); + $ztarr = mysql_fetch_array($rztn); $ztnodate = $ztarr['cn_dopen']; + + // find first event who is visit (with @ flag after $ztnodate) + $qv = sprintf("SELECT MIN(pc_eventDate) as mindate FROM openemr_postcalendar_events WHERE pc_eventDate >= '%s' AND pc_apptstatus = '@' AND pc_pid = %d ", $ztnodate, $_SESSION['pid']); + $rv = mysql_query($qv) or die (mysql_error()); + + $earr = mysql_fetch_array($rv); + $opendate = $earr['mindate']; + + // no encounter found so we cannot insert a DBC + if ( !$opendate ) { + echo ""; + exit(); + } + + } else { + $opendate = $today; + } + + $q = sprintf("INSERT INTO cl_axes (ax_ztn, ax_open, ax_as1, ax_as2, ax_as3, ax_as4, ax_as5, ax_odate) + VALUES('%s', %d, '%s', '%s', '%s', '%s', '%s', '%s')", + $opened_ztn, 1, serialize($as1arr), serialize ($as2arr), serialize ($_SESSION['as3']), serialize ($_SESSION['as4']), serialize ($_SESSION['as5']), $opendate); + mysql_query($q) or die(mysql_error()); // leave it here that next line to work + + // new circuit-dbc connection + $rlast = mysql_insert_id(); + $icircode = ( vl_validate_circuit($circode) ) ? $circode : '1' ; // validate the circuit + $qcir = sprintf("INSERT INTO cl_circuit_dbc(ccd_circuitcode, ccd_dbcid) VALUES(%d, %d)", $icircode, $rlast); + mysql_query($qcir) or die(mysql_error()); + + } // new | edit case + + } else { + echo ''; return FALSE; + } + + // reset implied session variables + $_SESSION['save'] = TRUE; + for ($i = 1; $i <= 5; $i++) { + $_SESSION["as$i"] = ''; + } + + mysql_query("COMMIT"); + + return TRUE; + +} //if +} + +//----------------------------------------------------------------------------- +/** + * VERIFY ZTN + * + * verify for a patient if a ZTN is already opened + * return the number of ztn if true, false otherwise + * + * @param $pid - optionally; if provided, we'll ignore the session var + * @return string $opened_ztn | bool false + */ +function verify_ztn($pid = 0){ + + // patient id could be taken from a param or from a session var + $cn_pid = ( $pid ) ? $pid : $_SESSION['pid']; + + // search for an opened ZTN (id1007) + $qc = sprintf("SELECT cn_ztn FROM cl_careroute_numbers WHERE cn_pid = %d AND cn_open = '1'", $cn_pid); + // echo $qc; // debug + $rez = mysql_query($qc) or die(mysql_error()); $opened_ztn = ''; + if ( mysql_num_rows($rez) ) { + $row = mysql_fetch_array($rez); + $opened_ztn = $row['cn_ztn']; + return $opened_ztn; + } else { + return false; + } + +} + +//----------------------------------------------------------------------------- +/** + * LIST ZTN's + * + * lists ZTN's from a patient + * + * @param int $mode 0-all 1-only opened 2-only closed + */ +function lists_ztn($mode = 0){ + switch ($mode) { + case 0: $qc = sprintf("SELECT * FROM cl_careroute_numbers WHERE cn_pid = %d ORDER BY cn_dopen", $_SESSION['pid']); break; + case 1: $qc = sprintf("SELECT * FROM cl_careroute_numbers WHERE cn_pid = %d AND cn_open = '1' ORDER BY cn_dopen", $_SESSION['pid']); break; + case 2: $qc = sprintf("SELECT * FROM cl_careroute_numbers WHERE cn_pid = %d AND cn_open = '0' ORDER BY cn_dopen", $_SESSION['pid']); break; + default: $qc = sprintf("SELECT * FROM cl_careroute_numbers WHERE cn_pid = %d ORDER BY cn_dopen", $_SESSION['pid']); break; + } + + $artn = array(); + $rez = mysql_query($qc) or die(mysql_error()); + if ( mysql_num_rows($rez) ) { + while ( $row = mysql_fetch_array($rez)) { + $artn[] = $row; + } + return $artn; + } else { + return false; + } +} + +//----------------------------------------------------------------------------- +/** + * LIST DIAGNOSES + * + * lists diagnoses for a ZTN + * if called for last, this means the open dbc + * + * @param string ax_odate DESC default, 'last' for the last one (ordered by date) + * @return array | bool(false) + */ +function lists_diagnoses($order = 'ax_odate DESC'){ + + // obtain opened ztn + $ztn = verify_ztn(); + if ( $order == 'last') { + $qc = sprintf("SELECT * FROM cl_axes WHERE ax_ztn = '%s' AND ax_open = 1 ORDER BY ax_odate DESC ", $ztn); + } else { + $qc = sprintf("SELECT * FROM cl_axes WHERE ax_ztn = '%s' ORDER BY %s ", $ztn, $order); + } + + $artn = array(); + $rez = mysql_query($qc) or die(mysql_error()); + + if ( mysql_num_rows($rez) ) { + while ( $row = mysql_fetch_array($rez)) { + $artn[] = $row; + } + return $artn; + } else { + return false; + } +} + +//----------------------------------------------------------------------------- +/** + * LAST DIAGNOSE + * + * specific function to return the last entered diagnose + * a.k.a. the open DBC + */ +function last_diagnose() { + $arr = lists_diagnoses('last'); + return $arr[0]; +} + +//----------------------------------------------------------------------------- +/** + * ZORGTYPE CODES + * + * @param none + * @return array +*/ +function zorgtype_codes() { + mysql_query("SET NAMES utf8"); + $check = first_dbc($_SESSION['show_axid']); + if ( $check ) { //first dbc + $qc = sprintf("SELECT * FROM cl_zorg WHERE cl_zorgtype_groepcode = 100 AND cl_zorgtype_selecteerbaar = 1"); + } else { + $qc = sprintf("SELECT * FROM cl_zorg WHERE cl_zorgtype_groepcode = 200 AND cl_zorgtype_selecteerbaar = 1"); + } + $rez = mysql_query($qc) or die(mysql_error()); + + $ra = array(); + while ($r = mysql_fetch_assoc($rez)) { + $ra[] = $r; + } + + return $ra; +} + +//----------------------------------------------------------------------------- +/** + * FIRST DBC? + * + * find if a dbc is the first , a 'follow-up' or there is no DBC yet. + * (the same function is in DBC_files) + * + * @param none + * @return bool - true if it's the first, 0 - otherwise + */ +function first_dbc($ax_id) { + // to be the first means there is only one DBC per open ZTN + $openztn = verify_ztn(); + + // to be the first means there is only one DBC per open ZTN + $qz = sprintf("SELECT * FROM cl_axes WHERE ax_ztn='%s' AND ax_id < %d", $openztn, $ax_id); + $rez = mysql_query($qz) or die(mysql_error()); + + return ( !mysql_num_rows($rez) ); +} + + +//----------------------------------------------------------------------------- +/** + * STATUS FOR A ZTN + * + * find if a dbc is the first , a 'follow-up' or there is no DBC yet. + * retcode 0 - no ZTN open + * 1 - ZTN open, no DBC + * 2 - ZTN open, (just) one opened DBC + * 3 - ZTN open, (just) one closed DBC + * 4 - ZTN open, more DBC's + * + * @param none + * @return int - for $retcode see above + */ +function ztn_status() { + + // return the open ztn if any + $openztn = verify_ztn(); + + if ( $openztn ) { + $qz = sprintf("SELECT * FROM cl_axes WHERE ax_ztn='%s'", $openztn); + $rez = mysql_query($qz) or die(mysql_error()); + $rows = mysql_num_rows($rez); + + switch ($rows) { + case 0: $retcode = 1; break; // no rows, means no DBC in ZTN + case 1: + $ro = mysql_fetch_array($rez); + $retcode = ( $ro['ax_open'] ) ? 2 : 3 ; + break; // just one row, means one DBC (initial) in ZTN + default: $retcode = 4; // any other numbers means more DBC's, so we have initial + follow's up + } + } else { + $retcode = 0; + } + + return $retcode; +} + + +//----------------------------------------------------------------------------- +/** + * REDENSLUITEN CODES + * + * @param none + * @return array - an array with all redensluiten codes + */ +function reden_codes() { +if ( $_SESSION['eind'] ) { + mysql_query("SET NAMES utf8"); + $eind = mysql_real_escape_string($_SESSION['eind']); + $qc = sprintf("SELECT * FROM cl_redensluiten clr WHERE clr.cl_redensluiten_begindatum < '%s' AND clr.cl_redensluiten_einddatum >'%s' ", $eind, $eind); + $rez = mysql_query($qc) or die(mysql_error()); + + $ra = array(); + while ($r = mysql_fetch_assoc($rez)) { + $ra[] = $r; + } + + return $ra; +}//if +} + +//----------------------------------------------------------------------------- +/** + * CHECK FOR 'SENT TO INSURER' CASE + * + * check if the open DBC was already sent to insurer or not + * + * @param none + * @return bool + */ +function sent_to_insurer() { + $ldbc = last_diagnose(1); // return open DBC + return ( $ldbc['ax_sti'] ) ? TRUE : FALSE; +} + + +//----------------------------------------------------------------------------- +/** + * LOAD OPEN DBC + * + * load the values from the open dbc into session variables + * to edit form + */ +function load_dbc() { + $ldbc = last_diagnose(1); + $as1 = unserialize($ldbc['ax_as1']); + $_SESSION['as1'] = $as1['content']; $_SESSION['posas'] = (int)$as1['mainpos']; + + $as2 = unserialize($ldbc['ax_as2']); + $_SESSION['as2'] = $as2['content']; + + $_SESSION['as3'] = unserialize($ldbc['ax_as3']); + $_SESSION['as4'] = unserialize($ldbc['ax_as4']); + $_SESSION['as5'] = unserialize($ldbc['ax_as5']); +} + +//----------------------------------------------------------------------------- +/** + * CLOSE AN OPEN DBC + * + * @param int $follow - specify if a DBC is followed by another one + * created with the same content, or close + ZTN close + * @param int $stoornis - $_POST['stoornis'] + * @param int $ztc - $_POST['ztc'] + * @param int $rtc - $_POST['rtc'] + * @param array $gaf - array with 2 elements (hoogste/eind) + * @param int $dbcid - dbcid if called from a script + * @param string $eind - closing date if called from a script + * @param int $patid - patient id if called from a script + * @return void +*/ +function close_dbc($follow = 0, $stoornis = 0, $ztc, $rtc, $gaf, $dbcid = 0, $eind = '', $patid = 0) { + mysql_query('START TRANSACTION'); + + $einddate = ( $dbcid ) ? $eind : $_SESSION['eind']; + $dbc_id = ( $dbcid ) ? $dbcid : $_SESSION['show_axid']; + $pid = ( $dbcid ) ? $patid : $_SESSION['pid']; + + // close the open dbc; also mark for vektis + // $q = sprintf("UPDATE cl_axes SET ax_open = 0, ax_cdate = '%s', ax_vkstatus = 1 + $q = sprintf("UPDATE cl_axes SET ax_open = 99, ax_cdate = '%s', ax_vkstatus = 1 + WHERE ax_id = %d", $einddate, $dbc_id); + mysql_query($q) or die(mysql_error()); + + // update for the current + // NOTE: we must run this here because the following statement + // retrieves the content for DBC; otherwise the duplicated dbc will not contain + // the new $gaf array + update_gaf($dbc_id, $gaf); + + // this MUST be run after update_gaf + $ldbc = content_diagnose($dbc_id); + + // write the closing parameters from dbc_sluiten form + write_stoornis($stoornis, $dbc_id); + write_zorg($ztc, $dbc_id); + write_reden($rtc, $dbc_id); + + // generate prestatie code + dt_prestatiecode($ztc, $stoornis, $dbc_id); + + // open a new one if it is the case + if ( $follow ) { + $newid = duplicate_dbc($ldbc); + if ( !$dbcid ) $_SESSION['show_axid'] = $newid; + } else { + $qztn = sprintf("UPDATE cl_careroute_numbers SET cn_open = 0, cn_dclosed = '%s' + WHERE cn_pid = %d", $einddate, $pid); + mysql_query($qztn) or die(mysql_error()); + + if ( !$dbcid ) $_SESSION['show_axid'] = FALSE; + } + + mysql_query('COMMIT'); +} + +//----------------------------------------------------------------------------- +/** + * TOTAL TIME SPENT + * + * adds all direct, indirect + travel time from the first day of this DBC to the last day + * only for encounters (events with @ pc_apptstatus) + * + * @param int $dbcid - if used instead of $_SESSION + * @return array - contains the three times (indirect, travel, total) + */ +function total_time_spent($dbcid = 0, $btime = '', $etime = '') { + // our big results + $total_time = 0 ; $indirect_time = 0 ; $travel_time = 0; + + // DBC ID + // we have a session var or a given value? + $dbc = ( $dbcid ) ? $_SESSION['show_axid'] : $dbcid; + + // begin date for DBC + if ( $btime ) { + $bd_dbc = $btime; + } else { + $cd = content_diagnose($dbc); + $bd_dbc = $cd['ax_odate']; + } + + // end date of DBC + if ( $etime ) { + $ed_dbc = $etime; + } else { + $ed_dbc = ( $_SESSION['eind'] ) ? $_SESSION['eind'] : date('Y-m-d'); + } + + // if we have a $dbcid we must find a $pid + if ( $dbcid ) { + $pid = what_patient($dbcid); + } else { + $pid = $_SESSION['pid']; + } + + // also, we don't check for first_dbc if we have $btime + if ( $btime == '2008-01-01' || $etime == '2007-12-31' ) { + $check_first = FALSE; + } else { + $check_first = TRUE; + } + + // find all events between DBC's dates and sum up total times + $q = sprintf("SELECT pc_eid, pc_duration FROM openemr_postcalendar_events + WHERE pc_pid = '%s' AND pc_eventDate >= '%s' AND pc_eventDate <= '%s' AND pc_apptstatus = '@' ", + $pid, $bd_dbc, $ed_dbc); + + $r = mysql_query($q) or die(mysql_error()); + + while ($row = mysql_fetch_array($r)) { + $total_time += $row['pc_duration']; + + // get indirect+travel time + $q1 = sprintf("SELECT * FROM cl_time_activiteit WHERE event_id = %d", $row['pc_eid']); + $r1 = mysql_query($q1) or die(mysql_error()); + if ( mysql_num_rows($r1) ) { + $row1 = mysql_fetch_array($r1); + $indirect_time += $row1['indirect_time']; + $travel_time += $row1['travel_time']; + } + } // while + + // if it is the first DBC we look for previous events + // which weren't included in DBC and add timing too + if ( $check_first && first_dbc($dbc) ) { + // begin date of ZTN + $r = lists_ztn(1); + $bdztn = $r[0]['cn_dopen']; + + // find all events between DBC's dates and sum up total times + $q = sprintf("SELECT pc_eid, pc_duration FROM openemr_postcalendar_events + WHERE pc_pid = '%s' AND pc_eventDate > '%s' AND pc_eventDate < '%s'", + $pid, $bdztn, $bd_dbc); + $r = mysql_query($q) or die(mysql_error()); + while ($row = mysql_fetch_array($r)) { + $total_time += $row['pc_duration']; + // get indirect+travel time + $q2 = sprintf("SELECT * FROM cl_time_activiteit WHERE event_id = %d", $row['pc_eid']); + $r2 = mysql_query($q2) or die(mysql_error()); + if ( mysql_num_rows($r2) ) { + $row2 = mysql_fetch_array($r2); + $indirect_time += $row2['indirect_time']; + $travel_time += $row2['travel_time']; + } + } // while + } // if + + $total_time /= 60 ; //transform it to minutes from seconds + $total_time += $indirect_time + $travel_time; + + $time = array ('total_time' => $total_time, 'indirect_time' => $indirect_time, 'travel_time' => $travel_time); + return $time; +} + +//----------------------------------------------------------------------------- +/** + * GENERATE STOORNIS(DISEASE) DROPDOWN + * + * NOTE maybe not used anymore; there is an automatic procedure (DBC_decisiontree) + * + * generates a dropdown for stoornis section in + * close dbc module + * + * @param string $odate - opening date for DBC (which is gonna be closed) + * @return string + */ +function stoornis_dropdown($odate) { + $s = ''; + return $s; +} + +//----------------------------------------------------------------------------- +/** + * GENERATE VERBLIJF(HOSPITAL STAY) DROPDOWN + * + * generates a dropdown for verblijf section in close dbc module + * + * @param return + */ +function verblijf_dropdown() { + $s = ''; + return $s; +} + +//----------------------------------------------------------------------------- +/** + * GENERATE CIRCUITCODE DROPDOWN + * + * @param int - $sel the selected item + * @return string + */ +function circuit_dropdown($sel = 0) { + $today = date('Y-m-d'); + $s = ''; + return $s; +} + +//----------------------------------------------------------------------------- +/** + * HAS CIRCUIT + * + * check if a dbc has a link with a circuit code in cl_circuit_dbc table + * + * @param int $axid + * @return int|bool - the circuit code or false + */ +function has_circuit($axid = 0) { + if ( !$axid ) return 0; + + $qh = sprintf("SELECT * FROM cl_circuit_dbc WHERE ccd_dbcid = %d", $axid); + $rh = mysql_query($qh) or die(mysql_error()); + + $result = ''; + if ( mysql_num_rows($rh) ) { + $row = mysql_fetch_array($rh); + $result = $row['ccd_circuitcode']; + } else { + $result = 0; + } + + return $result; +} + +//----------------------------------------------------------------------------- +/** + * GET CIRCUIT CODE + * + * return circuit code for a dbc + * + * @param int dbc id + * @param bool|int + */ +function get_circuitcode($dbcid) { + if ( !$dbcid) return FALSE; + + mysql_query("SET NAMES utf8"); + $qc = sprintf("SELECT cl_circuit_beschrijving FROM cl_circuit clc + JOIN cl_circuit_dbc clcd ON clcd.ccd_circuitcode = clc.cl_circuit_code + WHERE clcd.ccd_dbcid = %d", $dbcid); + $r = mysql_query($qc) or die(mysql_error()); + + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); + return $row['cl_circuit_beschrijving']; + } else return FALSE; + +} + + +//----------------------------------------------------------------------------- +/** + * WRITE ZORG + * + * write zorg sysid for a closing dbc + * + * @param int - zorg sysid + * @return none + */ +function write_zorg($zsysid) { + // validate the code + $izsysid = ( vl_validate_zorg($zsysid) ) ? $zsysid : 1 ; + + $qz = sprintf("INSERT INTO cl_zorg_dbc VALUES(%d, %d)", $_SESSION['show_axid'], $izsysid); + $r = mysql_query($qz) or die(mysql_error()); +} + +//----------------------------------------------------------------------------- +/** + * WRITE STOORNIS + * + * save the value from stoornis dropdown + * + * @param int - cl_productgroep_sysid + * @return none + */ +function write_stoornis($zsysid) { + $qz = sprintf("INSERT INTO cl_productgroep_dbc VALUES(%d, %d)", $zsysid, $_SESSION['show_axid']); + $r = mysql_query($qz) or die(mysql_error()); +} + +//----------------------------------------------------------------------------- +/** + * WRITE REDEN + * + * @param int cl_redensluiten_code + * @return void + */ +function write_reden($rcode) { + // validate the code + $ircode = ( vl_validate_redencode($rcode) ) ? $rcode : 1 ; + + $qz = sprintf("INSERT INTO cl_redensluiten_dbc VALUES(%d, %d)", $ircode, $_SESSION['show_axid']); + $r = mysql_query($qz) or die(mysql_error()); +} + + +//----------------------------------------------------------------------------- +/** + * UPDATE GAF + * + * When closing a DBC we still need two values from GAF dropdowns (middle and end). + * The first one was on DBC opening. + * + * @param int $dbcid + * @param array $gaf + * @return bool + */ +function update_gaf($dbcid, $gaf) { + if ( !$dbcid ) return FALSE; + + $qz = sprintf("SELECT ax_as5 FROM cl_axes WHERE ax_id = %d", $dbcid); + $rz = mysql_query($qz) or die(mysql_error()); + $rowrz = mysql_fetch_array($rz); + + // we update the missing values + $unser = unserialize($rowrz['ax_as5']); + $un['gaf1'] = $unser['gaf1']; + $un['gaf2'] = mysql_real_escape_string($gaf['gaf2']); + $un['gaf3'] = mysql_real_escape_string($gaf['gaf3']); + $ser = serialize($un); + // update the new values + $qu = sprintf("UPDATE cl_axes SET ax_as5 = '%s' WHERE ax_id = %d", $ser, $dbcid); + $ru = mysql_query($qu) or die(mysql_error()); + + return TRUE; +} + +//----------------------------------------------------------------------------- +/** + * GET PRIMARY CARE PROVIDER INFOS + * + * used at demographics_full + * @param int patient_id + * @return array + */ +function get_provider_DBC($pid = 0) { + if ( !$pid ) return FALSE; + $qz = sprintf("SELECT * FROM cl_providers WHERE pro_pid = %d", $pid); + $r = mysql_query($qz) or die(mysql_error()); + return mysql_fetch_assoc($r); +} + +//----------------------------------------------------------------------------- +/** + * GET REFERER INFOS + * + * used at demographics_full + * @param int patient_id + * @return array + */ +function get_referer_DBC($pid = 0) { + if ( !$pid ) return FALSE; + $qz = sprintf("SELECT * FROM cl_referers WHERE ref_pid = %d", $pid); + $r = mysql_query($qz) or die(mysql_error()); + return mysql_fetch_assoc($r); +} + + +//----------------------------------------------------------------------------- +/** + * RETURN JOB DESCRIPTION (BEROEP) + * + * for a specified user + * + * @param int user id + * @param int $code - look for code or name field + * @return string + */ +function what_beroep($pid = 0, $code = 0) { + if ( !$pid ) return FALSE; + + $qz = sprintf("SELECT cl_beroep_element as cbe, cl_beroep_code as cbc + FROM cl_beroep JOIN cl_user_beroep ON cl_beroep.cl_beroep_sysid = cl_user_beroep.cl_beroep_sysid + WHERE cl_user_beroep.cl_beroep_userid = %d", $pid); + $rz = mysql_query($qz) or die(mysql_error()); + $rez = mysql_fetch_assoc($rz); + + return ( $code ) ? $rez['cbc'] : $rez['cbe']; +} + +//----------------------------------------------------------------------------- +/** + * RETURN FULL DUTCH NAME + * + * for a specified patient + * + * @param int $pid - patient id + * @return string $full_name + */ +function dutch_name($pid = 0) { + if ( !$pid ) return FALSE; + + mysql_query("SET NAMES utf8"); + + $qn = sprintf("SELECT fname, lname FROM patient_data WHERE id = %d", $pid); + $rn = mysql_query($qn) or die(mysql_error()); + $rez = mysql_fetch_assoc($rn); + + $full_name = ''; + $first_name = $rez['fname']; + $last_name = $rez['lname']; + + // then we look into patient_data_NL because it's not mandatory that there would be a record for this $pid + // (so, don't use JOIN between these tables) + $qn2 = sprintf("SELECT pdn_pxlast, pdn_pxlastpar, pdn_lastpar FROM patient_data_NL WHERE pdn_id = %d", $pid); + $rn2 = mysql_query($qn2) or die(mysql_error()); + + if ( mysql_num_rows($rn2) ) { + $reznl = mysql_fetch_assoc($rn2); + // partner is prefix + last name + $partner = ( $reznl['pdn_lastpar'] ) ? $reznl['pdn_pxlastpar'] .' '. $reznl['pdn_lastpar'] .' - ' : '' ; + $prefix = $reznl['pdn_pxlast']; + // we make the full name + $full_name = $first_name .' '. $partner . $prefix .' '. $last_name; + } else { + $full_name = $first_name .' '. $last_name; + } + + return $full_name; + + +} + +//----------------------------------------------------------------------------- +/** + * PREPARE STRINGS FOR UTF8 + * + * check if a string is UTF8 encoded; if not, convert it + * (the string must be ISO-8859-1 because we use utf8_encode function) + * + * @param string $string (utf8 or latin1) + * @return string - converted utf8 string + */ + +function sutf8($string) +{ + $rez = preg_match('%(?: + [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte + |\xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs + |[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte + |\xED[\x80-\x9F][\x80-\xBF] # excluding surrogates + |\xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 + |[\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 + |\xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 + )+%xs', $string); + + $newst = ( $rez ) ? $string : utf8_encode($string); + return $newst; +} + +//----------------------------------------------------------------------------- +/** + * RETURN ALL THE ZTN's FOR A PATIENT + * + * @param int $pid + * @return array - contains all ztn's (closed, open) ; empty array if not ztn available + */ +function all_ztn($pid = 0) { + if ( !$pid ) return FALSE; + + $result = array(); + $q = sprintf("SELECT * FROM cl_careroute_numbers WHERE cn_pid = %d ORDER BY cn_dopen", $pid); + $r = mysql_query($q) or die( mysql_error() ); + if ( mysql_num_rows($r) ) { + while ( $row = mysql_fetch_array($r) ) { + $result[] = $row; + } + } + + return $result; +} + +//----------------------------------------------------------------------------- +/** + * RETURN ALL THE DBC's FOR A PATIENT + * + * using ztn id + * + * @param int $ztn + * @return array - contains all dbc's (closed, open, sent to insurer) ; empty array if not ztn available + */ +function all_dbc($ztnid = 0) { + if ( !$ztnid ) return FALSE; + + $result = array(); + $q = sprintf("SELECT * FROM cl_axes WHERE ax_ztn = '%s' ORDER BY ax_odate", $ztnid); + $r = mysql_query($q) or die( mysql_error() ); + if ( mysql_num_rows($r) ) { + while ( $row = mysql_fetch_array($r) ) { + $result[] = $row; + } + } + + return $result; +} + +//----------------------------------------------------------------------------- +/** + * OPEN ZTN/DBC? + * + * verify for a patient if a ZTN is already opened + * if it is, verify further if there is any open DBC + * + * DBC opened - DBC open - 2 + * DBC closed - Geen DBC - 1 + * ZTN closed - Dossier gesloten - 0 + * + * @param $pid patient id + * @return array - a string + a value + */ +function has_ztndbc($pid = 0){ + if ( !$pid ) return FALSE; + $result = ''; + + // search for an opened ZTN (id1007) + $qc = sprintf("SELECT cn_ztn FROM cl_careroute_numbers WHERE cn_pid = %d AND cn_open = '1'", $pid); + $rez = mysql_query($qc) or die(mysql_error()); + if ( mysql_num_rows($rez) ) { + $row = mysql_fetch_array($rez); + $opened_ztn = $row['cn_ztn']; + + $qb = sprintf("SELECT * FROM cl_axes WHERE ax_ztn = '%s' AND ax_open = '1' ", $opened_ztn); + $rezb = mysql_query($qb) or die(mysql_error()); + + $result['str'] = ( mysql_num_rows($rezb) ) ? 'DBC open.' : 'Geen DBC!'; + $result['code'] = ( mysql_num_rows($rezb) ) ? 2 : 1; + + } else { + $result['str'] = 'Dossier gesloten!'; $result['code'] = 0; + } + + return $result; +} + + +//----------------------------------------------------------------------------- +/** + * BEROEP DROPDOWN + * + * build the dropdown for providers jobs + * name: beroep id: beroep + * + * @param int $selected + * @return void - just echo the string - html encoded + */ +function beroep_dropdown($selected = 0){ + + $string = ''; + echo $string; + +} + +//----------------------------------------------------------------------------- +/** + * ZORGTYPECODES DROPDOWN + * + * build the dropdown for zorg types codes + * in dbc closing section (dbc_close.php) + * + * name="ztc" id="ztc" + * + * @param none + * @return void - just echo the string - html encoded + */ +function zorgtype_dropdown(){ + + $string = ''; + + echo $string; + +} + +//----------------------------------------------------------------------------- +/** + * PATIENT AGE + * + * return the patient age + * (!) uses a function from OpenEMR + * + * @param int $pid - patient ID + * @return int - age in years + */ +function patient_age($pid = 0){ + if ( !$pid ) return FALSE; + + // retrieve DOB for the patient + $q = sprintf("SELECT DOB FROM patient_data WHERE id = %d ", $pid); + $r = mysql_query($q) or die(mysql_error()); + $row = mysql_fetch_array($r); + + $dob = $row['DOB']; + if ( 0 == $dob ) { + vl_log("Patient with ID: $pid doesn't have DOB!"); return FALSE; + } + + $dobn = str_replace('-','', $dob); + $age = getPatientAge($dobn); // function from library/patient.inc + + // $age can contain strings like 6 month, 8 month for age < 2 years old + if ( is_string($age) ) $age = 2; + + return $age; +} + +//----------------------------------------------------------------------------- +/** + * HAS BEGIN GAF + * + * for some patients (with age < 4) we don't fill a begin GAF - AS5 + * so, if we close the DBC, we don't ask for the other 2 GAF if we don't have the first one. + * + * @param int $axid - DBC id + * @return bool - true if there is a begin GAF + */ +function has_beginGAF($axid = 0){ + if ( !$axid ) return FALSE; + + $dbc = content_diagnose($axid); + $ax5 = unserialize($dbc['ax_as5']); + + return ( !empty($ax5) ); + +} + +//----------------------------------------------------------------------------- +/** + * DISPLAY LINKS + * + * display links as Add/Edit DSM-IV, Close DSM-IV, etc... in coding.php (patient_file) + * + * @param none + * @return void + */ +function display_links(){ + $retcode = ztn_status(); // find the ZTN situation + + switch ( $retcode ) { + case 0: $msg = 'No ZTN opened!'; break; + case 1: + case 3: $msg = '
Add DSM IV
+
Close ZTN
'; break; + case 2: $msg = '
Edit DSM IV
+
DBC Sluiten
'; break; + case 4: $msg = '
Follow up display
+
DBC Sluiten
'; break; + } + + echo $msg; +} + +//----------------------------------------------------------------------------- +/** + * RETURN THE DBC'S W/OUT FUTURE EVENTS + * + * return opened dbc's without future events + * + * @param none + * @return array + */ +function df_future_events(){ + $resarr = array(); // dummy array for result + $date = date('Y-m-d'); + $q = mysql_query("SELECT * FROM cl_axes ca WHERE ca.ax_open = 1 ORDER BY ca.ax_odate") or die(mysql_error()); + + if ( mysql_num_rows($q) ) { + while ( $row = mysql_fetch_array($q) ) { + $count = 0; + $pid = what_patient($row['ax_id']); + $fe = mysql_query("SELECT COUNT(*) AS a FROM openemr_postcalendar_events WHERE pc_pid = $pid + AND pc_eventDate > '$date' ") or die(mysql_error()); + $rfe = mysql_fetch_array($fe); + $count = $rfe['a']; // how many future encounters + + if ( !$count ) { $row['pid'] = $pid; $resarr[] = $row; } + + } // while + } + + return $resarr; + +} + + +//----------------------------------------------------------------------------- +/** + * RETURN OPENED DBC'S WITH TOTAL TIME + * + * the times are separated per years 2007/2008 + * + * @param none + * @return array + */ +function df_allopendbc_wtimes(){ + $resarr = array(); // dummy array for result + $today = date('Y-m-d'); + $q = mysql_query("SELECT * FROM cl_axes ca WHERE ca.ax_open = 1 ORDER BY ca.ax_odate") or die(mysql_error()); + + if ( mysql_num_rows($q) ) { + $count = 1; + while ( $row = mysql_fetch_array($q) ) { + $odate = $row['ax_odate']; + $resarr[$count]['dbcid'] = $row['ax_id']; + $resarr[$count]['odate'] = $odate; + + if ( $odate <= '2007-12-31' ) { + $times2007 = total_time_spent($row['ax_id'], $odate, '2007-12-31'); + $times2008 = total_time_spent($row['ax_id'], '2008-01-01', $today); + $resarr[$count]['2007'] = $times2007['total_time']; + $resarr[$count]['2008'] = $times2008['total_time']; + } else { + $times = total_time_spent($row['ax_id'], '2008-01-01', $today); + $resarr[$count]['2007'] = 0; + $resarr[$count]['2008'] = $times['total_time']; + } + + $pid = what_patient($row['ax_id']); + $resarr[$count]['pid'] = $pid; // using $times as a returning array + $count++; + } // while + } +//echo '
' . print_r($resarr, TRUE) . '
'; // debug + return $resarr; + +} + +//----------------------------------------------------------------------------- +/** + * RETURNS SELECTED ACTIVITY FROM THE FORM + * + * it's about add_edit_event.php form + * @param none + * @return string + */ +function selected_ac() { + // same logic as in javascript validation + if ( $_POST['box5'] ) $ac = $_POST['box5']; + elseif ( $_POST['box4']) $ac = $_POST['box4']; + elseif ( $_POST['box3']) $ac = $_POST['box3']; + elseif ( $_POST['box2']) $ac = $_POST['box2']; + elseif ( $_POST['box1']) $ac = $_POST['box1']; + + return $ac; +} + + +//----------------------------------------------------------------------------- +/** + * RETURN OPENED DBC'S WITH MONEY VALUES FOR EACH + * + * it simulates a closing for opened DBC's + * + * @param none + * @return array + */ +function df_dbcvalues(){ + $dbcdata = array(); // dummy array for result + $ztn = 180101 ; // default zorgtraject at closing (Reguliere zorg) + $today = date('Y-m-d'); + $q = mysql_query("SELECT * FROM cl_axes ca WHERE ca.ax_open = 1 ORDER BY ca.ax_odate") or die(mysql_error()); + + if ( mysql_num_rows($q) ) { + $count = 1; + global $rfsum; + while ( $row = mysql_fetch_array($q) ) { + $dbcid = $row['ax_id']; + + $rfsum = 0; // reset the rfsum! + dt_main(1, $dbcid, $today); + $z = dt_whatproductgroep($rfsum, $today); + $pcode = $z['id']; + + $prestatie = dt_prestatiecode($ztn, $pcode, $dbcid, 1); + + $declaratie = df_declaratie($prestatie, $today); + $tariff = df_tariff($declaratie, $today); + + $dedamo = ( vk_is_overloop_dbc($dbcid) ) ? vk_deduction($dbcid) : 0; + + $tariff_per = round (((int)$tariff * C417) / 10000); + $tariff_final = $tariff_per - $dedamo; + + + $dbcdata[$count]['pid'] = what_patient($dbcid); + $dbcdata[$count]['dbcid'] = $dbcid; + $dbcdata[$count]['rfsum'] = $rfsum; + $dbcdata[$count]['pcode'] = $pcode; + $dbcdata[$count]['prestatie'] = $prestatie; + $dbcdata[$count]['declaratie'] = $declaratie; + $dbcdata[$count]['tariff'] = $tariff_final; + $dbcdata[$count]['odate'] = $row['ax_odate']; + + $count++; + } // while + } + + return $dbcdata; + +} + + +//----------------------------------------------------------------------------- +/** + * DECLARATIE CODE + * + * used by df_dbcvalues() + * + * @param + * @return + */ +function df_declaratie($pcode, $cdate) { + $q = sprintf("SELECT cl_declaratiecode AS cd FROM cl_prestatiecode WHERE cl_dbc_prestatiecode = '%s' + AND cl_prestatiecode_begindatum <= '%s' AND cl_prestatiecode_einddatum >= '%s' ", $pcode, $cdate, $cdate); + $r = mysql_query($q) or die(mysql_error()); + + if ( $row = mysql_fetch_array($r) ) { + $retval = $row['cd']; + } else { + $retval = 0; + } + + return $retval; +} + + +function df_tariff($decode, $date) { + $q = sprintf("SELECT cl_dbc_tarief FROM cl_dbc_tarief WHERE cl_declaratiecode = '%s' + AND cl_dbc_tarief_begindatum <= '%s' AND cl_dbc_tarief_einddatum >= '%s' ", $decode, $date, $date); + $r = mysql_query($q) or die(mysql_error()); + + if ( mysql_num_rows($r) ) { + $row = mysql_fetch_array($r); $val = $row['cl_dbc_tarief']; + } else { + $val = 0; + } + + return $val; +} + + +//----------------------------------------------------------------------------- +?> diff --git a/library/DBC_include.php b/library/DBC_include.php new file mode 100644 index 000000000..d1accf89a --- /dev/null +++ b/library/DBC_include.php @@ -0,0 +1,22 @@ + \ No newline at end of file diff --git a/library/DBC_validations.php b/library/DBC_validations.php new file mode 100644 index 000000000..bb2a31839 --- /dev/null +++ b/library/DBC_validations.php @@ -0,0 +1,540 @@ += 4 ) { + $good &= vl_diagnose_exist($as5['gaf1']); + $alldiag[] = $a5['gaf1']; + } + + // now we check for unique values + // the arrays must be the same if there are no duplicated values + $uniqdiag = array_unique($alldiag); + if ( count($uniqdiag) != count($alldiag) ) $good &= FALSE; + + return $good; + +} + + +// ---------------------------------------------------------------------------- +/** + * SIMPLE CHECK IF A DIAGNOSE EXISTS + * + * check if a diagnose is valid (exists in database) + * + * @access private + * @param string $diag - diagnose to check + * @return bool + */ +function vl_diagnose_exist($diag) { + $q = sprintf("SELECT * FROM cl_diagnose WHERE cl_diagnose_code = '%s' ", trim($diag)); + $r = mysql_query($q) or die (mysql_error()); + return mysql_num_rows($r); +} + + +// ---------------------------------------------------------------------------- +/** + * VALIDATE ZORGCODE + * + * validates the zorg sysid + * + * @param int $zorgsysid + * @return bool - an integer for true, otherwise FALSE + */ +function vl_validate_zorg($zorgsysid = 0) { + if ( !$zorgsysid ) return FALSE; + + $q = sprintf("SELECT * FROM cl_zorg WHERE cl_zorgtype_sysid = %d ", $zorgsysid); + $r = mysql_query($q) or die (mysql_error()); + return mysql_num_rows($r); +} + + +// ---------------------------------------------------------------------------- +/** + * CHECK IF THE MAIN DIAGNOSE IS NOT ON THE FORBIDDEN LIST OF ITEMS + * + * @access private + * @param string $diag - diagnose to check + * @return bool - true if it's forbidden + */ +function vl_main_forbidden($diag) { + + $forbidden_list = array('as1_18.02', 'as1_18.03', 'as2_18.02', 'as2_18.03', 'as2_17.01', 'as2_01.01.01', + 'as2_01.01.02', 'as2_01.01.03', 'as2_01.01.04', 'as2_01.01.05'); + $diag = trim($diag); + + return in_array($diag, $forbidden_list); + +} + + + + +// ---------------------------------------------------------------------------- +/** + * LOG + * + * simple function to log different events + * + * @param string $string + * @return + */ +function vl_log($string) { + $file = TMPDIR_DBC . '/DBC_problems.log'; + if ( !$h = fopen($file, 'ab') ) { + echo "Cannot create file ($filename)"; + exit; + } + + $content = date('d-m-Y') . " $string \r\n"; + + // WRITE DATA TO FILE + if ( fwrite($h, $content) === FALSE ) { + echo "Cannot write to file ($filename)"; + exit; + } + + fclose($h); + +} + + +// ---------------------------------------------------------------------------- +/** + * VERIFY PATIENT AGE WHEN CLOSING A DBC + * + * At the moment of closing DBC, if we have ZTC code = 115 | 210 (Ondertoezichtstelling) + * the patient must have the age < 18 years at the moment of opening DBC. + * We leave $ztcode here because we are sure that this code validation has already take place. + * + * @param int $ztcode - zorg code from the dropdown + * @param string $axodate - opening date for the DBC + * @param int $pid - patient id + * @return bool + */ +function vl_ztc_age($ztcode = 0, $axodate = 0, $pid = 0) { + if ( !$ztcode || !$axodate || !$pid) return FALSE; + + // these are the only 2 checked codes + if ( ( $ztcode != '180115') && ($ztcode != '180210') ) return TRUE; + + $age = patient_age($pid); + + return ( $age < 18 ); + +} + +// ---------------------------------------------------------------------------- +/** + * VERIFY IF THE CLOSING DATE IS BIGGER THAN LAST ACTIVITY DATE + * + * At the moment of closing DBC, we must have the closing date bigger than + * the date of the last activity associated with that DBC. + * With other words, the DBC must be closed AFTER all activities. + * + * @param string $eind - closing date + * @param int $axid - id for DBC + * @param int $pid - patient ID + * @return array - bool + string (result and lastdate) + */ +function vl_eind_event($eind = 0, $axid = 0, $pid = 0) { + if ( !$eind || !$axid || !$pid) return FALSE; + + // begin date for DBC + $cd = content_diagnose($axid); + $bd_dbc = $cd['ax_odate']; + + // find all events between DBC's dates and sum up total times + $q = sprintf("SELECT MAX(pc_eventDate) AS pcdate + FROM openemr_postcalendar_events + WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_apptstatus = '@' ", + $pid, $bd_dbc); + $r = mysql_query($q) or die(mysql_error()); + + if ( !mysql_num_rows($r) ) return FALSE; + $row = mysql_fetch_array($r); + $lastdate = strtotime($row['pcdate']); + $axdate = strtotime($eind); + + $result['bool'] = ( $axdate >= $lastdate ); + $result['date'] = $row['pcdate']; + + return $result; +} + +// ---------------------------------------------------------------------------- +/** + * VALIDATE THE TIMINGS FOR A SPECIFIC ACTIVITY + * + * if activity is act_1 or act_7% then no times (encounter, travel, indirect must be 0) + * NOTE: apparently not used anymore + * + * @param string $ac - activity string + * @return bool - true (there are no timings) if activity matches conditions + */ +function vl_activity_timing($ac) { + return ( $ac == 'act_1' || (strpos($ac, 'act_7') !== FALSE) ); + +} + + +// ---------------------------------------------------------------------------- +/** + * VALIDATE THE TRAVEL TIME FOR A SPECIFIC ACTIVITY + * + * if activity has mag_reistijd code = N (in cl_activiteit table), then no travel time + * + * @param string $ac - activity string + * @return bool - true (there are no timings) if activity matches conditions + */ +function vl_activity_travel($ac) { + $q = sprintf("SELECT cl_activiteit_mag_reistijd AS reis FROM cl_activiteit WHERE cl_activiteit_code = '%s' ", $ac); + $r = mysql_query($q) or die (mysql_error()); + + $row = mysql_fetch_array($r); + return ( $row['reis'] == 'N' ); +} + +// ---------------------------------------------------------------------------- +/** + * CHECK FOR ZORGTYPE CODE VALUE OF 104 + * + * if zorgtype code = 104 (sysid 180104), then all activities must have cl_activiteit_mag_groep = N + * must be called from within the openemr/dbc closing form + * + * @param none + * @return bool - true if all activities meet conditions + */ +function vl_zorgtype_104() { + $dia = content_diagnose($_SESSION['show_axid']); + $odate = $dia['ax_odate']; + $pid = (int)$_SESSION['pid']; + + // find all events from DBC opening and look for activities + $q = sprintf("SELECT pc_eid FROM openemr_postcalendar_events + WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_apptstatus = '@' ", + $pid, $odate); + $r = mysql_query($q) or die(mysql_error()); + + $res = TRUE; + while ( $row = mysql_fetch_array($r) ) { + $qe = sprintf("SELECT cl_activiteit_mag_groep AS cgroep FROM cl_activiteit ca + JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid + WHERE cea.event_id = %d", $row['pc_eid']); + $re = mysql_query($qe) or die(mysql_error()); + $rowe = mysql_fetch_array($re); + + if ( $rowe['cgroep'] != 'N' ) { + $res = FALSE; break; + } + } // while + + return $res; +} + + +// ---------------------------------------------------------------------------- +/** + * CHECK FOR ZORGTYPE CODE VALUE OF 104 + * + * if zorgtype code = 104 (sysid 180104), then direct time must be < 180 + * must be called from within the openemr/dbc closing form + * + * @param none + * @return bool - true if all activities meet conditions + */ +function vl_zorgtype_880() { + $ttime = total_time_spent(); + + return ( $ttime['total_time'] < 180); + +} + +// ---------------------------------------------------------------------------- +/** + * CHECK FOR ZORGTYPE CODE VALUE OF 106 + * + * if zorgtype code = 106 (sysid 180106), then direct time must be <= 250 + * must be called from within the openemr/dbc closing form + * + * @param none + * @return bool - true if all activities meet conditions + */ +function vl_zorgtype_106() { + $ttime = total_time_spent(); + $direct_time = $ttime['total_time'] - $ttime['indirect_time'] - $ttime['travel_time']; + + return ( $direct_time <= 250); + +} + +// ---------------------------------------------------------------------------- +/** + * CHECK FOR ZORGTYPE CODE VALUE OF 102 + * + * if zorgtype code = 102 (sysid 180102), then total length of DBC must be < 29 days + * must be called from within the openemr/dbc closing form + * + * @param int $axid - DBC id + * @param string $eind - ending date + * @return bool - true if the conditions are met + */ +function vl_zorgtype_102($axid, $eind) { + + $len = df_dbc_age($axid, $eind); + + return ( $len < 29); + +} + + +// ---------------------------------------------------------------------------- +/** + * CHECK FOR ZORGTYPE CODE VALUE OF 111 + * + * if zorgtype code = 111 (sysid 180111), then there is at least one provider with + * job starting with MB*. + * must be called from within the openemr/dbc closing form + * + * @param none + * @return bool - true if it's at least one provider with MB + */ +function vl_zorgtype_111() { + $dia = content_diagnose($_SESSION['show_axid']); + $odate = $dia['ax_odate']; + $pid = (int)$_SESSION['pid']; + + // find all events from DBC opening and look for activities + $q = sprintf("SELECT pc_aid, pc_eid FROM openemr_postcalendar_events + WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_apptstatus = '@' ", + $pid, $odate); + $r = mysql_query($q) or die(mysql_error()); + + $res = FALSE; + while ( $row = mysql_fetch_array($r) ) { + $qe = sprintf("SELECT cl_beroep_code AS cbc FROM cl_beroep cb + JOIN cl_user_beroep cub ON cub.cl_beroep_sysid = cb.cl_beroep_sysid + WHERE cub.cl_beroep_userid = %d ", $row['pc_aid']); + $re = mysql_query($qe) or die(mysql_error()); + $rowe = mysql_fetch_array($re); + + if ( strpos($rowe['cbc'], 'MB.') === 0 ) { + $res = TRUE; break; + } + } // while + + // as a last resort, we check for the job of the provider who close the DBC + if ( !$res ) { + $ql = sprintf("SELECT cl_beroep_code AS cbc FROM cl_beroep cb + JOIN cl_user_beroep cub ON cub.cl_beroep_sysid = cb.cl_beroep_sysid + WHERE cub.cl_beroep_userid = %d ", $_SESSION['authId']); + $rl = mysql_query($ql) or die(mysql_error()); + $rowl = mysql_fetch_array($rl); + if ( strpos($rowl['cbc'], 'MB.') === 0 ) { + $res = TRUE; + } + } + + return $res; + +} + + +// ---------------------------------------------------------------------------- +/** + * CHECK FOR REDENSLUITEN CODE 5 IF THERE ARE FORBIDDEN ACTIVITIES + * + * cl_activiteit_code should NOT contain act_3*, act_4*, act_5*, act_9* or act_10*) + * must be called from within the openemr/dbc closing form + * + * @param none + * @return void + */ +function vl_redensluiten_5() { + $dia = content_diagnose($_SESSION['show_axid']); + $odate = $dia['ax_odate']; + $pid = (int)$_SESSION['pid']; + + // find all events from DBC opening and look for activities + $q = sprintf("SELECT pc_eid FROM openemr_postcalendar_events + WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_apptstatus = '@' ", + $pid, $odate); + $r = mysql_query($q) or die(mysql_error()); + + $res = TRUE; + while ( $row = mysql_fetch_array($r) ) { + $qe = sprintf("SELECT cl_activiteit_code AS acode FROM cl_activiteit ca + JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid + WHERE cea.event_id = %d", $row['pc_eid']); + $re = mysql_query($qe) or die(mysql_error()); + $rowe = mysql_fetch_array($re); + + $c = $rowe['acode']; // activity code + + // check for forbidden activities + $pos1 = strpos($c, 'act_3'); + $pos2 = strpos($c, 'act_4'); + $pos3 = strpos($c, 'act_5'); + $pos4 = strpos($c, 'act_9'); + $pos5 = strpos($c, 'act_10'); + if ( ($pos1 === FALSE) && ($pos2 === FALSE) && ($pos3 === FALSE) && ($pos4 === FALSE) && ($pos5 === FALSE) ) { + $res = TRUE; + } else { + $res = FALSE; break; + } + } // while + + return $res; +} + + +// ---------------------------------------------------------------------------- +/** + * CHECK FOR ALLOWED COMBINATION OF ACTIVITIES FOR A DBC + * + * the following are forbidden: + * ONLY act_4.2* or + * ONLY act_9* or + * act_4.2* in combination with act_1 || act_2 || act_7* || act_9* + * + * @param $dbcid - dbc id + * @return bool + */ +function vl_validdbc_combinations($dbcid) { + $dia = content_diagnose($dbcid); + $odate = $dia['ax_odate']; + $cdate = $dia['ax_cdate']; + $pid = what_patient($dbcid); + + // find all events from DBC opening to DBC closing and look for activities + $q = sprintf("SELECT pc_eid FROM openemr_postcalendar_events + WHERE pc_pid = %d AND pc_eventDate >= '%s' AND pc_eventDate <= '%s' AND pc_apptstatus = '@' ", + $pid, $odate, $cdate); + $r = mysql_query($q) or die(mysql_error()); + + $acodes = array(); + while ( $row = mysql_fetch_array($r) ) { + $qe = sprintf("SELECT cl_activiteit_code AS acode FROM cl_activiteit ca + JOIN cl_event_activiteit cea ON cea.activity_sysid = ca.cl_activiteit_sysid + WHERE cea.event_id = %d", $row['pc_eid']); + $re = mysql_query($qe) or die(mysql_error()); + $rowe = mysql_fetch_array($re); + + // for forbidden ones, we use only pattern part + $ac = $rowe['acode']; // activity code + if ( strpos($ac, 'act_4.2') === 0 ) $acodes[] = 'act_4.2'; + else if ( strpos($ac, 'act_7') === 0 ) $acodes[] = 'act_7'; + else if ( strpos($ac, 'act_9') === 0 ) $acodes[] = 'act_9'; + else $acodes[] = $ac; + } // while + + // now we analyze all the activities codes + // check if all values are act_4.2* / act_9 forms + $c = array_count_values($acodes); + if ( $c['act_4.2'] == count($acodes) ) return FALSE; + if ( $c['act_9'] == count($acodes) ) return FALSE; + + // now we check for combinations for act_4.2 + if ( in_array('act_4.2', $c) ) { + $rez_1 = !( in_array('act_1', $c) || in_array('act_2', $c) || in_array('act_7', $c) || in_array('act_9', $c) ); + } else $rez_1 = TRUE; + + // now we check for act_10.2 condition + if ( in_array('act_10.2', $c) ) { + $rez_2 = in_array('act_3.2', $c); + } else $rez_2 = TRUE; + + /*if ( in_array('act_9', $c) ) { + WORK ZONE !!! + }*/ + + // combine the results + return ($rez_1 && $rez_2); +} +// ---------------------------------------------------------------------------- +?> \ No newline at end of file diff --git a/library/js/add_edit_event.js b/library/js/add_edit_event.js new file mode 100644 index 000000000..6fa66c56b --- /dev/null +++ b/library/js/add_edit_event.js @@ -0,0 +1,155 @@ +function verify_selecteerbaar (a) { + var f = document.forms[0]; var a; + if (f.box5.value != 0) a = f.box5.value; + else if (f.box4.value != 0) a = f.box4.value; + else if (f.box3.value != 0) a = f.box3.value; + else if (f.box2.value != 0) a = f.box2.value; + else if (f.box1.value != 0) a = f.box1.value; + else { alert('You must choose an activity.'); return false; } + + var answer = $.ajax({ + url: "", + type: 'POST', + data: 'vcode='+a, + async: false + }).responseText; + if ( answer == 'false') { alert("Please select again"); return false; } +} + + +/* +================================================== +DROPDOWNS FOR ACTIVITIES + +================================================== +*/ +function boxes() { + +$(document).ready(function(){ + var link_dbc = '../../../library/DBC_functions.php'; + $('#box2').hide(); + $('#box3').hide(); + $('#box4').hide(); + $('#box5').hide(); + $('#box1').bind('change', function(){ + $('#box2').html( + $.ajax({ + type: 'POST', + url: link_dbc, + data: 'code=' + $('#box1').val(), + async: false, + }).responseText + ) + // validation for timing NOTA maybe not used anymore + /*valbox = $('#box1').val(); + if ( valbox == 'act_1' || valbox == 'act_7' ) { + this.form.form_duration.disabled = true; this.form.form_duration.value = 0; + this.form.form_duration_indirect.disabled = true; + this.form.form_duration_travel.disabled = true; + } else { + this.form.form_duration.disabled = false; + this.form.form_duration_indirect.disabled = false; + this.form.form_duration_travel.disabled = false; + }*/ + }); + + $('#box1').bind('focus', function(){ + $('#box2').show(); $('#box3').hide(); $('#box4').hide(); $('#box5').hide(); + }); + + $('#box2').bind('change', function(){ + $('#box3').html( + $.ajax({ + type: 'POST', + url: link_dbc, + data: 'code=' + $('#box2').val(), + async: false, + }).responseText + ) + }); + // if empty box, prevent the next to show + $('#box2').bind('focus', function(){ + if ( $('#box2').val() != 0 ) { + $('#box3').show(); } + else { + $('#box3').hide(); + } + $('#box4').hide(); $('#box5').hide(); + }); + + $('#box3').bind('change', function(){ + $('#box4').html( + $.ajax({ + type: 'POST', + url: link_dbc, + data: 'code=' + $('#box3').val(), + async: false, + }).responseText + ) + }); + // if empty box, prevent the next to show + $('#box3').bind('focus', function(){ + if ( $('#box3').val() != 0 ) { + $('#box4').show(); } + else { + $('#box4').hide(); + } + $('#box5').hide(); + }); + + $('#box4').bind('change', function(){ + $('#box5').html( + $.ajax({ + type: 'POST', + url: link_dbc, + data: 'code=' + $('#box4').val(), + async: false + }).responseText + ) + }); + // if empty box, prevent the next to show + $('#box4').bind('focus', function(){ + if ( $('#box4').val() != 0 ) { + $('#box5').show(); } + else { + $('#box5').hide(); + } + }); + + // time validation client side + $('#form_save').bind('click', function(){ + // validation for timing + durbox = $('#form_duration').val(); + valbox = $('#box2').val(); + if ( valbox == 'act_3.2' && (!parseInt(durbox, 10)) ) { + alert("For selected activity you must have a value for direct time!"); + window.close(); + } + }); +}); + +} + + +/* +================================================== +EDITING CASE + +================================================== +*/ +function editcase() { +$(document).ready(function(){ + var link_dbc = '../../../library/DBC_functions.php'; + $('#box1').attr('disabled', true); + $('#addc').bind('click', function(){ + $('#box1').attr('disabled', false); + $.ajax({ + url: link_dbc, + type: 'POST', + data: 'editactiv=1', + async: false + }); +}); +}); + +} \ No newline at end of file diff --git a/library/js/jquery-calendar.css b/library/js/jquery-calendar.css new file mode 100644 index 000000000..4e8d45969 --- /dev/null +++ b/library/js/jquery-calendar.css @@ -0,0 +1,167 @@ +/* Main Style Sheet for jQuery Calendar */ +#calendar_div, .calendar_inline { + font-family: Arial, Helvetica, sans-serif; + font-size: 14px; + padding: 0; + margin: 0; + background: #ddd; +} +#calendar_div { + display: none; + border: 1px solid #777; + z-index: 10; /*must have*/ +} +#calendar_div, .calendar_control, .calendar_links, .calendar_header, .calendar { + width: 185px; +} +.calendar_inline { + float: left; + display: block; + border: 0; +} +.calendar_dialog { + padding: 5px !important; + border: 4px ridge #ddd !important; +} +button.calendar_trigger { + width: 25px; +} +img.calendar_trigger { + margin: 2px; + vertical-align: middle; +} +.calendar_prompt { + float: left; + width: 181px; + padding: 2px; + background: #ddd; + color: #000; +} +* html .calendar_prompt { + width: 185px; +} +.calendar_control, .calendar_links, .calendar_header, .calendar { + clear: both; + float: left; + color: #fff; +} +.calendar_control { + background: #400; +} +.calendar_links { + background: #000; +} +.calendar_control, .calendar_links { + font-weight: bold; + font-size: 80%; + letter-spacing: 1px; +} +.calendar_links label { /* disabled links */ + padding: 2px 5px; + color: #888; +} +.calendar_clear, .calendar_prev { + float: left; +} +.calendar_current { + float: left; + width: 35%; + text-align: center; +} +.calendar_close, .calendar_next { + float: right; +} +.calendar_header { + background: #333; + text-align: center; + font-weight: bold; +} +.calendar_header select { + background: #333; + color: #fff; + border: 0px; + font-weight: bold; +} +.calendar { + background: #ccc; + text-align: center; + font-size: 100%; +} +.calendar a { + display: block; + width: 100%; +} +.calendar .calendar_titleRow { + background: #777; +} +.calendar .calendar_daysRow { + background: #eee; + color: #666; +} +.calendar .calendar_daysCell { + color: #000; + border: 1px solid #ddd; +} +#calendar .calendar_daysCell a{ + display: block; +} +.calendar .calendar_weekEndCell { + background: #ddd; +} +.calendar .calendar_daysCellOver { + background: #fff; + border: 1px solid #777; +} +.calendar .calendar_unselectable { + color: #888; +} +.calendar_today { + background: #fcc !important; +} +.calendar_currentDay { + background: #999 !important; +} + +/* ________ CALENDAR LINKS _______ + +** Reset link properties and then override them with !important */ +#calendar_div a, .calendar_inline a { + cursor: pointer; + margin: 0; + padding: 0; + background: none; + color: #000; +} +.calendar_inline .calendar_links a { + padding: 0 5px !important; +} +.calendar_control a, .calendar_links a { + padding: 2px 5px !important; + color: #eee !important; +} +.calendar_titleRow a { + color: #eee !important; +} +.calendar_control a:hover { + background: #fdd !important; + color: #333 !important; +} +.calendar_links a:hover, .calendar_titleRow a:hover { + background: #ddd !important; + color: #333 !important; +} + +/* ___________ IE6 IFRAME FIX ________ */ + +.calendar_cover { + display: none; /*sorry for IE5*/ + display/**/: block; /*sorry for IE5*/ + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 193px; /*must have to match width and borders*/ + height: 200px; /*must have to match maximum height*/ +} + diff --git a/library/js/jquery-calendar.js b/library/js/jquery-calendar.js new file mode 100644 index 000000000..4d70d3d55 --- /dev/null +++ b/library/js/jquery-calendar.js @@ -0,0 +1,814 @@ +/* jQuery Calendar v2.7 + Written by Marc Grabanski (m@marcgrabanski.com) and enhanced by Keith Wood (kbwood@iprimus.com.au). + + Copyright (c) 2007 Marc Grabanski (http://marcgrabanski.com/code/jquery-calendar) + Dual licensed under the GPL (http://www.gnu.org/licenses/gpl-3.0.txt) and + CC (http://creativecommons.org/licenses/by/3.0/) licenses. "Share or Remix it but please Attribute the authors." + Date: 09-03-2007 */ + +/* PopUp Calendar manager. + Use the singleton instance of this class, popUpCal, to interact with the calendar. + Settings for (groups of) calendars are maintained in an instance object + (PopUpCalInstance), allowing multiple different settings on the same page. */ +function PopUpCal() { + this._nextId = 0; // Next ID for a calendar instance + this._inst = []; // List of instances indexed by ID + this._curInst = null; // The current instance in use + this._disabledInputs = []; // List of calendar inputs that have been disabled + this._popUpShowing = false; // True if the popup calendar is showing , false if not + this._inDialog = false; // True if showing within a "dialog", false if not + this.regional = []; // Available regional settings, indexed by language code + this.regional[''] = { // Default regional settings + clearText: 'Clear', // Display text for clear link + closeText: 'Close', // Display text for close link + prevText: '<Prev', // Display text for previous month link + nextText: 'Next>', // Display text for next month link + currentText: 'Today', // Display text for current month link + dayNames: ['Su','Mo','Tu','We','Th','Fr','Sa'], // Names of days starting at Sunday + monthNames: ['January','February','March','April','May','June', + 'July','August','September','October','November','December'], // Names of months + dateFormat: 'DMY/' // First three are day, month, year in the required order, + // fourth (optional) is the separator, e.g. US would be 'MDY/', ISO would be 'YMD-' + }; + this._defaults = { // Global defaults for all the calendar instances + autoPopUp: 'focus', // 'focus' for popup on focus, + // 'button' for trigger button, or 'both' for either + appendText: '', // Display text following the input box, e.g. showing the format + buttonText: '...', // Text for trigger button + buttonImage: '', // URL for trigger button image + buttonImageOnly: false, // True if the image appears alone, false if it appears on a button + closeAtTop: true, // True to have the clear/close at the top, + // false to have them at the bottom + hideIfNoPrevNext: false, // True to hide next/previous month links + // if not applicable, false to just disable them + changeMonth: true, // True if month can be selected directly, false if only prev/next + changeYear: true, // True if year can be selected directly, false if only prev/next + yearRange: '-10:+10', // Range of years to display in drop-down, + // either relative to current year (-nn:+nn) or absolute (nnnn:nnnn) + firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ... + changeFirstDay: true, // True to click on day name to change, false to remain as set + showOtherMonths: false, // True to show dates in other months, false to leave blank + minDate: null, // The earliest selectable date, or null for no limit + maxDate: null, // The latest selectable date, or null for no limit + speed: 'medium', // Speed of display/closure + customDate: null, // Function that takes a date and returns an array with + // [0] = true if selectable, false if not, + // [1] = custom CSS class name(s) or '', e.g. popUpCal.noWeekends + fieldSettings: null, // Function that takes an input field and + // returns a set of custom settings for the calendar + onSelect: null // Define a callback function when a date is selected + }; + $.extend(this._defaults, this.regional['']); + this._calendarDiv = $('
'); + $(document.body).append(this._calendarDiv); + $(document.body).mousedown(this._checkExternalClick); +} + +$.extend(PopUpCal.prototype, { + /* Register a new calendar instance - with custom settings. */ + _register: function(inst) { + var id = this._nextId++; + this._inst[id] = inst; + return id; + }, + + /* Retrieve a particular calendar instance based on its ID. */ + _getInst: function(id) { + return this._inst[id] || id; + }, + + /* Override the default settings for all instances of the calendar. + @param settings object - the new settings to use as defaults (anonymous object) + @return void */ + setDefaults: function(settings) { + $.extend(this._defaults, settings || {}); + }, + + /* Handle keystrokes. */ + _doKeyDown: function(e) { + var inst = popUpCal._getInst(this._calId); + if (popUpCal._popUpShowing) { + switch (e.keyCode) { + case 9: popUpCal.hideCalendar(inst, ''); + break; // hide on tab out + case 13: popUpCal._selectDate(inst); + break; // select the value on enter + case 27: popUpCal.hideCalendar(inst, inst._get('speed')); + break; // hide on escape + case 33: popUpCal._adjustDate(inst, -1, (e.ctrlKey ? 'Y' : 'M')); + break; // previous month/year on page up/+ ctrl + case 34: popUpCal._adjustDate(inst, +1, (e.ctrlKey ? 'Y' : 'M')); + break; // next month/year on page down/+ ctrl + case 35: if (e.ctrlKey) popUpCal._clearDate(inst); + break; // clear on ctrl+end + case 36: if (e.ctrlKey) popUpCal._gotoToday(inst); + break; // current on ctrl+home + case 37: if (e.ctrlKey) popUpCal._adjustDate(inst, -1, 'D'); + break; // -1 day on ctrl+left + case 38: if (e.ctrlKey) popUpCal._adjustDate(inst, -7, 'D'); + break; // -1 week on ctrl+up + case 39: if (e.ctrlKey) popUpCal._adjustDate(inst, +1, 'D'); + break; // +1 day on ctrl+right + case 40: if (e.ctrlKey) popUpCal._adjustDate(inst, +7, 'D'); + break; // +1 week on ctrl+down + } + } + else if (e.keyCode == 36 && e.ctrlKey) { // display the calendar on ctrl+home + popUpCal.showFor(this); + } + }, + + /* Filter entered characters. */ + _doKeyPress: function(e) { + var inst = popUpCal._getInst(this._calId); + var chr = String.fromCharCode(e.charCode == undefined ? e.keyCode : e.charCode); + return (chr < ' ' || chr == inst._get('dateFormat').charAt(3) || + (chr >= '0' && chr <= '9')); // only allow numbers and separator + }, + + /* Attach the calendar to an input field. */ + _connectCalendar: function(target, inst) { + var $input = $(target); + var appendText = inst._get('appendText'); + if (appendText) { + $input.after('' + appendText + ''); + } + var autoPopUp = inst._get('autoPopUp'); + if (autoPopUp == 'focus' || autoPopUp == 'both') { // pop-up calendar when in the marked field + $input.focus(this.showFor); + } + if (autoPopUp == 'button' || autoPopUp == 'both') { // pop-up calendar when button clicked + var buttonText = inst._get('buttonText'); + var buttonImage = inst._get('buttonImage'); + var buttonImageOnly = inst._get('buttonImageOnly'); + var trigger = $(buttonImageOnly ? '' + buttonText + '' : + ''); + $input.wrap('').after(trigger); + trigger.click(this.showFor); + } + $input.keydown(this._doKeyDown).keypress(this._doKeyPress); + $input[0]._calId = inst._id; + }, + + /* Attach an inline calendar to a div. */ + _inlineCalendar: function(target, inst) { + $(target).append(inst._calendarDiv); + target._calId = inst._id; + var date = new Date(); + inst._selectedDay = date.getDate(); + inst._selectedMonth = date.getMonth(); + inst._selectedYear = date.getFullYear(); + popUpCal._adjustDate(inst); + }, + + /* Pop-up the calendar in a "dialog" box. + @param dateText string - the initial date to display (in the current format) + @param onSelect function - the function(dateText) to call when a date is selected + @param settings object - update the dialog calendar instance's settings (anonymous object) + @param pos int[2] - coordinates for the dialog's position within the screen + leave empty for default (screen centre) + @return void */ + dialogCalendar: function(dateText, onSelect, settings, pos) { + var inst = this._dialogInst; // internal instance + if (!inst) { + inst = this._dialogInst = new PopUpCalInstance({}, false); + this._dialogInput = $(''); + this._dialogInput.keydown(this._doKeyDown); + $('body').append(this._dialogInput); + this._dialogInput[0]._calId = inst._id; + } + $.extend(inst._settings, settings || {}); + this._dialogInput.val(dateText); + + /* Cross Browser Positioning */ + if (self.innerHeight) { // all except Explorer + windowWidth = self.innerWidth; + windowHeight = self.innerHeight; + } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode + windowWidth = document.documentElement.clientWidth; + windowHeight = document.documentElement.clientHeight; + } else if (document.body) { // other Explorers + windowWidth = document.body.clientWidth; + windowHeight = document.body.clientHeight; + } + this._pos = pos || // should use actual width/height below + [(windowWidth / 2) - 100, (windowHeight / 2) - 100]; + + // move input on screen for focus, but hidden behind dialog + this._dialogInput.css('left', this._pos[0] + 'px').css('top', this._pos[1] + 'px'); + inst._settings.onSelect = onSelect; + this._inDialog = true; + this._calendarDiv.addClass('calendar_dialog'); + this.showFor(this._dialogInput[0]); + if ($.blockUI) { + $.blockUI(this._calendarDiv); + } + }, + + /* Enable the input field(s) for entry. + @param inputs element/object - single input field or jQuery collection of input fields + @return void */ + enableFor: function(inputs) { + inputs = (inputs.jquery ? inputs : $(inputs)); + inputs.each(function() { + this.disabled = false; + $('../button.calendar_trigger', this).each(function() { this.disabled = false; }); + $('../img.calendar_trigger', +this).css({opacity:'1.0',cursor:''}); + var $this = this; + popUpCal._disabledInputs = $.map(popUpCal._disabledInputs, + function(value) { return (value == $this ? null : value); }); // delete entry + }); + }, + + /* Disable the input field(s) from entry. + @param inputs element/object - single input field or jQuery collection of input fields + @return void */ + disableFor: function(inputs) { + inputs = (inputs.jquery ? inputs : $(inputs)); + inputs.each(function() { + this.disabled = true; + $('../button.calendar_trigger', this).each(function() { this.disabled = true; }); + $('../img.calendar_trigger', this).css({opacity:'0.5',cursor:'default'}); + var $this = this; + popUpCal._disabledInputs = $.map(popUpCal._disabledInputs, + function(value) { return (value == $this ? null : value); }); // delete entry + popUpCal._disabledInputs[popUpCal._disabledInputs.length] = this; + }); + }, + + /* Update the settings for a calendar attached to an input field or division. + @param control element - the input field or div/span attached to the calendar + @param settings object - the new settings to update + @return void */ + reconfigureFor: function(control, settings) { + var inst = this._getInst(control._calId); + if (inst) { + $.extend(inst._settings, settings || {}); + this._updateCalendar(inst); + } + }, + + /* Set the date for a calendar attached to an input field or division. + @param control element - the input field or div/span attached to the calendar + @param date Date - the new date + @return void */ + setDateFor: function(control, date) { + var inst = this._getInst(control._calId); + if (inst) { + inst._setDate(date); + } + }, + + /* Retrieve the date for a calendar attached to an input field or division. + @param control element - the input field or div/span attached to the calendar + @return Date - the current date */ + getDateFor: function(control) { + var inst = this._getInst(control._calId); + return (inst ? inst._getDate() : null); + }, + + /* Pop-up the calendar for a given input field. + @param target element - the input field attached to the calendar + @return void */ + showFor: function(target) { + var input = (target.nodeName && target.nodeName.toLowerCase() == 'input' ? target : this); + if (input.nodeName.toLowerCase() != 'input') { // find from button/image trigger + input = $('input', input.parentNode)[0]; + } + if (popUpCal._lastInput == input) { // already here + return; + } + for (var i = 0; i < popUpCal._disabledInputs.length; i++) { // check not disabled + if (popUpCal._disabledInputs[i] == input) { + return; + } + } + var inst = popUpCal._getInst(input._calId); + popUpCal.hideCalendar(inst, ''); + popUpCal._lastInput = input; + inst._setDateFromField(input); + if (popUpCal._inDialog) { // hide cursor + input.value = ''; + } + if (!popUpCal._pos) { // position below input + popUpCal._pos = popUpCal._findPos(input); + popUpCal._pos[1] += input.offsetHeight; + } + inst._calendarDiv.css('position', (popUpCal._inDialog && $.blockUI ? 'static' : 'absolute')). + css('left', popUpCal._pos[0] + 'px').css('top', popUpCal._pos[1] + 'px'); + popUpCal._pos = null; + var fieldSettings = inst._get('fieldSettings'); + $.extend(inst._settings, (fieldSettings ? fieldSettings(input) : {})); + popUpCal._showCalendar(inst); + }, + + /* Construct and display the calendar. */ + _showCalendar: function(id) { + var inst = this._getInst(id); + popUpCal._updateCalendar(inst); + if (!inst._inline) { + var speed = inst._get('speed'); + inst._calendarDiv.show(speed, function() { + popUpCal._popUpShowing = true; + popUpCal._afterShow(inst); + }); + if (speed == '') { + popUpCal._popUpShowing = true; + popUpCal._afterShow(inst); + } + if (inst._input[0].type != 'hidden') { + inst._input[0].focus(); + } + this._curInst = inst; + } + }, + + /* Generate the calendar content. */ + _updateCalendar: function(inst) { + inst._calendarDiv.empty().append(inst._generateCalendar()); + if (inst._input && inst._input != 'hidden') { + inst._input[0].focus(); + } + }, + + /* Tidy up after displaying the calendar. */ + _afterShow: function(inst) { + if ($.browser.msie) { // fix IE < 7 select problems + $('#calendar_cover').css({width: inst._calendarDiv[0].offsetWidth + 4, + height: inst._calendarDiv[0].offsetHeight + 4}); + } + /*// re-position on screen if necessary + var calDiv = inst._calendarDiv[0]; + var pos = popUpCal._findPos(inst._input[0]); + if ((calDiv.offsetLeft + calDiv.offsetWidth) > + (document.body.clientWidth + document.body.scrollLeft)) { + inst._calendarDiv.css('left', (pos[0] + inst._input[0].offsetWidth - calDiv.offsetWidth) + 'px'); + } + if ((calDiv.offsetTop + calDiv.offsetHeight) > + (document.body.clientHeight + document.body.scrollTop)) { + inst._calendarDiv.css('top', (pos[1] - calDiv.offsetHeight) + 'px'); + }*/ + }, + + /* Hide the calendar from view. + @param id string/object - the ID of the current calendar instance, + or the instance itself + @param speed string - the speed at which to close the calendar + @return void */ + hideCalendar: function(id, speed) { + var inst = this._getInst(id); + if (popUpCal._popUpShowing) { + speed = (speed != null ? speed : inst._get('speed')); + inst._calendarDiv.hide(speed, function() { + popUpCal._tidyDialog(inst); + }); + if (speed == '') { + popUpCal._tidyDialog(inst); + } + popUpCal._popUpShowing = false; + popUpCal._lastInput = null; + inst._settings.prompt = null; + if (popUpCal._inDialog) { + popUpCal._dialogInput.css('position', 'absolute'). + css('left', '0px').css('top', '-100px'); + if ($.blockUI) { + $.unblockUI(); + $('body').append(this._calendarDiv); + } + } + popUpCal._inDialog = false; + } + popUpCal._curInst = null; + }, + + /* Tidy up after a dialog display. */ + _tidyDialog: function(inst) { + inst._calendarDiv.removeClass('calendar_dialog'); + $('.calendar_prompt', inst._calendarDiv).remove(); + }, + + /* Close calendar if clicked elsewhere. */ + _checkExternalClick: function(event) { + if (!popUpCal._curInst) { + return; + } + var target = $(event.target); + if( (target.parents("#calendar_div").length == 0) + && (target.attr('class') != 'calendar_trigger') + && popUpCal._popUpShowing + && !(popUpCal._inDialog && $.blockUI) ) + { + popUpCal.hideCalendar(popUpCal._curInst, ''); + } + }, + + /* Adjust one of the date sub-fields. */ + _adjustDate: function(id, offset, period) { + var inst = this._getInst(id); + inst._adjustDate(offset, period); + this._updateCalendar(inst); + }, + + /* Action for current link. */ + _gotoToday: function(id) { + var date = new Date(); + var inst = this._getInst(id); + inst._selectedDay = date.getDate(); + inst._selectedMonth = date.getMonth(); + inst._selectedYear = date.getFullYear(); + this._adjustDate(inst); + }, + + /* Action for selecting a new month/year. */ + _selectMonthYear: function(id, select, period) { + var inst = this._getInst(id); + inst._selectingMonthYear = false; + inst[period == 'M' ? '_selectedMonth' : '_selectedYear'] = + select.options[select.selectedIndex].value - 0; + this._adjustDate(inst); + }, + + /* Restore input focus after not changing month/year. */ + _clickMonthYear: function(id) { + var inst = this._getInst(id); + if (inst._input && inst._selectingMonthYear && !$.browser.msie) { + inst._input[0].focus(); + } + inst._selectingMonthYear = !inst._selectingMonthYear; + }, + + /* Action for changing the first week day. */ + _changeFirstDay: function(id, a) { + var inst = this._getInst(id); + var dayNames = inst._get('dayNames'); + var value = a.firstChild.nodeValue; + for (var i = 0; i < 7; i++) { + if (dayNames[i] == value) { + inst._settings.firstDay = i; + break; + } + } + this._updateCalendar(inst); + }, + + /* Action for selecting a day. */ + _selectDay: function(id, td) { + var inst = this._getInst(id); + inst._selectedDay = $("a", td).html(); + this._selectDate(id); + }, + + /* Erase the input field and hide the calendar. */ + _clearDate: function(id) { + this._selectDate(id, ''); + }, + + /* Update the input field with the selected date. */ + _selectDate: function(id, dateStr) { + var inst = this._getInst(id); + dateStr = (dateStr != null ? dateStr : inst._formatDate()); + if (inst._input) { + inst._input.val(dateStr); + } + var onSelect = inst._get('onSelect'); + if (onSelect) { + onSelect(dateStr); // trigger custom callback + } + else { + inst._input.trigger('change'); // fire the change event + } + if (inst._inline) { + this._updateCalendar(inst); + } + else { + this.hideCalendar(inst, inst._get('speed')); + } + }, + + /* Set as customDate function to prevent selection of weekends. + @param date Date - the date to customise + @return [boolean, string] - is this date selectable?, what is its CSS class? */ + noWeekends: function(date) { + var day = date.getDay(); + return [(day > 0 && day < 6), '']; + }, + + /* Find an object's position on the screen. */ + _findPos: function(obj) { + if (obj.type == 'hidden') { + obj = obj.nextSibling; + } + var curleft = curtop = 0; + if (obj.offsetParent) { + curleft = obj.offsetLeft; + curtop = obj.offsetTop; + while (obj = obj.offsetParent) { + var origcurleft = curleft; + curleft += obj.offsetLeft; + if (curleft < 0) { + curleft = origcurleft; + } + curtop += obj.offsetTop; + } + } + return [curleft,curtop]; + } +}); + +/* Individualised settings for calendars applied to one or more related inputs. + Instances are managed and manipulated through the PopUpCal manager. */ +function PopUpCalInstance(settings, inline) { + this._id = popUpCal._register(this); + this._selectedDay = 0; + this._selectedMonth = 0; // 0-11 + this._selectedYear = 0; // 4-digit year + this._input = null; // The attached input field + this._inline = inline; // True if showing inline, false if used in a popup + this._calendarDiv = (!inline ? popUpCal._calendarDiv : + $('
')); + if (inline) { + var date = new Date(); + this._currentDay = date.getDate(); + this._currentMonth = date.getMonth(); + this._currentYear = date.getFullYear(); + } + // customise the calendar object - uses manager defaults if not overridden + this._settings = $.extend({}, settings || {}); // clone +} + +$.extend(PopUpCalInstance.prototype, { + /* Get a setting value, defaulting if necessary. */ + _get: function(name) { + return (this._settings[name] != null ? this._settings[name] : popUpCal._defaults[name]); + }, + + /* Parse existing date and initialise calendar. */ + _setDateFromField: function(input) { + this._input = $(input); + var dateFormat = this._get('dateFormat'); + var currentDate = this._input.val().split(dateFormat.charAt(3)); + if (currentDate.length == 3) { + this._currentDay = parseInt(currentDate[dateFormat.indexOf('D')], 10); + this._currentMonth = parseInt(currentDate[dateFormat.indexOf('M')], 10) - 1; + this._currentYear = parseInt(currentDate[dateFormat.indexOf('Y')], 10); + } + else { + var date = new Date(); + this._currentDay = date.getDate(); + this._currentMonth = date.getMonth(); + this._currentYear = date.getFullYear(); + } + this._selectedDay = this._currentDay; + this._selectedMonth = this._currentMonth; + this._selectedYear = this._currentYear; + this._adjustDate(); + }, + + /* Set the date directly. */ + _setDate: function(date) { + this._selectedDay = this._currentDay = date.getDate(); + this._selectedMonth = this._currentMonth = date.getMonth(); + this._selectedYear = this._currentYear = date.getFullYear(); + this._adjustDate(); + }, + + /* Retrieve the date directly. */ + _getDate: function() { + return new Date(this._currentYear, this._currentMonth, this._currentDay); + }, + + /* Generate the HTML for the current state of the calendar. */ + _generateCalendar: function() { + var today = new Date(); + today = new Date(today.getFullYear(), today.getMonth(), today.getDate()); // clear time + // build the calendar HTML + var controls = '
' + + '' + + this._get('clearText') + '' + + '' + + this._get('closeText') + '
'; + var prompt = this._get('prompt'); + var closeAtTop = this._get('closeAtTop'); + var hideIfNoPrevNext = this._get('hideIfNoPrevNext'); + // controls and links + var html = (prompt ? '
' + prompt + '
' : '') + + (closeAtTop && !this._inline ? controls : '') + '
'; + var minDate = this._get('minDate'); + var maxDate = this._get('maxDate'); + // month selection + var monthNames = this._get('monthNames'); + if (!this._get('changeMonth')) { + html += monthNames[this._selectedMonth] + ' '; + } + else { + var inMinYear = (minDate && minDate.getFullYear() == this._selectedYear); + var inMaxYear = (maxDate && maxDate.getFullYear() == this._selectedYear); + html += ''; + } + // year selection + if (!this._get('changeYear')) { + html += this._selectedYear; + } + else { + // determine range of years to display + var years = this._get('yearRange').split(':'); + var year = 0; + var endYear = 0; + if (years.length != 2) { + year = this._selectedYear - 10; + endYear = this._selectedYear + 10; + } + else if (years[0].charAt(0) == '+' || years[0].charAt(0) == '-') { + year = this._selectedYear + parseInt(years[0], 10); + endYear = this._selectedYear + parseInt(years[1], 10); + } + else { + year = parseInt(years[0], 10); + endYear = parseInt(years[1], 10); + } + year = (minDate ? Math.max(year, minDate.getFullYear()) : year); + endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); + html += ''; + } + html += '
' + + ''; + var firstDay = this._get('firstDay'); + var changeFirstDay = this._get('changeFirstDay'); + var dayNames = this._get('dayNames'); + for (var dow = 0; dow < 7; dow++) { // days of the week + html += ''; + } + html += ''; + var daysInMonth = this._getDaysInMonth(this._selectedYear, this._selectedMonth); + this._selectedDay = Math.min(this._selectedDay, daysInMonth); + var leadDays = (this._getFirstDayOfMonth(this._selectedYear, this._selectedMonth) - firstDay + 7) % 7; + var currentDate = new Date(this._currentYear, this._currentMonth, this._currentDay); + var selectedDate = new Date(this._selectedYear, this._selectedMonth, this._selectedDay); + var printDate = new Date(this._selectedYear, this._selectedMonth, 1 - leadDays); + var numRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate + var customDate = this._get('customDate'); + var showOtherMonths = this._get('showOtherMonths'); + for (var row = 0; row < numRows; row++) { // create calendar rows + html += ''; + for (var dow = 0; dow < 7; dow++) { // create calendar days + var customSettings = (customDate ? customDate(printDate) : [true, '']); + var otherMonth = (printDate.getMonth() != this._selectedMonth); + var unselectable = otherMonth || !customSettings[0] || + (minDate && printDate < minDate) || (maxDate && printDate > maxDate); + html += ''; // display for this month + printDate.setDate(printDate.getDate() + 1); + } + html += ''; + } + html += '
' + (!changeFirstDay ? '' : '') + dayNames[(dow + firstDay) % 7] + + (changeFirstDay ? '' : '') + '
' + // actions + (otherMonth ? (showOtherMonths ? printDate.getDate() : ' ') : // display for other months + (unselectable ? printDate.getDate() : '' + printDate.getDate() + '')) + '
' + (!closeAtTop && !this._inline ? controls : '') + + '
' + (!$.browser.msie ? '' : + ''); + return html; + }, + + /* Adjust one of the date sub-fields. */ + _adjustDate: function(offset, period) { + var date = new Date(this._selectedYear + (period == 'Y' ? offset : 0), + this._selectedMonth + (period == 'M' ? offset : 0), + this._selectedDay + (period == 'D' ? offset : 0)); + // ensure it is within the bounds set + var minDate = this._get('minDate'); + var maxDate = this._get('maxDate'); + date = (minDate && date < minDate ? minDate : date); + date = (maxDate && date > maxDate ? maxDate : date); + this._selectedDay = date.getDate(); + this._selectedMonth = date.getMonth(); + this._selectedYear = date.getFullYear(); + }, + + /* Find the number of days in a given month. */ + _getDaysInMonth: function(year, month) { + return 32 - new Date(year, month, 32).getDate(); + }, + + /* Find the day of the week of the first of a month. */ + _getFirstDayOfMonth: function(year, month) { + return new Date(year, month, 1).getDay(); + }, + + /* Determines if we should allow a "next/prev" month display change. */ + _canAdjustMonth: function(offset) { + var date = new Date(this._selectedYear, this._selectedMonth + offset, 1); + if (offset < 0) { + date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); + } + return this._isInRange(date); + }, + + /* Is the given date in the accepted range? */ + _isInRange: function(date) { + var minDate = this._get('minDate'); + var maxDate = this._get('maxDate'); + return ((!minDate || date >= minDate) && (!maxDate || date <= maxDate)); + }, + + /* Format the given date for display. */ + _formatDate: function() { + var day = this._currentDay = this._selectedDay; + var month = this._currentMonth = this._selectedMonth; + var year = this._currentYear = this._selectedYear; + month++; // adjust javascript month + var dateFormat = this._get('dateFormat'); + var dateString = ''; + for (var i = 0; i < 3; i++) { + dateString += dateFormat.charAt(3) + + (dateFormat.charAt(i) == 'D' ? (day < 10 ? '0' : '') + day : + (dateFormat.charAt(i) == 'M' ? (month < 10 ? '0' : '') + month : + (dateFormat.charAt(i) == 'Y' ? year : '?'))); + } + return dateString.substring(dateFormat.charAt(3) ? 1 : 0); + } +}); + +/* Attach the calendar to a jQuery selection. + @param settings object - the new settings to use for this calendar instance (anonymous) + @return jQuery object - for chaining further calls */ +$.fn.calendar = function(settings) { + return this.each(function() { + // check for settings on the control itself - in namespace 'cal:' + var inlineSettings = null; + for (attrName in popUpCal._defaults) { + var attrValue = this.getAttribute('cal:' + attrName); + if (attrValue) { + inlineSettings = inlineSettings || {}; + try { + inlineSettings[attrName] = eval(attrValue); + } + catch (err) { + inlineSettings[attrName] = attrValue; + } + } + } + var nodeName = this.nodeName.toLowerCase(); + if (nodeName == 'input') { + var instSettings = (inlineSettings ? $.extend($.extend({}, settings || {}), + inlineSettings || {}) : settings); // clone and customise + var inst = (inst && !inlineSettings ? inst : + new PopUpCalInstance(instSettings, false)); + popUpCal._connectCalendar(this, inst); + } + else if (nodeName == 'div' || nodeName == 'span') { + var instSettings = $.extend($.extend({}, settings || {}), + inlineSettings || {}); // clone and customise + var inst = new PopUpCalInstance(instSettings, true); + popUpCal._inlineCalendar(this, inst); + } + }); +}; + +/* Initialise the calendar. */ +$(document).ready(function() { + popUpCal = new PopUpCal(); // singleton instance +}); + diff --git a/library/js/jquery.js b/library/js/jquery.js new file mode 100644 index 000000000..b43f2b8d1 --- /dev/null +++ b/library/js/jquery.js @@ -0,0 +1,31 @@ +/* + * jQuery 1.2.1 - New Wave Javascript + * + * Copyright (c) 2007 John Resig (jquery.com) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * $Date$ + * $Rev: 3353 $ + */ +(function(){if(typeof jQuery!="undefined")var _jQuery=jQuery;var jQuery=window.jQuery=function(selector,context){return this instanceof jQuery?this.init(selector,context):new jQuery(selector,context);};if(typeof $!="undefined")var _$=$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(typeof selector=="string"){var m=quickExpr.exec(selector);if(m&&(m[1]||!context)){if(m[1])selector=jQuery.clean([m[1]],context);else{var tmp=document.getElementById(m[3]);if(tmp)if(tmp.id!=m[3])return jQuery().find(selector);else{this[0]=tmp;this.length=1;return this;}else +selector=[];}}else +return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.1",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(a){var ret=jQuery(a);ret.prevObject=this;return ret;},setArray:function(a){this.length=0;Array.prototype.push.apply(this,a);return this;},each:function(fn,args){return jQuery.each(this,fn,args);},index:function(obj){var pos=-1;this.each(function(i){if(this==obj)pos=i;});return pos;},attr:function(key,value,type){var obj=key;if(key.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],key)||undefined;else{obj={};obj[key]=value;}return this.each(function(index){for(var prop in obj)jQuery.attr(type?this.style:this,prop,jQuery.prop(this,obj[prop],type,index,prop));});},css:function(key,value){return this.attr(key,value,"curCSS");},text:function(e){if(typeof e!="object"&&e!=null)return this.empty().append(document.createTextNode(e));var t="";jQuery.each(e||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)t+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return t;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,1,function(a){this.appendChild(a);});},prepend:function(){return this.domManip(arguments,true,-1,function(a){this.insertBefore(a,this.firstChild);});},before:function(){return this.domManip(arguments,false,1,function(a){this.parentNode.insertBefore(a,this);});},after:function(){return this.domManip(arguments,false,-1,function(a){this.parentNode.insertBefore(a,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(t){var data=jQuery.map(this,function(a){return jQuery.find(t,a);});return this.pushStack(/[^+>] [^+>]/.test(t)||t.indexOf("..")>-1?jQuery.unique(data):data);},clone:function(events){var ret=this.map(function(){return this.outerHTML?jQuery(this.outerHTML)[0]:this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(t){return this.pushStack(jQuery.isFunction(t)&&jQuery.grep(this,function(el,index){return t.apply(el,[index]);})||jQuery.multiFilter(t,this));},not:function(t){return this.pushStack(t.constructor==String&&jQuery.multiFilter(t,this,true)||jQuery.grep(this,function(a){return(t.constructor==Array||t.jquery)?jQuery.inArray(a,t)<0:a!=t;}));},add:function(t){return this.pushStack(jQuery.merge(this.get(),t.constructor==String?jQuery(t).get():t.length!=undefined&&(!t.nodeName||jQuery.nodeName(t,"form"))?t:[t]));},is:function(expr){return expr?jQuery.multiFilter(expr,this).length>0:false;},hasClass:function(expr){return this.is("."+expr);},val:function(val){if(val==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,a=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,val)>=0);else if(jQuery.nodeName(this,"select")){var tmp=val.constructor==Array?val:[val];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,tmp)>=0||jQuery.inArray(this.text,tmp)>=0);});if(!tmp.length)this.selectedIndex=-1;}else +this.value=val;});},html:function(val){return val==undefined?(this.length?this[0].innerHTML:null):this.empty().append(val);},replaceWith:function(val){return this.after(val).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(fn){return this.pushStack(jQuery.map(this,function(elem,i){return fn.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},domManip:function(args,table,dir,fn){var clone=this.length>1,a;return this.each(function(){if(!a){a=jQuery.clean(args,this.ownerDocument);if(dir<0)a.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(a[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(document.createElement("tbody"));jQuery.each(a,function(){var elem=clone?this.cloneNode(true):this;if(!evalScript(0,elem))fn.call(obj,elem);});});}};function evalScript(i,elem){var script=jQuery.nodeName(elem,"script");if(script){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else +jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}else if(elem.nodeType==1)jQuery("script",elem).each(evalScript);return script;}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},a=1,al=arguments.length,deep=false;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};}if(al==1){target=this;a=0;}var prop;for(;a-1;}},swap:function(e,o,f){for(var i in o){e.style["old"+i]=e.style[i];e.style[i]=o[i];}f.apply(e,[]);for(var i in o)e.style[i]=e.style["old"+i];},css:function(e,p){if(p=="height"||p=="width"){var old={},oHeight,oWidth,d=["Top","Bottom","Right","Left"];jQuery.each(d,function(){old["padding"+this]=0;old["border"+this+"Width"]=0;});jQuery.swap(e,old,function(){if(jQuery(e).is(':visible')){oHeight=e.offsetHeight;oWidth=e.offsetWidth;}else{e=jQuery(e.cloneNode(true)).find(":radio").removeAttr("checked").end().css({visibility:"hidden",position:"absolute",display:"block",right:"0",left:"0"}).appendTo(e.parentNode)[0];var parPos=jQuery.css(e.parentNode,"position")||"static";if(parPos=="static")e.parentNode.style.position="relative";oHeight=e.clientHeight;oWidth=e.clientWidth;if(parPos=="static")e.parentNode.style.position="static";e.parentNode.removeChild(e);}});return p=="height"?oHeight:oWidth;}return jQuery.curCSS(e,p);},curCSS:function(elem,prop,force){var ret,stack=[],swap=[];function color(a){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(a,null);return!ret||ret.getPropertyValue("color")=="";}if(prop=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(prop.match(/float/i))prop=styleFloat;if(!force&&elem.style[prop])ret=elem.style[prop];else if(document.defaultView&&document.defaultView.getComputedStyle){if(prop.match(/float/i))prop="float";prop=prop.replace(/([A-Z])/g,"-$1").toLowerCase();var cur=document.defaultView.getComputedStyle(elem,null);if(cur&&!color(elem))ret=cur.getPropertyValue(prop);else{for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(a=0;a]*?)\/>/g,function(m,all,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area)$/i)?m:all+">";});var s=jQuery.trim(arg).toLowerCase(),div=doc.createElement("div"),tb=[];var wrap=!s.indexOf("",""]||!s.indexOf("",""]||s.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!s.indexOf("",""]||(!s.indexOf("",""]||!s.indexOf("",""]||jQuery.browser.msie&&[1,"div
","
"]||[0,"",""];div.innerHTML=wrap[1]+arg+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){if(!s.indexOf(""&&s.indexOf("=0;--n)if(jQuery.nodeName(tb[n],"tbody")&&!tb[n].childNodes.length)tb[n].parentNode.removeChild(tb[n]);if(/^\s/.test(arg))div.insertBefore(doc.createTextNode(arg.match(/^\s*/)[0]),div.firstChild);}arg=jQuery.makeArray(div.childNodes);}if(0===arg.length&&(!jQuery.nodeName(arg,"form")&&!jQuery.nodeName(arg,"select")))return;if(arg[0]==undefined||jQuery.nodeName(arg,"form")||arg.options)r.push(arg);else +r=jQuery.merge(r,arg);});return r;},attr:function(elem,name,value){var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(z,b){return b.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(t){return(t||"").replace(/^\s+|\s+$/g,"");},makeArray:function(a){var r=[];if(typeof a!="array")for(var i=0,al=a.length;i\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":"m[2]=='*'||jQuery.nodeName(a,m[2])","#":"a.getAttribute('id')==m[2]",":":{lt:"im[3]-0",nth:"m[3]-0==i",eq:"m[3]-0==i",first:"i==0",last:"i==r.length-1",even:"i%2==0",odd:"i%2","first-child":"a.parentNode.getElementsByTagName('*')[0]==a","last-child":"jQuery.nth(a.parentNode.lastChild,1,'previousSibling')==a","only-child":"!jQuery.nth(a.parentNode.lastChild,2,'previousSibling')",parent:"a.firstChild",empty:"!a.firstChild",contains:"(a.textContent||a.innerText||jQuery(a).text()||'').indexOf(m[3])>=0",visible:'"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden"',hidden:'"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden"',enabled:"!a.disabled",disabled:"a.disabled",checked:"a.checked",selected:"a.selected||jQuery.attr(a,'selected')",text:"'text'==a.type",radio:"'radio'==a.type",checkbox:"'checkbox'==a.type",file:"'file'==a.type",password:"'password'==a.type",submit:"'submit'==a.type",image:"'image'==a.type",reset:"'reset'==a.type",button:'"button"==a.type||jQuery.nodeName(a,"button")',input:"/input|select|textarea|button/i.test(a.nodeName)",has:"jQuery.find(m[3],a).length",header:"/h\\d/i.test(a.nodeName)",animated:"jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length"}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&!context.nodeType)context=null;context=context||document;var ret=[context],done=[],last;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){var nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName.toUpperCase()))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var nodeName=m[2],merge={};m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=jQuery.filter(m[3],r,true).r;else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(\d*)n\+?(\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"n+"+m[3]||m[3]),first=(test[1]||1)-0,last=test[2]-0;for(var i=0,rl=r.length;i<\/script>");var script=document.getElementById("__ie_init");if(script)script.onreadystatechange=function(){if(this.readyState!="complete")return;jQuery.ready();};script=null;}else if(jQuery.browser.safari)jQuery.safariTimer=setInterval(function(){if(document.readyState=="loaded"||document.readyState=="complete"){clearInterval(jQuery.safariTimer);jQuery.safariTimer=null;jQuery.ready();}},10);jQuery.event.add(window,"load",jQuery.ready);}jQuery.fn.extend({load:function(url,params,callback){if(jQuery.isFunction(url))return this.bind("load",url);var off=url.indexOf(" ");if(off>=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
").append(res.responseText.replace(//g,"")).find(selector):res.responseText);setTimeout(function(){self.each(callback,[res.responseText,status,res]);},13);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=(new Date).getTime();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null},lastModified:{},ajax:function(s){var jsonp,jsre=/=(\?|%3F)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=s.data.replace(jsre,"="+jsonp);s.url=s.url.replace(jsre,"="+jsonp);s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get")s.url+=(s.url.match(/\?/)?"&":"?")+"_="+(new Date()).getTime();if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if(!s.url.indexOf("http")&&s.dataType=="script"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(!jsonp&&(s.success||s.complete)){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async);if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else +jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();return xml;function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else +for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else +s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock?this.oldblock:"";if(jQuery.css(this,"display")=="none")this.style.display="block";}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");if(this.oldblock=="none")this.oldblock="block";this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var opt=jQuery.speed(speed,easing,callback);return this[opt.queue===false?"each":"queue"](function(){opt=jQuery.extend({},opt);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else +e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(){var timers=jQuery.timers;return this.each(function(){for(var i=0;i-10000?r:parseFloat(jQuery.css(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(){return self.step();}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timers.length==1){var timer=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var absolute=jQuery.css(elem,"position")=="absolute",parent=elem.parentNode,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522;if(elem.getBoundingClientRect){box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));if(msie){var border=jQuery("html").css("borderWidth");border=(border=="medium"||jQuery.boxModel&&parseInt(version)>=7)&&2||border;add(-border,-border);}}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&/^t[d|h]$/i.test(parent.tagName)||!safari2)border(offsetParent);if(safari2&&!absolute&&jQuery.css(offsetParent,"position")=="absolute")absolute=true;offsetParent=offsetParent.offsetParent;}while(parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table-row.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if(safari2&&absolute)add(-doc.body.offsetLeft,-doc.body.offsetTop);}results={top:top,left:left};}return results;function border(elem){add(jQuery.css(elem,"borderLeftWidth"),jQuery.css(elem,"borderTopWidth"));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}};})(); \ No newline at end of file diff --git a/library/translation.inc.php b/library/translation.inc.php index 24c5b13e0..4f8cfe539 100644 --- a/library/translation.inc.php +++ b/library/translation.inc.php @@ -22,6 +22,8 @@ function xl($constant,$mode='r',$prepend='',$append='') { } } + +// ---------------------------------------------------------------------------- /** HEADER HTML @@ -34,4 +36,58 @@ function html_header_show() { echo ' '."\n"; } + +// ---------------------------------------------------------------------------- +/** +* Returns a string padded to a certain length with another string. +* +* This method behaves exactly like str_pad but is multibyte safe. +* +* @param string $input The string to be padded. +* @param int $length The length of the resulting string. +* @param string $pad The string to pad the input string with. Must +* be in the same charset like the input string. +* @param const $type The padding type. One of STR_PAD_LEFT, +* STR_PAD_RIGHT, or STR_PAD_BOTH. +* @param string $charset The charset of the input and the padding +* strings. +* +* @return string The padded string. +*/ +function mb_strpad($input, $length, $pad = ' ', $type = STR_PAD_RIGHT, $charset = 'UTF-8') { + mb_internal_encoding($charset); + $mb_length = mb_strlen($input, $charset); + $sb_length = strlen($input); + $pad_length = mb_strlen($pad, $charset); + + /* Return if we already have the length. */ + if ($mb_length >= $length) { + return $input; + } + + /* Shortcut for single byte strings. */ + if ($mb_length == $sb_length && $pad_length == strlen($pad)) { + return str_pad($input, $length, $pad, $type); + } + + switch ($type) { + case STR_PAD_LEFT: + $left = $length - $mb_length; + $output = mb_substr(str_repeat($pad, ceil($left / $pad_length)), 0, $left, $charset) . $input; + break; + case STR_PAD_BOTH: + $left = floor(($length - $mb_length) / 2); + $right = ceil(($length - $mb_length) / 2); + $output = mb_substr(str_repeat($pad, ceil($left / $pad_length)), 0, $left, $charset) . + $input . + mb_substr(str_repeat($pad, ceil($right / $pad_length)), 0, $right, $charset); + break; + case STR_PAD_RIGHT: + $right = $length - $mb_length; + $output = $input . mb_substr(str_repeat($pad, ceil($right / $pad_length)), 0, $right, $charset); + break; + } + +return $output; +} ?> -- 2.11.4.GIT