PluginProbe
ShiftController Employee Shift Scheduling / 4.9.26
ShiftController Employee Shift Scheduling v4.9.26
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.26, at sh4/schedule/html/view/day.php

749 lines 19.1 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 class SH4_Schedule_Html_View_Day
3 {
4 protected $borderColor = 'gray';
5 protected $allCombos = array();
6 protected $allCombosShift = array();
7 protected $allCombosTimeoff = array();
8
9 public static $daysToShow = 1;
10
11 public function __construct(
12 HC3_Hooks $hooks,
13 HC3_Ui $ui,
14 HC3_Request $request,
15 HC3_Time $t,
16 HC3_Enqueuer $enqueuer,
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_Presenter $calendarsPresenter,
28 SH4_Schedule_Html_View_Common $common,
29 SH4_Shifts_View_Common $shiftsCommon
30 )
31 {
32 $this->self = $hooks->wrap($this);
33 $enqueuer->addScript('schedule', 'sh4/schedule/assets/js/calendar.js?hcver=' . SH4_VERSION);
34
35 $this->ui = $ui;
36
37 $this->uri = $uri;
38 $this->t = $t;
39 $this->request = $request;
40
41 $this->settings = $hooks->wrap( $settings );
42 $this->newAcl = $hooks->wrap( $newAcl );
43
44 $this->widgetDayGrid = $hooks->wrap( $widgetDayGrid );
45 $this->shiftsDuration = $hooks->wrap( $shiftsDuration );
46 $this->calendarsPresenter = $hooks->wrap( $calendarsPresenter );
47
48 $this->widget = $hooks->wrap( $widget );
49 $this->common = $hooks->wrap( $common );
50 $this->shiftsCommon = $hooks->wrap( $shiftsCommon );
51
52 $this->allCombos = $this->newAcl->findAllCombos();
53 $this->allCombosShift = $this->newAcl->findAllCombosShift();
54 $this->allCombosTimeoff = $this->newAcl->findAllCombosTimeoff();
55 }
56
57 public function renderDateLabel( $date )
58 {
59 $slug = $this->request->getSlug();
60 $today = $this->t->setNow()->formatDateDb();
61
62 $this->t->setDateDb( $date );
63 $ret = $this->t->getWeekdayName() . ', ' . $this->t->formatDate();
64
65 return $ret;
66 }
67
68 public function render()
69 {
70 $shifts = $this->common->getShifts();
71 $params = $this->request->getParams();
72 $today = $this->t->setNow()->formatDateDb();
73
74 $startDate = $params['start'];
75 $endDate = $startDate;
76 if( static::$daysToShow > 1 ){
77 $endDate = $this->t->setDateDb( $startDate )->modify( '+' . (static::$daysToShow - 1) . ' days')->formatDateDb();
78 }
79
80 $dayStart = $this->t->setDateDb( $startDate )->formatDateTimeDb();
81 $dayEnd = $this->t->setDateDb( $endDate )->modify( '+1 day')->formatDateTimeDb();
82
83 $disabledWeekdays = $this->settings->get( 'skip_weekdays', TRUE );
84 $this->t->setDateDb( $startDate );
85 $dates = array();
86 $rexDate = $startDate;
87 while( $rexDate <= $endDate ){
88 if( $disabledWeekdays ){
89 $wkd = $this->t->getWeekday();
90 if( in_array($wkd, $disabledWeekdays) ){
91 $rexDate = $this->t->modify('+1 day')->formatDateDb();
92 continue;
93 }
94 }
95 $dates[] = $rexDate;
96 $rexDate = $this->t->modify('+1 day')->formatDateDb();
97 }
98
99 $endDate = $startDate;
100
101 $viewShifts = array();
102 $iknow = array('date');
103
104 $this->shiftsDuration->reset();
105
106 reset( $shifts );
107 foreach( $shifts as $shift ){
108 $this->shiftsDuration->add( $shift );
109 $start = $shift->getStart();
110 $end = $shift->getEnd();
111
112 $startDayTime = substr($start, 8, 4);
113 $endDayTime = substr($end, 8, 4);
114 $shiftAllDay = ( (0 == $startDayTime) && (0 == $endDayTime) ) ? TRUE : FALSE;
115
116 $this->t->setDateTimeDb( $end )->modify('-1 second');
117 $shiftEndDate = $this->t->formatDateDb();
118
119 $this->t->setDateTimeDb( $start );
120 $shiftStartDate = $this->t->formatDateDb();
121
122 $rexDate = $shiftStartDate;
123 while( $rexDate <= $shiftEndDate ){
124 if( in_array($rexDate, $dates) ){
125 if( ! array_key_exists($rexDate, $viewShifts) ){
126 $viewShifts[$rexDate] = array();
127 }
128 $viewShifts[$rexDate][] = $shift;
129 }
130
131 if( ! $shiftAllDay ){
132 break;
133 }
134 $this->t->modify( '+1 day' );
135 $rexDate = $this->t->formatDateDb();
136 }
137 }
138
139 $iknow = array('date');
140 $rows = array();
141
142 foreach( $dates as $date ){
143 $row = array();
144 $cell = array();
145
146 $this->t->setDateDb( $date );
147 $dateView = $this->self->renderDateLabel( $date );
148 $cell[] = $dateView;
149
150 $thisShifts = isset($viewShifts[$date]) ? $viewShifts[$date] : array();
151
152 if( $thisShifts ){
153 $gridView = $this->self->renderDay( $thisShifts, $iknow, $date );
154 $cell[] = $gridView;
155 }
156
157 $toParams = array(
158 'date' => $date
159 );
160 if( array_key_exists('employee', $params) && (count($params['employee']) == 1) ){
161 if( ! in_array(-1, $params['employee']) ){
162 $toParams['employee'] = $params['employee'][0];
163 }
164 }
165
166 $links = array();
167
168 if( $this->allCombosShift ){
169 $label = '+' . ' ' . '__Shift__';
170 $thisTo = 'new/shift';
171 $thisTo = array( $thisTo, $toParams );
172 $link = $this->ui->makeAhref( $thisTo, $label )
173 ->tag('tab-link')
174 ->tag('align', 'center')
175 // ->addAttr('title', '__Add New__')
176 ;
177 if( $today > $date ){
178 $link->tag('muted', 3);
179 }
180 $links[] = $link;
181 }
182
183 if( $this->allCombosTimeoff ){
184 $label = '+' . ' ' . '__Time Off__';
185 $thisTo = 'new/timeoff';
186 $thisTo = array( $thisTo, $toParams );
187 $link = $this->ui->makeAhref( $thisTo, $label )
188 ->tag('tab-link')
189 ->tag('align', 'center')
190 // ->addAttr('title', '__Add New__')
191 ;
192 if( $today > $date ){
193 $link->tag('muted', 3);
194 }
195 $links[] = $link;
196 }
197
198 $links = $this->ui->makeList( $links )->gutter(0);
199
200 $cell[] = $links;
201
202 $cell = $this->ui->makeList( $cell )
203 ->gutter(1)
204 ->tag('margin', 1)
205 ;
206
207 $row[] = $cell;
208
209 $rows[] = $row;
210 }
211
212 $out = $this->ui->makeTable( NULL, $rows, FALSE )
213 ->gutter(0)
214 // ->setBordered( $this->borderColor )
215 ;
216
217 return $out;
218 }
219
220 public function renderByCalendar()
221 {
222 $calendars = $this->common->getCalendars();
223 $employees = $this->common->getEmployees();
224 $shifts = $this->common->getShifts();
225
226 $today = $this->t->setNow()->formatDateDb();
227 $disabledWeekdays = $this->settings->get( 'skip_weekdays', TRUE );
228
229 $params = $this->request->getParams();
230 $startDate = $params['start'];
231
232 $endDate = $startDate;
233 if( static::$daysToShow > 1 ){
234 $endDate = $this->t->setDateDb( $startDate )->modify( '+' . (static::$daysToShow - 1) . ' days')->formatDateDb();
235 }
236
237 $dayStart = $this->t->setDateDb( $startDate )->formatDateTimeDb();
238 $dayEnd = $this->t->setDateDb( $endDate )->modify( '+1 day')->formatDateTimeDb();
239
240 $disabledWeekdays = $this->settings->get( 'skip_weekdays', TRUE );
241 $this->t->setDateDb( $startDate );
242 $dates = array();
243 $rexDate = $startDate;
244 while( $rexDate <= $endDate ){
245 if( $disabledWeekdays ){
246 $wkd = $this->t->getWeekday();
247 if( in_array($wkd, $disabledWeekdays) ){
248 $rexDate = $this->t->modify('+1 day')->formatDateDb();
249 continue;
250 }
251 }
252 $dates[] = $rexDate;
253 $rexDate = $this->t->modify('+1 day')->formatDateDb();
254 }
255
256 $viewCalendars = array();
257 foreach( $calendars as $calendar ){
258 $calendarId = $calendar->getId();
259 // $calendarView = $this->calendarsPresenter->presentTitle( $calendar );
260
261 $label = $calendar->getTitle();
262
263 $title = htmlspecialchars( $label );
264 $description = $calendar->getDescription();
265 if( strlen($description) ){
266 $description = htmlspecialchars( $description );
267 $title .= "\n" . $description;
268 }
269
270 $label = $this->ui->makeSpan( $label )
271 ->addAttr( 'title', $title )
272 ;
273
274 $viewCalendars[ $calendarId ] = $label;
275 }
276
277 $viewShifts = array();
278
279 $iknow = array('calendar', 'date');
280 $hori = FALSE;
281
282 $allEmployees = $this->common->findAllEmployees();
283 if( count($allEmployees) < 2 ){
284 $iknow[] = 'employee';
285 }
286
287 $out = array();
288
289 reset( $dates );
290 foreach( $dates as $date ){
291 $thisOut = array();
292 $rows = array();
293
294 $this->t->setDateDb( $date );
295 $dateView = $this->self->renderDateLabel( $date );
296 $thisOut[] = $dateView;
297
298 $viewShifts = array();
299
300 reset( $shifts );
301 foreach( $shifts as $shift ){
302 $start = $shift->getStart();
303 $end = $shift->getEnd();
304
305 $startDate = $this->t->setDateTimeDb( $start )->formatDateDb();
306 // echo "START '$startDate' VS '$date'<br>";
307 if( $startDate > $date ){
308 continue;
309 }
310
311 $endDate = $this->t->setDateTimeDb( $end )->formatDateDb();
312 // echo "END '$endDate' VS '$date'<br>";
313 if( $endDate < $date ){
314 continue;
315 }
316
317 // echo "'$startDate' - '$endDate' VS '$date' OK<br><br>";
318
319 $calendar = $shift->getCalendar();
320 $id = $calendar->getId();
321
322 if( ! array_key_exists($id, $viewShifts) ){
323 $viewShifts[$id] = array();
324 }
325
326 $viewShifts[$id][] = $shift;
327 }
328
329 $header = array();
330 $header[] = NULL;
331 $header[] = NULL;
332
333 $dayStart = $this->t->setDateDb( $startDate )->formatDateTimeDb();
334 $dayEnd = $this->t->setDateDb( $startDate )->modify('+1 day')->formatDateTimeDb();
335
336 reset( $viewCalendars );
337 foreach( $viewCalendars as $id => $calendarView ){
338 $row = array();
339
340 $this->shiftsDuration->reset();
341 if( isset($viewShifts[$id]) ){
342 foreach( $viewShifts[$id] as $shift ){
343 $this->shiftsDuration->add( $shift );
344 }
345
346 $outReport = $this->common->renderReport( $this->shiftsDuration, FALSE );
347 $outReport = $this->ui->makeSpan( $outReport )
348 ->tag('font-size', 2)
349 ;
350 $calendarView = $this->ui->makeList( array($calendarView, $outReport) )
351 ->gutter(1)
352 ;
353 }
354
355 $calendarView = $this->ui->makeBlock( $calendarView )
356 ->tag('padding', 2)
357 ->tag('nowrap')
358 ;
359 $row[] = $calendarView;
360
361 $cell = array();
362
363 if( isset($viewShifts[$id]) ){
364 $gridView = $this->self->renderDay( $viewShifts[$id], $iknow, $date );
365 $cell[] = $gridView;
366 }
367
368 $thisCalendar = $calendars[$id];
369 if( $thisCalendar->isTimeoff() ){
370 $label = '+ ' . '__Time Off__';
371 }
372 else {
373 $label = '+ ' . '__Shift__';
374 }
375
376 $to = 'new';
377 $toParams = array(
378 'date' => $date
379 );
380 if( array_key_exists('employee', $params) && (count($params['employee']) == 1) ){
381 if( ! in_array(-1, $params['employee']) ){
382 $toParams['employee'] = $params['employee'][0];
383 }
384 }
385 $to = array( $to, $toParams );
386
387 $addOk = FALSE;
388 if( isset($toParams['employee']) ){
389 $testComboId = $id . '-' . $toParams['employee'];
390 if( isset($this->allCombos[$testComboId]) ){
391 $addOk = TRUE;
392 }
393 }
394 else {
395 $testComboId = $id . '-';
396 reset( $this->allCombos );
397 foreach( $this->allCombos as $comboId ){
398 if( $testComboId == substr($comboId, 0, strlen($testComboId)) ){
399 $addOk = TRUE;
400 break;
401 }
402 }
403 }
404
405 if( $addOk ){
406 $link = $this->ui->makeAhref( $to, $label )
407 ->tag('tab-link')
408 ->tag('align', 'center')
409 ;
410
411 if( $today > $date ){
412 $link->tag('muted', 3);
413 }
414
415 $cell[] = $link;
416 }
417
418 $cell = $this->ui->makeList( $cell )
419 ->gutter(1)
420 ->tag('margin', 1)
421 ;
422
423 $row[] = $cell;
424
425 $rows[] = $row;
426 }
427
428 $thisOut[] = $this->ui->makeTable( $header, $rows, FALSE )
429 ->gutter(0)
430 ->setBordered( $this->borderColor )
431 // ->setSegments( $weekSegments )
432 ->setLabelled( TRUE )
433 ;
434
435 $thisOut = $this->ui->makeList( $thisOut );
436
437 $out[] = $thisOut;
438 }
439
440 $out = $this->ui->makeList( $out );
441
442 return $out;
443 }
444
445 public function renderByEmployee()
446 {
447 $calendars = $this->common->getCalendars();
448 $employees = $this->common->getEmployees();
449 $shifts = $this->common->getShifts();
450 $today = $this->t->setNow()->formatDateDb();
451
452 $disabledWeekdays = $this->settings->get( 'skip_weekdays', TRUE );
453
454 $params = $this->request->getParams();
455 $startDate = $params['start'];
456 $endDate = $startDate;
457 if( static::$daysToShow > 1 ){
458 $endDate = $this->t->setDateDb( $startDate )->modify( '+' . (static::$daysToShow - 1) . ' days')->formatDateDb();
459 }
460
461 $dayStart = $this->t->setDateDb( $startDate )->formatDateTimeDb();
462 $dayEnd = $this->t->setDateDb( $endDate )->modify( '+1 day')->formatDateTimeDb();
463
464 $disabledWeekdays = $this->settings->get( 'skip_weekdays', TRUE );
465 $this->t->setDateDb( $startDate );
466 $dates = array();
467 $rexDate = $startDate;
468 while( $rexDate <= $endDate ){
469 if( $disabledWeekdays ){
470 $wkd = $this->t->getWeekday();
471 if( in_array($wkd, $disabledWeekdays) ){
472 $rexDate = $this->t->modify('+1 day')->formatDateDb();
473 continue;
474 }
475 }
476 $dates[] = $rexDate;
477 $rexDate = $this->t->modify('+1 day')->formatDateDb();
478 }
479
480 $viewEmployees = array();
481 foreach( $employees as $employee ){
482 $label = $employee->getTitle();
483
484 $title = htmlspecialchars( $label );
485 $description = $employee->getDescription();
486 if( strlen($description) ){
487 $description = htmlspecialchars( $description );
488 $title .= "\n" . $description;
489 }
490
491 $label = $this->ui->makeSpan( $label )
492 ->tag( 'font-size', 4 )
493 ->addAttr( 'title', $title )
494 ;
495
496 $viewEmployees[ $employee->getId() ] = $label;
497 }
498
499 $viewShifts = array();
500
501 $iknow = array('employee', 'date');
502 $hori = FALSE;
503
504 $out = array();
505
506 reset( $dates );
507 foreach( $dates as $date ){
508 $thisOut = array();
509
510 $thisOut = array();
511 $rows = array();
512
513 $this->t->setDateDb( $date );
514 $dateView = $this->self->renderDateLabel( $date );
515 $thisOut[] = $dateView;
516
517 $viewShifts = array();
518
519 foreach( $shifts as $shift ){
520 $employee = $shift->getEmployee();
521 $id = $employee ? $employee->getId() : 0;
522
523 if( ! array_key_exists($id, $viewShifts) ){
524 $viewShifts[$id] = array();
525 }
526
527 $viewShifts[$id][] = $shift;
528 }
529
530 $header = array();
531 $header[] = NULL;
532 $header[] = NULL;
533
534 $rows = array();
535
536 foreach( $viewEmployees as $id => $employeeView ){
537 $row = array();
538
539 $this->shiftsDuration->reset();
540 if( isset($viewShifts[$id]) ){
541 $counted = 0;
542 foreach( $viewShifts[$id] as $shift ){
543 $shiftCalendar = $shift->getCalendar();
544 // if( ! $shiftCalendar->isShift() ){
545 // continue;
546 // }
547 $this->shiftsDuration->add( $shift );
548 $counted++;
549 }
550
551 if( $counted ){
552 $outReport = $this->common->renderReport( $this->shiftsDuration, FALSE );
553 $outReport = $this->ui->makeSpan( $outReport )
554 ->tag('font-size', 2)
555 ;
556 $employeeView = $this->ui->makeList( array($employeeView, $outReport) )
557 ->gutter(1)
558 ;
559 }
560 }
561
562 $thisShifts = isset( $view_shifts[$id] ) ? $view_shifts[$id] : array();
563 $employeeView = $this->common->employeeRowLabel( $employeeView, $id, 'day', $dates, $thisShifts );
564
565 $employeeView = $this->ui->makeBlock( $employeeView )
566 ->tag('padding', 2)
567 ->tag('nowrap')
568 ;
569 $row[] = $employeeView;
570
571 $cell = array();
572
573 if( isset($viewShifts[$id]) ){
574 $gridView = $this->self->renderDay( $viewShifts[$id], $iknow, $date );
575 $cell[] = $gridView;
576 }
577
578 $toParams = array(
579 'employee' => $id,
580 'date' => $date
581 );
582
583 $links = array();
584
585 $comboId = 0 . '-' . $id;
586
587 if( isset($this->allCombosShift[$comboId]) ){
588 $label = '+' . ' ' . '__Shift__';
589 $thisTo = 'new/shift';
590 $thisTo = array( $thisTo, $toParams );
591 $link = $this->ui->makeAhref( $thisTo, $label )
592 ->tag('tab-link')
593 ->tag('align', 'center')
594 // ->addAttr('title', '__Add New__')
595 ;
596 if( $today > $date ){
597 $link->tag('muted', 3);
598 }
599 $links[] = $link;
600 }
601
602 if( isset($this->allCombosTimeoff[$comboId]) ){
603 $label = '+' . ' ' . '__Time Off__';
604 $thisTo = 'new/timeoff';
605 $thisTo = array( $thisTo, $toParams );
606 $link = $this->ui->makeAhref( $thisTo, $label )
607 ->tag('tab-link')
608 ->tag('align', 'center')
609 // ->addAttr('title', '__Add New__')
610 ;
611 if( $today > $date ){
612 $link->tag('muted', 3);
613 }
614 $links[] = $link;
615 }
616
617 $links = $this->ui->makeList( $links )->gutter(0);
618
619 $cell[] = $links;
620
621 $cell = $this->ui->makeList( $cell )
622 ->gutter(1)
623 ->tag('margin', 1)
624 ;
625
626 $row[] = $cell;
627
628 $rows[] = $row;
629 }
630
631
632 $thisOut[] = $this->ui->makeTable( $header, $rows, FALSE )
633 ->gutter(0)
634 ->setBordered( $this->borderColor )
635 // ->setSegments( $weekSegments )
636 ->setLabelled( TRUE )
637 ;
638
639 $thisOut = $this->ui->makeList( $thisOut );
640
641 $out[] = $thisOut;
642 }
643
644 $out = $this->ui->makeList( $out );
645
646 return $out;
647 }
648
649 public function renderDay( $shifts, $iknow, $startDate = NULL )
650 {
651 $hori = FALSE;
652 $params = $this->request->getParams();
653
654 $hideui = $params['hideui'];
655 $noZoom = in_array('shiftdetails', $hideui);
656
657 if( array_key_exists('employee', $params) && (count($params['employee']) == 1) ){
658 if( ! in_array(-1, $params['employee']) ){
659 $iknow[] = 'employee';
660 }
661 }
662 if( array_key_exists('calendar', $params) && (count($params['calendar']) == 1) ){
663 $iknow[] = 'calendar';
664 }
665
666 if( NULL === $startDate ){
667 $startDate = $params['start'];
668 }
669
670 $this->t->setDateDb( $startDate );
671 $minTime = $this->settings->get('datetime_min_time');
672 if( $minTime ){
673 $this->t->modify('+' . $minTime . ' seconds');
674 }
675 $dayStart = $this->t->formatDateTimeDb();
676
677 $this->t->setDateDb( $startDate );
678 $maxTime = $this->settings->get('datetime_max_time');
679 if( $maxTime ){
680 $this->t->modify('+' . $maxTime . ' seconds');
681 }
682 else {
683 $this->t->modify('+1 day');
684 }
685 $dayEnd = $this->t->formatDateTimeDb();
686
687 $grid = $this->widgetDayGrid
688 ->reset()
689 ;
690 $grid->setRange( $dayStart, $dayEnd );
691
692 // groups?
693 $groups = array();
694 $groupedShifts = array();
695 reset( $shifts );
696 foreach( $shifts as $shift ){
697 if( ! $shift->isOpen() ){
698 continue;
699 }
700
701 $groupId = $shift->getGroupingId();
702
703 if( ! isset($groups[$groupId]) ){
704 $groups[ $groupId ] = $shift->getId();
705 $groupedShifts[ $shift->getId() ] = array( $shift->getId() => $shift );
706 }
707 else {
708 $mainShiftId = $groups[ $groupId ];
709 $groupedShifts[ $mainShiftId ][ $shift->getId() ] = $shift;
710 $groupedShifts[ $shift->getId() ] = 0;
711 }
712 }
713
714 reset( $shifts );
715 foreach( $shifts as $shift ){
716 $id = $shift->getId();
717 if( isset($groupedShifts[$id]) && (! $groupedShifts[$id]) ){
718 continue;
719 }
720
721 $groupedQty = NULL;
722 if( isset($groupedShifts[$id]) && (count($groupedShifts[$id]) > 1) ){
723 $groupedQty = count($groupedShifts[$id]);
724 }
725
726 $thisView = $this->widget->render( $shift, $iknow, $hori, $noZoom, $groupedQty );
727 $shiftId = $shift->getId();
728
729 $buildMenuFromShifts = isset($groupedShifts[$id]) ? $groupedShifts[$id] : array( $shift );
730 $menu = $this->shiftsCommon->bulkMenu( $buildMenuFromShifts );
731 if( $menu ){
732 $thisView = $this->ui->makeCollection( array($thisView, $menu) );
733 }
734
735 $thisView = $this->ui->makeBlock( $thisView )
736 ->tag('block')
737 ->addAttr('class', 'sh4-shift-widget')
738 ->addAttr('style', 'padding-right: 1px;')
739 ;
740
741 $grid
742 ->add( $shift->getStart(), $shift->getEnd(), $thisView )
743 ;
744 }
745
746 $return = $grid->render();
747 return $return;
748 }
749 }