/**
* Add a delay to a date using the active calendar
*
* if delay >= DAY_TIMESTAMP : work in days
* else work in minutes
*
* @param $start datetime begin
* @param $delay timestamp delay to add
* @param $additional_delay timestamp delay to add (default 0)
* @param $work_in_days boolean force working in days (false by default)
* @param $end_of_working_day boolean end of working day (false by default)
*
* @return end date
**/
function computeEndDate($start, $delay, $additional_delay = 0, $work_in_days = false, $end_of_working_day = false)
{
if (!isset($this->fields['id'])) {
return false;
}
$actualtime = strtotime($start);
$timestart = strtotime($start);
$datestart = date('Y-m-d', $timestart);
// End of working day
if ($end_of_working_day) {
$numberofdays = $delay / DAY_TIMESTAMP;
// Add $additional_delay to start time.
// If start + delay is next day : +1 day
$actualtime += $additional_delay;
$cache_duration = $this->getDurationsCache();
$dayofweek = self::getDayNumberInWeek($actualtime);
$actualdate = date('Y-m-d', $actualtime);
// Begin next day working
if ($this->isHoliday($actualdate) || $cache_duration[$dayofweek] == 0) {
while ($this->isHoliday($actualdate) || $cache_duration[$dayofweek] == 0) {
$actualtime += DAY_TIMESTAMP;
$actualdate = date('Y-m-d', $actualtime);
$dayofweek = self::getDayNumberInWeek($actualtime);
}
}
while ($numberofdays > 0) {
if (!$this->isHoliday($actualdate) && $cache_duration[$dayofweek] > 0) {
$numberofdays--;
}
$actualtime += DAY_TIMESTAMP;
$actualdate = date('Y-m-d', $actualtime);
$dayofweek = self::getDayNumberInWeek($actualtime);
}
// Get next working day
if ($this->isHoliday($actualdate) || $cache_duration[$dayofweek] == 0) {
while ($this->isHoliday($actualdate) || $cache_duration[$dayofweek] == 0) {
$actualtime += DAY_TIMESTAMP;
$actualdate = date('Y-m-d', $actualtime);
$dayofweek = self::getDayNumberInWeek($actualtime);
}
}
$lastworkinghour = CalendarSegment::getLastWorkingHour($this->fields['id'], $dayofweek);
$actualtime = strtotime(date('Y-m-d', $actualtime) . ' ' . $lastworkinghour);
return date('Y-m-d H:i:s', $actualtime);
}
// Add additional delay to initial delay
$delay += $additional_delay;
if ($work_in_days) {
// only based on days
$cache_duration = $this->getDurationsCache();
// Compute Real starting time
// If day is an holiday must start on the begin of next working day
$actualdate = date('Y-m-d', $actualtime);
$dayofweek = self::getDayNumberInWeek($actualtime);
if ($this->isHoliday($actualdate) || $cache_duration[$dayofweek] == 0) {
while ($this->isHoliday($actualdate) || $cache_duration[$dayofweek] == 0) {
$actualtime += DAY_TIMESTAMP;
$actualdate = date('Y-m-d', $actualtime);
$dayofweek = self::getDayNumberInWeek($actualtime);
}
$firstworkhour = CalendarSegment::getFirstWorkingHour($this->fields['id'], $dayofweek);
$actualtime = strtotime($actualdate . ' ' . $firstworkhour);
}
while ($delay > 0) {
// Begin next day : do not take into account first day : must finish to a working day
$actualtime += DAY_TIMESTAMP;
$actualdate = date('Y-m-d', $actualtime);
$dayofweek = self::getDayNumberInWeek($actualtime);
if (!$this->isHoliday($actualdate) && $cache_duration[$dayofweek] > 0) {
$delay -= DAY_TIMESTAMP;
}
if ($delay < 0) {
// delay done : if < 0 delete hours
$actualtime += $delay;
}
}
// If > last working hour set last working hour
$dayofweek = self::getDayNumberInWeek($actualtime);
$lastworkinghour = CalendarSegment::getLastWorkingHour($this->fields['id'], $dayofweek);
if ($lastworkinghour < date('H:i:s', $actualtime)) {
$actualtime = strtotime(date('Y-m-d', $actualtime) . ' ' . $lastworkinghour);
}
return date('Y-m-d H:i:s', $actualtime);
}
// else // based on working hours
$cache_duration = $this->getDurationsCache();
// Only if segments exists
if (countElementsInTable('glpi_calendarsegments', "`calendars_id` = '" . $this->fields['id'] . "'")) {
while ($delay >= 0) {
$actualdate = date('Y-m-d', $actualtime);
if (!$this->isHoliday($actualdate)) {
$dayofweek = self::getDayNumberInWeek($actualtime);
$beginhour = '00:00:00';
/// Before PHP 5.3 need to be 23:59:59 and not 24:00:00
$endhour = '23:59:59';
if ($actualdate == $datestart) {
// First day cannot use cache
$beginhour = date('H:i:s', $timestart);
$timeoftheday = CalendarSegment::getActiveTimeBetween($this->fields['id'], $dayofweek, $beginhour, $endhour);
} else {
$timeoftheday = $cache_duration[$dayofweek];
}
// Day do not complete the delay : pass to next day
if ($timeoftheday < $delay) {
$actualtime += DAY_TIMESTAMP;
$delay -= $timeoftheday;
} else {
// End of the delay in the day : get hours with this delay
$beginhour = '00:00:00';
/// Before PHP 5.3 need to be 23:59:59 and not 24:00:00
$endhour = '23:59:59';
if ($actualdate == $datestart) {
$beginhour = date('H:i:s', $timestart);
}
$endhour = CalendarSegment::addDelayInDay($this->fields['id'], $dayofweek, $beginhour, $delay);
return $actualdate . ' ' . $endhour;
}
} else {
// Holiday : pass to next day
$actualtime += DAY_TIMESTAMP;
}
}
}
return false;
}