2 [-*****************************************************************************-]
3 [-* Copyright (C)
2005-
2006 Rod Roark
<rod@sunsetsystems.com
> and others *-]
5 [-* This program is free software; you can redistribute it and/or *-]
6 [-* modify it under the terms of the GNU General Public License *-]
7 [-* as published by the Free Software Foundation; either version
2 *-]
8 [-* of the License, or (at your option) any later version. *-]
9 [-*****************************************************************************-]
10 [-config_load
file=
"default.conf"-]
11 [-*Load the Language Definitions*-]
12 [-config_load
file=
"lang.$USER_LANG"-]
13 [-* DO NOT INCLUDE the default header,
14 * which includes a stylesheet to screw up
15 * our styles below *-]
16 [-*include
file=
"$TPL_NAME/views/header.html"*-]
20 [-*Values used in setting timeslot and event heights*-]
21 [-php-]$timeslotHeightVal=
20; $
timeslotHeightUnit=
"px";[-/php-]
31 font-family: Arial, Helvetica, sans-serif;
33 div.tiny { width:
1px; height:
1px; font-size:
1px; }
37 font-family: Arial, Helvetica, sans-serif;
51 page-break-after: always;
54 /* these are for the small datepicker DIV */
62 font-family: Arial, Helvetica, sans-serif;
66 border-collapse: collapse;
68 #datePicker .tdDOW-small {
69 font-family: Arial, Helvetica, sans-serif;
72 border-bottom:
1px solid black;
73 padding:
2px
3px
2px
3px;
75 #datePicker .tdWeekend-small {
76 font-family: Arial, Helvetica, sans-serif;
80 padding:
2px
3px
2px
3px;
83 #datePicker .tdOtherMonthDay-small {
84 font-family: Arial, Helvetica, sans-serif;
88 padding:
2px
3px
2px
3px;
92 #datePicker .tdMonthName-small {
94 font-family: Arial, Helvetica, sans-serif;
99 #datePicker .tdMonthDay-small {
100 font-family: Arial, Helvetica, sans-serif;
104 padding:
2px
3px
2px
3px;
105 background-color: #ffffff;
107 #datePicker .currentWeek {
108 border-top:
1px solid blue;
109 border-bottom:
1px solid blue;
111 #datePicker .currentDate {
112 border:
1px solid blue;
113 background-color: blue;
117 /* the DIV of times */
119 border-right:
1px solid #
999;
122 border-collapse: collapse;
129 border-top:
1px solid #
999;
135 height: [-php-]echo $timeslotHeightVal.$timeslotHeightUnit;[-/php-];
140 background-color: pink;
144 border-right:
1px solid black;
146 /* types of events */
175 /* these hold the day groupings */
179 border-collapse: collapse;
185 border:
1px solid #
333;
190 font-family: helvetica, arial;
192 border-bottom:
1px solid #
333;
198 <script type=
"text/javascript" src=
"../../../library/textformat.js"></script>
205 // build a day-of-week (DOW) list so we may properly build the calendars later in this code
207 $tmpDOW = pnModGetVar(__POSTCALENDAR__, 'pcFirstDayOfWeek');
208 // bound check and auto-correction
209 if ($tmpDOW
<0 || $tmpDOW
>6) {
210 pnModSetVar(__POSTCALENDAR__, 'pcFirstDayOfWeek', '
0');
213 while (count($DOWlist) <
7) {
214 array_push($DOWlist, $tmpDOW);
216 if ($tmpDOW
> 6) $tmpDOW =
0;
219 // A_CATEGORY is an ordered array of associative-array categories.
220 // Keys of interest are: id, name, color, desc, event_duration.
223 $A_CATEGORY =& $this-
>_tpl_vars['A_CATEGORY'];
225 $A_EVENTS =& $this-
>_tpl_vars['A_EVENTS'];
226 // $S_EVENTS =& $this-
>_tpl_vars['S_EVENTS']; // Deleted by Rod
227 $providers =& $this-
>_tpl_vars['providers'];
228 $times =& $this-
>_tpl_vars['times'];
229 $interval = $this-
>_tpl_vars['interval'];
230 $viewtype = $this-
>_tpl_vars['VIEW_TYPE'];
231 $PREV_WEEK_URL = $this-
>_tpl_vars['PREV_WEEK_URL'];
232 $NEXT_WEEK_URL = $this-
>_tpl_vars['NEXT_WEEK_URL'];
233 $PREV_DAY_URL = $this-
>_tpl_vars['PREV_DAY_URL'];
234 $NEXT_DAY_URL = $this-
>_tpl_vars['NEXT_DAY_URL'];
236 $Date = postcalendar_getDate();
237 if (!isset($y)) $y = substr($Date,
0,
4);
238 if (!isset($m)) $m = substr($Date,
4,
2);
239 if (!isset($d)) $d = substr($Date,
6,
2);
241 $MULTIDAY = count($A_EVENTS)
> 1;
245 [-assign
var=
"dayname" value=$DATE|date_format:
"%w"-]
246 [-assign
var=
"day" value=$DATE|date_format:
"%d"|string_format:
"%1d"-]
247 [-assign
var=
"month" value=$DATE|date_format:
"%m"|string_format:
"%1d"-]
248 [-assign
var=
"year" value=$DATE|date_format:
"%Y"|string_format:
"%4d"-]
250 [-pc_sort_events
var=
"S_EVENTS" sort=
"time" order=
"asc" value=$A_EVENTS-]
255 // start out without adding a pagebreak
256 $addPagebreak = false;
258 // This loops once for each provider to be displayed.
260 foreach ($providers as $provider) {
261 // output a pagebreak, if needed
262 if ($addPagebreak) { echo
"<div class='pagebreak'></div>\n"; }
263 $addPagebreak = true;
265 echo
"<div id='bigCalHeader'>";
267 echo
"<div id='bigCalText'>";
268 // output the provider name
269 echo
"<span id='provname'>".$provider['fname'] .
" " . $provider['lname'].
"</span>";
271 // output the date range
272 echo
"<span id='daterange'>";
273 $atmp = array_keys($A_EVENTS);
274 echo date('F d', strtotime($atmp[
0]));
276 echo date('F d', strtotime($atmp[count($atmp)-
1]));
280 // output a calendar for the subsequent month
281 list($nyear, $nmonth, $nday) = explode(
" ", date(
"Y m d", strtotime($atmp[
0])));
283 if ($nmonth
> 12) { $nyear++; $nmonth=
1; }
284 echo
"<div id='datePicker'>";
285 PrintDatePicker(strtotime($nyear.
"-".$nmonth.
"-1"), $DOWlist, $this-
>_tpl_vars['A_SHORT_DAY_NAMES']);
288 // output a small calendar for the chosen month
289 echo
"<div id='datePicker'>";
290 PrintDatePicker(strtotime($atmp[
0]), $DOWlist, $this-
>_tpl_vars['A_SHORT_DAY_NAMES']);
293 echo
"</div>"; // end the bigCalHeader
295 $providerid = $provider['id'];
297 // to specially handle the IN/OUT events I'm doing something new here
298 // for each IN event it will have a duration lasting until the next
299 // OUT event or until the end of the day
300 $tmpTime = $times[
0];
301 $calStartMin = ($tmpTime['hour'] *
60) + $tmpTime['minute'];
302 $tmpTime = $times[count($times)-
1];
303 $calEndMin = ($tmpTime['hour'] *
60) + $tmpTime['minute'];
306 // output a TD with an inner containing DIV positioned 'relative'
307 echo
"<table id='weekcal' >";
309 foreach ($A_EVENTS as $date =
> $events) {
311 $eventdate = substr($date,
0,
4) . substr($date,
5,
2) . substr($date,
8,
2);
313 // each date gets it's own header
314 echo
"<td><div id='dowheader'>".date(
"D m/d", strtotime($eventdate)).
"</div>";
316 // output the events for this date
317 PrintEvents($events, $providerid, $TPL_IMAGE_PATH);
319 // now output the events for this date+
4, if they exist
321 $dateplusfour = strtotime($eventdate) + (
4 *
24 *
60 *
60);
322 if (isset($A_EVENTS[date(
"Y-m-d", $dateplusfour)])) {
323 echo
"<div id='dowheader'>".date(
"D m/d", $dateplusfour).
"</div>";
324 $tmpEvents = $A_EVENTS[date(
"Y-m-d", $dateplusfour)];
325 PrintEvents($tmpEvents, $providerid, $TPL_IMAGE_PATH);
329 // limit the times through this loop by the limit of four TRs
330 if ($loopcount++
>=
3) break;
339 /* print out the array of events */
340 function PrintEvents($events, $providerid, $TPL_IMAGE_PATH) {
341 global $times, $calStartMin, $calEndMin;
343 // now loop over the events for the day and output their DIVs
344 foreach ($events as $event) {
345 // skip events for other providers
346 // yeah, we've got that sort of overhead here... it ain't perfect
347 if ($providerid != $event['aid']) { continue; }
349 // skip events without an ID (why they are in the loop, I have no idea)
350 if ($event['eid'] ==
"") { continue; }
352 // specially handle all-day events
353 if ($event['alldayevent'] ==
1) {
354 $tmpTime = $times[
0];
355 if (strlen($tmpTime['hour']) <
2) { $tmpTime['hour'] =
"0".$tmpTime['hour']; }
356 if (strlen($tmpTime['minute']) <
2) { $tmpTime['minute'] =
"0".$tmpTime['minute']; }
357 $event['startTime'] = $tmpTime['hour'].
":".$tmpTime['minute'].
":00";
358 $event['duration'] = ($calEndMin - $calStartMin) *
60; // measured in seconds
361 // figure the start time and minutes (from midnight)
362 $starth = substr($event['startTime'],
0,
2);
363 $startm = substr($event['startTime'],
3,
2);
364 $eStartMin = $starth *
60 + $startm;
366 // determine the class for the event DIV based on the event category
367 $evtClass =
"event_appointment";
368 switch ($event['catid']) {
369 case
1: // NO-SHOW appt
370 $evtClass =
"event_noshow";
373 $evtClass =
"event_in";
375 case
3: // OUT of office
376 $evtClass =
"event_out";
381 $evtClass =
"event_reserved";
383 default: // some appointment
384 $evtClass =
"event_appointment";
388 // if this is an IN or OUT event then we have some extra special
389 // processing to be done
390 // the IN event creates a DIV until the OUT event
391 // or, without an OUT DIV matching the IN event
392 // then the IN event runs until the end of the day
393 if ($event['catid'] ==
2) {
394 // locate a matching OUT for this specific IN
397 foreach ($events as $outevent) {
398 // skip events for other providers
399 if ($providerid != $outevent['aid']) { continue; }
400 // skip events with blank IDs
401 if ($outevent['eid'] ==
"") { continue; }
403 if ($outevent['eid'] == $event['eid']) { $found = true; continue; }
404 if (($found == true) && ($outevent['catid'] ==
3)) {
405 // calculate the duration from this event to the outevent
406 $outH = substr($outevent['startTime'],
0,
2);
407 $outM = substr($outevent['startTime'],
3,
2);
408 $outMins = ($outH *
60) + $outM;
409 $event['duration'] = ($outMins - $eStartMin) *
60; // duration is in seconds
415 // no OUT was found so this event's duration goes
416 // until the end of the day
417 $event['duration'] = ($calEndMin - $eStartMin) *
60; // duration is in seconds
421 // calculate the TOP value for the event DIV
422 // diff between event start and schedule start
423 $eMinDiff = $eStartMin - $calStartMin;
424 // diff divided by the time interval of the schedule
425 $eStartInterval = $eMinDiff / $interval;
426 // times the interval height
427 $eStartPos = $eStartInterval * $timeslotHeightVal;
428 $evtTop = $eStartPos.$timeslotHeightUnit;
430 // calculate the HEIGHT value for the event DIV
431 // diff between end and start of event
432 $eEndMin = $eStartMin + ($event['duration']/
60);
433 $eMinDiff = $eEndMin - $eStartMin;
434 // diff divided by the time interval of the schedule
435 $eEndInterval = $eMinDiff / $interval;
436 // times the interval height
437 $eHeight = $eEndInterval * $timeslotHeightVal;
438 $evtHeight = $eHeight.$timeslotHeightUnit;
440 // determine the DIV width based on any overlapping events
441 // see further above for the overlapping calculation code
444 if (isset($eventPositions[$event['eid']])) {
445 $divWidth =
"width: ".$eventPositions[$event['eid']]-
>width.
"%";
446 $divLeft =
"left: ".$eventPositions[$event['eid']]-
>leftpos.
"%";
449 $eventid = $event['eid'];
450 $patientid = $event['pid'];
451 $commapos = strpos($event['patient_name'],
",");
452 $lname = addslashes(ucfirst(strtolower(substr($event['patient_name'],
0, $commapos))));
453 $fname = addslashes(ucfirst(strtolower(substr($event['patient_name'], $commapos +
2))));
454 $patient_dob = $event['patient_dob'];
455 $patient_age = $event['patient_age'];
456 $catid = $event['catid'];
457 $comment = addslashes($event['hometext']);
458 $catname = $event['catname'];
459 $title =
"Age $patient_age ($patient_dob)";
463 if ($comment && $GLOBALS['calendar_appt_style'] <
4) $title .=
" " . $comment;
465 // the divTitle is what appears when the user hovers the mouse over the DIV
466 $divTitle = date(
"D, d M Y", strtotime($date));
468 $eventdatetime = strtotime($date.
" ".$starth.
":".$startm);
470 if ($catid ==
2 || $catid ==
3 || $catid ==
4 || $catid ==
8 || $catid ==
11) {
471 if ($catid ==
2) $catname =
"IN";
472 else if ($catid ==
3) $catname =
"OUT";
473 else if ($catid ==
4) $catname =
"VACATION";
474 else if ($catid ==
8) $catname =
"LUNCH";
475 else if ($catid ==
11) $catname =
"RESERVED";
477 $content .= date(
"h:i", $eventdatetime);
478 if ($event['recurrtype'] ==
1) $content .=
"<img src='$TPL_IMAGE_PATH/repeating8.png' border='0' style='margin:0px 2px 0px 2px;' title='Repeating event' alt='Repeating event'>";
479 $content .=
" ".$catname;
480 if ($comment) $content .=
" $comment";
483 // some sort of patient appointment
484 $content .=
"<span class='appointment".$apptToggle.
"'>";
485 $content .= date(
"h:i", $eventdatetime).
" ";
486 if ($event['recurrtype'] ==
1) $content .=
"<img src='$TPL_IMAGE_PATH/repeating8.png' border='0' style='margin:0px 2px 0px 2px;' title='Repeating event' alt='Repeating event'>";
488 if ($catid ==
1) $content .=
"<strike>";
490 if ($GLOBALS['calendar_appt_style'] !=
1) {
491 $content .=
"," . $fname;
492 if ($event['title'] && $GLOBALS['calendar_appt_style']
>=
3) {
493 $content .=
"(" . $event['title'];
494 if ($event['hometext'] && $GLOBALS['calendar_appt_style']
>=
4)
495 $content .=
": <font color='green'>" . htmlspecialchars(trim($event['hometext'])) .
"</font>";
499 if ($catid ==
1) $content .=
"</strike>";
502 // no patient id, just output the category name
503 $content .= $catname;
506 $content .=
"</span>";
509 $divTitle .=
"\n(double click to edit)";
511 // output the DIV and content
512 echo
"<div class='".$evtClass.
" event' style='background-color:".$event[
"catcolor"].
514 " id='".$eventdate.
"-".$eventid.
"'".
523 /* output a small calendar, based on the date-picker code from the normal calendar */
524 function PrintDatePicker($caldate, $DOWlist, $daynames) {
526 $cMonth = date(
"m", $caldate);
527 $cYear = date(
"Y", $caldate);
528 $cDay = date(
"d", $caldate);
532 echo '
<td colspan=
"7" class=
"tdMonthName-small">';
533 echo date('F Y', $caldate);
537 foreach ($DOWlist as $dow) {
538 echo
"<td class='tdDOW-small'>".$daynames[$dow].
"</td>";
542 // to make a complete week row we need to compute the real
543 // start and end dates for the view
544 list ($year, $month, $day) = explode(
" ", date('Y m d', $caldate));
545 $startdate = strtotime($year.$month.
"01");
546 while (date('w', $startdate) != $DOWlist[
0]) { $startdate -=
60*
60*
24; }
548 $enddate = strtotime($year.$month.date(
"t", $month));
549 while (date('w', $enddate) != $DOWlist[
6]) { $enddate +=
60*
60*
24; }
551 $currdate = $startdate;
552 while ($currdate <= $enddate) {
553 if (date('w', $currdate) == $DOWlist[
0]) {
557 // we skip outputting some days
561 $tdClass =
"tdMonthDay-small";
562 if (date('m', $currdate) != $month) {
563 $tdClass =
"tdOtherMonthDay-small";
566 if ((date('w', $currdate) ==
0) || (date('w', $currdate) ==
6)) {
567 $tdClass =
"tdWeekend-small";
570 if (date('Ymd',$currdate) == $Date) {
571 // $Date is defined near the top of this file
572 // and is equal to whatever date the user has clicked
573 $tdClass .=
" currentDate";
576 // add a class so that jQuery can grab these days for the 'click' event
577 $tdClass .=
" tdDatePicker";
581 $td .=
"class=\"".$tdClass."\
" ";
582 $td .=
"> ".date('d', $currdate).
"</td>\n";
583 if ($skipit == true) { echo
"<td></td>"; }
587 if (date('w', $currdate) == $DOWlist[
6]) echo
"</tr>\n";
589 // time correction = plus
1000 seconds, for some unknown reason
590 $currdate += (
60*
60*
24)+
1000;
599 <script type=
"text/javascript" src=
"[-php-] echo $GLOBALS['webroot'] [-/php-]/library/js/jquery-1.2.2.min.js"></script>
601 $(document
).ready(function(){
602 // a poor-man's attempt to scale down the text to make sure
603 // the calendar fits onto a single piece of paper
604 if (($("#bigCal").height() > 900) && ($("#bigCal").height() < 1200)) {
605 $("#weekcal *").css("font-size", "90%");
607 else if ($("#bigCal").height() > 1200) {
608 $("#weekcal *").css("font-size", "80%");