[% META title = "Ticket Due Dates" %]

Set the Due Date

This is where we get into a custom scrip that will be run each time you update a ticket.

The Due date of the ticket is the total elapsed operational time for a ticket. This is all the time the ticket is New or Open. This means that a ticket can be stalled, and it doesn tcount against your SLA. A ticket should be stalled if it is waiting for an external party, such as the requestor.

Scrip Fields

Descripton
Set Due Base Upon Service and Severity CFs
Condition
User Defined
Action
User defined
Template
Global template: transaction
Stafe
TransactionBatch

Custom Condition


return 0 if ( $self->TicketObj->Status =~ /^resolved|deleted|rejected$/);
return 1 if ($self->TransactionObj->Field eq "Status" &&  ($self->TransactionObj->OldValue eq "stalled" || $self->TransactionObj->NewValue eq "stalled" || $self->TransactionObj->NewValue eq "new"));
return 0 unless ($self->TransactionObj->Type eq "CustomField");
my $CustomField_severity = RT::CustomField->new($RT::SystemUser);
my $CustomField_service  = RT::CustomField->new($RT::SystemUser);
$CustomField_severity->LoadByName(Name => "Severity");
$CustomField_service->LoadByName(Name => "Service");
# Only proceed if we have status change, or updating our Service custom fields
return 0 unless ($self->TransactionObj->Field eq $CustomField_service->id || $self->TransactionObj->Field eq $CustomField_severity->id);
return 1;

Custom action preparation code


return 1;

Custom action cleanup code


my $classification_timeouts = {
 gold => { 
  critical => [ '1 hour', '24 hour' ],
  normal => [ '1 hour', '168 hour' ],
  minor => [ undef, '744 hour' ],
  },
 silver => { 
  critical => [ '2 global business hour', '32 global business hour' ],
  normal => [ '2 global business hour', '112 global business hour' ],
  minor => [ undef, '480 global business hour' ],
  },
 bronze => { 
  critical => [ '2 local business hour', '24 local business hour' ],
  normal => [ '2 local business hour', '56 local business hour' ],
  minor => [ undef, undef ],
  },
};

my $service_classification = {
  'crm'               => 'silver',
  'email'             => 'gold',
  'general it'        => 'silver',
  'internet access'   => 'bronze',
  'mobile devices'    => 'bronze',
  'office telephones' => 'bronze',
  'printing'          => 'bronze',
  'vpn'               => 'gold',
  'crm'               => 'gold',
  'production infrastructure' => 'gold',
  'web sites'          => 'gold',
};

# get ticket object
my $ticket = $self->TicketObj;
# If we're stalled, then the Due is not set, return
$ticket->SetDue(0) and return 1 if ($ticket->Status eq "stalled");

my $service;
my $severity;
my $CustomFields = $ticket->QueueObj->TicketCustomFields();
while (my $CustomField = $CustomFields->Next) {
  my $CustomFieldValues = $ticket->CustomFieldValues($CustomField->Id);
  while (my $CustomFieldValue = $CustomFieldValues->Next()) {
    $severity = lc($CustomFieldValue->Content) if ($CustomField->Name eq "Severity" && $CustomFieldValue->Content ne "");
    $service = lc($CustomFieldValue->Content) if ($CustomField->Name eq "Service");
  }
}

my $timeouts = $classification_timeouts->{$service_classification->{$service}}{$severity};
$RT::Logger->debug("Service is $service, severity is $severity, timeout is " . $timeouts->[1]);

if (not defined $timeouts->[1]) {
  $RT::Logger->warning("Due set to 0; no timeout for this service/severity");
  $ticket->SetDue(0);
  return 1;
}


# Has there been any "stall" time?
my $stalled_time = 0;
my $previous_time = RT::Date->new( $RT::SystemUser );
my $this_time = RT::Date->new( $RT::SystemUser );
$previous_time->Set(Format => "ISO", Value => $ticket->Created);
my $transactions = $ticket->Transactions();

while (my $transaction = $transactions->Next()) {
  if ($transaction->Field eq "Status") {
    if (($transaction->OldValue eq "stalled") || ($transaction->OldValue eq "deleted") || ($transaction->OldValue eq "resolved") || ($transaction->OldValue eq "rejected")) {
      $this_time->Set(Format => "ISO", Value => $transaction->Created);
      $stalled_time+=$this_time->Diff($previous_time);
    }
    # Update previous time
    $previous_time->Set(Format => "ISO", Value => $transaction->Created );
  }
}
$RT::Logger->debug("Stall time is " . $stalled_time );

# Now set the Due date/time
my $created_date = RT::Date->new( $RT::SystemUser );
my $due_date = RT::Date->new( $RT::SystemUser );
$created_date->Set(Format => "ISO", Value => $ticket->Created);
$due_date->Set(Format => "ISO", Value => $ticket->Created);

if ($timeouts->[1] =~ /^(\d+) (hour|minute|second)s?$/) {
  my $multiplier = ($2 == "hour" ? 3600 : $2 == "minute" ? 60 : 1);
  my $seconds_to_add = $1 * $multiplier;
  $due_date->AddSeconds($seconds_to_add + $stalled_time);
  $RT::Logger->debug( "Adding $seconds_to_add elapsed + $stalled_time stalled seconds to create date " . scalar(localtime($created_date->Unix)) . " should be due " . scalar(localtime($due_date->Unix)));
} elsif ($timeouts->[1] =~ /^(\d+) local business (hour|minute|second)s?$/)
{
  my $multiplier = ($2 == "hour" ? 3600 : $2 == "minute" ? 60 : 1);
  my $seconds_to_add = $1 * $multiplier;
  use Business::Hours;
  my $bh = Business::Hours->new;
  my $end = $bh->add_seconds($created_date->Unix, $seconds_to_add + $stalled_time);
  $RT::Logger->debug( "Adding $1 local business hours ($seconds_to_add + $stalled_time secs) makes this " . scalar(localtime($end)));
  $due_date->Set(Format => 'unix', Value => $end);
} elsif ($timeouts->[1] =~ /^(\d+) global business (hour|minute|second)s?$/) 
{
  my $multiplier = ($2 == "hour" ? 3600 : $2 == "minute" ? 60 : 1);
  my $seconds_to_add = $1 * $multiplier;
  use Business::Hours;
  my $bh = Business::Hours->new;
  $bh->business_hours(
    1 => { Start => '08:00', End => '23:59' },
    2 => { Start => '08:00', End => '23:59' },
    3 => { Start => '08:00', End => '23:59' },
    4 => { Start => '08:00', End => '23:59' },
    5 => { Start => '08:00', End => '23:59' },
    );
  my $end = $bh->add_seconds($created_date->Unix, $seconds_to_add + $stalled_time);
  $RT::Logger->debug( "Adding $1 global business hours ($seconds_to_add + $stalled_time secs) makes this " . scalar(localtime($end)));
  $due_date->Set(Format => 'unix', Value => $end);
}
$RT::Logger->info("Due date set to " . $due_date->ISO );
return $ticket->SetDue($due_date->ISO);