823 lines
27 KiB
Perl
823 lines
27 KiB
Perl
# --
|
|
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
|
# --
|
|
# 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 https://www.gnu.org/licenses/gpl-3.0.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 the company tickets are not disabled.
|
|
if ( !$DisableCompanyTickets ) {
|
|
my @CustomerIDs;
|
|
my %AccessibleCustomers = $Kernel::OM->Get('Kernel::System::CustomerGroup')->GroupContextCustomers(
|
|
CustomerUserID => $Self->{UserID},
|
|
);
|
|
|
|
# Show customer companies as additional filter selection.
|
|
if ( $Self->{Subaction} eq 'CompanyTickets' && scalar keys %AccessibleCustomers > 1 ) {
|
|
|
|
@CustomerIDs = $ParamObject->GetArray( Param => 'CustomerIDs' );
|
|
$Param{CustomerIDStrg} = $LayoutObject->BuildSelection(
|
|
Data => \%AccessibleCustomers,
|
|
Name => 'CustomerIDs',
|
|
Multiple => 1,
|
|
Size => 1,
|
|
SelectedID => \@CustomerIDs,
|
|
Class => 'Modernize',
|
|
);
|
|
|
|
# Remember the active customer ID filter.
|
|
$Param{CustomerIDs} = '';
|
|
for my $CustomerID (@CustomerIDs) {
|
|
$Param{CustomerIDs} .= ';CustomerIDs=' . $LayoutObject->LinkEncode($CustomerID);
|
|
}
|
|
}
|
|
else {
|
|
|
|
# Default behavior - use all available customer IDs.
|
|
@CustomerIDs = sort keys %AccessibleCustomers;
|
|
}
|
|
|
|
$Filters{CompanyTickets} = {
|
|
All => {
|
|
Name => 'All',
|
|
Prio => 1000,
|
|
Search => {
|
|
CustomerIDRaw => \@CustomerIDs,
|
|
OrderBy => $OrderByCurrent,
|
|
SortBy => $SortBy,
|
|
CustomerUserID => $Self->{UserID},
|
|
Permission => 'ro',
|
|
},
|
|
},
|
|
Open => {
|
|
Name => 'Open',
|
|
Prio => 1100,
|
|
Search => {
|
|
CustomerIDRaw => \@CustomerIDs,
|
|
StateType => 'Open',
|
|
OrderBy => $OrderByCurrent,
|
|
SortBy => $SortBy,
|
|
CustomerUserID => $Self->{UserID},
|
|
Permission => 'ro',
|
|
},
|
|
},
|
|
Closed => {
|
|
Name => 'Closed',
|
|
Prio => 1200,
|
|
Search => {
|
|
CustomerIDRaw => \@CustomerIDs,
|
|
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',
|
|
) || 0;
|
|
|
|
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 => {
|
|
%Param,
|
|
%{ $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 $ArticleObject = $Kernel::OM->Get('Kernel::System::Ticket::Article');
|
|
my $CommunicationChannelObject = $Kernel::OM->Get('Kernel::System::CommunicationChannel');
|
|
my $TicketID = $Param{TicketID} || return;
|
|
|
|
# Get last customer article.
|
|
my @ArticleList = $ArticleObject->ArticleList(
|
|
TicketID => $Param{TicketID},
|
|
IsVisibleForCustomer => 1,
|
|
OnlyLast => 1,
|
|
);
|
|
|
|
my %Article;
|
|
if ( $ArticleList[0] && IsHashRefWithData( $ArticleList[0] ) ) {
|
|
my $ArticleBackendObject = $ArticleObject->BackendForArticle( %{ $ArticleList[0] } );
|
|
%Article = $ArticleBackendObject->ArticleGet(
|
|
TicketID => $Param{TicketID},
|
|
ArticleID => $ArticleList[0]->{ArticleID},
|
|
);
|
|
}
|
|
|
|
# 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 the last customer subject or ticket title should be shown.
|
|
# If ticket title should be shown, check if there are articles, because ticket title
|
|
# could be related with a subject of an article which does not visible for customer (see bug#13614).
|
|
# If there is no subject, set to 'Untitled'.
|
|
if ( $SmallViewColumnHeader eq 'LastCustomerSubject' ) {
|
|
$Subject = $Article{Subject} || '';
|
|
}
|
|
elsif ( $SmallViewColumnHeader eq 'TicketTitle' && $ArticleList[0] ) {
|
|
$Subject = $Ticket{Title};
|
|
}
|
|
else {
|
|
$Subject = Translatable('Untitled!');
|
|
}
|
|
|
|
# Condense down the subject.
|
|
$Subject = $TicketObject->TicketSubjectClean(
|
|
TicketNumber => $Ticket{TicketNumber},
|
|
Subject => $Subject,
|
|
);
|
|
|
|
# Age design.
|
|
$Ticket{CustomerAge} = $LayoutObject->CustomerAge(
|
|
Age => $Ticket{Age},
|
|
Space => ' '
|
|
) || 0;
|
|
|
|
# return ticket information if there is no article
|
|
if ( !IsHashRefWithData( \%Article ) ) {
|
|
$Article{State} = $Ticket{State};
|
|
$Article{TicketNumber} = $Ticket{TicketNumber};
|
|
$Article{Body} = $LayoutObject->{LanguageObject}->Translate('This item has no articles yet.');
|
|
}
|
|
|
|
# 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} );
|
|
}
|
|
|
|
# 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},
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
1;
|