POS default selection for encounter (#1088)
[openemr.git] / library / report.inc
blob5ddf24afec74acaed2a26c95a01ccdc1d46f2f82
1 <?php
2 // This program is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU General Public License
4 // as published by the Free Software Foundation; either version 2
5 // of the License, or (at your option) any later version.
7 require_once("{$GLOBALS['srcdir']}/acl.inc");
8 require_once($GLOBALS["srcdir"] . "/options.inc.php");
10 $patient_data_array = array(
11 title => xl('Title') . ": ",
12 fname => xl('First Name') . ": ",
13 mname => xl('Middle Name') . ": ",
14 lname => xl('Last Name') . ": ",
15 sex => xl('Sex') . ": ",
16 ss => xl('SS') . ": ",
17 DOB => xl('Date of Birth') . ": ",
18 street => xl('Street') . ": ",
19 city => xl('City') . ": ",
20 state => xl('State') . ": ",
21 postal_code => xl('Zip') . ": ",
22 country_code => xl('Country') . ": ",
23 occupation => xl('Occupation') . ": ",
24 phone_home => xl('Home Phone') . ": ",
25 phone_biz => xl('Business Phone') . ": ",
26 phone_contact => xl('Contact Phone') . ": ",
27 contact_relationship => xl('Contact Person') . ": ",
28 hipaa_mail => xl('Allows Mail') . ": ",
29 hipaa_voice => xl('Allows Voice msgs') . ": ",
30 hipaa_notice => xl('Notice Received') . ": ",
31 hipaa_message => xl('Leave Message With') . ": "
34 $history_data_array = array(
35 coffee => xl('Coffee Use') . ": ",
36 tobacco => xl('Tobacco Use') . ": ",
37 alcohol => xl('Alcohol Use') . ": ",
38 sleep_patterns => xl('Sleep Patterns') . ": ",
39 exercise_patterns => xl('Exercise Patterns') . ": ",
40 seatbelt_use => xl('Seatbelt Use') . ": ",
41 counseling => xl('Counseling') . ": ",
42 hazardous_activities => xl('Hazardous Activities') . ": ",
43 last_breast_exam => xl('Last Breast Exam') . ": ",
44 last_mammogram => xl('Last Mammogram') . ": ",
45 last_gynocological_exam => xl('Last Gyn. Exam') . ": ",
46 last_rectal_exam => xl('Last Rectal Exam') . ": ",
47 last_prostate_exam => xl('Last Prostate Exam') . ": ",
48 last_physical_exam => xl('Last Physical Exam') . ": ",
49 last_sigmoidoscopy_colonoscopy => xl('Last Sigmoid/Colonoscopy') . ": ",
50 cataract_surgery => xl('Last Cataract Surgery') . ": ",
51 tonsillectomy => xl('Last Tonsillectomy') . ": ",
52 cholecystestomy => xl('Last Cholecystestomy') . ": ",
53 heart_surgery => xl('Last Heart Surgery') . ": ",
54 hysterectomy => xl('Last Hysterectomy') . ": ",
55 hernia_repair => xl('Last Hernia Repair') . ": ",
56 hip_replacement => xl('Last Hip Replacement') . ": ",
57 knee_replacement => xl('Last Knee Replacement') . ": ",
58 appendectomy => xl('Last Appendectomy') . ": ",
59 history_mother => xl('Mothers History') . ": ",
60 history_father => xl('Fathers History') . ": ",
61 history_siblings => xl('Sibling History') . ": ",
62 history_offspring => xl('Offspring History') . ": ",
63 history_spouse => xl('Spouses History') . ": ",
64 relatives_cancer => xl('Relatives Cancer') . ": ",
65 relatives_tuberculosis => xl('Relatives Tuberculosis') . ": ",
66 relatives_diabetes => xl('Relatives Diabetes') . ": ",
67 relatives_high_blood_pressure => xl('Relatives Blood Pressure') . ": ",
68 relatives_heart_problems => xl('Relatives Heart') . ": ",
69 relatives_stroke => xl('Relatives Stroke') . ": ",
70 relatives_epilepsy => xl('Relatives Epilepsy') . ": ",
71 relatives_mental_illness => xl('Relatives Mental Illness') . ": ",
72 relatives_suicide => xl('Relatives Suicide') . ": "
75 $employer_data_array = array(
76 name => xl('Employer') . ": ",
77 street => xl('Address') . ": ",
78 city => xl('City') . ": ",
79 postal_code => xl('Zip') . ": ",
80 state => xl('State') . ": ",
81 country => xl('Country') . ": "
84 $insurance_data_array = array(
85 provider_name => xl('Provider') . ": ",
86 plan_name => xl('Plan Name') . ": ",
87 policy_number => xl('Policy Number') . ": ",
88 group_number => xl('Group Number') . ": ",
89 subscriber_fname => xl('Subscriber First Name') . ": ",
90 subscriber_mname => xl('Subscriber Middle Name') . ": ",
91 subscriber_lname => xl('Subscriber Last Name') . ": ",
92 subscriber_relationship => xl('Subscriber Relationship') . ": ",
93 subscriber_ss => xl('Subscriber SS') . ": ",
94 subscriber_DOB => xl('Subscriber Date of Birth') . ": ",
95 subscriber_phone => xl('Subscribter Phone') . ": ",
96 subscriber_street => xl('Subscriber Address') . ": ",
97 subscriber_postal_code => xl('Subscriber Zip') . ": ",
98 subscriber_city => xl('Subscriber City') . ": ",
99 subscriber_state => xl('Subscriber State') . ": ",
100 subscriber_country => xl('Subscriber Country') . ": ",
101 subscriber_employer => xl('Subscriber Employer') . ": ",
102 subscriber_employer_street => xl('Subscriber Employer Street') . ": ",
103 subscriber_employer_city => xl('Subscriber Employer City') . ": ",
104 subscriber_employer_postal_code => xl('Subscriber Employer Zip') . ": ",
105 subscriber_employer_state => xl('Subscriber Employer State') . ": ",
106 subscriber_employer_country => xl('Subscriber Employer Country') . ": "
109 function getPatientReport($pid)
111     $sql = "select * from patient_data where pid='$pid' order by date ASC";
112     $res = sqlStatement("$sql");
113     while ($list = sqlFetchArray($res)) {
114         while (list($key, $value) = each($list)) {
115             if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date']) {
116                 $ret[$key]['title'] = $key;
117                 $ret[$key]['content'] = $value;
118                 $ret[$key]['date'] = $list['date'];
119             }
120         }
121     }
123     return $ret;
126 function getHistoryReport($pid)
128         $sql = "select * from history_data where pid='$pid' order by date ASC";
129         $res = sqlStatement("$sql");
130     while ($list = sqlFetchArray($res)) {
131         while (list($key, $value) = each($list)) {
132             if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date']) {
133                 $ret[$key]['content'] = $value;
134                 $ret[$key]['date'] = $list['date'];
135             }
136         }
137     }
139         return $ret;
142 function getInsuranceReport($pid, $type = "primary")
144         $sql = "select * from insurance_data where pid='$pid' and type='$type' order by date ASC";
145         $res = sqlStatement("$sql");
146     while ($list = sqlFetchArray($res)) {
147         while (list($key, $value) = each($list)) {
148             if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date']) {
149                 $ret[$key]['content'] = $value;
150                 $ret[$key]['date'] = $list['date'];
151             }
152         }
153     }
155         return $ret;
158 function getEmployerReport($pid)
160         $sql = "select * from employer_data where pid='$pid' order by date ASC";
161         $res = sqlStatement("$sql");
162     while ($list = sqlFetchArray($res)) {
163         while (list($key, $value) = each($list)) {
164             if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date']) {
165                 $ret[$key]['content'] = $value;
166                 $ret[$key]['date'] = $list['date'];
167             }
168         }
169     }
171         return $ret;
174 function getListsReport($pid)
176         $sql = "select * from lists where id='$id' order by date ASC";
177         $res = sqlStatement("$sql");
178     while ($list = sqlFetchArray($res)) {
179         while (list($key, $value) = each($list)) {
180             if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date']) {
181                 $ret[$key]['content'] = $value;
182                 $ret[$key]['date'] = $list['date'];
183             }
184         }
185     }
187         return $ret;
190 function printListData($pid, $list_type, $list_activity = "%")
192     $res = sqlStatement("select * from lists where pid='$pid' and type='$list_type' and activity like '$list_activity' order by date");
193     while ($result = sqlFetchArray($res)) {
194         print "<span class=bold>" . $result{"title"} . ":</span><span class=text> " . $result{"comments"} . "</span><br>\n";
195     }
198 function printPatientNotes($pid)
200   // exclude ALL deleted notes
201     $res = sqlStatement("select * from pnotes where pid = '$pid' and deleted != 1 and activity = 1 order by date");
202     while ($result = sqlFetchArray($res)) {
203         print "<span class=bold>" . oeFormatSDFT(strtotime($result{"date"})) .
204         ":</span><span class=text> " .
205         stripslashes(oeFormatPatientNote($result['body'])) . "</span><br>\n";
206     }
209 // Get the current value for a layout based transaction field.
211 function lbt_current_value($frow, $formid)
213     $formname = $frow['form_id'];
214     $field_id = $frow['field_id'];
215     $currvalue = '';
216     if ($formid) {
217         $ldrow = sqlQuery("SELECT field_value FROM lbt_data WHERE " .
218         "form_id = ? AND field_id = ?", array($formid, $field_id));
219         if (!empty($ldrow)) {
220             $currvalue = $ldrow['field_value'];
221         }
222     }
224     return $currvalue;
227 // Display a particular transaction.
229 function lbt_report($id, $formname)
231     $arr = array();
232     $fres = sqlStatement("SELECT * FROM layout_options " .
233     "WHERE form_id = ? AND uor > 0 " .
234     "ORDER BY group_id, seq", array($formname));
235     while ($frow = sqlFetchArray($fres)) {
236         $field_id  = $frow['field_id'];
237         $currvalue = lbt_current_value($frow, $id);
238         // For brevity, skip fields without a value.
239         if ($currvalue === '') {
240             continue;
241         }
243         $arr[$field_id] = wordwrap($currvalue, 30, "\n", true);
244     }
246     echo "<table>\n";
247     display_layout_rows($formname, $arr);
248     echo "</table>\n";
251 // Display all transactions for the specified patient.
253 function printPatientTransactions($pid)
255     $res = sqlStatement("SELECT * FROM transactions WHERE pid = ? ORDER BY date", array($pid));
256     while ($row = sqlFetchArray($res)) {
257         echo "<p><span class='bold'>" .
258         text(oeFormatSDFT(strtotime($row['date']))) .
259         " (" .
260         generate_display_field(array('data_type'=>'1','list_id'=>'transactions'), $row['title']) .
261         ")</span><br />\n";
262         lbt_report($row['id'], $row['title']);
263         echo "</p>\n";
264     }
267 function printPatientBilling($pid)
269     $res = sqlStatement("select * from billing where pid='$pid' order by date");
270     while ($result = sqlFetchArray($res)) {
271         echo "<span class=bold>" . oeFormatSDFT(strtotime($result{"date"})) . " : </span>";
272         echo "<span class=text>(".$result{"code_type"}.") ";
273         echo $result['code_type'] == 'COPAY' ? oeFormatMoney($result['code']) : $result['code'];
274         echo " - ". wordwrap(htmlspecialchars($result['code_text']), 70, "\n", true)."</span>";
275         echo "<br>\n";
276     }
279 function getPatientBillingEncounter($pid, $encounter)
281   /*******************************************************************
282         $sql = "SELECT billing.*, u.id, u.fname, u.mname, u.lname, " .
283     "CONCAT(u.fname,' ', u.lname) AS provider_name, u.federaltaxid " .
284     "FROM billing LEFT JOIN users AS u ON u.id = billing.provider_id " .
285     "WHERE pid='" . add_escape_custom($pid) . "' AND " .
286     "encounter = '" . add_escape_custom($encounter) .
287     "' AND activity='1' ORDER BY date";
288   *******************************************************************/
289     $erow = sqlQuery("SELECT provider_id FROM form_encounter WHERE " .
290     "pid = '$pid' AND encounter = '$encounter' " .
291     "ORDER BY id DESC LIMIT 1");
292     $inv_provider = $erow['provider_id'] + 0;
293     $sql = "SELECT b.*, u.id, u.fname, u.mname, u.lname, " .
294     "CONCAT(u.fname,' ', u.lname) AS provider_name, u.federaltaxid " .
295     "FROM billing AS b " .
296     "LEFT JOIN users AS u ON " .
297     "( b.provider_id != 0 AND u.id = b.provider_id ) OR " .
298     "( b.provider_id  = 0 AND u.id = $inv_provider ) " .
299     "WHERE pid='" . add_escape_custom($pid) . "' AND " .
300     "encounter = '" . add_escape_custom($encounter) .
301     "' AND activity = '1' ORDER BY date";
302   /******************************************************************/
303     $res = sqlStatement($sql);
304     $billings = array();
305     while ($result = sqlFetchArray($res)) {
306         $billings[] = $result;
307     }
309     return $billings;
312 function printPatientForms($pid, $cols)
314     //this function takes a $pid
315     $inclookupres = sqlStatement("select distinct formdir from forms where pid='$pid' AND deleted=0");
316     while ($result = sqlFetchArray($inclookupres)) {
317         include_once("{$GLOBALS['incdir']}/forms/" . $result{"formdir"} . "/report.php");
318     }
320     $res = sqlStatement("select * from forms where pid='$pid' AND deleted=0 order by date");
321     while ($result = sqlFetchArray($res)) {
322         if ($result{"form_name"} == "New Patient Encounter") {
323             echo "<div class='text encounter'>\n";
324             echo "<h1>" . $result["form_name"] . "</h1>";
326             // display the provider info
327             $tmp = sqlQuery("SELECT u.title, u.fname, u.mname, u.lname " .
328                                     "FROM forms AS f, users AS u WHERE " .
329                                     "f.pid = '$pid' AND f.encounter = ".$result['encounter']." AND " .
330                                     "f.formdir = 'newpatient' AND u.username = f.user " .
331                                     " AND f.deleted=0 ". //--JRM--
332                                     "ORDER BY f.id LIMIT 1");
333             echo " ".xl('Provider').": ".$tmp['title']." ".
334                 $tmp['fname']." ".$tmp['mname']." ".$tmp['lname'];
335             echo "<br/>";
336         } else {
337             echo "<div class='text encounter_form'>";
338             echo "<h1>" . $result["form_name"] . "</h1>";
339         }
341         echo "(" . oeFormatSDFT(strtotime($result["date"])) . ") ";
343         if (acl_check('acct', 'rep') || acl_check('acct', 'eob') || acl_check('acct', 'bill')) {
344             if ($result{"form_name"} == "New Patient Encounter") {
345                 // display billing info
346                 echo "<br/>";
347                 $bres = sqlStatement(
348                     "SELECT b.date, b.code, b.code_text " .
349                     "FROM billing AS b, code_types AS ct WHERE " .
350                     "b.pid = ? AND " .
351                     "b.encounter = ? AND " .
352                     "b.activity = 1 AND " .
353                     "b.code_type = ct.ct_key AND " .
354                     "ct.ct_diag = 0 " .
355                     "ORDER BY b.date",
356                     array($pid, $result['encounter'])
357                 );
358                 while ($brow=sqlFetchArray($bres)) {
359                     echo "<span class='bold'>&nbsp;".xl('Procedure').": </span><span class='text'>" .
360                         $brow['code'] . " " . $brow['code_text'] . "</span><br>\n";
361                 }
362             }
363         }
365         call_user_func($result{"formdir"} . "_report", $pid, $result{"encounter"}, $cols, $result{"form_id"});
367         echo "</div>";
368     }
371 function getRecHistoryData($pid)
373     //data is returned as a multi-level array:
374     //column name->dates->values
375     //$return{"lname"}[0..n]{"date"}
376     //$return{"lname"}[0..n]{"value"}
377     $res = sqlStatement("select * from history_data where pid=? order by date", array($pid));
379     while ($result = sqlFetchArray($res)) {
380         foreach ($result as $key => $val) {
381             if ($key == "pid" || $key == "date" || $key == "id") {
382                 next;
383             } else {
384                 $curdate = $result{"date"};
385                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
386                     $arcount{$key}++;
387                     $retar{$key}[$arcount{$key}]{"value"} = $val;
388                     $retar{$key}[$arcount{$key}]{"date"} = $curdate;
389                 }
390             }
391         }
392     }
394     return $retar;
397 function getRecEmployerData($pid)
399     //data is returned as a multi-level array:
400     //column name->dates->values
401     //$return{"lname"}[0..n]{"date"}
402     //$return{"lname"}[0..n]{"value"}
403     $res = sqlStatement("select * from employer_data where pid=? order by date", array($pid));
405     while ($result = sqlFetchArray($res)) {
406         foreach ($result as $key => $val) {
407             if ($key == "pid" || $key == "date" || $key == "id") {
408                 next;
409             } else {
410                 $curdate = $result{"date"};
411                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
412                     $arcount{$key}++;
413                     $retar{$key}[$arcount{$key}]{"value"} = $val;
414                     $retar{$key}[$arcount{$key}]{"date"} = $curdate;
415                 }
416             }
417         }
418     }
420     return $retar;
423 function getRecPatientData($pid)
425     //data is returned as a multi-level array:
426     //column name->dates->values
427     //$return{"lname"}[0..n]{"date"}
428     //$return{"lname"}[0..n]{"value"}
429     $res = sqlStatement("select * from patient_data where pid=? order by date", array($pid));
431     while ($result = sqlFetchArray($res)) {
432         foreach ($result as $key => $val) {
433             if ($key == "pid" || $key == "date" || $key == "id") {
434                 next;
435             } else {
436                 $curdate = $result{"date"};
437                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
438                     $arcount{$key}++;
439                     $retar{$key}[$arcount{$key}]{"value"} = $val;
440                     $retar{$key}[$arcount{$key}]{"date"} = $curdate;
441                 }
442             }
443         }
444     }
446     return $retar;
449 function getRecInsuranceData($pid, $ins_type)
451     //data is returned as a multi-level array:
452     //column name->dates->values
453     //$return{"lname"}[0..n]{"date"}
454     //$return{"lname"}[0..n]{"value"}
455     $res = sqlStatement("select *, ic.name as provider_name from insurance_data left join insurance_companies as ic on ic.id = provider where pid=? and type=? order by date", array($pid,$ins_type));
457     while ($result = sqlFetchArray($res)) {
458         foreach ($result as $key => $val) {
459             if ($key == "pid" || $key == "date" || $key == "id") {
460                 next;
461             } else {
462                 $curdate = $result{"date"};
463                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
464                     $arcount{$key}++;
465                     $retar{$key}[$arcount{$key}]{"value"} = $val;
466                     $retar{$key}[$arcount{$key}]{"date"} = $curdate;
467                 }
468             }
469         }
470     }
472     return $retar;
475 function printRecData($data_array, $recres, $N)
477     //this function generates a formatted history of all changes to the data
478     //it is a multi-level recursive function that exhaustively displays all of
479     //the changes, with dates, of any data in the database under the given
480     //argument restrictions.
481     //$data_array is an array with table_column_name => "display name"
482     //$recres is the return from getRecPatientData for example
483     //$N is the number of items to display in one row
484     print "<table><tr>\n";
485     $count = 0;
486     foreach ($data_array as $akey => $aval) {
487         if ($count == $N) {
488             print "</tr><tr>\n";
489             $count = 0;
490         }
492         print "<td valign=top><span class=bold>$aval</span><br><span class=text>";
493         printData($recres, $akey, "<br>", "Y-m-d");
494         print "</span></td>\n";
495         $count++;
496     }
498     print "</tr></table>\n";
501 function printData($retar, $key, $sep, $date_format)
503     //$retar{$key}
504     if (@array_key_exists($key, $retar)) {
505         $length = sizeof($retar{$key});
506         for ($iter = $length; $iter>=1; $iter--) {
507             if ($retar{$key}[$iter]{"value"} != "0000-00-00 00:00:00") {
508                 print $retar{$key}[$iter]{"value"} . " (" . oeFormatSDFT(strtotime($retar{$key}[$iter]{"date"})) . ")$sep";
509             }
510         }
511     }
514 function printRecDataOne($data_array, $recres, $N)
516     //this function is like printRecData except it will only print out those elements that
517     //have values. when they do have values, this function will only print out the most recent
518     //value of each element.
519     //this may be considered a compressed data viewer.
520     //this function generates a formatted history of all changes to the data
521     //$data_array is an array with table_column_name => "display name"
522     //$recres is the return from getRecPatientData for example
523     //$N is the number of items to display in one row
524     print "<table><tr>\n";
525     $count = 0;
526     foreach ($data_array as $akey => $aval) {
527         if (sizeof($recres{$akey})>0 && ($recres{$akey}[1]{"value"}!="0000-00-00 00:00:00")) {
528             if ($count == $N) {
529                 print "</tr><tr>\n";
530                 $count = 0;
531             }
533             print "<td valign=top><span class=bold>" . text($aval) . "</span><br><span class=text>";
534             printDataOne($recres, $akey, "<br>", "Y-m-d");
535             print "</span></td>\n";
536             $count++;
537         }
538     }
540     print "</tr></table>\n";
543 function printDataOne($retar, $key, $sep, $date_format)
545     //this function supports the printRecDataOne function above
546     if (@array_key_exists($key, $retar)) {
547         $length = sizeof($retar{$key});
548         if ($retar{$key}[$length]{"value"} != "0000-00-00 00:00:00") {
549             $tmp = $retar{$key}[$length]{"value"};
550             if (strstr($key, 'DOB')) {
551                 $tmp = oeFormatShortDate($tmp);
552             }
554             print text($tmp) . $sep;
555         }
556     }