/** * @return mixed|void */ public function createFormRows() { $this->basicFormRows[] = new FormRowView('subject', 'serviceplan.field.subject', $this->dto->subject); $this->basicFormRows[] = new FormRowView('startDate', 'serviceplan.field.start', $this->dateTimeService->convertDateTimeToDateTimeString($this->dto->start)); $this->basicFormRows[] = new FormRowView('endDate', 'serviceplan.field.end', $this->dateTimeService->convertDateTimeToDateTimeString($this->dto->end)); $this->basicFormRows[] = new FormRowView('memo', 'serviceplan.field.memo', $this->dto->memo); }
/** * @param $driverId * @return RepeatedDrivingAssertionEmbeddedListDTO */ public static function createReferenceDTOByDriverId($driverId) { $dto = new RepeatedDrivingAssertionEmbeddedListDTO(); $dto->driverId = $driverId; $dto->endDate = DateTimeService::getUTCnow(); return $dto; }
/** * @param $passengerId * @return RepeatedDrivingOrderEmbeddedListDTO */ public static function createReferenceDTOByPassengerId($passengerId) { $dto = new RepeatedDrivingOrderEmbeddedListDTO(); $dto->passengerId = $passengerId; $dto->endDate = DateTimeService::getUTCnow(); return $dto; }
/** * @param $vehicleId * @return ServicePlanEmbeddedListDTO */ public static function createReferenceDTOByVehicleId($vehicleId) { $dto = new ServicePlanEmbeddedListDTO(); $dto->vehicleId = $vehicleId; $dto->end = DateTimeService::getUTCnow(); return $dto; }
/** * Get json routing information for feasibility, for example: * /service/ride/repeatedFeasible?fromDate=01.06.2014&toDate=01.07.2025 * &weekday=1&time=12:23&direction=1&duration=23&additionalTime=2 * * @Route("/ride/repeatedFeasible", name="tixiapp_service_ride_repeated_feasible") * @Method({"GET"}) * @param Request $request * @return \Symfony\Component\HttpFoundation\JsonResponse */ public function getRepeatedFeasibilityAction(Request $request) { /**@var $rideManagement RideManagement */ $rideManagement = $this->container->get('tixi_app.ridemanagement'); $fromDateStr = $request->get('fromDate'); $toDateStr = $request->get('toDate'); $timeStr = $request->get('time'); $dayTime = \DateTime::createFromFormat('d.m.Y H:i', $fromDateStr . ' ' . $timeStr); if ($toDateStr !== '') { $toDate = \DateTime::createFromFormat('d.m.Y', $toDateStr); } else { $toDate = DateTimeService::getMaxDateTime(); } if (!$dayTime) { $response = new JsonResponse(); $response->setData(array('status' => '-1')); return $response; } $weekday = $request->get('weekday'); $direction = $request->get('direction'); $duration = $request->get('duration'); $additionalTime = $request->get('additionalTime'); try { $isFeasible = $rideManagement->checkRepeatedFeasibility($dayTime, $toDate, $weekday, $direction, $duration, $additionalTime); } catch (\Exception $e) { $response = new JsonResponse(); $response->setData(array('status' => '-1')); return $response; } $response = new JsonResponse(); $response->setData(array('status' => '0', 'isFeasible' => $isFeasible)); return $response; }
/** * @param string $subject * @param \DateTime $anchorDate * @param string $frequency * @param boolean $withHolidays * @param \DateTime $endingDate * @param string $memo * @return RepeatedDrivingAssertionPlan */ public static function registerRepeatedAssertionPlan($subject, \DateTime $anchorDate, $frequency, $withHolidays, \DateTime $endingDate = null, $memo = null) { $endingDate = null !== $endingDate ? $endingDate : DateTimeService::getMaxDateTime(); $assertion = new RepeatedDrivingAssertionPlan(); $assertion->setSubject($subject); $assertion->setMemo($memo); $assertion->setAnchorDate($anchorDate); $assertion->setEndingDate($endingDate); $assertion->setFrequency($frequency); $assertion->setWithHolidays($withHolidays); return $assertion; }
/** * Get the shift that begins before a date and a time and ends after * the same. * * @param \DateTime $dayTime * @return null|Shift */ public function getResponsibleShiftForDayAndTime(\DateTime $dayTime) { $timeService = $this->container->get('tixi_api.datetimeservice'); $shiftRepo = $this->container->get('shift_repository'); $shiftsForDay = $shiftRepo->findShiftsForDay($dayTime); $pickTime = $timeService->convertToLocalDateTime($dayTime); foreach ($shiftsForDay as $shift) { $startTime = $timeService->convertToLocalDateTime($shift->getStartDate()); $endTime = $timeService->convertToLocalDateTime($shift->getEndDate()); if (DateTimeService::matchTimeBetweenTwoDateTimes($pickTime, $startTime, $endTime)) { return $shift; } } return null; }
/** * @param RepeatedDrivingOrderPlan $orderPlan * @return RepeatedDrivingOrderEmbeddedListDTO */ public function orderPlanToEmbeddedListDTOs(RepeatedDrivingOrderPlan $orderPlan) { $dto = new RepeatedDrivingOrderEmbeddedListDTO(); $dto->id = $orderPlan->getId(); $dto->isDeleted = !$orderPlan->isActive(); $dto->anchorDate = $orderPlan->getAnchorDate()->format('d.m.Y'); $dto->endDate = $orderPlan->getEndingDate() != DateTimeService::getMaxDateTime() ? $orderPlan->getEndingDate()->format('d.m.Y') : 'repeateddrivingorder.validtillrecalled'; /** @var Passenger $passenger */ $passenger = $orderPlan->getPassenger(); $dto->passengerId = $passenger->getId(); $repeatedDrivingOrders = $orderPlan->getRepeatedDrivingOrders(); /** @var RepeatedDrivingOrder $repeatedDrivingOrder */ foreach ($repeatedDrivingOrders as $repeatedDrivingOrder) { if ($repeatedDrivingOrder->getDirection() == RepeatedDrivingOrder::OUTWARD_DIRECTION) { $dto->weekDay = $this->convertWeekDay($repeatedDrivingOrder->getWeekday()); $dto->outwardTime = $this->dateTimeService->convertToLocalTimeString($repeatedDrivingOrder->getPickUpTime()); } else { $dto->returnTime = $this->dateTimeService->convertToLocalTimeString($repeatedDrivingOrder->getPickUpTime()); } } return $dto; }
/** ------------------------- * Get one flat Driving Assertion Plan (one dimensional array) * * @param RepeatedDrivingAssertionPlan $assertionPlan * @param RepeatedDrivingAssertion[] $repeatedAssertions * @return DrivingAssertionManagementDTO[] * @throws \Exception */ protected function flatAssertionPlan($assertionPlan, $repeatedAssertions) { $asserts = array(); $frequency = $assertionPlan->getFrequency(); if ($frequency == 'weekly') { /** @var RepeatedWeeklyDrivingAssertion $weeklyAssertion */ foreach ($repeatedAssertions as $weeklyAssertion) { /** @var ShiftType $shiftType */ foreach ($weeklyAssertion->getShiftTypes() as $shiftType) { $dto = new DrivingAssertionManagementDTO(); $dto->planId = $assertionPlan->getId(); $dto->anchordate = $assertionPlan->getAnchorDate(); $dto->enddate = !is_null($assertionPlan->getEndingDate()) ? $assertionPlan->getEndingDate() : DateTimeService::getMaxDateTime(); $dto->weekdayAsText = WeekdayService::$numericToWeekdayConverter[$weeklyAssertion->getWeekday()]; $dto->shiftTypeName = $shiftType->getName(); $asserts[] = $dto; } } } elseif ($frequency == 'monthly') { /** @var RepeatedMonthlyDrivingAssertion $monthlyAssertion */ foreach ($repeatedAssertions as $monthlyAssertion) { /** @var ShiftType $shiftType */ foreach ($monthlyAssertion->getShiftTypes() as $shiftType) { $dto = new DrivingAssertionManagementDTO(); $dto->planId = $assertionPlan->getId(); $dto->anchordate = $assertionPlan->getAnchorDate(); $dto->enddate = !is_null($assertionPlan->getEndingDate()) ? $assertionPlan->getEndingDate() : DateTimeService::getMaxDateTime(); $dto->weekdayAsText = $monthlyAssertion->getWeekdayAsText(); $dto->shiftTypeName = $shiftType->getName(); $asserts[] = $dto; } } } else { throw new \Exception("Driving Assertion Plan error, " . "illegal frequency({$frequency}) encountered!"); } // exit return $asserts; }
/** * @param $now * @return bool */ protected function isNewLookupMonth($now) { $toReturn = false; if (DateTimeService::getYear($now) !== DateTimeService::getYear($this->lastLookupDateTime) || DateTimeService::getMonth($now) !== DateTimeService::getMonth($this->lastLookupDateTime)) { $toReturn = true; } return $toReturn; }
/** * @param \DateTime $dateTime * @return bool */ public function isResponsibleForTime(\DateTime $dateTime) { return DateTimeService::matchTimeBetweenTwoDateTimes($dateTime, $this->start, $this->end); }
/** * Create DTO for the selected working month * @param WorkingMonth $workingMonth * @return array */ public function workingMonthToEditDTO(WorkingMonth $workingMonth) { $tr = $this->container->get('translator'); $dto = new MonthlyPlanGetDTO(); $dto->targetSrc = $this->container->get('router')->generate('tixiapi_dispo_monthlyplan_edit', array('workingMonthId' => $workingMonth->getId(), 'workingDayId' => '__workingDayId__', 'editParams' => 'edit')); $dto->closeUrl = $this->container->get('router')->generate('tixiapi_dispo_monthlyplans_get'); /** @var WorkingDay $workingDay */ foreach ($workingMonth->getWorkingDays() as $workingDay) { $dayDto = new MonthlyPlanGetDayDTO(); $dayDto->workingDayId = $workingDay->getId(); $dayDto->swissDate = $workingDay->getDate()->format('d.m.Y'); $dayDto->dayOfWeek = $tr->trans(DateTimeService::getDayOfWeek($workingDay->getDate())); $shifts = $workingDay->getShifts(); /** @var Shift $shift */ foreach ($shifts as $shift) { $dayDto->shifts[] = $this->getMonthlyPlanGetShiftDTO($shift); } $dto->workingDays[] = $dayDto; } /** @var Shift $shift */ foreach ($workingMonth->getWorkingDays()[0]->getShifts() as $shift) { $dto->shiftNames[] = $shift->getShiftType()->getName(); } return $dto; }
/** * @param RepeatedDrivingAssertionPlan $assertionPlan * @return RepeatedDrivingAssertionEmbeddedListDTO */ protected function assertionPlanToEmbeddedListDTO(RepeatedDrivingAssertionPlan $assertionPlan) { $dto = new RepeatedDrivingAssertionEmbeddedListDTO(); $dto->id = $assertionPlan->getId(); $dto->subject = $assertionPlan->getSubject(); $dto->anchorDate = $assertionPlan->getAnchorDate()->format('d.m.Y'); $dto->endDate = $assertionPlan->getEndingDate() != DateTimeService::getMaxDateTime() ? $assertionPlan->getEndingDate()->format('d.m.Y') : 'repeateddrivingassertion.validtillrecalled'; $dto->frequency = $assertionPlan->getFrequency(); return $dto; }
/** * minimal Ride to check feasibility in a configuration * @param $direction * @param \DateTime $time * @param $duration //in Minutes * @param $additionalTime //from Passenger * @return RideNode */ public static function registerFeasibleRide(\DateTime $time, $direction = DrivingMission::SAME_START, $duration, $additionalTime) { $ride = new RideNode(self::RIDE_FEASIBLE); if ($direction === DrivingMission::SAME_START) { $ride->startMinute = DateTimeService::getMinutesOfDay($time); $ride->duration = $duration + DispositionVariables::getBoardingTimes() + $additionalTime; $ride->endMinute = $ride->startMinute + $ride->duration; } else { $ride->endMinute = DateTimeService::getMinutesOfDay($time); $ride->duration = $duration + DispositionVariables::getBoardingTimes() + $additionalTime; $ride->startMinute = $ride->endMinute - $ride->duration; } return $ride; }
/** * @param \DateTime $anchorDate * @param null $withHolidays * @param null $companion * @param \DateTime $endingDate * @param null $memo * @param null $additionalTime * @return RepeatedDrivingOrderPlan */ public static function registerRepeatedDrivingOrderPlan(\DateTime $anchorDate, $withHolidays = null, $companion = null, \DateTime $endingDate = null, $memo = null, $additionalTime = null) { $correctedWithHolidays = null !== $withHolidays ? $withHolidays : false; $correctedCompanion = null !== $companion ? $companion : 0; $correctedAdditionalTime = null !== $additionalTime ? $additionalTime : 0; $correctedEndingDate = $endingDate !== null ? $endingDate : DateTimeService::getMaxDateTime(); $correctedMemo = $memo !== null ? $memo : ''; $rdPlan = new RepeatedDrivingOrderPlan(); $rdPlan->setAnchorDate($anchorDate); $rdPlan->setEndingDate($correctedEndingDate); $rdPlan->setWithHolidays($correctedWithHolidays); $rdPlan->setCompanion($correctedCompanion); $rdPlan->setMemo($correctedMemo); $rdPlan->setAdditionalTime($correctedAdditionalTime); return $rdPlan; }
/** * @param \DateTime $date * @return mixed|void */ public function matching(\DateTime $date) { return DateTimeService::getWeekday($date) == $this->getWeekday(); }
/** * @param DrivingOrder $drivingOrder * @return DrivingMission */ public static function registerDrivingMissionFromOrder(DrivingOrder $drivingOrder) { $drivingMission = new DrivingMission(); $drivingMission->setDirection(self::SAME_START); $drivingMission->setServiceOrder(array($drivingOrder->getId())); $boardingTime = DispositionVariables::getBoardingTimes(); $extraMinutesPassenger = $drivingOrder->getPassenger()->getExtraMinutes(); $additionalTimesOnRide = $boardingTime + $extraMinutesPassenger; $serviceMinuteOfDay = DateTimeService::getMinutesOfDay($drivingOrder->getPickUpTime()); $serviceDuration = $drivingOrder->getRoute()->getDurationInMinutes() + $additionalTimesOnRide; $serviceDistance = $drivingOrder->getRoute()->getDistanceInMeters(); $drivingMission->setServiceMinuteOfDay($serviceMinuteOfDay); $drivingMission->setServiceDuration($serviceDuration); $drivingMission->setServiceDistance($serviceDistance); //DrivingMission <-> Order $drivingMission->assignDrivingOrder($drivingOrder); $drivingOrder->assignDrivingMission($drivingMission); return $drivingMission; }
/** * 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; }
/** * @param \DateTime $date * @return string */ private function dateToLocalWeekday(\DateTime $date) { $weekday = DateTimeService::getDayOfWeek($date); $tr = $this->get('translator'); return $tr->trans($weekday); }
/** * Assign drivers, vehicles and driving orders (missions) to driving pools. * * @param \DateTime $scope is the date of the WorkingDay being assigned * @return mixed value true = success */ protected function assignResourcesForDay(\DateTime $scope) { set_time_limit(60); $timeStamp = microtime(true); $tr = $this->get('translator'); $logger = $this->get('logger'); $memo = ''; /** @var DrivingAssertionManagement $drivingAssertionService */ $drivingAssertionService = $this->get('tixi_app.drivingassertionmanagement'); /** @var DispositionManagement $dispoService */ $dispoService = $this->get('tixi_app.dispomanagement'); /** @var EntityManager $entityManager */ $entityManager = $this->get('entity_manager'); /** @var WorkingDayRepository $workingDayRepository */ $workingDayRepository = $this->get('workingday_repository'); $workingDay = $workingDayRepository->findWorkingDayByDate($scope); if (null !== $workingDay) { /* add driving assertions for working day ----------------------- */ $logger->debug($tr->trans('productionplan.debug.addDrivingAssertions') . ' ' . $scope->format('d.m.Y')); $errors = $drivingAssertionService->createAllDrivingAssertionsForNewWorkingDay($workingDay); foreach ($errors as $error) { $memo .= $error . "\n"; } $entityManager->flush(); // update MySQL database $entityManager->clear(); // clear ORM cache /* assign driving assertions to driving pools ------------------- */ $logger->debug($tr->trans('productionplan.debug.assignAssertions') . ' ' . $scope->format('d.m.Y')); $workingDayChildren = $workingDayRepository->fetchWorkingDayChildrenForDay($scope); $errors = $dispoService->assignAssertionsToPools($workingDayChildren); foreach ($errors as $error) { $memo .= $error . "\n"; } $entityManager->flush(); // update MySQL database ***ERROR HERE*** $entityManager->clear(); // clear ORM cache /* assign vehicles to driving pools ----------------------------- */ $logger->debug($tr->trans('productionplan.debug.assignVehicles') . ' ' . $scope->format('d.m.Y')); $workingDayChildren = $workingDayRepository->fetchWorkingDayChildrenForDay($scope); $errors = $dispoService->assignVehiclesToPools($workingDayChildren); foreach ($errors as $error) { $memo .= $error . "\n"; } $entityManager->flush(); // update MySQL database $entityManager->clear(); // clear ORM cache /* add driving orders for working day --------------------------- */ $logger->debug($tr->trans('productionplan.debug.addDrivingOrders') . ' ' . $scope->format('d.m.Y')); /** @var DrivingOrderManagement $drivingOrderService */ $drivingOrderService = $this->get('tixi_app.drivingordermanagement'); $errors = $drivingOrderService->handleNewWorkingDay($workingDay, DrivingOrder::BOOKED); // status BOOKED foreach ($errors as $error) { $memo .= $error . "\n"; } $entityManager->flush(); // update MySQL database $entityManager->clear(); // clear ORM cache /* build ride configurations ------------------------------------ */ $logger->debug($tr->trans('productionplan.debug.assignOrders') . ' ' . $scope->format('d.m.Y')); /**@var RideManagement $rideManagement */ $rideManagement = $this->get('tixi_app.ridemanagement'); $workingDayChildren = $workingDayRepository->fetchWorkingDayChildrenForDay($scope); foreach ($workingDayChildren->getShifts() as $shift) { $errors = $rideManagement->buildRidePlanForShift($shift); foreach ($errors as $error) { $memo .= $error . "\n"; } } } else { $memo .= $tr->trans('productionplan.form.daymissing') . "\n"; } $memo .= $tr->trans('productionplan.form.memo.days') . ' ' . $tr->trans(DateTimeService::getDayOfWeek($scope)) . ' ' . $scope->format('d.m.Y') . ' (' . $this->getTimeExpired($timeStamp) . "s).\n"; $queueService = $this->get('tixi_app.queueservice'); $queueService->push($this->getQueueTag($scope), $memo); return true; // success = true }