/** * Register new Shift from type ShiftType * @param WorkingDay $workingDay * @param ShiftType $shiftType * @param int $amountOfDrivers * @param int $status * @param bool $manuallyEdited * @return Shift */ public static function registerShift(WorkingDay $workingDay, ShiftType $shiftType, $amountOfDrivers = 0, $status = self::OPEN, $manuallyEdited = false) { $shift = new Shift(); $shift->setWorkingDay($workingDay); $shift->setShiftType($shiftType); $shift->setAmountOfDrivers($amountOfDrivers); $shift->setStatus($status); $shift->setManuallyEdited($manuallyEdited); return $shift; }
/** * @param Shift $shift * @return bool */ public function matching(Shift $shift) { $startDate = $this->getAssertionPlan()->getAnchorDate(); $endDate = $this->getAssertionPlan()->getEndingDate(); /**@var $shiftDate \DateTime */ $shiftDate = $shift->getDate(); $wd = $shiftDate->format('N'); if ($shiftDate >= $startDate && $shiftDate <= $endDate) { if ($wd == $this->getWeekday()) { if ($this->matchShiftType($shift->getShiftType())) { return true; } } } return false; }
public function testWorkingMonthDriverAssignment() { $monthDate = new \DateTime('2014-07-01'); $workingMonth = $this->init->workingMonthRepo->findWorkingMonthByDate($monthDate); if ($workingMonth === null) { $workingMonth = WorkingMonth::registerWorkingMonth($monthDate); $workingMonth->setMemo('Test'); $workingMonth->createWorkingDaysForThisMonth(); $this->init->workingMonthRepo->store($workingMonth); $workingDays = $workingMonth->getWorkingDays(); $shiftTypes = $this->init->shiftTypeRepo->findAllActive(); //create workingDays shifts, assign them drivingpools, get amount of needed drivers /** @var $workingDay WorkingDay */ foreach ($workingDays as $workingDay) { /** @var $shiftType ShiftType */ foreach ($shiftTypes as $shiftType) { $shift = Shift::registerShift($workingDay, $shiftType); $shift->setAmountOfDrivers(rand(12, 20)); $workingDay->assignShift($shift); for ($i = 1; $i <= $shift->getAmountOfDrivers(); $i++) { $drivingPool = DrivingPool::registerDrivingPool($shift); $shift->assignDrivingPool($drivingPool); $this->init->drivingPoolRepo->store($drivingPool); } $this->init->shiftRepo->store($shift); } $this->init->workingDayRepo->store($workingDay); } $this->init->em->flush(); } }
/** * @param Shift $shift * @return bool */ public function matching(Shift $shift) { $startDate = $this->getAssertionPlan()->getAnchorDate(); $endDate = $this->getAssertionPlan()->getEndingDate(); /**@var $shiftDate \DateTime */ $shiftDate = $shift->getDate(); $checkDate = clone $shiftDate; $checkDate->modify($this->getRelativeWeekAsText() . ' ' . $this->getWeekdayAsText() . ' of this month'); if ($shiftDate >= $startDate && $shiftDate <= $endDate) { if ($shiftDate->format('Ymd') === $checkDate->format('Ymd')) { if ($this->matchShiftType($shift->getShiftType())) { return true; } } } return false; }
public function testShiftCRUD() { $from = \DateTime::createFromFormat('H:i', '10:00'); $to = \DateTime::createFromFormat('H:i', '14:00'); $shiftType = ShiftType::registerShiftType('Test123', $from, $to); $this->init->shiftTypeRepo->store($shiftType); $this->init->em->flush(); $find = $this->init->shiftTypeRepo->find($shiftType->getId()); $this->assertEquals($shiftType, $find); $workDay = WorkingDay::registerWorkingDay(new \DateTime()); $this->init->workingDayRepo->store($workDay); $shift = Shift::registerShift($workDay, $shiftType, 12); $this->init->shiftRepo->store($shift); $this->init->em->flush(); $find = $this->init->shiftRepo->find($shift->getId()); $this->assertEquals($shift, $find); }
/** * @param Shift $shift */ public function matching(Shift $shift) { foreach ($this->getServicePlans() as $servicePlan) { if ($servicePlan->matchDate($shift->getDate())) { // todo code incomplete... } } }
/** * @param Shift $shift * @param $driverId * @return null|DrivingAssertion */ private function getDrivingAssertion(Shift $shift, $driverId) { /** @var DrivingAssertion $drivingAssertion */ foreach ($shift->getDrivingAssertionsAsArray() as $drivingAssertion) { if ($drivingAssertion->getDriver()->getId() == $driverId) { return $drivingAssertion; } } return null; }
public function testDrivingOrderCRUD() { $addressFrom = $this->init->createTestAddressBaar(); $addressTo = $this->init->createTestAddressGoldau(); $passenger = Passenger::registerPassenger('m', 'Arthuro', 'Benatone', '+418182930', $addressFrom); $this->init->passengerRepo->store($passenger); $date = $this->init->dateTimeService->convertDateTimeStringToUTCDateTime('20.05.2014 00:00'); $time = $this->init->dateTimeService->convertDateTimeStringToUTCDateTime('20.05.2014 15:05'); $route = Route::registerRoute($addressFrom, $addressTo, 0, 0); $route->setDuration(15); $route->setDistance(6); $this->init->routeRepo->store($route); $drivingOrder = DrivingOrder::registerDrivingOrder($passenger, $date, $time, 2, 'möchte nicht hinten sitzen'); $drivingOrder->assignRoute($route); $passenger->assignDrivingOrder($drivingOrder); $drivingOrder->assignPassenger($passenger); $this->init->drivingOrderRepo->store($drivingOrder); $this->init->em->flush(); $this->assertNotNull($this->init->drivingOrderRepo->find($drivingOrder->getId())); //TimePeriod from start day of month to next start day of month $monthsAgo = 3; $monthDate = new \DateTime('today'); $monthDate->modify('+' . $monthsAgo . ' month'); $monthDate->format('first day of this month'); $workingMonth = WorkingMonth::registerWorkingMonth($monthDate); $workingMonth->createWorkingDaysForThisMonth(); foreach ($workingMonth->getWorkingDays() as $wd) { $this->init->workingDayRepo->store($wd); } $this->init->workingMonthRepo->store($workingMonth); $workingDays = $workingMonth->getWorkingDays(); /**@var $shiftTypes ShiftType[] */ $shiftTypes = $this->init->shiftTypeRepo->findAllActive(); //create workingDays shifts, assign them drivingpools, get amount of needed drivers /** @var $workingDay WorkingDay */ foreach ($workingDays as $workingDay) { /** @var $shiftType ShiftType */ foreach ($shiftTypes as $shiftType) { $shift = Shift::registerShift($workingDay, $shiftType); $shift->setAmountOfDrivers(16); $workingDay->assignShift($shift); for ($i = 1; $i <= $shift->getAmountOfDrivers(); $i++) { $drivingPool = DrivingPool::registerDrivingPool($shift); $shift->assignDrivingPool($drivingPool); $this->init->drivingPoolRepo->store($drivingPool); } $this->init->shiftRepo->store($shift); } $this->init->workingDayRepo->store($workingDay); } $this->init->em->flush(); $this->assertNotNull($this->init->workingMonthRepo->find($workingMonth->getId())); $drivingAssertionPlans = $this->init->repeatedDrivingAssertionPlanRepo->findPlanForDate(new \DateTime()); $this->assertNotNull($drivingAssertionPlans); $drivingPools = array(); foreach ($workingMonth->getWorkingDays() as $wd) { foreach ($wd->getShifts() as $s) { foreach ($s->getDrivingPools() as $dp) { array_push($drivingPools, $dp); } } } foreach ($drivingAssertionPlans as $drivingAssertionPlan) { $assertions = $drivingAssertionPlan->getRepeatedDrivingAssertions(); foreach ($assertions as $assertion) { if ($assertion->matching($shift)) { echo "\nmatches\n"; $drivingPool = DrivingPool::registerDrivingPool($shift); $this->init->drivingPoolRepo->store($drivingPool); } } } $vehicles = $this->init->vehicleRepo->findAll(); /**@var $vehicle Vehicle */ foreach ($vehicles as $vehicle) { foreach ($vehicle->getServicePlans() as $sp) { } } }
/** * @param Shift $shift */ public function assignShift(Shift $shift) { $this->shift = $shift; $shift->assignDrivingAssertion($this); /* * set sortOrder to shifts working day + start time * this is redundant, but needed for sorting in DataGrid */ $localDate = clone $shift->getDate(); // date in timezone Europe/Paris $utcStart = clone $shift->getStart(); // time in timezone UTC $utcStart->setTimezone($localDate->getTimezone()); $localDate->setTime($utcStart->format('H'), $utcStart->format('i')); $localDate->setTimezone(new \DateTimeZone('UTC')); $this->sortOrder = $localDate; }
/** * Production code: * runs routing algorithm to set optimized missions and orders for a shift * * @param Shift $shift * @param boolean $verbose * @return array containing information for user */ public function buildRidePlanForShift(Shift $shift, $verbose = true) { $day = $shift->getDate(); $tr = $this->container->get('translator'); $infos = array(); if ($verbose) { $infos[] = $tr->trans('ride.info.shift') . ' ' . $day->format('d.m.Y') . ', ' . $tr->trans(DateTimeService::getDayOfWeek($day)) . ' ' . $shift->getShiftType()->getName() . '.'; } //set php execution timeout for big calculations ini_set('max_execution_time', 300); $em = $this->container->get('entity_manager'); $em->beginTransaction(); //set STRATEGY for RideOptimization $rideStrategy = new RideStrategyAnnealing(); $rideStrategy->setContainer($this->container); //set Shift $shift->setManuallyEdited(false); // optimization resets manual attribute // set DrivingPools $drivingPools = $shift->getDrivingPoolsAsArray(); if (count($drivingPools) < 1) { $em->rollback(); $infos[] = $tr->trans('ride.error.noPools') . ' ' . $shift->getShiftType()->getName() . '.'; return $infos; } // set DrivingMissions $dispoManagement = $this->container->get('tixi_app.dispomanagement'); $drivingMissions = $dispoManagement->getDrivingMissionsInShift($shift); if (count($drivingMissions) < 1) { $em->rollback(); $infos[] = $tr->trans('ride.error.noMissions') . ' ' . $shift->getShiftType()->getName() . '.'; return $infos; } //clean drivingPools for new optimization foreach ($drivingPools as $pool) { $pool->removeDrivingMissions(); } $configurationBuilder = new ConfigurationBuilder($drivingMissions, $drivingPools, $rideStrategy); $this->logger($tr->trans('ride.log.dayAndShift'), array($day->format('d.m.Y'), $shift->getShiftType()->getName())); //get all empty Rides $emptyRides = $configurationBuilder->buildAllPossibleEmptyRides(); //get routing information from routing machine and fill node objects $s = microtime(true); $routeManagement = $this->container->get('tixi_app.routemanagement'); $emptyRides = $routeManagement->fillRoutesForMultipleRideNodes($emptyRides); $e = microtime(true); $this->logger($tr->trans('ride.log.routingTime'), array(count($emptyRides), round($e - $s, 3))); //create ride configurations with strategy $s = microtime(true); $rideConfigurations = $configurationBuilder->buildConfigurations(); if ($rideConfigurations === null) { $em->rollback(); $infos[] = $tr->trans('ride.error.noConfiguration'); return $infos; } $e = microtime(true); $nodes = count($rideConfigurations); $this->logger($tr->trans('ride.log.buildTime'), array($nodes, round($e - $s, 3))); // get the best feasible configuration $rideConfiguration = $this->getBestConfiguration($rideConfigurations); $configurationAnalyzer = new ConfigurationAnalyzer($rideConfiguration); $configurationAnalyzer->assignMissionsAndVehiclesToPool(); $booked = $rideConfiguration->countNodes(); $overbooked = count($rideConfiguration->getNotFeasibleNodes()); if ($verbose) { $infos[] = $tr->trans('ride.info.nodes') . ' ' . $booked . ', ' . $tr->trans('ride.info.overbooked') . ' ' . $overbooked . '.'; } $this->logger($tr->trans('ride.log.success'), array($nodes, $overbooked)); // if everything worked, return successfully $em->commit(); $em->flush(); return $infos; }
/** * Open (build) a new working month and associated working days (~30), * shifts (~90) , and driving pools (~1800). * * @param $year * @param $month * @return array|null|WorkingMonth */ public function openWorkingMonth($year, $month) { /** @var WorkingMonthRepository $workingMonthRepository */ $workingMonthRepository = $this->container->get('workingmonth_repository'); /** @var WorkingDayRepository $workingDayRepository */ $workingDayRepository = $this->container->get('workingday_repository'); /** @var ShiftRepository $shiftRepository */ $shiftRepository = $this->container->get('shift_repository'); /** @var ShiftTypeRepository $shiftTypeRepository */ $shiftTypeRepository = $this->container->get('shifttype_repository'); /** @var VehicleRepository $vehicleRepository */ $vehicleRepository = $this->container->get('vehicle_repository'); /** @var DrivingPoolRepository $drivingPoolRepository */ $drivingPoolRepository = $this->container->get('drivingpool_repository'); try { $date = new \DateTime(); $date->setDate($year, $month, 1); } catch (\Exception $e) { $logger = $this->container->get('logger'); $logger->error('DispositionManagementImpl->openWorkingMonth: ' . 'illegal date, ' . $e->getMessage()); return null; } $workingMonth = WorkingMonth::registerWorkingMonth($date); $workingMonth->createWorkingDaysForThisMonth(); $shiftTypes = $shiftTypeRepository->findAllActive(); $workingDays = $workingMonth->getWorkingDays(); /** @var WorkingDay $workingDay */ foreach ($workingDays as $workingDay) { $workingDayRepository->store($workingDay); foreach ($shiftTypes as $shiftType) { /* make shifts for working day */ $shift = Shift::registerShift($workingDay, $shiftType, $vehicleRepository->getAmountOfCompanyOwnedVehicles()); $workingDay->assignShift($shift); $shiftRepository->store($shift); /* make driving pools for shift */ $pools = $shift->getAmountOfDrivers(); for ($i = 0; $i < $pools; $i++) { $drivingPoolRepository->store(DrivingPool::registerDrivingPool($shift)); } } } $workingMonthRepository->store($workingMonth); return $workingMonth; }