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