3 * Copyright (C) 2017 Brady Miller <brady.g.miller@gmail.com>
5 * LICENSE: This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 3
8 * of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
17 * @author Brady Miller <brady.g.miller@gmail.com>
18 * @link http://www.open-emr.org
21 include_once("../globals.php");
22 include_once("$srcdir/log.inc");
23 require_once("$srcdir/formatting.inc.php");
27 <?php
html_header_show();?
>
29 <link rel
="stylesheet" href
="<?php echo $css_header;?>" type
="text/css">
30 <link rel
="stylesheet" href
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-datetimepicker-2-5-4/build/jquery.datetimepicker.min.css">
38 border
-collapse
: collapse
;
41 background
-color
: #cccccc;
42 cursor
: pointer
; cursor
: hand
;
49 background
-color
: #ffffff;
50 border
-bottom
: 1px solid
#808080;
56 background
-color
: #336699;
61 <script type
="text/javascript" src
="<?php echo $GLOBALS['webroot'] ?>/library/dialog.js?v=<?php echo $v_js_includes; ?>"></script
>
62 <script type
="text/javascript" src
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-min-3-1-1/index.js"></script
>
63 <script type
="text/javascript" src
="<?php echo $GLOBALS['assets_static_relative']; ?>/jquery-datetimepicker-2-5-4/build/jquery.datetimepicker.full.min.js"></script
>
66 //function to disable the event type field if the event name is disclosure
67 function eventTypeChange(eventname
)
69 if (eventname
== "disclosure") {
70 document
.theform
.type_event
.disabled
= true;
73 document
.theform
.type_event
.disabled
= false;
77 // VicarePlus :: This invokes the find-patient popup.
78 function sel_patient() {
79 dlgopen('../main/calendar/find_patient_popup.php?pflag=0', '_blank', 500, 400);
82 // VicarePlus :: This is for callback by the find-patient popup.
83 function setpatient(pid
, lname
, fname
, dob
) {
84 var f
= document
.theform
;
85 f
.form_patient
.value
= lname +
', ' + fname
;
86 f
.form_pid
.value
= pid
;
91 <body
class="body_top">
92 <font
class="title"><?php
xl('Logs Viewer','e'); ?
></font
>
96 if ($_GET["start_date"])
97 $start_date = formData('start_date','G');
99 if ($_GET["end_date"])
100 $end_date = formData('end_date','G');
102 if ($_GET["form_patient"])
103 $form_patient = formData('form_patient','G');
106 * Start date should not be greater than end date - Date Validation
108 if ($start_date && $end_date)
110 if($start_date > $end_date){
111 echo "<table><tr class='alert'><td colspan=7>"; xl('Start Date should not be greater than End Date',e
);
112 echo "</td></tr></table>";
119 $form_user = formData('form_user','R');
120 $form_pid = formData('form_pid','R');
121 if ($form_patient == '' ) $form_pid = '';
123 $res = sqlStatement("select distinct LEFT(date,10) as date from log order by date desc limit 30");
124 for($iter=0;$row=sqlFetchArray($res);$iter++
) {
128 // Get the users list.
129 $sqlQuery = "SELECT username, fname, lname FROM users " .
130 "WHERE active = 1 AND ( info IS NULL OR info NOT LIKE '%Inactive%' ) ";
132 $ures = sqlStatement($sqlQuery);
136 $get_sdate=$start_date ?
$start_date : date("Y-m-d H:i:s");
137 $get_edate=$end_date ?
$end_date : date("Y-m-d H:i:s");
142 <FORM METHOD
="GET" name
="theform" id
="theform">
145 $sortby = formData('sortby','G') ;
146 $direction = formData('direction','G') ;
148 <input type
="hidden" name
="direction" id
="direction" value
="<?php echo !empty($direction) ? $direction : 'asc'; ?>">
149 <input type
="hidden" name
="sortby" id
="sortby" value
="<?php echo $sortby; ?>">
150 <input type
=hidden name
=csum value
="">
153 <span
class="text"><?php
xl('Start Date','e'); ?
>: </span
>
155 <input
class="datetimepicker" type
="text" size
="18" name
="start_date" id
="start_date" value
="<?php echo $start_date ? $start_date : (date("Y
-m
-d
") . " 00:00:00"); ?>" title
="<?php xl('yyyy-mm-dd H:m Start Date','e'); ?>" />
158 <span
class="text"><?php
xl('End Date','e'); ?
>: </span
>
160 <input
class="datetimepicker" type
="text" size
="18" name
="end_date" id
="end_date" value
="<?php echo $end_date ? $end_date : (date("Y
-m
-d
") . " 23:59:00"); ?>" title
="<?php xl('yyyy-mm-dd H:m End Date','e'); ?>" />
162 <!--VicarePlus
:: Feature
For Generating Log
For The Selected Patient
--!>
164  
; 
;<span
class='text'><?php
echo htmlspecialchars(xl('Patient'),ENT_NOQUOTES
); ?
>: </span
>
167 <input type
='text' size
='20' name
='form_patient' style
='width:100%;cursor:pointer;cursor:hand' value
='<?php echo $form_patient ? $form_patient : htmlspecialchars(xl('Click To Select
'),ENT_QUOTES); ?>' onclick
='sel_patient()' title
='<?php echo htmlspecialchars(xl('Click to select patient
'),ENT_QUOTES); ?>' />
168 <input type
='hidden' name
='form_pid' value
='<?php echo $form_pid; ?>' />
172 <span
class='text'><?php
xl('User','e'); ?
>: </span
>
176 echo "<select name='form_user'>\n";
177 echo " <option value=''>" . xl('All') . "</option>\n";
178 while ($urow = sqlFetchArray($ures)) {
179 if (!trim($urow['username'])) continue;
180 echo " <option value='" . $urow['username'] . "'";
181 if ($urow['username'] == $form_user) echo " selected";
182 echo ">" . $urow['lname'];
183 if ($urow['fname']) echo ", " . $urow['fname'];
190 <!-- list of events name
-->
191 <span
class='text'><?php
xl('Name of Events','e'); ?
>: </span
>
195 $res = sqlStatement("select distinct event from log order by event ASC");
196 $ename_list=array(); $j=0;
197 while ($erow = sqlFetchArray($res)) {
198 if (!trim($erow['event'])) continue;
199 $data = explode('-', $erow['event']);
200 $data_c = count($data);
202 for($i=1;$i<($data_c-1);$i++
)
204 $ename.="-".$data[$i];
206 $ename_list[$j]=$ename;
209 $res1 = sqlStatement("select distinct event from extended_log order by event ASC");
210 // $j=0; // This can't be right! -- Rod 2013-08-23
211 while ($row = sqlFetchArray($res1)) {
212 if (!trim($row['event'])) continue;
213 $new_event = explode('-', $row['event']);
214 $no = count($new_event);
215 $events=$new_event[0];
216 for($i=1;$i<($no-1);$i++
)
218 $events.="-".$new_event[$i];
220 if ($events=="disclosure")
221 $ename_list[$j]=$events;
224 $ename_list=array_unique($ename_list);
225 $ename_list=array_merge($ename_list);
226 $ecount=count($ename_list);
227 echo "<select name='eventname' onchange='eventTypeChange(this.options[this.selectedIndex].value);'>\n";
228 echo " <option value=''>" . xl('All') . "</option>\n";
229 for($k=0;$k<$ecount;$k++
) {
230 echo " <option value='" .$ename_list[$k]. "'";
231 if ($ename_list[$k] == $eventname && $ename_list[$k]!= "") echo " selected";
232 echo ">" . $ename_list[$k];
238 <!-- type of events ends
-->
240  
; 
;<span
class='text'><?php
xl('Type of Events','e'); ?
>: </span
>
243 $event_types=array("select", "update", "insert", "delete", "replace");
244 $lcount=count($event_types);
245 if($eventname=="disclosure"){
246 echo "<select name='type_event' disabled='disabled'>\n";
247 echo " <option value=''>" . xl('All') . "</option>\n";
251 echo "<select name='type_event'>\n";}
252 echo " <option value=''>" . xl('All') . "</option>\n";
253 for($k=0;$k<$lcount;$k++
) {
254 echo " <option value='" .$event_types[$k]. "'";
255 if ($event_types[$k] == $type_event && $event_types[$k]!= "") echo " selected";
256 echo ">" . preg_replace('/^select$/','Query',$event_types[$k]); // Convert select to Query for MU2 requirement
263 <span
class='text'><?php
xl('Include Checksum','e'); ?
>: </span
>
267 $check_sum = formData('check_sum','G');
269 <input type
="checkbox" name
="check_sum" " <?php if ($check_sum == 'on') echo "checked
"; ?>"></input
>
272 <input type
=hidden name
="event" value
=<?php
echo $event ; ?
>>
273 <a href
="javascript:document.theform.submit();" class='link_submit'>[<?php
xl('Refresh','e'); ?
>]</a
>
276 <div id
='valid_button'>
277 <input type
=button id
='validate_log' onclick
='validatelog();' value
='<?php echo xla('Validate Log
'); ?>'></input
>
279 <div id
='log_loading' style
="display: none">
280 <img src
='../../images/loading.gif'/>
288 <?php
if ($start_date && $end_date && $err_message!=1) { ?
>
292 <!-- <TH
><?php
xl('Date', 'e'); ?
><TD
> -->
293 <th id
="sortby_date" class="text sortby" title
="<?php xl('Sort by date/time','e'); ?>"><?php
xl('Date','e'); ?
></th
>
294 <th id
="sortby_event" class="text sortby" title
="<?php xl('Sort by Event','e'); ?>"><?php
xl('Event','e'); ?
></th
>
295 <th id
="sortby_category" class="text sortby" title
="<?php xl('Sort by Category','e'); ?>"><?php
xl('Category','e'); ?
></th
>
296 <th id
="sortby_user" class="text sortby" title
="<?php xl('Sort by User','e'); ?>"><?php
xl('User','e'); ?
></th
>
297 <th id
="sortby_cuser" class="text sortby" title
="<?php xl('Sort by Crt User','e'); ?>"><?php
xl('Certificate User','e'); ?
></th
>
298 <th id
="sortby_group" class="text sortby" title
="<?php xl('Sort by Group','e'); ?>"><?php
xl('Group','e'); ?
></th
>
299 <th id
="sortby_pid" class="text sortby" title
="<?php xl('Sort by PatientID','e'); ?>"><?php
xl('PatientID','e'); ?
></th
>
300 <th id
="sortby_success" class="text sortby" title
="<?php xl('Sort by Success','e'); ?>"><?php
xl('Success','e'); ?
></th
>
301 <th id
="sortby_comments" class="text sortby" title
="<?php xl('Sort by Comments','e'); ?>"><?php
xl('Comments','e'); ?
></th
>
302 <?php
if($check_sum) {?
>
303 <th id
="sortby_checksum" class="text sortby" title
="<?php xl('Sort by Checksum','e'); ?>"><?php
xl('Checksum','e'); ?
></th
>
308 $eventname = formData('eventname','G');
309 $type_event = formData('type_event','G');
311 <input type
=hidden name
=event value
=<?php
echo $eventname."-".$type_event ?
>>
315 if($eventname != "" && $type_event != "")
317 $getevent=$eventname."-".$type_event;
320 if(($eventname == "") && ($type_event != ""))
321 { $tevent=$type_event;
323 else if($type_event =="" && $eventname != "")
325 else if ($eventname == "")
330 if ($ret = getEvents(array('sdate' => $get_sdate,'edate' => $get_edate, 'user' => $form_user, 'patient' => $form_pid, 'sortby' => $_GET['sortby'], 'levent' =>$gev, 'tevent' =>$tevent,'direction' => $_GET['direction']))) {
333 foreach ($ret as $iter) {
335 $patterns = array ('/^success/','/^failure/','/ encounter/');
336 $replace = array ( xl('success'), xl('failure'), xl('encounter','',' '));
338 $log_id = $iter['id'];
339 $commentEncrStatus = "No";
340 $logEncryptData = logCommentEncryptData($log_id);
341 if(count($logEncryptData) > 0){
342 $commentEncrStatus = $logEncryptData['encrypt'];
345 //July 1, 2014: Ensoftek: Decrypt comment data if encrypted
346 if($commentEncrStatus == "Yes"){
347 $trans_comments = preg_replace($patterns, $replace, aes256Decrypt($iter["comments"]));
349 $trans_comments = preg_replace($patterns, $replace, $iter["comments"]);
353 <TR
class="oneresult">
354 <TD
class="text"><?php
echo oeFormatShortDate(substr($iter["date"], 0, 10)) . substr($iter["date"], 10) ?
></TD
>
355 <TD
class="text"><?php
echo preg_replace('/select$/','Query',$iter["event"]); //Convert select term to Query for MU2 requirements ?></TD>
356 <TD
class="text"><?php
echo $iter["category"]?
></TD
>
357 <TD
class="text"><?php
echo $iter["user"]?
></TD
>
358 <TD
class="text"><?php
echo $iter["crt_user"]?
></TD
>
359 <TD
class="text"><?php
echo $iter["groupname"]?
></TD
>
360 <TD
class="text"><?php
echo $iter["patient_id"]?
></TD
>
361 <TD
class="text"><?php
echo $iter["success"]?
></TD
>
362 <TD
class="text"><?php
echo nl2br(text(preg_replace('/^select/i','Query',$trans_comments))); //Convert select term to Query for MU2 requirements ?></TD>
363 <?php
if($check_sum) { ?
>
364 <TD
class="text"><?php
echo $iter["checksum"]?
></TD
>
372 if (($eventname=="disclosure") ||
($gev == ""))
374 $eventname="disclosure";
375 if ($ret = getEvents(array('sdate' => $get_sdate,'edate' => $get_edate, 'user' => $form_user, 'patient' => $form_pid, 'sortby' => $_GET['sortby'], 'event' =>$eventname))) {
376 foreach ($ret as $iter) {
377 $comments=xl('Recipient Name').":".$iter["recipient"].";".xl('Disclosure Info').":".$iter["description"];
379 <TR
class="oneresult">
380 <TD
class="text"><?php
echo htmlspecialchars(oeFormatShortDate(substr($iter["date"], 0, 10)) . substr($iter["date"], 10),ENT_NOQUOTES
); ?
></TD
>
381 <TD
class="text"><?php
echo htmlspecialchars(xl($iter["event"]),ENT_NOQUOTES
);?
></TD
>
382 <TD
class="text"><?php
echo htmlspecialchars(xl($iter["category"]),ENT_NOQUOTES
);?
></TD
>
383 <TD
class="text"><?php
echo htmlspecialchars($iter["user"],ENT_NOQUOTES
);?
></TD
>
384 <TD
class="text"><?php
echo htmlspecialchars($iter["crt_user"],ENT_NOQUOTES
);?
></TD
>
385 <TD
class="text"><?php
echo htmlspecialchars($iter["groupname"],ENT_NOQUOTES
);?
></TD
>
386 <TD
class="text"><?php
echo htmlspecialchars($iter["patient_id"],ENT_NOQUOTES
);?
></TD
>
387 <TD
class="text"><?php
echo htmlspecialchars($iter["success"],ENT_NOQUOTES
);?
></TD
>
388 <TD
class="text"><?php
echo htmlspecialchars($comments,ENT_NOQUOTES
);?
></TD
>
389 <?php
if($check_sum) { ?
>
390 <TD
class="text"><?php
echo htmlspecialchars($iter["checksum"],ENT_NOQUOTES
);?
></TD
>
405 <script language
="javascript">
407 // jQuery stuff to make the page a little easier to use
408 $
(document
).ready(function(){
409 // funny thing here... good learning experience
410 // the TR has TD children which have their own background and text color
411 // toggling the TR color doesn't change the TD color
412 // so we need to change all the TR's children (the TD's) just as we did the TR
413 // thus we have two calls to toggleClass:
414 // 1 - for the parent (the TR)
415 // 2 - for each of the children (the TDs)
416 $
(".oneresult").mouseover(function() { $
(this
).toggleClass("highlight"); $
(this
).children().toggleClass("highlight"); });
417 $
(".oneresult").mouseout(function() { $
(this
).toggleClass("highlight"); $
(this
).children().toggleClass("highlight"); });
419 // click-able column headers to sort the list
421 $
("#sortby_date").click(function() { set_sort_direction(); $
("#sortby").val("date"); $
("#theform").submit(); });
422 $
("#sortby_event").click(function() { set_sort_direction(); $
("#sortby").val("event"); $
("#theform").submit(); });
423 $
("#sortby_category").click(function() { set_sort_direction(); $
("#sortby").val("category"); $
("#theform").submit(); });
424 $
("#sortby_user").click(function() { set_sort_direction(); $
("#sortby").val("user"); $
("#theform").submit(); });
425 $
("#sortby_cuser").click(function() { set_sort_direction(); $
("#sortby").val("user"); $
("#theform").submit(); });
426 $
("#sortby_group").click(function() { set_sort_direction(); $
("#sortby").val("groupname"); $
("#theform").submit(); });
427 $
("#sortby_pid").click(function() { set_sort_direction(); $
("#sortby").val("patient_id"); $
("#theform").submit(); });
428 $
("#sortby_success").click(function() { set_sort_direction(); $
("#sortby").val("success"); $
("#theform").submit(); });
429 $
("#sortby_comments").click(function() { set_sort_direction(); $
("#sortby").val("comments"); $
("#theform").submit(); });
430 $
("#sortby_checksum").click(function() { set_sort_direction(); $
("#sortby").val("checksum"); $
("#theform").submit(); });
432 $
('.datetimepicker').datetimepicker({
433 <?php
$datetimepicker_timepicker = true; ?
>
434 <?php
$datetimepicker_formatInput = false; ?
>
435 <?php
require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?
>
436 <?php
// can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
440 function set_sort_direction(){
441 if($
('#direction').val() == 'asc')
442 $
('#direction').val('desc');
444 $
('#direction').val('asc');
447 function validatelog(){
448 var img
= document
.getElementById('log_loading');
449 var btn
= document
.getElementById('valid_button');
451 if(img
.style
.display
== "block"){
454 img
.style
.display
= "block";
455 if(btn
){btn
.style
.display
= "none"}
458 url
:"../../library/log_validation.php",
461 success
:function(response
){
463 img
.style
.display
="none";
464 if(btn
){btn
.style
.display
="block";}
470 img
.style
.display
="none";
471 if(btn
){btn
.style
.display
="block";}
473 alert('<?php echo xls("Audit Log Validation Failed"); ?>');