sub _ticket_info {
# Takes an RT::Ticket; returns a hashref of the ticket's fields, including
# custom fields. Also returns custom and selfservice priority values as
- # _custom_priority and _selfservice_priority.
+ # _custom_priority and _selfservice_priority, and the IsUnreplied property
+ # as is_unreplied.
my $t = shift;
my $custom_priority =
if ( $ss_priority ) {
$ticket_info{'_selfservice_priority'} = $ticket_info{"CF.{$ss_priority}"};
}
+ $ticket_info{'is_unreplied'} = $t->IsUnreplied;
my $svcnums = [
map { $_->Target =~ /cust_svc\/(\d+)/; $1 }
@{ $t->Services->ItemsArrayRef }
overflow:visible;
}
+
+/* elements/notify-tickets.html is in the menu area */
+.dot {
+ border-radius: 50%;
+ border: 1px solid black;
+ width: 1ex;
+ height: 1ex;
+ display: inline-block;
+ margin-top: 0.3ex;
+}
border-left: solid #bbffbb 30px;
display: inline-block;
}
+
+
% if ($enabled) {
-<style>
-.dot {
- border-radius: 50%;
- border: 1px solid black;
- width: 1ex;
- height: 1ex;
- display: inline-block;
-}
-</style>
<div style="font-weight: bold; vertical-align: bottom; text-align: left">
% if ( $UnrepliedTickets->Count > 0 ) {
<a href="<% $fsurl %>rt/Search/UnrepliedTickets.html">
<THEAD>
<TR>
+ <TH CLASS="grid" BGCOLOR="#cccccc"></TH>
<TH CLASS="grid" BGCOLOR="#cccccc"><% mt('#') |h %></TH>
<TH CLASS="grid" BGCOLOR="#cccccc"><% mt('Subject') |h %></TH>
<TH CLASS="grid" BGCOLOR="#cccccc"><% mt('Status') |h %></TH>
<TR>
<TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
+% if ( $ticket->{is_unreplied} ) {
+ <A CLASS="dot" STYLE="background-color: green" HREF=<%$href%>>
+% } else {
+% # placeholder
+ <A CLASS="dot" STYLE="visibility: hidden" HREF=<%$href%>>
+% }
+ </A>
+ </TD>
+
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>">
<A HREF=<%$href%>><% $ticket->{id} %></A>
</TD>
=head1 DESCRIPTION
-Find all unresolved tickets owned by the current user where the last correspondence
-from a requestor (or ticket creation) is more recent than the last
-correspondence from a non-requestor (if there is any).
+Find all unresolved tickets owned by the current user where the last
+correspondence from a requestor (or ticket creation) is more recent than the
+last correspondence from a non-requestor (if there is any).
=head1 METHODS
my $self = shift;
my $TicketsObj = $self->TicketsObj;
+ # if SystemUser does this search (as in QueueSummaryByLifecycle), they
+ # should get all tickets regardless of ownership
+ if ($TicketsObj->CurrentUser->id != RT->SystemUser->id) {
+ $TicketsObj->Limit(
+ FIELD => 'Owner',
+ VALUE => $TicketsObj->CurrentUser->id
+ );
+ }
$TicketsObj->Limit(
- FIELD => 'Owner',
- VALUE => $TicketsObj->CurrentUser->id
+ FIELD => 'Status',
+ OPERATOR => '!=',
+ VALUE => 'resolved'
);
$TicketsObj->Limit(
FIELD => 'Status',
OPERATOR => '!=',
- VALUE => 'resolved'
+ VALUE => 'rejected',
);
my $txn_alias = $TicketsObj->JoinTransactions;
$TicketsObj->Limit(
return $self->WillResolveObj->AsString();
}
+=head2 IsUnreplied
+
+Returns true if there's a Correspond or Create transaction more recent than
+the Told date of this ticket (or the ticket has no Told date) and the ticket
+is not rejected or resolved.
+
+=cut
+
+sub IsUnreplied {
+ my $self = shift;
+ return 0 if $self->Status eq 'resolved'
+ or $self->Status eq 'rejected';
+
+ my $Told = $self->Told || '1970-01-01';
+ my $Txns = $self->Transactions;
+ $Txns->Limit(FIELD => 'Type',
+ OPERATOR => 'IN',
+ VALUE => [ 'Correspond', 'Create' ]);
+ $Txns->Limit(FIELD => 'Created',
+ OPERATOR => '>',
+ VALUE => $Told);
+ $Txns->Count ? 1 : 0;
+}
1;
$Classes => ''
</%ARGS>
<%init>
+# it's a hack, but it has to be applied in every ticket search regardless
+# of format, so...
+if ( $record and $record->isa('RT::Ticket') and $record->IsUnreplied ) {
+ $Classes .= ' unreplied-ticket';
+}
$m->out( '<tr class="' . $Classes . ' '
. ( $Warning ? 'warnline' : $i % 2 ? 'oddline' : 'evenline' ) . '" >'
. "\n" );
next if lc($queue->{Lifecycle} || '') ne lc $lifecycle->Name;
$i++;
+
+ my $classes = $i%2 ? 'oddline' : 'evenline';
+ $classes .= ' unreplied-ticket' if $queue->{Unreplied} > 0;
</%PERL>
-<tr class="<% $i%2 ? 'oddline' : 'evenline'%>" >
+<tr class="<% $classes %>">
+<td></td>
<td>
<a href="<% $link_all->($queue, \@cur_statuses) %>" title="<% $queue->{Description} %>"><% $queue->{Name} %></a>
</td>
$lifecycle{ lc $cycle->Name } = $cycle;
}
+use RT::Search::UnrepliedTickets;
+my $Tickets = RT::Tickets->new( RT->SystemUser );
+my $Search = RT::Search::UnrepliedTickets->new( TicketsObj => $Tickets );
+$Search->Prepare;
+
+for my $queue (@queues) {
+ my $cycle = RT::Lifecycle->Load( Name => $queue->{'Lifecycle'} );
+ $lifecycle{ lc $cycle->Name } = $cycle;
+
+ # show whether there are unreplied tickets
+ # somewhat inefficient but we only use the count query
+ my $tix = $Tickets->Clone;
+ $tix->Limit(FIELD => 'Queue',
+ OPERATOR => '=',
+ VALUE => $queue->{id});
+ $queue->{Unreplied} = $tix->Count;
+}
+
unless (@statuses) {
my %seen;
foreach my $set ( 'initial', 'active' ) {
}
-
-
+tr.unreplied-ticket > :first-child::before {
+ /* green dot */
+ border: 1px solid black;
+ border-radius: 50%;
+ display: inline-block;
+ height: 1ex;
+ width: 1ex;
+ float: left;
+ content: '';
+ margin-top: 1ex;
+ background-color: green;
+}
table.queue-summary td {
background: #efefef;
border-bottom: 2px solid #ccc
}
+tr.unreplied-ticket > :first-child::before {
+ /* green dot */
+ border: 1px solid black;
+ border-radius: 50%;
+ display: inline-block;
+ height: 1ex;
+ width: 1ex;
+ float: left;
+ content: '';
+ margin-right: 1ex;
+ background-color: green;
+}
+
table.queue-summary td {
background: #efefef;
border-bottom: 1px solid #ccc;