/** * Run tests to ensure the output is correct for set/getDayOffset * * @return void */ public function testOffset() { $schedule = new Schedule(); $schedule->setDayOffset(0, 38, 1); $this->assertEquals(1, $schedule->getDayOffset(0, 38)); $schedule->setDayOffset(1, 93, 1); $this->assertEquals(1, $schedule->getDayOffset(1, 93)); $schedule->setDayOffset(2, 61, 1); $this->assertEquals(1, $schedule->getDayOffset(2, 61)); $schedule->setDayOffset(3, 11, 1); $this->assertEquals(1, $schedule->getDayOffset(3, 11)); $schedule->setDayOffset(4, 87, 1); $this->assertEquals(1, $schedule->getDayOffset(4, 87)); $schedule->setDayOffset(5, 74, 1); $this->assertEquals(1, $schedule->getDayOffset(5, 74)); $schedule->setDayOffset(6, 52, 1); $this->assertEquals(1, $schedule->getDayOffset(6, 52)); }
public function weekClockReport($uid, $week) { $week = $this->dtUtils->getFirstDayOfWeek($week); $nextWeek = clone $week; $nextWeek->modify("+7 days"); $user = $this->em->getRepository('OpenSkedgeBundle:User')->find($uid); if (!$user instanceof User) { throw new \Exception('User entity was not found!'); } $archivedClock = $this->em->getRepository('OpenSkedgeBundle:ArchivedClock')->findOneBy(array('week' => $week, 'user' => $uid)); if (!$archivedClock instanceof ArchivedClock) { return new Schedule(); } $schedulePeriods = $this->em->getRepository('OpenSkedgeBundle:SchedulePeriod')->findSchedulePeriodsForWeek($week); $schedules = array(); foreach ($schedulePeriods as $sp) { $schedules[] = $this->em->getRepository('OpenSkedgeBundle:Schedule')->findBy(array('user' => $uid, 'schedulePeriod' => $sp->getId())); } // Create a temporary Schedule entity to store the composite of all the users schedules. $scheduled = new Schedule(); for ($i = 0; $i < count($schedulePeriods); $i++) { foreach ($schedules[$i] as $s) { for ($timesect = 0; $timesect < 96; $timesect++) { for ($day = 0; $day < 7; $day++) { if ($s->getDayOffset($day, $timesect) == '1') { $scheduled->setDayOffset($day, $timesect, '1'); } } } } } $shifts = $this->em->createQuery("SELECT sh FROM OpenSkedgeBundle:Shift sh\n WHERE (sh.pickedUpBy = :user AND sh.startTime >= :week AND sh.endTime < :nextWeek AND sh.status != 'unapproved')")->setParameter('user', $user)->setParameter('week', $week)->setParameter('nextWeek', $nextWeek)->getResult(); foreach ($shifts as $shift) { $startIndex = $this->dtUtils->getIndexFromTime($shift->getStartTime()); $endIndex = $this->dtUtils->getIndexFromTime($shift->getEndTime()); if ($endIndex === -1) { // Midnight end hour $endIndex = 96; } // Update the schedule composite to mark shifts they had picked up. if ($shift->getStartTime()->format('w') === $shift->getEndTime()->format('w')) { $day = $shift->getStartTime()->format('w'); for ($i = $startIndex; $i < $endIndex; $i++) { $scheduled->setDayOffset($day, $i, '1'); } } else { if ($shift->getStartTime()->format('w') === $shift->getEndTime()->format('w') - 1) { $day = $shift->getStartTime()->format('w'); for ($i = $startIndex; $i < 96; $i++) { $scheduled->setDayOffset($day, $i, '1'); } for ($i = 0; $i < $endIndex; $i++) { $scheduled->setDayOffset($day + 1, $i, '1'); } } } } for ($i = 0; $i < 7; $i++) { for ($j = 0; $j < 96; $j++) { if ($archivedClock->getDayOffset($i, $j) == '1' and $scheduled->getDayOffset($i, $j) == '1') { $scheduled->setDayOffset($i, $j, '1'); } elseif ($archivedClock->getDayOffset($i, $j) == '1' and $scheduled->getDayOffset($i, $j) == '0') { $scheduled->setDayOffset($i, $j, '3'); } elseif ($archivedClock->getDayOffset($i, $j) == '0' and $scheduled->getDayOffset($i, $j) == '1') { $scheduled->setDayOffset($i, $j, '2'); } else { $scheduled->setDayOffset($i, $j, '0'); } } } return $scheduled; }
/** * Edits an existing Schedule entity. * * @param Request $request The user's request object * @param integer $pid Position ID from request * @param integer $spid Schedule period ID from request * * @return Symfony\Component\HttpFoundation\Response */ public function editAction(Request $request, $pid, $spid) { if (false === $this->get('security.context')->isGranted('ROLE_ADMIN')) { throw new AccessDeniedException(); } $em = $this->getDoctrine()->getManager(); $position = $em->getRepository('OpenSkedgeBundle:Position')->find($pid); if (!$position instanceof Position) { throw $this->createNotFoundException('Unable to find Position entity.'); } $schedulePeriod = $em->getRepository('OpenSkedgeBundle:SchedulePeriod')->find($spid); if (!$schedulePeriod instanceof SchedulePeriod) { throw $this->createNotFoundException('Unable to find SchedulePeriod entity.'); } $availSchedules = $em->getRepository('OpenSkedgeBundle:AvailabilitySchedule')->findBy(array('schedulePeriod' => $spid)); $availData = array(); foreach ($availSchedules as $avail) { /* We're using this entity as a temporary container * which generates a schedule based on the user's * availability schedule and any scheduled positions they may have. * 0 = Pending (treated as available if present in Twig template) * 1 = Unavailable (They're schedule for something else or marked unavailable) * 2 = Scheduled for current position * 3 = Available */ $genAS = new Schedule(); $genAS->setUser($avail->getUser()); $hoursScheduled = 0; foreach ($avail->getUser()->getSchedules() as $schedule) { $isPosition = $schedule->getPosition()->getId() == $position->getId(); $isSchedulePeriod = $schedule->getSchedulePeriod()->getId() == $schedulePeriod->getId(); for ($timesect = 0; $timesect < 96; $timesect++) { for ($day = 0; $day < 7; $day++) { // Check the availability schedule to see if the user is available at all. if ($avail->getDayOffset($day, $timesect) != '0' && $isSchedulePeriod) { if ($isPosition && $schedule->getDayOffset($day, $timesect) == '1') { $genAS->setDayOffset($day, $timesect, 2); } else { if (!$isPosition && $schedule->getDayOffset($day, $timesect) == '1' && $genAS->getDayOffset($day, $timesect) != '2') { $genAS->setDayOffset($day, $timesect, 1); } else { if ($schedule->getDayOffset($day, $timesect) == '0' && $genAS->getDayOffset($day, $timesect) == 0) { $genAS->setDayOffset($day, $timesect, 3); } } } } else { if ($avail->getDayOffset($day, $timesect) == '0') { $genAS->setDayOffset($day, $timesect, 1); } } } } if ($isSchedulePeriod) { $scheduleSum = 0; for ($day = 0; $day < 7; $day++) { $scheduleSum += substr_count($schedule->getDay($day), '1'); } $hoursScheduled += $scheduleSum / 4; } } // Pass the user's availability schedule too, as we'll need to reference that for priorties. $availData[] = array('gen' => $genAS, 'schedule' => $avail, 'totalHours' => $hoursScheduled); } $deleteForm = $this->createDeleteForm($pid, $spid); $appSettings = $this->get('app_settings')->getAppSettings(); // Get the requested time resolution, if available. Default to global default. $resolution = $request->query->get('timeresolution', $appSettings->getDefaultTimeResolution()); if ($request->getMethod() == 'POST') { // Get the section divisor from the resolution used when the form was POSTed. $sectiondiv = $request->request->get('sectiondiv'); $schedules = $em->getRepository('OpenSkedgeBundle:Schedule')->findBy(array('schedulePeriod' => $spid, 'position' => $pid)); $uids = array(); /** * Populate UID array with UIDs of users who already have * schedule for $pid and $spid. */ foreach ($schedules as $schedule) { $uids[] = $schedule->getUser()->getId(); } /** * Append UID array with UIDs of users who have been scheduled * in the POSTed request. */ for ($timesect = 0; $timesect < 96; $timesect += $sectiondiv) { for ($day = 0; $day < 7; $day++) { $hourElement = "hour-" . $timesect . "-" . $day; $hourUids = $request->request->get($hourElement); if (!empty($hourUids)) { foreach ($hourUids as $uid) { $uids[] = (int) $uid; } } } } // Filter out duplicate UIDs. $uids = array_unique($uids); // Build or rebuild the schedule for each UID. foreach ($uids as $uid) { // Get the user's schedule for this $pid and $spid, if it exists. $schedule = $em->getRepository('OpenSkedgeBundle:Schedule')->findOneBy(array('schedulePeriod' => $spid, 'position' => $pid, 'user' => $uid)); $new = false; // If it doesn't exist, create it. if (!$schedule instanceof Schedule) { $schedule = new Schedule(); $tuser = $em->getRepository('OpenSkedgeBundle:User')->find($uid); if (!$tuser instanceof \OpenSkedge\AppBundle\Entity\User) { throw $this->createNotFoundException('Unable to find User entity'); } $schedule->setUser($tuser); $schedule->setSchedulePeriod($schedulePeriod); $schedule->setPosition($position); // Mark that this is a new schedule for the user. $new = true; } /** * If the each timesect exists in the POSTed data, mark it as scheduled. * If it doesn't exist in the POSTed data, mark it as not scheduled. */ for ($timesect = 0; $timesect < 96; $timesect += $sectiondiv) { for ($day = 0; $day < 7; $day++) { $hourElement = "hour-" . $timesect . "-" . $day; $hourUids = $request->request->get($hourElement); if (empty($hourUids) or !in_array($uid, $hourUids)) { for ($sectpart = 0; $sectpart < $sectiondiv; $sectpart++) { $schedule->setDayOffset($day, $timesect + $sectpart, 0); } } else { for ($sectpart = 0; $sectpart < $sectiondiv; $sectpart++) { $schedule->setDayOffset($day, $timesect + $sectpart, 1); } } } } $em->persist($schedule); // If this is a new schedule, notify the user of their new schedule. if ($new) { $mailer = $this->container->get('notify_mailer'); $mailer->notifyUserScheduleChange($schedule); } } $em->flush(); return $this->redirect($this->generateUrl('position_schedule_view', array('pid' => $pid, 'spid' => $spid))); } $dtUtils = $this->get('dt_utils'); $startIndex = $dtUtils->getIndexFromTime($appSettings->getStartHour()); $endIndex = $dtUtils->getIndexFromTime($appSettings->getEndHour()) - 1; if ($endIndex === -1) { // Midnight end hour $endIndex = 95; } return $this->render('OpenSkedgeBundle:Schedule:edit.html.twig', array('htime' => $dtUtils->timeStrToDateTime($appSettings->getStartHour()), 'resolution' => $resolution, 'schedulePeriod' => $schedulePeriod, 'position' => $position, 'availData' => $availData, 'edit' => true, 'deleteForm' => $deleteForm->createView(), 'startIndex' => $startIndex, 'endIndex' => $endIndex)); }