Added support for repeating events like "2nd Tuesday" or "Last Friday" of the month.
[openemr.git] / library / dated_reminder_functions.php
blob6b5b518c63c58b4e530dc5e7144ac20f0e75bb1a
1 <?php
2 /**
3 * Contains functions used in the dated reminders.
5 * Copyright (C) 2012 tajemo.co.za <http://www.tajemo.co.za/>
7 * LICENSE: This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://opensource.org/licenses/gpl-license.php>;.
18 * @package OpenEMR
19 * @author Craig Bezuidenhout <http://www.tajemo.co.za/>
20 * @link http://www.open-emr.org
23 require_once("$srcdir/htmlspecialchars.inc.php");
25 // ------------------------------------------------
26 // @ RemindersArray function
27 // @ returns array with reminders for specified user, defaults to current user if none specified
28 // ------------------------------------------------
29 function RemindersArray($days_to_show,$today,$alerts_to_show,$userID = false){
30 if(!$userID) $userID = $_SESSION['authId'];
31 global $hasAlerts;
32 // ----- define a blank reminders array
33 $reminders = array();
35 // ----- sql statement for getting uncompleted reminders (sorts by date, then by priority)
36 $drSQL = sqlStatement(
37 "SELECT
38 dr.pid, dr.dr_id, dr.dr_message_text,dr.dr_message_due_date,
39 u.fname ffname, u.mname fmname, u.lname flname
40 FROM `dated_reminders` dr
41 JOIN `users` u ON dr.dr_from_ID = u.id
42 JOIN `dated_reminders_link` drl ON dr.dr_id = drl.dr_id
43 WHERE drl.to_id = ?
44 AND dr.`message_processed` = 0
45 AND dr.`dr_message_due_date` < ADDDATE(NOW(), INTERVAL $days_to_show DAY)
46 ORDER BY `dr_message_due_date` ASC , `message_priority` ASC LIMIT 0,$alerts_to_show"
47 , array($userID)
48 );
50 // --------- loop through the results
51 for($i=0; $drRow=sqlFetchArray($drSQL); $i++){
52 // --------- need to run patient query seperately to allow for reminders not linked to a patient
53 $pRow = array();
54 if($drRow['pid'] > 0){
55 $pSQL = sqlStatement("SELECT pd.title ptitle, pd.fname pfname, pd.mname pmname, pd.lname plname FROM `patient_data` pd WHERE pd.pid = ?",array($drRow['pid']));
56 $pRow = sqlFetchArray($pSQL);
59 // --------- fill the $reminders array
60 $reminders[$i]['messageID'] = $drRow['dr_id'];
61 $reminders[$i]['PatientID'] = $drRow['pid'];
63 // ------------------------------------- if there was a patient linked, set the name, else set it to blank
64 $reminders[$i]['PatientName'] = (empty($pRow) ? '' : $pRow['ptitle'].' '.$pRow['pfname'].' '.$pRow['pmname'].' '.$pRow['plname']);
65 // -------------------------------------
67 $reminders[$i]['message'] = $drRow['dr_message_text'];
68 $reminders[$i]['dueDate'] = $drRow['dr_message_due_date'];
69 $reminders[$i]['fromName'] = $drRow['ffname'].' '.$drRow['fmname'].' '.$drRow['flname'];
71 // --------- if the message is due or overdue set $hasAlerts to true, this will stop autohiding of reminders
72 if(strtotime($drRow['dr_message_due_date']) <= $today) $hasAlerts = true;
74 // --------- END OF loop through the results
76 return $reminders;
78 // ------------------------------------------------
79 // @ END OF RemindersArray function
80 // ------------------------------------------------
85 // ------------------------------------------------
86 // @ GetDueReminder function
87 // @ returns int with number of due reminders for specified user, defaults to current user if none specified
88 // ------------------------------------------------
89 function GetDueReminderCount($days_to_show,$today,$userID = false){
90 if(!$userID) $userID = $_SESSION['authId'];
92 // ----- sql statement for getting uncompleted reminders (sorts by date, then by priority)
93 $drSQL = sqlStatement(
94 "SELECT count(dr.dr_id) c
95 FROM `dated_reminders` dr
96 JOIN `users` u ON dr.dr_from_ID = u.id
97 JOIN `dated_reminders_link` drl ON dr.dr_id = drl.dr_id
98 WHERE drl.to_id = ?
99 AND dr.`message_processed` = 0
100 AND dr.`dr_message_due_date` < ADDDATE(NOW(), INTERVAL $days_to_show DAY)"
101 , array($userID)
104 $drRow=sqlFetchArray($drSQL);
105 return $drRow['c'];
107 // ------------------------------------------------
108 // @ END OF GetDueReminder function
109 // ------------------------------------------------
111 // ------------------------------------------------
112 // @ GetAllReminderCount function
113 // @ returns int with number of unprocessed reminders for specified user, defaults to current user if none specified
114 // ------------------------------------------------
115 function GetAllReminderCount($userID = false){
116 if(!$userID) $userID = $_SESSION['authId'];
118 // ----- sql statement for getting uncompleted reminders
119 $drSQL = sqlStatement(
120 "SELECT count(dr.dr_id) c
121 FROM `dated_reminders` dr
122 JOIN `users` u ON dr.dr_from_ID = u.id
123 JOIN `dated_reminders_link` drl ON dr.dr_id = drl.dr_id
124 WHERE drl.to_id = ?
125 AND dr.`message_processed` = 0"
126 , array($userID)
129 $drRow=sqlFetchArray($drSQL);
130 return $drRow['c'];
132 // ------------------------------------------------
133 // @ END OF GetAllReminderCount function
134 // ------------------------------------------------
136 // ------------------------------------------------
137 // @ getRemindersHTML(array $reminders)
138 // @ returns HTML as a string, for printing
139 // ------------------------------------------------
140 function getRemindersHTML($reminders = array(),$today){
141 global $hasAlerts;
142 // --- initialize the string as blank
143 $pdHTML = '';
144 // --- loop through the $reminders
145 foreach($reminders as $r){
146 // --- initialize $warning as the date, this is placed in front of the message
147 $warning = text($r['dueDate']);
148 // --- initialize $class as 'text dr', this is the basic class
149 $class='text dr';
151 // --------- check if reminder is overdue
152 if(strtotime($r['dueDate']) < $today){
153 $warning = '! '.xlt('OVERDUE');
154 $class = 'bold alert dr';
156 // --------- check if reminder is due
157 elseif(strtotime($r['dueDate']) == $today){
158 $warning = xlt('TODAY');
159 $class='bold alert dr';
161 // end check if reminder is due or overdue
162 // apend to html string
163 $pdHTML .= '<p id="p_'.attr($r['messageID']).'">
164 <a class="dnRemover css_button_small" onclick="updateme('."'".attr($r['messageID'])."'".')" id="'.attr($r['messageID']).'" href="#">
165 <span>'.xlt('Set As Completed').'</span>
166 </a>
167 <span title="'.($r['PatientID'] > 0 ? xla('Click Patient Name to Open Patient File') : '').'" class="'.attr($class).'">'.
168 $warning.'
169 <span onclick="goPid('.attr($r['PatientID']).')" class="patLink" id="'.attr($r['PatientID']).'">'.
170 text($r['PatientName']).'
171 </span> '.
172 text($r['message']).' - ['.text($r['fromName']).']
173 </span> ----->
174 <a onclick="openAddScreen('.attr($r['messageID']).')" class="dnForwarder" id="'.attr($r['messageID']).'" href="#">[ '.xlt('Forward').' ]</a>
175 </p>';
177 return ($pdHTML == '' ? '<p class="alert"><br />'.xlt('No Reminders').'</p>' : $pdHTML);
179 // ------------------------------------------------
180 // @ END OF getRemindersHTML function
181 // ------------------------------------------------
184 // ------------------------------------------------
185 // @ setReminderAsProccessed(int $rID)
186 // @ marks reminder as processed
187 // ------------------------------------------------
188 function setReminderAsProcessed($rID,$userID = false){
189 if(!$userID) $userID = $_SESSION['authId'];
190 if(is_numeric($rID) and $rID > 0){
191 // --- check if this user can remove this message
192 // --- need a better way of checking the current user, I don't like using $_SESSION for checks
193 $rdrSQL = sqlStatement("SELECT count(dr.dr_id) c FROM `dated_reminders` dr JOIN `dated_reminders_link` drl ON dr.dr_id = drl.dr_id WHERE drl.to_id = ? AND dr.`dr_id` = ? LIMIT 0,1", array($userID,$rID));
194 $rdrRow=sqlFetchArray($rdrSQL);
196 // --- if this user can delete this message (ie if it was sent to this user)
197 if($rdrRow['c'] == 1){
198 // ----- update the data, set the message to proccesses
199 sqlStatement("UPDATE `dated_reminders` SET `message_processed` = 1, `processed_date` = NOW(), `dr_processed_by` = ? WHERE `dr_id` = ? ", array(intval($userID),intval($rID)));
203 // ------------------------------------------------
204 // @ END OF setReminderAsProccessed function
205 // ------------------------------------------------
208 // ------------------------------------------------
209 // @ getReminderById(int $mID)
210 // @ returns an array with message details for forwarding
211 // ------------------------------------------------
212 function getReminderById($mID,$userID = false){
213 if(!$userID) $userID = $_SESSION['authId'];
214 $rdrSQL = sqlStatement("SELECT * FROM `dated_reminders` dr
215 JOIN `dated_reminders_link` drl ON dr.dr_id = drl.dr_id
216 WHERE drl.to_id = ? AND dr.`dr_id` = ? LIMIT 0,1", array($userID,$mID));
217 $rdrRow=sqlFetchArray($rdrSQL);
218 if(!empty($rdrRow)){
219 return $rdrRow;
221 return false;
223 // ------------------------------------------------
224 // @ END OF getReminderById function
225 // ------------------------------------------------
228 // ------------------------------------------------
229 // @ getReminderById(
230 // array $sendTo
231 // int $fromID
232 // string $message
233 // date $dueDate
234 // int $patID
235 // int $priority
236 // )
237 // @ returns an array with message details for forwarding
238 // ------------------------------------------------
239 function sendReminder($sendTo,$fromID,$message,$dueDate,$patID,$priority){
240 if(
241 // ------- Should run data checks before running this function for more accurate error reporting
242 // ------- check sendTo is not empty
243 !empty($sendTo) and
244 // ------- check dueDate, only allow valid dates, todo -> enhance date checker
245 preg_match('/\d{4}[-]\d{2}[-]\d{2}/',$dueDate) and
246 // ------- check priority, only allow 1-3
247 intval($priority) <= 3 and
248 // ------- check message, only up to 255 characters
249 strlen($message) <= 255 and strlen($message) > 0 and
250 // ------- check if PatientID is set and in numeric
251 is_numeric($patID)
253 // ------- check for valid recipient
254 $cRow=sqlFetchArray(sqlStatement('SELECT count(id) FROM `users` WHERE `id` = ?',array($sendDMTo)));
255 if($cRow == 0){
256 return false;
258 // ------- if no errors
259 // --------- insert the new message
260 $mID = sqlInsert("INSERT INTO `dated_reminders`
261 (`dr_from_ID` ,`dr_message_text` ,`dr_message_sent_date` ,`dr_message_due_date` ,`pid` ,`message_priority` ,`message_processed` ,`processed_date`)
262 VALUES (?, ?, NOW( ), ?, ?, ?, '0', '');",
263 array($fromID,$message,$dueDate,$patID,$priority));
265 foreach($sendTo as $st){
266 sqlInsert("INSERT INTO `dated_reminders_link`
267 (`dr_id` ,`to_id`)
268 VALUES (?, ?);",
269 array($mID,$st));
271 return true;
272 } //---- end of if block
273 return false;
276 // ------- get current patient name
277 // ---- returns string, blank if no current patient
278 function getPatName($patientID){
279 $patientID = intval($patientID);
280 $pSQL = sqlStatement("SELECT pd.title ptitle, pd.fname pfname, pd.mname pmname, pd.lname plname FROM `patient_data` pd WHERE pd.pid = ?",array($patientID));
281 $pRow = sqlFetchArray($pSQL);
282 return (empty($pRow) ? '' : $pRow['ptitle'].' '.$pRow['pfname'].' '.$pRow['pmname'].' '.$pRow['plname']);
285 // -- log reminders array function uses $_GET to filter
286 function logRemindersArray(){
288 // set blank array for data to be parsed to sql
289 $input = array();
290 // set blank string for the query
291 $where = '';
292 $sentBy = $_GET['sentBy'];
293 $sentTo = $_GET['sentTo'];
294 //------------------------------------------
295 // ----- HANDLE SENT BY FILTER
296 if(!empty($sentBy)){
297 $sbCount = 0;
298 foreach($sentBy as $sb){
299 $where .= ($sbCount == 0 ? '(' : ' OR ').'dr.dr_from_ID = ? ';
300 $sbCount++;
301 $input[] = $sb;
303 $where .= ')';
305 //------------------------------------------
306 // ----- HANDLE SENT TO FILTER
307 if(!empty($sentTo)){
308 $where = ($where == '' ? '' : $where.' AND ');
309 $stCount = 0;
310 foreach($sentTo as $st){
311 $where .= ($stCount == 0 ? '(' : ' OR ').'drl.to_id = ? ';
312 $stCount++;
313 $input[] = $st;
315 $where .= ')';
317 //------------------------------------------
318 // ----- HANDLE PROCCESSED/PENDING FILTER ONLY RUN THIS IF BOTH ARE NOT SET
319 if(isset($_GET['processed']) and !isset($_GET['pending'])){
320 $where = ($where == '' ? 'dr.message_processed = 1' : $where.' AND dr.message_processed = 1');
322 elseif(!isset($_GET['processed']) and isset($_GET['pending'])){
323 $where = ($where == '' ? 'dr.message_processed = 0' : $where.' AND dr.message_processed = 0');
325 //------------------------------------------
326 // ----- HANDLE DATE RANGE FILTERS
327 if(isset($_GET['sd']) and $_GET['sd'] != ''){
328 $where = ($where == '' ? 'dr.dr_message_sent_date >= ?' : $where.' AND dr.dr_message_sent_date >= ?');
329 $input[] = $_GET['sd'].' 00:00:00';
331 if(isset($_GET['ed']) and $_GET['ed'] != ''){
332 $where = ($where == '' ? 'dr.dr_message_sent_date <= ?' : $where.' AND dr.dr_message_sent_date <= ?');
333 $input[] = $_GET['ed'].' 24:00:00';
335 //------------------------------------------
338 //-------- add the "WHERE" the string if string is not blank, avoid sql errors for blannk WHERE statements
339 $where = ($where == '' ? '' : 'WHERE '.$where);
341 // ----- define a blank reminders array
342 $reminders = array();
344 // ----- sql statement for getting uncompleted reminders (sorts by date, then by priority)
345 $drSQL = sqlStatement(
346 "SELECT
347 dr.pid, dr.dr_id, dr.dr_message_text, dr.dr_message_due_date dDate, dr.dr_message_sent_date sDate,dr.processed_date processedDate, dr.dr_processed_by,
348 u.fname ffname, u.mname fmname, u.lname flname,
349 tu.fname tfname, tu.mname tmname, tu.lname tlname
350 FROM `dated_reminders` dr
351 JOIN `dated_reminders_link` drl ON dr.dr_id = drl.dr_id
352 JOIN `users` u ON dr.dr_from_ID = u.id
353 JOIN `users` tu ON drl.to_id = tu.id
354 $where"
355 ,$input);
356 // --------- loop through the results
357 for($i=0; $drRow=sqlFetchArray($drSQL); $i++){
358 // --------- need to run patient query seperately to allow for messages not linked to a patient
359 $pSQL = sqlStatement("SELECT pd.title ptitle, pd.fname pfname, pd.mname pmname, pd.lname plname FROM `patient_data` pd WHERE pd.pid = ?",array($drRow['pid']));
360 $pRow = sqlFetchArray($pSQL);
362 $prSQL = sqlStatement("SELECT u.fname pfname, u.mname pmname, u.lname plname FROM `users` u WHERE u.id = ?",array($drRow['dr_processed_by']));
363 $prRow = sqlFetchArray($prSQL );
365 // --------- fill the $reminders array
366 $reminders[$i]['messageID'] = $drRow['dr_id'];
367 $reminders[$i]['PatientID'] = $drRow['pid'];
369 $reminders[$i]['pDate'] = ($drRow['processedDate'] == '0000-00-00 00:00:00' ? 'N/A' : $drRow['processedDate']);
370 $reminders[$i]['sDate'] = $drRow['sDate'];
371 $reminders[$i]['dDate'] = $drRow['dDate'];
373 // ------------------------------------- if there was a patient linked, set the name, else set it to blank
374 $reminders[$i]['PatientName'] = (empty($pRow) ? 'N/A' : $pRow['ptitle'].' '.$pRow['pfname'].' '.$pRow['pmname'].' '.$pRow['plname']);
375 // -------------------------------------
377 $reminders[$i]['message'] = $drRow['dr_message_text'];
378 $reminders[$i]['fromName'] = $drRow['ffname'].' '.$drRow['fmname'].' '.$drRow['flname'];
379 $reminders[$i]['ToName'] = $drRow['tfname'].' '.$drRow['tmname'].' '.$drRow['tlname'];
380 $reminders[$i]['processedByName'] = (empty($prRow) ? 'N/A' : $prRow['ptitle'].' '.$prRow['pfname'].' '.$prRow['pmname'].' '.$prRow['plname']);
382 // --------- END OF loop through the results
384 return $reminders;