PluginProbe
ShiftController Employee Shift Scheduling / 4.9.85
ShiftController Employee Shift Scheduling v4.9.85
4.9.97 4.9.96 4.9.95 4.9.74 4.9.75 4.9.76 4.9.77 4.9.78 4.9.84 4.9.85 4.9.87 4.9.91 4.9.92 trunk 2.1.0 2.1.1 2.1.2 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 3.2.4 All 38 releases
shiftcontroller / sh4 / schedule / html / view / day.php

day.php in ShiftController Employee Shift Scheduling 4.9.85, at sh4/schedule/html/view/day.php

956 lines 25.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php if (! defined('ABSPATH')) exit; // Exit if accessed directly
2 #[AllowDynamicProperties]
3 class SH4_Schedule_Html_View_Day
4 {
5 protected $borderColor = 'gray';
6 protected $allCombos = array();
7 protected $allCombosShift = array();
8 protected $allCombosTimeoff = array();
9
10 public static $daysToShow = 1;
11
12 public function __construct(
13 HC3_Hooks $hooks,
14 HC3_Ui $ui,
15 HC3_Request $request,
16 HC3_Time $t,
17 HC3_Settings $settings,
18
19 HC3_Uri $uri,
20
21 SH4_New_Acl $newAcl,
22
23 SH4_Schedule_Html_Widget_DayGrid $widgetDayGrid,
24
25 SH4_Shifts_Duration $shiftsDuration,
26 SH4_Shifts_View_Widget $widget,
27 SH4_Calendars_Query $calendarsQuery,
28 SH4_Calendars_Presenter $calendarsPresenter,
29 SH4_Employees_Presenter $employeesPresenter,
30 SH4_Schedule_Html_View_Common $common,
31 SH4_Shifts_View_Common $shiftsCommon
32 )
33 {
34 $this->self = $hooks->wrap($this);
35
36 $this->ui = $ui;
37
38 $this->uri = $uri;
39 $this->t = $t;
40 $this->request = $request;
41
42 $this->settings = $hooks->wrap( $settings );
43 $this->newAcl = $hooks->wrap( $newAcl );
44
45 $this->widgetDayGrid = $hooks->wrap( $widgetDayGrid );
46 $this->shiftsDuration = $hooks->wrap( $shiftsDuration );
47 $this->calendarsQuery = $hooks->wrap( $calendarsQuery );
48 $this->calendarsPresenter = $hooks->wrap( $calendarsPresenter );
49 $this->employeesPresenter = $hooks->wrap( $employeesPresenter );
50
51 $this->widget = $hooks->wrap( $widget );
52 $this->common = $hooks->wrap( $common );
53 $this->shiftsCommon = $hooks->wrap( $shiftsCommon );
54
55 $this->allCombos = $this->newAcl->findAllCombos();
56 $this->allCombosShift = $this->newAcl->findAllCombosShift();
57 $this->allCombosTimeoff = $this->newAcl->findAllCombosTimeoff();
58 }
59
60 public function renderDateLabel( $date )
61 {
62 $slug = $this->request->getSlug();
63 $today = $this->t->setNow()->formatDateDb();
64
65 $this->t->setDateDb( $date );
66 $ret = $this->t->getWeekdayName() . ', ' . $this->t->formatDate();
67
68 return $ret;
69 }
70
71 public function render()
72 {
73 $shifts = $this->common->getShifts();
74 $params = $this->request->getParams();
75 $today = $this->t->setNow()->formatDateDb();
76
77 $startDate = $params['start'];
78 $endDate = $startDate;
79 if( static::$daysToShow > 1 ){
80 $endDate = $this->t->setDateDb( $startDate )->modify( '+' . (static::$daysToShow - 1) . ' days')->formatDateDb();
81 }
82
83 $dayStart = $this->t->setDateDb( $startDate )->formatDateTimeDb();
84 $dayEnd = $this->t->setDateDb( $endDate )->modify( '+1 day')->formatDateTimeDb();
85
86 $disabledWeekdays = $this->settings->get( 'skip_weekdays', TRUE );
87 $this->t->setDateDb( $startDate );
88 $dates = array();
89 $rexDate = $startDate;
90 while( $rexDate <= $endDate ){
91 if( $disabledWeekdays ){
92 $wkd = $this->t->getWeekday();
93 if( in_array($wkd, $disabledWeekdays) ){
94 $rexDate = $this->t->modify('+1 day')->formatDateDb();
95 continue;
96 }
97 }
98 $dates[] = $rexDate;
99 $rexDate = $this->t->modify('+1 day')->formatDateDb();
100 }
101
102 $endDate = $startDate;
103
104 $viewShifts = array();
105 $iknow = array('date');
106
107 $this->shiftsDuration->reset();
108
109 reset( $shifts );
110 foreach( $shifts as $shift ){
111 $this->shiftsDuration->add( $shift );
112 $start = $shift->getStart();
113 $end = $shift->getEnd();
114
115 $startDayTime = substr($start, 8, 4);
116 $endDayTime = substr($end, 8, 4);
117 $shiftAllDay = ( (0 == $startDayTime) && (0 == $endDayTime) ) ? TRUE : FALSE;
118
119 $this->t->setDateTimeDb( $end )->modify('-1 second');
120 $shiftEndDate = $this->t->formatDateDb();
121
122 $this->t->setDateTimeDb( $start );
123 $shiftStartDate = $this->t->formatDateDb();
124
125 $rexDate = $shiftStartDate;
126 while( $rexDate <= $shiftEndDate ){
127 if( in_array($rexDate, $dates) ){
128 if( ! array_key_exists($rexDate, $viewShifts) ){
129 $viewShifts[$rexDate] = array();
130 }
131 $viewShifts[$rexDate][] = $shift;
132 }
133
134 if( ! $shiftAllDay ){
135 break;
136 }
137 $this->t->modify( '+1 day' );
138 $rexDate = $this->t->formatDateDb();
139 }
140 }
141
142 $iknow = array('date');
143 $rows = array();
144
145 foreach( $dates as $date ){
146 $row = array();
147 $cell = array();
148
149 $this->t->setDateDb( $date );
150 $dateView = $this->self->renderDateLabel( $date );
151 $cell[] = $dateView;
152
153 $thisShifts = isset($viewShifts[$date]) ? $viewShifts[$date] : array();
154
155 if( $thisShifts ){
156 $gridView = $this->self->renderDay( $thisShifts, $iknow, $date );
157 $cell[] = $gridView;
158 }
159
160 $toParams = array(
161 'date' => $date
162 );
163 if( array_key_exists('employee', $params) && (count($params['employee']) == 1) ){
164 if( ! in_array(-1, $params['employee']) ){
165 $toParams['employee'] = $params['employee'][0];
166 }
167 }
168
169 $links = array();
170
171 if( $this->allCombosShift ){
172 $label = '+' . ' ' . '__Shift__';
173 $thisTo = 'new/shift';
174 $thisTo = array( $thisTo, $toParams );
175 $link = $this->ui->makeAhref( $thisTo, $label )
176 ->tag('tab-link')
177 ->tag('align', 'center')
178 // ->addAttr('title', '__Add New__')
179 ;
180 if( $today > $date ){
181 $link->tag('muted', 3);
182 }
183 $links[] = $link;
184 }
185
186 if( $this->allCombosTimeoff ){
187 $label = '+' . ' ' . '__Time Off__';
188 $thisTo = 'new/timeoff';
189 $thisTo = array( $thisTo, $toParams );
190 $link = $this->ui->makeAhref( $thisTo, $label )
191 ->tag('tab-link')
192 ->tag('align', 'center')
193 // ->addAttr('title', '__Add New__')
194 ;
195 if( $today > $date ){
196 $link->tag('muted', 3);
197 }
198 $links[] = $link;
199 }
200
201 $links = $this->ui->makeList( $links )->gutter(0);
202
203 $cell[] = $links;
204
205 $cell = $this->ui->makeList( $cell )
206 ->gutter(1)
207 ->tag('margin', 1)
208 ;
209
210 $row[] = $cell;
211
212 $rows[] = $row;
213 }
214
215 $out = $this->ui->makeTable( NULL, $rows, FALSE )
216 ->gutter(0)
217 // ->setBordered( $this->borderColor )
218 ;
219
220 return $out;
221 }
222
223 public function renderByCalendar()
224 {
225 $calendars = $this->common->getCalendars();
226 $employees = $this->common->getEmployees();
227 $shifts = $this->common->getShifts();
228
229 // finalize calendars to include those that employee was removed from but still have shifts in
230 $listCalendarId = array_keys( $calendars );
231 $dictCalendarId = array_combine( $listCalendarId, $listCalendarId );
232 foreach( $shifts as $shift ){
233 $calendar = $shift->getCalendar();
234 if( ! $calendar ) continue;
235 $calendarId = $calendar->getId();
236 $dictCalendarId[ $calendarId ] = $calendarId;
237 }
238 if( count($dictCalendarId) > count($calendars) ){
239 $allCalendars = $this->common->findAllCalendars();
240 $calendars = array_intersect_key( $allCalendars, $dictCalendarId );
241 }
242
243 // we can probably have archived calendars so if such calendars have no shifts then skip them
244 $removeArchivedCalendars = array();
245 foreach( $calendars as $calendar ){
246 if( $calendar->isArchived() ){
247 $removeArchivedCalendars[ $calendar->getId() ] = $calendar->getId();
248 }
249 }
250 if( $removeArchivedCalendars ){
251 foreach( $shifts as $shift ){
252 $calendar = $shift->getCalendar();
253 $id = $calendar ? $calendar->getId() : 0;
254 if( isset($removeArchivedCalendars[$id]) ){
255 unset( $removeArchivedCalendars[$id] );
256 }
257 if( ! $removeArchivedCalendars ){
258 break;
259 }
260 }
261 foreach( $removeArchivedCalendars as $id ){
262 unset( $calendars[$id] );
263 }
264 reset( $shifts );
265 }
266
267 $today = $this->t->setNow()->formatDateDb();
268 $disabledWeekdays = $this->settings->get( 'skip_weekdays', TRUE );
269
270 $params = $this->request->getParams();
271 $startDate = $params['start'];
272
273 $endDate = $startDate;
274 if( static::$daysToShow > 1 ){
275 $endDate = $this->t->setDateDb( $startDate )->modify( '+' . (static::$daysToShow - 1) . ' days')->formatDateDb();
276 }
277
278 $dayStart = $this->t->setDateDb( $startDate )->formatDateTimeDb();
279 $dayEnd = $this->t->setDateDb( $endDate )->modify( '+1 day')->formatDateTimeDb();
280
281 $disabledWeekdays = $this->settings->get( 'skip_weekdays', TRUE );
282 $this->t->setDateDb( $startDate );
283 $dates = array();
284 $rexDate = $startDate;
285 while( $rexDate <= $endDate ){
286 if( $disabledWeekdays ){
287 $wkd = $this->t->getWeekday();
288 if( in_array($wkd, $disabledWeekdays) ){
289 $rexDate = $this->t->modify('+1 day')->formatDateDb();
290 continue;
291 }
292 }
293 $dates[] = $rexDate;
294 $rexDate = $this->t->modify('+1 day')->formatDateDb();
295 }
296
297 $viewCalendars = array();
298 foreach( $calendars as $calendar ){
299 $calendarId = $calendar->getId();
300
301 $label = $this->calendarsPresenter->presentTitle( $calendar );
302 $title = htmlspecialchars( $calendar->getTitle() );
303 $description = $calendar->getDescription();
304 if( strlen($description) ){
305 $description = htmlspecialchars( $description );
306 $title .= "\n" . $description;
307 }
308
309 $label = $this->ui->makeSpan( $label )
310 ->addAttr( 'title', $title )
311 ;
312
313 $viewCalendars[ $calendarId ] = $label;
314 }
315
316 $viewShifts = array();
317
318 $iknow = array('calendar', 'date');
319 $hori = FALSE;
320
321 $allEmployees = $this->common->findAllEmployees();
322 if( count($allEmployees) < 2 ){
323 $iknow[] = 'employee';
324 }
325
326 $out = array();
327
328 reset( $dates );
329 foreach( $dates as $date ){
330 $thisOut = array();
331 $rows = array();
332
333 $this->t->setDateDb( $date );
334 $dateView = $this->self->renderDateLabel( $date );
335 $thisOut[] = $dateView;
336
337 $viewShifts = array();
338
339 reset( $shifts );
340 foreach( $shifts as $shift ){
341 $start = $shift->getStart();
342 $end = $shift->getEnd();
343
344 $startDate = $this->t->setDateTimeDb( $start )->formatDateDb();
345 // echo "START '$startDate' VS '$date'<br>";
346 if( $startDate > $date ){
347 continue;
348 }
349
350 $endDate = $this->t->setDateTimeDb( $end )->formatDateDb();
351 // echo "END '$endDate' VS '$date'<br>";
352 if( $endDate < $date ){
353 continue;
354 }
355
356 // echo "'$startDate' - '$endDate' VS '$date' OK<br><br>";
357
358 $calendar = $shift->getCalendar();
359 $id = $calendar->getId();
360
361 if( ! array_key_exists($id, $viewShifts) ){
362 $viewShifts[$id] = array();
363 }
364
365 $viewShifts[$id][] = $shift;
366 }
367
368 $header = array();
369 $header[] = NULL;
370 $header[] = NULL;
371
372 $dayStart = $this->t->setDateDb( $startDate )->formatDateTimeDb();
373 $dayEnd = $this->t->setDateDb( $startDate )->modify('+1 day')->formatDateTimeDb();
374
375 reset( $viewCalendars );
376 foreach( $viewCalendars as $id => $calendarView ){
377 $row = array();
378
379 $this->shiftsDuration->reset();
380 if( isset($viewShifts[$id]) ){
381 foreach( $viewShifts[$id] as $shift ){
382 $this->shiftsDuration->add( $shift );
383 }
384
385 $outReport = $this->common->renderReport( $this->shiftsDuration, FALSE );
386 $outReport = $this->ui->makeSpan( $outReport )
387 ->tag('font-size', 2)
388 ;
389 $calendarView = $this->ui->makeList( array($calendarView, $outReport) )
390 ->gutter(1)
391 ;
392 }
393
394 $calendarView = $this->ui->makeBlock( $calendarView )
395 ->tag('padding', 2)
396 ->tag('nowrap')
397 ;
398 $row[] = $calendarView;
399
400 $cell = array();
401
402 if( isset($viewShifts[$id]) ){
403 $gridView = $this->self->renderDay( $viewShifts[$id], $iknow, $date );
404 $cell[] = $gridView;
405 }
406
407 $thisCalendar = $calendars[$id];
408 if( $thisCalendar->isTimeoff() ){
409 $label = '+ ' . '__Time Off__';
410 }
411 else {
412 $label = '+ ' . '__Shift__';
413 }
414
415 $to = 'new/calendar';
416 $toParams = array(
417 'calendar' => $id,
418 'date' => $date,
419 );
420 if( array_key_exists('employee', $params) && (count($params['employee']) == 1) ){
421 if( ! in_array(-1, $params['employee']) ){
422 $toParams['employee'] = $params['employee'][0];
423 }
424 }
425 $to = array( $to, $toParams );
426
427 $addOk = FALSE;
428 if( isset($toParams['employee']) ){
429 $testComboId = $id . '-' . $toParams['employee'];
430 if( isset($this->allCombos[$testComboId]) ){
431 $addOk = TRUE;
432 }
433 }
434 else {
435 $testComboId = $id . '-';
436 reset( $this->allCombos );
437 foreach( $this->allCombos as $comboId ){
438 if( $testComboId == substr($comboId, 0, strlen($testComboId)) ){
439 $addOk = TRUE;
440 break;
441 }
442 }
443 }
444
445 if( $addOk ){
446 $link = $this->ui->makeAhref( $to, $label )
447 ->tag('tab-link')
448 ->tag('align', 'center')
449 ;
450
451 if( $today > $date ){
452 $link->tag('muted', 3);
453 }
454
455 $cell[] = $link;
456 }
457
458 $cell = $this->ui->makeList( $cell )
459 ->gutter(1)
460 ->tag('margin', 1)
461 ;
462
463 $row[] = $cell;
464
465 $rows[] = $row;
466 }
467
468 $thisOut[] = $this->ui->makeTable( $header, $rows, FALSE )
469 ->gutter(0)
470 ->setBordered( $this->borderColor )
471 // ->setSegments( $weekSegments )
472 ->setLabelled( TRUE )
473 ;
474
475 $thisOut = $this->ui->makeList( $thisOut );
476
477 $out[] = $thisOut;
478 }
479
480 $out = $this->ui->makeList( $out );
481
482 return $out;
483 }
484
485 public function renderByEmployee()
486 {
487 $calendars = $this->common->getCalendars();
488 $employees = $this->common->getEmployees();
489 $shifts = $this->common->getShifts();
490
491 // finalize employees to include those that employee was removed from but still have shifts in
492 $listEmployeeId = array_keys( $employees );
493 $dictEmployeeId = array_combine( $listEmployeeId, $listEmployeeId );
494 foreach( $shifts as $shift ){
495 $employee = $shift->getEmployee();
496 if( ! $employee ) continue;
497 $employeeId = $employee->getId();
498 $dictEmployeeId[ $employeeId ] = $employeeId;
499 }
500 if( count($dictEmployeeId) > count($employees) ){
501 $allEmployees = $this->common->findAllEmployees();
502 $employees = array_intersect_key( $allEmployees, $dictEmployeeId );
503 }
504
505 // we can probably have archived employees so if such employees have no shifts then skip them
506 $removeArchivedEmployees = array();
507 foreach( $employees as $employee ){
508 if( $employee->isArchived() ){
509 $removeArchivedEmployees[ $employee->getId() ] = $employee->getId();
510 }
511 }
512 if( $removeArchivedEmployees ){
513 foreach( $shifts as $shift ){
514 $employee = $shift->getEmployee();
515 $id = $employee ? $employee->getId() : 0;
516 if( isset($removeArchivedEmployees[$id]) ){
517 unset( $removeArchivedEmployees[$id] );
518 }
519 if( ! $removeArchivedEmployees ){
520 break;
521 }
522 }
523 foreach( $removeArchivedEmployees as $id ){
524 unset( $employees[$id] );
525 }
526 reset( $shifts );
527 }
528
529 $today = $this->t->setNow()->formatDateDb();
530
531 $disabledWeekdays = $this->settings->get( 'skip_weekdays', TRUE );
532
533 $params = $this->request->getParams();
534 $startDate = $params['start'];
535 $endDate = $startDate;
536 if( static::$daysToShow > 1 ){
537 $endDate = $this->t->setDateDb( $startDate )->modify( '+' . (static::$daysToShow - 1) . ' days')->formatDateDb();
538 }
539
540 $dayStart = $this->t->setDateDb( $startDate )->formatDateTimeDb();
541 $dayEnd = $this->t->setDateDb( $endDate )->modify( '+1 day')->formatDateTimeDb();
542
543 $disabledWeekdays = $this->settings->get( 'skip_weekdays', TRUE );
544 $this->t->setDateDb( $startDate );
545 $dates = array();
546 $rexDate = $startDate;
547 while( $rexDate <= $endDate ){
548 if( $disabledWeekdays ){
549 $wkd = $this->t->getWeekday();
550 if( in_array($wkd, $disabledWeekdays) ){
551 $rexDate = $this->t->modify('+1 day')->formatDateDb();
552 continue;
553 }
554 }
555 $dates[] = $rexDate;
556 $rexDate = $this->t->modify('+1 day')->formatDateDb();
557 }
558
559 $viewEmployees = array();
560 foreach( $employees as $employee ){
561 $label = $this->employeesPresenter->presentTitle( $employee );
562 $title = htmlspecialchars( $label );
563
564 $description = $employee->getDescription();
565 if( strlen($description) ){
566 $imgpos = strpos( $description, '<img' );
567 if( false !== $imgpos ){
568 $label = $this->ui->makeList( array($label, $description) );
569 }
570 else {
571 $title .= "\n" . htmlspecialchars( $description );
572 }
573 }
574
575 $label = $this->ui->makeSpan( $label )
576 ->tag( 'font-size', 4 )
577 ->addAttr( 'title', $title )
578 ;
579
580 $viewEmployees[ $employee->getId() ] = $label;
581 }
582
583 $viewShifts = array();
584
585 $iknow = array('employee', 'date');
586 $hori = FALSE;
587
588 $out = array();
589
590 reset( $dates );
591 foreach( $dates as $date ){
592 $thisOut = array();
593
594 $thisOut = array();
595 $rows = array();
596
597 $this->t->setDateDb( $date );
598 $dateView = $this->self->renderDateLabel( $date );
599 $thisOut[] = $dateView;
600
601 $viewShifts = array();
602
603 foreach( $shifts as $shift ){
604 $employee = $shift->getEmployee();
605 $id = $employee ? $employee->getId() : 0;
606
607 if( ! array_key_exists($id, $viewShifts) ){
608 $viewShifts[$id] = array();
609 }
610
611 $viewShifts[$id][] = $shift;
612 }
613
614 $header = array();
615 $header[] = NULL;
616 $header[] = NULL;
617
618 $rows = array();
619
620 foreach( $viewEmployees as $id => $employeeView ){
621 $row = array();
622
623 $this->shiftsDuration->reset();
624 if( isset($viewShifts[$id]) ){
625 $counted = 0;
626 foreach( $viewShifts[$id] as $shift ){
627 $shiftCalendar = $shift->getCalendar();
628 // if( ! $shiftCalendar->isShift() ){
629 // continue;
630 // }
631 $this->shiftsDuration->add( $shift );
632 $counted++;
633 }
634
635 if( $counted ){
636 $outReport = $this->common->renderReport( $this->shiftsDuration, FALSE );
637 $outReport = $this->ui->makeSpan( $outReport )
638 ->tag('font-size', 2)
639 ;
640 $employeeView = $this->ui->makeList( array($employeeView, $outReport) )
641 ->gutter(1)
642 ;
643 }
644 }
645
646 $thisShifts = isset( $view_shifts[$id] ) ? $view_shifts[$id] : array();
647 $employeeView = $this->common->employeeRowLabel( $employeeView, $id, 'day', $dates, $thisShifts );
648
649 $employeeView = $this->ui->makeBlock( $employeeView )
650 ->tag('padding', 2)
651 ->tag('nowrap')
652 ;
653 $row[] = $employeeView;
654
655 $cell = array();
656
657 if( isset($viewShifts[$id]) ){
658 $gridView = $this->self->renderDay( $viewShifts[$id], $iknow, $date );
659 $cell[] = $gridView;
660 }
661
662 $toParams = array(
663 'employee' => $id,
664 'date' => $date
665 );
666
667 $links = array();
668
669 $comboId = 0 . '-' . $id;
670
671 if( isset($this->allCombosShift[$comboId]) ){
672 $label = '+' . ' ' . '__Shift__';
673 $thisTo = 'new/shift';
674 $thisTo = array( $thisTo, $toParams );
675 $link = $this->ui->makeAhref( $thisTo, $label )
676 ->tag('tab-link')
677 ->tag('align', 'center')
678 // ->addAttr('title', '__Add New__')
679 ;
680 if( $today > $date ){
681 $link->tag('muted', 3);
682 }
683 $links[] = $link;
684 }
685
686 if( isset($this->allCombosTimeoff[$comboId]) ){
687 $label = '+' . ' ' . '__Time Off__';
688 $thisTo = 'new/timeoff';
689 $thisTo = array( $thisTo, $toParams );
690 $link = $this->ui->makeAhref( $thisTo, $label )
691 ->tag('tab-link')
692 ->tag('align', 'center')
693 // ->addAttr('title', '__Add New__')
694 ;
695 if( $today > $date ){
696 $link->tag('muted', 3);
697 }
698 $links[] = $link;
699 }
700
701 $links = $this->ui->makeList( $links )->gutter(0);
702
703 $cell[] = $links;
704
705 $cell = $this->ui->makeList( $cell )
706 ->gutter(1)
707 ->tag('margin', 1)
708 ;
709
710 $row[] = $cell;
711
712 $rows[] = $row;
713 }
714
715
716 /* append calendars summary */
717 $appendCalendars = $this->settings->get('datetime_summary_by_calendar');
718 if( $appendCalendars && $shifts ){
719 $calendarIds = array();
720 foreach( $shifts as $shift ){
721 $calendar = $shift->getCalendar();
722 $calendarId = $calendar ? $calendar->getId() : 0;
723 if( ! $calendarId ) continue;
724 $calendarIds[ $calendarId ] = $calendarId;
725 }
726
727 $calendars = $this->calendarsQuery->findManyById( $calendarIds );
728
729 $shiftsByCalendar = $shiftsByDate = array();
730 foreach( $shifts as $shift ){
731 $thisCalendar = $shift->getCalendar();
732 if( ! $thisCalendar ) continue;
733 $shiftId = $shift->getId();
734 $thisCalendarId = $thisCalendar->getId();
735 $shiftsByCalendar[ $thisCalendarId ][ $shiftId ] = $shift;
736
737 $start = $shift->getStart();
738 $end = $shift->getEnd();
739
740 $startDayTime = substr($start, 8, 4);
741 $endDayTime = substr($end, 8, 4);
742 $shiftAllDay = ( (0 == $startDayTime) && (0 == $endDayTime) ) ? TRUE : FALSE;
743
744 $this->t->setDateTimeDb( $end )->modify('-1 second');
745 $shiftEndDate = $this->t->formatDateDb();
746
747 $this->t->setDateTimeDb( $start );
748 $shiftStartDate = $this->t->formatDateDb();
749
750 $rexDate = $shiftStartDate;
751 while( $rexDate <= $shiftEndDate ){
752 if( in_array($rexDate, $dates) ){
753 $shiftsByDate[ $rexDate ][ $shiftId ] = $shift;
754 }
755
756 if( ! $shiftAllDay ){
757 break;
758 }
759 $this->t->modify( '+1 day' );
760 $rexDate = $this->t->formatDateDb();
761 }
762 }
763
764 foreach( $calendars as $calendarId => $calendar ){
765 $row = array();
766
767 $calendarView = $this->calendarsPresenter->presentTitle( $calendar );
768 $title = htmlspecialchars( $calendar->getTitle() );
769 $calendarView = $this->ui->makeSpan( $calendarView )
770 ->addAttr( 'title', $title )
771 ;
772
773 $this->shiftsDuration->reset();
774 foreach( $shiftsByCalendar[$calendarId] as $shift ){
775 $this->shiftsDuration->add( $shift );
776 }
777
778 $outReport = $this->common->renderReport( $this->shiftsDuration, FALSE );
779 $outReport = $this->ui->makeSpan( $outReport )
780 ->tag('font-size', 2)
781 ;
782 $calendarView = $this->ui->makeList( array($calendarView, $outReport) )
783 ->gutter(1)
784 ;
785
786 $calendarView = $this->ui->makeBlock( $calendarView )
787 ->tag('padding', 2)
788 ->tag('nowrap')
789 ;
790 $row[] = $calendarView;
791
792 foreach( $dates as $date ){
793 $cell = '';
794 if( isset($shiftsByDate[$date]) ){
795 $thisShifts = array_intersect_key( $shiftsByDate[$date], $shiftsByCalendar[$calendarId] );
796 if( $thisShifts ){
797 $this->shiftsDuration->reset();
798 foreach( $thisShifts as $shift ){
799 $this->shiftsDuration->add( $shift );
800 }
801 $outReport = $this->common->renderReport( $this->shiftsDuration, FALSE );
802 $outReport = $this->ui->makeSpan( $outReport )
803 ->tag('font-size', 2)
804 ;
805 $outReport = $this->ui->makeBlock( $outReport )
806 ->tag('align', 'center')
807 ;
808 $cell = $outReport;
809 }
810 }
811 $row[] = $cell;
812 }
813 $rows[] = $row;
814 }
815 }
816
817 $thisOut[] = $this->ui->makeTable( $header, $rows, FALSE )
818 ->gutter(0)
819 ->setBordered( $this->borderColor )
820 // ->setSegments( $weekSegments )
821 ->setLabelled( TRUE )
822 ;
823
824 $thisOut = $this->ui->makeList( $thisOut );
825
826 $out[] = $thisOut;
827 }
828
829 $out = $this->ui->makeList( $out );
830
831 return $out;
832 }
833
834 public function renderDay( $shifts, $iknow, $startDate = NULL )
835 {
836 $hori = FALSE;
837 $params = $this->request->getParams();
838
839 $hideui = $params['hideui'];
840 $noZoom = in_array('shiftdetails', $hideui);
841
842 if( array_key_exists('employee', $params) && (count($params['employee']) == 1) ){
843 if( ! in_array(-1, $params['employee']) ){
844 $iknow[] = 'employee';
845 }
846 }
847 if( array_key_exists('calendar', $params) && (count($params['calendar']) == 1) ){
848 $iknow[] = 'calendar';
849 }
850
851 if( NULL === $startDate ){
852 $startDate = $params['start'];
853 }
854
855 $this->t->setDateDb( $startDate );
856 $minTime = $this->settings->get('datetime_min_time');
857 if( $minTime ){
858 $this->t->modify('+' . $minTime . ' seconds');
859 }
860 $dayStart = $this->t->formatDateTimeDb();
861
862 $this->t->setDateDb( $startDate );
863 $maxTime = $this->settings->get('datetime_max_time');
864 if( $maxTime ){
865 $this->t->modify('+' . $maxTime . ' seconds');
866 }
867 else {
868 $this->t->modify('+1 day');
869 }
870 $dayEnd = $this->t->formatDateTimeDb();
871 // echo "DAY END $dayEnd<br>";
872 // exit;
873
874 // check if we need to extend ranges to show overtime shifts
875 if( $shifts ){
876 $this->t->setDateDb( $startDate )->modify('+1 day');
877 $minCheckEnd = $this->t->formatDateTimeDb();
878
879 $this->t->modify('+1 day');
880 $maxCheckEnd = $this->t->formatDateTimeDb();
881
882 foreach( $shifts as $shift ){
883 $thisStart = $shift->getStart();
884 $thisEnd = $shift->getEnd();
885 // if( ($thisStart < $dayEnd) && ($thisEnd > $minCheckEnd) && ($thisEnd < $maxCheckEnd) ){
886 if( ($thisEnd > $minCheckEnd) && ($thisEnd < $maxCheckEnd) ){
887 if( $thisEnd > $dayEnd ){
888 $dayEnd = $thisEnd;
889 }
890 }
891 }
892 }
893
894 $grid = $this->widgetDayGrid
895 ->reset()
896 ;
897 $grid->setRange( $dayStart, $dayEnd );
898
899 // groups?
900 $groups = array();
901 $groupedShifts = array();
902 reset( $shifts );
903 foreach( $shifts as $shift ){
904 if( ! $shift->isOpen() ){
905 continue;
906 }
907
908 $groupId = $shift->getGroupingId();
909
910 if( ! isset($groups[$groupId]) ){
911 $groups[ $groupId ] = $shift->getId();
912 $groupedShifts[ $shift->getId() ] = array( $shift->getId() => $shift );
913 }
914 else {
915 $mainShiftId = $groups[ $groupId ];
916 $groupedShifts[ $mainShiftId ][ $shift->getId() ] = $shift;
917 $groupedShifts[ $shift->getId() ] = 0;
918 }
919 }
920
921 reset( $shifts );
922 foreach( $shifts as $shift ){
923 $id = $shift->getId();
924 if( isset($groupedShifts[$id]) && (! $groupedShifts[$id]) ){
925 continue;
926 }
927
928 $groupedQty = NULL;
929 if( isset($groupedShifts[$id]) && (count($groupedShifts[$id]) > 1) ){
930 $groupedQty = count($groupedShifts[$id]);
931 }
932
933 $thisView = $this->widget->render( $shift, $iknow, $hori, $noZoom, $groupedQty );
934 $shiftId = $shift->getId();
935
936 $buildMenuFromShifts = isset($groupedShifts[$id]) ? $groupedShifts[$id] : array( $shift );
937 $menu = $this->shiftsCommon->bulkMenu( $buildMenuFromShifts );
938 if( $menu ){
939 $thisView = $this->ui->makeCollection( array($thisView, $menu) );
940 }
941
942 $thisView = $this->ui->makeBlock( $thisView )
943 ->tag('block')
944 ->addAttr('class', 'sh4-shift-widget')
945 ->addAttr('style', 'padding-right: 1px;')
946 ;
947
948 $grid
949 ->add( $shift->getStart(), $shift->getEnd(), $thisView )
950 ;
951 }
952
953 $return = $grid->render();
954 return $return;
955 }
956 }