Portal Update Forum Request (#2068)
[openemr.git] / interface / batchcom / batchcom.php
blob52233a56ff0081c7f1cb40569e354d7b2a25a5ab
1 <?php
2 /**
3 * Batch Communication Tool for selecting/communicating with subsets of patients
5 * @package OpenEMR
6 * @author Brady Miller <brady.g.miller@gmail.com>
7 * @author Jason 'Toolbox' Oettinger <jason@oettinger.email>
8 * @link http://www.open-emr.org
9 * @copyright Copyright (c) 2017 Brady Miller <brady.g.miller@gmail.com>
10 * @copyright Copyright (c) 2017 Jason 'Toolbox' Oettinger <jason@oettinger.email>
11 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
14 //INCLUDES, DO ANY ACTIONS, THEN GET OUR DATA
15 require_once("../globals.php");
16 require_once("$srcdir/registry.inc");
17 require_once("../../library/acl.inc");
18 require_once("batchcom.inc.php");
20 use OpenEMR\Core\Header;
22 if (!acl_check('admin', 'batchcom')) {
23 echo "<html>\n<body>\n<h1>";
24 echo xlt('You are not authorized for this.');
25 echo "</h1>\n</body>\n</html>";
26 exit();
29 // menu arrays (done this way so it's easier to validate input on validate selections)
30 $process_choices = array(xl('Download CSV File'), xl('Send Emails'), xl('Phone call list'));
31 $gender_choices = array(xl('Any'), xl('Male'), xl('Female'));
32 $hipaa_choices = array(xl('No'), xl('Yes'));
33 $sort_by_choices = array(xl('Zip Code')=>'patient_data.postal_code', xl('Last Name')=>'patient_data.lname', xl('Appointment Date')=>'last_appt');
35 // process form
36 if ($_POST['form_action']=='process') {
37 if (!verifyCsrfToken($_POST["csrf_token_form"])) {
38 csrfNotVerified();
41 //validation uses the functions in batchcom.inc.php
42 //validate dates
43 if (!check_date_format($_POST['app_s'])) {
44 $form_err .= xl('Date format for "appointment start" is not valid');
47 if (!check_date_format($_POST['app_e'])) {
48 $form_err .= xl('Date format for "appointment end" is not valid');
51 if (!check_date_format($_POST['seen_since'])) {
52 $form_err .= xl('Date format for "seen since" is not valid');
55 if (!check_date_format($_POST['seen_before'])) {
56 $form_err .= xl('Date format for "seen before" is not valid');
59 // validate numbers
60 if (!check_age($_POST['age_from'])) {
61 $form_err .= xl('Age format for "age from" is not valid');
64 if (!check_age($_POST['age_upto'])) {
65 $form_err .= xl('Age format for "age up to" is not valid');
68 // validate selections
69 if (!check_select($_POST['gender'], $gender_choices)) {
70 $form_err .= xl('Error in "Gender" selection');
73 if (!check_select($_POST['process_type'], $process_choices)) {
74 $form_err .= xl('Error in "Process" selection');
77 if (!check_select($_POST['hipaa_choice'], $hipaa_choices)) {
78 $form_err .= xl('Error in "HIPAA" selection');
81 if (!check_select($_POST['sort_by'], $sort_by_choices)) {
82 $form_err.=xl('Error in "Sort By" selection');
85 //process sql
86 if (!$form_err) {
87 $sql = "select patient_data.*, cal_events.pc_eventDate as next_appt, cal_events.pc_startTime
88 as appt_start_time,cal_date.last_appt,forms.last_visit from patient_data
89 left outer join openemr_postcalendar_events as cal_events on patient_data.pid=cal_events.pc_pid
90 and curdate() < cal_events.pc_eventDate left outer join (select pc_pid,max(pc_eventDate)
91 as last_appt from openemr_postcalendar_events where curdate() >= pc_eventDate group by pc_pid )
92 as cal_date on cal_date.pc_pid=patient_data.pid left outer join (select pid,max(date)
93 as last_visit from forms where curdate() >= date group by pid)
94 as forms on forms.pid=patient_data.pid where 1=1";
95 $params = array();
97 //appointment dates
98 if ($_POST['app_s']!=0 and $_POST['app_s']!='') {
99 $sql .= " and cal_events.pc_eventDate >= ?";
100 array_push($params, $_POST['app_s']);
103 if ($_POST['app_e']!=0 and $_POST['app_e']!='') {
104 $sql .= " and cal_events.pc_endDate <= ?";
105 array_push($params, $_POST['app_e']);
108 // encounter dates
109 if ($_POST['seen_since']!=0 and $_POST['seen_since']!='') {
110 $sql .= " and forms.date >= ?" ;
111 array_push($params, $_POST['seen_since']);
114 if ($_POST['seen_before']!=0 and $_POST['seen_before']!='') {
115 $sql .= " and forms.date <= ?" ;
116 array_push($params, $_POST['seen_before']);
119 // age
120 if ($_POST['age_from']!=0 and $_POST['age_from']!='') {
121 $sql .= " and DATEDIFF( CURDATE( ), patient_data.DOB )/ 365.25 >= ?";
122 array_push($params, $_POST['age_from']);
125 if ($_POST['age_upto']!=0 and $_POST['age_upto']!='') {
126 $sql .= " and DATEDIFF( CURDATE( ), patient_data.DOB )/ 365.25 <= ?";
127 array_push($params, $_POST['age_upto']);
130 // gender
131 if ($_POST['gender']!='Any') {
132 $sql .= " and patient_data.sex=?";
133 array_push($params, $_POST['gender']);
136 // hipaa override
137 if ($_POST['hipaa_choice'] != $hipaa_choices[0]) {
138 $sql .= " and patient_data.hipaa_mail='YES' ";
141 switch ($_POST['process_type']) :
142 case $choices[1]: // Email
143 $sql.=" and patient_data.email IS NOT NULL ";
144 break;
145 endswitch;
147 // sort by
148 $sql .= ' ORDER BY ' . escape_identifier($_POST['sort_by'], array_values($sort_by_choices), true);
149 // send query for results.
150 //echo $sql;exit();
151 $res = sqlStatement($sql, $params);
153 if (sqlNumRows($res) == 0) {
154 $form_err = xl('No results found, please try again.');
155 } else {
156 switch ($_POST['process_type']) :
157 case $process_choices[0]: // CSV File
158 generate_csv($res);
159 exit();
160 case $process_choices[1]: // Email
161 require_once('batchEmail.php');
162 exit();
163 case $process_choices[2]: // Phone list
164 require_once('batchPhoneList.php');
165 exit();
166 endswitch;
172 <html>
173 <head>
174 <title><?php echo xlt('BatchCom'); ?></title>
175 <?php Header::setupHeader(['datetime-picker']); ?>
176 </head>
177 <body class="body_top container">
178 <header class="row">
179 <?php require_once("batch_navigation.php");?>
180 <h1 class="col-md-6 col-md-offset-3 text-center">
181 <?php echo xlt('Batch Communication Tool')?>
182 </h1>
183 </header>
184 <main>
185 <?php
186 if ($form_err) {
187 echo '<div class="alert alert-danger">' . xlt('The following errors occurred') . ': ' . text($form_err) . '</div>';
190 <form name="select_form" method="post" action="">
191 <input type="hidden" name="csrf_token_form" value="<?php echo attr(collectCsrfToken()); ?>" />
192 <div class="row">
193 <div class="col-md-3 well form-group">
194 <label for="process_type"><?php echo xlt("Process") . ":"; ?></label>
195 <select name="process_type" class="form-control">
196 <?php
197 foreach ($process_choices as $choice) {
198 echo "<option>" . text($choice) . "</option>";
201 </select>
202 </div>
203 <div class="col-md-3 well form-group">
204 <label for="hipaa_choice"><?php echo xlt("Override HIPAA choice") . ":"; ?></label>
205 <select name="hipaa_choice" class="form-control">
206 <?php
207 foreach ($hipaa_choices as $choice) {
208 echo "<option>" . text($choice) . "</option>";
211 </select>
212 </div>
213 <div class="col-md-3 well form-group">
214 <label for="sort_by"><?php echo xlt("Sort by"); ?></label>
215 <select name="sort_by" class="form-control">
216 <?php
217 foreach ($sort_by_choices as $choice => $sorting_code) {
218 echo "<option value=\"$sorting_code\">" . text($choice) . "</option>";
221 </select>
222 </div>
223 <div class="col-md-3 well form-group">
224 <label for="gender"><?php echo xlt('Gender') ?>:</label>
225 <select name="gender" class="form-control">
226 <?php
227 foreach ($gender_choices as $choice) {
228 echo "<option>" . text($choice) . "</option>";
231 </select>
232 </div>
233 </div>
234 <div class="row">
235 <div class="col-md-3 well form-group">
236 <label for="age_from"><?php echo xlt("Age Range") . ":"; ?></label>
237 <input name="age_from" size="2" type="num" class="form-control" placeholder="<?php echo xla("any"); ?>">
238 <label for="age_upto" class="text-center"><?php echo xlt('to'); ?></label>
239 <input name="age_upto" size="2" type="num" class="form-control" placeholder="<?php echo xla("any"); ?>">
240 </div>
241 <div class="col-md-3 well form-group">
242 <label for="app_s"><?php echo xlt('Appointment within') ?>:</label>
243 <input type="text" class="datepicker form-control" name="app_s" placeholder="<?php echo xla('any date'); ?>">
244 <div class="text-center"><?php echo xlt('to'); ?></div>
245 <input type="text" class="datepicker form-control" name="app_e" placeholder="<?php echo xla('any date'); ?>">
246 </div>
247 <!-- later gator <br>Insurance: <SELECT multiple NAME="insurance" Rows="10" cols="20"></SELECT> -->
248 <div class="col-md-3 well form-group">
249 <label for="app_s"><?php echo xlt('Seen within')?>:</label>
250 <input type="text" class="datepicker form-control" name="seen_since" placeholder="<?php echo xla('any date'); ?>">
251 <div class="text-center"><?php echo xlt('to'); ?></div>
252 <input type="text" class="datepicker form-control" name="seen_before" placeholder="<?php echo xla('any date'); ?>">
253 </div>
254 </div>
255 <div class="email row form-group">
256 <div class="col-md-6 col-md-offset-3 well">
257 <div class="col-md-6">
258 <label for="email_sender"><?php echo xlt('Email Sender'); ?>:</label>
259 <input class="form-control" type="text" name="email_sender" placeholder="your@email.email">
260 </div>
262 <div class="col-md-6">
263 <label for="email_subject"><?php echo xlt('Email Subject'); ?>:</label>
264 <input class="form-control" type="text" name="email_subject" placeholder="From your clinic">
265 </div>
266 <div class="col-md-12">
267 <label for="email_subject"><?php echo xlt('Email Text, Usable Tag: ***NAME*** , i.e. Dear ***NAME***{{Do Not translate the ***NAME*** elements of this constant.}}'); ?>:</label>
268 </div>
269 <div class="col-md-12">
270 <textarea class="form-control" name="email_body" id="" cols="40" rows="8"></textarea>
271 </div>
272 </div>
273 </div>
274 <div class="row">
275 <div class="col-md-12 form-group">
276 <input type="hidden" name="form_action" value="process">
277 <button type="submit" name="submit" class="btn btn-default btn-save">
278 <?php echo xla("Process"); ?>
279 </button>
280 </div>
281 </div>
282 </form>
283 </main>
284 </body>
286 <script>
287 (function() {
288 var email = document.querySelector('.email');
289 var process = document.querySelector('select[name="process_type"]');
290 function hideEmail() {
291 if (process.value !== '<?php echo attr($process_choices[1]); ?>') { email.style.display = 'none'; } else { email.style.display = ''; }
293 process.addEventListener('change', hideEmail);
294 hideEmail();
295 $('.datepicker').datetimepicker({
296 <?php $datetimepicker_timepicker = false; ?>
297 <?php $datetimepicker_showseconds = false; ?>
298 <?php $datetimepicker_formatInput = false; ?>
299 <?php require($GLOBALS['srcdir'] . '/js/xl/jquery-datetimepicker-2-5-4.js.php'); ?>
300 <?php // can add any additional javascript settings to datetimepicker here; need to prepend first setting with a comma ?>
302 })();
303 </script>
304 </html>