
I have just started looking at OTRS and it looks like a very good system. I am using Sun Solaris 5.7 but it works just fine (except that SetPermisions.sh fails since no bash and chown syntax is different). One thing I found during testing was that the initial auto response from PostMaster was always sent to the From address and ignored any Reply-To email address. The following patch (against 0.5BETA7) fixes this. -- Phil Davis *** CURRENT/OpenTRS/Kernel/System/PostMaster/NewTicket.pm Mon Sep 9 12:22:13 2002 --- orig/OpenTRS/Kernel/System/PostMaster/NewTicket.pm Mon Aug 5 13:29:49 2002 *************** *** 166,182 **** QueueID => $QueueID, Type => $AutoResponseType, ); - - my $Send_to = $GetParam{ReplyTo}; - if ($Send_to eq "") { - $Send_to = $GetParam{From}; - } - if ($Data{Text} && $Data{Realname} && $Data{Address} && !$GetParam{'X-OTRS-Loop'}) { # -- # check / loop protection! # -- ! if (!$Self->{LoopProtectionObject}->Check(To => $Send_to)) { # add history row $TicketObject->AddHistoryRow( TicketID => $TicketID, --- 166,176 ---- QueueID => $QueueID, Type => $AutoResponseType, ); if ($Data{Text} && $Data{Realname} && $Data{Address} && !$GetParam{'X-OTRS-Loop'}) { # -- # check / loop protection! # -- ! if (!$Self->{LoopProtectionObject}->Check(To => $GetParam{From})) { # add history row $TicketObject->AddHistoryRow( TicketID => $TicketID, *************** *** 187,193 **** return; } # write log ! if (!$Self->{LoopProtectionObject}->SendEmail(To => $Send_to)) { return; } --- 181,187 ---- return; } # write log ! if (!$Self->{LoopProtectionObject}->SendEmail(To => $GetParam{From})) { return; } *************** *** 239,248 **** TicketID => $TicketID, TicketObject => $TicketObject, HistoryType => 'SendAutoReply', ! HistoryComment => "Sent auto response to '$Send_to'", From => "$Data{Realname} <$Data{Address}>", Email => $Data{Address}, ! To => $Send_to, RealName => $Data{Realname}, Charset => $Data{Charset}, Subject => $Subject, --- 233,242 ---- TicketID => $TicketID, TicketObject => $TicketObject, HistoryType => 'SendAutoReply', ! HistoryComment => "Sent auto response to '$GetParam{From}'", From => "$Data{Realname} <$Data{Address}>", Email => $Data{Address}, ! To => $GetParam{From}, RealName => $Data{Realname}, Charset => $Data{Charset}, Subject => $Subject, *************** *** 256,267 **** # do log $LogObject->Log( Message => "Sent auto reply for Ticket [$NewTn] (TicketID=$TicketID, " . ! "ArticleID=$ArticleID) to '$Send_to' " ); } else { # do log ! $LogObject->Log(MSG => "Sent no auto reply for Ticket [$NewTn] ($Send_to) " ); } --- 250,261 ---- # do log $LogObject->Log( Message => "Sent auto reply for Ticket [$NewTn] (TicketID=$TicketID, " . ! "ArticleID=$ArticleID) to '$GetParam{From}' " ); } else { # do log ! $LogObject->Log(MSG => "Sent no auto reply for Ticket [$NewTn] ($GetParam{From}) " ); }

Hi Phil, On Mon, Sep 09, 2002 at 12:35:56PM +0100, Phil Davis wrote:
I have just started looking at OTRS and it looks like a very good system. I am using Sun Solaris 5.7 but it works just fine (except that SetPermisions.sh fails since no bash and chown syntax is different).
One thing I found during testing was that the initial auto response from PostMaster was always sent to the From address and ignored any Reply-To email address.
The following patch (against 0.5BETA7) fixes this.
Cool. That's right. Thanks for the pretty good patch. I add it to the CVS. Thanks again. :-)
-- Phil Davis
Martin -- Martin Edenhofer - <martin at edenhofer.de> - http://martin.edenhofer.de/ -- nohl: 1:51pm up 16 days, 15:38, 6 users, load average: 0.03, 0.03, 0.00

I need to set up 2 instances of OTRS on the same box (as the same
user) in different directories. I got the web interface to
work fine by using 2 different ScriptAlias lines.
E.g.
ScriptAlias /otrstest /home/otrs/test
ScriptAlias /otrslive /home/otrs/live
However all the email notifications always had the same
path "......./otrs/index.pl.....".
The following diff to Notification.pm makes the emailed links
use a new Self->{ScriptAlias} which can be set up in Config.pm
This is against very recent CVS version.
--
Phil Davis
IT Action
*** Notification.pm Thu Oct 10 18:07:15 2002
--- /home/otrs/src/otrs/Kernel/Config/Notification.pm Sat Oct 5
17:10:21 2002
***************
*** 46,52 ****

Hi Phil, On Thu, Oct 10, 2002 at 06:46:27PM +0100, Phil Davis wrote:
I need to set up 2 instances of OTRS on the same box (as the same user) in different directories. I got the web interface to work fine by using 2 different ScriptAlias lines.
E.g. ScriptAlias /otrstest /home/otrs/test ScriptAlias /otrslive /home/otrs/live
However all the email notifications always had the same path "......./otrs/index.pl.....".
The following diff to Notification.pm makes the emailed links use a new Self->{ScriptAlias} which can be set up in Config.pm
Fine! I updated CVS with your patch. Thanks! :)
-- Phil Davis
Martin -- Martin Edenhofer - <martin at edenhofer.de> - http://martin.edenhofer.de/ -- Old programmers never die. They just branch to a new address.

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 Hi Phil,
On Mon, Oct 14, 2002 at 01:58:39PM +0100, Phil Davis wrote: 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.
[...] Wow! It's really cool. Thanks Phil! Of course I put it into the CVS.
I just added sorting links (age, state, queue, customer id, ...).
PS0: I added your name to the source code header. I hope this is ok?
PS1: Is it ok if I move the link (to AgentStatusView) to the utilities
section? Because it's probably not a "main" view (maybe confusing).
Martin
--
Martin Edenhofer - <martin at edenhofer.de> - http://martin.edenhofer.de/
--
Perfection is our goal, excellence will be tolerated. -- J. Yahl Martin Edenhofer wrote: 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.
[...] Wow! It's really cool. Thanks Phil! Of course I put it into the CVS. I just added sorting links (age, state, queue, customer id, ...). PS0: I added your name to the source code header. I hope this is ok? Yes fine. PS1: Is it ok if I move the link (to AgentStatusView) to the utilities
section? Because it's probably not a "main" view (maybe confusing). Well for our use we really want it in the main section since everyone on
our support team
probably needs to use it a lot but it's your system :-)
--
Phil Davis
<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
participants (2)