Wednesday, April 25, 2012

OTRS Using Ticket Last Updated Time Instead of Age Solution



::Printing Last Update Time On The Agent Ticket Queue View::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Output\HTML\Standard\AgentTicketQueueTicketView.dtl
----------
Look for:
----------
 $Env{"Box0"}$Text{"Age"}: $Data{"Age"}$Env{"Box1"}
----------
Change to:
----------
 $Env{"Box0"}$Text{"LastUpdated"}: $Data{"LastUpdated"}$Env{"Box1"}
----------
Look for:
----------
        <tr>
          <td class="mainkey">$Text{"Created"}:</td>
          <td class="mainvalue"> $TimeLong{"$Data{"AgeCreated"}"}</td>
        </tr>
----------
Change to:
----------
        <tr>
          <td class="mainkey">$Text{"Age"}:</td>
          <td class="mainvalue">&nbsp;$Data{"Age"} </td>
          <td>&nbsp;</td>
          <td class="mainkey">$Text{"Created"}:</td>
          <td class="mainvalue"> $TimeLong{"$Data{"AgeCreated"}"}</td>
        </tr>
----------
Locate:
----------
Kernel\Output\HTML\Standard\AgentTicketZoom.dtl
----------
Look for:
----------
    <td align="right" width="30%" class="mainhead">
      $Env{"Box0"}$Text{"Age"}: $Data{"Age"}$Env{"Box1"}
    </td>
----------
Change to:
----------
    <td align="right" width="30%" class="mainhead">
      $Env{"Box0"}$Text{"Updated"}: $TimeLong{"$Data{"LastUpdated"}"}$Env{"Box1"}
    </td>
----------
Look for:
----------
    <td align="right" width="30%" class="menu">
      <table border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td class="mainkey">$Text{"Created"}:</td>
          <td class="mainvalue"> $TimeLong{"$Data{"Created"}"}</td>
        </tr>
      </table>
    </td>
----------
Change to:
----------
    <td align="right" width="30%" class="menu">
      <table border="0" cellspacing="0" cellpadding="0">
        <tr>
          <td class="mainkey">$Text{"Age"}:</td>
          <td class="mainvalue">&nbsp;$Data{"Age"} </td>
          <td>&nbsp;</td>
          <td class="mainkey">$Text{"Created"}:</td>
          <td class="mainvalue"> $TimeLong{"$Data{"Created"}"}</td>
        </tr>
      </table>
    </td>
----------
Locate:
----------
Kernel\System\Ticket\Article.pm
----------
Look for:
----------
        . ' st.escalation_solution_time, st.escalation_time '
----------
Change to:
----------
        . ' st.escalation_solution_time, st.escalation_time, st.change_time '
----------
Look for:
----------
        $Data{SLAID}               = $Row[75];
        $Ticket{SLAID}             = $Row[75];
----------
Change to:
----------
        $Data{SLAID}               = $Row[75];
        $Ticket{SLAID}             = $Row[75];
        $Data{LastUpdated}           = $Row[79];
        $Ticket{LastUpdated}         = $Data{LastUpdated};
        $Data{AgeCreated}            = $Self->{TimeObject}->SystemTime2TimeStamp( SystemTime => $Row[8] );
        $Ticket{AgeCreated}          = $Data{AgeCreated};
----------
Locate:
----------
Kernel\System\Ticket.pm
----------
Look for:
----------
        $Ticket{TicketFreeTime6}        = defined( $Row[53] ) ? $Row[53] : '';
----------
Change to:
----------
        $Ticket{TicketFreeTime6}        = defined( $Row[53] ) ? $Row[53] : '';
        $Ticket{LastUpdated}            = $Row[54];
        $Ticket{AgeCreated}             = $Self->{TimeObject}->SystemTime2TimeStamp( SystemTime => $Row[7] );
----------------------------------------------------------------------------------------------------
::Sort Agent Ticket Queue View By Last Updated Time::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Modules\AgentTicketQueue.pm
----------
Look for:
----------
        TicketFreeText16       => 'st.freetext16'
----------
Change to:
----------
        TicketFreeText16       => 'st.freetext16',
        LastUpdated            => 'st.change_time'
----------
Locate:
----------
Kernel\Config\Files\Ticket.xml
----------
Look for:
----------
        <SubGroup>Frontend::Agent::Ticket::ViewQueue</SubGroup>
        <Setting>
            <Option SelectedID="Age">
                <Item Key="Age">Age</Item>
