Fixed bug: https://sourceforge.net/p/openemr/bugs/416/
[openemr.git] / interface / reports / non_reported.php
blob7bf712c9f6d543300845229e2a3635e11142692e
1 <?php
2 // Copyright (C) 2008 Rod Roark <rod@sunsetsystems.com>
3 // Copyright (C) 2010 Tomasz Wyderka <wyderkat@cofoh.com>
4 // Copyright (C) 2015 Ensoftek <rammohan@ensoftek.com>
5 //
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This report lists non reported patient diagnoses for a given date range.
12 // Ensoftek: Jul-2015: Modified HL7 generation to 2.5.1 spec and MU2 compliant.
13 // This implementation is only for the A01 profile which will suffice for MU2 certification.
16 require_once("../globals.php");
17 require_once("$srcdir/patient.inc");
18 require_once("../../custom/code_types.inc.php");
21 // Ensoftek: Jul-2015: Get the facility of the logged in user.
22 function getLoggedInUserFacility(){
23 $sql = "SELECT f.name, f.facility_npi FROM users AS u LEFT JOIN facility AS f ON u.facility_id = f.id WHERE u.id=?";
24 $res = sqlStatement($sql, array($_SESSION['authUserID']) );
25 while ($arow = sqlFetchArray($res)) {
26 return $arow;
28 return null;
31 // Ensoftek: Jul-2015: Map codes to confirm to HL7.
32 function mapCodeType($incode){
33 $outcode = null;
34 $code = explode(":", $incode);
35 switch ($code[0]) {
36 case "ICD9":
37 $outcode = "I9CDX";
38 break;
39 case "ICD10":
40 $outcode = "I10";
41 break;
42 case "SNOMED-CT":
43 $outcode = "SCT";
44 break;
45 case "US Ext SNOMEDCT":
46 $outcode = "SCT";
47 break;
48 default:
49 $outcode = "I9CDX"; // default to ICD9
50 break;
51 // Only ICD9, ICD10 and SNOMED codes allowed in Syndromic Surveillance
53 return $outcode;
57 if(isset($_POST['form_from_date'])) {
58 $from_date = $_POST['form_from_date'] !== "" ?
59 fixDate($_POST['form_from_date'], date('Y-m-d')) :
62 if(isset($_POST['form_to_date'])) {
63 $to_date =$_POST['form_to_date'] !== "" ?
64 fixDate($_POST['form_to_date'], date('Y-m-d')) :
68 $form_code = isset($_POST['form_code']) ? $_POST['form_code'] : Array();
70 if (empty ($form_code) ) {
71 $query_codes = '';
72 } else {
73 $query_codes = 'c.id in (';
74 foreach( $form_code as $code ){ $query_codes .= $code . ","; }
75 $query_codes = substr($query_codes ,0,-1);
76 $query_codes .= ') and ';
79 function tr($a) {
80 return (str_replace(' ','^',$a));
83 $query =
84 "select " .
85 "l.pid as patientid, " .
86 "p.language, ".
87 "l.diagnosis , " ;
88 if ($_POST['form_get_hl7']==='true') {
89 $query .=
90 "DATE_FORMAT(p.DOB,'%Y%m%d') as DOB, ".
91 "concat(p.street, '^',p.postal_code,'^', p.city, '^', p.state) as address, ".
92 "p.country_code, ".
93 "p.phone_home, ".
94 "p.phone_biz, ".
95 "p.status, ".
96 "p.sex, ".
97 "p.ethnoracial, ".
98 "c.code_text, ".
99 "c.code, ".
100 "c.code_type, ".
101 "DATE_FORMAT(l.date,'%Y%m%d') as issuedate, ".
102 "concat(p.fname, '^',p.mname,'^', p.lname) as patientname, ";
103 } else {
104 $query .= "concat(p.fname, ' ',p.mname,' ', p.lname) as patientname, ".
105 "l.date as issuedate, " ;
107 $query .=
108 "l.id as issueid, l.title as issuetitle, DATE_FORMAT(l.begdate,'%Y%m%d%H%i') as begin_date ". // Ensoftek: Jul-2015: Get begin date
109 "from lists l, patient_data p, codes c ".
110 "where ".
111 "c.reportable=1 and ".
112 "l.id not in (select lists_id from syndromic_surveillance) and ";
113 if($from_date!=0) {
114 $query .= "l.date >= '$from_date' " ;
116 if($from_date!=0 and $to_date!=0) {
117 $query .= " and " ;
119 if($to_date!=0) {
120 $query .= "l.date <= '$to_date' ";
122 if($from_date!=0 or $to_date!=0) {
123 $query .= " and " ;
125 $query .= "l.pid=p.pid and ".
126 $query_codes .
127 "l.diagnosis LIKE 'ICD9:%' and ".
128 "substring(l.diagnosis,6) = c.code ";
130 //echo "<p> DEBUG query: $query </p>\n"; // debugging
132 $D="\r";
133 $nowdate = date('YmdHi');
134 $now = date('YmdGi');
135 $now1 = date('Y-m-d G:i');
136 $filename = "syn_sur_". $now . ".hl7";
139 // Ensoftek: Jul-2015: Get logged in user's facility to be used in the MSH segment
140 $facility_info = getLoggedInUserFacility();
142 // GENERATE HL7 FILE
143 if ($_POST['form_get_hl7']==='true') {
144 $content = '';
146 $res = sqlStatement($query);
148 while ($r = sqlFetchArray($res)) {
149 // MSH
150 $content .= "MSH|^~\&|".strtoupper($openemr_name).
151 "|" . $facility_info['name'] . "^" . $facility_info['facility_npi'] . "^NPI" .
152 "|||$now||".
153 "ADT^A01^ADT_A01" . // Hard-code to A01: Patient visits provider/facility
154 "|$nowdate|P^T|2.5.1|||||||||PH_SS-NoAck^SS Sender^2.16.840.1.114222.4.10.3^ISO" . // No acknowlegement
155 "$D";
157 // EVN
158 $content .= "EVN|" .
159 "|" . // 1.B Event Type Code
160 "$now" . // 2.R Recorded Date/Time
161 "||||" .
162 "|" . $facility_info['name'] . "^" . $facility_info['facility_npi'] . "^NPI" .
163 "$D" ;
165 if ($r['sex']==='Male') $r['sex'] = 'M';
166 if ($r['sex']==='Female') $r['sex'] = 'F';
167 if ($r['status']==='married') $r['status'] = 'M';
168 if ($r['status']==='single') $r['status'] = 'S';
169 if ($r['status']==='divorced') $r['status'] = 'D';
170 if ($r['status']==='widowed') $r['status'] = 'W';
171 if ($r['status']==='separated') $r['status'] = 'A';
172 if ($r['status']==='domestic partner') $r['status'] = 'P';
174 // PID
175 $content .= "PID|" .
176 "1|" . // 1. Set id
177 "|" .
178 $r['patientid']."^^^^MR"."|". // 3. (R) Patient indentifier list
179 "|" . // 4. (B) Alternate PID
180 "^^^^^^~^^^^^^S"."|" . // 5.R. Name
181 "|" . // 6. Mather Maiden Name
182 $r['DOB']."|" . // 7. Date, time of birth
183 $r['sex'] . // 8. Sex
184 "|||^^^||||||||||||||||||||||||||||" .
185 "$D" ;
187 $content .= "PV1|" .
188 "1|" . // 1. Set ID
189 "|||||||||||||||||" .
190 // Restrict the string to 15 characters. Will fail if longer.
191 substr($now . "_" . $r['patientid'], 0, 15) . "^^^^VN" . // Supposed to be visit number. Since, we don't have any encounter, we'll use the format 'date_pid' to make it unique
192 "|||||||||||||||||||||||||" .
193 $r['begin_date'] .
194 "$D" ;
196 // OBX: Records chief complaint in LOINC code
197 $content .= "OBX|" .
198 "1|" . // 1. Set ID
199 "CWE|8661-1^^LN||" . // LOINC code for chief complaint
200 "^^^^^^^^" . $r['issuetitle'] .
201 "||||||" .
202 "F" .
203 "$D" ;
205 // DG1
206 $r['diagnosis'] = mapCodeType($r['diagnosis']); // Only ICD9, ICD10 and SNOMED
207 $r['code'] = str_replace(".", "", $r['code']); // strip periods code
209 $content .= "DG1|" .
210 "1|" . // 1. Set ID
211 "|" .
212 $r['code'] . "^" . $r['code_text'] . "^" . $r['diagnosis'] .
213 "|||W" .
214 "$D" ;
217 // mark if issues generated/sent
218 $query_insert = "insert into syndromic_surveillance(lists_id,submission_date,filename) " .
219 "values (" . $r['issueid'] . ",'" . $now1 . "','" . $filename . "')";
220 sqlStatement($query_insert);
223 // Ensoftek: Jul-2015: No need to tr the content
224 //$content = tr($content);
226 // send the header here
227 header('Content-type: text/plain');
228 header('Content-Disposition: attachment; filename=' . $filename );
230 // put the content in the file
231 echo($content);
232 exit;
236 <html>
237 <head>
238 <?php html_header_show();?>
239 <title><?php xl('Syndromic Surveillance - Non Reported Issues','e'); ?></title>
240 <style type="text/css">@import url(../../library/dynarch_calendar.css);</style>
241 <script type="text/javascript" src="../../library/dialog.js"></script>
242 <script type="text/javascript" src="../../library/textformat.js"></script>
243 <script type="text/javascript" src="../../library/dynarch_calendar.js"></script>
244 <?php include_once("{$GLOBALS['srcdir']}/dynarch_calendar_en.inc.php"); ?>
245 <script type="text/javascript" src="../../library/dynarch_calendar_setup.js"></script>
246 <script type="text/javascript" src="../../library/js/jquery.1.3.2.js"></script>
248 <script language="JavaScript">
250 <?php require($GLOBALS['srcdir'] . "/restoreSession.php"); ?>
252 $(document).ready(function() {
253 var win = top.printLogSetup ? top : opener.top;
254 win.printLogSetup(document.getElementById('printbutton'));
257 </script>
259 <link rel='stylesheet' href='<?php echo $css_header ?>' type='text/css'>
260 <style type="text/css">
261 /* specifically include & exclude from printing */
262 @media print {
263 #report_parameters {
264 visibility: hidden;
265 display: none;
267 #report_parameters_daterange {
268 visibility: visible;
269 display: inline;
270 margin-bottom: 10px;
272 #report_results table {
273 margin-top: 0px;
276 /* specifically exclude some from the screen */
277 @media screen {
278 #report_parameters_daterange {
279 visibility: hidden;
280 display: none;
282 #report_results {
283 width: 100%;
286 </style>
287 </head>
289 <body class="body_top">
291 <span class='title'><?php xl('Report','e'); ?> - <?php xl('Syndromic Surveillance - Non Reported Issues','e'); ?></span>
293 <div id="report_parameters_daterange">
294 <?php echo date("d F Y", strtotime($form_from_date)) ." &nbsp; to &nbsp; ". date("d F Y", strtotime($form_to_date)); ?>
295 </div>
297 <form name='theform' id='theform' method='post' action='non_reported.php'
298 onsubmit='return top.restoreSession()'>
299 <div id="report_parameters">
300 <input type='hidden' name='form_refresh' id='form_refresh' value=''/>
301 <input type='hidden' name='form_get_hl7' id='form_get_hl7' value=''/>
302 <table>
303 <tr>
304 <td width='410px'>
305 <div style='float:left'>
306 <table class='text'>
307 <tr>
308 <td class='label'>
309 <?php xl('Diagnosis','e'); ?>:
310 </td>
311 <td>
312 <?php
313 // Build a drop-down list of codes.
315 $query1 = "select id, code as name, code_type from codes ".
316 " where reportable=1 ORDER BY name";
317 $cres = sqlStatement($query1);
318 echo " <select multiple='multiple' size='3' name='form_code[]'>\n";
319 //echo " <option value=''>-- " . xl('All Codes') . " --\n";
320 while ($crow = sqlFetchArray($cres)) {
321 if (convert_type_id_to_key($crow['code_type']) == "ICD9") {
322 // This report currently only works for ICD9 codes. Need to make this work for other
323 // diagnosis code sets in the future.
324 $crow['name'] = convert_type_id_to_key($crow['code_type']) . ":" . $crow['name'];
325 $codeid = $crow['id'];
326 echo " <option value='$codeid'";
327 if (in_array($codeid, $form_code)) echo " selected";
328 echo ">" . $crow['name'] . "\n";
331 echo " </select>\n";
333 </td>
334 <td class='label'>
335 <?php xl('From','e'); ?>:
336 </td>
337 <td>
338 <input type='text' name='form_from_date' id="form_from_date"
339 size='10' value='<?php echo $form_from_date ?>'
340 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)'
341 title='yyyy-mm-dd'>
342 <img src='../pic/show_calendar.gif' align='absbottom'
343 width='24' height='22' id='img_from_date' border='0'
344 alt='[?]' style='cursor:pointer'
345 title='<?php xl('Click here to choose a date','e'); ?>'>
346 </td>
347 <td class='label'>
348 <?php xl('To','e'); ?>:
349 </td>
350 <td>
351 <input type='text' name='form_to_date' id="form_to_date"
352 size='10' value='<?php echo $form_to_date ?>'
353 onkeyup='datekeyup(this,mypcc)' onblur='dateblur(this,mypcc)'
354 title='yyyy-mm-dd'>
355 <img src='../pic/show_calendar.gif' align='absbottom'
356 width='24' height='22' id='img_to_date' border='0'
357 alt='[?]' style='cursor:pointer'
358 title='<?php xl('Click here to choose a date','e'); ?>'>
359 </td>
360 </tr>
361 </table>
362 </div>
363 </td>
364 <td align='left' valign='middle' height="100%">
365 <table style='border-left:1px solid; width:100%; height:100%' >
366 <tr>
367 <td>
368 <div style='margin-left:15px'>
369 <a href='#' class='css_button'
370 onclick='
371 $("#form_refresh").attr("value","true");
372 $("#form_get_hl7").attr("value","false");
373 $("#theform").submit();
375 <span>
376 <?php xl('Refresh','e'); ?>
377 </spain>
378 </a>
379 <?php if ($_POST['form_refresh']) { ?>
380 <a href='#' class='css_button' id='printbutton'>
381 <span>
382 <?php echo xlt('Print'); ?>
383 </span>
384 </a>
385 <a href='#' class='css_button' onclick=
386 "if(confirm('<?php xl('This step will generate a file which you have to save for future use. The file cannot be generated again. Do you want to proceed?','e'); ?>')) {
387 $('#form_get_hl7').attr('value','true');
388 $('#theform').submit();
390 <span>
391 <?php xl('Get HL7','e'); ?>
392 </span>
393 </a>
394 <?php } ?>
395 </div>
396 </td>
397 </tr>
398 </table>
399 </td>
400 </tr>
401 </table>
402 </div> <!-- end of parameters -->
405 <?php
406 if ($_POST['form_refresh']) {
408 <div id="report_results">
409 <table>
410 <thead align="left">
411 <th> <?php xl('Patient ID','e'); ?> </th>
412 <th> <?php xl('Patient Name','e'); ?> </th>
413 <th> <?php xl('Diagnosis','e'); ?> </th>
414 <th> <?php xl('Issue ID','e'); ?> </th>
415 <th> <?php xl('Issue Title','e'); ?> </th>
416 <th> <?php xl('Issue Date','e'); ?> </th>
417 </thead>
418 <tbody>
419 <?php
420 $total = 0;
421 //echo "<p> DEBUG query: $query </p>\n"; // debugging
422 $res = sqlStatement($query);
425 while ($row = sqlFetchArray($res)) {
427 <tr>
428 <td>
429 <?php echo htmlspecialchars($row['patientid']) ?>
430 </td>
431 <td>
432 <?php echo htmlspecialchars($row['patientname']) ?>
433 </td>
434 <td>
435 <?php echo htmlspecialchars($row['diagnosis']) ?>
436 </td>
437 <td>
438 <?php echo htmlspecialchars($row['issueid']) ?>
439 </td>
440 <td>
441 <?php echo htmlspecialchars($row['issuetitle']) ?>
442 </td>
443 <td>
444 <?php echo htmlspecialchars($row['issuedate']) ?>
445 </td>
446 </tr>
447 <?php
448 ++$total;
451 <tr class="report_totals">
452 <td colspan='9'>
453 <?php xl('Total Number of Issues','e'); ?>
455 <?php echo $total ?>
456 </td>
457 </tr>
459 </tbody>
460 </table>
461 </div> <!-- end of results -->
462 <?php } else { ?>
463 <div class='text'>
464 <?php echo xlt('Click Refresh to view all results, or please input search criteria above to view specific results.'); ?><br>
465 (<?php echo xlt('This report currently only works for ICD9 codes.'); ?>)
466 </div>
467 <?php } ?>
468 </form>
470 <script language='JavaScript'>
471 Calendar.setup({inputField:"form_from_date", ifFormat:"%Y-%m-%d", button:"img_from_date"});
472 Calendar.setup({inputField:"form_to_date", ifFormat:"%Y-%m-%d", button:"img_to_date"});
473 </script>
475 </body>
476 </html>