1102 lines
33 KiB
Perl
1102 lines
33 KiB
Perl
# --
|
|
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
|
# --
|
|
# $origin: otrs - b9cf29ede488bbc3bf5bd0d49f422ecc65668a0c - Kernel/Output/HTML/TicketOverview/Medium.pm
|
|
# --
|
|
# 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::Output::HTML::TicketOverview::Medium;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Kernel::System::VariableCheck qw(:all);
|
|
use Kernel::Language qw(Translatable);
|
|
|
|
our @ObjectDependencies = (
|
|
'Kernel::System::CustomerUser',
|
|
'Kernel::System::DynamicField',
|
|
'Kernel::System::DynamicField::Backend',
|
|
'Kernel::Config',
|
|
'Kernel::System::Group',
|
|
'Kernel::System::Log',
|
|
'Kernel::Output::HTML::Layout',
|
|
'Kernel::System::User',
|
|
'Kernel::System::Ticket',
|
|
'Kernel::System::Ticket::Article',
|
|
'Kernel::System::Main',
|
|
'Kernel::System::Queue'
|
|
);
|
|
|
|
sub new {
|
|
my ( $Type, %Param ) = @_;
|
|
|
|
# allocate new hash for object
|
|
my $Self = \%Param;
|
|
bless( $Self, $Type );
|
|
|
|
# get UserID param
|
|
$Self->{UserID} = $Param{UserID} || die "Got no UserID!";
|
|
# ---
|
|
# ITSMIncidentProblemManagement
|
|
# ---
|
|
|
|
# Check if ITSMIncidentProblemManagement is used.
|
|
my $OutputFilterConfig = $Kernel::OM->Get('Kernel::Config')->Get('Frontend::Output::FilterElementPost');
|
|
if ( $OutputFilterConfig->{ITSMIncidentProblemManagement} ) {
|
|
$Self->{ITSMIncidentProblemManagement} = 1;
|
|
}
|
|
# ---
|
|
|
|
return $Self;
|
|
}
|
|
|
|
sub ActionRow {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# get needed object
|
|
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
# check if bulk feature is enabled
|
|
my $BulkFeature = 0;
|
|
if ( $Param{Bulk} && $ConfigObject->Get('Ticket::Frontend::BulkFeature') ) {
|
|
my @Groups;
|
|
if ( $ConfigObject->Get('Ticket::Frontend::BulkFeatureGroup') ) {
|
|
@Groups = @{ $ConfigObject->Get('Ticket::Frontend::BulkFeatureGroup') };
|
|
}
|
|
if ( !@Groups ) {
|
|
$BulkFeature = 1;
|
|
}
|
|
else {
|
|
my $GroupObject = $Kernel::OM->Get('Kernel::System::Group');
|
|
GROUP:
|
|
for my $Group (@Groups) {
|
|
my $HasPermission = $GroupObject->PermissionCheck(
|
|
UserID => $Self->{UserID},
|
|
GroupName => $Group,
|
|
Type => 'rw',
|
|
);
|
|
if ($HasPermission) {
|
|
$BulkFeature = 1;
|
|
last GROUP;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'DocumentActionRow',
|
|
Data => \%Param,
|
|
);
|
|
|
|
if ($BulkFeature) {
|
|
$LayoutObject->Block(
|
|
Name => 'DocumentActionRowBulk',
|
|
Data => {
|
|
%Param,
|
|
Name => Translatable('Bulk'),
|
|
},
|
|
);
|
|
}
|
|
|
|
# run ticket overview document item menu modules
|
|
if (
|
|
$Param{Config}->{OverviewMenuModules}
|
|
&& ref $ConfigObject->Get('Ticket::Frontend::OverviewMenuModule') eq 'HASH'
|
|
)
|
|
{
|
|
|
|
my %Menus = %{ $ConfigObject->Get('Ticket::Frontend::OverviewMenuModule') };
|
|
MENUMODULE:
|
|
for my $Menu ( sort keys %Menus ) {
|
|
|
|
next MENUMODULE if !IsHashRefWithData( $Menus{$Menu} );
|
|
next MENUMODULE if ( $Menus{$Menu}->{View} && $Menus{$Menu}->{View} ne $Param{View} );
|
|
|
|
# load module
|
|
if ( !$Kernel::OM->Get('Kernel::System::Main')->Require( $Menus{$Menu}->{Module} ) ) {
|
|
return $LayoutObject->FatalError();
|
|
}
|
|
my $Object = $Menus{$Menu}->{Module}->new( %{$Self} );
|
|
|
|
# run module
|
|
my $Item = $Object->Run(
|
|
%Param,
|
|
Config => $Menus{$Menu},
|
|
);
|
|
next MENUMODULE if !IsHashRefWithData($Item);
|
|
|
|
if ( $Item->{Block} eq 'DocumentActionRowItem' ) {
|
|
|
|
# add session id if needed
|
|
if ( !$LayoutObject->{SessionIDCookie} && $Item->{Link} ) {
|
|
$Item->{Link}
|
|
.= ';'
|
|
. $LayoutObject->{SessionName} . '='
|
|
. $LayoutObject->{SessionID};
|
|
}
|
|
|
|
# create id
|
|
$Item->{ID} = $Item->{Name};
|
|
$Item->{ID} =~ s/(\s|&|;)//ig;
|
|
|
|
my $Link = $Item->{Link};
|
|
if ( $Item->{Target} ) {
|
|
$Link = '#';
|
|
}
|
|
|
|
my $Class = '';
|
|
if ( $Item->{PopupType} ) {
|
|
$Class = 'AsPopup PopupType_' . $Item->{PopupType};
|
|
}
|
|
|
|
$LayoutObject->Block(
|
|
Name => $Item->{Block},
|
|
Data => {
|
|
ID => $Item->{ID},
|
|
Name => $LayoutObject->{LanguageObject}->Translate( $Item->{Name} ),
|
|
Link => $LayoutObject->{Baselink} . $Item->{Link},
|
|
Description => $Item->{Description},
|
|
Block => $Item->{Block},
|
|
Class => $Class,
|
|
},
|
|
);
|
|
}
|
|
elsif ( $Item->{Block} eq 'DocumentActionRowHTML' ) {
|
|
|
|
next MENUMODULE if !$Item->{HTML};
|
|
|
|
$LayoutObject->Block(
|
|
Name => $Item->{Block},
|
|
Data => $Item,
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
my $Output = $LayoutObject->Output(
|
|
TemplateFile => 'AgentTicketOverviewMedium',
|
|
Data => \%Param,
|
|
);
|
|
|
|
return $Output;
|
|
}
|
|
|
|
sub SortOrderBar {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
return '';
|
|
}
|
|
|
|
sub Run {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
for my $Item (qw(TicketIDs PageShown StartHit)) {
|
|
if ( !$Param{$Item} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $Item!",
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
# get needed object
|
|
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
# check if bulk feature is enabled
|
|
my $BulkFeature = 0;
|
|
if ( $Param{Bulk} && $ConfigObject->Get('Ticket::Frontend::BulkFeature') ) {
|
|
my @Groups;
|
|
if ( $ConfigObject->Get('Ticket::Frontend::BulkFeatureGroup') ) {
|
|
@Groups = @{ $ConfigObject->Get('Ticket::Frontend::BulkFeatureGroup') };
|
|
}
|
|
if ( !@Groups ) {
|
|
$BulkFeature = 1;
|
|
}
|
|
else {
|
|
my $GroupObject = $Kernel::OM->Get('Kernel::System::Group');
|
|
GROUP:
|
|
for my $Group (@Groups) {
|
|
my $HasPermission = $GroupObject->PermissionCheck(
|
|
UserID => $Self->{UserID},
|
|
GroupName => $Group,
|
|
Type => 'rw',
|
|
);
|
|
if ($HasPermission) {
|
|
$BulkFeature = 1;
|
|
last GROUP;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'DocumentHeader',
|
|
Data => \%Param,
|
|
);
|
|
|
|
my $OutputMeta = $LayoutObject->Output(
|
|
TemplateFile => 'AgentTicketOverviewMedium',
|
|
Data => \%Param,
|
|
);
|
|
my $OutputRaw = '';
|
|
if ( !$Param{Output} ) {
|
|
$LayoutObject->Print( Output => \$OutputMeta );
|
|
}
|
|
else {
|
|
$OutputRaw .= $OutputMeta;
|
|
}
|
|
my $Output = '';
|
|
my $Counter = 0;
|
|
my $CounterOnSite = 0;
|
|
my @TicketIDsShown;
|
|
|
|
# check if there are tickets to show
|
|
if ( scalar @{ $Param{TicketIDs} } ) {
|
|
|
|
for my $TicketID ( @{ $Param{TicketIDs} } ) {
|
|
$Counter++;
|
|
if (
|
|
$Counter >= $Param{StartHit}
|
|
&& $Counter < ( $Param{PageShown} + $Param{StartHit} )
|
|
)
|
|
{
|
|
push @TicketIDsShown, $TicketID;
|
|
my $Output = $Self->_Show(
|
|
TicketID => $TicketID,
|
|
Counter => $CounterOnSite,
|
|
Bulk => $BulkFeature,
|
|
Config => $Param{Config},
|
|
);
|
|
$CounterOnSite++;
|
|
if ( !$Param{Output} ) {
|
|
$LayoutObject->Print( Output => $Output );
|
|
}
|
|
else {
|
|
$OutputRaw .= ${$Output};
|
|
}
|
|
}
|
|
}
|
|
|
|
# send data to JS
|
|
$LayoutObject->AddJSData(
|
|
Key => 'ActionRowTickets',
|
|
Value => $Self->{ActionRowTickets},
|
|
);
|
|
}
|
|
else {
|
|
$LayoutObject->Block( Name => 'NoTicketFound' );
|
|
}
|
|
|
|
# check if bulk feature is enabled
|
|
if ($BulkFeature) {
|
|
$LayoutObject->Block(
|
|
Name => 'DocumentFooter',
|
|
Data => \%Param,
|
|
);
|
|
for my $TicketID (@TicketIDsShown) {
|
|
$LayoutObject->Block(
|
|
Name => 'DocumentFooterBulkItem',
|
|
Data => \%Param,
|
|
);
|
|
}
|
|
my $OutputMeta = $LayoutObject->Output(
|
|
TemplateFile => 'AgentTicketOverviewMedium',
|
|
Data => \%Param,
|
|
);
|
|
if ( !$Param{Output} ) {
|
|
$LayoutObject->Print( Output => \$OutputMeta );
|
|
}
|
|
else {
|
|
$OutputRaw .= $OutputMeta;
|
|
}
|
|
}
|
|
|
|
# add action row js data
|
|
|
|
return $OutputRaw;
|
|
}
|
|
|
|
sub _Show {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
if ( !$Param{TicketID} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => 'Need TicketID!',
|
|
);
|
|
return;
|
|
}
|
|
|
|
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');
|
|
|
|
# Get last customer article.
|
|
my @Articles = $ArticleObject->ArticleList(
|
|
TicketID => $Param{TicketID},
|
|
SenderType => 'customer',
|
|
OnlyLast => 1,
|
|
);
|
|
|
|
# If the ticket has no customer article, get the last agent article.
|
|
if ( !@Articles ) {
|
|
@Articles = $ArticleObject->ArticleList(
|
|
TicketID => $Param{TicketID},
|
|
SenderType => 'agent',
|
|
OnlyLast => 1,
|
|
);
|
|
}
|
|
|
|
# Finally, if everything failed, get latest article.
|
|
if ( !@Articles ) {
|
|
@Articles = $ArticleObject->ArticleList(
|
|
TicketID => $Param{TicketID},
|
|
OnlyLast => 1,
|
|
);
|
|
}
|
|
|
|
my %Article;
|
|
for my $Article (@Articles) {
|
|
%Article = $ArticleObject->BackendForArticle( %{$Article} )->ArticleGet(
|
|
%{$Article},
|
|
DynamicFields => 0,
|
|
);
|
|
|
|
my %ArticleFields = $LayoutObject->ArticleFields(
|
|
%{$Article},
|
|
);
|
|
|
|
$Article{ArticleFields} = \%ArticleFields;
|
|
}
|
|
|
|
# Get ticket data.
|
|
my %Ticket = $TicketObject->TicketGet(
|
|
TicketID => $Param{TicketID},
|
|
# ---
|
|
# ITSMIncidentProblemManagement
|
|
# ---
|
|
# DynamicFields => 0,
|
|
DynamicFields => 1,
|
|
# ---
|
|
);
|
|
|
|
%Article = ( %Article, %Ticket );
|
|
|
|
# Fallback for tickets without articles: get at least basic ticket data.
|
|
if ( !%Article ) {
|
|
%Article = %Ticket;
|
|
if ( !$Article{Title} ) {
|
|
$Article{Title} = $LayoutObject->{LanguageObject}->Translate(
|
|
'This ticket has no title or subject'
|
|
);
|
|
}
|
|
$Article{Subject} = $Article{Title};
|
|
}
|
|
|
|
# show ticket create time in current view
|
|
$Article{Created} = $Ticket{Created};
|
|
# ---
|
|
# ITSMIncidentProblemManagement
|
|
# ---
|
|
# set criticality and impact
|
|
$Article{Criticality} = $Article{DynamicField_ITSMCriticality} || '-';
|
|
$Article{Impact} = $Article{DynamicField_ITSMImpact} || '-';
|
|
# ---
|
|
|
|
# user info
|
|
my %UserInfo = $Kernel::OM->Get('Kernel::System::User')->GetUserData(
|
|
UserID => $Article{OwnerID},
|
|
);
|
|
%Article = ( %UserInfo, %Article );
|
|
|
|
# get responsible info from Ticket
|
|
my %TicketResponsible = $Kernel::OM->Get('Kernel::System::User')->GetUserData(
|
|
UserID => $Ticket{ResponsibleID},
|
|
);
|
|
|
|
# create human age
|
|
$Article{Age} = $LayoutObject->CustomerAge(
|
|
Age => $Article{Age},
|
|
Space => ' ',
|
|
);
|
|
|
|
# fetch all std. templates ...
|
|
my %StandardTemplates = $Kernel::OM->Get('Kernel::System::Queue')->QueueStandardTemplateMemberList(
|
|
QueueID => $Article{QueueID},
|
|
TemplateTypes => 1,
|
|
);
|
|
|
|
$Param{StandardResponsesStrg} = $LayoutObject->BuildSelection(
|
|
Name => 'ResponseID',
|
|
Data => $StandardTemplates{Answer} || {},
|
|
);
|
|
|
|
# customer info
|
|
if ( $Param{Config}->{CustomerInfo} ) {
|
|
if ( $Article{CustomerUserID} ) {
|
|
$Article{CustomerName} = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerName(
|
|
UserLogin => $Article{CustomerUserID},
|
|
);
|
|
}
|
|
}
|
|
|
|
# get ACL restrictions
|
|
my %PossibleActions;
|
|
my $Counter = 0;
|
|
|
|
# get config object
|
|
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
|
|
|
# get all registered Actions
|
|
if ( ref $ConfigObject->Get('Frontend::Module') eq 'HASH' ) {
|
|
|
|
my %Actions = %{ $ConfigObject->Get('Frontend::Module') };
|
|
|
|
# only use those Actions that stats with AgentTicket
|
|
%PossibleActions = map { ++$Counter => $_ }
|
|
grep { substr( $_, 0, length 'AgentTicket' ) eq 'AgentTicket' }
|
|
sort keys %Actions;
|
|
}
|
|
|
|
my $ACL = $TicketObject->TicketAcl(
|
|
Data => \%PossibleActions,
|
|
Action => $Self->{Action},
|
|
TicketID => $Article{TicketID},
|
|
ReturnType => 'Action',
|
|
ReturnSubType => '-',
|
|
UserID => $Self->{UserID},
|
|
);
|
|
|
|
my %AclAction = %PossibleActions;
|
|
if ($ACL) {
|
|
%AclAction = $TicketObject->TicketAclActionData();
|
|
}
|
|
|
|
# get main object
|
|
my $MainObject = $Kernel::OM->Get('Kernel::System::Main');
|
|
|
|
# run ticket pre menu modules
|
|
my @ActionItems;
|
|
if ( ref $ConfigObject->Get('Ticket::Frontend::PreMenuModule') eq 'HASH' ) {
|
|
my %Menus = %{ $ConfigObject->Get('Ticket::Frontend::PreMenuModule') };
|
|
MENU:
|
|
for my $Menu ( sort keys %Menus ) {
|
|
|
|
# load module
|
|
if ( !$MainObject->Require( $Menus{$Menu}->{Module} ) ) {
|
|
return $LayoutObject->FatalError();
|
|
}
|
|
my $Object = $Menus{$Menu}->{Module}->new(
|
|
%{$Self},
|
|
TicketID => $Param{TicketID},
|
|
);
|
|
|
|
# run module
|
|
my $Item = $Object->Run(
|
|
%Param,
|
|
Ticket => \%Article,
|
|
ACL => \%AclAction,
|
|
Config => $Menus{$Menu},
|
|
);
|
|
next MENU if !$Item;
|
|
next MENU if ref $Item ne 'HASH';
|
|
|
|
# add session id if needed
|
|
if ( !$LayoutObject->{SessionIDCookie} && $Item->{Link} ) {
|
|
$Item->{Link}
|
|
.= ';'
|
|
. $LayoutObject->{SessionName} . '='
|
|
. $LayoutObject->{SessionID};
|
|
}
|
|
|
|
# create id
|
|
$Item->{ID} = $Item->{Name};
|
|
$Item->{ID} =~ s/(\s|&|;)//ig;
|
|
|
|
my $Output;
|
|
if ( $Item->{Block} ) {
|
|
$LayoutObject->Block(
|
|
Name => $Item->{Block},
|
|
Data => $Item,
|
|
);
|
|
$Output = $LayoutObject->Output(
|
|
TemplateFile => 'AgentTicketOverviewMedium',
|
|
Data => $Item,
|
|
);
|
|
}
|
|
else {
|
|
$Output = '<li id="'
|
|
. $Item->{ID}
|
|
. '"><a href="#" title="'
|
|
. $LayoutObject->{LanguageObject}->Translate( $Item->{Description} )
|
|
. '">'
|
|
. $LayoutObject->{LanguageObject}->Translate( $Item->{Name} )
|
|
. '</a></li>';
|
|
}
|
|
|
|
$Output =~ s/\n+//g;
|
|
$Output =~ s/\s+/ /g;
|
|
$Output =~ s/<\!--.+?-->//g;
|
|
|
|
push @ActionItems, {
|
|
HTML => $Output,
|
|
ID => $Item->{ID},
|
|
Name => $Item->{Name},
|
|
Link => $LayoutObject->{Baselink} . $Item->{Link},
|
|
Target => $Item->{Target},
|
|
PopupType => $Item->{PopupType},
|
|
Description => $Item->{Description},
|
|
Block => $Item->{Block},
|
|
};
|
|
}
|
|
}
|
|
|
|
# prepare subject
|
|
$Article{Subject} = $TicketObject->TicketSubjectClean(
|
|
TicketNumber => $Article{TicketNumber},
|
|
Subject => $Article{Subject} || '',
|
|
);
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'DocumentContent',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
# ---
|
|
# ITSMIncidentProblemManagement
|
|
# ---
|
|
ITSMIncidentProblemManagement => $Self->{ITSMIncidentProblemManagement},
|
|
# ---
|
|
},
|
|
);
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'OwnerResponsible',
|
|
Data => {
|
|
Owner => $UserInfo{'UserLogin'},
|
|
OwnerFullname => $UserInfo{'UserFullname'},
|
|
Responsible => $TicketResponsible{'UserLogin'},
|
|
ResponsibleFullname => $TicketResponsible{'UserFullname'},
|
|
},
|
|
);
|
|
|
|
# if "Actions per Ticket" (Inline Action Row) is active
|
|
if ( $Param{Config}->{TicketActionsPerTicket} ) {
|
|
$LayoutObject->Block(
|
|
Name => 'InlineActionRow',
|
|
Data => \%Param,
|
|
);
|
|
|
|
# Add list entries for every action
|
|
for my $Item (@ActionItems) {
|
|
my $Link = $Item->{Link};
|
|
if ( $Item->{Target} ) {
|
|
$Link = '#';
|
|
}
|
|
|
|
my $Class = '';
|
|
if ( $Item->{PopupType} ) {
|
|
$Class = 'AsPopup PopupType_' . $Item->{PopupType};
|
|
}
|
|
|
|
if ( !$Item->{Block} ) {
|
|
$LayoutObject->Block(
|
|
Name => 'InlineActionRowItem',
|
|
Data => {
|
|
TicketID => $Param{TicketID},
|
|
QueueID => $Article{QueueID},
|
|
ID => $Item->{ID},
|
|
Name => $Item->{Name},
|
|
Description => $Item->{Description},
|
|
Class => $Class,
|
|
Link => $Link,
|
|
},
|
|
);
|
|
}
|
|
else {
|
|
my $TicketID = $Param{TicketID};
|
|
my $SelectHTML = $Item->{HTML};
|
|
$SelectHTML =~ s/id="DestQueueID"/id="DestQueueID$TicketID"/xmig;
|
|
$SelectHTML =~ s/for="DestQueueID"/for="DestQueueID$TicketID"/xmig;
|
|
$LayoutObject->Block(
|
|
Name => 'InlineActionRowItemHTML',
|
|
Data => {
|
|
HTML => $SelectHTML,
|
|
},
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
# check if bulk feature is enabled
|
|
if ( $Param{Bulk} ) {
|
|
$LayoutObject->Block(
|
|
Name => Translatable('Bulk'),
|
|
Data => \%Param,
|
|
);
|
|
}
|
|
|
|
# show ticket flags
|
|
my @TicketMetaItems = $LayoutObject->TicketMetaItems(
|
|
Ticket => \%Article,
|
|
);
|
|
for my $Item (@TicketMetaItems) {
|
|
$LayoutObject->Block(
|
|
Name => 'Meta',
|
|
Data => $Item,
|
|
);
|
|
if ($Item) {
|
|
$LayoutObject->Block(
|
|
Name => 'MetaIcon',
|
|
Data => $Item,
|
|
);
|
|
}
|
|
}
|
|
|
|
# run article modules
|
|
if ( $Article{ArticleID} ) {
|
|
if ( ref $ConfigObject->Get('Ticket::Frontend::ArticlePreViewModule') eq 'HASH' ) {
|
|
my %Jobs = %{ $ConfigObject->Get('Ticket::Frontend::ArticlePreViewModule') };
|
|
for my $Job ( sort keys %Jobs ) {
|
|
|
|
# load module
|
|
if ( !$MainObject->Require( $Jobs{$Job}->{Module} ) ) {
|
|
return $LayoutObject->FatalError();
|
|
}
|
|
my $Object = $Jobs{$Job}->{Module}->new(
|
|
%{$Self},
|
|
ArticleID => $Article{ArticleID},
|
|
UserID => $Self->{UserID},
|
|
Debug => $Self->{Debug},
|
|
);
|
|
|
|
# run module
|
|
my @Data = $Object->Check(
|
|
Article => \%Article,
|
|
%Param,
|
|
Config => $Jobs{$Job},
|
|
);
|
|
|
|
for my $DataRef (@Data) {
|
|
$LayoutObject->Block(
|
|
Name => 'ArticleOption',
|
|
Data => $DataRef,
|
|
);
|
|
}
|
|
|
|
# filter option
|
|
$Object->Filter(
|
|
Article => \%Article,
|
|
%Param,
|
|
Config => $Jobs{$Job},
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
# create output
|
|
$LayoutObject->Block(
|
|
Name => 'AgentAnswer',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
%AclAction,
|
|
},
|
|
);
|
|
if (
|
|
$ConfigObject->Get('Frontend::Module')->{AgentTicketCompose}
|
|
&& ( !defined $AclAction{AgentTicketCompose} || $AclAction{AgentTicketCompose} )
|
|
)
|
|
{
|
|
my $Access = 1;
|
|
my $Config = $ConfigObject->Get("Ticket::Frontend::AgentTicketCompose");
|
|
if ( $Config->{Permission} ) {
|
|
my $Ok = $TicketObject->TicketPermission(
|
|
Type => $Config->{Permission},
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Self->{UserID},
|
|
LogNo => 1,
|
|
);
|
|
if ( !$Ok ) {
|
|
$Access = 0;
|
|
}
|
|
if ($Access) {
|
|
$LayoutObject->Block(
|
|
Name => 'AgentAnswerCompose',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
%AclAction,
|
|
},
|
|
);
|
|
}
|
|
}
|
|
}
|
|
if (
|
|
$ConfigObject->Get('Frontend::Module')->{AgentTicketPhoneOutbound}
|
|
&& (
|
|
!defined $AclAction{AgentTicketPhoneOutbound}
|
|
|| $AclAction{AgentTicketPhoneOutbound}
|
|
)
|
|
)
|
|
{
|
|
my $Access = 1;
|
|
my $Config = $ConfigObject->Get("Ticket::Frontend::AgentTicketPhoneOutbound");
|
|
if ( $Config->{Permission} ) {
|
|
my $OK = $TicketObject->TicketPermission(
|
|
Type => $Config->{Permission},
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Self->{UserID},
|
|
LogNo => 1,
|
|
);
|
|
if ( !$OK ) {
|
|
$Access = 0;
|
|
}
|
|
}
|
|
if ($Access) {
|
|
$LayoutObject->Block(
|
|
Name => 'AgentAnswerPhoneOutbound',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
%AclAction,
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
# ticket type
|
|
if ( $ConfigObject->Get('Ticket::Type') ) {
|
|
$LayoutObject->Block(
|
|
Name => 'Type',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
},
|
|
);
|
|
}
|
|
|
|
# ticket service
|
|
if ( $ConfigObject->Get('Ticket::Service') && $Article{Service} ) {
|
|
$LayoutObject->Block(
|
|
Name => 'Service',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
},
|
|
);
|
|
if ( $Article{SLA} ) {
|
|
$LayoutObject->Block(
|
|
Name => 'SLA',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
# show first response time if needed
|
|
if ( defined $Article{FirstResponseTime} ) {
|
|
$Article{FirstResponseTimeHuman} = $LayoutObject->CustomerAge(
|
|
Age => $Article{FirstResponseTime},
|
|
TimeShowAlwaysLong => 1,
|
|
Space => ' ',
|
|
);
|
|
$Article{FirstResponseTimeWorkingTime} = $LayoutObject->CustomerAge(
|
|
Age => $Article{FirstResponseTimeWorkingTime},
|
|
TimeShowAlwaysLong => 1,
|
|
Space => ' ',
|
|
);
|
|
if ( 60 * 60 * 1 > $Article{FirstResponseTime} ) {
|
|
$Article{FirstResponseTimeClass} = 'Warning';
|
|
}
|
|
$LayoutObject->Block(
|
|
Name => 'FirstResponseTime',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
},
|
|
);
|
|
}
|
|
|
|
# show update time if needed
|
|
if ( defined $Article{UpdateTime} ) {
|
|
$Article{UpdateTimeHuman} = $LayoutObject->CustomerAge(
|
|
Age => $Article{UpdateTime},
|
|
TimeShowAlwaysLong => 1,
|
|
Space => ' ',
|
|
);
|
|
$Article{UpdateTimeWorkingTime} = $LayoutObject->CustomerAge(
|
|
Age => $Article{UpdateTimeWorkingTime},
|
|
TimeShowAlwaysLong => 1,
|
|
Space => ' ',
|
|
);
|
|
if ( 60 * 60 * 1 > $Article{UpdateTime} ) {
|
|
$Article{UpdateTimeClass} = 'Warning';
|
|
}
|
|
$LayoutObject->Block(
|
|
Name => 'UpdateTime',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
},
|
|
);
|
|
}
|
|
|
|
# show solution time if needed
|
|
if ( defined $Article{SolutionTime} ) {
|
|
$Article{SolutionTimeHuman} = $LayoutObject->CustomerAge(
|
|
Age => $Article{SolutionTime},
|
|
TimeShowAlwaysLong => 1,
|
|
Space => ' ',
|
|
);
|
|
$Article{SolutionTimeWorkingTime} = $LayoutObject->CustomerAge(
|
|
Age => $Article{SolutionTimeWorkingTime},
|
|
TimeShowAlwaysLong => 1,
|
|
Space => ' ',
|
|
);
|
|
if ( 60 * 60 * 1 > $Article{SolutionTime} ) {
|
|
$Article{SolutionTimeClass} = 'Warning';
|
|
}
|
|
$LayoutObject->Block(
|
|
Name => 'SolutionTime',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
},
|
|
);
|
|
}
|
|
|
|
# Dynamic fields
|
|
$Counter = 0;
|
|
my $DisplayDynamicFieldTable = 1;
|
|
|
|
# get dynamic field config for frontend module
|
|
my $DynamicFieldFilter
|
|
= $Kernel::OM->Get('Kernel::Config')->Get("Ticket::Frontend::OverviewMedium")->{DynamicField};
|
|
|
|
# get the dynamic fields for this screen
|
|
my $DynamicField = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldListGet(
|
|
Valid => 1,
|
|
ObjectType => ['Ticket'],
|
|
FieldFilter => $DynamicFieldFilter || {},
|
|
);
|
|
|
|
# cycle trough the activated Dynamic Fields for this screen
|
|
DYNAMICFIELD:
|
|
for my $DynamicFieldConfig ( @{$DynamicField} ) {
|
|
next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig);
|
|
|
|
# get dynamic field backend object
|
|
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
|
|
|
|
# get field value
|
|
my $Value = $DynamicFieldBackendObject->ValueGet(
|
|
DynamicFieldConfig => $DynamicFieldConfig,
|
|
ObjectID => $Param{TicketID},
|
|
);
|
|
|
|
next DYNAMICFIELD if ( !defined $Value );
|
|
|
|
$Counter++;
|
|
|
|
my $ValueStrg = $DynamicFieldBackendObject->DisplayValueRender(
|
|
DynamicFieldConfig => $DynamicFieldConfig,
|
|
Value => $Value,
|
|
ValueMaxChars => 20,
|
|
LayoutObject => $LayoutObject,
|
|
);
|
|
|
|
my $Label = $DynamicFieldConfig->{Label};
|
|
|
|
# show dynamic field table if at least one field is displayed
|
|
if ( $DisplayDynamicFieldTable == 1 ) {
|
|
$LayoutObject->Block(
|
|
Name => 'DynamicFieldTable',
|
|
Data => {},
|
|
);
|
|
$DisplayDynamicFieldTable = 0;
|
|
}
|
|
|
|
# create a new row if counter is starting
|
|
if ( $Counter == 1 ) {
|
|
$LayoutObject->Block(
|
|
Name => 'DynamicFieldTableRow',
|
|
Data => {},
|
|
);
|
|
}
|
|
|
|
# outout dynamic field label
|
|
$LayoutObject->Block(
|
|
Name => 'DynamicFieldTableRowRecord',
|
|
Data => {
|
|
Label => $Label,
|
|
},
|
|
);
|
|
|
|
if ( $ValueStrg->{Link} ) {
|
|
|
|
# outout dynamic field value link
|
|
$LayoutObject->Block(
|
|
Name => 'DynamicFieldTableRowRecordLink',
|
|
Data => {
|
|
Value => $ValueStrg->{Value},
|
|
Title => $ValueStrg->{Title},
|
|
Link => $ValueStrg->{Link},
|
|
$DynamicFieldConfig->{Name} => $ValueStrg->{Title},
|
|
},
|
|
);
|
|
}
|
|
else {
|
|
|
|
# outout dynamic field value plain
|
|
$LayoutObject->Block(
|
|
Name => 'DynamicFieldTableRowRecordPlain',
|
|
Data => {
|
|
Value => $ValueStrg->{Value},
|
|
Title => $ValueStrg->{Title},
|
|
},
|
|
);
|
|
}
|
|
|
|
# only 5 dynamic fields by row are allowed, reset couter if needed
|
|
if ( $Counter == 5 ) {
|
|
$Counter = 0;
|
|
}
|
|
|
|
# example of dynamic fields order customization
|
|
# outout dynamic field label
|
|
$LayoutObject->Block(
|
|
Name => 'DynamicFieldTableRowRecord' . $DynamicFieldConfig->{Name},
|
|
Data => {
|
|
Label => $Label,
|
|
},
|
|
);
|
|
|
|
if ( $ValueStrg->{Link} ) {
|
|
|
|
# outout dynamic field value link
|
|
$LayoutObject->Block(
|
|
Name => 'DynamicFieldTableRowRecord' . $DynamicFieldConfig->{Name} . 'Link',
|
|
Data => {
|
|
Value => $ValueStrg->{Value},
|
|
Title => $ValueStrg->{Title},
|
|
Link => $ValueStrg->{Link},
|
|
$DynamicFieldConfig->{Name} => $ValueStrg->{Title},
|
|
},
|
|
);
|
|
}
|
|
else {
|
|
|
|
# outout dynamic field value plain
|
|
$LayoutObject->Block(
|
|
Name => 'DynamicFieldTableRowRecord' . $DynamicFieldConfig->{Name} . 'Plain',
|
|
Data => {
|
|
Value => $ValueStrg->{Value},
|
|
Title => $ValueStrg->{Title},
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
# fill the rest of the Dynamic Fields row with empty cells, this will look better
|
|
if ( $Counter > 0 && $Counter < 5 ) {
|
|
|
|
for ( $Counter + 1 ... 5 ) {
|
|
|
|
# outout dynamic field label
|
|
$LayoutObject->Block(
|
|
Name => 'DynamicFieldTableRowRecord',
|
|
Data => {
|
|
Label => '',
|
|
},
|
|
);
|
|
|
|
# outout dynamic field value plain
|
|
$LayoutObject->Block(
|
|
Name => 'DynamicFieldTableRowRecordPlain',
|
|
Data => {
|
|
Value => '',
|
|
Title => '',
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
# test access to frontend module for Customer
|
|
my $Access = $LayoutObject->Permission(
|
|
Action => 'AgentTicketCustomer',
|
|
Type => 'rw',
|
|
);
|
|
if ($Access) {
|
|
|
|
# test access to ticket
|
|
my $Config = $ConfigObject->Get('Ticket::Frontend::AgentTicketCustomer');
|
|
if ( $Config->{Permission} ) {
|
|
my $OK = $TicketObject->Permission(
|
|
Type => $Config->{Permission},
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Self->{UserID},
|
|
LogNo => 1,
|
|
);
|
|
if ( !$OK ) {
|
|
$Access = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
# define proper tt block based on permissions
|
|
my $CustomerIDBlock = $Access ? 'CustomerIDRW' : 'CustomerIDRO';
|
|
$LayoutObject->Block(
|
|
Name => $CustomerIDBlock,
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
},
|
|
);
|
|
|
|
my %ActionRowTickets;
|
|
|
|
# add action items as js
|
|
if ( @ActionItems && !$Param{Config}->{TicketActionsPerTicket} ) {
|
|
|
|
# replace TT directives from string with values
|
|
for my $ActionItem (@ActionItems) {
|
|
$ActionItem->{Link} = $LayoutObject->Output(
|
|
Template => $ActionItem->{Link},
|
|
Data => {
|
|
TicketID => $Article{TicketID},
|
|
},
|
|
);
|
|
}
|
|
|
|
$Self->{ActionRowTickets}->{ $Param{TicketID} } = $LayoutObject->JSONEncode(
|
|
Data => \@ActionItems,
|
|
);
|
|
}
|
|
|
|
# create & return output
|
|
my $Output = $LayoutObject->Output(
|
|
TemplateFile => 'AgentTicketOverviewMedium',
|
|
Data => {
|
|
%Param,
|
|
%Article,
|
|
%AclAction,
|
|
},
|
|
);
|
|
|
|
return \$Output;
|
|
}
|
|
|
|
1;
|