----------
Change to:
----------
        <SubGroup>Frontend::Agent::Ticket::ViewQueue</SubGroup>
        <Setting>
            <Option SelectedID="Age">
                <Item Key="Age">Age</Item>
                <Item Key="LastUpdated">LastUpdated</Item>
----------
Note!
----------
Then select the LastUpdated option in the web interface.
Its under Admin->SysConfig->Ticket->Frontend::Agent::Ticket::ViewQueue->
Ticket::Frontend::AgentTicketQueue###SortBy::Default:
----------------------------------------------------------------------------------------------------
::Updating Last Updated Time When A Note Is Added To A Ticket::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Modules\AgentTicketNote.pm
----------
Look for:
----------
    # redirect to last screen overview on closed tickets
    if ( $StateData{TypeName} =~ /^close/i ) {
        return $Self->{LayoutObject}->Redirect( OP => $Self->{LastScreenOverview} );
    }
----------
Change to:
----------
    # redirect to last screen overview on closed tickets
    if ( $StateData{TypeName} =~ /^close/i ) {
        return $Self->{LayoutObject}->Redirect( OP => $Self->{LastScreenOverview} );
    }
    $Self->{TicketObject}->TicketUpdateTimeSet(
        UserID   => $Self->{UserID},
        TicketID => $Self->{TicketID},
        %GetParam,
    );
----------
Locate:
----------
Kernel\System\Ticket.pm
----------
Look for:
----------
=item TicketAclActionData()
return the current ACL action data hash after TicketAcl()
    my %AclAction = $TicketObject->TicketAclActionData();
=cut
sub TicketAclActionData {
    my ( $Self, %Param ) = @_;
    if ( $Self->{TicketAclActionData} ) {
        return %{ $Self->{TicketAclActionData} };
    }
    else {
        return %{ $Self->{ConfigObject}->Get('TicketACL::Default::Action') };
    }
}
----------
Change to:
----------
=item TicketAclActionData()
return the current ACL action data hash after TicketAcl()
    my %AclAction = $TicketObject->TicketAclActionData();
=cut
sub TicketAclActionData {
    my ( $Self, %Param ) = @_;
    if ( $Self->{TicketAclActionData} ) {
        return %{ $Self->{TicketAclActionData} };
    }
    else {
        return %{ $Self->{ConfigObject}->Get('TicketACL::Default::Action') };
    }
}
=item TicketUpdateTimeSet()
set ticket update time
    $TicketObject->TicketUpdateTimeSet(
        Year     => 2003,
        Month    => 08,
        Day      => 14,
        Hour     => 22,
        Minute   => 05,
        TicketID => 123,
        UserID   => 23,
    );
or use a time stamp
    $TicketObject->TicketUpdateTimeSet(
        String   => '2003-08-14 22:05:00',
        TicketID => 123,
        UserID   => 23,
    );
=cut
sub TicketUpdateTimeSet {
    my ( $Self, %Param ) = @_;
    my $Time;
    # check needed stuff
    if ( !$Param{String} ) {
        for (qw(Year Month Day Hour Minute TicketID UserID)) {
            if ( !defined $Param{$_} ) {
                $Self->{LogObject}->Log( Priority => 'error', Message => "Need $_!" );
                return;
            }
        }
    }
    # get system time from string/params
    if ( $Param{String} ) {
        $Time = $Self->{TimeObject}->TimeStamp2SystemTime( String => $Param{String}, );
        ( $Param{Sec}, $Param{Minute}, $Param{Hour}, $Param{Day}, $Param{Month}, $Param{Year} )
            = $Self->{TimeObject}->SystemTime2Date( SystemTime => $Time, );
    }
    else {
        $Time = $Self->{TimeObject}->TimeStamp2SystemTime(
            String => "$Param{Year}-$Param{Month}-$Param{Day} $Param{Hour}:$Param{Minute}:00",
        );
    }
    # return if no convert is possible
    if ( !$Time ) {
        return;
    }
    # db update
    return if !$Self->{DBObject}->Do(
        SQL => 'UPDATE ticket SET '
            . ' change_time = current_timestamp, change_by = ? WHERE id = ?',
        Bind => [ \$Param{UserID}, \$Param{TicketID} ],
    );
    # clear ticket cache
    delete $Self->{ 'Cache::GetTicket' . $Param{TicketID} };
    # ticket event
    $Self->TicketEventHandlerPost(
        Event    => 'TicketUpdateTimeUpdate',
        UserID   => $Param{UserID},
        TicketID => $Param{TicketID},
    );
    return 1;
}
----------
Look for:
----------
=item TicketEventHandlerPost()
call ticket event post handler, returns true if it's executed successfully
    $TicketObject->TicketEventHandlerPost(
        TicketID => 123,
        Event    => 'TicketStateUpdate',
        UserID   => 123,
    );
