added days of week to reccurence widget (#286)
[openemr.git] / library / report.inc
blob5150788bd86fa08eff0c2c192d8e9cf19c2e0a82
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");
11 require_once($GLOBALS["srcdir"] . "/options.inc.php");
13 $patient_data_array = array(
14 title => xl('Title') . ": ",
15 fname => xl('First Name') . ": ",
16 mname => xl('Middle Name') . ": ",
17 lname => xl('Last Name') . ": ",
18 sex => xl('Sex') . ": ",
19 ss => xl('SS') . ": ",
20 DOB => xl('Date of Birth') . ": ",
21 street => xl('Street') . ": ",
22 city => xl('City') . ": ",
23 state => xl('State') . ": ",
24 postal_code => xl('Zip') . ": ",
25 country_code => xl('Country') . ": ",
26 occupation => xl('Occupation') . ": ",
27 phone_home => xl('Home Phone') . ": ",
28 phone_biz => xl('Business Phone') . ": ",
29 phone_contact => xl('Contact Phone') . ": ",
30 contact_relationship => xl('Contact Person') . ": ",
31 hipaa_mail => xl('Allows Mail') . ": ",
32 hipaa_voice => xl('Allows Voice msgs') . ": ",
33 hipaa_notice => xl('Notice Received') . ": ",
34 hipaa_message => xl('Leave Message With') . ": "
37 $history_data_array = array(
38 coffee => xl('Coffee Use') . ": ",
39 tobacco => xl('Tobacco Use') . ": ",
40 alcohol => xl('Alcohol Use') . ": ",
41 sleep_patterns => xl('Sleep Patterns') . ": ",
42 exercise_patterns => xl('Exercise Patterns') . ": ",
43 seatbelt_use => xl('Seatbelt Use') . ": ",
44 counseling => xl('Counseling') . ": ",
45 hazardous_activities => xl('Hazardous Activities') . ": ",
46 last_breast_exam => xl('Last Breast Exam') . ": ",
47 last_mammogram => xl('Last Mammogram') . ": ",
48 last_gynocological_exam => xl('Last Gyn. Exam') . ": ",
49 last_rectal_exam => xl('Last Rectal Exam') . ": ",
50 last_prostate_exam => xl('Last Prostate Exam') . ": ",
51 last_physical_exam => xl('Last Physical Exam') . ": ",
52 last_sigmoidoscopy_colonoscopy => xl('Last Sigmoid/Colonoscopy') . ": ",
53 cataract_surgery => xl('Last Cataract Surgery') . ": ",
54 tonsillectomy => xl('Last Tonsillectomy') . ": ",
55 cholecystestomy => xl('Last Cholecystestomy') . ": ",
56 heart_surgery => xl('Last Heart Surgery') . ": ",
57 hysterectomy => xl('Last Hysterectomy') . ": ",
58 hernia_repair => xl('Last Hernia Repair') . ": ",
59 hip_replacement => xl('Last Hip Replacement') . ": ",
60 knee_replacement => xl('Last Knee Replacement') . ": ",
61 appendectomy => xl('Last Appendectomy') . ": ",
62 history_mother => xl('Mothers History') . ": ",
63 history_father => xl('Fathers History') . ": ",
64 history_siblings => xl('Sibling History') . ": ",
65 history_offspring => xl('Offspring History') . ": ",
66 history_spouse => xl('Spouses History') . ": ",
67 relatives_cancer => xl('Relatives Cancer') . ": ",
68 relatives_tuberculosis => xl('Relatives Tuberculosis') . ": ",
69 relatives_diabetes => xl('Relatives Diabetes') . ": ",
70 relatives_high_blood_pressure => xl('Relatives Blood Pressure') . ": ",
71 relatives_heart_problems => xl('Relatives Heart') . ": ",
72 relatives_stroke => xl('Relatives Stroke') . ": ",
73 relatives_epilepsy => xl('Relatives Epilepsy') . ": ",
74 relatives_mental_illness => xl('Relatives Mental Illness') . ": ",
75 relatives_suicide => xl('Relatives Suicide') . ": "
78 $employer_data_array = array(
79 name => xl('Employer') . ": ",
80 street => xl('Address') . ": ",
81 city => xl('City') . ": ",
82 postal_code => xl('Zip') . ": ",
83 state => xl('State') . ": ",
84 country => xl('Country') . ": "
87 $insurance_data_array = array(
88 provider_name => xl('Provider') . ": ",
89 plan_name => xl('Plan Name') . ": ",
90 policy_number => xl('Policy Number') . ": ",
91 group_number => xl('Group Number') . ": ",
92 subscriber_fname => xl('Subscriber First Name') . ": ",
93 subscriber_mname => xl('Subscriber Middle Name') . ": ",
94 subscriber_lname => xl('Subscriber Last Name') . ": ",
95 subscriber_relationship => xl('Subscriber Relationship') . ": ",
96 subscriber_ss => xl('Subscriber SS') . ": ",
97 subscriber_DOB => xl('Subscriber Date of Birth') . ": ",
98 subscriber_phone => xl('Subscribter Phone') . ": ",
99 subscriber_street => xl('Subscriber Address') . ": ",
100 subscriber_postal_code => xl('Subscriber Zip') . ": ",
101 subscriber_city => xl('Subscriber City') . ": ",
102 subscriber_state => xl('Subscriber State') . ": ",
103 subscriber_country => xl('Subscriber Country') . ": ",
104 subscriber_employer => xl('Subscriber Employer') . ": ",
105 subscriber_employer_street => xl('Subscriber Employer Street') . ": ",
106 subscriber_employer_city => xl('Subscriber Employer City') . ": ",
107 subscriber_employer_postal_code => xl('Subscriber Employer Zip') . ": ",
108 subscriber_employer_state => xl('Subscriber Employer State') . ": ",
109 subscriber_employer_country => xl('Subscriber Employer Country') . ": "
112 function getPatientReport($pid)
114         $sql = "select * from patient_data where pid='$pid' order by date ASC";
115         $res = sqlStatement("$sql");
116         while($list = sqlFetchArray($res))
117         {
118                 while(list($key, $value) = each($list))
119                 {
120                         if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date'])
121                         {
122                                 $ret[$key]['title'] = $key;
123                                 $ret[$key]['content'] = $value;
124                                 $ret[$key]['date'] = $list['date'];
125                         }
126                 }
127         }
128         return $ret;
131 function getHistoryReport($pid)
133         $sql = "select * from history_data where pid='$pid' order by date ASC";
134         $res = sqlStatement("$sql");
135         while($list = sqlFetchArray($res))
136         {
137                 while(list($key, $value) = each($list))
138                 {
139                         if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date'])
140                         {
141                                 $ret[$key]['content'] = $value;
142                                 $ret[$key]['date'] = $list['date'];
143                         }
144                 }
145         }
146         return $ret;
149 function getInsuranceReport($pid, $type = "primary")
151         $sql = "select * from insurance_data where pid='$pid' and type='$type' order by date ASC";
152         $res = sqlStatement("$sql");
153         while($list = sqlFetchArray($res))
154         {
155                 while(list($key, $value) = each($list))
156                 {
157                         if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date'])
158                         {
159                                 $ret[$key]['content'] = $value;
160                                 $ret[$key]['date'] = $list['date'];
161                         }
162                 }
163         }
164         return $ret;
167 function getEmployerReport($pid)
169         $sql = "select * from employer_data where pid='$pid' order by date ASC";
170         $res = sqlStatement("$sql");
171         while($list = sqlFetchArray($res))
172         {
173                 while(list($key, $value) = each($list))
174                 {
175                         if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date'])
176                         {
177                                 $ret[$key]['content'] = $value;
178                                 $ret[$key]['date'] = $list['date'];
179                         }
180                 }
181         }
182         return $ret;
185 function getListsReport($pid)
187         $sql = "select * from lists where id='$id' order by date ASC";
188         $res = sqlStatement("$sql");
189         while($list = sqlFetchArray($res))
190         {
191                 while(list($key, $value) = each($list))
192                 {
193                         if ($ret[$key]['content'] != $value && $ret[$key]['date'] < $list['date'])
194                         {
195                                 $ret[$key]['content'] = $value;
196                                 $ret[$key]['date'] = $list['date'];
197                         }
198                 }
199         }
200         return $ret;
203 function printListData($pid, $list_type, $list_activity = "%") {
204         $res = sqlStatement("select * from lists where pid='$pid' and type='$list_type' and activity like '$list_activity' order by date");
205         while($result = sqlFetchArray($res)) {
206                 print "<span class=bold>" . $result{"title"} . ":</span><span class=text> " . $result{"comments"} . "</span><br>\n";
207         }
210 function printPatientNotes($pid) {
211   // exclude ALL deleted notes
212   $res = sqlStatement("select * from pnotes where pid = '$pid' and deleted != 1 and activity = 1 order by date");
213   while($result = sqlFetchArray($res)) {
214     print "<span class=bold>" . oeFormatSDFT(strtotime($result{"date"})) .
215       ":</span><span class=text> " .
216       stripslashes(oeFormatPatientNote($result['body'])) . "</span><br>\n";
217   }
220 // Get the current value for a layout based transaction field.
222 function lbt_current_value($frow, $formid) {
223   $formname = $frow['form_id'];
224   $field_id = $frow['field_id'];
225   $currvalue = '';
226   if ($formid) {
227     $ldrow = sqlQuery("SELECT field_value FROM lbt_data WHERE " .
228       "form_id = ? AND field_id = ?", array($formid, $field_id) );
229     if (!empty($ldrow)) $currvalue = $ldrow['field_value'];
230   }
231   return $currvalue;
234 // Display a particular transaction.
236 function lbt_report($id, $formname) {
237   $arr = array();
238   $fres = sqlStatement("SELECT * FROM layout_options " .
239     "WHERE form_id = ? AND uor > 0 " .
240     "ORDER BY group_name, seq", array($formname));
241   while ($frow = sqlFetchArray($fres)) {
242     $field_id  = $frow['field_id'];
243     $currvalue = lbt_current_value($frow, $id);
244     // For brevity, skip fields without a value.
245     if ($currvalue === '') continue;
246     $arr[$field_id] = wordwrap($currvalue, 30, "\n", true);
247   }
248   echo "<table>\n";
249   display_layout_rows($formname, $arr);
250   echo "</table>\n";
253 // Display all transactions for the specified patient.
255 function printPatientTransactions($pid) {
256         $res = sqlStatement("SELECT * FROM transactions WHERE pid = ? ORDER BY date", array($pid));
257         while($row = sqlFetchArray($res)) {
258     echo "<p><span class='bold'>" .
259       text(oeFormatSDFT(strtotime($row['date']))) .
260       " (" .
261       generate_display_field(array('data_type'=>'1','list_id'=>'transactions'), $row['title']) .
262       ")</span><br />\n";
263     lbt_report($row['id'], $row['title']);
264     echo "</p>\n";
265         }
268 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($result['code_text'], 70, "\n", true)."</span>";
275     echo "<br>\n";
276         }
279 function getPatientBillingEncounter($pid, $encounter) {
280   /*******************************************************************
281         $sql = "SELECT billing.*, u.id, u.fname, u.mname, u.lname, " .
282     "CONCAT(u.fname,' ', u.lname) AS provider_name, u.federaltaxid " .
283     "FROM billing LEFT JOIN users AS u ON u.id = billing.provider_id " .
284     "WHERE pid='" . add_escape_custom($pid) . "' AND " .
285     "encounter = '" . add_escape_custom($encounter) .
286     "' AND activity='1' ORDER BY date";
287   *******************************************************************/
288   $erow = sqlQuery("SELECT provider_id FROM form_encounter WHERE " .
289     "pid = '$pid' AND encounter = '$encounter' " .
290     "ORDER BY id DESC LIMIT 1");
291   $inv_provider = $erow['provider_id'] + 0;
292         $sql = "SELECT b.*, u.id, u.fname, u.mname, u.lname, " .
293     "CONCAT(u.fname,' ', u.lname) AS provider_name, u.federaltaxid " .
294     "FROM billing AS b " .
295     "LEFT JOIN users AS u ON " .
296     "( b.provider_id != 0 AND u.id = b.provider_id ) OR " .
297     "( b.provider_id  = 0 AND u.id = $inv_provider ) " .
298     "WHERE pid='" . add_escape_custom($pid) . "' AND " .
299     "encounter = '" . add_escape_custom($encounter) .
300     "' AND activity = '1' ORDER BY date";
301   /******************************************************************/
302         $res = sqlStatement($sql);
303         $billings = array();
304         while($result = sqlFetchArray($res)) {
305                 $billings[] = $result;
306         }
307         return $billings;
310 function printPatientForms($pid, $cols) {
311     //this function takes a $pid
312     $inclookupres = sqlStatement("select distinct formdir from forms where pid='$pid' AND deleted=0");
313     while($result = sqlFetchArray($inclookupres)) {
314         include_once("{$GLOBALS['incdir']}/forms/" . $result{"formdir"} . "/report.php");
315     }
316         
317     $res = sqlStatement("select * from forms where pid='$pid' AND deleted=0 order by date");
318     while($result = sqlFetchArray($res)) {
319         if ($result{"form_name"} == "New Patient Encounter") {
320             echo "<div class='text encounter'>\n";
321             echo "<h1>" . $result["form_name"] . "</h1>";
323             // display the provider info
324             $tmp = sqlQuery("SELECT u.title, u.fname, u.mname, u.lname " .
325                                     "FROM forms AS f, users AS u WHERE " .
326                                     "f.pid = '$pid' AND f.encounter = ".$result['encounter']." AND " .
327                                     "f.formdir = 'newpatient' AND u.username = f.user " .
328                                     " AND f.deleted=0 ". //--JRM--
329                                     "ORDER BY f.id LIMIT 1");
330             echo " ".xl('Provider').": ".$tmp['title']." ".
331                 $tmp['fname']." ".$tmp['mname']." ".$tmp['lname'];
332             echo "<br/>";
333         }
334         else {
335             echo "<div class='text encounter_form'>";
336             echo "<h1>" . $result["form_name"] . "</h1>";
337         }
338         echo "(" . oeFormatSDFT(strtotime($result["date"])) . ") ";
340         if (acl_check('acct', 'rep') || acl_check('acct', 'eob') || acl_check('acct', 'bill')) {
341             if ($result{"form_name"} == "New Patient Encounter") {
342                 // display billing info
343                 echo "<br/>";
344                 $bres = sqlStatement("SELECT b.date, b.code, b.code_text " .
345                   "FROM billing AS b, code_types AS ct WHERE " .
346                   "b.pid = ? AND " .
347                   "b.encounter = ? AND " .
348                   "b.activity = 1 AND " .
349                   "b.code_type = ct.ct_key AND " .
350                   "ct.ct_diag = 0 " .
351                   "ORDER BY b.date",
352                   array($pid, $result['encounter']));
353                 while ($brow=sqlFetchArray($bres)) {
354                     echo "<span class='bold'>&nbsp;".xl('Procedure').": </span><span class='text'>" .
355                         $brow['code'] . " " . $brow['code_text'] . "</span><br>\n";
356                 }
357             }
358         }
360         call_user_func($result{"formdir"} . "_report", $pid, $result{"encounter"}, $cols, $result{"form_id"});
362         echo "</div>";
363     }
366 function getRecHistoryData ($pid) {
367         //data is returned as a multi-level array:
368         //column name->dates->values
369         //$return{"lname"}[0..n]{"date"}
370         //$return{"lname"}[0..n]{"value"}
371         $res = sqlStatement("select * from history_data where pid=? order by date", array($pid) );
372         
373         while($result = sqlFetchArray($res)) {
374                 foreach ($result as $key => $val) {
375                         if ($key == "pid" || $key == "date" || $key == "id") {
376                                 next;
377                         } else {
378                                 $curdate = $result{"date"};
379                                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
380                                         $arcount{$key}++;
381                                         $retar{$key}[$arcount{$key}]{"value"} = $val;
382                                         $retar{$key}[$arcount{$key}]{"date"} = $curdate;
383                                 }
384                         }
385                 }
386         }
387         return $retar;
390 function getRecEmployerData ($pid) {
391         //data is returned as a multi-level array:
392         //column name->dates->values
393         //$return{"lname"}[0..n]{"date"}
394         //$return{"lname"}[0..n]{"value"}
395         $res = sqlStatement("select * from employer_data where pid=? order by date", array($pid) );
396         
397         while($result = sqlFetchArray($res)) {
398                 foreach ($result as $key => $val) {
399                         if ($key == "pid" || $key == "date" || $key == "id") {
400                                 next;
401                         } else {
402                                 $curdate = $result{"date"};
403                                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
404                                         $arcount{$key}++;
405                                         $retar{$key}[$arcount{$key}]{"value"} = $val;
406                                         $retar{$key}[$arcount{$key}]{"date"} = $curdate;
407                                 }
408                         }
409                 }
410         }
411         return $retar;
414 function getRecPatientData ($pid) {
415         //data is returned as a multi-level array:
416         //column name->dates->values
417         //$return{"lname"}[0..n]{"date"}
418         //$return{"lname"}[0..n]{"value"}
419         $res = sqlStatement("select * from patient_data where pid=? order by date", array($pid) );
420         
421         while($result = sqlFetchArray($res)) {
422                 foreach ($result as $key => $val) {
423                         if ($key == "pid" || $key == "date" || $key == "id") {
424                                 next;
425                         } else {
426                                 $curdate = $result{"date"};
427                                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
428                                         $arcount{$key}++;
429                                         $retar{$key}[$arcount{$key}]{"value"} = $val;
430                                         $retar{$key}[$arcount{$key}]{"date"} = $curdate;
431                                 }
432                         }
433                 }
434         }
435         return $retar;
438 function getRecInsuranceData ($pid, $ins_type) {
439         //data is returned as a multi-level array:
440         //column name->dates->values
441         //$return{"lname"}[0..n]{"date"}
442         //$return{"lname"}[0..n]{"value"}
443         $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) );
444         
445         while($result = sqlFetchArray($res)) {
446                 foreach ($result as $key => $val) {
447                         if ($key == "pid" || $key == "date" || $key == "id") {
448                                 next;
449                         } else {
450                                 $curdate = $result{"date"};
451                                 if (($retar{$key}[$arcount{$key}]{"value"} != $val)) {
452                                         $arcount{$key}++;
453                                         $retar{$key}[$arcount{$key}]{"value"} = $val;
454                                         $retar{$key}[$arcount{$key}]{"date"} = $curdate;
455                                 }
456                         }
457                 }
458         }
459         return $retar;
462 function printRecData($data_array, $recres, $N) {
463         //this function generates a formatted history of all changes to the data
464         //it is a multi-level recursive function that exhaustively displays all of
465         //the changes, with dates, of any data in the database under the given
466         //argument restrictions.
467         //$data_array is an array with table_column_name => "display name"
468         //$recres is the return from getRecPatientData for example
469         //$N is the number of items to display in one row
470         print "<table><tr>\n";
471         $count = 0;
472         foreach ($data_array as $akey => $aval) {
473                 if ($count == $N) {
474                         print "</tr><tr>\n";
475                         $count = 0;
476                 }
477                 print "<td valign=top><span class=bold>$aval</span><br><span class=text>";
478                 printData($recres, $akey, "<br>", "Y-m-d");
479                 print "</span></td>\n";
480                 $count++;
481         }
482         print "</tr></table>\n";
485 function printData ($retar, $key, $sep, $date_format) {
486         //$retar{$key}
487         if (@array_key_exists($key,$retar)) {
488                 $length = sizeof($retar{$key});
489                 for ($iter = $length;$iter>=1;$iter--) {
490                         if ($retar{$key}[$iter]{"value"} != "0000-00-00 00:00:00") {
491                                 print $retar{$key}[$iter]{"value"} . " (" . oeFormatSDFT(strtotime($retar{$key}[$iter]{"date"})) . ")$sep";
492                         }
493                 }
494         }
497 function printRecDataOne($data_array, $recres, $N) {
498         //this function is like printRecData except it will only print out those elements that
499         //have values. when they do have values, this function will only print out the most recent
500         //value of each element.
501         //this may be considered a compressed data viewer.
502         //this function generates a formatted history of all changes to the data
503         //$data_array is an array with table_column_name => "display name"
504         //$recres is the return from getRecPatientData for example
505         //$N is the number of items to display in one row
506         print "<table><tr>\n";
507         $count = 0;
508         foreach ($data_array as $akey => $aval) {
509                 if (sizeof($recres{$akey})>0 && ($recres{$akey}[1]{"value"}!="0000-00-00 00:00:00")) {
510                         if ($count == $N) {
511                                 print "</tr><tr>\n";
512                                 $count = 0;
513                         }
514                         print "<td valign=top><span class=bold>" . text($aval) . "</span><br><span class=text>";
515                         printDataOne($recres, $akey, "<br>", "Y-m-d");
516                         print "</span></td>\n";
517                         $count++;
518                 }
519         }
520         print "</tr></table>\n";
523 function printDataOne ($retar, $key, $sep, $date_format) {
524         //this function supports the printRecDataOne function above
525         if (@array_key_exists($key,$retar)) {
526                 $length = sizeof($retar{$key});
527                 if ($retar{$key}[$length]{"value"} != "0000-00-00 00:00:00") {
528       $tmp = $retar{$key}[$length]{"value"};
529       if (strstr($key, 'DOB')) $tmp = oeFormatShortDate($tmp);
530                         print text($tmp) . $sep;
531                 }
532         }