diff --git a/include/class.format.php b/include/class.format.php index 6058142d8c0adb2b51e996943f2ac1562d60b647..0ff1b75e00875da44edb440b79be2b1c6a0b3e3e 100644 --- a/include/class.format.php +++ b/include/class.format.php @@ -521,10 +521,12 @@ class Format { // Set the desired timezone (caching since it will be mostly same // for most date formatting. + $timezone = Format::timezone($timezone, $cfg->getTimezone()); if (isset($cache[$timezone])) $tz = $cache[$timezone]; else - $cache[$timezone] = $tz = new DateTimeZone($timezone ?: $cfg->getTimezone()); + $cache[$timezone] = $tz = new DateTimeZone($timezone); + $datetime->setTimezone($tz); // Formmating options @@ -608,7 +610,7 @@ class Format { return $tz; } - function parseDatetime($date, $locale=null, $format=false) { + function parseDateTime($date, $locale=null, $format=false) { global $cfg; if (!$date) diff --git a/include/class.forms.php b/include/class.forms.php index d13a0533ce51f6f57fa6e2d4fc8c76d88f0daf6c..c94f5bfdea87543bb2930f932b45d8cfec4d53ce 100644 --- a/include/class.forms.php +++ b/include/class.forms.php @@ -1952,7 +1952,7 @@ class DatetimeField extends FormField { function display($value) { global $cfg; - if (!$value || !($datetime = Format::parseDatetime($value))) + if (!$value || !($datetime = Format::parseDateTime($value))) return ''; $config = $this->getConfiguration(); @@ -2067,14 +2067,14 @@ class DatetimeField extends FormField { $config = $this->getConfiguration(); parent::validateEntry($value); - if (!$value || !($datetime = Format::parseDatetime($value))) + if (!$value || !($datetime = Format::parseDateTime($value))) return; // Parse value to DateTime object - $val = Format::parseDatetime($value); + $val = Format::parseDateTime($value); // Get configured min/max (if any) - $min = $this->getMinDatetime(); - $max = $this->getMaxDatetime(); + $min = $this->getMinDateTime(); + $max = $this->getMaxDateTime(); if (!$val) { $this->_errors[] = __('Enter a valid date'); @@ -2177,9 +2177,12 @@ class DatetimeField extends FormField { $name = $name ?: $this->get('name'); $now = SqlFunction::NOW(); $config = $this->getConfiguration(); - $value = is_int($value) - ? DateTime::createFromFormat('U', !$config['gmt'] ? Misc::gmtime($value) : $value) ?: $value - : $value; + + if (is_int($value)) + $value = DateTime::createFromFormat('U', !$config['gmt'] ? Misc::gmtime($value) : $value) ?: $value; + elseif (is_string($value)) + $value = Format::parseDateTime($value) ?: $value; + switch ($method) { case 'equal': $l = clone $value; @@ -2695,7 +2698,7 @@ class SLAField extends ChoiceField { function to_database($sla) { return ($sla instanceof SLA) - ? array($sla->getName(), $slas->getId()) + ? array($sla->getName(), $sla->getId()) : $sla; } diff --git a/include/class.ticket.php b/include/class.ticket.php index 7dfe783f5e140392608f4fac888baeea6768659d..4b7e455fed6b7162050e841719a5f81e13ee5a88 100644 --- a/include/class.ticket.php +++ b/include/class.ticket.php @@ -416,30 +416,36 @@ implements RestrictedAccess, Threadable, Searchable { return $this->duedate; } - function getSLADueDate() { + function getSLADueDate($datetime=null) { if ($sla = $this->getSLA()) { - $dt = new DateTime($this->getCreateDate()); - + $dt = new DateTime($datetime ?: $this->getReopenDate() ?: $this->getCreateDate()); return $dt ->add(new DateInterval('PT' . $sla->getGracePeriod() . 'H')) ->format('Y-m-d H:i:s'); } } - function updateEstDueDate() { - $this->est_duedate = $this->getEstDueDate(); - $this->save(); + function updateEstDueDate($clearOverdue=true) { + $DueDate = $this->getEstDueDate(); + $this->est_duedate = $this->getSLADueDate(); + // Clear overdue flag if duedate or SLA changes and the ticket is no longer overdue. + if ($this->isOverdue() + && $clearOverdue + && (!$DueDate // Duedate + SLA cleared + || Misc::db2gmtime($DueDate) > Misc::gmtime() //New due date in the future. + )) { + $this->isoverdue = 0; + } + + return $this->save(); } function getEstDueDate() { - // Real due date - if ($duedate = $this->getDueDate()) { - return $duedate; - } - // return sla due date (If ANY) - return $this->getSLADueDate(); + // Real due date or sla due date (If ANY) + return $this->getDueDate() ?: $this->getSLADueDate(); } + function getCloseDate() { return $this->closed; } @@ -934,8 +940,10 @@ implements RestrictedAccess, Threadable, Searchable { // Special fields switch ($fid) { case 'priority': - if (($a = $this->_answers['priority'])) + if (($a = $this->getAnswer('priority'))) return $a->getField(); + + return TicketForm::getInstance()->getField('priority'); break; case 'sla': return ChoiceField::init(array( @@ -3232,11 +3240,12 @@ implements RestrictedAccess, Threadable, Searchable { function updateField($form, &$errors) { - global $thisstaff; + global $thisstaff, $cfg; if (!($field = $form->getField('field'))) return null; + $updateDuedate = false; if (!($changes = $field->getChanges())) $errors['field'] = sprintf(__('%s is already assigned this value'), __($field->getLabel())); @@ -3248,19 +3257,23 @@ implements RestrictedAccess, Threadable, Searchable { } else { $val = $field->getClean(); $fid = $field->get('name'); - $this->{$fid} = $val; - - if ($fid == 'duedate') - $this->isoverdue = 0; + // Convert duedate to DB timezone. + if ($fid == 'duedate' + && ($dt = Format::parseDateTime($val))) { + $dt->setTimezone(new DateTimeZone($cfg->getDbTimezone())); + $val = $dt->format('Y-m-d H:i:s'); + } $changes = array(); + $this->{$fid} = $val; foreach ($this->dirty as $F=>$old) { switch ($F) { + case 'sla_id': + case 'duedate': + $updateDuedate = true; case 'topic_id': case 'user_id': case 'source': - case 'duedate': - case 'sla_id': $changes[$F] = array($old, $this->{$F}); } } @@ -3275,8 +3288,8 @@ implements RestrictedAccess, Threadable, Searchable { // Record the changes $this->logEvent('edited', $changes); - // Log comments (if any) + // Log comments (if any) if (($comments = $form->getField('comments')->getClean())) { $title = sprintf(__('%s updated'), __($field->getLabel())); $_errors = array(); @@ -3285,6 +3298,15 @@ implements RestrictedAccess, Threadable, Searchable { $_errors, $thisstaff, false); } + $this->lastupdate = SqlFunction::NOW(); + + if ($updateDuedate) + $this->updateEstDueDate(); + + $this->save(); + + Signal::send('model.updated', $this); + return true; }