# -- # 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::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!"; 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}, DynamicFields => 0, ); %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}; # 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 = '