events available:
TicketCreate, TicketDelete, TicketTitleUpdate, TicketUnlockTimeoutUpdate,
TicketQueueUpdate, TicketTypeUpdate, TicketServiceUpdate,
TicketSLAUpdate, TicketCustomerUpdate, TicketFreeTextUpdate, TicketFreeTimeUpdate,
TicketPendingTimeUpdate, TicketLockUpdate, TicketStateUpdate, TicketOwnerUpdate,
TicketResponsibleUpdate, TicketPriorityUpdate, HistoryAdd, HistoryDelete,
TicketAccountTime, TicketMerge, ArticleCreate, ArticleFreeTextUpdate,
ArticleUpdate, ArticleSend, ArticleBounce, ArticleAgentNotification,
ArticleCustomerNotification, ArticleAutoResponse, ArticleFlagSet, ArticleFlagDelete;
----------
Change to:
----------
=item TicketEventHandlerPost()
call ticket event post handler, returns true if it's executed successfully
    $TicketObject->TicketEventHandlerPost(
        TicketID => 123,
        Event    => 'TicketStateUpdate',
        UserID   => 123,
    );
events available:
TicketCreate, TicketDelete, TicketTitleUpdate, TicketUnlockTimeoutUpdate,
TicketQueueUpdate, TicketTypeUpdate, TicketServiceUpdate,
TicketSLAUpdate, TicketCustomerUpdate, TicketFreeTextUpdate, TicketFreeTimeUpdate,
TicketPendingTimeUpdate, TicketLockUpdate, TicketStateUpdate, TicketOwnerUpdate,
TicketResponsibleUpdate, TicketPriorityUpdate, HistoryAdd, HistoryDelete,
TicketAccountTime, TicketMerge, ArticleCreate, ArticleFreeTextUpdate,
ArticleUpdate, ArticleSend, ArticleBounce, ArticleAgentNotification,
ArticleCustomerNotification, ArticleAutoResponse, ArticleFlagSet, ArticleFlagDelete, TicketUpdateTimeUpdate;
----------
Look for:
----------
        elsif ( $Param{Event} eq 'ArticleAutoResponse' ) {
            $Param{Event} = 'SendAutoResponse';
        }
        else {
            return 1;
        }
----------
Change to:
----------
        elsif ( $Param{Event} eq 'ArticleAutoResponse' ) {
            $Param{Event} = 'SendAutoResponse';
        }
        elsif ( $Param{Event} eq 'TicketUpdateTimeUpdate' ) {
            $Param{Event} = 'TicketUpdateTimeSet';
        }
        else {
            return 1;
        }
----------------------------------------------------------------------------------------------------
::Updating Last Updated Time When A Phone Reply Is Added To A Ticket::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Modules\AgentTicketPhoneOutbound.pm
----------
Look for:
----------
        # should i set an unlock? yes if the ticket is closed
----------
Change to:
----------
        # set last updated time
        $Self->{TicketObject}->TicketUpdateTimeSet(
            UserID   => $Self->{UserID},
            TicketID => $Self->{TicketID},
            %GetParam,
        );
        # should i set an unlock? yes if the ticket is closed
----------------------------------------------------------------------------------------------------
::Display Accounted Time Units On Customer Screen::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Modules\CustomerTicketOverview.pm
----------
Look for:
----------
    # condense down the subject
----------
Change to:
----------
    my $WorkTime = $Self->{TicketObject}->TicketAccountedTimeGet(TicketID => $Param{TicketID});
    # condense down the subject
