Support for the CMS Patient Portal.
[openemr.git] / interface / patient_file / report / custom_report.php
blobd058c585d5d26e46cdcf7144d6d34808f13003e6
1 <?php
2 use ESign\Api;
3 /**
5 * Patient custom report.
7 * LICENSE: This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
18 * @package OpenEMR
19 * @author Brady Miller <brady@sparmy.com>
20 * @author Ken Chapple <ken@mi-squared.com>
21 * @author Tony McCormick <tony@mi-squared.com>
22 * @link http://www.open-emr.org
25 require_once("../../globals.php");
26 require_once("$srcdir/forms.inc");
27 require_once("$srcdir/billing.inc");
28 require_once("$srcdir/pnotes.inc");
29 require_once("$srcdir/patient.inc");
30 require_once("$srcdir/options.inc.php");
31 require_once("$srcdir/acl.inc");
32 require_once("$srcdir/lists.inc");
33 require_once("$srcdir/report.inc");
34 require_once("$srcdir/classes/Document.class.php");
35 require_once("$srcdir/classes/Note.class.php");
36 require_once("$srcdir/formatting.inc.php");
37 require_once("$srcdir/htmlspecialchars.inc.php");
38 require_once("$srcdir/formdata.inc.php");
39 require_once(dirname(__file__) . "/../../../custom/code_types.inc.php");
40 require_once $GLOBALS['srcdir'].'/ESign/Api.php';
41 if ($GLOBALS['gbl_portal_cms_enable']) {
42 require_once($GLOBALS["include_root"] . "/cmsportal/portal.inc.php");
45 // For those who care that this is the patient report.
46 $GLOBALS['PATIENT_REPORT_ACTIVE'] = true;
48 $PDF_OUTPUT = empty($_POST['pdf']) ? 0 : intval($_POST['pdf']);
50 if ($PDF_OUTPUT) {
51 require_once("$srcdir/html2pdf/html2pdf.class.php");
52 // $pdf = new HTML2PDF('P', 'Letter', 'en', array(5, 5, 5, 5) ); // add a little margin 5cm all around TODO: add to globals
53 $pdf = new HTML2PDF ($GLOBALS['pdf_layout'],
54 $GLOBALS['pdf_size'],
55 $GLOBALS['pdf_language'],
56 array($GLOBALS['pdf_left_margin'],$GLOBALS['pdf_top_margin'],$GLOBALS['pdf_right_margin'],$GLOBALS['pdf_bottom_margin'])
57 );
58 ob_start();
61 // get various authorization levels
62 $auth_notes_a = acl_check('encounters', 'notes_a');
63 $auth_notes = acl_check('encounters', 'notes');
64 $auth_coding_a = acl_check('encounters', 'coding_a');
65 $auth_coding = acl_check('encounters', 'coding');
66 $auth_relaxed = acl_check('encounters', 'relaxed');
67 $auth_med = acl_check('patients' , 'med');
68 $auth_demo = acl_check('patients' , 'demo');
70 $esignApi = new Api();
72 $printable = empty($_GET['printable']) ? false : true;
73 if ($PDF_OUTPUT) { $printable = true; }
74 unset($_GET['printable']);
76 // Number of columns in tables for insurance and encounter forms.
77 $N = $PDF_OUTPUT ? 4 : 6;
79 $first_issue = 1;
81 function getContent() {
82 global $web_root, $webserver_root;
83 $content = ob_get_clean();
84 // Fix a nasty html2pdf bug - it ignores document root!
85 $i = 0;
86 $wrlen = strlen($web_root);
87 $wsrlen = strlen($webserver_root);
88 while (true) {
89 $i = stripos($content, " src='/", $i + 1);
90 if ($i === false) break;
91 if (substr($content, $i+6, $wrlen) === $web_root &&
92 substr($content, $i+6, $wsrlen) !== $webserver_root)
94 $content = substr($content, 0, $i + 6) . $webserver_root . substr($content, $i + 6 + $wrlen);
97 return $content;
100 function postToGet($arin) {
101 $getstring="";
102 foreach ($arin as $key => $val) {
103 if (is_array($val)) {
104 foreach ($val as $k => $v) {
105 $getstring .= urlencode($key . "[]") . "=" . urlencode($v) . "&";
108 else {
109 $getstring .= urlencode($key) . "=" . urlencode($val) . "&";
112 return $getstring;
116 <?php if ($PDF_OUTPUT) { ?>
117 <link rel="stylesheet" href="<?php echo $webserver_root; ?>/interface/themes/style_pdf.css" type="text/css">
118 <link rel="stylesheet" type="text/css" href="<?php echo $webserver_root; ?>/library/ESign/css/esign_report.css" />
119 <?php } else {?>
120 <html>
121 <head>
122 <link rel="stylesheet" href="<?php echo $css_header;?>" type="text/css">
123 <link rel="stylesheet" type="text/css" href="<?php echo $GLOBALS['webroot'] ?>/library/ESign/css/esign_report.css" />
124 <?php } ?>
126 <?php // do not show stuff from report.php in forms that is encaspulated
127 // by div of navigateLink class. Specifically used for CAMOS, but
128 // can also be used by other forms that require output in the
129 // encounter listings output, but not in the custom report. ?>
130 <style>
131 div.navigateLink {display:none;}
132 .hilite {background-color: #FFFF00;}
133 .hilite2 {background-color: transparent;}
134 mark {background-color: #FFFF00;}
135 .css_button{cursor:pointer;}
136 .next {background-color: #FFFF00;}
137 #search_options{
138 position:fixed;
139 left:0px;
140 top:0px;
141 z-index:10;
142 border-bottom: solid thin #6D6D6D;
143 padding:0% 2% 0% 2.5%;
145 </style>
147 <?php if (!$PDF_OUTPUT) { ?>
149 <script type="text/javascript" src="<?php echo $GLOBALS['web_root']?>/library/js/jquery-1.5.js"></script>
150 <script type="text/javascript" src="<?php echo $GLOBALS['web_root']?>/library/js/SearchHighlight.js"></script>
151 <script type="text/javascript">var $j = jQuery.noConflict();</script>
153 <?php // if the track_anything form exists, then include the styling
154 if (file_exists(dirname(__FILE__) . "/../../forms/track_anything/style.css")) { ?>
155 <link rel="stylesheet" href="<?php echo $GLOBALS['web_root']?>/interface/forms/track_anything/style.css" type="text/css">
156 <?php } ?>
158 <script type="text/javascript">
160 // Code for search & Highlight
161 function reset_highlight(form_id,form_dir,class_name) { // Removes <span class='hilite' id=''>VAL</span> with VAL
162 $j("."+class_name).each(function(){
163 val = document.getElementById(this.id).innerHTML;
164 $j("#"+this.id).replaceWith(val);
168 var res_id = 0;
169 function doSearch(form_id,form_dir,exact,class_name,keys,case_sensitive) { // Uses jquery SearchHighlight Plug in
170 var options ={};
171 var keys = keys.replace(/^\s+|\s+$/g, '') ;
172 options = {
173 exact :exact,
174 style_name :class_name,
175 style_name_suffix:false,
176 highlight:'#search_div_'+form_id+'_'+form_dir,
177 keys :keys,
178 set_case_sensitive:case_sensitive
180 $j(document).SearchHighlight(options);
181 $j('.'+class_name).each(function(){
182 res_id = res_id+1;
183 $j(this).attr("id",'result_'+res_id);
187 function remove_mark(form_id,form_dir){ // Removes all <mark> and </mark> tags
188 var match1 = null;
189 var src_str = document.getElementById('search_div_'+form_id+'_'+form_dir).innerHTML;
190 var re = new RegExp('<mark>',"gi");
191 var match2 = src_str.match(re);
192 if(match2){
193 src_str = src_str.replace(re,'');
195 var match2 = null;
196 re = new RegExp('</mark>',"gi");
197 if(match2){
198 src_str = src_str.replace(re,'');
200 document.getElementById('search_div_'+form_id+'_'+form_dir).innerHTML=src_str;
202 function mark_hilight(form_id,form_dir,keys,case_sensitive){ // Adds <mark>match_val</mark> tags
203 keys = keys.replace(/^\s+|\s+$/g, '') ;
204 if(keys == '') return;
205 var src_str = $j('#search_div_'+form_id+'_'+form_dir).html();
206 var term = keys;
207 if((/\s+/).test(term) == true || (/['""-]{1,}/).test(term) == true){
208 term = term.replace(/(\s+)/g,"(<[^>]+>)*$1(<[^>]+>)*");
209 if(case_sensitive == true){
210 var pattern = new RegExp("("+term+")", "g");
212 else{
213 var pattern = new RegExp("("+term+")", "ig");
215 src_str = src_str.replace(/[\s\r\n]{1,}/g, ' '); // Replace text area newline or multiple spaces with single space
216 src_str = src_str.replace(pattern, "<mark class='hilite'>$1</mark>");
217 src_str = src_str.replace(/(<mark class=\'hilite\'>[^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/g,"$1</mark>$2<mark class='hilite'>$4");
218 $j('#search_div_'+form_id+'_'+form_dir).html(src_str);
219 $j('.hilite').each(function(){
220 res_id = res_id+1;
221 $j(this).attr("id",'result_'+res_id);
223 }else{
224 if(case_sensitive == true)
225 doSearch(form_id,form_dir,'partial','hilite',keys,'true');
226 else
227 doSearch(form_id,form_dir,'partial','hilite',keys,'false');
231 var forms_array;
232 var res_array = Array();
233 function find_all(){ // for each report the function mark_hilight() is called
234 case_sensitive = false;
235 if ($j('#search_case').attr('checked')) {
236 case_sensitive = true;
238 var keys = document.getElementById('search_element').value;
239 var match = null;
240 match = keys.match(/[\^\$\.\|\?\+\(\)\\~`\!@#%&\+={}<>]{1,}/);
241 if(match){
242 document.getElementById('alert_msg').innerHTML='<?php echo xla('Special characters are not allowed');?>..!';
243 return;
245 else{
246 document.getElementById('alert_msg').innerHTML='';
249 forms_arr = document.getElementById('forms_to_search');
250 for (var i = 0; i < forms_arr.options.length; i++) {
251 if(forms_arr.options[i].selected ==true){
252 $j('.class_'+forms_arr.options[i].value).each(function(){
253 id_arr = this.id.split('search_div_');
254 var re = new RegExp('_','i');
255 new_id = id_arr[1].replace(re, "|");
256 new_id_arr = new_id.split('|');
257 form_id = new_id_arr[0];
258 form_dir = new_id_arr[1];
259 mark_hilight(form_id,form_dir,keys,case_sensitive);
264 if($j('.hilite').length <1){
265 if(keys != '')
266 document.getElementById('alert_msg').innerHTML='<?php echo xla('No results found');?>..!';
268 else{
269 document.getElementById('alert_msg').innerHTML='';
270 f_id = $j('.hilite:first').attr('id');
271 element = document.getElementById(f_id);
272 element.scrollIntoView(false);
277 function remove_mark_all(){ // clears previous search results if exists
278 $j('.report_search_div').each(function(){
279 var id_arr = this.id.split('search_div_');
280 var re = new RegExp('_','i');
281 var new_id = id_arr[1].replace(re, "|");
282 var new_id_arr = new_id.split('|');
283 var form_id = new_id_arr[0];
284 var form_dir = new_id_arr[1];
285 reset_highlight(form_id,form_dir,'hilite');
286 reset_highlight(form_id,form_dir,'hilite2');
287 remove_mark(form_id,form_dir);
288 res_id = 0;
289 res_array =[];
293 var last_visited = -1;
294 var last_clicked = "";
295 var cur_res =0;
296 function next(w_count){
297 cur_res++;
298 remove_mark_all();
299 find_all();
300 var index = -1;
301 if(!($j(".hilite")[0])) {
302 return;
304 $j('.hilite').each(function(){
305 if($j(this).is(":visible")){
306 index = index+1;
307 res_array[index] = this.id;
310 $j('.hilite').addClass("hilite2");
311 $j('.hilite').removeClass("hilite");
312 var array_count = res_array.length;
313 if(last_clicked == "prev"){
314 last_visited = last_visited + (w_count-1);
316 last_clicked = "next";
317 for(k=0;k<w_count;k++){
318 last_visited ++;
319 if(last_visited == array_count){
320 cur_res = 0;
321 last_visited = -1;
322 next(w_count);
323 return;
325 $j("#"+res_array[last_visited]).addClass("next");
327 element = document.getElementById(res_array[last_visited]);
328 element.scrollIntoView(false);
332 function prev(w_count){
333 cur_res--;
334 remove_mark_all();
335 find_all();
336 var index = -1;
337 if(!($j(".hilite")[0])) {
338 return;
340 $j('.hilite').each(function(){
341 if($j(this).is(":visible")){
342 index = index+1;
343 res_array[index] = this.id;
346 $j('.hilite').addClass("hilite2");
347 $j('.hilite').removeClass("hilite");
348 var array_count = res_array.length;
349 if(last_clicked == "next"){
350 last_visited = last_visited - (w_count-1);
352 last_clicked = "prev";
353 for(k=0;k<w_count;k++){
354 last_visited --;
355 if(last_visited < 0){
356 cur_res = (array_count/w_count) + 1;
357 last_visited = array_count;
358 prev(w_count);
359 return;
361 $j("#"+res_array[last_visited]).addClass("next");
365 element = document.getElementById(res_array[last_visited]);
366 element.scrollIntoView(false);
368 function clear_last_visit(){
369 last_visited = -1;
370 cur_res = 0;
371 res_array = [];
372 last_clicked = "";
375 function get_word_count(form_id,form_dir,keys,case_sensitive){
376 keys = keys.replace(/^\s+|\s+$/g, '') ;
377 if(keys == '') return;
378 var src_str = $j('#search_div_'+form_id+'_'+form_dir).html();
379 var term = keys;
380 if((/\s+/).test(term) == true){
381 term = term.replace(/(\s+)/g,"(<[^>]+>)*$1(<[^>]+>)*");
382 if(case_sensitive == true){
383 var pattern = new RegExp("("+term+")", "");
385 else{
386 var pattern = new RegExp("("+term+")", "i");
388 src_str = src_str.replace(/[\s\r\n]{1,}/g, ' '); // Replace text area newline or multiple spaces with single space
389 src_str = src_str.replace(pattern, "<mark class='hilite'>$1</mark>");
390 src_str = src_str.replace(/(<mark class=\'hilite\'>[^<>]*)((<[^>]+>)+)([^<>]*<\/mark>)/,"$1</mark>$2<mark class='hilite'>$4");
391 var res =[];
392 res = src_str.match(/<mark class=\'hilite\'>/g);
393 if(res != null){
394 return res.length;
396 }else{
397 return 1;
401 function next_prev(action){
402 var w_count =0;
403 case_sensitive = false;
404 if ($j('#search_case').attr('checked')) {
405 case_sensitive = true;
407 var keys = document.getElementById('search_element').value;
408 var match = null;
409 match = keys.match(/[\^\$\.\|\?\+\(\)\\~`\!@#%&\+={}<>]{1,}/);
410 if(match){
411 document.getElementById('alert_msg').innerHTML='<?php echo xla('Special characters are not allowed');?>..!';
412 return;
414 else{
415 document.getElementById('alert_msg').innerHTML='';
417 forms_arr = document.getElementById('forms_to_search');
418 for (var i = 0; i < forms_arr.options.length; i++) {
419 if(forms_arr.options[i].selected ==true){
420 $j('.class_'+forms_arr.options[i].value).each(function(){
421 id_arr = this.id.split('search_div_');
422 var re = new RegExp('_','i');
423 new_id = id_arr[1].replace(re, "|");
424 new_id_arr = new_id.split('|');
425 form_id = new_id_arr[0];
426 form_dir = new_id_arr[1];
427 w_count = get_word_count(form_id,form_dir,keys,case_sensitive);
429 if(!isNaN(w_count)){
430 break;
434 if(w_count <1){
435 if(keys != '')
436 document.getElementById('alert_msg').innerHTML='<?php echo xla('No results found');?>..!';
438 else{
439 document.getElementById('alert_msg').innerHTML='';
440 if(action == 'next'){
441 next(w_count);
443 else if (action == 'prev'){
444 prev(w_count);
446 var tot_res = res_array.length/w_count;
447 if(tot_res > 0){
448 document.getElementById('alert_msg').innerHTML='<?php echo xla('Showing result');?> '+cur_res+' <?php echo xla('of');?> '+tot_res;
453 </script>
454 </head>
455 <body class="body_top" style="padding-top:95px;">
456 <?php } ?>
457 <div id="report_custom" style="width:100%;"> <!-- large outer DIV -->
459 <?php
460 if (sizeof($_GET) > 0) { $ar = $_GET; }
461 else { $ar = $_POST; }
463 if ($printable) {
464 /*******************************************************************
465 $titleres = getPatientData($pid, "fname,lname,providerID");
466 $sql = "SELECT * FROM facility ORDER BY billing_location DESC LIMIT 1";
467 *******************************************************************/
468 $titleres = getPatientData($pid, "fname,lname,providerID,DATE_FORMAT(DOB,'%m/%d/%Y') as DOB_TS");
469 if ($_SESSION['pc_facility']) {
470 $sql = "select * from facility where id=" . $_SESSION['pc_facility'];
471 } else {
472 $sql = "SELECT * FROM facility ORDER BY billing_location DESC LIMIT 1";
474 /******************************************************************/
475 $db = $GLOBALS['adodb']['db'];
476 $results = $db->Execute($sql);
477 $facility = array();
478 if (!$results->EOF) {
479 $facility = $results->fields;
481 // Setup Headers and Footers for html2PDF only Download
482 // in HTML view it's just one line at the top of page 1
483 echo '<page_header> ' . xlt("PATIENT") . ':' . text($titleres['lname']) . ', ' . text($titleres['fname']) . ' - ' . $titleres['DOB_TS'] . '</page_header> ';
484 echo '<page_footer>' . xlt('Generated on') . ' ' . oeFormatShortDate() . ' - ' . text($facility['name']) . ' ' . text($facility['phone']) . '</page_footer>';
486 // Use logo if it exists as 'practice_logo.gif' in the site dir
487 // old code used the global custom dir which is no longer a valid
488 $practice_logo = "$OE_SITE_DIR/images/practice_logo.gif";
489 if (file_exists($practice_logo)) {
490 echo "<img src='$practice_logo' align='left'><br />\n";
493 <h2><?php echo $facility['name'] ?></h2>
494 <?php echo $facility['street'] ?><br>
495 <?php echo $facility['city'] ?>, <?php echo $facility['state'] ?> <?php echo $facility['postal_code'] ?><br clear='all'>
496 <?php echo $facility['phone'] ?><br>
498 <a href="javascript:window.close();"><span class='title'><?php echo $titleres['fname'] . " " . $titleres['lname']; ?></span></a><br>
499 <span class='text'><?php xl('Generated on','e'); ?>: <?php echo oeFormatShortDate(); ?></span>
500 <br><br>
502 <?php
505 else { // not printable
508 <a href="patient_report.php" onclick='top.restoreSession()'>
509 <span class='title'><?php xl('Patient Report','e'); ?></span>
510 <span class='back'><?php echo $tback;?></span>
511 </a><br><br>
512 <a href="custom_report.php?printable=1&<?php print postToGet($ar); ?>" class='link_submit' target='new' onclick='top.restoreSession()'>
513 [<?php xl('Printable Version','e'); ?>]
514 </a><br>
515 <div class="report_search_bar" style="width:100%;" id="search_options">
516 <table style="width:100%;">
517 <tr>
518 <td>
519 <input type="text" onKeyUp="clear_last_visit();remove_mark_all();find_all();" name="search_element" id="search_element" style="width:180px;"/>
520 </td>
521 <td>
522 <a class="css_button" onClick="clear_last_visit();remove_mark_all();find_all();" ><span><?php echo xlt('Find'); ?></span></a>
523 </td>
524 <td>
525 <a class="css_button" onClick="next_prev('prev');" ><span><?php echo xlt('Prev'); ?></span></a>
526 </td>
527 <td>
528 <a class="css_button" onClick="next_prev('next');" ><span><?php echo xlt('Next'); ?></span></a>
529 </td>
530 <td>
531 <input type="checkbox" onClick="clear_last_visit();remove_mark_all();find_all();" name="search_case" id="search_case" />
532 </td>
533 <td>
534 <span><?php echo xlt('Match case'); ?></span>
535 </td>
536 <td style="padding-left:10px;">
537 <span class="text"><b><?php echo xlt('Search In'); ?>:</b></span>
538 <br>
539 <?php
540 $form_id_arr = array();
541 $form_dir_arr = array();
542 $last_key ='';
543 //ksort($ar);
544 foreach ($ar as $key_search => $val_search) {
545 if ($key_search == 'pdf' || $key_search == '' ) continue;
546 if (($auth_notes_a || $auth_notes || $auth_coding_a || $auth_coding || $auth_med || $auth_relaxed)) {
547 preg_match('/^(.*)_(\d+)$/', $key_search, $res_search);
548 $form_id_arr[] = add_escape_custom($res_search[2]);
549 $form_dir_arr[] = add_escape_custom($res_search[1]);
552 //echo json_encode(json_encode($array_key_id));
553 if(sizeof($form_id_arr)>0){
554 $query = "SELECT DISTINCT(form_name),formdir FROM forms WHERE form_id IN ( '".implode("','",$form_id_arr)."') AND formdir IN ( '".implode("','",$form_dir_arr)."')";
555 $arr = sqlStatement($query);
556 echo "<select multiple size='4' style='width:300px;' id='forms_to_search' onchange='clear_last_visit();remove_mark_all();find_all();' >";
557 while($res_forms_ids = sqlFetchArray($arr)){
558 echo "<option value='".attr($res_forms_ids['formdir'])."' selected>".text($res_forms_ids['form_name'])."</option>";
560 echo "</select>";
563 </td>
564 <td style="padding-left:10px;;width:30%;">
565 <span id ='alert_msg' style='color:red;'></span>
566 </td>
567 </tr>
568 </table>
569 </div>
570 <?php
571 } // end not printable ?>
573 <?php
575 // include ALL form's report.php files
576 $inclookupres = sqlStatement("select distinct formdir from forms where pid = '$pid' AND deleted=0");
577 while($result = sqlFetchArray($inclookupres)) {
578 // include_once("{$GLOBALS['incdir']}/forms/" . $result{"formdir"} . "/report.php");
579 $formdir = $result['formdir'];
580 if (substr($formdir,0,3) == 'LBF')
581 include_once($GLOBALS['incdir'] . "/forms/LBF/report.php");
582 else
583 include_once($GLOBALS['incdir'] . "/forms/$formdir/report.php");
586 // For each form field from patient_report.php...
588 foreach ($ar as $key => $val) {
589 if ($key == 'pdf') continue;
591 // These are the top checkboxes (demographics, allergies, etc.).
593 if (stristr($key,"include_")) {
595 if ($val == "demographics") {
597 echo "<hr />";
598 echo "<div class='text demographics' id='DEM'>\n";
599 print "<h1>".xl('Patient Data').":</h1>";
600 // printRecDataOne($patient_data_array, getRecPatientData ($pid), $N);
601 $result1 = getPatientData($pid);
602 $result2 = getEmployerData($pid);
603 echo " <table>\n";
604 display_layout_rows('DEM', $result1, $result2);
605 echo " </table>\n";
606 echo "</div>\n";
608 } elseif ($val == "history") {
610 echo "<hr />";
611 echo "<div class='text history' id='HIS'>\n";
612 if (acl_check('patients', 'med')) {
613 print "<h1>".xl('History Data').":</h1>";
614 // printRecDataOne($history_data_array, getRecHistoryData ($pid), $N);
615 $result1 = getHistoryData($pid);
616 echo " <table>\n";
617 display_layout_rows('HIS', $result1);
618 echo " </table>\n";
620 echo "</div>";
622 // } elseif ($val == "employer") {
623 // print "<br><span class='bold'>".xl('Employer Data').":</span><br>";
624 // printRecDataOne($employer_data_array, getRecEmployerData ($pid), $N);
626 } elseif ($val == "insurance") {
628 echo "<hr />";
629 echo "<div class='text insurance'>";
630 echo "<h1>".xl('Insurance Data').":</h1>";
631 print "<br><span class=bold>".xl('Primary Insurance Data').":</span><br>";
632 printRecDataOne($insurance_data_array, getRecInsuranceData ($pid,"primary"), $N);
633 print "<span class=bold>".xl('Secondary Insurance Data').":</span><br>";
634 printRecDataOne($insurance_data_array, getRecInsuranceData ($pid,"secondary"), $N);
635 print "<span class=bold>".xl('Tertiary Insurance Data').":</span><br>";
636 printRecDataOne($insurance_data_array, getRecInsuranceData ($pid,"tertiary"), $N);
637 echo "</div>";
639 } elseif ($val == "billing") {
641 echo "<hr />";
642 echo "<div class='text billing'>";
643 print "<h1>".xl('Billing Information').":</h1>";
644 if (count($ar['newpatient']) > 0) {
645 $billings = array();
646 echo "<table>";
647 echo "<tr><td width='400' class='bold'>Code</td><td class='bold'>".xl('Fee')."</td></tr>\n";
648 $total = 0.00;
649 $copays = 0.00;
650 foreach ($ar['newpatient'] as $be) {
651 $ta = split(":",$be);
652 $billing = getPatientBillingEncounter($pid,$ta[1]);
653 $billings[] = $billing;
654 foreach ($billing as $b) {
655 echo "<tr>\n";
656 echo "<td class=text>";
657 echo $b['code_type'] . ":\t" . $b['code'] . "&nbsp;". $b['modifier'] . "&nbsp;&nbsp;&nbsp;" . $b['code_text'] . "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
658 echo "</td>\n";
659 echo "<td class=text>";
660 echo oeFormatMoney($b['fee']);
661 echo "</td>\n";
662 echo "</tr>\n";
663 $total += $b['fee'];
664 if ($b['code_type'] == "COPAY") {
665 $copays += $b['fee'];
669 echo "<tr><td>&nbsp;</td></tr>";
670 echo "<tr><td class=bold>".xl('Sub-Total')."</td><td class=text>" . oeFormatMoney($total + abs($copays)) . "</td></tr>";
671 echo "<tr><td class=bold>".xl('Paid')."</td><td class=text>" . oeFormatMoney(abs($copays)) . "</td></tr>";
672 echo "<tr><td class=bold>".xl('Total')."</td><td class=text>" . oeFormatMoney($total) . "</td></tr>";
673 echo "</table>";
674 echo "<pre>";
675 //print_r($billings);
676 echo "</pre>";
677 } else {
678 printPatientBilling($pid);
680 echo "</div>\n"; // end of billing DIV
682 /****
684 } elseif ($val == "allergies") {
686 print "<span class=bold>Patient Allergies:</span><br>";
687 printListData($pid, "allergy", "1");
689 } elseif ($val == "medications") {
691 print "<span class=bold>Patient Medications:</span><br>";
692 printListData($pid, "medication", "1");
694 } elseif ($val == "medical_problems") {
696 print "<span class=bold>Patient Medical Problems:</span><br>";
697 printListData($pid, "medical_problem", "1");
699 ****/
701 } elseif ($val == "immunizations") {
703 if (acl_check('patients', 'med')) {
704 echo "<hr />";
705 echo "<div class='text immunizations'>\n";
706 print "<h1>".xl('Patient Immunization').":</h1>";
707 $sql = "select i1.immunization_id, i1.administered_date, substring(i1.note,1,20) as immunization_note, c.code_text_short ".
708 " from immunizations i1 ".
709 " left join code_types ct on ct.ct_key = 'CVX' ".
710 " left join codes c on c.code_type = ct.ct_id AND i1.cvx_code = c.code ".
711 " where i1.patient_id = '$pid' and i1.added_erroneously = 0 ".
712 " order by administered_date desc";
713 $result = sqlStatement($sql);
714 while ($row=sqlFetchArray($result)) {
715 // Figure out which name to use (ie. from cvx list or from the custom list)
716 if ($GLOBALS['use_custom_immun_list']) {
717 $vaccine_display = generate_display_field(array('data_type'=>'1','list_id'=>'immunizations'), $row['immunization_id']);
719 else {
720 if (!empty($row['code_text_short'])) {
721 $vaccine_display = htmlspecialchars( xl($row['code_text_short']), ENT_NOQUOTES);
723 else {
724 $vaccine_display = generate_display_field(array('data_type'=>'1','list_id'=>'immunizations'), $row['immunization_id']);
727 echo $row['administered_date'] . " - " . $vaccine_display;
728 if ($row['immunization_note']) {
729 echo " - " . $row['immunization_note'];
731 echo "<br>\n";
733 echo "</div>\n";
736 // communication report
737 } elseif ($val == "batchcom") {
739 echo "<hr />";
740 echo "<div class='text transactions'>\n";
741 print "<h1>".xl('Patient Communication sent').":</h1>";
742 $sql="SELECT concat( 'Messsage Type: ', batchcom.msg_type, ', Message Subject: ', batchcom.msg_subject, ', Sent on:', batchcom.msg_date_sent ) AS batchcom_data, batchcom.msg_text, concat( users.fname, users.lname ) AS user_name FROM `batchcom` JOIN `users` ON users.id = batchcom.sent_by WHERE batchcom.patient_id='$pid'";
743 // echo $sql;
744 $result = sqlStatement($sql);
745 while ($row=sqlFetchArray($result)) {
746 echo $row{'batchcom_data'}.", By: ".$row{'user_name'}."<br>Text:<br> ".$row{'msg_txt'}."<br>\n";
748 echo "</div>\n";
750 } elseif ($val == "notes") {
752 echo "<hr />";
753 echo "<div class='text notes'>\n";
754 print "<h1>".xl('Patient Notes').":</h1>";
755 printPatientNotes($pid);
756 echo "</div>";
758 } elseif ($val == "transactions") {
760 echo "<hr />";
761 echo "<div class='text transactions'>\n";
762 print "<h1>".xl('Patient Transactions').":</h1>";
763 printPatientTransactions($pid);
764 echo "</div>";
768 } else {
770 // Documents is an array of checkboxes whose values are document IDs.
772 if ($key == "documents") {
774 echo "<hr />";
775 echo "<div class='text documents'>";
776 foreach($val as $valkey => $valvalue) {
777 $document_id = $valvalue;
778 if (!is_numeric($document_id)) continue;
779 $d = new Document($document_id);
780 $fname = basename($d->get_url());
781 $couch_docid = $d->get_couch_docid();
782 $couch_revid = $d->get_couch_revid();
783 $extension = substr($fname, strrpos($fname,"."));
784 echo "<h1>" . xl('Document') . " '" . $fname ."'</h1>";
785 $notes = Note::notes_factory($d->get_id());
786 if (!empty($notes)) echo "<table>";
787 foreach ($notes as $note) {
788 echo '<tr>';
789 echo '<td>' . xl('Note') . ' #' . $note->get_id() . '</td>';
790 echo '</tr>';
791 echo '<tr>';
792 echo '<td>' . xl('Date') . ': ' . oeFormatShortDate($note->get_date()) . '</td>';
793 echo '</tr>';
794 echo '<tr>';
795 echo '<td>'.$note->get_note().'<br><br></td>';
796 echo '</tr>';
798 if (!empty($notes)) echo "</table>";
800 $url_file = $d->get_url_filepath();
801 if($couch_docid && $couch_revid){
802 $url_file = $d->get_couch_url($pid,$encounter);
804 // Collect filename and path
805 $from_all = explode("/",$url_file);
806 $from_filename = array_pop($from_all);
807 $from_pathname_array = array();
808 for ($i=0;$i<$d->get_path_depth();$i++) {
809 $from_pathname_array[] = array_pop($from_all);
811 $from_pathname_array = array_reverse($from_pathname_array);
812 $from_pathname = implode("/",$from_pathname_array);
814 if($couch_docid && $couch_revid) {
815 $from_file = $GLOBALS['OE_SITE_DIR'] . '/documents/temp/' . $from_filename;
816 $to_file = substr($from_file, 0, strrpos($from_file, '.')) . '_converted.jpg';
818 else {
819 $from_file = $GLOBALS["fileroot"] . "/sites/" . $_SESSION['site_id'] .
820 '/documents/' . $from_pathname . '/' . $from_filename;
821 $to_file = substr($from_file, 0, strrpos($from_file, '.')) . '_converted.jpg';
824 if ($extension == ".png" || $extension == ".jpg" || $extension == ".jpeg" || $extension == ".gif") {
825 if ($PDF_OUTPUT) {
826 // OK to link to the image file because it will be accessed by the
827 // HTML2PDF parser and not the browser.
828 $from_rel = $web_root . substr($from_file, strlen($webserver_root));
829 echo "<img src='$from_rel'";
830 // Flag images with excessive width for possible stylesheet action.
831 $asize = getimagesize($from_file);
832 if ($asize[0] > 750) echo " class='bigimage'";
833 echo " /><br><br>";
835 else {
836 echo "<img src='" . $GLOBALS['webroot'] .
837 "/controller.php?document&retrieve&patient_id=&document_id=" .
838 $document_id . "&as_file=false'><br><br>";
841 else {
843 // Most clinic documents are expected to be PDFs, and in that happy case
844 // we can avoid the lengthy image conversion process.
845 if ($PDF_OUTPUT && $extension == ".pdf") {
846 // HTML to PDF conversion will fail if there are open tags.
847 echo "</div></div>\n";
848 $content = getContent();
849 // $pdf->setDefaultFont('Arial');
850 $pdf->writeHTML($content, false);
851 $pagecount = $pdf->pdf->setSourceFile($from_file);
852 for($i = 0; $i < $pagecount; ++$i){
853 $pdf->pdf->AddPage();
854 $itpl = $pdf->pdf->importPage($i + 1, '/MediaBox');
855 $pdf->pdf->useTemplate($itpl);
857 // Make sure whatever follows is on a new page.
858 $pdf->pdf->AddPage();
859 // Resume output buffering and the above-closed tags.
860 ob_start();
861 echo "<div><div class='text documents'>\n";
863 else {
864 if (! is_file($to_file)) exec("convert -density 200 \"$from_file\" -append -resize 850 \"$to_file\"");
865 if (is_file($to_file)) {
866 if ($PDF_OUTPUT) {
867 // OK to link to the image file because it will be accessed by the
868 // HTML2PDF parser and not the browser.
869 echo "<img src='$to_file'><br><br>";
871 else {
872 echo "<img src='" . $GLOBALS['webroot'] .
873 "/controller.php?document&retrieve&patient_id=&document_id=" .
874 $document_id . "&as_file=false&original_file=false'><br><br>";
876 } else {
877 echo "<b>NOTE</b>: " . xl('Document') . "'" . $fname . "' " .
878 xl('cannot be converted to JPEG. Perhaps ImageMagick is not installed?') . "<br><br>";
879 if($couch_docid && $couch_revid) {
880 unlink($from_file);
885 } // end if-else
886 } // end Documents loop
887 echo "</div>";
889 } else if (strpos($key, "issue_") === 0) {
890 // display patient Issues
892 if ($first_issue) {
893 $prevIssueType = 'asdf1234!@#$'; // random junk so as to not match anything
894 $first_issue = 0;
895 echo "<hr />";
896 echo "<h1>".xl("Issues")."</h1>";
898 preg_match('/^(.*)_(\d+)$/', $key, $res);
899 $rowid = $res[2];
900 $irow = sqlQuery("SELECT type, title, comments, diagnosis " .
901 "FROM lists WHERE id = '$rowid'");
902 $diagnosis = $irow['diagnosis'];
903 if ($prevIssueType != $irow['type']) {
904 // output a header for each Issue Type we encounter
905 $disptype = $ISSUE_TYPES[$irow['type']][0];
906 echo "<div class='issue_type'>" . $disptype . ":</div>\n";
907 $prevIssueType = $irow['type'];
909 echo "<div class='text issue'>";
910 echo "<span class='issue_title'>" . $irow['title'] . ":</span>";
911 echo "<span class='issue_comments'> " . $irow['comments'] . "</span>\n";
912 // Show issue's chief diagnosis and its description:
913 if ($diagnosis) {
914 echo "<div class='text issue_diag'>";
915 echo "<span class='bold'>[".xl('Diagnosis')."]</span><br>";
916 $dcodes = explode(";", $diagnosis);
917 foreach ($dcodes as $dcode) {
918 echo "<span class='italic'>".$dcode."</span>: ";
919 echo lookup_code_descriptions($dcode)."<br>\n";
921 //echo $diagnosis." -- ".lookup_code_descriptions($diagnosis)."\n";
922 echo "</div>";
925 // Supplemental data for GCAC or Contraception issues.
926 if ($irow['type'] == 'ippf_gcac') {
927 echo " <table>\n";
928 display_layout_rows('GCA', sqlQuery("SELECT * FROM lists_ippf_gcac WHERE id = '$rowid'"));
929 echo " </table>\n";
931 else if ($irow['type'] == 'contraceptive') {
932 echo " <table>\n";
933 display_layout_rows('CON', sqlQuery("SELECT * FROM lists_ippf_con WHERE id = '$rowid'"));
934 echo " </table>\n";
937 echo "</div>\n"; //end the issue DIV
939 } else {
940 // we have an "encounter form" form field whose name is like
941 // dirname_formid, with a value which is the encounter ID.
943 // display encounter forms, encoded as a POST variable
944 // in the format: <formdirname_formid>=<encounterID>
946 if (($auth_notes_a || $auth_notes || $auth_coding_a || $auth_coding || $auth_med || $auth_relaxed)) {
947 $form_encounter = $val;
948 preg_match('/^(.*)_(\d+)$/', $key, $res);
949 $form_id = $res[2];
950 $formres = getFormNameByFormdirAndFormid($res[1],$form_id);
951 $dateres = getEncounterDateByEncounter($form_encounter);
952 $formId = getFormIdByFormdirAndFormid($res[1], $form_id);
954 if ($res[1] == 'newpatient') {
955 echo "<div class='text encounter'>\n";
956 echo "<h1>" . xl($formres["form_name"]) . "</h1>";
958 else {
959 echo "<div class='text encounter_form'>";
960 echo "<h1>" . xl_form_title($formres["form_name"]) . "</h1>";
963 // show the encounter's date
964 echo "(" . oeFormatSDFT(strtotime($dateres["date"])) . ") ";
965 if ($res[1] == 'newpatient') {
966 // display the provider info
967 echo ' '. xl('Provider') . ': ' . text(getProviderName(getProviderIdOfEncounter($form_encounter)));
969 echo "<br>\n";
971 // call the report function for the form
973 <div name="search_div" id="search_div_<?php echo attr($form_id)?>_<?php echo attr($res[1])?>" class="report_search_div class_<?php echo attr($res[1]); ?>">
974 <?php
975 if (substr($res[1],0,3) == 'LBF')
976 call_user_func("lbf_report", $pid, $form_encounter, $N, $form_id, $res[1]);
977 else
978 call_user_func($res[1] . "_report", $pid, $form_encounter, $N, $form_id);
980 $esign = $esignApi->createFormESign( $formId, $res[1], $form_encounter );
981 if ( $esign->isLogViewable("report") ) {
982 $esign->renderLog();
986 </div>
987 <?php
989 if ($res[1] == 'newpatient') {
990 // display billing info
991 $bres = sqlStatement("SELECT b.date, b.code, b.code_text " .
992 "FROM billing AS b, code_types AS ct WHERE " .
993 "b.pid = ? AND " .
994 "b.encounter = ? AND " .
995 "b.activity = 1 AND " .
996 "b.code_type = ct.ct_key AND " .
997 "ct.ct_diag = 0 " .
998 "ORDER BY b.date",
999 array($pid, $form_encounter));
1000 while ($brow=sqlFetchArray($bres)) {
1001 echo "<span class='bold'>&nbsp;".xl('Procedure').": </span><span class='text'>" .
1002 $brow['code'] . " " . $brow['code_text'] . "</span><br>\n";
1006 print "</div>";
1008 } // end auth-check for encounter forms
1010 } // end if('issue_')... else...
1012 } // end if('include_')... else...
1014 } // end $ar loop
1016 if ($printable)
1017 echo "<br /><br />" . xl('Signature') . ": _______________________________<br />";
1020 </div> <!-- end of report_custom DIV -->
1022 <?php
1023 if ($PDF_OUTPUT) {
1024 $content = getContent();
1025 // $pdf->setDefaultFont('Arial');
1026 $pdf->writeHTML($content, false);
1027 if ($PDF_OUTPUT == 1) {
1028 $pdf->Output('report.pdf', $GLOBALS['pdf_output']); // D = Download, I = Inline
1030 else {
1031 // This is the case of writing the PDF as a message to the CMS portal.
1032 $ptdata = getPatientData($pid, 'cmsportal_login');
1033 $contents = $pdf->Output('', true);
1034 echo "<html><head>\n";
1035 echo "<link rel='stylesheet' href='$css_header' type='text/css'>\n";
1036 echo "</head><body class='body_top'>\n";
1037 $result = cms_portal_call(array(
1038 'action' => 'putmessage',
1039 'user' => $ptdata['cmsportal_login'],
1040 'title' => xl('Your Clinical Report'),
1041 'message' => xl('Please see the attached PDF.'),
1042 'filename' => 'report.pdf',
1043 'mimetype' => 'application/pdf',
1044 'contents' => base64_encode($contents),
1046 if ($result['errmsg']) die(text($result['errmsg']));
1047 echo "<p>" . xlt('Report has been sent to the patient.') . "</p>\n";
1048 echo "</body></html>\n";
1051 else {
1053 </body>
1054 </html>
1055 <?php } ?>