
One of the things stopping my team switching over to OTRS is the lack of
an overall
Status view showing _all_ open (inc. new) tickets no matter whether they
are locked or
not and who is working on them.
I have done a very quick hack to show you the sort of thing I am
thinking about. This
patch adds a new StatusView page. I only did the Standard theme since it
needs a lot
more work but is functional.
*** otrs/Kernel/Config/Modules.pm Thu Oct 3 22:10:13 2002
--- ../otrs/Kernel/Config/Modules.pm Fri Oct 11 16:39:06 2002
***************
*** 32,37 ****
--- 32,38 ----
# web agent middle ware modules
use Kernel::Modules::AgentQueueView;
+ use Kernel::Modules::AgentStatusView;
use Kernel::Modules::AgentMove;
use Kernel::Modules::AgentZoom;
use Kernel::Modules::AgentAttachment;
*** otrs/Kernel/Output/HTML/Agent.pm Mon Sep 23 14:53:44 2002
--- ../otrs/Kernel/Output/HTML/Agent.pm Mon Oct 14 12:55:06 2002
***************
*** 1016,1021 ****
--- 1016,1043 ----
return $Output;
}
# --
+ sub AgentStatusView {
+ my $Self = shift;
+ my %Param = @_;
+ # create & return output
+ return $Self->Output(TemplateFile => 'AgentStatusView', Data =>
\%Param);
+ }
+ # --
+ sub AgentStatusViewTable {
+ my $Self = shift;
+ my %Param = @_;
+ $Param{Age} = $Self->CustomerAge(Age => $Param{Age}, Space => ' ')
|| 0;
+ # do html quoteing
+ foreach (qw(State Queue Owner Lock)) {
+ $Param{$_} = $Self->Ascii2Html(Text => $Param{$_}, Max => 16);
+ }
+ foreach (qw(Subject)) {
+ $Param{$_} = $Self->Ascii2Html(Text => $Param{$_}, Max => 20);
+ }
+ # create & return output
+ return $Self->Output(TemplateFile => 'AgentStatusViewTable', Data
=> \%Param);
+ }
+ # --
1;
*** otrs/Kernel/Output/HTML/Standard/AgentNavigationBar.dtl Thu Oct
3 22:15:07 2002
--- ../otrs/Kernel/Output/HTML/Standard/AgentNavigationBar.dtl Mon Oct
14 13:43:16 2002
***************
*** 27,32 ****
--- 27,33 ----
<br>
$Env{"Box0"}$Text{"QueueView"}</a>$Env{"Box1"}
$Env{"Box0"}$Text{"PhoneView"}</a>$Env{"Box1"}
+ $Env{"Box0"}$Text{"StatusView"}</a>$Env{"Box1"}
</td>
<td align="right" width="60%">
$Env{"Box0"}$Text{"Utilities"}</a>$Env{"Box1"}
And finally here are new new files:
Kernel/Modules/AgentStatusView.pm
---------------------------------------------------------------------------------------------------
# --
# Kernel/Modules/AgentStatusView.pm - status for all open tickets
#
# --
# $Id$
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see http://www.gnu.org/licenses/gpl.txt.
# --
package Kernel::Modules::AgentStatusView;
use strict;
use vars qw($VERSION);
$VERSION = '$Revision: 1.20 $';
$VERSION =~ s/^.*:\s(\d+\.\d+)\s.*$/$1/;
# --
sub new {
my $Type = shift;
my %Param = @_;
# allocate new hash for object
my $Self = {};
bless ($Self, $Type);
# get common opjects
foreach (keys %Param) {
$Self->{$_} = $Param{$_};
}
# check all needed objects
foreach (
'ParamObject',
'DBObject',
'QueueObject',
'LayoutObject',
'ConfigObject',
'LogObject',
'UserObject',
) {
die "Got no $_" if (!$Self->{$_});
}
# --
# get config data
# --
# default viewable tickets a page
$Self->{ViewableTickets} =
$Self->{ConfigObject}->Get('ViewableTickets');
# viewable tickets a page
$Self->{Limit} = $Self->{ParamObject}->GetParam(Param => 'Limit')
|| $Self->{ViewableTickets};
# sure is sure!
$Self->{MaxLimit} = $Self->{ConfigObject}->Get('MaxLimit') || 300;
if ($Self->{Limit} > $Self->{MaxLimit}) {
$Self->{Limit} = $Self->{MaxLimit};
}
# --
# all static variables
# --
$Self->{ViewableLocks} = $Self->{ConfigObject}->Get('ViewableLocks')
|| die 'No Config entry "ViewableLocks"!';
$Self->{ViewableStats} = $Self->{ConfigObject}->Get('ViewableStats')
|| die 'No Config entry "ViewableStats"!';
$Self->{ViewableSenderTypes} =
$Self->{ConfigObject}->Get('ViewableSenderTypes')
|| die 'No Config entry "ViewableSenderTypes"!';
$Self->{CustomQueue} = $Self->{ConfigObject}->Get('CustomQueue') ||
'???';
return $Self;
}
# --
sub Run {
my $Self = shift;
my %Param = @_;
my $QueueID = $Self->{QueueID};
# --
# store last screen
# --
if (!$Self->{SessionObject}->UpdateSessionID(
SessionID => $Self->{SessionID},
Key => 'LastScreen',
Value => $Self->{RequestedURL},
)) {
my $Output = $Self->{LayoutObject}->Header(Title => 'Error');
$Output .= $Self->{LayoutObject}->Error();
$Output .= $Self->{LayoutObject}->Footer();
return $Output;
}
# starting with page ...
my $Refresh = '';
if ($Self->{UserRefreshTime}) {
$Refresh = 60 * $Self->{UserRefreshTime};
}
my $Output = $Self->{LayoutObject}->Header(
Title => 'QueueView',
Refresh => $Refresh,
);
# get user lock data
my %LockedData = $Self->{TicketObject}->GetLockedCount(UserID =>
$Self->{UserID});
# build NavigationBar
$Output .= $Self->{LayoutObject}->NavigationBar(LockData =>
\%LockedData);
# --
# build queue view ...
# --
my @ViewableQueueIDs = ();
if ($QueueID == 0) {
@ViewableQueueIDs = $Self->{QueueObject}->GetAllCustomQueues(
UserID => $Self->{UserID}
);
}
else {
@ViewableQueueIDs = ($QueueID);
}
# to get the output faster!
print $Output; $Output = '';
# --
# get data (viewable tickets...)
# --
my @ViewableTickets = ();
if (@ViewableQueueIDs) {
my @ViewableLocks = @{$Self->{ViewableLocks}};
my @ViewableStats = @{$Self->{ViewableStats}};
my $SQL = "SELECT st.id, st.queue_id FROM " .
" ticket st, ticket_state tsd " .
" WHERE " .
" tsd.id = st.ticket_state_id " .
" AND " .
" tsd.name in ( ${\(join ', ', @ViewableStats)} ) " .
" AND " .
" st.queue_id in ( ${\(join ', ', @ViewableQueueIDs)} ) " .
" ORDER BY st.ticket_priority_id DESC, st.create_time_unix ASC ";
$Self->{DBObject}->Prepare(SQL => $SQL, Limit => $Self->{Limit});
while (my @RowTmp = $Self->{DBObject}->FetchrowArray()) {
my $Data = {
TicketID => $RowTmp[0],
TicketQueueID => $RowTmp[1],
};
push (@ViewableTickets, $Data);
}
}
# --
# show ticket's
# --
my $OutputTable = "";
foreach my $DataTmp (@ViewableTickets) {
my %Data = %$DataTmp;
$OutputTable .= ShowTicketStatus($Self,
%Data,
QueueID => $QueueID,
);
}
$Output .= $Self->{LayoutObject}->AgentStatusView(
StatusTable => $OutputTable);
# get page footer
$Output .= $Self->{LayoutObject}->Footer();
# return page
return $Output;
}
# --
# ShowTicket
# --
sub ShowTicketStatus {
my $Self = shift;
my %Param = @_;
my $TicketID = $Param{TicketID} || return;
my $QueueID = $Param{QueueID} || 0;
my $TicketQueueID = $Param{TicketQueueID} || '';
my $Output = '';
# --
# get articles
# --
my @ShownViewableTicket = ();
my $SQL = "SELECT sa.ticket_id, sa.a_subject, " .
" st.create_time_unix, st.user_id, " .
" st.customer_id, sq.name as queue, sa.id as article_id, " .
" st.id, st.tn, sp.name, sd.name as state, st.queue_id, " .
" st.create_time, ".
" su.$Self->{ConfigObject}->{DatabaseUserTableUser} " .
" FROM " .
" article sa, ticket st, ticket_priority sp, ticket_state sd, " .
" article_sender_type sdt, queue sq, " .
" $Self->{ConfigObject}->{DatabaseUserTable} su " .
" WHERE " .
" sa.ticket_id = st.id " .
" AND " .
" sa.article_sender_type_id = sdt.id " .
" AND " .
" sq.id = st.queue_id" .
" AND " .
" sp.id = st.ticket_priority_id " .
" AND " .
" st.ticket_state_id = sd.id " .
" AND " .
" sa.ticket_id = $TicketID " .
" AND " .
" su.$Self->{ConfigObject}->{DatabaseUserTableUserID} =
st.user_id " .
" AND " .
" sdt.name in ( ${\(join ', ', @{$Self->{ViewableSenderTypes}})}
) " .
" ORDER BY sa.create_time DESC ";
$Self->{DBObject}->Prepare(SQL => $SQL, Limit => 1);
while (my $Data = $Self->{DBObject}->FetchrowHashref() ) {
my $Age = time() - $$Data{create_time_unix};
my $TicketOverTime = '';
if ($$Data{escalation_time} && !$$Data{ticket_answered}) {
$TicketOverTime = (time() - ($$Data{incoming_time} +
($$Data{escalation_time}*60)));
}
if ($$Data{a_content_type} && $$Data{a_content_type} =~
/charset=(.*)(| |\n)/i) {
$$Data{ContentCharset} = $1;
}
if ($$Data{a_content_type} && $$Data{a_content_type} =~
/^(.+?\/.+?)( |;)/i) {
$$Data{MimeType} = $1;
}
# Condense down the subject
my $TicketHook = $Self->{ConfigObject}->Get('TicketHook');
my $subject = $$Data{a_subject};
$subject =~ s/^RE:*//i;
$subject =~ s/\[${TicketHook}:\s*\d+\]//;
$Output .= $Self->{LayoutObject}->AgentStatusViewTable(
TicketNumber => $$Data{tn},
Priority => $$Data{name},
State => $$Data{state},
TicketID => $$Data{id},
ArticleID => $$Data{article_id},
Owner => $$Data{login},
Subject => $subject,
Age => $Age,
TicketOverTime => $TicketOverTime,
Created => $$Data{create_time},
QueueID => $QueueID,
Queue => $$Data{queue},
CustomerID => $$Data{customer_id},
);
push (@ShownViewableTicket, $$Data{id});
}
# if there is no customer article avalible! Error!
my $Hit = 0;
foreach (@ShownViewableTicket) {
if ($_ == $TicketID) {
$Hit = 1;
}
}
if ($Hit == 0) {
$Output .= $Self->{LayoutObject}->Error(
Message => "No customer article found!! (TicketID=$TicketID)",
Comment => 'Please contact your admin',
);
$Self->{LogObject}->Log(
Priority => 'error',
Message => "No customer article found!! (TicketID=$TicketID)",
Comment => 'Please contact your admin',
);
}
# return page
return $Output;
}
# --
1;
------------------------------------------------------------------------------------------------
Kernel/Output/HTML/Standard/AgentStatusViewTable.dtl
------------------------------------------------------------------------------------------------
# --
# AgentStatusViewTable.dtl
# --
# $Id$
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see http://www.gnu.org/licenses/gpl.txt.
# --
<!-- start record -->
<tr>
<td align="center">$Data{"TicketNumber"}</a></td>
<td>$Data{"Age"}</td>
<td>$Data{"Subject"}</td>
<td>$Data{"State"}</td>
<td>$Data{"Queue"}</td>
<td>$Data{"Owner"}</td>
<td>$Data{"CustomerId"}</td>
</tr>
<!-- end record -->
---------------------------------------------------------------------------------------------------
Kernel/Output/HTML/Standard/AgentStatusView.dtl
----------------------------------------------------------------------------------------------------
# --
# AgentStatusView.dtl -
# Copyright (C) 2001 Martin Edenhofer
<b>$Env{"Box0"}$Text{"Ticket
Status"}$Env{"Box1"}</font></b>
</font>
</td>
<b>-</font></b>
</font>
</td>
</tr>
</table>
<table border="0" width="100%" cellspacing="0" cellpadding="3">
<td align="center" valign="top">
<table border="0" width="100%" cellspacing="0" cellpadding="3" cols="5">
<tr>
<th width="15%">$Config{"TicketHook"}</th>
<th width="35%">$Text{"Age"}</th>
<th width="70%">$Text{"Subject"}</th>
<th width="10%">$Text{"State"}</th>
<th width="15%">$Text{"Queue"}</th>
<th width="15%">$Text{"Owner"}</th>
<th width="10%">$Text{"CustomerId"}</th>
</tr>
$Data{"StatusTable"}
</table>
</td>
</tr>
</table>
<!-- end form -->
---------------------------------------------------------------------------------------------------
PS, Does the mailing list accept attachments or is there a better place
to post such patches?
--
Phil Davis
IT Action