various bugs (#4331)
[openemr.git] / interface / reports / immunization_report.php
blob1ab09a51e0027964a8830c17a93f1dc804febffc
1 <?php
3 /**
4 * This report lists patient immunizations for a given date range.
6 * @package OpenEMR
7 * @link http://www.open-emr.org
8 * @author Brady Miller <brady.g.miller@gmail.com>
9 * @copyright Copyright (c) 2011 Ensoftek Inc.
10 * @copyright Copyright (c) 2017-2018 Brady Miller <brady.g.miller@gmail.com>
11 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
14 require_once("../globals.php");
15 require_once("$srcdir/patient.inc");
17 use OpenEMR\Common\Csrf\CsrfUtils;
18 use OpenEMR\Core\Header;
20 if (!empty($_POST)) {
21 if (!CsrfUtils::verifyCsrfToken($_POST["csrf_token_form"])) {
22 CsrfUtils::csrfNotVerified();
26 $form_from_date = (isset($_POST['form_from_date'])) ? DateToYYYYMMDD($_POST['form_from_date']) : '';
27 $form_to_date = (isset($_POST['form_to_date'])) ? DateToYYYYMMDD($_POST['form_to_date']) : '';
29 function tr($a)
31 return (str_replace(' ', '^', $a));
34 function format_cvx_code($cvx_code)
37 if ($cvx_code < 10) {
38 return "0$cvx_code";
41 return $cvx_code;
44 function format_phone($phone)
47 $phone = preg_replace("/[^0-9]/", "", $phone);
48 switch (strlen($phone)) {
49 case 7:
50 return tr(preg_replace("/([0-9]{3})([0-9]{4})/", "000 $1$2", $phone));
51 case 10:
52 return tr(preg_replace("/([0-9]{3})([0-9]{3})([0-9]{4})/", "$1 $2$3", $phone));
53 default:
54 return tr("000 0000000");
58 function format_ethnicity($ethnicity)
61 switch ($ethnicity) {
62 case "hisp_or_latin":
63 return ("H^Hispanic or Latino^HL70189");
64 case "not_hisp_or_latin":
65 return ("N^not Hispanic or Latino^HL70189");
66 default: // Unknown
67 return ("U^Unknown^HL70189");
71 $sqlBindArray = array();
72 $query =
73 "select " .
74 "i.patient_id as patientid, " .
75 "p.language, " .
76 "i.cvx_code , ";
77 if (!empty($_POST['form_get_hl7']) && ($_POST['form_get_hl7'] === 'true')) {
78 $query .=
79 "DATE_FORMAT(p.DOB,'%Y%m%d') as DOB, " .
80 "concat(p.street, '^^', p.city, '^', p.state, '^', p.postal_code) as address, " .
81 "p.country_code, " .
82 "p.phone_home, " .
83 "p.phone_biz, " .
84 "p.status, " .
85 "p.sex, " .
86 "p.ethnoracial, " .
87 "p.race, " .
88 "p.ethnicity, " .
89 "c.code_text, " .
90 "c.code, " .
91 "c.code_type, " .
92 "DATE_FORMAT(i.vis_date,'%Y%m%d') as immunizationdate, " .
93 "DATE_FORMAT(i.administered_date,'%Y%m%d') as administered_date, " .
94 "i.lot_number as lot_number, " .
95 "i.manufacturer as manufacturer, " .
96 "concat(p.fname, '^', p.lname) as patientname, ";
97 } else {
98 $query .= "concat(p.fname, ' ',p.mname,' ', p.lname) as patientname, " .
99 "i.vis_date as immunizationdate, ";
102 $query .=
103 "i.id as immunizationid, c.code_text_short as immunizationtitle " .
104 "from immunizations i, patient_data p, codes c " .
105 "left join code_types ct on c.code_type = ct.ct_id " .
106 "where " .
107 "ct.ct_key='CVX' and ";
109 if (!empty($form_from_date)) {
110 $query .= "i.vis_date >= ? and ";
111 array_push($sqlBindArray, $form_from_date);
114 if (!empty($form_to_date)) {
115 $query .= "i.vis_date <= ? and ";
116 array_push($sqlBindArray, $form_to_date);
119 $form_code = isset($_POST['form_code']) ? $_POST['form_code'] : array();
120 if (empty($form_code)) {
121 $query_codes = '';
122 } else {
123 $query_codes = "c.id in (";
124 $codes = '';
125 foreach ($form_code as $code) {
126 $codes .= '?,';
127 array_push($sqlBindArray, $code);
129 $codes = substr($codes, 0, -1);
130 $query_codes .= $codes . ") and ";
133 $query .= "i.patient_id=p.pid and " .
134 $query_codes .
135 "i.cvx_code = c.code and ";
137 //do not show immunization added erroneously
138 $query .= "i.added_erroneously = 0";
140 $D = "\r";
141 $nowdate = date('Ymd');
142 $now = date('YmdGi');
143 $now1 = date('Y-m-d G:i');
144 $filename = "imm_reg_" . $now . ".hl7";
146 // GENERATE HL7 FILE
147 if (!empty($_POST['form_get_hl7']) && ($_POST['form_get_hl7'] === 'true')) {
148 $content = '';
150 $res = sqlStatement($query, $sqlBindArray);
152 while ($r = sqlFetchArray($res)) {
153 $content .= "MSH|^~\&|OPENEMR||||$nowdate||" .
154 "VXU^V04^VXU_V04|OPENEMR-110316102457117|P|2.5.1" .
155 "$D";
156 if ($r['sex'] === 'Male') {
157 $r['sex'] = 'M';
160 if ($r['sex'] === 'Female') {
161 $r['sex'] = 'F';
164 if ($r['status'] === 'married') {
165 $r['status'] = 'M';
168 if ($r['status'] === 'single') {
169 $r['status'] = 'S';
172 if ($r['status'] === 'divorced') {
173 $r['status'] = 'D';
176 if ($r['status'] === 'widowed') {
177 $r['status'] = 'W';
180 if ($r['status'] === 'separated') {
181 $r['status'] = 'A';
184 if ($r['status'] === 'domestic partner') {
185 $r['status'] = 'P';
188 $content .= "PID|" . // [[ 3.72 ]]
189 "|" . // 1. Set id
190 "|" . // 2. (B)Patient id
191 $r['patientid'] . "^^^MPI&2.16.840.1.113883.19.3.2.1&ISO^MR" . "|" . // 3. (R) Patient indentifier list. TODO: Hard-coded the OID from NIST test.
192 "|" . // 4. (B) Alternate PID
193 $r['patientname'] . "|" . // 5.R. Name
194 "|" . // 6. Mather Maiden Name
195 $r['DOB'] . "|" . // 7. Date, time of birth
196 $r['sex'] . "|" . // 8. Sex
197 "|" . // 9.B Patient Alias
198 "2106-3^" . $r['race'] . "^HL70005" . "|" . // 10. Race // Ram change
199 $r['address'] . "^^M" . "|" . // 11. Address. Default to address type Mailing Address(M)
200 "|" . // 12. county code
201 "^PRN^^^^" . format_phone($r['phone_home']) . "|" . // 13. Phone Home. Default to Primary Home Number(PRN)
202 "^WPN^^^^" . format_phone($r['phone_biz']) . "|" . // 14. Phone Work.
203 "|" . // 15. Primary language
204 $r['status'] . "|" . // 16. Marital status
205 "|" . // 17. Religion
206 "|" . // 18. patient Account Number
207 "|" . // 19.B SSN Number
208 "|" . // 20.B Driver license number
209 "|" . // 21. Mathers Identifier
210 format_ethnicity($r['ethnicity']) . "|" . // 22. Ethnic Group
211 "|" . // 23. Birth Plase
212 "|" . // 24. Multiple birth indicator
213 "|" . // 25. Birth order
214 "|" . // 26. Citizenship
215 "|" . // 27. Veteran military status
216 "|" . // 28.B Nationality
217 "|" . // 29. Patient Death Date and Time
218 "|" . // 30. Patient Death Indicator
219 "|" . // 31. Identity Unknown Indicator
220 "|" . // 32. Identity Reliability Code
221 "|" . // 33. Last Update Date/Time
222 "|" . // 34. Last Update Facility
223 "|" . // 35. Species Code
224 "|" . // 36. Breed Code
225 "|" . // 37. Breed Code
226 "|" . // 38. Production Class Code
227 "" . // 39. Tribal Citizenship
228 "$D";
229 $content .= "ORC" . // ORC mandatory for RXA
230 "|" .
231 "RE" .
232 "$D";
233 $content .= "RXA|" .
234 "0|" . // 1. Give Sub-ID Counter
235 "1|" . // 2. Administrattion Sub-ID Counter
236 $r['administered_date'] . "|" . // 3. Date/Time Start of Administration
237 $r['administered_date'] . "|" . // 4. Date/Time End of Administration
238 format_cvx_code($r['code']) . "^" . $r['immunizationtitle'] . "^" . "CVX" . "|" . // 5. Administration Code(CVX)
239 "999|" . // 6. Administered Amount. TODO: Immunization amt currently not captured in database, default to 999(not recorded)
240 "|" . // 7. Administered Units
241 "|" . // 8. Administered Dosage Form
242 "|" . // 9. Administration Notes
243 "|" . // 10. Administering Provider
244 "|" . // 11. Administered-at Location
245 "|" . // 12. Administered Per (Time Unit)
246 "|" . // 13. Administered Strength
247 "|" . // 14. Administered Strength Units
248 $r['lot_number'] . "|" . // 15. Substance Lot Number
249 "|" . // 16. Substance Expiration Date
250 "MSD" . "^" . $r['manufacturer'] . "^" . "HL70227" . "|" . // 17. Substance Manufacturer Name
251 "|" . // 18. Substance/Treatment Refusal Reason
252 "|" . // 19.Indication
253 "|" . // 20.Completion Status
254 "A" . // 21.Action Code - RXA
255 "$D";
258 // send the header here
259 header('Content-type: text/plain');
260 header('Content-Disposition: attachment; filename=' . $filename);
262 // put the content in the file
263 echo($content);
264 exit;
267 <html>
268 <head>
269 <title><?php echo xlt('Immunization Registry'); ?></title>
271 <?php Header::setupHeader(['datetime-picker', 'report-helper']); ?>
273 <script>
274 <?php require($GLOBALS['srcdir'] . "/restoreSession.php"); ?>
275 function confirmHl7() {
276 let msg = <?php echo js_escape(xlt('This step will generate a file which you have to save for future use.') .
277 '<br />' . xlt('The file cannot be generated again. Do you want to proceed?')); ?>;
278 dialog.confirm(msg).then(returned => {
279 if (returned === true) {
280 $('#form_get_hl7').attr('value', 'true');
281 $('#theform').submit();
282 } else {
283 return false;
288 $(function () {
289 var win = top.printLogSetup ? top : opener.top;
290 win.printLogSetup(document.getElementById('printbutton'));
292 $('.datepicker').datetimepicker({
293 <?php $datetimepicker_timepicker = false; ?>
294 <?php $datetimepicker_showseconds = false; ?>
295 <?php $datetimepicker_formatInput = true; ?>
296 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
297 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
300 </script>
302 <style>
303 /* specifically include & exclude from printing */
304 @media print {
305 #report_parameters {
306 visibility: hidden;
307 display: none;
310 #report_parameters_daterange {
311 visibility: visible;
312 display: inline;
313 margin-bottom: 10px;
316 #report_results table {
317 margin-top: 0px;
321 /* specifically exclude some from the screen */
322 @media screen {
323 #report_parameters_daterange {
324 visibility: hidden;
325 display: none;
328 #report_results {
329 width: 100%;
332 </style>
333 </head>
335 <body class="body_top">
337 <span class='title'><?php echo xlt('Report'); ?> - <?php echo xlt('Immunization Registry'); ?></span>
339 <div id="report_parameters_daterange">
340 <?php echo text(oeFormatShortDate($form_from_date)) . " &nbsp; " . xlt('to{{Range}}') . " &nbsp; " . text(oeFormatShortDate($form_to_date)); ?>
341 </div>
343 <form name='theform' id='theform' method='post' action='immunization_report.php' onsubmit='return top.restoreSession()'>
344 <input type="hidden" name="csrf_token_form" value="<?php echo attr(CsrfUtils::collectCsrfToken()); ?>" />
345 <div id="report_parameters">
346 <input type='hidden' name='form_refresh' id='form_refresh' value='' />
347 <input type='hidden' name='form_get_hl7' id='form_get_hl7' value='' />
348 <table>
349 <tr>
350 <td class='w-50'>
351 <div style='float:left'>
352 <table class='text'>
353 <tr>
354 <td class='col-form-label'>
355 <?php echo xlt('Codes'); ?>:
356 </td>
357 <td>
358 <?php
359 // Build a drop-down list of codes.
361 $query1 = "select id, concat('CVX:',code) as name from codes " .
362 " left join code_types ct on codes.code_type = ct.ct_id " .
363 " where ct.ct_key='CVX' ORDER BY name";
364 $cres = sqlStatement($query1);
365 echo " <select multiple='multiple' size='3' name='form_code[]' class='form-control'>\n";
366 //echo " <option value=''>-- " . xl('All Codes') . " --\n";
367 while ($crow = sqlFetchArray($cres)) {
368 $codeid = $crow['id'];
369 echo " <option value='" . attr($codeid) . "'";
370 if (in_array($codeid, $form_code)) {
371 echo " selected";
373 echo ">" . text($crow['name']) . "\n";
376 echo " </select>\n";
378 </td>
379 <td class='col-form-label'>
380 <?php echo xlt('From'); ?>:
381 </td>
382 <td>
383 <input type='text' name='form_from_date' id="form_from_date"
384 class='datepicker form-control'
385 size='10' value='<?php echo attr(oeFormatShortDate($form_from_date)); ?>' />
386 </td>
387 <td class='col-form-label'>
388 <?php echo xlt('To{{Range}}'); ?>:
389 </td>
390 <td>
391 <input type='text' name='form_to_date' id="form_to_date"
392 class='datepicker form-control'
393 size='10' value='<?php echo attr(oeFormatShortDate($form_to_date)); ?>' />
394 </td>
395 </tr>
396 </table>
397 </div>
398 </td>
399 <td class='h-100' valign='middle'>
400 <table class='w-100 h-100' style='border-left:1px solid;'>
401 <tr>
402 <td>
403 <div class="text-center">
404 <div class="btn-group" role="group">
405 <a href='#' class='btn btn-secondary btn-save'
406 onclick='
407 $("#form_refresh").attr("value","true");
408 $("#form_get_hl7").attr("value","false");
409 $("#theform").submit();
411 <?php echo xlt('Refresh'); ?>
412 </a>
413 <?php if (!empty($_POST['form_refresh'])) { ?>
414 <a href='#' class='btn btn-secondary btn-print' id='printbutton'>
415 <?php echo xlt('Print'); ?>
416 </a>
417 <a href='#' class='btn btn-secondary btn-transmit' onclick="confirmHl7()">
418 <?php echo xlt('Get HL7'); ?>
419 </a>
420 <?php } ?>
421 </div>
422 </div>
423 </td>
424 </tr>
425 </table>
426 </td>
427 </tr>
428 </table>
429 </div> <!-- end of parameters -->
431 <?php
432 if (!empty($_POST['form_refresh'])) {
434 <div id="report_results">
435 <table class='table'>
436 <thead class='thead-light'>
437 <tr>
438 <th> <?php echo xlt('Patient ID'); ?> </th>
439 <th> <?php echo xlt('Patient Name'); ?> </th>
440 <th> <?php echo xlt('Immunization Code'); ?> </th>
441 <th> <?php echo xlt('Immunization Title'); ?> </th>
442 <th> <?php echo xlt('Immunization Date'); ?> </th>
443 </tr>
444 </thead>
445 <tbody>
446 <?php
447 $total = 0;
448 //echo "<p> DEBUG query: $query </p>\n"; // debugging
449 $res = sqlStatement($query, $sqlBindArray);
451 while ($row = sqlFetchArray($res)) {
453 <tr>
454 <td>
455 <?php echo text($row['patientid']); ?>
456 </td>
457 <td>
458 <?php echo text($row['patientname']); ?>
459 </td>
460 <td>
461 <?php echo text($row['cvx_code']); ?>
462 </td>
463 <td>
464 <?php echo text($row['immunizationtitle']); ?>
465 </td>
466 <td>
467 <?php echo text($row['immunizationdate']); ?>
468 </td>
469 </tr>
470 <?php
471 ++$total;
474 <tr class="report_totals">
475 <td colspan='9'>
476 <?php echo xlt('Total Number of Immunizations'); ?>
478 <?php echo text($total); ?>
479 </td>
480 </tr>
481 </tbody>
482 </table>
483 </div> <!-- end of results -->
484 <?php } else { ?>
485 <div class='text'>
486 <?php echo xlt('Click Refresh to view all results, or please input search criteria above to view specific results.'); ?>
487 </div>
488 <?php } ?>
489 </form>
491 </body>
492 </html>