incremented patch version 1
[openemr.git] / library / report.inc
blob745e34e9d4f6a8f679cb6ad5ed9c680e69c1ca45
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']}/sql.inc");
8 require_once("{$GLOBALS['srcdir']}/acl.inc");
9 require_once("{$GLOBALS['srcdir']}/formatting.inc.php");
10 require_once("{$GLOBALS['srcdir']}/formdata.inc.php");
12 $patient_data_array = array(title => "Title: ",
13 fname => "First Name: ",
14 mname => "Middle Name: ",
15 lname => "Last Name: ",
16 sex => "Sex",
17 ss => "SS: ",
18 DOB => "Date of Birth: ",
19 street => "Street: ",
20 city => "City: ",
21 state => "State: ",
22 postal_code => "Zip: ",
23 country_code => "Country: ",
24 occupation => "Occupation: ",
25 phone_home => "Home Phone: ",
26 phone_biz => "Business Phone: ",
27 phone_contact => "Contact Phone: ",
28 contact_relationship => "Contact Person",
29 hipaa_mail => "Allows Mail: ",
30 hipaa_voice => "Allows Voice msgs: ",
31 hipaa_notice => "Notice Received: ",
32 hipaa_message => "Leave Message With: "
35 $history_data_array = array(
36 coffee => "Coffee Use: ",
37 tobacco => "Tobacco Use: ",
38 alcohol => "Alcohol Use: ",
39 sleep_patterns => "Sleep Patterns: ",
40 exercise_patterns => "Exercise Patterns: ",
41 seatbelt_use => "Seatbelt Use: ",
42 counseling => "Counseling: ",
43 hazardous_activities => "Hazardous Activities: ",
44 last_breast_exam => "Last Breast Exam: ",
45 last_mammogram => "Last Mammogram: ",
46 last_gynocological_exam => "Last Gyn. Exam: ",
47 last_rectal_exam => "Last Rectal Exam: ",
48 last_prostate_exam => "Last Prostate Exam: ",
49 last_physical_exam => "Last Physical Exam: ",
50 last_sigmoidoscopy_colonoscopy => "Last Sigmoid/Colonoscopy: ",
51 cataract_surgery => "Last Cataract Surgery: ",
52 tonsillectomy => "Last Tonsillectomy: ",
53 cholecystestomy => "Last Cholecystestomy: ",
54 heart_surgery => "Last Heart Surgery: ",
55 hysterectomy => "Last Hysterectomy: ",
56 hernia_repair => "Last Hernia Repair: ",
57 hip_replacement => "Last Hip Replacement: ",
58 knee_replacement => "Last Knee Replacement: ",
59 appendectomy => "Last Appendectomy: ",
60 history_mother => "Mother's History: ",
61 history_father => "Father's History: ",
62 history_siblings => "Sibling History: ",
63 history_offspring => "Offspring History: ",
64 history_spouse => "Spouse's History: ",
65 relatives_cancer => "Relatives Cancer: ",
66 relatives_tuberculosis => "Relatives Tuberculosis: ",
67 relatives_diabetes => "Relatives Diabetes: ",
68 relatives_high_blood_pressure => "Relatives Blood Pressure: ",
69 relatives_heart_problems => "Relatives Heart: ",
70 relatives_stroke => "Relatives Stroke: ",
71 relatives_epilepsy => "Relatives Epilepsy: ",
72 relatives_mental_illness => "Relatives Mental Illness: ",
73 relatives_suicide => "Relatives Suicide: ");
75 $employer_data_array = array(
76 name => "Employer: ",
77 street => "Address: ",
78 city => "City: ",
79 postal_code => "Zip: ",
80 state => "State",
81 country => "Country: ");
83 $insurance_data_array = array(
84 provider_name => "Provider: ",
85 plan_name => "Plan Name: ",
86 policy_number => "Policy Number: ",
87 group_number => "Group Number: ",
88 subscriber_fname => "Subscriber First Name: ",
89 subscriber_mname => "Subscriber Middle Name: ",
90 subscriber_lname => "Subscriber Last Name: ",
91 subscriber_relationship => "Subscriber Relationship: ",
92 subscriber_ss => "Subscriber SS: ",
93 subscriber_DOB => "Subscriber Date of Birth: ",
94 subscriber_phone => "Subscribter Phone: ",
95 subscriber_street => "Subscriber Address: ",
96 subscriber_postal_code => "Subscriber Zip: ",
97 subscriber_city => "Subscriber City: ",
98 subscriber_state => "Subscriber State: ",
99 subscriber_country => "Subscriber Country: ",
100 subscriber_employer => "Subscriber Employer: ",
101 subscriber_employer_street => "Subscriber Employer Street: ",
102 subscriber_employer_city => "Subscriber Employer City: ",
103 subscriber_employer_postal_code => "Subscriber Employer Zip: ",
104 subscriber_employer_state => "Subscriber Employer State: ",
105 subscriber_employer_country => "Subscriber Employer Country: "
108 function getPatientReport($pid)
110         $sql = "select * from patient_data where pid='$pid' order by date ASC";
111         $res = sqlStatement("$sql");
112         while($list = sqlFetchArray($res))
113         {
114                 while(list($key, $value) = each($list))
115                 {
116                         if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date'])
117                         {
118                                 $ret[$key]['title'] = $key;
119                                 $ret[$key]['content'] = $value;
120                                 $ret[$key]['date'] = $list['date'];
121                         }
122                 }
123         }
124         return $ret;
127 function getHistoryReport($pid)
129         $sql = "select * from history_data where pid='$pid' order by date ASC";
130         $res = sqlStatement("$sql");
131         while($list = sqlFetchArray($res))
132         {
133                 while(list($key, $value) = each($list))
134                 {
135                         if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date'])
136                         {
137                                 $ret[$key]['content'] = $value;
138                                 $ret[$key]['date'] = $list['date'];
139                         }
140                 }
141         }
142         return $ret;
145 function getInsuranceReport($pid, $type = "primary")
147         $sql = "select * from insurance_data where pid='$pid' and type='$type' order by date ASC";
148         $res = sqlStatement("$sql");
149         while($list = sqlFetchArray($res))
150         {
151                 while(list($key, $value) = each($list))
152                 {
153                         if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date'])
154                         {
155                                 $ret[$key]['content'] = $value;
156                                 $ret[$key]['date'] = $list['date'];
157                         }
158                 }
159         }
160         return $ret;
163 function getEmployerReport($pid)
165         $sql = "select * from employer_data where pid='$pid' order by date ASC";
166         $res = sqlStatement("$sql");
167         while($list = sqlFetchArray($res))
168         {
169                 while(list($key, $value) = each($list))
170                 {
171                         if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date'])
172                         {
173                                 $ret[$key]['content'] = $value;
174                                 $ret[$key]['date'] = $list['date'];
175                         }
176                 }
177         }
178         return $ret;
181 function getListsReport($pid)
183         $sql = "select * from lists where id='$id' order by date ASC";
184         $res = sqlStatement("$sql");
185         while($list = sqlFetchArray($res))
186         {
187                 while(list($key, $value) = each($list))
188                 {
189                         if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date'])
190                         {
191                                 $ret[$key]['content'] = $value;
192                                 $ret[$key]['date'] = $list['date'];
193                         }
194                 }
195         }
196         return $ret;
199 function printListData($pid, $list_type, $list_activity = "%") {
200         $res = sqlStatement("select * from lists where pid='$pid' and type='$list_type' and activity like '$list_activity' order by date");
201         while($result = sqlFetchArray($res)) {
202                 print "<span class=bold>" . $result{"title"} . ":</span><span class=text> " . $result{"comments"} . "</span><br>\n";
203         }
206 function printPatientNotes($pid) {
207   // exclude ALL deleted notes
208   $res = sqlStatement("select * from pnotes where pid = '$pid' and deleted != 1 and activity = 1 order by date");
209   while($result = sqlFetchArray($res)) {
210     print "<span class=bold>" . oeFormatSDFT(strtotime($result{"date"})) .
211       ":</span><span class=text> " .
212       stripslashes(oeFormatPatientNote($result['body'])) . "</span><br>\n";
213   }
216 function printPatientTransactions($pid) {
217         $res = sqlStatement("select * from transactions where pid=? order by date", array($pid) );
218         while($result = sqlFetchArray($res)) {
219                 print "<span class=bold>" .
220                 htmlspecialchars( oeFormatSDFT(strtotime($result{"date"})), ENT_NOQUOTES) .
221                 ":</span><span class=text>(" .
222                 generate_display_field(array('data_type'=>'1','list_id'=>'transactions'), $result{"title"}) .
223                 ") " . htmlspecialchars( $result{"body"}, ENT_NOQUOTES) .
224                 "</span><br>\n";
225         }
228 function printPatientBilling($pid) {
229   $res = sqlStatement("select * from billing where pid='$pid' order by date");
230   while($result = sqlFetchArray($res)) {
231     echo "<span class=bold>" . oeFormatSDFT(strtotime($result{"date"})) . " : </span>";
232     echo "<span class=text>(".$result{"code_type"}.") ";
233     echo $result['code_type'] == 'COPAY' ? oeFormatMoney($result['code']) : $result['code'];
234     echo " - ". $result['code_text']."</span>";
235     echo "<br>\n";
236         }
239 function getPatientBillingEncounter($pid, $encounter) {
240   /*******************************************************************
241         $sql = "SELECT billing.*, u.id, u.fname, u.mname, u.lname, " .
242     "CONCAT(u.fname,' ', u.lname) AS provider_name, u.federaltaxid " .
243     "FROM billing LEFT JOIN users AS u ON u.id = billing.provider_id " .
244     "WHERE pid='" . mysql_real_escape_string($pid) . "' AND " .
245     "encounter = '" . mysql_real_escape_string($encounter) .
246     "' AND activity='1' ORDER BY date";
247   *******************************************************************/
248   $erow = sqlQuery("SELECT provider_id FROM form_encounter WHERE " .
249     "pid = '$pid' AND encounter = '$encounter' " .
250     "ORDER BY id DESC LIMIT 1");
251   $inv_provider = $erow['provider_id'] + 0;
252         $sql = "SELECT b.*, u.id, u.fname, u.mname, u.lname, " .
253     "CONCAT(u.fname,' ', u.lname) AS provider_name, u.federaltaxid " .
254     "FROM billing AS b " .
255     "LEFT JOIN users AS u ON " .
256     "( b.provider_id != 0 AND u.id = b.provider_id ) OR " .
257     "( b.provider_id  = 0 AND u.id = $inv_provider ) " .
258     "WHERE pid='" . mysql_real_escape_string($pid) . "' AND " .
259     "encounter = '" . mysql_real_escape_string($encounter) .
260     "' AND activity = '1' ORDER BY date";
261   /******************************************************************/
262         $res = sqlStatement($sql);
263         $billings = array();
264         while($result = sqlFetchArray($res)) {
265                 $billings[] = $result;
266         }
267         return $billings;
270 function printPatientForms($pid, $cols) {
271     //this function takes a $pid
272     $inclookupres = sqlStatement("select distinct formdir from forms where pid='$pid' AND deleted=0");
273     while($result = sqlFetchArray($inclookupres)) {
274         include_once("{$GLOBALS['incdir']}/forms/" . $result{"formdir"} . "/report.php");
275     }
276         
277     $res = sqlStatement("select * from forms where pid='$pid' AND deleted=0 order by date");
278     while($result = sqlFetchArray($res)) {
279         if ($result{"form_name"} == "New Patient Encounter") {
280             echo "<div class='text encounter'>\n";
281             echo "<h1>" . $result["form_name"] . "</h1>";
283             // display the provider info
284             $tmp = sqlQuery("SELECT u.title, u.fname, u.mname, u.lname " .
285                                     "FROM forms AS f, users AS u WHERE " .
286                                     "f.pid = '$pid' AND f.encounter = ".$result['encounter']." AND " .
287                                     "f.formdir = 'newpatient' AND u.username = f.user " .
288                                     " AND f.deleted=0 ". //--JRM--
289                                     "ORDER BY f.id LIMIT 1");
290             echo " ".xl('Provider').": ".$tmp['title']." ".
291                 $tmp['fname']." ".$tmp['mname']." ".$tmp['lname'];
292             echo "<br/>";
293         }
294         else {
295             echo "<div class='text encounter_form'>";
296             echo "<h1>" . $result["form_name"] . "</h1>";
297         }
298         echo "(" . oeFormatSDFT(strtotime($result["date"])) . ") ";
300         if (acl_check('acct', 'rep') || acl_check('acct', 'eob') || acl_check('acct', 'bill')) {
301             if ($result{"form_name"} == "New Patient Encounter") {
302                 // display billing info
303                 echo "<br/>";
304                 $bres = sqlStatement("SELECT b.date, b.code, b.code_text " .
305                   "FROM billing AS b, code_types AS ct WHERE " .
306                   "b.pid = ? AND " .
307                   "b.encounter = ? AND " .
308                   "b.activity = 1 AND " .
309                   "b.code_type = ct.ct_key AND " .
310                   "ct.ct_diag = 0 " .
311                   "ORDER BY b.date",
312                   array($pid, $result['encounter']));
313                 while ($brow=sqlFetchArray($bres)) {
314                     echo "<span class='bold'>&nbsp;".xl('Procedure').": </span><span class='text'>" .
315                         $brow['code'] . " " . $brow['code_text'] . "</span><br>\n";
316                 }
317             }
318         }
320         call_user_func($result{"formdir"} . "_report", $pid, $result{"encounter"}, $cols, $result{"form_id"});
322         echo "</div>";
323     }
326 function getRecHistoryData ($pid) {
327         //data is returned as a multi-level array:
328         //column name->dates->values
329         //$return{"lname"}[0..n]{"date"}
330         //$return{"lname"}[0..n]{"value"}
331         $res = sqlStatement("select * from history_data where pid=? order by date", array($pid) );
332         
333         while($result = sqlFetchArray($res)) {
334                 foreach ($result as $key => $val) {
335                         if ($key == "pid" || $key == "date" || $key == "id") {
336                                 next;
337                         } else {
338                                 $curdate = $result{"date"};
339                                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
340                                         $arcount{$key}++;
341                                         $retar{$key}[$arcount{$key}]{"value"} = $val;
342                                         $retar{$key}[$arcount{$key}]{"date"} = $curdate;
343                                 }
344                         }
345                 }
346         }
347         return $retar;
350 function getRecEmployerData ($pid) {
351         //data is returned as a multi-level array:
352         //column name->dates->values
353         //$return{"lname"}[0..n]{"date"}
354         //$return{"lname"}[0..n]{"value"}
355         $res = sqlStatement("select * from employer_data where pid=? order by date", array($pid) );
356         
357         while($result = sqlFetchArray($res)) {
358                 foreach ($result as $key => $val) {
359                         if ($key == "pid" || $key == "date" || $key == "id") {
360                                 next;
361                         } else {
362                                 $curdate = $result{"date"};
363                                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
364                                         $arcount{$key}++;
365                                         $retar{$key}[$arcount{$key}]{"value"} = $val;
366                                         $retar{$key}[$arcount{$key}]{"date"} = $curdate;
367                                 }
368                         }
369                 }
370         }
371         return $retar;
374 function getRecPatientData ($pid) {
375         //data is returned as a multi-level array:
376         //column name->dates->values
377         //$return{"lname"}[0..n]{"date"}
378         //$return{"lname"}[0..n]{"value"}
379         $res = sqlStatement("select * from patient_data where pid=? order by date", array($pid) );
380         
381         while($result = sqlFetchArray($res)) {
382                 foreach ($result as $key => $val) {
383                         if ($key == "pid" || $key == "date" || $key == "id") {
384                                 next;
385                         } else {
386                                 $curdate = $result{"date"};
387                                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
388                                         $arcount{$key}++;
389                                         $retar{$key}[$arcount{$key}]{"value"} = $val;
390                                         $retar{$key}[$arcount{$key}]{"date"} = $curdate;
391                                 }
392                         }
393                 }
394         }
395         return $retar;
398 function getRecInsuranceData ($pid, $ins_type) {
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 *, 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) );
404         
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         }
419         return $retar;
422 function printRecData($data_array, $recres, $N) {
423         //this function generates a formatted history of all changes to the data
424         //it is a multi-level recursive function that exhaustively displays all of
425         //the changes, with dates, of any data in the database under the given
426         //argument restrictions.
427         //$data_array is an array with table_column_name => "display name"
428         //$recres is the return from getRecPatientData for example
429         //$N is the number of items to display in one row
430         print "<table><tr>\n";
431         $count = 0;
432         foreach ($data_array as $akey => $aval) {
433                 if ($count == $N) {
434                         print "</tr><tr>\n";
435                         $count = 0;
436                 }
437                 print "<td valign=top><span class=bold>$aval</span><br><span class=text>";
438                 printData($recres, $akey, "<br>", "Y-m-d");
439                 print "</span></td>\n";
440                 $count++;
441         }
442         print "</tr></table>\n";
445 function printData ($retar, $key, $sep, $date_format) {
446         //$retar{$key}
447         if (@array_key_exists($key,$retar)) {
448                 $length = sizeof($retar{$key});
449                 for ($iter = $length;$iter>=1;$iter--) {
450                         if ($retar{$key}[$iter]{"value"} != "0000-00-00 00:00:00") {
451                                 print $retar{$key}[$iter]{"value"} . " (" . oeFormatSDFT(strtotime($retar{$key}[$iter]{"date"})) . ")$sep";
452                         }
453                 }
454         }
457 function printRecDataOne($data_array, $recres, $N) {
458         //this function is like printRecData except it will only print out those elements that
459         //have values. when they do have values, this function will only print out the most recent
460         //value of each element.
461         //this may be considered a compressed data viewer.
462         //this function generates a formatted history of all changes to the data
463         //$data_array is an array with table_column_name => "display name"
464         //$recres is the return from getRecPatientData for example
465         //$N is the number of items to display in one row
466         print "<table><tr>\n";
467         $count = 0;
468         foreach ($data_array as $akey => $aval) {
469                 if (sizeof($recres{$akey})>0 && ($recres{$akey}[1]{"value"}!="0000-00-00 00:00:00")) {
470                         if ($count == $N) {
471                                 print "</tr><tr>\n";
472                                 $count = 0;
473                         }
474                         print "<td valign=top><span class=bold>" . text($aval) . "</span><br><span class=text>";
475                         printDataOne($recres, $akey, "<br>", "Y-m-d");
476                         print "</span></td>\n";
477                         $count++;
478                 }
479         }
480         print "</tr></table>\n";
483 function printDataOne ($retar, $key, $sep, $date_format) {
484         //this function supports the printRecDataOne function above
485         if (@array_key_exists($key,$retar)) {
486                 $length = sizeof($retar{$key});
487                 if ($retar{$key}[$length]{"value"} != "0000-00-00 00:00:00") {
488       $tmp = $retar{$key}[$length]{"value"};
489       if (strstr($key, 'DOB')) $tmp = oeFormatShortDate($tmp);
490                         print text($tmp) . $sep;
491                 }
492         }