예제 #1
0
 /**
  * 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;
 }
예제 #5
0
 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);
 }
예제 #6
0
 /**
  * @param Shift $shift
  */
 public function matching(Shift $shift)
 {
     foreach ($this->getServicePlans() as $servicePlan) {
         if ($servicePlan->matchDate($shift->getDate())) {
             // todo code incomplete...
         }
     }
 }
예제 #7
0
 /**
  * @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;
 }
예제 #8
0
 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) {
         }
     }
 }
예제 #9
0
 /**
  * @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;
 }
예제 #10
0
 /**
  * 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;
 }