Calendar::computeEndDate PHP Method

computeEndDate() public method

if delay >= DAY_TIMESTAMP : work in days else work in minutes
public computeEndDate ( $start, $delay, $additional_delay, $work_in_days = false, $end_of_working_day = false ) : end
$start datetime begin
$delay timestamp delay to add
$additional_delay timestamp delay to add (default 0)
$work_in_days boolean force working in days (false by default)
$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;
    }

Usage Example

Example #1
0
 function pre_updateInDB()
 {
     global $LANG, $CFG_GLPI;
     // Check dates change interval due to the fact that second are not displayed in form
     if (($key = array_search('date', $this->updates)) !== false && substr($this->fields["date"], 0, 16) == substr($this->oldvalues['date'], 0, 16)) {
         unset($this->updates[$key]);
         unset($this->oldvalues['date']);
     }
     if (($key = array_search('closedate', $this->updates)) !== false && substr($this->fields["closedate"], 0, 16) == substr($this->oldvalues['closedate'], 0, 16)) {
         unset($this->updates[$key]);
         unset($this->oldvalues['closedate']);
     }
     if (($key = array_search('due_date', $this->updates)) !== false && substr($this->fields["due_date"], 0, 16) == substr($this->oldvalues['due_date'], 0, 16)) {
         unset($this->updates[$key]);
         unset($this->oldvalues['due_date']);
     }
     if (($key = array_search('solvedate', $this->updates)) !== false && substr($this->fields["solvedate"], 0, 16) == substr($this->oldvalues['solvedate'], 0, 16)) {
         unset($this->updates[$key]);
         unset($this->oldvalues['solvedate']);
     }
     if ($this->fields['status'] == 'new') {
         if (in_array("suppliers_id_assign", $this->updates) && $this->input["suppliers_id_assign"] > 0) {
             if (!in_array('status', $this->updates)) {
                 $this->oldvalues['status'] = $this->fields['status'];
                 $this->updates[] = 'status';
             }
             $this->fields['status'] = 'assign';
             $this->input['status'] = 'assign';
         }
     }
     // Setting a solution or solution type means the ticket is solved
     if (in_array("ticketsolutiontypes_id", $this->updates) && $this->input["ticketsolutiontypes_id"] > 0 || in_array("solution", $this->updates) && !empty($this->input["solution"])) {
         if (!in_array('status', $this->updates)) {
             $this->oldvalues['status'] = $this->fields['status'];
             $this->updates[] = 'status';
         }
         $entitydata = new EntityData();
         if ($entitydata->getFromDB($this->fields['entities_id'])) {
             $autoclosedelay = $entitydata->getfield('autoclose_delay');
         } else {
             $autoclosedelay = -1;
         }
         // -1 = config
         if ($autoclosedelay == -1) {
             $autoclosedelay = $CFG_GLPI['autoclose_delay'];
         }
         // 0 = immediatly
         if ($autoclosedelay == 0) {
             $this->fields['status'] = 'closed';
             $this->input['status'] = 'closed';
         } else {
             $this->fields['status'] = 'solved';
             $this->input['status'] = 'solved';
         }
     }
     if (isset($this->input["status"])) {
         if ($this->input["status"] != 'waiting' && isset($this->input["suppliers_id_assign"]) && $this->input["suppliers_id_assign"] == 0 && $this->countUsers(self::ASSIGN) == 0 && $this->countGroups(self::ASSIGN) == 0 && $this->fields['status'] != 'closed' && $this->fields['status'] != 'solved') {
             if (!in_array('status', $this->updates)) {
                 $this->oldvalues['status'] = $this->fields['status'];
                 $this->updates[] = 'status';
             }
             $this->fields['status'] = 'new';
         }
         if (in_array("status", $this->updates) && $this->input["status"] == "solved") {
             $this->updates[] = "solvedate";
             $this->oldvalues['solvedate'] = $this->fields["solvedate"];
             $this->fields["solvedate"] = $_SESSION["glpi_currenttime"];
             // If invalid date : set open date
             if ($this->fields["solvedate"] < $this->fields["date"]) {
                 $this->fields["solvedate"] = $this->fields["date"];
             }
         }
         if (in_array("status", $this->updates) && $this->input["status"] == "closed") {
             $this->updates[] = "closedate";
             $this->oldvalues['closedate'] = $this->fields["closedate"];
             $this->fields["closedate"] = $_SESSION["glpi_currenttime"];
             // If invalid date : set open date
             if ($this->fields["closedate"] < $this->fields["date"]) {
                 $this->fields["closedate"] = $this->fields["date"];
             }
             // Set solvedate to closedate
             if (empty($this->fields["solvedate"])) {
                 $this->updates[] = "solvedate";
                 $this->oldvalues['solvedate'] = $this->fields["solvedate"];
                 $this->fields["solvedate"] = $this->fields["closedate"];
             }
         }
     }
     // check dates
     // check due_date (SLA)
     if ((in_array("date", $this->updates) || in_array("due_date", $this->updates)) && !is_null($this->fields["due_date"])) {
         // Date set
         if ($this->fields["due_date"] < $this->fields["date"]) {
             addMessageAfterRedirect($LANG['tracking'][3] . $this->fields["due_date"], false, ERROR);
             if (($key = array_search('date', $this->updates)) !== false) {
                 unset($this->updates[$key]);
                 unset($this->oldvalues['date']);
             }
             if (($key = array_search('due_date', $this->updates)) !== false) {
                 unset($this->updates[$key]);
                 unset($this->oldvalues['due_date']);
             }
         }
     }
     // Status solved : check dates
     if ($this->fields["status"] == "solved" && (in_array("date", $this->updates) || in_array("solvedate", $this->updates))) {
         // Invalid dates : no change
         // solvedate must be > create date
         if ($this->fields["solvedate"] < $this->fields["date"]) {
             addMessageAfterRedirect($LANG['tracking'][3], false, ERROR);
             if (($key = array_search('date', $this->updates)) !== false) {
                 unset($this->updates[$key]);
                 unset($this->oldvalues['date']);
             }
             if (($key = array_search('solvedate', $this->updates)) !== false) {
                 unset($this->updates[$key]);
                 unset($this->oldvalues['solvedate']);
             }
         }
     }
     // Status close : check dates
     if ($this->fields["status"] == "closed" && (in_array("date", $this->updates) || in_array("closedate", $this->updates))) {
         // Invalid dates : no change
         // closedate must be > solvedate
         if ($this->fields["closedate"] < $this->fields["solvedate"]) {
             addMessageAfterRedirect($LANG['tracking'][3], false, ERROR);
             if (($key = array_search('closedate', $this->updates)) !== false) {
                 unset($this->updates[$key]);
                 unset($this->oldvalues['closedate']);
             }
         }
         // closedate must be > create date
         if ($this->fields["closedate"] < $this->fields["date"]) {
             addMessageAfterRedirect($LANG['tracking'][3], false, ERROR);
             if (($key = array_search('date', $this->updates)) !== false) {
                 unset($this->updates[$key]);
                 unset($this->oldvalues['date']);
             }
             if (($key = array_search('closedate', $this->updates)) !== false) {
                 unset($this->updates[$key]);
                 unset($this->oldvalues['closedate']);
             }
         }
     }
     /*      if (in_array("users_id",$this->updates)) {
              $user = new User;
              $user->getFromDB($this->input["users_id"]);
              if (!empty($user->fields["email"])) {
                 $this->updates[] = "user_email";
                 $this->fields["user_email"] = $user->fields["email"];
              }
           }*/
     if (($key = array_search('status', $this->updates)) !== false && $this->oldvalues['status'] == $this->fields['status']) {
         unset($this->updates[$key]);
         unset($this->oldvalues['status']);
     }
     $sla = new SLA();
     // Set begin waiting date if needed
     if (($key = array_search('status', $this->updates)) !== false && ($this->fields['status'] == 'waiting' || $this->fields['status'] == 'solved')) {
         $this->updates[] = "begin_waiting_date";
         $this->fields["begin_waiting_date"] = $_SESSION["glpi_currenttime"];
         if ($this->fields['slas_id'] > 0) {
             $sla->deleteLevelsToDo($this);
         }
     }
     // Manage come back to waiting state
     if ($key = array_search('status', $this->updates) !== false && ($this->oldvalues['status'] == 'waiting' || $this->oldvalues['status'] == 'solved' && $this->fields['status'] != 'closed')) {
         // Compute ticket waiting time use calendar if exists
         $calendars_id = EntityData::getUsedConfig('calendars_id', $this->fields['entities_id']);
         $calendar = new Calendar();
         $delay_time = 0;
         // Compute ticket waiting time use calendar if exists
         // Using calendar
         if ($calendars_id > 0 && $calendar->getFromDB($calendars_id)) {
             $delay_time = $calendar->getActiveTimeBetween($this->fields['begin_waiting_date'], $_SESSION["glpi_currenttime"]);
         } else {
             // Not calendar defined
             $delay_time = strtotime($_SESSION["glpi_currenttime"]) - strtotime($this->fields['begin_waiting_date']);
         }
         // SLA case : compute sla duration
         if ($this->fields['slas_id'] > 0) {
             if ($sla->getFromDB($this->fields['slas_id'])) {
                 $delay_time_sla = $sla->getActiveTimeBetween($this->fields['begin_waiting_date'], $_SESSION["glpi_currenttime"]);
                 $this->updates[] = "sla_waiting_duration";
                 $this->fields["sla_waiting_duration"] += $delay_time_sla;
             }
             // Compute new due date
             $this->updates[] = "due_date";
             $this->fields['due_date'] = $sla->computeDueDate($this->fields['date'], $this->fields["sla_waiting_duration"]);
             // Add current level to do
             $sla->addLevelToDo($this);
         } else {
             // Using calendar
             if ($calendars_id > 0 && $calendar->getFromDB($calendars_id)) {
                 if ($this->fields['due_date'] > 0) {
                     // compute new due date using calendar
                     $this->updates[] = "due_date";
                     $this->fields['due_date'] = $calendar->computeEndDate($this->fields['due_date'], $delay_time);
                 }
             } else {
                 // Not calendar defined
                 if ($this->fields['due_date'] > 0) {
                     // compute new due date : no calendar so add computed delay_time
                     $this->updates[] = "due_date";
                     $this->fields['due_date'] = date('Y-m-d H:i:s', $delay_time + strtotime($this->fields['due_date']));
                 }
             }
         }
         $this->updates[] = "ticket_waiting_duration";
         $this->fields["ticket_waiting_duration"] += $delay_time;
         // Reset begin_waiting_date
         $this->updates[] = "begin_waiting_date";
         $this->fields["begin_waiting_date"] = 'NULL';
     }
     // solve_delay_stat : use delay between opendate and solvedate
     if (in_array("solvedate", $this->updates)) {
         $this->updates[] = "solve_delay_stat";
         $this->fields['solve_delay_stat'] = $this->computeSolveDelayStat();
     }
     // close_delay_stat : use delay between opendate and closedate
     if (in_array("closedate", $this->updates)) {
         $this->updates[] = "close_delay_stat";
         $this->fields['close_delay_stat'] = $this->computeCloseDelayStat();
     }
     // takeintoaccount :
     //     - update done by someone who have update right / see also updatedatemod used by ticketfollowup updates
     if ($this->canUpdateItem() && $this->fields['takeintoaccount_delay_stat'] == 0) {
         $this->updates[] = "takeintoaccount_delay_stat";
         $this->fields['takeintoaccount_delay_stat'] = $this->computeTakeIntoAccountDelayStat();
     }
     // Do not take into account date_mod if no update is done
     if (count($this->updates) == 1 && ($key = array_search('date_mod', $this->updates)) !== false) {
         unset($this->updates[$key]);
     }
 }
All Usage Examples Of Calendar::computeEndDate