fix: whitelist session pid setting pt from billing manager (#7980)
[openemr.git] / portal / add_edit_event_user.php
blobd4cfb83054548390c65d2badbbd7436bcc463c98
1 <?php
3 /**
5 * Modified from interface/main/calendar/add_edit_event.php for
6 * the patient portal.
8 * @package OpenEMR
9 * @link http://www.open-emr.org
10 * @author Rod Roark <rod@sunsetsystems.com>
11 * @author Jerry Padgett <sjpadgett@gmail.com>
12 * @author Brady Miller <brady.g.miller@gmail.com>
13 * @copyright Copyright (C) 2005-2006 Rod Roark <rod@sunsetsystems.com>
14 * @copyright Copyright (C) 2016-2021 Jerry Padgett <sjpadgett@gmail.com>
15 * @copyright Copyright (c) 2019 Brady Miller <brady.g.miller@gmail.com>
16 * @license https://github.com/openemr/openemr/blob/master/LICENSE GNU General Public License 3
19 // Will start the (patient) portal OpenEMR session/cookie.
20 require_once(__DIR__ . "/../src/Common/Session/SessionUtil.php");
21 OpenEMR\Common\Session\SessionUtil::portalSessionStart();
23 require_once("./../library/pnotes.inc.php");
25 //landing page definition -- where to go if something goes wrong
26 $landingpage = "index.php?site=" . urlencode($_SESSION['site_id']);
29 // kick out if patient not authenticated
30 if (isset($_SESSION['pid']) && isset($_SESSION['patient_portal_onsite_two'])) {
31 $pid = $_SESSION['pid'];
32 } else {
33 OpenEMR\Common\Session\SessionUtil::portalSessionCookieDestroy();
34 header('Location: ' . $landingpage . '&w');
35 exit;
38 $ignoreAuth_onsite_portal = true;
39 global $ignoreAuth_onsite_portal;
41 require_once("../interface/globals.php");
42 require_once("$srcdir/patient.inc.php");
43 require_once("$srcdir/forms.inc.php");
44 require_once("$srcdir/appointments.inc.php");
46 use OpenEMR\Services\AppointmentService;
48 // Things that might be passed by our opener.
50 $eid = intval($_GET['eid'] ?? 0); // only for existing events
51 $date = $_GET['date'] ?? null; // this and below only for new events
52 $userid = $_GET['userid'] ?? null;
53 $default_catid = ($_GET['catid'] ?? null) ? $_GET['catid'] : '5';
54 $patientid = $_GET['patid'] ?? null;
57 // did someone tamper with eid?
58 $checkEidInAppt = false;
59 $patient_appointments = fetchAppointments('1970-01-01', '2382-12-31', $pid);
60 $checkEidInAppt = array_search($eid, array_column($patient_appointments, 'pc_eid'));
62 if ($eid !== 0 && $checkEidInAppt === false) {
63 echo js_escape("error");
64 exit();
67 if (!empty($_POST['form_pid'])) {
68 if ($_POST['form_pid'] != $pid) {
69 echo js_escape("error");
70 exit();
73 if (! getAvailableSlots($_POST['form_date'], date('Y-m-d', strtotime("+1 year " . $_POST['form_date'])), $_POST['form_provider_ae'])) {
74 echo js_escape("error");
75 exit();
78 $appointment_service = (new AppointmentService())->getOneCalendarCategory($_POST['form_category']);
79 if (($_POST['form_duration'] * 60) != ($appointment_service[0]['pc_duration'])) {
80 echo js_escape("error");
81 exit();
85 if ($date) {
86 $date = substr($date, 0, 4) . '-' . substr($date, 4, 2) . '-' . substr($date, 6);
87 } else {
88 $date = date("Y-m-d");
90 // internationalize the date
91 $date = oeFormatShortDate($date);
94 $starttimem = '00';
95 if (isset($_GET['starttimem'])) {
96 $starttimem = substr('00' . $_GET['starttimem'], -2);
100 if (isset($_GET['starttimeh'])) {
101 $starttimeh = $_GET['starttimeh'];
102 if (isset($_GET['startampm'])) {
103 if ($_GET['startampm'] == '2' && $starttimeh < 12) {
104 $starttimeh += 12;
107 } else {
108 $starttimeh = date("G");
111 $startampm = '';
113 $info_msg = "";
115 // EVENTS TO FACILITIES (lemonsoftware)
116 //(CHEMED) get facility name
117 // edit event case - if there is no association made, then insert one with the first facility
118 if ($eid !== 0) {
119 $selfacil = '';
120 $facility = sqlQuery("SELECT pc_facility, pc_multiple, pc_aid, facility.name
121 FROM openemr_postcalendar_events
122 LEFT JOIN facility ON (openemr_postcalendar_events.pc_facility = facility.id)
123 WHERE pc_eid = ?", array($eid));
124 if (!$facility['pc_facility']) {
125 $qmin = sqlQuery("SELECT facility_id as minId, facility FROM users WHERE id = ?", array($facility['pc_aid']));
126 $min = $qmin['minId'];
127 $min_name = $qmin['facility'];
129 // multiple providers case
130 if ($GLOBALS['select_multi_providers']) {
131 $mul = $facility['pc_multiple'];
132 sqlStatement("UPDATE openemr_postcalendar_events SET pc_facility = ? WHERE pc_multiple = ?", array($min, $mul));
135 // EOS multiple
137 sqlStatement("UPDATE openemr_postcalendar_events SET pc_facility = ? WHERE pc_eid = ?", array($min, $eid));
138 $e2f = $min;
139 $e2f_name = $min_name;
140 } else {
141 $e2f = $facility['pc_facility'];
142 $e2f_name = $facility['name'];
146 // EOS E2F
147 // ===========================
150 // If we are saving, then save and close the window.
152 if (($_POST['form_action'] ?? null) == "save") {
153 //print_r($_POST);
154 //exit();
155 $event_date = fixDate($_POST['form_date']);
157 // Compute start and end time strings to be saved.
158 if ($_POST['form_allday'] ?? null) {
159 $tmph = 0;
160 $tmpm = 0;
161 $duration = 24 * 60;
162 } else {
163 $tmph = $_POST['form_hour'] + 0;
164 $tmpm = $_POST['form_minute'] + 0;
165 if ($_POST['form_ampm'] == '2' && $tmph < 12) {
166 $tmph += 12;
169 $duration = $_POST['form_duration'];
172 $starttime = "$tmph:$tmpm:00";
174 $tmpm += $duration;
175 while ($tmpm >= 60) {
176 $tmpm -= 60;
177 ++$tmph;
180 $endtime = "$tmph:$tmpm:00";
182 // Useless garbage that we must save.
183 $locationspec = 'a:6:{s:14:"event_location";N;s:13:"event_street1";N;' .
184 's:13:"event_street2";N;s:10:"event_city";N;s:11:"event_state";N;s:12:"event_postal";N;}';
186 // More garbage, but this time 1 character of it is used to save the
187 // repeat type.
188 if ($_POST['form_repeat'] ?? null) {
189 $recurrspec = 'a:5:{' .
190 's:17:"event_repeat_freq";s:1:"' . $_POST['form_repeat_freq'] . '";' .
191 's:22:"event_repeat_freq_type";s:1:"' . $_POST['form_repeat_type'] . '";' .
192 's:19:"event_repeat_on_num";s:1:"1";' .
193 's:19:"event_repeat_on_day";s:1:"0";' .
194 's:20:"event_repeat_on_freq";s:1:"0";}';
195 } else {
196 $recurrspec = 'a:5:{' .
197 's:17:"event_repeat_freq";N;' .
198 's:22:"event_repeat_freq_type";s:1:"0";' .
199 's:19:"event_repeat_on_num";s:1:"1";' .
200 's:19:"event_repeat_on_day";s:1:"0";' .
201 's:20:"event_repeat_on_freq";s:1:"1";}';
204 //The modification of the start date for events that take place on one day of the week
205 //for example monday, or thursday. We set the start date on the first day of the week
206 //that the event is scheduled. For example if you set the event to repeat on each monday
207 //the start date of the event will be set on the first monday after the day the event is scheduled
208 if (($_POST['form_repeat_type'] ?? null) == 5) {
209 $exploded_date = explode("-", $event_date);
210 $edate = date("D", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2], $exploded_date[0]));
211 if ($edate == "Tue") {
212 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 6, $exploded_date[0]));
213 } elseif ($edate == "Wed") {
214 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 5, $exploded_date[0]));
215 } elseif ($edate == "Thu") {
216 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 4, $exploded_date[0]));
217 } elseif ($edate == "Fri") {
218 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 3, $exploded_date[0]));
219 } elseif ($edate == "Sat") {
220 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 2, $exploded_date[0]));
221 } elseif ($edate == "Sun") {
222 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 1, $exploded_date[0]));
224 } elseif (($_POST['form_repeat_type'] ?? null) == 6) {
225 $exploded_date = explode("-", $event_date);
226 $edate = date("D", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2], $exploded_date[0]));
227 if ($edate == "Wed") {
228 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 6, $exploded_date[0]));
229 } elseif ($edate == "Thu") {
230 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 5, $exploded_date[0]));
231 } elseif ($edate == "Fri") {
232 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 4, $exploded_date[0]));
233 } elseif ($edate == "Sat") {
234 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 3, $exploded_date[0]));
235 } elseif ($edate == "Sun") {
236 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 2, $exploded_date[0]));
237 } elseif ($edate == "Mon") {
238 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 1, $exploded_date[0]));
240 } elseif (($_POST['form_repeat_type'] ?? null) == 7) {
241 $exploded_date = explode("-", $event_date);
242 $edate = date("D", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2], $exploded_date[0]));
243 if ($edate == "Thu") {
244 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 6, $exploded_date[0]));
245 } elseif ($edate == "Fri") {
246 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 5, $exploded_date[0]));
247 } elseif ($edate == "Sat") {
248 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 4, $exploded_date[0]));
249 } elseif ($edate == "Sun") {
250 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 3, $exploded_date[0]));
251 } elseif ($edate == "Mon") {
252 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 2, $exploded_date[0]));
253 } elseif ($edate == "Tue") {
254 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 1, $exploded_date[0]));
256 } elseif (($_POST['form_repeat_type'] ?? null) == 8) {
257 $exploded_date = explode("-", $event_date);
258 $edate = date("D", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2], $exploded_date[0]));
259 if ($edate == "Fri") {
260 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 6, $exploded_date[0]));
261 } elseif ($edate == "Sat") {
262 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 5, $exploded_date[0]));
263 } elseif ($edate == "Sun") {
264 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 4, $exploded_date[0]));
265 } elseif ($edate == "Mon") {
266 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 3, $exploded_date[0]));
267 } elseif ($edate == "Tue") {
268 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 2, $exploded_date[0]));
269 } elseif ($edate == "Wed") {
270 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 1, $exploded_date[0]));
272 } elseif (($_POST['form_repeat_type'] ?? null) == 9) {
273 $exploded_date = explode("-", $event_date);
274 $edate = date("D", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2], $exploded_date[0]));
275 if ($edate == "Sat") {
276 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 6, $exploded_date[0]));
277 } elseif ($edate == "Sun") {
278 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 5, $exploded_date[0]));
279 } elseif ($edate == "Mon") {
280 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 4, $exploded_date[0]));
281 } elseif ($edate == "Tue") {
282 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 3, $exploded_date[0]));
283 } elseif ($edate == "Wed") {
284 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 2, $exploded_date[0]));
285 } elseif ($edate == "Thu") {
286 $event_date = date("Y-m-d", mktime(0, 0, 0, $exploded_date[1], $exploded_date[2] + 1, $exploded_date[0]));
288 }//if end
289 /* =======================================================
290 // UPDATE EVENTS
291 ========================================================*/
292 if ($eid !== 0) {
293 // what is multiple key around this $eid?
294 $row = sqlQuery("SELECT pc_multiple FROM openemr_postcalendar_events WHERE pc_eid = ?", array($eid));
296 if ($GLOBALS['select_multi_providers'] && $row['pc_multiple']) {
297 /* ==========================================
298 // multi providers BOS
299 ==========================================*/
301 // obtain current list of providers regarding the multiple key
302 $up = sqlStatement("SELECT pc_aid FROM openemr_postcalendar_events WHERE pc_multiple = ?", array($row['pc_multiple']));
303 while ($current = sqlFetchArray($up)) {
304 $providers_current[] = $current['pc_aid'];
307 $providers_new = $_POST['form_provider_ae'];
309 // this difference means that some providers from current was UNCHECKED
310 // so we must delete this event for them
311 $r1 = array_diff($providers_current, $providers_new);
312 if (count($r1)) {
313 foreach ($r1 as $to_be_removed) {
314 sqlQuery("DELETE FROM openemr_postcalendar_events WHERE pc_aid = ? AND pc_multiple = ?", array($to_be_removed, $row['pc_multiple']));
318 // this difference means that some providers was added
319 // so we must insert this event for them
320 $r2 = array_diff($providers_new, $providers_current);
321 if (count($r2)) {
322 foreach ($r2 as $to_be_inserted) {
323 sqlStatement("INSERT INTO openemr_postcalendar_events ( pc_catid, pc_multiple, pc_aid, pc_pid, pc_title, pc_time, pc_hometext, pc_informant, pc_eventDate, pc_endDate, pc_duration, pc_recurrtype, pc_recurrspec, pc_startTime, pc_endTime, pc_alldayevent, pc_apptstatus, pc_prefcatid, pc_location, pc_eventstatus, pc_sharing, pc_facility)
324 VALUES ( " .
325 "'" . add_escape_custom($_POST['form_category']) . "', " .
326 "'" . add_escape_custom($row['pc_multiple']) . "', " .
327 "'" . add_escape_custom($to_be_inserted) . "', " .
328 "'" . add_escape_custom($pid) . "', " .
329 "'" . add_escape_custom($_POST['form_title']) . "', " .
330 "NOW(), " .
331 "'" . add_escape_custom($_POST['form_comments']) . "', " .
332 "'" . add_escape_custom($_SESSION['providerId']) . "', " .
333 "'" . add_escape_custom($event_date) . "', " .
334 "'" . add_escape_custom(fixDate($_POST['form_enddate'])) . "', " .
335 "'" . add_escape_custom(($duration * 60)) . "', " .
336 "'" . ($_POST['form_repeat'] ? '1' : '0') . "', " .
337 "'" . add_escape_custom($recurrspec) . "', " .
338 "'" . add_escape_custom($starttime) . "', " .
339 "'" . add_escape_custom($endtime) . "', " .
340 "'" . add_escape_custom($_POST['form_allday']) . "', " .
341 "'" . add_escape_custom($_POST['form_apptstatus']) . "', " .
342 "'" . add_escape_custom($_POST['form_prefcat']) . "', " .
343 "'" . add_escape_custom($locationspec) . "', " .
344 "1, " .
345 "1, " . (int)$_POST['facility'] . " )"); // FF stuff
346 } // foreach
347 } //if count
350 // after the two diffs above, we must update for remaining providers
351 // those who are intersected in $providers_current and $providers_new
352 foreach ($_POST['form_provider_ae'] as $provider) {
353 sqlStatement("UPDATE openemr_postcalendar_events SET " .
354 "pc_catid = '" . add_escape_custom($_POST['form_category']) . "', " .
355 "pc_pid = '" . add_escape_custom($pid) . "', " .
356 "pc_title = '" . add_escape_custom($_POST['form_title']) . "', " .
357 "pc_time = NOW(), " .
358 "pc_hometext = '" . add_escape_custom($_POST['form_comments']) . "', " .
359 "pc_informant = '" . add_escape_custom($_SESSION['providerId']) . "', " .
360 "pc_eventDate = '" . add_escape_custom($event_date) . "', " .
361 "pc_endDate = '" . add_escape_custom(fixDate($_POST['form_enddate'])) . "', " .
362 "pc_duration = '" . add_escape_custom(($duration * 60)) . "', " .
363 "pc_recurrtype = '" . ($_POST['form_repeat'] ? '1' : '0') . "', " .
364 "pc_recurrspec = '" . add_escape_custom($recurrspec) . "', " .
365 "pc_startTime = '" . add_escape_custom($starttime) . "', " .
366 "pc_endTime = '" . add_escape_custom($endtime) . "', " .
367 "pc_alldayevent = '" . add_escape_custom($_POST['form_allday']) . "', " .
368 "pc_apptstatus = '" . add_escape_custom($_POST['form_apptstatus']) . "', " .
369 "pc_prefcatid = '" . add_escape_custom($_POST['form_prefcat']) . "', " .
370 "pc_facility = '" . (int)$_POST['facility'] . "' " . // FF stuff
371 "WHERE pc_aid = '" . add_escape_custom($provider) . "' AND pc_multiple='" . add_escape_custom($row['pc_multiple']) . "'");
372 } // foreach
374 /* ==========================================
375 // multi providers EOS
376 ==========================================*/
377 } elseif (!$row['pc_multiple']) {
378 if ($GLOBALS['select_multi_providers']) {
379 $prov = $_POST['form_provider_ae'][0];
380 } else {
381 $prov = $_POST['form_provider_ae'];
383 $insert = false;
384 // simple provider case
385 sqlStatement("UPDATE openemr_postcalendar_events SET " .
386 "pc_catid = '" . add_escape_custom($_POST['form_category']) . "', " .
387 "pc_aid = '" . add_escape_custom($prov) . "', " .
388 "pc_pid = '" . add_escape_custom($pid) . "', " .
389 "pc_title = '" . add_escape_custom($_POST['form_title']) . "', " .
390 "pc_time = NOW(), " .
391 "pc_hometext = '" . add_escape_custom($_POST['form_comments']) . "', " .
392 "pc_informant = '" . add_escape_custom($_SESSION['providerId']) . "', " .
393 "pc_eventDate = '" . add_escape_custom($event_date) . "', " .
394 "pc_endDate = '" . add_escape_custom(fixDate($_POST['form_enddate'] ?? '')) . "', " .
395 "pc_duration = '" . add_escape_custom(($duration * 60)) . "', " .
396 "pc_recurrtype = '" . (($_POST['form_repeat'] ?? null) ? '1' : '0') . "', " .
397 "pc_recurrspec = '" . add_escape_custom($recurrspec) . "', " .
398 "pc_startTime = '" . add_escape_custom($starttime) . "', " .
399 "pc_endTime = '" . add_escape_custom($endtime) . "', " .
400 "pc_alldayevent = '" . add_escape_custom(($_POST['form_allday'] ?? '')) . "', " .
401 "pc_apptstatus = '" . add_escape_custom($_POST['form_apptstatus']) . "', " .
402 "pc_prefcatid = '" . add_escape_custom(($_POST['form_prefcat'] ?? '')) . "', " .
403 "pc_facility = '" . (int)($_POST['facility'] ?? null) . "' " . // FF stuff
404 "WHERE pc_eid = '" . add_escape_custom($eid) . "'");
407 // =======================================
408 // EOS multi providers case
409 // =======================================
411 // EVENTS TO FACILITIES
413 $e2f = (int)$eid;
415 /* =======================================================
416 // INSERT EVENTS
417 ========================================================*/
418 } else {
419 // =======================================
420 // multi providers case
421 // =======================================
423 if (is_array($_POST['form_provider_ae'])) {
424 // obtain the next available unique key to group multiple providers around some event
425 $q = sqlStatement("SELECT MAX(pc_multiple) as max FROM openemr_postcalendar_events");
426 $max = sqlFetchArray($q);
427 $new_multiple_value = $max['max'] + 1;
429 foreach ($_POST['form_provider_ae'] as $provider) {
430 sqlStatement("INSERT INTO openemr_postcalendar_events ( " .
431 "pc_catid, pc_multiple, pc_aid, pc_pid, pc_title, pc_time, pc_hometext, " .
432 "pc_informant, pc_eventDate, pc_endDate, pc_duration, pc_recurrtype, " .
433 "pc_recurrspec, pc_startTime, pc_endTime, pc_alldayevent, " .
434 "pc_apptstatus, pc_prefcatid, pc_location, pc_eventstatus, pc_sharing, pc_facility " .
435 ") VALUES ( " .
436 "'" . add_escape_custom($_POST['form_category']) . "', " .
437 "'" . add_escape_custom($new_multiple_value) . "', " .
438 "'" . add_escape_custom($provider) . "', " .
439 "'" . add_escape_custom($pid) . "', " .
440 "'" . add_escape_custom($_POST['form_title']) . "', " .
441 "NOW(), " .
442 "'" . add_escape_custom($_POST['form_comments']) . "', " .
443 "'" . add_escape_custom($_SESSION['providerId']) . "', " .
444 "'" . add_escape_custom($event_date) . "', " .
445 "'" . add_escape_custom(fixDate($_POST['form_enddate'])) . "', " .
446 "'" . add_escape_custom(($duration * 60)) . "', " .
447 "'" . ($_POST['form_repeat'] ? '1' : '0') . "', " .
448 "'" . add_escape_custom($recurrspec) . "', " .
449 "'" . add_escape_custom($starttime) . "', " .
450 "'" . add_escape_custom($endtime) . "', " .
451 "'" . add_escape_custom($_POST['form_allday']) . "', " .
452 "'" . add_escape_custom($_POST['form_apptstatus']) . "', " .
453 "'" . add_escape_custom($_POST['form_prefcat']) . "', " .
454 "'" . add_escape_custom($locationspec) . "', " .
455 "1, " .
456 "1, " . (int)$_POST['facility'] . " )"); // FF stuff
457 } // foreach
458 } else {
459 $_POST['form_apptstatus'] = '^';
460 $insert = true;
461 sqlStatement("INSERT INTO openemr_postcalendar_events ( " .
462 "pc_catid, pc_aid, pc_pid, pc_title, pc_time, pc_hometext, " .
463 "pc_informant, pc_eventDate, pc_endDate, pc_duration, pc_recurrtype, " .
464 "pc_recurrspec, pc_startTime, pc_endTime, pc_alldayevent, " .
465 "pc_apptstatus, pc_prefcatid, pc_location, pc_eventstatus, pc_sharing, pc_facility " .
466 ") VALUES ( " .
467 "'" . add_escape_custom($_POST['form_category']) . "', " .
468 "'" . add_escape_custom($_POST['form_provider_ae']) . "', " .
469 "'" . add_escape_custom($pid) . "', " .
470 "'" . add_escape_custom($_POST['form_title']) . "', " .
471 "NOW(), " .
472 "'" . add_escape_custom($_POST['form_comments']) . "', " .
473 "'" . add_escape_custom($_SESSION['providerId']) . "', " .
474 "'" . add_escape_custom($event_date) . "', " .
475 "'" . add_escape_custom(fixDate(($_POST['form_enddate'] ?? ''))) . "', " .
476 "'" . add_escape_custom(($duration * 60)) . "', " .
477 "'" . (($_POST['form_repeat'] ?? null) ? '1' : '0') . "', " .
478 "'" . add_escape_custom($recurrspec) . "', " .
479 "'" . add_escape_custom($starttime) . "', " .
480 "'" . add_escape_custom($endtime) . "', " .
481 "'" . add_escape_custom(($_POST['form_allday'] ?? '')) . "', " .
482 "'" . add_escape_custom($_POST['form_apptstatus']) . "', " .
483 "'" . add_escape_custom(($_POST['form_prefcat'] ?? null)) . "', " .
484 "'" . add_escape_custom($locationspec) . "', " .
485 "1, " .
486 "1, " . (int)($_POST['facility'] ?? null) . ")"); // FF stuff
487 } // INSERT single
488 } // else - insert
489 } elseif (($_POST['form_action'] ?? null) == "delete") {
490 // =======================================
491 // multi providers case
492 // =======================================
493 if ($GLOBALS['select_multi_providers']) {
494 // what is multiple key around this $eid?
495 $row = sqlQuery("SELECT pc_multiple FROM openemr_postcalendar_events WHERE pc_eid = ?", array($eid));
496 if ($row['pc_multiple']) {
497 sqlStatement("DELETE FROM openemr_postcalendar_events WHERE pc_multiple = ?", array($row['pc_multiple']));
498 } else {
499 sqlStatement("DELETE FROM openemr_postcalendar_events WHERE pc_eid = ?", array($eid));
502 // =======================================
503 // EOS multi providers case
504 // =======================================
505 } else {
506 sqlStatement("DELETE FROM openemr_postcalendar_events WHERE pc_eid = ?", array($eid));
510 if (!empty($_POST['form_action'])) {
511 // Leave
512 $type = $insert ? xl("A New Appointment") : xl("An Updated Appointment");
513 $note = $type . " " . xl("request was received from portal patient") . " ";
514 $note .= $_SESSION['ptName'] . " " . xl("regarding appointment dated") . " " . $event_date . " " . $starttime . ". ";
515 $note .= !empty($_POST['form_comments']) ? (xl("Reason") . " " . $_POST['form_comments']) : "";
516 $note .= ". " . xl("Use Portal Dashboard to confirm with patient.");
517 $title = xl("Patient Reminders");
518 $user = sqlQueryNoLog("SELECT users.username FROM users WHERE authorized = 1 And id = ?", array($_POST['form_provider_ae']));
519 $rtn = addPnote($pid, $note, 1, 1, $title, $user['username'], '', 'New');
521 $_SESSION['whereto'] = '#appointmentcard';
522 header('Location:./home.php');
523 exit();
526 // If we get this far then we are displaying the form.
528 $statuses = array(
529 '-' => '',
530 '*' => xl('* Reminder done'),
531 '+' => xl('+ Chart pulled'),
532 'x' => xl('x Cancelled'), // added Apr 2008 by JRM
533 '?' => xl('? No show'),
534 '@' => xl('@ Arrived'),
535 '~' => xl('~ Arrived late'),
536 '!' => xl('! Left w/o visit'),
537 '#' => xl('# Ins/fin issue'),
538 '<' => xl('< In exam room'),
539 '>' => xl('> Checked out'),
540 '$' => xl('$ Coding done'),
541 '^' => xl('^ Pending'),
544 $repeats = 0; // if the event repeats
545 $repeattype = '0';
546 $repeatfreq = '0';
547 $patienttitle = "";
548 $hometext = "";
549 $row = array();
551 // If we are editing an existing event, then get its data.
552 if ($eid !== 0) {
553 $row = sqlQuery("SELECT * FROM openemr_postcalendar_events WHERE pc_eid = ?", array($eid));
554 $date = oeFormatShortDate($row['pc_eventDate']);
555 $userid = $row['pc_aid'];
556 $patientid = $row['pc_pid'];
557 $starttimeh = substr($row['pc_startTime'], 0, 2) + 0;
558 $starttimem = substr($row['pc_startTime'], 3, 2);
559 $repeats = $row['pc_recurrtype'];
560 $multiple_value = $row['pc_multiple'];
562 if (preg_match('/"event_repeat_freq_type";s:1:"(\d)"/', $row['pc_recurrspec'], $matches)) {
563 $repeattype = $matches[1];
566 if (preg_match('/"event_repeat_freq";s:1:"(\d)"/', $row['pc_recurrspec'], $matches)) {
567 $repeatfreq = $matches[1];
570 $hometext = $row['pc_hometext'];
571 if (substr($hometext, 0, 6) == ':text:') {
572 $hometext = substr($hometext, 6);
574 } else {
575 $patientid = $pid;
578 // If we have a patient ID, get the name and phone numbers to display.
579 if ($patientid) {
580 $prow = sqlQuery("SELECT lname, fname, phone_home, phone_biz, DOB " .
581 "FROM patient_data WHERE pid = ?", array($patientid));
582 $patientname = $prow['lname'] . ", " . $prow['fname'];
583 if ($prow['phone_home']) {
584 $patienttitle .= " H=" . $prow['phone_home'];
587 if ($prow['phone_biz']) {
588 $patienttitle .= " W=" . $prow['phone_biz'];
592 // Get the providers list.
593 $ures = sqlStatement("SELECT `id`, `username`, `fname`, `lname`, `mname` FROM `users` WHERE " .
594 "`authorized` != 0 AND `active` = 1 AND `username` > '' ORDER BY `lname`, `fname`");
596 //Set default facility for a new event based on the given 'userid'
597 if ($userid) {
598 $pref_facility = sqlFetchArray(sqlStatement("SELECT facility_id, facility FROM users WHERE id = ?", array($userid)));
599 $e2f = $pref_facility['facility_id'];
600 $e2f_name = $pref_facility['facility'];
603 <!DOCTYPE html>
604 <html>
605 <head>
606 <title><?php echo $eid ? xlt("Edit Event") : xlt("Add New Event"); ?></title>
607 <?php // no header necessary. scope is home.php ?>
608 </head>
609 <script>
610 var durations = Array();
611 <?php
612 // Read the event categories, generate their options list, and get
613 // the default event duration from them if this is a new event.
614 $cattype = 0;
616 // Get event categories.
617 $cres = sqlStatement("SELECT pc_catid, pc_cattype, pc_constant_id, pc_catname, " .
618 "pc_recurrtype, pc_duration, pc_end_all_day " .
619 "FROM openemr_postcalendar_categories where pc_active = 1 ORDER BY pc_seq");
620 $catoptions = "";
621 $prefcat_options = " <option value='0'>-- " . xlt("None{{Category}}") . " --</option>\n";
622 $thisduration = 0;
623 if ($eid !== 0) {
624 $thisduration = $row['pc_alldayevent'] ? 1440 : round($row['pc_duration'] / 60);
626 while ($crow = sqlFetchArray($cres)) {
627 $duration = round($crow['pc_duration'] / 60);
628 if ($crow['pc_end_all_day']) {
629 $duration = 1440;
632 // This section is to build the list of preferred categories:
633 if ($duration) {
634 $prefcat_options .= " <option value='" . attr($crow['pc_catid']) . "'";
635 if ($eid !== 0) {
636 if ($crow['pc_catid'] == $row['pc_prefcatid']) {
637 $prefcat_options .= " selected";
641 $prefcat_options .= ">" . text(xl_appt_category($crow['pc_catname'])) . "</option>\n";
644 if ($crow['pc_cattype'] != $cattype || $crow['pc_constant_id'] === AppointmentService::CATEGORY_CONSTANT_NO_SHOW) {
645 continue;
648 echo " durations[" . attr($crow['pc_catid']) . "] = " . attr($duration) . ";\n";
649 // echo " rectypes[" . $crow['pc_catid'] . "] = " . $crow['pc_recurrtype'] . "\n";
650 $catoptions .= " <option value='" . attr($crow['pc_catid']) . "'";
651 if ($eid !== 0) {
652 if ($crow['pc_catid'] == $row['pc_catid']) {
653 $catoptions .= " selected";
655 } else {
656 if ($crow['pc_catid'] == $default_catid) {
657 $catoptions .= " selected";
658 $thisduration = $duration;
662 $catoptions .= ">" . text(xl_appt_category($crow['pc_catname'])) . "</option>\n";
664 // Fix up the time format for AM/PM.
665 $startampm = '1';
666 if ($starttimeh >= 12) { // p.m. starts at noon and not 12:01
667 $startampm = '2';
668 if ($starttimeh > 12) {
669 $starttimeh -= 12;
674 </script>
675 <body class="skin-blue">
676 <div class="container-fluid">
677 <form method='post' name='theaddform' id='theaddform' action='add_edit_event_user.php?eid=<?php echo attr_url($eid); ?>'>
678 <div class="col-12">
679 <input type="hidden" name="form_action" id="form_action" value="" />
680 <input type='hidden' name='form_title' id='form_title' value='<?php echo ($row['pc_catid'] ?? '') ? attr($row['pc_title']) : xla("Office Visit"); ?>' />
681 <input type='hidden' name='form_apptstatus' id='form_apptstatus' value='<?php echo ($row['pc_apptstatus'] ?? '') ? attr($row['pc_apptstatus'] ?? '') : "^" ?>' />
682 <div class="row form-group">
683 <div class="input-group col-12 col-md-6">
684 <label class="mr-2" for="form_category"><?php echo xlt('Visit'); ?>:</label>
685 <select class="form-control mb-1" onchange='set_category()' id='form_category' name='form_category' value='<?php echo (($row['pc_catid'] ?? '') > "") ? attr($row['pc_catid']) : '5'; ?>'>
686 <?php echo $catoptions ?>
687 </select>
688 </div>
689 <div class="input-group col-12 col-md-6">
690 <label class="mr-2" for="form_date"><?php echo xlt('Date'); ?>:</label>
691 <input class="form-control mb-1" type='text' name='form_date' readonly id='form_date' value='<?php echo (isset($eid) && $eid !== 0) ? attr(oeFormatShortDate($row['pc_eventDate'])) : attr($date); ?>' />
692 </div>
693 </div>
694 <div class="row">
695 <div class="form-group form-inline col-12">
696 <div class="input-group mb-1">
697 <label class="mr-2"><?php echo xlt('Time'); ?>:</label>
698 <input class="form-control col-2 col-md-3" type='text' name='form_hour' size='2' value='<?php echo ((isset($eid) && $eid !== 0)) ? $starttimeh : ''; ?>' title='<?php echo xla('Event start time'); ?>' readonly />
699 <input class="form-control col-2 col-md-3" type='text' name='form_minute' size='2' value='<?php echo ((isset($eid) && $eid !== 0)) ? $starttimem : ''; ?>' title='<?php echo xla('Event start time'); ?>' readonly />
700 <select class="form-control col-3 col-md-4" name='form_ampm' title='Note: 12:00 noon is PM, not AM' readonly>
701 <option value='1'><?php echo xlt('AM'); ?></option>
702 <option value='2'<?php echo ($startampm == '2') ? " selected" : ""; ?>><?php echo xlt('PM'); ?></option>
703 </select>
704 </div>
705 <div class="input-group">
706 <label class="mr-2" for="form_duration"><?php echo xlt('Duration'); ?></label>
707 <input class="form-control" type='text' size='1' id='form_duration' name='form_duration' value='<?php echo ($row['pc_duration'] ?? '') ? ($row['pc_duration'] * 1 / 60) : attr($thisduration) ?>' readonly />
708 <span class="input-group-append">
709 <span class="input-group-text"><?php echo "&nbsp;" . xlt('minutes'); ?></span>
710 </span>
711 </div>
712 </div>
713 </div>
714 <div class="row">
715 <div class="input-group col-12 mb-1">
716 <label class="mr-2" for="form_patient"><?php echo xlt('Patient'); ?>:</label>
717 <input class="form-control" type='text' id='form_patient' name='form_patient' value='<?php echo attr($patientname); ?>' title='Patient' readonly />
718 <input type='hidden' name='form_pid' value='<?php echo attr($patientid); ?>' />
719 </div>
720 </div>
721 <div class="row">
722 <div class="input-group col-12 mb-1">
723 <label class="mr-2" for="form_provider_ae"><?php echo xlt('Provider'); ?>:</label>
724 <select class="form-control" name='form_provider_ae' id='form_provider_ae' onchange='change_provider();'>
725 <?php
726 // present a list of providers to choose from
727 // default to the currently logged-in user
728 while ($urow = sqlFetchArray($ures)) {
729 echo "<option value='" . attr($urow['id']) . "'";
730 if (($urow['id'] == ($_GET['userid'] ?? null)) || ($urow['id'] == $userid)) {
731 echo " selected";
733 echo ">" . text($urow['lname']);
734 if ($urow['fname']) {
735 echo ", " . text($urow['fname']);
737 echo "</option>\n";
740 </select>
741 <div class="text-right">
742 <input type='button' class='btn btn-success' value='<?php echo xla('See Availability'); ?>' onclick='find_available()' />
743 </div>
744 </div>
745 </div>
746 <div class="row">
747 <div class="input-group col-12">
748 <label class="mr-2"><?php echo xlt('Reason'); ?>:</label>
749 <input class="form-control" type='text' size='40' name='form_comments' value='<?php echo attr($hometext); ?>' title='<?php echo xla('Optional information about this event'); ?>' />
750 </div>
751 </div>
752 <div class="row input-group my-1">
753 <?php if (($_GET['eid'] ?? null) && $row['pc_apptstatus'] !== 'x') { ?>
754 <input type='button' id='form_cancel' class='btn btn-danger' onsubmit='return false' value='<?php echo xla('Cancel Appointment'); ?>' onclick="cancel_appointment()" />
755 <?php } ?>
756 <input type='button' name='form_save' class='btn btn-success' onsubmit='return false' value='<?php echo xla('Save'); ?>' onclick="validate()" />
757 </div>
758 </div>
759 </form>
760 <script>
761 function change_provider() {
762 var f = document.forms.namedItem("theaddform");
763 // use today's date but reset everything else when changing providers so we can
764 // search on availability. jsGlobals['date_display_format']
765 f.form_date.value = window.top.oeFormatters.I18NDateFormat(new Date());
766 f.form_hour.value = '';
767 f.form_minute.value = '';
770 function set_display() {
771 var f = document.forms.namedItem("theaddform");
772 var si = document.getElementById('form_category');
773 if (si.selectedIndex >= 0) {
774 var catid = si.options[si.selectedIndex].value;
775 //var style_apptstatus = document.getElementById('title_apptstatus').style;
776 //var style_prefcat = document.getElementById('title_prefcat').style;
777 // will keep this for future. not needed now.
781 function cancel_appointment() {
782 let f = document.forms.namedItem("theaddform");
783 let msg = <?php echo xlj("Click Okay if you are sure you want to cancel this appointment?") . "\n" .
784 xlj("It is prudent to follow up with provider if not contacted.") ?>;
785 let msg_reason = <?php echo xlj("You must enter a reason to cancel this appointment?") . "\n" .
786 xlj("Reason must be at least 10 characters!") ?>;
787 if (f.form_comments.value.length <= 10) {
788 alert(msg_reason);
789 return false;
791 let yn = confirm(msg);
792 if (!yn) {
793 return false;
795 document.getElementById('form_apptstatus').value = "x";
796 validate();
799 // Do whatever is needed when a new event category is selected.
800 // For now this means changing the event title and duration.
801 function set_category() {
802 var f = document.forms.namedItem("theaddform");
803 var s = f.form_category;
804 if (s.selectedIndex >= 0) {
805 var catid = s.options[s.selectedIndex].value;
806 f.form_title.value = s.options[s.selectedIndex].text;
807 f.form_duration.value = durations[catid] || '15';
808 set_display();
812 // This is for callback by the find-available popup.
813 function setappt(year, mon, mday, hours, minutes) {
814 var f = document.forms.namedItem("theaddform");
815 // note that month is 0 based, 0-11 so need to subtract 1 as the api caller is 1 based (1-12)
816 let date= new Date(year, mon-1, mday, hours, minutes);
817 f.form_date.value = window.top.oeFormatters.I18NDateFormat(date);
818 f.form_ampm.selectedIndex = (hours > 12) ? 1 : 0;
819 if (hours == 0) {
820 f.form_hour.value = 12;
821 } else {
822 f.form_hour.value = (hours >= 13) ? hours - 12 : hours;
824 f.form_minute.value = minutes;
827 function get_form_category_value() {
828 var catid = 0;
829 var f = document.forms.namedItem("theaddform");
830 var s = f.form_category;
831 if (s.selectedIndex >= 0) {
832 catid = s.options[s.selectedIndex].value;
834 return catid;
837 // Invoke the find-available popup.
838 function find_available() {
839 // when making an appointment for a specific provider
840 var catId = get_form_category_value() || 5;
841 var se = document.getElementById('form_provider_ae');
842 <?php if ($userid != 0) { ?>
843 s = se.value;
844 <?php } else {?>
845 s = se.options[se.selectedIndex].value;
846 <?php }?>
847 var formDate = document.getElementById('form_date');
848 var url = 'find_appt_popup_user.php?bypatient&providerid=' + encodeURIComponent(s) + '&catid=' + encodeURIComponent(catId)
849 + '&startdate=' + encodeURIComponent(formDate.value);
850 var params = {
851 buttons: [
852 {text: <?php echo xlj('Cancel'); ?>, close: true, style: 'danger btn-sm'}
855 allowResize: true,
856 dialogId: 'apptDialog',
857 type: 'iframe'
859 dlgopen(url, 'apptFind', 'modal-md', 300, '', 'Find Date', params);
862 // Check for errors when the form is submitted.
863 function validate() {
864 var f = document.getElementById('theaddform');
865 if (!f.form_date.value || !f.form_hour.value || !f.form_minute.value) {
866 alert(<?php echo xlj('Please click on Openings to select a time.'); ?>);
867 return false;
870 if (f.form_patient.value == '') {
871 alert(<?php echo xlj('Your Id is missing. Cancel and try again.'); ?>);
872 return false;
875 var form_action = document.getElementById('form_action');
876 form_action.value = "save";
877 f.submit();
878 return false;
881 <?php if ($eid !== 0) { ?>
882 set_display();
883 <?php } ?>
884 $(function () {
887 </script>
888 </div>
889 </body>
890 </html>