PluginProbe
ShiftController Employee Shift Scheduling / 4.9.66
ShiftController Employee Shift Scheduling v4.9.66
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 / week.php

week.php in ShiftController Employee Shift Scheduling 4.9.66, at sh4/schedule/html/view/week.php

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