Adding customer name in Customer ticket overview
Moderator: crythias
Adding customer name in Customer ticket overview
Hello everybody
I'm using OTRS 5.0.13 on CentOS 7
I was wondering if it is possible to add the customer user name of the user that logged the ticket in an extra column in the customer ticket overview. A customer has multiple employees that can create tickets and their supervisor would like to see a list of the tickets with the addition of the name of the original ticket reporter.
I've found the option Frontend::Customer::TicketOverview, but apparently this does not provide the same options as I was expecting like in Frontend::Agent::DefaultOverviewColumns.
I can add dynamicfield, but since the CustomerName (full name of the customer user actually) is not a dynamicfield, I can't enable this.
Is there another way to add this or am I overlooking something?
I'm using OTRS 5.0.13 on CentOS 7
I was wondering if it is possible to add the customer user name of the user that logged the ticket in an extra column in the customer ticket overview. A customer has multiple employees that can create tickets and their supervisor would like to see a list of the tickets with the addition of the name of the original ticket reporter.
I've found the option Frontend::Customer::TicketOverview, but apparently this does not provide the same options as I was expecting like in Frontend::Agent::DefaultOverviewColumns.
I can add dynamicfield, but since the CustomerName (full name of the customer user actually) is not a dynamicfield, I can't enable this.
Is there another way to add this or am I overlooking something?
You do not have the required permissions to view the files attached to this post.
OTRS 6.0.5
-
- Znuny guru
- Posts: 2210
- Joined: 13 Mar 2014, 09:16
- Znuny Version: 6.0.14
- Real Name: Rolf Straub
Re: Adding customer name in Customer ticket overview
No, it seem you'd need a modification of the OTRS framework to acomplish that.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
Re: Adding customer name in Customer ticket overview
Thank you very much for your quick reply.RStraub wrote:No, it seem you'd need a modification of the OTRS framework to acomplish that.
At this moment I don't have a lot of experience manually modifying the OTRS framework, can you guide me in the right direction?
Or perhaps link me some more information so I know where to look? Thanks!
OTRS 6.0.5
-
- Znuny guru
- Posts: 2210
- Joined: 13 Mar 2014, 09:16
- Znuny Version: 6.0.14
- Real Name: Rolf Straub
Re: Adding customer name in Customer ticket overview
Hi there,
that's actually not too hard.
1) Create a new folder (if it's not there yet) ~otrs/Custom/
2) Copy these files to the new folder (PRESERVING the same folder structure):
Kernel/Output/HTML/Templates/Standard/CustomerTicketOverview.tt
Kernel/Modules/CustomerTicketOverview.pm
so as otrs-user:
cp -p ~/Kernel/Output/HTML/Templates/Standard/CustomerTicketOverview.tt ~/Custom/Kernel/Output/HTML/Templates/Standard/CustomerTicketOverview.tt
3) Modify the template file (.tt):
3.1.) Add a new html header:
https://github.com/OTRS/otrs/blob/rel-5 ... iew.tt#L39
e.g.:
3.2.) Add a new data row:
https://github.com/OTRS/otrs/blob/rel-5 ... ew.tt#L110
e.g.:
4) Add the created-by name to the data hash in the perl module here:
https://github.com/OTRS/otrs/blob/rel-5 ... ew.pm#L677
Add these lines:
This should suffice to give you the additional column.
that's actually not too hard.
1) Create a new folder (if it's not there yet) ~otrs/Custom/
2) Copy these files to the new folder (PRESERVING the same folder structure):
Kernel/Output/HTML/Templates/Standard/CustomerTicketOverview.tt
Kernel/Modules/CustomerTicketOverview.pm
so as otrs-user:
cp -p ~/Kernel/Output/HTML/Templates/Standard/CustomerTicketOverview.tt ~/Custom/Kernel/Output/HTML/Templates/Standard/CustomerTicketOverview.tt
3) Modify the template file (.tt):
3.1.) Add a new html header:
https://github.com/OTRS/otrs/blob/rel-5 ... iew.tt#L39
e.g.:
Code: Select all
<th class="State [% Data.CreatedBy| uri %]">
<a href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];SortBy=CreatedBy;OrderBy=[% Data.OrderBy | uri %];Filter=[% Data.Filter | uri %]">
[% Translate("CreatedBy") | html %]
</a>
</th>
https://github.com/OTRS/otrs/blob/rel-5 ... ew.tt#L110
e.g.:
Code: Select all
<td class="Status">[% Translate(Data.CreatedBy) | html %]</td>
https://github.com/OTRS/otrs/blob/rel-5 ... ew.pm#L677
Add these lines:
Code: Select all
$Param{CreatedBy} = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerName(
UserLogin => $Ticket{CreateBy},
);
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
Re: Adding customer name in Customer ticket overview
Thank you for your response!
How does one go about to enable these custom files?
Is it just enough to have them in the correct directory .../otrs/Custom/Kernel/...? Or do I need to change some option in sysconfig?
I'm sorry for this question, but I've never used custom pages for OTRS.
Thanks in advance!
How does one go about to enable these custom files?
Is it just enough to have them in the correct directory .../otrs/Custom/Kernel/...? Or do I need to change some option in sysconfig?
I'm sorry for this question, but I've never used custom pages for OTRS.
Thanks in advance!
OTRS 6.0.5
-
- Znuny guru
- Posts: 2210
- Joined: 13 Mar 2014, 09:16
- Znuny Version: 6.0.14
- Real Name: Rolf Straub
Re: Adding customer name in Customer ticket overview
No, putting them into the ~/Custom/ folder is enough.
OTRS scans first all files in ~/... and THEN overwrites the files with those found in ~/Custom/..
This is true for most of the perl files and the template files. There are some exceptions, like the Config.pm or the config files in ~/Kernel/Config/Files.
It's only important to have the exact same folder structure under ~/Custom as you have in the original path. Also make sure to migrate the Custom folder on upgrades
OTRS scans first all files in ~/... and THEN overwrites the files with those found in ~/Custom/..
This is true for most of the perl files and the template files. There are some exceptions, like the Config.pm or the config files in ~/Kernel/Config/Files.
It's only important to have the exact same folder structure under ~/Custom as you have in the original path. Also make sure to migrate the Custom folder on upgrades
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
Re: Adding customer name in Customer ticket overview
Hello
I've added the additions that you replied in the /opt/otrs/Custom directory. After restarting apache, I don't see any changes. Did I do something wrong? These are my custom files:
CustomerTicketOverview.tt
CustomerTicketOverview.pm
It seems to me, like the custom files are not getting loaded?
I've added the additions that you replied in the /opt/otrs/Custom directory. After restarting apache, I don't see any changes. Did I do something wrong? These are my custom files:
CustomerTicketOverview.tt
Code: Select all
# --
# Copyright (C) 2001-2016 xxx, http://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --
<div id="MainBox" class="TicketView ARIARoleMain [% Config("Ticket::Frontend::CustomerTicketOverviewSortable") %]">
[% RenderBlockStart("Filled") %]
<div class="ActionRow">
<ul class="Filter Tabs">
[% RenderBlockStart("FilterHeader") %]
<li>
<a class="[% Data.ClassA | html %]" href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];Filter=[% Data.Filter | uri %];SortBy=[% Data.SortBy | uri %];OrderBy=[% Data.OrderBy | uri %];">
[% Translate(Data.Name) | html %] ([% Data.Count | html %])
</a>
</li>
[% RenderBlockEnd("FilterHeader") %]
</ul>
<div class="Tabs Pagination">
[% Data.SiteNavBar %]
</div>
<div class="Clear"></div>
</div>
<div class="Content">
<table class="Overview">
<thead>
<tr>
<th class="Ticket [% Data.TicketSort | uri %]">
<a href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];SortBy=Ticket;OrderBy=[% Data.OrderBy | uri %];Filter=[% Data.Filter | uri %]">
[% Config("Ticket::Hook") %]
</a>
</th>
<th class="Title [% Data.TitleSort | uri %]">
<a href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];SortBy=Title;OrderBy=[% Data.OrderBy | uri %];Filter=[% Data.Filter | uri %]">
[% Translate("Title") | html %]
</a>
</th>
<th class="State [% Data.StateSort | uri %]">
<a href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];SortBy=State;OrderBy=[% Data.OrderBy | uri %];Filter=[% Data.Filter | uri %]">
[% Translate("State") | html %]
</a>
</th>
<th class="State [% Data.CreatedBy| uri %]">
<a href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];SortBy=CreatedBy;OrderBy=[% Data.OrderBy | uri %];Filter=[% Data.Filter | uri %]">
[% Translate("CreatedBy") | html %]
</a>
</th>
[% RenderBlockStart("OverviewNavBarPageOwner") %]
<th class="Owner [% Data.OwnerSort | uri %]">
<a href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];SortBy=Owner;OrderBy=[% Data.OrderBy | uri %];Filter=[% Data.Filter | uri %]">
[% Translate("Owner") | html %]
</a>
</th>
[% RenderBlockEnd("OverviewNavBarPageOwner") %]
[% RenderBlockStart("OverviewNavBarPageQueue") %]
<th class="Queue [% Data.QueueSort | uri %]">
<a href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];SortBy=Queue;OrderBy=[% Data.OrderBy | uri %];Filter=[% Data.Filter | uri %]">
[% Translate("Queue") | html %]
</a>
</th>
[% RenderBlockEnd("OverviewNavBarPageQueue") %]
[% RenderBlockStart("OverviewNavBarPageDynamicField") %]
<th class="DynamicField Last [% Data.CSS | html %]">
[% RenderBlockStart("OverviewNavBarPageDynamicFieldSortable") %]
<a name="OverviewControl" href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];SortBy=DynamicField_[% Data.DynamicFieldName | uri %];OrderBy=[% Data.OrderBy | uri %];Filter=[% Data.Filter | uri %]">[% Translate(Data.Label) | html %]</a>
[% RenderBlockEnd("OverviewNavBarPageDynamicFieldSortable") %]
[% RenderBlockStart("OverviewNavBarPageDynamicFieldNotSortable") %]
<span>[% Translate(Data.Label) | html %]</span>
[% RenderBlockEnd("OverviewNavBarPageDynamicFieldNotSortable") %]
</th>
[% RenderBlockEnd("OverviewNavBarPageDynamicField") %]
# example of how to use fixed dynamic field blocks for customizations
# Note: Field1 and Field2 are the names of the fields and had to be replaced with the actual
# field names
#[% RenderBlockStart("OverviewNavBarPageDynamicField_Field1") %]
# <th class="DynamicField Last [% Data.CSS | html %]">
#[% RenderBlockStart("OverviewNavBarPageDynamicField_Field1_Sortable") %]
# <a name="OverviewControl" href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];SortBy=DynamicField_[% Data.DynamicFieldName | uri %];OrderBy=[% Data.OrderBy | uri %];Filter=[% Data.Filter | uri %]">[% Translate(Data.Label) | html %]</a>
#[% RenderBlockEnd("OverviewNavBarPageDynamicField_Field1_Sortable") %]
#[% RenderBlockStart("OverviewNavBarPageDynamicField_Field1_NotSortable") %]
# <span>[% Translate(Data.Label) | html %]</span>
#[% RenderBlockEnd("OverviewNavBarPageDynamicField_Field1_NotSortable") %]
# </th>
#[% RenderBlockEnd("OverviewNavBarPageDynamicField_Field1") %]
#[% RenderBlockStart("OverviewNavBarPageDynamicField_Field2") %]
# <th class="DynamicField Last [% Data.CSS | html %]">
#[% RenderBlockStart("OverviewNavBarPageDynamicField_Field2_Sortable") %]
# <a name="OverviewControl" href="[% Env("Baselink") %]Action=[% Env("Action") %];[% Data.LinkSort %];SortBy=DynamicField_[% Data.DynamicFieldName | uri %];OrderBy=[% Data.OrderBy | uri %]">[% Translate(Data.Label) | html %]</a>
#[% RenderBlockEnd("OverviewNavBarPageDynamicField_Field2_Sortable") %]
#[% RenderBlockStart("OverviewNavBarPageDynamicField_Field2_NotSortable") %]
# <span>[% Translate(Data.Label) | html %]</span>
#[% RenderBlockEnd("OverviewNavBarPageDynamicField_Field2_NotSortable") %]
# </th>
#[% RenderBlockEnd("OverviewNavBarPageDynamicField_Field2") %]
<th class="Age [% Data.AgeSort | uri %]">
<a href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];SortBy=Age;OrderBy=[% Data.OrderBy | uri %];Filter=[% Data.Filter | uri %]">
[% Translate("Age") | html %]
</a>
</th>
</tr>
</thead>
<tbody>
[% RenderBlockStart("Record") %]
<tr class="MasterAction">
<td class="Ticket">
<a href="[% Env("Baselink") %]Action=CustomerTicketZoom;TicketNumber=[% Data.TicketNumber | uri %]" class="MasterActionLink">[% Data.TicketNumber | html %]</a>
</td>
<td class="Title">
<div>
<h2>[% Data.Subject | truncate(60) | html %]</h2>
- [% Data.Body | truncate(200) | html %]
</div>
</td>
<td class="Status">[% Translate(Data.State) | html %]</td>
<td class="Status">[% Translate(Data.CreatedBy) | html %]</td>
[% RenderBlockStart("RecordOwner") %]
<td class="Owner">[% Data.OwnerName | html %]</td>
[% RenderBlockEnd("RecordOwner") %]
[% RenderBlockStart("RecordQueue") %]
<td class="Queue" title="[% Data.Queue | html %]">[% Data.Queue | truncate(20) | html %]</td>
[% RenderBlockEnd("RecordQueue") %]
[% RenderBlockStart("RecordDynamicField") %]
<td>
<div title="[% Data.Title | html %]">
[% RenderBlockStart("RecordDynamicFieldLink") %]
<a href="[% Data.Link | Interpolate %]" class="DynamicFieldLink">[% Data.Value %]</a>
[% RenderBlockEnd("RecordDynamicFieldLink") %]
[% RenderBlockStart("RecordDynamicFieldPlain") %]
[% Data.Value %]
[% RenderBlockEnd("RecordDynamicFieldPlain") %]
</div>
</td>
[% RenderBlockEnd("RecordDynamicField") %]
# example of how to use fixed dynamic field blocks for customizations
# Note: Field1 and Field2 are the names of the fields and had to be replaced with the actual
# field names
#[% RenderBlockStart("RecordDynamicField_Field1") %]
# <td>
# <div title="[% Data.Title | html %]">
#[% RenderBlockStart("RecordDynamicField1Link") %]
# <a href="[% Data.Link | Interpolate %]" class="DynamicFieldLink">[% Data.Value %]</a>
#[% RenderBlockEnd("RecordDynamicField1Link") %]
#[% RenderBlockStart("RecordDynamicField1Plain") %]
# [% Data.Value %]
#[% RenderBlockEnd("RecordDynamicField1Plain") %]
# </div>
# </td>
#[% RenderBlockEnd("RecordDynamicField_Field1") %]
#[% RenderBlockStart("RecordDynamicField_Field2") %]
# <td>
# <div title="[% Data.Title | html %]">
#[% RenderBlockEnd("RecordDynamicField1Link") %]
# <a href="[% Data.Link | Interpolate %]" class="DynamicFieldLink">[% Data.Value %]</a>
#[% RenderBlockEnd("RecordDynamicField1Link") %]
#[% RenderBlockEnd("RecordDynamicField1Plain") %]
# [% Data.Value %]
#[% RenderBlockEnd("RecordDynamicField1Plain") %]
# </div>
# </td>
#[% RenderBlockEnd("RecordDynamicField_Field2") %]
<td class="Age" title="[% Data.Created | Localize("TimeShort") | html %]">[% Data.CustomerAge | truncate(20) | html %]</td>
</tr>
[% RenderBlockEnd("Record") %]
[% WRAPPER JSOnDocumentComplete %]
<script type="text/javascript">//<![CDATA[
$('.MasterAction').bind('click', function (Event) {
var $MasterActionLink = $(this).find('.MasterActionLink');
// only act if the link was not clicked directly
if (Event.target !== $MasterActionLink.get(0)) {
window.location = $MasterActionLink.attr('href');
return false;
}
});
//]]></script>
[% END %]
</tbody>
</table>
</div>
[% RenderBlockStart("FilterFooter") %]
<div id="BottomActionRow" class="ActionRow BigButtons">
<ul class="Tabs Filter">
[% RenderBlockStart("FilterFooterItem") %]
<li class="[% Data.ClassLI | html %]">
<a class="[% Data.ClassA | html %]" href="[% Env("Baselink") %]Action=[% Env("Action") %];Subaction=[% Env("Subaction") %];Filter=[% Data.Filter | uri %];SortBy=[% Data.SortBy | uri %];OrderBy=[% Data.OrderBy | uri %];">
[% Translate(Data.Name) | html %] ([% Data.Count | html %])
</a>
</li>
[% RenderBlockEnd("FilterFooterItem") %]
<li class="Clear"></li>
</ul>
<div class="Tabs Pagination">
[% Data.SiteNavBar %]
</div>
<div class="Clear"></div>
</div>
[% RenderBlockEnd("FilterFooter") %]
[% RenderBlockEnd("Filled") %]
[% RenderBlockStart("Empty") %]
<div class="Placeholder">
[% RenderBlockStart("EmptyDefault") %]
<h2>[% Translate("Welcome!") | html %]</h2>
<p>
[% Translate("Please click the button below to create your first ticket.") | html %]
</p>
[% RenderBlockStart("EmptyDefaultButton") %]
<a class="Button" href="[% Env("Baselink") %]Action=CustomerTicketMessage">[% Translate("Create your first ticket") | html %]</a>
[% RenderBlockEnd("EmptyDefaultButton") %]
[% RenderBlockEnd("EmptyDefault") %]
[% RenderBlockStart("EmptyCustom") %]
<h2>[% Translate(Data.Title) | html %]</h2>
<p>
[% Translate(Data.Text) | html %]
</p>
[% RenderBlockStart("EmptyCustomButton") %]
<a class="Button" href="[% Env("Baselink") %]Action=CustomerTicketMessage">[% Translate(Data.Button) | html %]</a>
[% RenderBlockEnd("EmptyCustomButton") %]
[% RenderBlockEnd("EmptyCustom") %]
</div>
[% RenderBlockEnd("Empty") %]
</div>
Code: Select all
# --
# Copyright (C) 2001-2016 xxx, http://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (AGPL). If you
# did not receive this file, see http://www.gnu.org/licenses/agpl.txt.
# --
package Kernel::Modules::CustomerTicketOverview;
## nofilter(TidyAll::Plugin::OTRS::Perl::DBObject)
use strict;
use warnings;
our $ObjectManagerDisabled = 1;
use Kernel::System::VariableCheck qw(:all);
use Kernel::Language qw(Translatable);
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {%Param};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
# disable output of customer company tickets
my $DisableCompanyTickets = $ConfigObject->Get('Ticket::Frontend::CustomerDisableCompanyTicketAccess');
# check subaction
if ( !$Self->{Subaction} ) {
return $LayoutObject->Redirect(
OP => 'Action=CustomerTicketOverview;Subaction=MyTickets',
);
}
elsif ( $Self->{Subaction} eq 'CompanyTickets' && $DisableCompanyTickets ) {
return $LayoutObject->CustomerNoPermission( WithHeader => 'yes' );
}
# check needed CustomerID
if ( !$Self->{UserCustomerID} ) {
my $Output = $LayoutObject->CustomerHeader(
Title => Translatable('Error'),
);
$Output .= $LayoutObject->CustomerError(
Message => Translatable('Need CustomerID!'),
);
$Output .= $LayoutObject->CustomerFooter();
return $Output;
}
$Kernel::OM->Get('Kernel::System::AuthSession')->UpdateSessionID(
SessionID => $Self->{SessionID},
Key => 'LastScreenOverview',
Value => $Self->{RequestedURL},
);
my $SortBy = $ParamObject->GetParam( Param => 'SortBy' ) || 'Age';
my $OrderByCurrent = $ParamObject->GetParam( Param => 'OrderBy' ) || 'Down';
# filter definition
my %Filters = (
MyTickets => {
All => {
Name => 'All',
Prio => 1000,
Search => {
CustomerUserLoginRaw => $Self->{UserID},
OrderBy => $OrderByCurrent,
SortBy => $SortBy,
CustomerUserID => $Self->{UserID},
Permission => 'ro',
},
},
Open => {
Name => 'Open',
Prio => 1100,
Search => {
CustomerUserLoginRaw => $Self->{UserID},
StateType => 'Open',
OrderBy => $OrderByCurrent,
SortBy => $SortBy,
CustomerUserID => $Self->{UserID},
Permission => 'ro',
},
},
Closed => {
Name => 'Closed',
Prio => 1200,
Search => {
CustomerUserLoginRaw => $Self->{UserID},
StateType => 'Closed',
OrderBy => $OrderByCurrent,
SortBy => $SortBy,
CustomerUserID => $Self->{UserID},
Permission => 'ro',
},
},
},
);
my $UserObject = $Kernel::OM->Get('Kernel::System::CustomerUser');
# add filter for customer company if not disabled
if ( !$DisableCompanyTickets ) {
$Filters{CompanyTickets} = {
All => {
Name => 'All',
Prio => 1000,
Search => {
CustomerIDRaw =>
[ $UserObject->CustomerIDs( User => $Self->{UserLogin} ) ],
OrderBy => $OrderByCurrent,
SortBy => $SortBy,
CustomerUserID => $Self->{UserID},
Permission => 'ro',
},
},
Open => {
Name => 'Open',
Prio => 1100,
Search => {
CustomerIDRaw =>
[ $UserObject->CustomerIDs( User => $Self->{UserLogin} ) ],
StateType => 'Open',
OrderBy => $OrderByCurrent,
SortBy => $SortBy,
CustomerUserID => $Self->{UserID},
Permission => 'ro',
},
},
Closed => {
Name => 'Closed',
Prio => 1200,
Search => {
CustomerIDRaw =>
[ $UserObject->CustomerIDs( User => $Self->{UserLogin} ) ],
StateType => 'Closed',
OrderBy => $OrderByCurrent,
SortBy => $SortBy,
CustomerUserID => $Self->{UserID},
Permission => 'ro',
},
},
};
}
my $FilterCurrent = $ParamObject->GetParam( Param => 'Filter' ) || 'Open';
# check if filter is valid
if ( !$Filters{ $Self->{Subaction} }->{$FilterCurrent} ) {
my $Output = $LayoutObject->CustomerHeader(
Title => Translatable('Error'),
);
$Output .= $LayoutObject->CustomerError(
Message => $LayoutObject->{LanguageObject}->Translate( 'Invalid Filter: %s!', $FilterCurrent ),
);
$Output .= $LayoutObject->CustomerFooter();
return $Output;
}
# check if archive search is allowed, otherwise search for all tickets
my %SearchInArchive;
if (
$ConfigObject->Get('Ticket::ArchiveSystem')
&& !$ConfigObject->Get('Ticket::CustomerArchiveSystem')
)
{
$SearchInArchive{ArchiveFlags} = [ 'y', 'n' ];
}
my %NavBarFilter;
my $Counter = 0;
my $AllTickets = 0;
my $AllTicketsTotal = 0;
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
for my $Filter ( sort keys %{ $Filters{ $Self->{Subaction} } } ) {
$Counter++;
my $Count = $TicketObject->TicketSearch(
%{ $Filters{ $Self->{Subaction} }->{$Filter}->{Search} },
%SearchInArchive,
Result => 'COUNT',
);
my $ClassA = '';
if ( $Filter eq $FilterCurrent ) {
$ClassA = 'Selected';
$AllTickets = $Count;
}
if ( $Filter eq 'All' ) {
$AllTicketsTotal = $Count;
}
$NavBarFilter{ $Filters{ $Self->{Subaction} }->{$Filter}->{Prio} } = {
%{ $Filters{ $Self->{Subaction} }->{$Filter} },
Count => $Count,
Filter => $Filter,
ClassA => $ClassA,
};
}
my $StartHit = int( $ParamObject->GetParam( Param => 'StartHit' ) || 1 );
my $PageShown = $Self->{UserShowTickets} || 1;
if ( !$AllTicketsTotal ) {
$LayoutObject->Block(
Name => 'Empty',
);
my $CustomTexts = $ConfigObject->Get('Ticket::Frontend::CustomerTicketOverviewCustomEmptyText');
if ( ref $CustomTexts eq 'HASH' ) {
$LayoutObject->Block(
Name => 'EmptyCustom',
Data => $CustomTexts,
);
# only show button, if frontend module for NewTicket is registered
# and button text is configured
if (
ref $ConfigObject->Get('CustomerFrontend::Module')->{CustomerTicketMessage}
eq 'HASH'
&& defined $ConfigObject->Get('Ticket::Frontend::CustomerTicketOverviewCustomEmptyText')
->{Button}
)
{
$LayoutObject->Block(
Name => 'EmptyCustomButton',
Data => $CustomTexts,
);
}
}
else {
$LayoutObject->Block(
Name => 'EmptyDefault',
);
# only show button, if frontend module for NewTicket is registered
if (
ref $ConfigObject->Get('CustomerFrontend::Module')->{CustomerTicketMessage}
eq 'HASH'
)
{
$LayoutObject->Block(
Name => 'EmptyDefaultButton',
);
}
}
}
else {
# create & return output
my $Link = 'SortBy=' . $LayoutObject->Ascii2Html( Text => $SortBy )
. ';OrderBy=' . $LayoutObject->Ascii2Html( Text => $OrderByCurrent )
. ';Filter=' . $LayoutObject->Ascii2Html( Text => $FilterCurrent )
. ';Subaction=' . $LayoutObject->Ascii2Html( Text => $Self->{Subaction} )
. ';';
my %PageNav = $LayoutObject->PageNavBar(
Limit => 10000,
StartHit => $StartHit,
PageShown => $PageShown,
AllHits => $AllTickets,
Action => 'Action=CustomerTicketOverview',
Link => $Link,
IDPrefix => 'CustomerTicketOverview',
);
my $OrderBy = 'Down';
if ( $OrderByCurrent eq 'Down' ) {
$OrderBy = 'Up';
}
my $Sort = '';
my $StateSort = '';
my $TicketSort = '';
my $TitleSort = '';
my $AgeSort = '';
my $QueueSort = '';
my $OwnerSort = '';
# this sets the opposite to the $OrderBy
if ( $OrderBy eq 'Down' ) {
$Sort = 'SortAscending';
}
if ( $OrderBy eq 'Up' ) {
$Sort = 'SortDescending';
}
if ( $SortBy eq 'State' ) {
$StateSort = $Sort;
}
elsif ( $SortBy eq 'Ticket' ) {
$TicketSort = $Sort;
}
elsif ( $SortBy eq 'Title' ) {
$TitleSort = $Sort;
}
elsif ( $SortBy eq 'Age' ) {
$AgeSort = $Sort;
}
elsif ( $SortBy eq 'Queue' ) {
$QueueSort = $Sort;
}
elsif ( $SortBy eq 'Owner' ) {
$OwnerSort = $Sort;
}
$LayoutObject->Block(
Name => 'Filled',
Data => {
%Param,
%PageNav,
OrderBy => $OrderBy,
StateSort => $StateSort,
TicketSort => $TicketSort,
TitleSort => $TitleSort,
AgeSort => $AgeSort,
Filter => $FilterCurrent,
},
);
my $Owner = $ConfigObject->Get('Ticket::Frontend::CustomerTicketOverview')->{Owner};
my $Queue = $ConfigObject->Get('Ticket::Frontend::CustomerTicketOverview')->{Queue};
if ($Owner) {
$LayoutObject->Block(
Name => 'OverviewNavBarPageOwner',
Data => {
OrderBy => $OrderBy,
OwnerSort => $OwnerSort,
Filter => $FilterCurrent,
},
);
}
if ($Queue) {
$LayoutObject->Block(
Name => 'OverviewNavBarPageQueue',
Data => {
OrderBy => $OrderBy,
QueueSort => $QueueSort,
Filter => $FilterCurrent,
},
);
}
# show header filter
for my $Key ( sort keys %NavBarFilter ) {
$LayoutObject->Block(
Name => 'FilterHeader',
Data => {
%{ $NavBarFilter{$Key} },
},
);
}
# show footer filter - show only if more the one page is available
if ( $AllTickets > $PageShown ) {
$LayoutObject->Block(
Name => 'FilterFooter',
Data => {
%Param,
%PageNav,
},
);
}
for my $Key ( sort keys %NavBarFilter ) {
if ( $AllTickets > $PageShown ) {
$LayoutObject->Block(
Name => 'FilterFooterItem',
Data => {
%{ $NavBarFilter{$Key} },
},
);
}
}
# get the dynamic fields for this screen
my $DynamicFieldObject = $Kernel::OM->Get('Kernel::System::DynamicField');
my $BackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
# get dynamic field config for frontend module
my $DynamicFieldFilter = $ConfigObject->Get("Ticket::Frontend::CustomerTicketOverview")->{DynamicField};
my $DynamicField = $DynamicFieldObject->DynamicFieldListGet(
Valid => 1,
ObjectType => ['Ticket'],
FieldFilter => $DynamicFieldFilter || {},
);
# reduce the dynamic fields to only the ones that are desinged for customer interface
my @CustomerDynamicFields;
DYNAMICFIELD:
for my $DynamicFieldConfig ( @{$DynamicField} ) {
next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig);
my $IsCustomerInterfaceCapable = $BackendObject->HasBehavior(
DynamicFieldConfig => $DynamicFieldConfig,
Behavior => 'IsCustomerInterfaceCapable',
);
next DYNAMICFIELD if !$IsCustomerInterfaceCapable;
push @CustomerDynamicFields, $DynamicFieldConfig;
}
$DynamicField = \@CustomerDynamicFields;
# Dynamic fields
# cycle trough the activated Dynamic Fields for this screen
DYNAMICFIELD:
for my $DynamicFieldConfig ( @{$DynamicField} ) {
next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig);
my $Label = $DynamicFieldConfig->{Label};
# get field sortable condition
my $IsSortable = $BackendObject->HasBehavior(
DynamicFieldConfig => $DynamicFieldConfig,
Behavior => 'IsSortable',
);
if ($IsSortable) {
my $CSS = '';
if (
$SortBy
&& ( $SortBy eq ( 'DynamicField_' . $DynamicFieldConfig->{Name} ) )
)
{
if ( $OrderByCurrent && ( $OrderByCurrent eq 'Up' ) ) {
$OrderBy = 'Down';
$CSS .= ' SortDescending';
}
else {
$OrderBy = 'Up';
$CSS .= ' SortAscending';
}
}
$LayoutObject->Block(
Name => 'OverviewNavBarPageDynamicField',
Data => {
%Param,
CSS => $CSS,
},
);
$LayoutObject->Block(
Name => 'OverviewNavBarPageDynamicFieldSortable',
Data => {
%Param,
OrderBy => $OrderBy,
Label => $Label,
DynamicFieldName => $DynamicFieldConfig->{Name},
Filter => $FilterCurrent,
},
);
# example of dynamic fields order customization
$LayoutObject->Block(
Name => 'OverviewNavBarPageDynamicField_' . $DynamicFieldConfig->{Name},
Data => {
%Param,
CSS => $CSS,
},
);
$LayoutObject->Block(
Name => 'OverviewNavBarPageDynamicField_'
. $DynamicFieldConfig->{Name}
. '_Sortable',
Data => {
%Param,
OrderBy => $OrderBy,
Label => $Label,
DynamicFieldName => $DynamicFieldConfig->{Name},
Filter => $FilterCurrent,
},
);
}
else {
$LayoutObject->Block(
Name => 'OverviewNavBarPageDynamicField',
Data => {
%Param,
},
);
$LayoutObject->Block(
Name => 'OverviewNavBarPageDynamicFieldNotSortable',
Data => {
%Param,
Label => $Label,
},
);
# example of dynamic fields order customization
$LayoutObject->Block(
Name => 'OverviewNavBarPageDynamicField_' . $DynamicFieldConfig->{Name},
Data => {
%Param,
},
);
$LayoutObject->Block(
Name => 'OverviewNavBarPageDynamicField_'
. $DynamicFieldConfig->{Name}
. '_NotSortable',
Data => {
%Param,
Label => $Label,
},
);
}
}
my @ViewableTickets = $TicketObject->TicketSearch(
%{ $Filters{ $Self->{Subaction} }->{$FilterCurrent}->{Search} },
%SearchInArchive,
Result => 'ARRAY',
);
# show tickets
$Counter = 0;
for my $TicketID (@ViewableTickets) {
$Counter++;
if (
$Counter >= $StartHit
&& $Counter < ( $PageShown + $StartHit )
)
{
$Self->ShowTicketStatus( TicketID => $TicketID );
}
}
}
# create & return output
my $Title = $Self->{Subaction};
if ( $Title eq 'MyTickets' ) {
$Title = Translatable('My Tickets');
}
elsif ( $Title eq 'CompanyTickets' ) {
$Title = Translatable('Company Tickets');
}
my $Refresh = '';
if ( $Self->{UserRefreshTime} ) {
$Refresh = 60 * $Self->{UserRefreshTime};
}
my $Output = $LayoutObject->CustomerHeader(
Title => $Title,
Refresh => $Refresh,
);
# build NavigationBar
$Output .= $LayoutObject->CustomerNavigationBar();
$Output .= $LayoutObject->Output(
TemplateFile => 'CustomerTicketOverview',
Data => \%Param,
);
# get page footer
$Output .= $LayoutObject->CustomerFooter();
# return page
return $Output;
}
# ShowTicket
sub ShowTicketStatus {
my ( $Self, %Param ) = @_;
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
my $TicketID = $Param{TicketID} || return;
# contains last article (non-internal)
my %Article;
# get whole article index
my @ArticleIDs = $TicketObject->ArticleIndex( TicketID => $Param{TicketID} );
# get article data
if (@ArticleIDs) {
my %LastNonInternalArticle;
ARTICLEID:
for my $ArticleID ( reverse @ArticleIDs ) {
my %CurrentArticle = $TicketObject->ArticleGet( ArticleID => $ArticleID );
# check for non-internal and non-chat article
next ARTICLEID if $CurrentArticle{ArticleType} =~ m{internal|chat}smx;
# check for customer article
if ( $CurrentArticle{SenderType} eq 'customer' ) {
%Article = %CurrentArticle;
last ARTICLEID;
}
# check for last non-internal article (sender type does not matter)
if ( !%LastNonInternalArticle ) {
%LastNonInternalArticle = %CurrentArticle;
}
}
if ( !%Article && %LastNonInternalArticle ) {
%Article = %LastNonInternalArticle;
}
}
my $NoArticle;
if ( !%Article ) {
$NoArticle = 1;
}
# get ticket info
my %Ticket = $TicketObject->TicketGet(
TicketID => $TicketID,
DynamicFields => 0,
);
my $Subject;
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
my $SmallViewColumnHeader = $ConfigObject->Get('Ticket::Frontend::CustomerTicketOverview')->{ColumnHeader};
# check if last customer subject or ticket title should be shown
if ( $SmallViewColumnHeader eq 'LastCustomerSubject' ) {
$Subject = $Article{Subject} || '';
}
elsif ( $SmallViewColumnHeader eq 'TicketTitle' ) {
$Subject = $Ticket{Title};
}
# return ticket information if there is no article
if ($NoArticle) {
$Article{State} = $Ticket{State};
$Article{TicketNumber} = $Ticket{TicketNumber};
$Article{CustomerAge} = $LayoutObject->CustomerAge(
Age => $Ticket{Age},
Space => ' '
) || 0;
$Article{Body} = $LayoutObject->{LanguageObject}->Translate('This item has no articles yet.');
}
# otherwise return article information
else {
$Article{CustomerAge} = $LayoutObject->CustomerAge(
Age => $Article{Age},
Space => ' '
) || 0;
}
# customer info (customer name)
if ( $Article{CustomerUserID} ) {
$Param{CustomerName} = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerName(
UserLogin => $Article{CustomerUserID},
);
$Param{CustomerName} = '(' . $Param{CustomerName} . ')' if ( $Param{CustomerName} );
}
# if there is no subject try with Ticket title or set to Untitled
if ( !$Subject ) {
$Subject = $Ticket{Title} || Translatable('Untitled!');
}
# condense down the subject
$Subject = $TicketObject->TicketSubjectClean(
TicketNumber => $Article{TicketNumber},
Subject => $Subject,
);
$Param{CreatedBy} = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerName(
UserLogin => $Ticket{CreateBy},
);
# add block
$LayoutObject->Block(
Name => 'Record',
Data => {
%Article,
%Ticket,
Subject => $Subject,
%Param,
},
);
my $Owner = $ConfigObject->Get('Ticket::Frontend::CustomerTicketOverview')->{Owner};
my $Queue = $ConfigObject->Get('Ticket::Frontend::CustomerTicketOverview')->{Queue};
if ($Owner) {
my $OwnerName = $Kernel::OM->Get('Kernel::System::User')->UserName( UserID => $Ticket{OwnerID} );
$LayoutObject->Block(
Name => 'RecordOwner',
Data => {
OwnerName => $OwnerName,
},
);
}
if ($Queue) {
$LayoutObject->Block(
Name => 'RecordQueue',
Data => {
%Ticket,
},
);
}
# get the dynamic fields for this screen
my $DynamicFieldObject = $Kernel::OM->Get('Kernel::System::DynamicField');
my $BackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
# get dynamic field config for frontend module
my $DynamicFieldFilter = $ConfigObject->Get("Ticket::Frontend::CustomerTicketOverview")->{DynamicField};
my $DynamicField = $DynamicFieldObject->DynamicFieldListGet(
Valid => 1,
ObjectType => ['Ticket'],
FieldFilter => $DynamicFieldFilter || {},
);
# reduce the dynamic fields to only the ones that are desinged for customer interface
my @CustomerDynamicFields;
DYNAMICFIELD:
for my $DynamicFieldConfig ( @{$DynamicField} ) {
next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig);
my $IsCustomerInterfaceCapable = $BackendObject->HasBehavior(
DynamicFieldConfig => $DynamicFieldConfig,
Behavior => 'IsCustomerInterfaceCapable',
);
next DYNAMICFIELD if !$IsCustomerInterfaceCapable;
push @CustomerDynamicFields, $DynamicFieldConfig;
}
$DynamicField = \@CustomerDynamicFields;
# Dynamic fields
# cycle trough the activated Dynamic Fields for this screen
DYNAMICFIELD:
for my $DynamicFieldConfig ( @{$DynamicField} ) {
next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig);
# get field value
my $Value = $BackendObject->ValueGet(
DynamicFieldConfig => $DynamicFieldConfig,
ObjectID => $Ticket{TicketID},
);
my $ValueStrg = $BackendObject->DisplayValueRender(
DynamicFieldConfig => $DynamicFieldConfig,
Value => $Value,
ValueMaxChars => 20,
LayoutObject => $LayoutObject,
);
$LayoutObject->Block(
Name => 'RecordDynamicField',
Data => {
Value => $ValueStrg->{Value},
Title => $ValueStrg->{Title},
},
);
if ( $ValueStrg->{Link} ) {
$LayoutObject->Block(
Name => 'RecordDynamicFieldLink',
Data => {
Value => $ValueStrg->{Value},
Title => $ValueStrg->{Title},
Link => $ValueStrg->{Link},
$DynamicFieldConfig->{Name} => $ValueStrg->{Title},
},
);
}
else {
$LayoutObject->Block(
Name => 'RecordDynamicFieldPlain',
Data => {
Value => $ValueStrg->{Value},
Title => $ValueStrg->{Title},
},
);
}
# example of dynamic fields order customization
$LayoutObject->Block(
Name => 'RecordDynamicField' . $DynamicFieldConfig->{Name},
Data => {
Value => $ValueStrg->{Value},
Title => $ValueStrg->{Title},
},
);
if ( $ValueStrg->{Link} ) {
$LayoutObject->Block(
Name => 'RecordDynamicField' . $DynamicFieldConfig->{Name} . 'Link',
Data => {
Value => $ValueStrg->{Value},
Title => $ValueStrg->{Title},
Link => $ValueStrg->{Link},
$DynamicFieldConfig->{Name} => $ValueStrg->{Title},
},
);
}
else {
$LayoutObject->Block(
Name => 'RecordDynamicField' . $DynamicFieldConfig->{Name} . 'Plain',
Data => {
Value => $ValueStrg->{Value},
Title => $ValueStrg->{Title},
},
);
}
}
}
1;
OTRS 6.0.5
-
- Znuny guru
- Posts: 2210
- Joined: 13 Mar 2014, 09:16
- Znuny Version: 6.0.14
- Real Name: Rolf Straub
Re: Adding customer name in Customer ticket overview
Hey there,
so I tried to do this on my test system and ran into this problem: OTRS does not log the CustomerUser (ID) of the customer creating a ticket. Customer tickets are always created from "root@localhost" it seems.
To get the first customer user who created the ticket, I parsed the history lines and took the first CustomerUser which got set. To do so, use this code in your perl code INSTEAD of the one posted earlier (same position though):
On my test system this works.
Now, you said you don't see changes. Do you atleast see a new header in the table? Are you using Addons that might modify your frontend, especially KIX or something?
so I tried to do this on my test system and ran into this problem: OTRS does not log the CustomerUser (ID) of the customer creating a ticket. Customer tickets are always created from "root@localhost" it seems.
To get the first customer user who created the ticket, I parsed the history lines and took the first CustomerUser which got set. To do so, use this code in your perl code INSTEAD of the one posted earlier (same position though):
Code: Select all
my @HistoryLines = $TicketObject->HistoryGet(
TicketID => $Ticket{TicketID},
UserID => $Self->{UserID},
);
my @HistorySorted = sort { $a->{CreateTime} cmp $b->{CreateTime} } @HistoryLines;
my $FirstCustomerUser;
foreach my $Line ( @HistorySorted ) {
if ($Line->{Name} =~ m/CustomerID=.*CustomerUser=.*/ ) {
my @LineParts = split /[=;]+/, $Line->{Name};
$FirstCustomerUser = $LineParts[3];
last;
}
}
$Param{CreatedBy} = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerName(
UserLogin => $FirstCustomerUser,
);
Now, you said you don't see changes. Do you atleast see a new header in the table? Are you using Addons that might modify your frontend, especially KIX or something?
You do not have the required permissions to view the files attached to this post.
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
Re: Adding customer name in Customer ticket overview
Well, when I was first figuring out which file needed to be edited (either ~/Kernel/... or in ~/Custom/Kernel/...) it wasn't working when the modified file was in ~/Custom/Kernel/..., but then I copied those files to ~/Kernel/... and it showed an extra column, but with no data.
Since you replied that the custom pages need to be in the ~/Custom/Kernel/... directory, I haven't moved them from there, but now I do not see an extra column.
I'm not using any addons, the only custom thing about my OTRS installation is this
Thanks for helping me, I really appreciate it!
I'm gonna try your new script (I hope today) and I'll let you know.
Just to be sure, are my directories ok, I'm starting to doubt myself ?
[*]/opt/otrs/Custom/Kernel/Output/HTML/Templates/Standard/CustomerTicketOverview.tt
[*]/opt/otrs/Custom/Kernel/Modules/CustomerTicketOverview.pm
Since you replied that the custom pages need to be in the ~/Custom/Kernel/... directory, I haven't moved them from there, but now I do not see an extra column.
I'm not using any addons, the only custom thing about my OTRS installation is this
Thanks for helping me, I really appreciate it!
I'm gonna try your new script (I hope today) and I'll let you know.
Just to be sure, are my directories ok, I'm starting to doubt myself ?
[*]/opt/otrs/Custom/Kernel/Output/HTML/Templates/Standard/CustomerTicketOverview.tt
[*]/opt/otrs/Custom/Kernel/Modules/CustomerTicketOverview.pm
Last edited by JHS on 07 Aug 2017, 14:55, edited 2 times in total.
OTRS 6.0.5
Re: Adding customer name in Customer ticket overview
Hello
I've added your new code in the CustomerTicketOverview.pm file under ~/Custom/Kernel/...
I could not check it because there was no extra column added in the overview.
Just out of curiosity I copied my template from ~/Custom/Kernel/... to ~/Kernel/... and restarted apache, and now I can see the extra column: Out of more curiosity, I copied the .pm file from ~/Custom/Kernel/... to ~/Kernel/... and restarted apache, and now I can see exactly what I wanted:
So your new code works, but for some reason, OTRS does not seem to load the files in the ~/Custom/Kernel/... directory.
Any idea's why not?
I've already checked the files privileges, owned by OTRS and chmod 660 (for CustomerTicketOverview.tt and .pm)
Just to be sure, are my directories ok, I'm starting to doubt myself ?
EDIT:Nevermind, I found the issue, apparently the directories under the ~/otrs/Custom directory did not have the correct privileges.
Did a chmod 775 for all the directories under ~/otrs/Custom and then an apache restart and this fixed it!
So now I have what I wanted!
Thank you very much for assisting me in this matter!
I've added your new code in the CustomerTicketOverview.pm file under ~/Custom/Kernel/...
I could not check it because there was no extra column added in the overview.
Just out of curiosity I copied my template from ~/Custom/Kernel/... to ~/Kernel/... and restarted apache, and now I can see the extra column: Out of more curiosity, I copied the .pm file from ~/Custom/Kernel/... to ~/Kernel/... and restarted apache, and now I can see exactly what I wanted:
So your new code works, but for some reason, OTRS does not seem to load the files in the ~/Custom/Kernel/... directory.
Any idea's why not?
I've already checked the files privileges, owned by OTRS and chmod 660 (for CustomerTicketOverview.tt and .pm)
Just to be sure, are my directories ok, I'm starting to doubt myself ?
Code: Select all
/opt/otrs/Custom/Kernel/Output/HTML/Templates/Standard/CustomerTicketOverview.tt
/opt/otrs/Custom/Kernel/Modules/CustomerTicketOverview.pm
Did a chmod 775 for all the directories under ~/otrs/Custom and then an apache restart and this fixed it!
So now I have what I wanted!
Thank you very much for assisting me in this matter!
You do not have the required permissions to view the files attached to this post.
OTRS 6.0.5
-
- Znuny guru
- Posts: 2210
- Joined: 13 Mar 2014, 09:16
- Znuny Version: 6.0.14
- Real Name: Rolf Straub
Re: Adding customer name in Customer ticket overview
Yey, great it works!
Doesn't it feel good to hack the OTRS ?
Doesn't it feel good to hack the OTRS ?
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS
Re: Adding customer name in Customer ticket overview
Yeah, it does, once it works, its awesome!RStraub wrote:Yey, great it works!
Doesn't it feel good to hack the OTRS ?
OTRS 6.0.5
Re: Adding customer name in Customer ticket overview
I actually did notice something that might be handy for our customers. When they click the "createdby" header to sort, they are forwarded to the: "welcome, create your first ticket" page instead of sorting by the "createdby" value
Is there a way to add this function like with the default columns (state, age, etc...)?
Is there a way to add this function like with the default columns (state, age, etc...)?
OTRS 6.0.5
Re: Adding customer name in Customer ticket overview
Hi Guys,
I am having the same "problem". I would also like to insert 2 new columns,
Customer ticket owner(not creator of the ticket, but the customer owner of the ticket) and
Ticket creation date(Instead of ticket AGE).
Is this possible to do it?
Also when you said that the owner of all tickets is roos@localhost, how is then possible that in db table TICKET there is column CUSTOMER_USER_ID with the id of the customer?
Regards and thanks,
Savo
I am having the same "problem". I would also like to insert 2 new columns,
Customer ticket owner(not creator of the ticket, but the customer owner of the ticket) and
Ticket creation date(Instead of ticket AGE).
Is this possible to do it?
Also when you said that the owner of all tickets is roos@localhost, how is then possible that in db table TICKET there is column CUSTOMER_USER_ID with the id of the customer?
Regards and thanks,
Savo
-
- Znuny guru
- Posts: 2210
- Joined: 13 Mar 2014, 09:16
- Znuny Version: 6.0.14
- Real Name: Rolf Straub
Re: Adding customer name in Customer ticket overview
Hey savoir,
the db-column is the customer the ticket is ASSIGNED to. But it's not the customer that created the ticket. Since you can change customers after ticket creation these might be different values. That's why I parsed the history lines to see who the first customer is that got assigned.
Where are you struggling when inserting creation date and/or owner?
the db-column is the customer the ticket is ASSIGNED to. But it's not the customer that created the ticket. Since you can change customers after ticket creation these might be different values. That's why I parsed the history lines to see who the first customer is that got assigned.
Where are you struggling when inserting creation date and/or owner?
Currently using: OTRS 6.0.14 -- MariaDB -- Ubuntu 16 LTS