fix: Smarty cal php82 warnings (#6316)
[openemr.git] / interface / orders / orders_results.php
blobec3060031d6e3dbf3db252ba1327b8475ce74418
1 <?php
3 /**
4 * orders_results.php
6 * @package OpenEMR
7 * @link https://www.open-emr.org
8 * @author Rod Roark <rod@sunsetsystems.com>
9 * @author Brady Miller <brady.g.miller@gmail.com>
10 * @copyright Copyright (c) 2010 Rod Roark <rod@sunsetsystems.com>
11 * @copyright Copyright (c) 2017-2019 Brady Miller <brady.g.miller@gmail.com>
12 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
15 require_once("../globals.php");
16 require_once("$srcdir/options.inc.php");
17 require_once("$srcdir/lab.inc.php");
19 use OpenEMR\Common\Acl\AclMain;
20 use OpenEMR\Common\Twig\TwigContainer;
21 use OpenEMR\Core\Header;
23 // Indicates if we are entering in batch mode.
24 $form_batch = empty($_GET['batch']) ? 0 : 1;
26 // Indicates if we are entering in review mode.
27 $form_review = empty($_GET['review']) ? 0 : 1;
29 // Check authorization.
30 $thisauth = AclMain::aclCheckCore('patients', 'lab');
31 if (!$thisauth) {
32 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => xl("Procedure Results")]);
33 exit;
36 // Check authorization for pending review.
37 $reviewauth = AclMain::aclCheckCore('patients', 'sign');
38 if ($form_review and !$reviewauth and !$thisauth) {
39 echo (new TwigContainer(null, $GLOBALS['kernel']))->getTwig()->render('core/unauthorized.html.twig', ['pageTitle' => xl("Procedure Results")]);
40 exit;
43 // Set pid for pending review.
44 if (!empty($_GET['set_pid']) && $form_review) {
45 require_once("$srcdir/pid.inc.php");
46 require_once("$srcdir/patient.inc.php");
47 setpid($_GET['set_pid']);
49 $result = getPatientData($pid, "*, DATE_FORMAT(DOB,'%Y-%m-%d') as DOB_YMD");
51 <script>
52 parent.left_nav.setPatient(<?php echo js_escape($result['fname'] . " " . $result['lname']) . "," . js_escape($pid) . "," . js_escape($result['pubpid']) . ",''," . js_escape(" " . xl('DOB') . ": " . oeFormatShortDate($result['DOB_YMD']) . " " . xl('Age') . ": " . getPatientAge($result['DOB_YMD'])); ?>);
53 </script>
54 <?php
57 if (!$form_batch && !$pid && !$form_review) {
58 die(xlt('There is no current patient'));
61 function oresRawData($name, $index)
63 $s = isset($_POST[$name][$index]) ? $_POST[$name][$index] : '';
64 return trim($s);
67 function oresData($name, $index)
69 $s = isset($_POST[$name][$index]) ? $_POST[$name][$index] : '';
70 return add_escape_custom(trim($s));
73 function QuotedOrNull($fld)
75 if (empty($fld)) {
76 return "null";
79 return "'$fld'";
82 $current_report_id = 0;
84 if (!empty($_POST['form_submit']) && !empty($_POST['form_line'])) {
85 foreach ($_POST['form_line'] as $lino => $line_value) {
86 list($order_id, $order_seq, $report_id, $result_id) = explode(':', $line_value);
88 // Not using xl() here because this is for debugging only.
89 if (empty($order_id)) {
90 die("Order ID is missing from line " . text($lino) . ".");
93 // If report data exists for this line, save it.
94 $date_report = oresData("form_date_report", $lino);
96 if (!empty($date_report)) {
97 $sets =
98 "procedure_order_id = '" . add_escape_custom($order_id) . "', " .
99 "procedure_order_seq = '" . add_escape_custom($order_seq) . "', " .
100 "date_report = '" . add_escape_custom($date_report) . "', " .
101 "date_collected = " . QuotedOrNull(oresData("form_date_collected", $lino)) . ", " .
102 "specimen_num = '" . oresData("form_specimen_num", $lino) . "', " .
103 "report_status = '" . oresData("form_report_status", $lino) . "'";
105 // Set the review status to reviewed.
106 if ($form_review) {
107 $sets .= ", review_status = 'reviewed'";
110 if ($report_id) { // Report already exists.
111 sqlStatement("UPDATE procedure_report SET $sets " .
112 "WHERE procedure_report_id = '" . add_escape_custom($report_id) . "'");
113 } else { // Add new report.
114 $report_id = sqlInsert("INSERT INTO procedure_report SET $sets");
118 // If this line had report data entry fields, filled or not, set the
119 // "current report ID" which the following result data will link to.
120 if (isset($_POST["form_date_report"][$lino])) {
121 $current_report_id = $report_id;
124 // If there's a report, save corresponding results.
125 if ($current_report_id) {
126 // Comments and notes will be combined into one comments field.
127 $form_comments = oresRawData("form_comments", $lino);
128 $form_comments = str_replace("\n", '~', $form_comments);
129 $form_comments = str_replace("\r", '', $form_comments);
130 $form_notes = oresRawData("form_notes", $lino);
131 if ($form_notes !== '') {
132 $form_comments .= "\n" . $form_notes;
135 $sets =
136 "procedure_report_id = '" . add_escape_custom($current_report_id) . "', " .
137 "result_code = '" . oresData("form_result_code", $lino) . "', " .
138 "result_text = '" . oresData("form_result_text", $lino) . "', " .
139 "`date` = " . QuotedOrNull(oresData("form_result_date", $lino)) . ", " .
140 "abnormal = '" . oresData("form_result_abnormal", $lino) . "', " .
141 "result = '" . oresData("form_result_result", $lino) . "', " .
142 "`range` = '" . oresData("form_result_range", $lino) . "', " .
143 "units = '" . oresData("form_result_units", $lino) . "', " .
144 "facility = '" . oresData("form_facility", $lino) . "', " .
145 "comments = '" . $form_comments . "', " .
146 "result_status = '" . oresData("form_result_status", $lino) . "', " .
147 "`date_end` = " . QuotedOrNull(oresData("form_result_date_end", $lino));
148 if ($result_id) { // result already exists
149 sqlStatement("UPDATE procedure_result SET $sets " .
150 "WHERE procedure_result_id = '" . add_escape_custom($result_id) . "'");
151 } else { // Add new result.
152 $result_id = sqlInsert("INSERT INTO procedure_result SET $sets");
155 } // end foreach
158 <html>
160 <head>
162 <?php Header::setupHeader('datetime-picker'); ?>
164 <title><?php echo xlt('Procedure Results'); ?></title>
166 <style>
168 tr.head {
169 font-size: 13px;
170 background-color: var(--gray400);
171 text-align: center;
173 tr.detail {
174 font-size: 13px;
177 .reccolor {
178 color: var(--success);
181 </style>
183 <script>
185 // This invokes the find-procedure-type popup.
186 var ptvarname;
187 function sel_proc_type(varname) {
188 var f = document.forms[0];
189 if (typeof varname == 'undefined') {
190 varname = 'form_proc_type';
192 ptvarname = varname;
193 dlgopen('types.php?popup=1&order=' + encodeURIComponent(f[ptvarname].value), '_blank', 800, 500);
196 // This is for callback by the find-procedure-type popup.
197 // Sets both the selected type ID and its descriptive name.
198 function set_proc_type(typeid, typename) {
199 var f = document.forms[0];
200 f[ptvarname].value = typeid;
201 f[ptvarname + '_desc'].value = typename;
204 // Helper functions.
205 function extGetX(elem) {
206 var x = 0;
207 while (elem != null) {
208 x += elem.offsetLeft;
209 elem = elem.offsetParent;
211 return x;
214 function extGetY(elem) {
215 var y = 0;
216 while (elem != null) {
217 y += elem.offsetTop;
218 elem = elem.offsetParent;
220 return y;
223 // Show or hide the "extras" div for a result.
224 var extdiv = null;
225 function extShow(lino, show) {
226 var thisdiv = document.getElementById("ext_" + lino);
227 if (extdiv) {
228 extdiv.style.visibility = 'hidden';
229 extdiv.style.left = '-1000px';
230 extdiv.style.top = '0px';
232 if (show && thisdiv != extdiv) {
233 extdiv = thisdiv;
234 var dw = window.innerWidth ? window.innerWidth - 20 : document.body.clientWidth;
235 x = dw - extdiv.offsetWidth;
236 if (x < 0) {
237 x = 0;
239 var y = extGetY(show) + show.offsetHeight;
240 extdiv.style.left = x;
241 extdiv.style.top = y;
242 extdiv.style.visibility = 'visible';
243 } else {
244 extdiv = null;
248 // Helper function for validate.
249 function prDateRequired(rlino) {
250 var f = document.forms[0];
251 if (f['form_date_report[' + rlino + ']'].value.length < 10) {
252 alert(<?php echo xlj('Missing report date'); ?>);
253 if (f['form_date_report[' + rlino + ']'].focus)
254 f['form_date_report[' + rlino + ']'].focus();
255 return false;
257 return true;
260 // Validation at submit time.
261 function validate(f) {
262 var rlino = 0;
263 for (var lino = 0; f['form_line[' + lino + ']']; ++lino) {
264 if (f['form_date_report[' + lino + ']']) {
265 rlino = lino;
266 if (f['form_report_status[' + rlino + ']'].selectedIndex > 0) {
267 if (!prDateRequired(rlino)) {
268 return false;
272 var abnstat = f['form_result_abnormal[' + lino + ']'].selectedIndex > 0;
273 if (abnstat && !prDateRequired(rlino)) {
274 return false;
277 top.restoreSession();
278 return true;
281 $(function () {
282 $('.datepicker').datetimepicker({
283 <?php $datetimepicker_timepicker = false; ?>
284 <?php $datetimepicker_showseconds = false; ?>
285 <?php $datetimepicker_formatInput = false; ?>
286 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
287 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
289 $('.datetimepicker').datetimepicker({
290 <?php $datetimepicker_timepicker = true; ?>
291 <?php $datetimepicker_showseconds = false; ?>
292 <?php $datetimepicker_formatInput = false; ?>
293 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
294 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
298 </script>
300 </head>
302 <body>
303 <div class="container-fluid mt-3">
304 <form method='post' action='orders_results.php?batch=<?php echo attr_url($form_batch); ?>&review=<?php echo attr_url($form_review); ?>' onsubmit='return validate(this)'>
305 <table class="table table-borderless">
306 <tr>
307 <td class='text form-inline'>
308 <?php
309 if ($form_batch) {
310 $form_from_date = isset($_POST['form_from_date']) ? trim($_POST['form_from_date']) : '';
311 $form_to_date = isset($_POST['form_to_date']) ? trim($_POST['form_to_date']) : '';
312 if (empty($form_to_date)) {
313 $form_to_date = $form_from_date;
316 $form_proc_type = isset($_REQUEST['form_proc_type']) ? $_REQUEST['form_proc_type'] + 0 : 0;
317 if (!$form_proc_type) {
318 $form_proc_type = -1;
321 $form_proc_type_desc = '';
322 if ($form_proc_type > 0) {
323 $ptrow = sqlQuery("SELECT name FROM procedure_type WHERE " .
324 "procedure_type_id = ?", [$form_proc_type]);
325 $form_proc_type_desc = $ptrow['name'];
328 <?php echo xlt('Procedure'); ?>:
330 <input class='form-control' type='text' size='30' name='form_proc_type_desc'
331 value='<?php echo attr($form_proc_type_desc) ?>'
332 onclick='sel_proc_type()' onfocus='this.blur()'
333 title='<?php echo xla('Click to select the desired procedure'); ?>'
334 style='cursor:pointer;cursor:hand' readonly />
336 <input type='hidden' name='form_proc_type' value='<?php echo attr($form_proc_type); ?>' />
338 &nbsp;<?php echo xlt('From'); ?>:
339 <input type='text' size='10' class='form-control datepicker' name='form_from_date' id='form_from_date' value='<?php echo attr($form_from_date); ?>' title='<?php echo xla('yyyy-mm-dd'); ?>' />
341 &nbsp;<?php echo xlt('To{{Range}}'); ?>:
342 <input type='text' size='10' class='form-control datepicker' name='form_to_date' id='form_to_date' value='<?php echo attr($form_to_date); ?>' title='<?php echo xla('yyyy-mm-dd'); ?>' />
344 &nbsp;
345 <?php
346 } // end header for batch option
348 <!-- removed by jcw -- check/submit sequece too tedious. This is a quick fix -->
349 <!-- <input type='checkbox' name='form_all' value='1' <?php if (!empty($_POST['form_all'])) {
350 echo " checked";
351 } ?>><?php echo xlt('Include Completed') ?>&nbsp;-->
352 <button type="submit" class="btn btn-primary btn-refresh" name='form_refresh' value='<?php echo xla('Refresh'); ?>'>
353 <?php echo xlt('Refresh'); ?>
354 </button>
355 </td>
356 </tr>
357 </table>
359 <?php if (!$form_batch || ($form_proc_type > 0 && $form_from_date)) { ?>
360 <table class="table table-hover">
361 <tr class='head'>
362 <td colspan='2'>
363 <?php echo $form_batch ? xlt('Patient') : xlt('Order'); ?>
364 </td>
365 <td colspan='4'>
366 <?php echo xlt('Report'); ?>
367 </td>
368 <td colspan='7'>
369 <?php echo xlt('Results and'); ?> <span class='reccolor'><?php echo xlt('Recommendations'); ?></span>
370 </td>
371 </tr>
372 <tr class='head'>
373 <td><?php echo $form_batch ? xlt('Name') : xlt('Date'); ?></td>
374 <td><?php echo $form_batch ? xlt('ID') : xlt('Procedure Name'); ?></td>
375 <td><?php echo xlt('Reported'); ?></td>
376 <td><?php echo xlt('Ext Time Collected'); ?></td>
377 <td><?php echo xlt('Specimen'); ?></td>
378 <td><?php echo xlt('Status'); ?></td>
379 <td><?php echo xlt('Code'); ?></td>
380 <td><?php echo xlt('Name'); ?></td>
381 <td><?php echo xlt('Date'); ?></td>
382 <td><?php echo xlt('End Date'); ?></td>
383 <td><?php echo xlt('Abn'); ?></td>
384 <td><?php echo xlt('Value'); ?></td>
385 <td><?php echo xlt('Units'); ?></td>
386 <td><?php echo xlt('Range'); ?></td>
387 <td><?php echo xlt('?'); ?></td>
388 </tr>
390 <?php
391 $sqlBindArray = array();
393 $selects =
394 "po.procedure_order_id, po.date_ordered, pc.procedure_order_seq, " .
395 "pt1.procedure_type_id AS order_type_id, pc.procedure_name, " .
396 "pr.procedure_report_id, pr.date_report, pr.date_collected, pr.specimen_num, " .
397 "pr.report_status, pr.review_status";
399 $joins =
400 "JOIN procedure_order_code AS pc ON pc.procedure_order_id = po.procedure_order_id " .
401 "LEFT JOIN procedure_type AS pt1 ON pt1.lab_id = po.lab_id AND pt1.procedure_code = pc.procedure_code " .
402 "LEFT JOIN procedure_report AS pr ON pr.procedure_order_id = po.procedure_order_id AND " .
403 "pr.procedure_order_seq = pc.procedure_order_seq";
405 $orderby =
406 "po.date_ordered, po.procedure_order_id, " .
407 "pc.procedure_order_seq, pr.procedure_report_id";
409 // removed by jcw -- check/submit sequece too tedious. This is a quick fix
410 //$where = empty($_POST['form_all']) ?
411 // "( pr.report_status IS NULL OR pr.report_status = '' OR pr.report_status = 'prelim' )" :
412 // "1 = 1";
414 $where = "1 = 1";
416 if ($form_batch) {
417 $query = "SELECT po.patient_id, " .
418 "pd.fname, pd.mname, pd.lname, pd.pubpid, $selects " .
419 "FROM procedure_order AS po " .
420 "LEFT JOIN patient_data AS pd ON pd.pid = po.patient_id $joins " .
421 "WHERE pt1.procedure_type_id = ? AND " .
422 "po.date_ordered >= ? AND po.date_ordered <= ? " .
423 "AND $where " .
424 "ORDER BY pd.lname, pd.fname, pd.mname, po.patient_id, $orderby";
425 array_push($sqlBindArray, $form_proc_type, $form_from_date, $form_to_date);
426 } else {
427 $query = "SELECT $selects " .
428 "FROM procedure_order AS po " .
429 "$joins " .
430 "WHERE po.patient_id = ? AND $where " .
431 "ORDER BY $orderby";
432 array_push($sqlBindArray, $pid);
435 $res = sqlStatement($query, $sqlBindArray);
437 $lastpoid = -1;
438 $lastpcid = -1;
439 $lastprid = -1;
440 $encount = 0;
441 $lino = 0;
442 $extra_html = '';
443 $lastrcn = '';
444 $facilities = array();
446 while ($row = sqlFetchArray($res)) {
447 $order_type_id = empty($row['order_type_id']) ? 0 : ($row['order_type_id'] + 0);
448 $order_id = empty($row['procedure_order_id']) ? 0 : ($row['procedure_order_id'] + 0);
449 $order_seq = empty($row['procedure_order_seq']) ? 0 : ($row['procedure_order_seq'] + 0);
450 $report_id = empty($row['procedure_report_id']) ? 0 : ($row['procedure_report_id'] + 0);
451 $date_report = empty($row['date_report']) ? '' : substr($row['date_report'], 0, 16);
452 $date_collected = empty($row['date_collected']) ? '' : substr($row['date_collected'], 0, 16);
453 $specimen_num = empty($row['specimen_num']) ? '' : $row['specimen_num'];
454 $report_status = empty($row['report_status']) ? '' : $row['report_status'];
455 $review_status = empty($row['review_status']) ? 'received' : $row['review_status'];
457 // skip report_status = receive to make sure do not show the report before it reviewed and sign off by Physicians
458 if ($form_review) {
459 if ($review_status == "reviewed") {
460 continue;
462 } else {
463 if ($review_status == "received") {
464 continue;
468 $query_test = sqlFetchArray(sqlStatement("select deleted from forms where form_id=? and formdir='procedure_order'", array($order_id)));
469 // skip the procedure that has been deleted from the encounter form
470 if ($query_test['deleted'] == 1) {
471 continue;
474 $selects = "pt2.procedure_type, pt2.procedure_code, ll.title AS pt2_units, " .
475 "pt2.range AS pt2_range, pt2.procedure_type_id AS procedure_type_id, " .
476 "pt2.name AS name, pt2.description, pt2.seq AS seq, " .
477 "ps.procedure_result_id, ps.result_code AS result_code, ps.result_text, ps.date, ps.date_end, ps.abnormal, ps.result, " .
478 "ps.range, ps.result_status, ps.facility, ps.comments, ps.units, ps.comments";
480 // procedure_type_id for order:
481 $pt2cond = "pt2.parent = '" . add_escape_custom($order_type_id) . "' AND " .
482 "(pt2.procedure_type LIKE 'res%' OR pt2.procedure_type LIKE 'rec%')";
484 // pr.procedure_report_id or 0 if none:
485 $pscond = "ps.procedure_report_id = '" . add_escape_custom($report_id) . "'";
487 $joincond = "ps.result_code = pt2.procedure_code";
489 // This union emulates a full outer join. The idea is to pick up all
490 // result types defined for this order type, as well as any actual
491 // results that do not have a matching result type.
492 $query = "(SELECT $selects FROM procedure_type AS pt2 " .
493 "LEFT JOIN procedure_result AS ps ON $pscond AND $joincond " .
494 "LEFT JOIN list_options AS ll ON ll.list_id = 'proc_unit' AND ll.option_id = pt2.units " .
495 "WHERE $pt2cond" .
496 ") UNION (" .
497 "SELECT $selects FROM procedure_result AS ps " .
498 "LEFT JOIN procedure_type AS pt2 ON $pt2cond AND $joincond " .
499 "LEFT JOIN list_options AS ll ON ll.list_id = 'proc_unit' AND ll.option_id = pt2.units " .
500 "WHERE $pscond) " .
501 "ORDER BY seq, name, procedure_type_id, result_code";
503 $rres = sqlStatement($query);
504 while ($rrow = sqlFetchArray($rres)) {
505 $restyp_code = empty($rrow['procedure_code']) ? '' : $rrow['procedure_code'];
506 $restyp_type = empty($rrow['procedure_type']) ? '' : $rrow['procedure_type'];
507 $restyp_name = empty($rrow['name']) ? '' : $rrow['name'];
508 $restyp_units = empty($rrow['pt2_units']) ? '' : $rrow['pt2_units'];
509 $restyp_range = empty($rrow['pt2_range']) ? '' : $rrow['pt2_range'];
511 $result_id = empty($rrow['procedure_result_id']) ? 0 : ($rrow['procedure_result_id'] + 0);
512 $result_code = empty($rrow['result_code']) ? $restyp_code : $rrow['result_code'];
513 $result_text = empty($rrow['result_text']) ? $restyp_name : $rrow['result_text'];
514 $result_date = empty($rrow['date']) ? '' : $rrow['date'];
515 $result_date_end = empty($rrow['date_end']) ? '' : $rrow['date_end'];
516 $result_abnormal = empty($rrow['abnormal']) ? '' : $rrow['abnormal'];
517 $result_result = empty($rrow['result']) ? '' : $rrow['result'];
518 $result_units = empty($rrow['units']) ? $restyp_units : $rrow['units'];
519 $result_facility = empty($rrow['facility']) ? '' : $rrow['facility'];
520 $result_comments = empty($rrow['comments']) ? '' : $rrow['comments'];
521 $result_range = empty($rrow['range']) ? $restyp_range : $rrow['range'];
522 $result_status = empty($rrow['result_status']) ? '' : $rrow['result_status'];
524 // If there is more than one line of comments, everything after that is "notes".
525 $result_notes = '';
526 $i = strpos($result_comments, "\n");
527 if ($i !== false) {
528 $result_notes = trim(substr($result_comments, $i + 1));
529 $result_comments = substr($result_comments, 0, $i);
532 $result_comments = trim($result_comments);
534 if ($result_facility <> "" && !in_array($result_facility, $facilities)) {
535 $facilities[] = $result_facility;
538 if ($lastpoid != $order_id || $lastpcid != $order_seq) {
539 ++$encount;
540 $lastrcn = '';
543 echo " <tr class='detail'>\n";
545 // Generate first 2 columns.
546 if ($lastpoid != $order_id || $lastpcid != $order_seq) {
547 $lastprid = -1; // force report fields on first line of each procedure
548 if ($form_batch) {
549 if ($lastpoid != $order_id) {
550 $tmp = $row['lname'];
551 if ($row['fname'] || $row['mname']) {
552 $tmp .= ', ' . $row['fname'] . ' ' . $row['mname'];
555 echo " <td>" . text($tmp) . "</td>\n";
556 echo " <td>" . text($row['pubpid']) . "</td>\n";
557 } else {
558 echo " <td colspan='2'>&nbsp;</td>";
560 } else {
561 if ($lastpoid != $order_id) {
562 echo " <td>" . text($row['date_ordered']) . "</td>\n";
563 } else {
564 echo " <td>&nbsp;</td>";
567 echo " <td>" . text($row['procedure_name']) . "</td>\n";
569 } else {
570 echo " <td colspan='2'>&nbsp;</td>";
573 // If this starts a new report or a new order, generate the report form
574 // fields. In the case of a new order with no report yet, the fields will
575 // have their blank/default values, and form_line (above) will indicate a
576 // report ID of 0.
578 // TBD: Also generate default report fields and another set of results if
579 // the previous report is marked "Preliminary".
581 if ($report_id != $lastprid) { ?>
582 <td class="text-nowrap">
583 <input type='text' size='13' name='form_date_report[<?php echo attr($lino); ?>]'
584 id='form_date_report[<?php echo attr($lino); ?>]'
585 class='form-control datetimepicker' value='<?php echo attr($date_report); ?>'
586 title='<?php echo xla('Date and time of this report'); ?>' />
587 </td>
588 <td class="text-nowrap">
589 <input type='text' size='13' name='form_date_collected[<?php echo attr($lino); ?>]'
590 id='form_date_collected[<?php echo attr($lino); ?>]'
591 class='form-control datetimepicker' value='<?php echo attr($date_collected); ?>'
592 title='<?php echo xla('Date and time of sample collection'); ?>' />
593 </td>
594 <td>
595 <input type='text' size='8' name='form_specimen_num[<?php echo attr($lino); ?>]'
596 class='form-control'
597 value='<?php echo attr($specimen_num); ?>'
598 title='<?php echo xla('Specimen number/identifier'); ?>' />
599 </td>
600 <td>
601 <?php
602 echo generate_select_list(
603 "form_report_status[$lino]",
604 'proc_rep_status',
605 $report_status,
606 xl('Report Status'),
607 ' ',
608 'form-control'
609 ); ?>
610 </td>
611 <?php } else { ?>
612 <td colspan='4'>&nbsp;</td>
613 <?php } ?>
615 <td class="text-nowrap">
616 <input type='text' size='6' name='form_result_code[<?php echo attr($lino); ?>]'
617 class='form-control'
618 value='<?php echo attr($result_code); ?>' />
619 </td>
620 <td>
621 <input type='text' size='16' name='form_result_text[<?php echo attr($lino); ?>]'
622 class='form-control'
623 value='<?php echo attr($result_text); ?>' />
624 </td>
625 <td class="text-nowrap">
626 <input type='text' size='13' name='form_result_date[<?php echo attr($lino); ?>]'
627 id='form_result_date[<?php echo attr($lino); ?>]'
628 class='form-control datetimepicker' value='<?php echo attr($result_date); ?>'
629 title='<?php echo xla('Date and time of this result'); ?>' />
630 </td>
631 <td class="text-nowrap">
632 <input type='text' size='13' name='form_result_date_end[<?php echo attr($lino); ?>]'
633 id='form_result_date_end[<?php echo attr($lino); ?>]'
634 class='form-control datetimepicker' value='<?php echo attr($result_date_end); ?>'
635 title='<?php echo xla('End date and time of this result'); ?>' />
636 </td>
637 <td>
638 <?php echo generate_select_list(
639 "form_result_abnormal[$lino]",
640 'proc_res_abnormal',
641 $result_abnormal,
642 xl('Indicates abnormality'),
643 ' ',
644 'form-control'
645 ); ?>
646 </td>
647 <td>
648 <?php if ($result_units == 'bool') {
649 echo "&nbsp;--";
650 } else { ?>
651 <input type='text' size='7' name='form_result_result[<?php echo attr($lino); ?>]'
652 class='form-control'
653 value='<?php echo attr($result_result); ?>' />
654 <?php } ?>
655 </td>
656 <td>
657 <input type='text' size='4' name='form_result_units[<?php echo attr($lino); ?>]'
658 class='form-control'
659 value='<?php echo attr($result_units); ?>'
660 title='<?php echo xla('Units applicable to the result value'); ?>' />
661 </td>
662 <td>
663 <input type='text' size='8' name='form_result_range[<?php echo attr($lino); ?>]'
664 class='form-control'
665 value='<?php echo attr($result_range); ?>'
666 title='<?php echo xla('Reference range of results'); ?>' />
667 <!-- Include a hidden form field containing all IDs for this line. -->
668 <input type='hidden' name='form_line[<?php echo attr($lino); ?>]'
669 value='<?php echo attr($order_id) . ":" . attr($order_seq) . ":" . attr($report_id) . ":" . attr($result_id); ?>' />
670 </td>
671 <td class='font-weight-bold text-center' style='cursor:pointer' onclick='extShow(<?php echo attr_js($lino); ?>, this)'
672 title='<?php echo xla('Click here to view/edit more details'); ?>'>
673 &nbsp;?&nbsp;
674 </td>
675 </tr>
676 <?php
677 // Create a floating div for additional attributes of this result.
678 $extra_html .= "<div id='ext_" . attr($lino) . "' " .
679 "style='position:absolute;width:750px;border:1px solid black;" .
680 "padding:2px;background-color:#cccccc;visibility:hidden;" .
681 "z-index:1000;left:-1000px;top:0px;font-size:9pt;'>\n" .
682 "<table class='table'>\n" .
683 "<tr><td class='font-weight-bold text-center' colspan='2' style='padding:4pt 0 4pt 0'>" .
684 text($result_text) .
685 "</td></tr>\n" .
686 "<tr><td class='text-nowrap'>" . xlt('Status') . ": </td>" .
687 "<td>" . generate_select_list(
688 "form_result_status[$lino]",
689 'proc_res_status',
690 $result_status,
691 xl('Result Status'),
693 ) . "</td></tr>\n" .
694 "<tr><td class='font-weight-bold text-nowrap'>" . xlt('Facility') . ": </td>" . // Ensoftek: Changed Facility to Text Area as the field procedure_result-->facility is now multi-line
695 "<td><textarea class='form-control' rows='3' cols='15' name='form_facility[" . attr($lino) . "]'" .
696 " title='" . xla('Supplier facility name') . "'" .
697 " />" . text($result_facility) .
698 "</textarea></td></tr>\n" .
699 "<tr><td class='font-weight-bold text-nowrap'>" . xlt('Comments') . ": </td>" .
700 "<td><textarea class='form-control' rows='3' cols='15' name='form_comments[" . attr($lino) . "]'" .
701 " title='" . xla('Comments for this result or recommendation') . "'" .
702 " />" . text($result_comments) .
703 "</textarea></td></tr>\n" .
704 "<tr><td class='font-weight-bold text-nowrap'>" . xlt('Notes') . ": </td>" .
705 "<td><textarea class='form-control' rows='4' cols='15' name='form_notes[" . attr($lino) . "]'" .
706 " title='" . xla('Additional notes for this result or recommendation') . "'" .
707 " />" . text($result_notes) .
708 "</textarea></td></tr>\n" .
709 "</table>\n" .
710 "<p class='text-center'><input class='btn btn-primary' type='button' value='" . xla('Close') . "' " .
711 "onclick='extShow(" . attr_js($lino) . ", false)' /></p>\n" .
712 "</div>";
714 $lastpoid = $order_id;
715 $lastpcid = $order_seq;
716 $lastprid = $report_id;
717 ++$lino;
721 if (!empty($facilities)) {
722 // display facility information
723 $extra_html .= "<table class='table'>";
724 $extra_html .= "<tr><th>" . xlt('Performing Laboratory Facility') . "</th></tr>";
725 foreach ($facilities as $facilityID) {
726 foreach (explode(":", $facilityID) as $lab_facility) {
727 $facility_array = getFacilityInfo($lab_facility);
728 if ($facility_array) {
729 $extra_html .=
730 "<tr><td><hr></td></tr>" .
731 "<tr><td>" . text($facility_array['fname']) . " " . text($facility_array['lname']) . ", " . text($facility_array['title']) . "</td></tr>" .
732 "<tr><td>" . text($facility_array['organization']) . "</td></tr>" .
733 "<tr><td>" . text($facility_array['street']) . " " . text($facility_array['city']) . " " . text($facility_array['state']) . "</td></tr>" .
734 "<tr><td>" . text(formatPhone($facility_array['phone'])) . "</td></tr>";
738 $extra_html .= "</table>\n";
742 </table>
743 <div class="col-12 text-center mt-3">
744 <?php
745 if ($form_review) {
746 // if user authorized for pending review.
747 if ($reviewauth) { ?>
748 <button type="submit" class="btn btn-primary" name='form_submit' value='<?php echo xla('Sign Results'); ?>'>
749 <?php echo xlt('Sign Results'); ?>
750 </button>
751 <?php } else { ?>
752 <button type="button" class="btn btn-primary" name='form_submit' value='<?php echo xla('Sign Results'); ?>' onclick="alert(<?php echo attr_js(xl('Not authorized')) ?>);">
753 <?php echo xlt('Sign Results'); ?>
754 </button>
755 <?php }
756 } else { ?>
757 <button type="submit" class="btn btn-primary btn-save" name='form_submit' value='<?php echo xla('Save'); ?>'>
758 <?php echo xlt('Save'); ?>
759 </button>
760 <?php } ?>
761 <?php } ?>
762 </div>
763 <?php echo ($extra_html ?? ''); ?>
764 </form>
765 </div>
766 </body>
767 </html>