----------
Look for:
----------
    # add block
    $Self->{LayoutObject}->Block(
        Name => 'Record',
        Data => {
            %Article,
            Subject => $Subject,
            %Param,
----------
Change to:
----------
    # add block
    $Self->{LayoutObject}->Block(
        Name => 'Record',
        Data => {
            %Article,
            Subject => $Subject,
            WorkTime => $WorkTime,
            %Param,
----------
Locate:
----------
Kernel\Output\HTML\Standard\CustomerStatusView.dtl
----------
Look for:
----------
          <th width="10%">$Text{"Owner"}<br/>
          <a href="$Env{"Baselink"}Action=$Env{"Action"}&SortBy=Owner&Order=Up&Limit=$Data{"Limit"}&ShowClosedTickets=$Data{"ShowClosed"}&Type=$Data{"Type"}" onmouseover="window.status='$JSText{"sort upward"}'; return true;" onmouseout="window.status='';"><img border="0" src="$Env{"Images"}up-small.png" alt="$Text{"up"}"></a> /
          <a href="$Env{"Baselink"}Action=$Env{"Action"}&SortBy=Owner&Order=Down&Limit=$Data{"Limit"}&ShowClosedTickets=$Data{"ShowClosed"}&Type=$Data{"Type"}" onmouseover="window.status='$JSText{"sort downward"}'; return true;" onmouseout="window.status='';"><img border="0" src="$Env{"Images"}down-small.png" alt="$Text{"down"}"></a>
          </th>
----------
Change to:
----------
          <th width="5%">$Text{"Owner"}<br/>
          <a href="$Env{"Baselink"}Action=$Env{"Action"}&SortBy=Owner&Order=Up&Limit=$Data{"Limit"}&ShowClosedTickets=$Data{"ShowClosed"}&Type=$Data{"Type"}" onmouseover="window.status='$JSText{"sort upward"}'; return true;" onmouseout="window.status='';"><img border="0" src="$Env{"Images"}up-small.png" alt="$Text{"up"}"></a> /
          <a href="$Env{"Baselink"}Action=$Env{"Action"}&SortBy=Owner&Order=Down&Limit=$Data{"Limit"}&ShowClosedTickets=$Data{"ShowClosed"}&Type=$Data{"Type"}" onmouseover="window.status='$JSText{"sort downward"}'; return true;" onmouseout="window.status='';"><img border="0" src="$Env{"Images"}down-small.png" alt="$Text{"down"}"></a>
          </th>
          <th width="5%">$Text{"Time"}</th>
----------
Look for:
----------
          <td class="$Env{"Color"}"><div title="$Quote{"$Data{"Owner"}"}">$Quote{"$Data{"Owner"}","18"}</div></td>
----------
Change to:
----------
          <td class="$Env{"Color"}"><div title="$Quote{"$Data{"Owner"}"}">$Quote{"$Data{"Owner"}","18"}</div></td>
          <td class="$Env{"Color"}">$QData{"WorkTime"}</td>
----------------------------------------------------------------------------------------------------
::Printing Last Update Time On The Customer Ticket Zoom::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Output\HTML\Standard\CustomerTicketZoom.dtl
----------
Look for:
----------
<table border="0" width="100%" cellspacing="0" cellpadding="3">
  <tr>
    <td width="50%" class="mainhead">
      $Env{"Box0"}$Text{"Zoom"} $Config{"Ticket::Hook"}: $Data{"TicketNumber"}$Env{"Box1"}
    </td>
    <td align="right" width="50%" class="mainhead">
      $Env{"Box0"}$Text{"Age"}: $Data{"Age"}$Env{"Box1"}
    </td>
  </tr>
</table>
<table border="0" width="100%" cellspacing="0" cellpadding="3">
  <tr>
    <td width="70%" class="menu">
      <a href="$Env{"Baselink"}Action=CustomerTicketPrint&TicketID=$QData{"TicketID"}" onmouseover="window.status='$JSText{"Print Ticket"}'; return true;" onmouseout="window.status='';" target="_blank">$Text{"Print"}</a>
    </td>
    <td align="right" width="30%" class="menu">
      <b>$Text{"Created"}:</b> $TimeLong{"$Data{"Created"}"}
    </td>
  </tr>
</table>
----------
Change to:
----------
<table border="0" width="100%" cellspacing="0" cellpadding="3">
  <tr>
    <td width="50%" class="mainhead">
      $Env{"Box0"}$Text{"Zoom"} $Config{"Ticket::Hook"}: $Data{"TicketNumber"}$Env{"Box1"}
    </td>
    <td align="right" width="50%" class="mainhead">
      $Env{"Box0"}$Text{"Updated"}: $TimeLong{"$Data{"LastUpdated"}"}$Env{"Box1"}
    </td>
  </tr>
</table>
<table border="0" width="100%" cellspacing="0" cellpadding="3">
  <tr>
    <td width="60%" class="menu">
      <a href="$Env{"Baselink"}Action=CustomerTicketPrint&TicketID=$QData{"TicketID"}" onmouseover="window.status='$JSText{"Print Ticket"}'; return true;" onmouseout="window.status='';" target="_blank">$Text{"Print"}</a>
    </td>
    <td align="right" width="40%" class="menu">
      <b>$Text{"Age"}:</b> $Data{"Age"} <b>$Text{"Created"}:</b> $TimeLong{"$Data{"Created"}"}
    </td>
  </tr>
</table>
----------------------------------------------------------------------------------------------------
::Printing Last Update Time On The Customer Screen::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\Output\HTML\Standard\CustomerStatusView.dtl
----------
Look for:
----------
          <th width="20%">$Text{"Age"}<br/>
----------
Change to:
----------
          <th width="20%">$Text{"Updated"}<br/>
----------
Look for:
----------
          <td class="$Env{"Color"}">$QData{"Age","20"}</td>
----------
Change to:
----------
          <td class="$Env{"Color"}">$TimeLong{"$QData{"LastUpdated","20"}"}</td>
----------------------------------------------------------------------------------------------------
::Show Latest Update (regardless of who its by) on Agent Ticket Queue View::
----------------------------------------------------------------------------------------------------
----------
Locate:
----------
Kernel\System\Ticket\Article.pm
----------
Look for:
----------
    # check if latest article is sent to customer
    elsif (
        $Param{SenderType} eq 'agent'
        && $Param{ArticleType} =~ /email-ext|phone|fax|sms|note-ext/
----------
Change to:
----------
    # check if latest article is sent to customer
    elsif (
        $Param{SenderType} eq 'agent'
#        && $Param{ArticleType} =~ /email-ext|phone|fax|sms|note-ext/
#NOTE: I don't remember why this needed to be removed, but it works this way
----------
Look for:
----------
    # return ArticleID
    return $ArticleID;
}
# just for internal use
----------
Change to:
----------
    $Self->{DBObject}->Do(
        SQL => 'UPDATE ticket SET change_time = current_timestamp WHERE id = ?',
        Bind => [ \$Param{TicketID} ],
    );
    # return ArticleID
    return $ArticleID;
}
# just for internal use
----------
Look for:
----------
    # if we got no internal article, return the latest one
    return $Self->ArticleGet( ArticleID => $Index[-1] );
}
----------
Change to:
----------
    # if we got no internal article, return the latest one
    return $Self->ArticleGet( ArticleID => $Index[-1] );
}
=item ArticleLastArticle()
get last customer article
    my %Article = $TicketObject->ArticleLastArticle(
        TicketID => 123,
    );
=cut
sub ArticleLastArticle {
    my ( $Self, %Param ) = @_;
    # check needed stuff
    if ( !$Param{TicketID} ) {
        $Self->{LogObject}->Log( Priority => 'error', Message => "Need TicketID!" );
        return;
    }
    # get article index
    my @Index = $Self->ArticleIndex( TicketID => $Param{TicketID} );
    # get article data
    return $Self->ArticleGet( ArticleID => $Index[-1] ) if @Index;
    @Index = $Self->ArticleIndex( TicketID => $Param{TicketID} );
    if ( !@Index ) {
        $Self->{LogObject}->Log(
            Priority => 'error',
            Message  => "No article found for TicketID $Param{TicketID}!",
        );
        return;
    }
    # return latest non internal article
    return $Self->ArticleGet( ArticleID => $Index[-1] );
}
----------
Locate:
----------
Kernel\Modules\AgentTicketQueue.pm
----------
Look for:
----------
    # get last article
    my %Article = $Self->{TicketObject}->ArticleLastCustomerArticle( TicketID => $TicketID );
----------
Change to:
----------
    # get last article
    my %Article = $Self->{TicketObject}->ArticleLastArticle( TicketID => $TicketID );


0 comments:

Post a Comment