4 * Message and Reminder Center UI
7 * @link http://www.open-emr.org
8 * @author OpenEMR Support LLC
9 * @author Roberto Vasquez <robertogagliotta@gmail.com>
10 * @author Rod Roark <rod@sunsetsystems.com>
11 * @author Brady Miller <brady.g.miller@gmail.com>
12 * @author Ray Magauran <magauran@medfetch.com>
13 * @author Tyler Wrenn <tyler@tylerwrenn.com>
14 * @copyright Copyright (c) 2010 OpenEMR Support LLC
15 * @copyright Copyright (c) 2017 MedEXBank.com
16 * @copyright Copyright (c) 2018-2019 Brady Miller <brady.g.miller@gmail.com>
17 * @copyright Copyright (c) 2020 Tyler Wrenn <tyler@tylerwrenn.com>
18 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
21 require_once("../../globals.php");
22 require_once("$srcdir/pnotes.inc");
23 require_once("$srcdir/patient.inc");
24 require_once("$srcdir/options.inc.php");
25 require_once("$srcdir/gprelations.inc.php");
26 require_once "$srcdir/user.inc";
27 require_once("$srcdir/MedEx/API.php");
29 use OpenEMR\Common\Acl\AclMain
;
30 use OpenEMR\Common\Csrf\CsrfUtils
;
31 use OpenEMR\Common\Logging\EventAuditLogger
;
32 use OpenEMR\Core\Header
;
33 use OpenEMR\OeUI\OemrUI
;
35 //Gets validation rules from Page Validation list.
36 $collectthis = collectValidationPageRules("/interface/main/messages/messages.php");
37 if (empty($collectthis)) {
40 $collectthis = json_sanitize($collectthis[array_keys($collectthis)[0]]["rules"]);
43 $MedEx = new MedExApi\
MedEx('MedExBank.com');
45 if ($GLOBALS['medex_enable'] == '1') {
46 if ($_REQUEST['SMS_bot']) {
47 $result = $MedEx->login('');
48 $MedEx->display
->SMS_bot($result);
51 $logged_in = $MedEx->login();
56 $setting_bootstrap_submenu = prevSetting('', 'setting_bootstrap_submenu', 'setting_bootstrap_submenu', ' ');
57 //use $uspfx as the first variable for page/script specific user settings instead of '' (which is like a global but you have to request it).
58 $uspfx = substr(__FILE__
, strlen($webserver_root)) . '.';
59 $rcb_selectors = prevSetting($uspfx, 'rcb_selectors', 'rcb_selectors', 'block');
60 $rcb_facility = prevSetting($uspfx, 'form_facility', 'form_facility', '');
61 $rcb_provider = prevSetting($uspfx, 'form_provider', 'form_provider', $_SESSION['authUserID']);
64 (array_key_exists('setting_bootstrap_submenu', $_POST)) ||
65 (array_key_exists('rcb_selectors', $_POST))
67 // These are not form elements. We only ever change them via ajax, so exit now.
77 require_once($GLOBALS['srcdir'] . "/validation/validation_script.js.php");
79 <meta charset
="utf-8" />
80 <meta http
-equiv
="X-UA-Compatible" content
="IE=edge" />
81 <meta name
="description" content
="MedEx Bank" />
82 <meta name
="author" content
="OpenEMR: MedExBank" />
83 <?php Header
::setupHeader(['datetime-picker', 'opener', 'moment', 'select2']); ?
>
84 <link rel
="stylesheet" href
="<?php echo $webroot; ?>/interface/main/messages/css/reminder_style.css?v=<?php echo $v_js_includes; ?>">
87 var xljs1
= '<?php echo xla('Preferences updated successfully
'); ?>';
88 var format_date_moment_js
= '<?php echo attr(DateFormatRead("validateJS")); ?>';
89 <?php
require_once "$srcdir/restoreSession.php"; ?
>
92 <script src
="<?php echo $GLOBALS['web_root']; ?>/interface/main/messages/js/reminder_appts.js?v=<?php echo $v_js_includes; ?>"></script
>
94 @media only screen
and (max
-width
: 768px
) {
97 text
-align
: left
!important
;
101 background
-color
: var(--danger
);
107 if (($GLOBALS['medex_enable'] == '1') && (empty($_REQUEST['nomenu'])) && ($GLOBALS['disable_rcb'] != '1')) {
108 $MedEx->display
->navigation($logged_in);
109 echo "<br /><br /><br />";
112 if (!empty($_REQUEST['go'])) { ?
>
114 if (($_REQUEST['go'] == "setup") && (!$logged_in)) {
115 echo "<title>" . xlt('MedEx Setup') . "</title>";
116 $stage = $_REQUEST['stage'];
117 if (!is_numeric($stage)) {
118 echo "<br /><span class='title'>$stage " . xlt('Warning') . ": " . xlt('This is not a valid request') . ".</span>";
120 $MedEx->setup
->MedExBank($stage);
122 } elseif ($_REQUEST['go'] == "addRecall") {
123 echo "<title>" . xlt('New Recall') . "</title>";
124 $MedEx->display
->display_add_recall();
125 } elseif ($_REQUEST['go'] == 'Recalls') {
126 echo "<title>" . xlt('Recall Board') . "</title>";
127 $MedEx->display
->display_recalls($logged_in);
128 } elseif ((($_REQUEST['go'] == "setup") ||
($_REQUEST['go'] == 'Preferences')) && ($logged_in)) {
129 echo "<title>MedEx: " . xlt('Preferences') . "</title>";
130 $MedEx->display
->preferences();
131 } elseif ($_REQUEST['go'] == 'icons') {
132 echo "<title>MedEx: " . xlt('Icons') . "Ⓒ</title>";
133 $MedEx->display
->icon_template();
134 } elseif ($_REQUEST['go'] == 'SMS_bot') {
135 echo "<title>MedEx: SMS BotⒸ</title>";
136 $MedEx->display
->SMS_bot($logged_in);
139 echo "<title>" . xlt('MedEx Setup') . "</title>";
140 echo xlt('Warning: Navigation error. Please refresh this page.');
143 //original message.php stuff
145 if ($GLOBALS['enable_help'] == 1) {
146 $help_icon = '<a class="float-right oe-help-redirect" data-target="#myModal" data-toggle="modal" href="#" id="help-href" name="help-href" style="color: var(--gray)" title="' . xla("Click to view Help") . '"><i class="fa fa-question-circle" aria-hidden="true"></i></a>';
147 } elseif ($GLOBALS['enable_help'] == 2) {
148 $help_icon = '<a class="float-right oe-help-redirect" data-target="#myModal" data-toggle="modal" href="#" id="help-href" name="help-href" style="color: var(--gray300) !important" title="' . xla("To enable help - Go to Administration > Globals > Features > Enable Help Modal") . '"><i class="fa fa-question-circle" aria-hidden="true"></i></a>';
149 } elseif ($GLOBALS['enable_help'] == 0) {
152 $heading_caption = xlt('Messages') . ', ' . xlt('Reminders');
153 if ($GLOBALS['disable_rcb'] != '1') {
154 $heading_caption .= ', ' . xlt('Recalls');
157 $arrOeUiSettings = array(
158 'heading_title' => $heading_caption,
159 'include_patient_name' => false,// use only in appropriate pages
160 'expandable' => false,
161 'expandable_files' => array(""),//all file names need suffix _xpd
162 'action' => "",//conceal, reveal, search, reset, link or back
163 'action_title' => "",
164 'action_href' => "",//only for actions - reset, link or back
165 'show_help_icon' => true,
166 'help_file_name' => "message_center_help.php"
168 $oemr_ui = new OemrUI($arrOeUiSettings);
170 echo "<title>" . xlt('Message Center') . "</title>";
173 <body
class='body_top'>
174 <div id
="container_div" class="<?php echo attr($oemr_ui->oeContainer()); ?>">
176 <div
class="col-sm-12">
177 <div
class="clearfix">
178 <?php
echo $oemr_ui->pageHeading() . "\r\n"; ?
>
182 <div
class="container-fluid mb-3">
183 <ul
class="nav nav-pills">
184 <li
class="nav-item" id
='li-mess'>
185 <a href
='#' class="active nav-link font-weight-bold" id
='messages-li'><?php
echo xlt('Messages'); ?
></a
>
187 <li
class="nav-item" id
='li-remi'>
188 <a href
='#' id
='reminders-li' class="nav-link font-weight-bold"><?php
echo xlt('Reminders'); ?
></a
>
190 <?php
if ($GLOBALS['disable_rcb'] != '1') { ?
>
191 <li
class="nav-item" id
='li-reca'>
192 <a href
='#' id
='recalls-li' class="nav-link font-weight-bold"><?php
echo xlt('Recalls'); ?
></a
>
195 <?php
if ($logged_in) { ?
>
196 <li
class="nav-item" id
='li-sms'>
197 <a href
='#' id
='sms-li' class="nav-link font-weight-bold"><?php
echo xlt('SMS Zone'); ?
></a
>
202 <div
class="row" id
="messages-div">
203 <div
class="col-sm-12">
204 <div
class="jumbotron jumbotron-fluid py-3">
205 <div
class="col-sm-12 col-md-12 col-lg-12">
207 // Check to see if the user has Admin rights, and if so, allow access to See All.
208 $showall = isset($_GET['show_all']) ?
$_GET['show_all'] : "";
209 if ($showall == "yes") {
210 $show_all = $showall;
214 // Collect active variable and applicable html code for links
215 $form_active = (isset($_REQUEST['form_active']) ?
$_REQUEST['form_active'] : false);
216 $form_inactive = (isset($_REQUEST['form_inactive']) ?
$_REQUEST['form_inactive'] : false);
219 $activity_string_html = 'form_active=1';
220 } elseif ($form_inactive) {
222 $activity_string_html = 'form_inactive=1';
225 $activity_string_html = '';
227 //collect the task setting
228 $task = isset($_REQUEST['task']) ?
$_REQUEST['task'] : "";
229 if (AclMain
::aclCheckCore('admin', 'super')) {
230 if ($show_all == 'yes') {
232 $lnkvar = "messages.php?show_all=no&" . $activity_string_html;
233 $lnkattributes = "name='Just Mine' onclick='top.restoreSession()'";
234 $otherstuff = "<i id='just-mine-tooltip' class='fa fa-user fa-lg text-body' aria-hidden='true'></i>";
235 $messages = xl('All Messages');
238 $lnkvar = "messages.php?show_all=yes&" . $activity_string_html;
239 $lnkattributes = "name='See All' onclick='top.restoreSession()'";
240 $otherstuff = "<i id='see-all-tooltip' class='fa fa-users fa-lg text-body' aria-hidden='true'></i>";
241 $messages = xl('My Messages');
244 $messages = xlt('My Messages');
247 <div
class="oe-margin-b-20">
248 <span
class="title"><?php
echo text($messages); ?
></span
>
249 <a
class='more' href
="<?php echo $lnkvar ?? ''; ?>" <?php
echo $lnkattributes ??
''; ?
>><?php
echo $otherstuff ??
''; ?
></a
>
251 <div
class="oe-margin-b-10">
253 //show the activity links
254 if (empty($task) ||
$task == "add" ||
$task == "delete") { ?
>
255 <?php
if ($active == "all") { ?
>
256 <span
class="font-weight-bold"><?php
echo xlt('All Messages'); ?
></span
>
258 <a href
="messages.php" class="link btn btn-secondary" onclick
="top.restoreSession()"><?php
echo xlt('Show All'); ?
></a
>
261 <?php
if ($active == '1') { ?
>
262 <span
class="font-weight-bold"><?php
echo xlt('Active Messages'); ?
></span
>
264 <a href
="messages.php?form_active=1" class="link btn btn-secondary" onclick
="top.restoreSession()"><?php
echo xlt('Show Active'); ?
></a
>
267 <?php
if ($active == '0') { ?
>
268 <span
class="font-weight-bold"><?php
echo xlt('Inactive Messages'); ?
></span
>
270 <a href
="messages.php?form_inactive=1" class="link btn btn-secondary" onclick
="top.restoreSession()"><?php
echo xlt('Show Inactive'); ?
></a
>
278 $form_message_status = '';
283 // Add a new message for a specific patient; the message is documented in Patient Notes.
284 // Add a new message; it's treated as a new note in Patient Notes.
285 $note = $_POST['note'];
286 $noteid = $_POST['noteid'];
287 $form_note_type = $_POST['form_note_type'];
288 $form_message_status = $_POST['form_message_status'];
289 $reply_to = explode(';', rtrim($_POST['reply_to'], ';'));
290 $assigned_to_list = explode(';', $_POST['assigned_to']);
291 $datetime = isset($_POST['form_datetime']) ?
DateTimeToYYYYMMDDHHMMSS($_POST['form_datetime']) : '';
292 foreach ($assigned_to_list as $assigned_to) {
293 if ($noteid && $assigned_to != '-patient-') {
294 updatePnote($noteid, $note, $form_note_type, $assigned_to, $form_message_status, $datetime);
297 if ($noteid && $assigned_to == '-patient-') {
298 // When $assigned_to == '-patient-' we don't update the current note, but
299 // instead create a new one with the current note's body prepended and
300 // attributed to the patient. This seems to be all for the patient portal.
301 $row = getPnoteById($noteid);
303 die("getPnoteById() did not find id '" . text($noteid) . "'");
305 $pres = sqlQuery("SELECT lname, fname " .
306 "FROM patient_data WHERE pid = ?", array($reply_to[0]));
307 $patientname = $pres['lname'] . ", " . $pres['fname'];
308 $note .= "\n\n$patientname on " . $row['date'] . " wrote:\n\n";
309 $note .= $row['body'];
311 // There's no note ID, and/or it's assigned to the patient.
312 // In these cases a new note is created.
313 foreach ($reply_to as $patient) {
314 addPnote($patient, $note, $userauthorized, '1', $form_note_type, $assigned_to, $datetime, $form_message_status);
322 $noteid = $_POST['noteid'];
323 $form_message_status = $_POST['form_message_status'];
324 $reply_to = $_POST['reply_to'];
325 if ($task == "save") {
326 updatePnoteMessageStatus($noteid, $form_message_status);
328 updatePnotePatient($noteid, $reply_to);
331 $note = $_POST['note'];
332 $title = $_POST['form_note_type'];
333 $reply_to = $_POST['reply_to'];
337 $noteid = $_GET['noteid'];
339 // Update the message if it already exists; it's appended to an existing note in Patient Notes.
340 $result = getPnoteById($noteid);
343 $title = $result['title'];
345 $body = $result['body'];
346 // if our reply-to is 0 it breaks multi patient select and other functionality
347 // this most likely didn't break before due to php implicit type conversion of 0 to ""
348 if ($reply_to == "" && $result['pid'] != 0) {
349 $reply_to = $result['pid'];
351 $form_message_status = $result['message_status'];
352 $datetime = $result['date'];
356 // Delete selected message(s) from the Messages box (only).
357 $delete_id = $_POST['delete_id'];
358 for ($i = 0; $i < count($delete_id); $i++
) {
359 deletePnote($delete_id[$i]);
360 EventAuditLogger
::instance()->newEvent("delete", $_SESSION['authUser'], $_SESSION['authProvider'], 1, "pnotes: id " . $delete_id[$i]);
364 // This is for sorting the records.
365 $sort = array("users.lname", "patient_data.lname", "pnotes.title", "pnotes.date", "pnotes.message_status");
366 $sortby = (isset($_REQUEST['sortby']) && ($_REQUEST['sortby'] != "")) ?
$_REQUEST['sortby'] : $sort[3];
367 $sortorder = (isset($_REQUEST['sortorder']) && ($_REQUEST['sortorder'] != "")) ?
$_REQUEST['sortorder'] : "desc";
368 $begin = isset($_REQUEST['begin']) ?
$_REQUEST['begin'] : 0;
370 if ($task == "addnew" or $task == "edit") {
371 // Display the Messages page layout.
372 echo "<form name='form_patient' id='new_note'
373 class='form-horizontal'
374 action=\"messages.php?showall=" . attr_url($showall) . "&sortby=" . attr_url($sortby) . "&sortorder=" . attr_url($sortorder) . "&begin=" . attr_url($begin) . "&$activity_string_html\"
376 <input type='hidden' name='noteid' id='noteid' value='" . attr($noteid) . "' />
377 <input type='hidden' name='task' id='task' value='add' />";
378 if ($task == "addnew") {
379 $message_legend = xl('Create New Message');
380 $onclick = "onclick=multi_sel_patient()";
381 } elseif ($task == "edit") {
382 $message_legend = xl('Add To Existing Message');
387 <div
class='col-md-12'>
388 <div
class="jumbotron jumbotron-fluid py-3">
389 <h4
><?php
echo text($message_legend); ?
></h4
>
391 <div
class="col-12 oe-custom-line">
393 <div
class="col-6 col-md-3">
394 <label
for="form_note_type"><?php
echo xlt('Type'); ?
>:</label
>
397 $title = "Unassigned";
399 // Added 6/2009 by BM to incorporate the patient notes into the list_options listings.
400 generate_form_field(array('data_type' => 1, 'field_id' => 'note_type', 'list_id' => 'note_type', 'empty_title' => 'SKIP', 'order_by' => 'title', 'class' => 'form-control'), $title);
403 <div
class="col-6 col-md-3">
404 <label
for="form_message_status"><?php
echo xlt('Status'); ?
>:</label
>
406 if ($form_message_status == "") {
407 $form_message_status = 'New';
409 generate_form_field(array('data_type' => 1, 'field_id' => 'message_status', 'list_id' => 'message_status', 'empty_title' => 'SKIP', 'order_by' => 'title', 'class' => 'form-control'), $form_message_status); ?
>
411 <div
class="col-6 col-md-4">
413 if ($task != "addnew" && $result['pid'] != 0) { ?
>
414 <a
class="patLink" onclick
="goPid('<?php echo attr(addslashes($result['pid'])); ?>')" title
='<?php echo xla('Click me to Open Patient Dashboard
') ?>'><?php
echo xlt('Patient'); ?
>:</a
><label
for="form_patient"> 
</label
>
417 <span
class='font-weight-bold <?php echo($task == "addnew" ? "text-danger" : "") ?>'><?php
echo xlt('Patient'); ?
>:</span
></a
><label
for="form_patient"></label
>
422 $prow = sqlQuery("SELECT lname, fname,pid, pubpid, DOB " .
423 "FROM patient_data WHERE pid = ?", array($reply_to));
424 $patientname = $prow['lname'] . ", " . $prow['fname'];
426 if ($task == "addnew" ||
$result['pid'] == 0) {
427 $cursor = "oe-cursor-add";
428 $background = "oe-patient-background";
429 } elseif ($task == "edit") {
430 $cursor = "oe-cursor-stop";
434 <input type
='text' id
='form_patient' name
='form_patient' class='form-control <?php echo $cursor . " " . $background;?>' onclick
="multi_sel_patient()" placeholder
='<?php echo xla("Click to add patient"); ?>' value
='<?php echo attr($patientname); ?>' readonly
/>
435 <input type
='hidden' class="form-control" name
='reply_to' id
='reply_to' value
='<?php echo attr($reply_to); ?>'/>
437 <div
class="col-6 col-md-2 d-flex flex-wrap">
439 if ($task == "addnew" ||
$result['pid'] == 0) {
440 echo "<label class='oe-empty-label' for='clear_patients'></label>";
441 echo '<button type="button" id="clear_patients" class="btn btn-secondary btn-undo float-left flip" value="' . xla('Clear') . '">' . xlt("Clear") . '</button>';
448 <div
class="col-12 oe-custom-line">
450 <?php
if ($GLOBALS['messages_due_date']) { ?
>
451 <div
class="col-6 col-sm-2">
452 <label
for="form_note_type"><?php
echo xlt('Due date'); ?
>:</label
>
453 <?php
generate_form_field(array('data_type' => 4, 'field_id' => 'datetime', 'edit_options' => 'F'), empty($datetime) ?
date('Y-m-d H:i') : $datetime) ?
>
456 <div
class="col-6 col-sm-4 d-flex align-items-end flex-wrap">
457 <label
for="assigned_to_text"><?php
echo xlt('To{{Destination}}'); ?
>:</label
>
458 <input type
='text' name
='assigned_to_text' class='form-control oe-cursor-stop' id
='assigned_to_text' readonly
='readonly' value
='' placeholder
='<?php echo xla("SELECT Users FROM The Dropdown LIST"); ?>' />
459 <input type
='hidden' name
='assigned_to' id
='assigned_to' />
461 <div
class="col-6 col-sm-4">
462 <label
class="oe-empty-label" for="users"></label
>
463 <select name
='users' id
='users' class='form-control' onchange
='addtolist(this);'>
465 echo "<option value='--'";
466 echo ">" . xlt('Select User');
468 $ures = sqlStatement("SELECT username, fname, lname FROM users " .
469 "WHERE username != '' AND active = 1 AND " .
470 "( info IS NULL OR info NOT LIKE '%Inactive%' ) " .
471 "ORDER BY lname, fname");
472 while ($urow = sqlFetchArray($ures)) {
473 echo " <option value='" . attr($urow['username']) . "'";
474 echo ">" . text($urow['lname']);
475 if ($urow['fname']) {
476 echo ", " . text($urow['fname']);
483 <div
class="col-6 col-sm-2 d-flex align-items-end flex-wrap">
484 <label
class="oe-empty-label" for="users"></label
>
485 <button type
="button" name
="clear_user" id
="clear_user" class="btn btn-secondary btn-undo float-left flip" value
="<?php echo xla('Clear'); ?>"><?php
echo xlt('Clear'); ?
></button
>
488 <div
class='col-12 oe-margin-t-3'>
491 // Get the related document IDs if any.
493 "SELECT id1 FROM gprelations WHERE " .
494 "type1 = ? AND type2 = ? AND id2 = ?",
495 array('1', '6', $noteid)
497 if (sqlNumRows($tmp)) {
499 echo " <td class='text'><span class='font-weight-bold'>" . xlt('Linked document') . ":</span>\n";
500 while ($gprow = sqlFetchArray($tmp)) {
501 $d = new Document($gprow['id1']);
502 echo "<a href='javascript:void(0);' ";
504 // when a direct message is received we can't open the document unless its linked to a patient.
505 echo "onClick=\"previewDocument(" . attr_js($d->get_id()) . ");\">";
507 $enc_list = sqlStatement("SELECT fe.encounter,fe.date,openemr_postcalendar_categories.pc_catname FROM form_encounter AS fe " .
508 " LEFT JOIN openemr_postcalendar_categories ON fe.pc_catid=openemr_postcalendar_categories.pc_catid WHERE fe.pid = ? ORDER BY fe.date DESC", array($prow['pid']));
509 $str_dob = xl("DOB") . ":" . $prow['DOB'] . " " . xl("Age") . ":" . getPatientAge($prow['DOB']);
510 $pname = $prow['fname'] . " " . $prow['lname'];
512 echo "onClick=\"gotoReport(" . attr(addslashes($d->get_id())) . ",'" . attr(addslashes($pname)) . "'," . attr(addslashes($prow['pid'])) . "," . attr(addslashes($prow['pubpid'] ??
$prow['pid'])) . ",'" . attr(addslashes($str_dob)) . "');\">";
514 echo text($d->get_name()) . "-" . text($d->get_id());
520 // Get the related procedure order IDs if any.
522 "SELECT id1 FROM gprelations WHERE " .
523 "type1 = ? AND type2 = ? AND id2 = ?",
524 array('2', '6', $noteid)
526 if (sqlNumRows($tmp)) {
528 echo " <td class='text'><span class='font-weight-bold'>" . xlt('Linked procedure order') . ":</span>\n";
529 while ($gprow = sqlFetchArray($tmp)) {
531 echo $GLOBALS['webroot'] . "/interface/orders/single_order_results.php?orderid=";
532 echo attr_url($gprow['id1']);
533 echo "' target='_blank' onclick='top.restoreSession()'>";
534 echo text($gprow['id1']);
544 <!-- <div
class="row"> -->
549 $body = preg_replace('/(:\d{2}\s\()' . $result['pid'] . '(\sto\s)/', '${1}' . $patientname . '${2}', $body);
550 $body = preg_replace('/(\d{4}-\d{2}-\d{2} \d{2}:\d{2}\s\([^)(]+\s)(to)(\s[^)(]+\))/', '${1}' . xl('to{{Destination}}') . '${3}', $body);
551 $body = pnoteConvertLinks(nl2br(text(oeFormatPatientNote($body))));
552 echo "<div style='height: 120px; resize: vertical;' class='border overflow-auto text oe-margin-t-3 p-2 mb-2 w-100'>" . $body . "</div>";
556 <textarea name
='note' id
='note' class='form-control oe-margin-t-3 p-1' rows
="5"><?php
echo nl2br(text($note)); ?
></textarea
>
558 <div
class="col-12 position-override oe-margin-t-10">
559 <?php
if ($noteid) { ?
>
560 <!-- This is
for displaying an existing note
. -->
561 <button type
="button" class="btn btn-primary btn-send-msg" id
="newnote" value
="<?php echo xla('Send message'); ?>"><?php
echo xlt('Send message'); ?
></button
>
562 <button type
="button" class="btn btn-primary btn-print" id
="printnote" value
="<?php echo xla('Print message'); ?>"><?php
echo xlt('Print message'); ?
></button
>
563 <button type
="button" class="btn btn-secondary btn-cancel" id
="cancel" value
="<?php echo xla('Cancel'); ?>"><?php
echo xlt('Cancel'); ?
></button
>
565 <!-- This is
for displaying a
new note
. -->
566 <button type
="button" class="btn btn-primary btn-send-msg" id
="newnote" value
="<?php echo xla('Send message'); ?>"><?php
echo xlt('Send message'); ?
></button
>
567 <button type
="button" class="btn btn-cancel btn-secondary" id
="cancel" value
="<?php echo xla('Cancel'); ?>"><?php
echo xlt('Cancel'); ?
></button
>
577 for ($i = 0; $i < count($sort); $i++
) {
578 $sortlink[$i] = "<a class='arrowhead' href=\"messages.php?show_all=" . attr($showall) . "&sortby=" . attr($sort[$i]) . "&sortorder=asc&$activity_string_html\" onclick=\"top.restoreSession()\" alt=\"" . xla('Sort Up') . "\"><i class='fa fa-sort-down fa-lg' aria-hidden='true'></i></a>";
580 for ($i = 0; $i < count($sort); $i++
) {
581 if ($sortby == $sort[$i]) {
582 switch ($sortorder) {
584 $sortlink[$i] = "<a class='arrowhead' href=\"messages.php?show_all=" . attr($showall) . "&sortby=" . attr($sortby) . "&sortorder=desc&$activity_string_html\" onclick=\"top.restoreSession()\" alt=\"" . xla('Sort Up') . "\"><i class='fa fa-sort-up fa-lg' aria-hidden='true'></i></a>";
587 $sortlink[$i] = "<a class='arrowhead' href=\"messages.php?show_all=" . attr($showall) . "&sortby=" . attr($sortby) . "&sortorder=asc&$activity_string_html\" onclick=\"top.restoreSession()\" alt=\"" . xla('Sort Down') . "\"><i class='fa fa-sort-down fa-lg' aria-hidden='true'></i></a>";
592 // Manage page numbering and display beneath the Messages table.
594 $total = getPnotesByUser($active, $show_all, $_SESSION['authUser'], true);
595 if ($begin == "" or $begin == 0) {
598 $prev = $begin - $listnumber;
599 $next = $begin +
$listnumber;
601 $end = $listnumber +
$start - 1;
603 $chevron_icon_left = $_SESSION['language_direction'] == 'ltr' ?
'fa-chevron-circle-left' : 'fa-chevron-circle-right';
604 $chevron_icon_right = $_SESSION['language_direction'] == 'ltr' ?
'fa-chevron-circle-right' : 'fa-chevron-circle-left';
606 if ($end >= $total) {
613 $prevlink = "<a href=\"messages.php?show_all=" . attr($showall) . "&sortby=" . attr($sortby) . "&sortorder=" . attr($sortorder) . "&begin=" . attr($prev) . "&$activity_string_html\" onclick=\"top.restoreSession()\"><i class=\"fa " . $chevron_icon_left . " chevron_color\" aria-hidden=\"true\"></i></a>";
615 $prevlink = "<i class=\"fa " . $chevron_icon_left . " text-muted\" aria-hidden=\"true\" title=\"" . xla("On first page") . "\"></i>";
618 if ($next < $total) {
619 $nextlink = "<a href=\"messages.php?show_all=" . attr($showall) . "&sortby=" . attr($sortby) . "&sortorder=" . attr($sortorder) . "&begin=" . attr($next) . "&$activity_string_html\" onclick=\"top.restoreSession()\"><i class=\"fa . $chevron_icon_right . chevron_color\" aria-hidden=\"true\"></i></a>";
621 $nextlink = "<i class=\"fa " . $chevron_icon_right . " text-muted\" aria-hidden=\"true\" title=\"" . xla("On first page") . "\"></i>";
623 // Display the Messages table header.
625 <table class=\"w-100\">
628 <form name='MessageList' id='MessageList' action=\"messages.php?showall=" . attr($showall) . "&sortby=" . attr($sortby) . "&sortorder=" . attr($sortorder) . "&begin=" . attr($begin) . "&$activity_string_html\" method='post'>
629 <table class='table table-sm table-hover w-100'>
630 <input type='hidden' name='task' value='delete' />
631 <thead class='table-primary'>
633 <th align='center' width='25'><input type='checkbox' id='checkAll' onclick='selectAll()'></th>
634 <th width='20%' class='font-weight-bold'> " . xlt('From') . " $sortlink[0]</th>
635 <th width='20%' class='font-weight-bold'> " . xlt('Patient') . " $sortlink[1]</th>
636 <th class='font-weight-bold'> " . xlt('Type') . " $sortlink[2]</th>
637 <th width='15%' class='font-weight-bold'> " . xlt($GLOBALS['messages_due_date'] ?
'Due date' : 'Date') . " $sortlink[3]</th>
638 <th width='15%' class='font-weight-bold'> " . xlt('Status') . " $sortlink[4]</th>
641 // Display the Messages table body.
643 $result = getPnotesByUser($active, $show_all, $_SESSION['authUser'], false, $sortby, $sortorder, $begin, $listnumber);
644 while ($myrow = sqlFetchArray($result)) {
645 $name = $myrow['user'];
646 $name = $myrow['users_lname'];
647 if ($myrow['users_fname']) {
648 $name .= ", " . $myrow['users_fname'];
650 $patient = $myrow['pid'];
652 $patient = $myrow['patient_data_lname'];
653 if ($myrow['patient_data_fname']) {
654 $patient .= ", " . $myrow['patient_data_fname'];
657 $patient = "* " . xl('Patient must be set manually') . " *";
661 <tr id=\"row" . attr($count) . "\" height='24'>
663 <input type='checkbox' id=\"check" . attr($count) . "\" name=\"delete_id[]\" value=\"" .
664 attr($myrow['id']) . "\" onclick=\"if(this.checked==true){ selectRow('row" . attr(addslashes($count)) . "'); }else{ deselectRow('row" . attr(addslashes($count)) . "'); }\"></td>
666 <div>" . text($name) . "</div>
669 <div><a href=\"messages.php?showall=" . attr_url($showall) . "&sortby=" . attr_url($sortby) . "&sortorder=" . attr_url($sortorder) . "&begin=" . attr_url($begin) . "&task=edit¬eid=" .
670 attr_url($myrow['id']) . "&$activity_string_html\" onclick=\"top.restoreSession()\">" .
671 text($patient) . "</a></div>
675 xlt($myrow['title']) . "</div>
677 <div>" . text(oeFormatDateTime($myrow['date'])) . "</div>
680 <div>" . text(getListItemTitle('message_status', $myrow['message_status'])) . "</div>
684 // Display the Messages table footer.
688 <div class='row oe-margin-t-10'>
690 <div class=\"col-12 col-md-12 col-lg-12\"><a href=\"messages.php?showall=" . attr_url($showall) . "&sortby=" . attr_url($sortby) . "&sortorder=" . attr_url($sortorder) . "&begin=" . attr_url($begin) . "&task=addnew&$activity_string_html\" class=\"btn btn-primary btn-add\" onclick=\"top.restoreSession()\">" .
691 xlt('Add New{{Message}}') . "</a> <a href=\"javascript:confirmDeleteSelected()\" class=\"btn btn-danger btn-delete\" onclick=\"top.restoreSession()\">" .
692 xlt('Delete') . "</a>";
694 if ($GLOBALS['phimail_enable']) {
695 echo " <a href='trusted-messages.php' onclick='top.restoreSession()' class='btn btn-secondary btn-mail'>" . xlt("Compose Trusted Direct Message") . "</a>";
696 echo " <button class='btn btn-secondar btn-refresh trusted-messages-force-check'>" . xlt("Check New Trusted Messages") . "</button>";
699 <div class=\"text-right\">$prevlink " . text($end) . " " . xlt('of') . " " . text($total) . " $nextlink</div>
709 // This is to confirm delete action.
710 function confirmDeleteSelected() {
712 var elem
= document
.forms
.namedItem("MessageList").getElementsByTagName("input");
714 for (i
=0; i
< elem
.length
; i++
){
715 if(elem
[i
].checked
== true){
716 int_checked
= ++int_checked
;
719 if (int_checked
> 0){
720 if (confirm("<?php echo xls('Do you really want to delete the selection?'); ?>")) {
721 document
.MessageList
.submit();
724 alert("<?php echo xls('Please select message(s) to delete'); ?>");
729 // This is to allow selection of all items in Messages table for deletion.
730 function selectAll() {
731 if (document
.getElementById("checkAll").checked
=== true) {
732 document
.getElementById("checkAll").checked
= true;<?php
733 for ($i = 1; $i <= $count; $i++
) {
734 echo "document.getElementById(\"check$i\").checked=true; document.getElementById(\"row$i\").style.background='var(--gray200)'; ";
737 document
.getElementById("checkAll").checked
= false;<?php
738 for ($i = 1; $i <= $count; $i++
) {
739 echo "document.getElementById(\"check$i\").checked=false; document.getElementById(\"row$i\").style.background='var(--light)'; ";
744 // The two functions below are for managing row styles in Messages table.
745 function selectRow(row
) {
746 document
.getElementById(row
).style
.background
= "var(--gray200)";
749 function deselectRow(row
) {
750 document
.getElementById(row
).style
.background
= "var(--light)";
759 </div
><!--end of messages div
-->
760 <div
class="row oe-display" id
="reminders-div">
761 <div
class="col-sm-12">
762 <div
class="jumbotron jumbotron-fluid py-3">
763 <div
class="col-sm-12 col-md-12 col-lg-12">
764 <div
class="oe-margin-b-10">
765 <span
class="title"><?php
echo xlt('Reminders'); ?
></span
>
768 // TajEmo Work by CB 2012/01/11 02:51:25 PM adding dated reminders
769 // I am asuming that at this point security checks have been performed
770 //require_once '../dated_reminders/dated_reminders.php';
771 require_once '../dated_reminders/dated_reminders.php';
776 </div
><!--end of reminders div
-->
777 <div
class="row oe-display" id
="recalls-div">
778 <div
class="col-sm-12">
779 <div
class="jumbotron jumbotron-fluid py-3">
780 <?php
if ($GLOBALS['disable_rcb'] != '1') { ?
>
781 <div
class="col-sm-6 col-md-6 col-lg-6">
782 <div
class="dr_container">
783 <span
class="title"><?php
echo xlt('Recalls'); ?
></span
>
785 <button
class="btn btn-primary btn-add" onclick
="goReminderRecall('addRecall');"><?php
echo xlt('New Recall'); ?
></button
>
786 <a
class="btn btn-secondary btn-transmit" onclick
="goReminderRecall('Recalls');"><span
><?php
echo xlt('Recall Board'); ?
></span
></a
>
793 </div
><!--end of recalls div
-->
794 <div
class="row oe-display" id
="sms-div">
795 <div
class="col-sm-12">
796 <div
class="jumbotron jumbotron-fluid py-3">
797 <?php
if ($logged_in) { ?
>
798 <div
class="col-sm-4 col-md-4 col-lg-4">
799 <span
class="title"><?php
echo xlt('SMS Zone'); ?
></span
>
801 <form id
="smsForm" class="input-group">
802 <select id
="SMS_patient" type
="text" class="form-control m-0 w-100" placeholder
="<?php echo xla("Patient Name
"); ?>" > </select
>
803 <span
class="input-group-addon" onclick
="SMS_direct();"><i
class="fas fa-phone"></i
></span
>
804 <input type
="hidden" id
="sms_pid" />
805 <input type
="hidden" id
="sms_mobile" value
="" />
806 <input type
="hidden" id
="sms_allow" value
="" />
812 </div
><!--end of sms div
-->
813 </div
><!--end of container div
-->
814 <?php
$oemr_ui->oeBelowContainerDiv();?
>
816 //home of the help modal ;)
817 //$GLOBALS['enable_help'] = 0; // Please comment out line if you want help modal to function on this page
818 if ($GLOBALS['enable_help'] == 1) {
819 echo "<script>var helpFile = 'message_center_help.php'</script>";
820 //help_modal.php lives in interface, set path accordingly
821 require "../../help_modal.php";
826 var collectvalidation
= <?php
echo $collectthis; ?
>;
829 var webRoot
= <?php
echo js_escape($GLOBALS['web_root']); ?
>;
830 $
("#reminders-div").hide();
831 $
("#recalls-div").hide();
832 $
("#sms-div").hide();
833 $
("#messages-li").click(function(){
834 $
("#messages-div").show(250);
835 $
("#reminders-div").hide(250);
836 $
("#recalls-div").hide(250);
837 $
("#sms-div").hide(250);
838 $
("#messages-li").addClass("active");
839 $
("#reminders-li").removeClass("active");
840 $
("#recalls-li").removeClass("active");
841 $
("#sms-li").removeClass("active");
844 $
("#reminders-li").click(function(){
845 $
("#messages-div").hide(250);
846 $
("#reminders-div").show(250);
847 $
("#recalls-div").hide(250);
848 $
("#sms-div").hide(250);
849 $
("#reminders-li").addClass("active");
850 $
("#messages-li").removeClass("active");
851 $
("#recalls-li").removeClass("active");
852 $
("#sms-li").removeClass("active");
854 $
("#recalls-li").click(function(){
855 $
("#messages-div").hide(250);
856 $
("#reminders-div").hide(250);
857 $
("#recalls-div").show(250);
858 $
("#sms-div").hide(250);
859 $
("#reminders-li").removeClass("active");
860 $
("#messages-li").removeClass("active");
861 $
("#recalls-li").addClass("active");
862 $
("#sms-li").removeClass("active");
864 $
("#sms-li").click(function(){
865 $
("#messages-div").hide(250);
866 $
("#reminders-div").hide(250);
867 $
("#recalls-div").hide(250);
868 $
("#sms-div").show(250);
869 $
("#reminders-li").removeClass("active");
870 $
("#messages-li").removeClass("active");
871 $
("#recalls-li").removeClass("active");
872 $
("#sms-li").addClass("active");
875 $
('.datetimepicker').datetimepicker({
876 <?php
$datetimepicker_timepicker = true; ?
>
877 <?php
$datetimepicker_showseconds = false; ?
>
878 <?php
$datetimepicker_formatInput = true; ?
>
879 <?php
require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?
>
880 ,minDate
: 0 //only future
883 <?php
if ($GLOBALS['phimail_enable']) : ?
>
884 $
('.trusted-messages-force-check').click(function() {
885 window
.top
.restoreSession();
886 request
= new FormData
;
887 request
.append("ajax", "1");
888 request
.append("csrf_token_form", <?php
echo js_escape(CsrfUtils
::collectCsrfToken()); ?
>);
889 request
.append("background_service", "phimail");
890 request
.append("background_force", "1");
891 fetch(webRoot +
"/library/ajax/execute_background_services.php", {
893 credentials
: 'same-origin',
895 }).then((response
) => {
896 if (response
.status
!== 200) {
897 console
.log('Background Service refresh failed. Status Code: ' + response
.status
);
899 // we've refreshed give them time to reload the page
900 setTimeout(function() {
901 window
.location
.reload();
904 }).catch(function(error
) {
905 console
.log('Background Service refresh failed: ', error
);
906 alert(window
.xl("Check new messages failed. Check the server logs for more information."));
913 $
( "ul.navbar-nav" ).children().click(function(){
914 $
(".collapse").collapse('hide');
918 $
('#see-all-tooltip').attr({"title": <?php
echo xlj('Click to show messages for all users'); ?
>, "data-toggle":"tooltip", "data-placement":"bottom"}).tooltip();
919 $
('#just-mine-tooltip').attr({"title": <?php
echo xlj('Click to show messages for only the current user'); ?
>, "data-toggle":"tooltip", "data-placement":"bottom"}).tooltip();
922 var f
= $
("#smsForm");
923 $
("#SMS_patient").select2({
927 data
: function(params
) {
933 processResults
: function(data
) {
935 results
: $
.map(data
, function(item
, index
) {
939 value
: item
.Label +
' ' + item
.mobile
,
951 $
('#SMS_patient').on('select2:select', function (e
) {
953 $
("#SMS_patient").val(e
.params
.data
.value
);
954 $
("#sms_pid").val(e
.params
.data
.pid
);
955 $
("#sms_mobile").val(e
.params
.data
.mobile
);
956 $
("#sms_allow").val(e
.params
.data
.allow
);
962 $
("#newnote").click(function (event
) {
966 $
("#printnote").click(function () {
970 var obj
= $
("#form_message_status");
971 obj
.onchange
= function () {
975 $
("#cancel").click(function () {
979 $
("#form_patient").focus();
981 //clear button in messages
982 $
("#clear_user").click(function(){
983 $
("#assigned_to_text").val("<?php echo xls('Select Users From The Dropdown List'); ?>");
984 $
("#assigned_to").val("");
985 $
("#users").val("--");
988 //clear inputs of patients
989 $
("#clear_patients").click(function(){
990 $
("#reply_to").val("");
991 $
("#form_patient").val("");
995 var NewNote
= function (event
) {
996 top
.restoreSession();
997 if(document
.getElementById("form_message_status").value
!== 'Done'){
998 collectvalidation
.assigned_to
= {
999 presence
: {message
: "<?php echo xls('Recipient required unless status is Done'); ?>"}
1003 delete collectvalidation
.assigned_to
;
1006 $
('#newnote').attr('disabled', true);
1008 var submit
= submitme(1, event
, 'new_note', collectvalidation
);
1010 $
('#newnote').attr('disabled', false);
1013 $
("#new_note").submit();
1016 var PrintNote
= function () {
1017 <?php
if ($noteid) { ?
>
1018 top
.restoreSession();
1019 window
.open('../../patient_file/summary/pnotes_print.php?noteid=' +
<?php
echo js_url($noteid); ?
>, '_blank', 'resizable=1,scrollbars=1,width=600,height=500');
1024 var SaveNote
= function () {
1025 <?php
if ($noteid) { ?
>
1026 top
.restoreSession();
1027 $
("#task").val("save");
1028 $
("#new_note").submit();
1032 var CancelNote
= function () {
1033 top
.restoreSession();
1035 $
("#new_note").submit();
1039 * Given a document that we don't know what patient to attach the document to we need to look at a preview of
1040 * the document. This loads up the document from the Miscellaneous -> New Documents page. To access the page
1041 * the user must have the following ACLs: "patients","docs","write","addonly"
1042 * @param doc_id The id of the document we want to preview in OpenEMR
1044 function previewDocument(doc_id
) {
1045 top
.restoreSession();
1046 var docurl
= '../controller.php?document&view' +
"&patient_id=0&document_id=" +
encodeURIComponent(doc_id
) +
"&";
1047 parent
.left_nav
.loadFrame('adm0', 'msc', docurl
);
1050 function gotoReport(doc_id
, pname
, pid
, pubpid
, str_dob
) {
1051 EncounterDateArray
= [];
1052 CalendarCategoryArray
= [];
1053 EncounterIdArray
= [];
1056 if (isset($enc_list) && sqlNumRows($enc_list) > 0) {
1057 while ($row = sqlFetchArray($enc_list)) {
1059 EncounterIdArray
[Count
] = '<?php echo attr($row['encounter
']); ?>';
1060 EncounterDateArray
[Count
] = '<?php echo attr(oeFormatShortDate(date("Y-m-d", strtotime($row['date
'])))); ?>';
1061 CalendarCategoryArray
[Count
] = '<?php echo attr(xl_appt_category($row['pc_catname
'])); ?>';
1067 top
.restoreSession();
1070 url
: '<?php echo $GLOBALS['webroot
'] . "/library/ajax/set_pt.php";?>',
1073 csrf_token_form
: <?php
echo js_escape(CsrfUtils
::collectCsrfToken()); ?
>
1077 parent
.left_nav
.setPatient(pname
, pid
, pubpid
, '', str_dob
);
1078 parent
.left_nav
.setPatientEncounter(EncounterIdArray
, EncounterDateArray
, CalendarCategoryArray
);
1079 var docurl
= '../controller.php?document&view' +
"&patient_id=" +
encodeURIComponent(pid
) +
"&document_id=" +
encodeURIComponent(doc_id
) +
"&";
1080 var paturl
= 'patient_file/summary/demographics.php?pid=' +
encodeURIComponent(pid
);
1081 parent
.left_nav
.loadFrame('dem1', 'pat', paturl
);
1082 parent
.left_nav
.loadFrame('doc0', 'enc', docurl
);
1083 top
.activateTabByName('enc', true);
1086 // This is for callback by the find-patient popup.
1087 function setpatient(pid
, lname
, fname
, dob
) {
1088 var f
= document
.getElementById('new_note');
1089 f
.form_patient
.value +
= lname +
', ' + fname +
'; ';
1090 f
.reply_to
.value +
= pid +
';';
1091 <?php
if ($noteid) { ?
>
1092 //used when direct messaging service inserts a pnote with indeterminate patient
1093 //to allow the user to assign the message to a patient.
1094 top
.restoreSession();
1095 $
("#task").val("savePatient");
1096 $
("#new_note").submit();
1100 // This is for callback by the multi_patients_finder popup.
1101 function setMultiPatients(patientsList
) {
1102 var f
= document
.getElementById('new_note');
1103 f
.form_patient
.value
='';
1104 f
.reply_to
.value
='';
1105 $
.each(patientsList
, function (key
, patient
) {
1106 f
.form_patient
.value +
= patient
.lname +
', ' + patient
.fname +
'; ';
1107 f
.reply_to
.value +
= patient
.pid +
';';
1110 <?php
if ($noteid) { ?
>
1111 //used when direct messaging service inserts a pnote with indeterminate patient
1112 //to allow the user to assign the message to a patient.
1113 top
.restoreSession();
1114 $
("#task").val("savePatient");
1115 $
("#new_note").submit();
1119 // This invokes the find-patient popup.
1120 function sel_patient() {
1121 dlgopen('../../main/calendar/find_patient_popup.php', '_blank', 625, 400);
1124 function multi_sel_patient() {
1125 $
('#reply_to').trigger('click');
1126 var url
= '../../main/finder/multi_patients_finder.php'
1127 // for edit selected list
1128 if ($
('#reply_to').val() !== '') {
1129 url
= url +
'?patients=' + $
('#reply_to').val() +
'&csrf_token_form=<?php echo attr_url(CsrfUtils::collectCsrfToken()); ?>';
1131 dlgopen(url
, '_blank', 625, 400);
1134 function addtolist(sel
) {
1135 $
('#assigned_to').trigger("click");
1136 var itemtext
= document
.getElementById('assigned_to_text');
1137 var item
= document
.getElementById('assigned_to');
1138 if (sel
.value
!== '--') {
1140 if (item
.value
.indexOf(sel
.value
) === -1) {
1141 itemtext
.value
= itemtext
.value +
' ; ' + sel
.options
[sel
.selectedIndex
].text
;
1142 item
.value
= item
.value +
';' + sel
.value
;
1145 itemtext
.value
= sel
.options
[sel
.selectedIndex
].text
;
1146 item
.value
= sel
.value
;
1151 function SMS_direct() {
1152 var pid
= $
("#sms_pid").val();
1153 var m
= $
("#sms_mobile").val();
1154 var allow
= $
("#sms_allow").val();
1155 if ((pid
=== '') ||
(m
=== '')) {
1156 alert('<?php echo xls("MedEx needs a valid mobile number to send SMS messages..."); ?>');
1157 } else if (allow
=== 'NO') {
1158 alert('<?php echo xls("This patient does not allow SMS messaging!"); ?>');
1160 top
.restoreSession();
1161 window
.open('messages.php?nomenu=1&go=SMS_bot&pid=' +
encodeURIComponent(pid
) +
'&m=' +
encodeURIComponent(m
), 'SMS_bot', 'width=370,height=600,resizable=0');