Added DataTables 1.9.0, minus examples and documentation.
[openemr.git] / library / reminders.php
blob5c6aac879322be66413bf8f38a3379dba6ab58e8
1 <?php
2 // Copyright (C) 2010 Brady Miller <brady@sparmy.com>
3 //
4 // This program is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU General Public License
6 // as published by the Free Software Foundation; either version 2
7 // of the License, or (at your option) any later version.
9 // Functions are kept here that will support reminders.
11 require_once(dirname(__FILE__) . "/clinical_rules.php");
14 // Display the patient reminder widget.
15 // Parameters:
16 // $patient_id - pid of selected patient
17 // $dateTarget - target date. If blank then will test with current date as target.
18 function patient_reminder_widget($patient_id,$dateTarget='') {
20 // Set date to current if not set
21 $dateTarget = ($dateTarget) ? $dateTarget : date('Y-m-d H:i:s');
23 // Update reminders for patient
24 update_reminders($dateTarget, $patient_id);
26 // Fetch the active reminders
27 $listReminders = fetch_reminders($patient_id);
29 if (empty($listReminders)) {
30 // No reminders to show.
31 echo htmlspecialchars( xl('No active patient reminders.'), ENT_NOQUOTES);
32 return;
35 echo "<table cellpadding='0' cellspacing='0'>";
36 foreach ($listReminders as $reminder) {
37 echo "<tr><td style='padding:0 1em 0 1em;'><span class='small'>";
38 // show reminder label
39 echo generate_display_field(array('data_type'=>'1','list_id'=>'rule_action_category'),$reminder['category']) .
40 ": " . generate_display_field(array('data_type'=>'1','list_id'=>'rule_action'),$reminder['item']);
41 echo "</span></td><td style='padding:0 1em 0 1em;'><span class='small'>";
42 // show reminder due status
43 echo generate_display_field(array('data_type'=>'1','list_id'=>'rule_reminder_due_opt'),$reminder['due_status']);
44 echo "</span></td><td style='padding:0 1em 0 1em;'><span class='small'>";
45 // show reminder sent date
46 if (empty($reminder['date_sent'])) {
47 echo htmlspecialchars( xl('Reminder Not Sent Yet'), ENT_NOQUOTES);
49 else {
50 echo htmlspecialchars( xl('Reminder Sent On').": ".$reminder['date_sent'], ENT_NOQUOTES);
52 echo "</span></td></tr>";
54 echo "</table>";
57 // Function to update reminders.
58 // Parameters:
59 // $dateTarget - target date. If blank then will test with current date as target.
60 // $patient_id - pid of patient. If blank then will check all patients.
61 // Return:
62 // Returns a array with following element:
63 // 'total_active_actions' - Number of active actions.
64 // 'total_pre_active_reminders' - Number of active reminders before processing.
65 // 'total_pre_unsent_reminders' - Number of unsent reminders before processing.
66 // 'total_post_active_reminders' - Number of active reminders after processing.
67 // 'total_post_unsent_reminders' - Number of unsent reminders after processing.
68 // 'number_new_reminders' - Number of new reminders
69 // 'number_updated_reminders' - Number of updated reminders (due_status change)
70 // 'number_inactivated_reminders' - Number of inactivated reminders.
71 // 'number_unchanged_reminders' - Number of unchanged reminders.
72 function update_reminders($dateTarget='', $patient_id='') {
74 $logging = array();
76 // Set date to current if not set
77 $dateTarget = ($dateTarget) ? $dateTarget : date('Y-m-d H:i:s');
79 // Collect reminders (note that this function removes redundant and keeps the most distant
80 // reminder (ie. prefers 'past_due' over 'due' over 'soon_due')
81 // Note that due to a limitation in the test_rules_clinic function, the patient_id is explicitly
82 // needed to work correctly. So rather than pass in a '' patient_id to do the entire clinic,
83 // we instead need to pass in each patient_id separately.
84 $collectedReminders = array();
85 if (!(empty($patient_id))) {
86 // only one patient id, so run the function
87 $collectedReminders = test_rules_clinic('','patient_reminder',$dateTarget,'reminders-due',$patient_id);
89 else {
90 // as described above, need to pass in each patient_id
91 // Collect all patient ids
92 $patientData = array();
93 $rez = sqlStatement("SELECT `pid` FROM `patient_data`");
94 for($iter=0; $row=sqlFetchArray($rez); $iter++) {
95 $patientData[$iter]=$row;
97 foreach ($patientData as $patient) {
98 $tempCollectReminders = test_rules_clinic('','patient_reminder',$dateTarget,'reminders-due',$patient['pid']);
99 $collectedReminders = array_merge($collectedReminders,$tempCollectReminders);
103 $logging['total_active_actions'] = count($collectedReminders);
105 // For logging purposes only:
106 // Collect number active of active and unsent reminders
107 $logging['total_pre_active_reminders'] = count(fetch_reminders($patient_id));
108 $logging['total_pre_unsent_reminders'] = count(fetch_reminders($patient_id, 'unsent'));
110 // Migrate reminders into the patient_reminders table
111 $logging['number_new_reminders'] = 0;
112 $logging['number_updated_reminders'] = 0;
113 $logging['number_unchanged_reminders'] = 0;
114 foreach ($collectedReminders as $reminder) {
116 // See if a reminder already exist
117 $sql = "SELECT `id`, `pid`, `due_status`, `category`, `item` FROM `patient_reminders` WHERE " .
118 "`active`='1' AND `pid`=? AND `category`=? AND `item`=?";
119 $result = sqlQuery($sql, array($reminder['pid'], $reminder['category'], $reminder['item']) );
121 if (empty($result)) {
122 // It does not yet exist, so add a new reminder
123 $sql = "INSERT INTO `patient_reminders` (`pid`, `due_status`, `category`, `item`, `date_created`) " .
124 "VALUES (?, ?, ?, ?, NOW())";
125 sqlStatement($sql, array($reminder['pid'], $reminder['due_status'], $reminder['category'], $reminder['item']) );
126 $logging['number_new_reminders']++;
128 else {
129 // It already exist (see if if needs to be updated via adding a new reminder)
130 if ($reminder['due_status'] == $result['due_status']) {
131 // No change in due status, so no need to update
132 $logging['number_unchanged_reminders']++;
133 continue;
135 else {
136 // Change in due status, so inactivate current reminder and create a new one
137 // First, inactivate the previous reminder
138 $sql = "UPDATE `patient_reminders` SET `active` = '0', `reason_inactivated` = 'due_status_update', " .
139 "`date_inactivated` = NOW() WHERE `id`=?";
140 sqlStatement($sql, array($result['id']) );
141 // Then, add the new reminder
142 $sql = "INSERT INTO `patient_reminders` (`pid`, `due_status`, `category`, `item`, `date_created`) " .
143 "VALUES (?, ?, ?, ?, NOW())";
144 sqlStatement($sql, array($reminder['pid'], $reminder['due_status'], $reminder['category'], $reminder['item']) );
149 // Inactivate reminders that no longer exist
150 // Go through each active reminder and ensure it is in the current list
151 $sqlReminders = fetch_reminders($patient_id);
152 $logging['number_inactivated_reminders'] = 0;
153 foreach ( $sqlReminders as $row ) {
154 $inactivateFlag = true;
155 foreach ($collectedReminders as $reminder) {
156 if ( ($row['pid'] == $reminder['pid']) &&
157 ($row['category'] == $reminder['category']) &&
158 ($row['item'] == $reminder['item']) &&
159 ($row['due_status'] == $reminder['due_status']) ) {
160 // The sql reminder has been confirmed, so do not inactivate it
161 $inactivateFlag = false;
162 break;
165 if ($inactivateFlag) {
166 // The sql reminder was not confirmed, so inactivate it
167 $sql = "UPDATE `patient_reminders` SET `active` = '0', `reason_inactivated` = 'auto', " .
168 "`date_inactivated` = NOW() WHERE `id`=?";
169 sqlStatement($sql, array($row['id']) );
170 $logging['number_inactivated_reminders'] = 0;
174 // For logging purposes only:
175 // Collect number of active and unsent reminders
176 $logging['total_post_active_reminders'] = count(fetch_reminders($patient_id));
177 $logging['total_post_unsent_reminders'] = count(fetch_reminders($patient_id, 'unsent'));
179 return $logging;
183 // Function to send reminders
184 // Return:
185 // Returns a array with following element:
186 // 'total_pre_unsent_reminders' - Number of reminders before processing.
187 // 'total_post_unsent_reminders' - Number of reminders after processing.
188 // 'number_success_emails' - Number of successfully sent email reminders.
189 // 'number_failed_emails' - Number of failed sent email reminders.
190 // 'number_success_calls' - Number of successfully call reminders.
191 // 'number_failed_calls' - Number of failed call reminders.
192 function send_reminders() {
194 $logging = array();
196 // Collect active reminders that have not yet been sent.
197 $active_unsent_reminders = fetch_reminders($patient_id, 'unsent');
198 $logging['total_pre_unsent_reminders'] = count($active_unsent_reminders);
200 // Send the unsent reminders
201 $logging['number_success_emails'] = 0;
202 $logging['number_failed_emails'] = 0;
203 $logging['number_success_calls'] = 0;
204 $logging['number_failed_calls'] = 0;
205 foreach ( $active_unsent_reminders as $reminder ) {
207 // Collect patient information that reminder is going to.
208 $sql = "SELECT `fname`, `lname`, `email`, `phone_home`, `hipaa_voice`, `hipaa_allowemail` from `patient_data` where `pid`=?";
209 $result = sqlQuery($sql, array($reminder['pid']) );
210 $patientfname = $result['fname'];
211 $patientlname = $result['lname'];
212 $patientemail = $result['email'];
213 $patientphone = $result['phone_home'];
214 $hipaa_voice = $result['hipaa_voice'];
215 $hipaa_allowemail = $result['hipaa_allowemail'];
217 // Email to patient if Allow Email and set reminder sent flag.
218 if ($hipaa_allowemail == "YES") {
219 $mail = new MyMailer();
220 $sender_name = $GLOBALS['patient_reminder_sender_name'];
221 $email_address = $GLOBALS['patient_reminder_sender_email'];
222 $mail->FromName = $sender_name; // required
223 $mail->Sender = $email_address; // required
224 $mail->From = $email_address; // required
225 $mail->AddAddress($patientemail, $patientfname.", ".$patientlname); // required
226 $mail->AddReplyTo($email_address,$sender_name); // required
227 $category_title = generate_display_field(array('data_type'=>'1','list_id'=>'rule_action_category'),$reminder['category']);
228 $item_title = generate_display_field(array('data_type'=>'1','list_id'=>'rule_action'),$reminder['item']);
229 $mail->Body = "Dear ".$patientfname.", This is a message from your clinic to remind you of your ".$category_title.": ".$item_title;
230 $mail->Subject = "Clinic Reminder";
231 if ($mail->Send()) {
232 // deal with and keep track of this successful email
233 sqlStatement("UPDATE `patient_reminders` SET `email_status`='1', `date_sent`=NOW() WHERE id=?", array($reminder['id']) );
234 $logging['number_success_emails']++;
236 else {
237 // deal with and keep track of this unsuccesful email
238 $logging['number_failed_emails']++;
242 // Call to patient if Allow Voice Message and set reminder sent flag.
243 if ($hipaa_voice == "YES") {
244 // Automated VOIP service provided by Maviq. Please visit http://signup.maviq.com for more information.
245 $siteId = $GLOBALS['phone_gateway_username'];
246 $token = $GLOBALS['phone_gateway_password'];
247 $endpoint = $GLOBALS['phone_gateway_url'];
248 $client = new MaviqClient($siteId, $token, $endpoint);
249 //Set up params.
250 $data = array(
251 "firstName" => $patientfname,
252 "lastName" => $patientlname,
253 "phone" => $patientphone,
254 //"apptDate" => "$scheduled_date[1]/$scheduled_date[2]/$scheduled_date[0]",
255 "timeRange" => "10-18",
256 "type" => "reminder",
257 "timeZone" => date('P'),
258 "greeting" => str_replace("[[sender]]", $sender_name, str_replace("[[patient_name]]", $patientfname, $myrow['reminder_content']))
261 // Make the call.
262 $response = $client->sendRequest("appointment", "POST", $data);
264 if ($response->IsError) {
265 // deal with and keep track of this unsuccessful call
266 $logging['number_failed_calls']++;
268 else {
269 // deal with and keep track of this succesful call
270 sqlStatement("UPDATE `patient_reminders` SET `voice_status`='1', `date_sent`=NOW() WHERE id=?", array($reminder['id']) );
271 $logging['number_success_calls']++;
276 // For logging purposes only:
277 // Collect active reminders that have not yet been sent.
278 $logging['total_post_unsent_reminders'] = count(fetch_reminders($patient_id, 'unsent'));
280 return $logging;
283 // Function to fetch reminders
284 // Parameters:
285 // $patient_id - pid of patient. If blank then will check all patients.
286 // $type - unsent (unsent) vs all active (BLANK) reminders
287 // $due_status - due status of reminders (soon_due,due,past_due). If blank,
288 // then will return all.
289 // $select - Select component of select statement. If blank, then
290 // will return all columns.
291 // Return:
292 // Returns a array of reminders
293 function fetch_reminders($patient_id='',$type='',$due_status='',$select='*') {
295 $arraySqlBind = array();
297 if (!empty($patient_id)) {
298 $where = "`pid`=? AND ";
299 array_push($arraySqlBind,$patient_id);
302 if (!empty($due_status)) {
303 $where .= "`due_status`=? AND ";
304 array_push($arraySqlBind,$due_status);
307 if (empty($type)) {
308 $where .= "`active`='1'";
310 else { // $type == 'unsent'
311 $where .= "`active`='1' AND `date_sent` IS NULL";
314 $order = "`due_status`, `date_created`";
316 $sql = "SELECT " . $select . " FROM `patient_reminders` WHERE " .
317 $where . " ORDER BY " . $order;
318 $rez = sqlStatement($sql, $arraySqlBind);
320 $returnval=array();
321 for($iter=0; $row=sqlFetchArray($rez); $iter++)
322 $returnval[$iter]=$row;
324 return $returnval;