# -- # 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::AgentTicketResponsibleView; use strict; use warnings; use Kernel::System::VariableCheck qw(:all); use Kernel::Language qw(Translatable); our $ObjectManagerDisabled = 1; sub new { my ( $Type, %Param ) = @_; # allocate new hash for object my $Self = {%Param}; bless( $Self, $Type ); return $Self; } sub Run { my ( $Self, %Param ) = @_; # get needed object my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request'); my $ConfigObject = $Kernel::OM->Get('Kernel::Config'); # get config my $Config = $ConfigObject->Get("Ticket::Frontend::$Self->{Action}"); my $SortBy = $ParamObject->GetParam( Param => 'SortBy' ) || $Config->{'SortBy::Default'} || 'Age'; my $OrderBy = $ParamObject->GetParam( Param => 'OrderBy' ) || $Config->{'Order::Default'} || 'Up'; # store last queue screen $Kernel::OM->Get('Kernel::System::AuthSession')->UpdateSessionID( SessionID => $Self->{SessionID}, Key => 'LastScreenOverview', Value => $Self->{RequestedURL}, ); # get user object my $UserObject = $Kernel::OM->Get('Kernel::System::User'); # get filters stored in the user preferences my %Preferences = $UserObject->GetPreferences( UserID => $Self->{UserID}, ); my $StoredFiltersKey = 'UserStoredFilterColumns-' . $Self->{Action}; my $JSONObject = $Kernel::OM->Get('Kernel::System::JSON'); my $StoredFilters = $JSONObject->Decode( Data => $Preferences{$StoredFiltersKey}, ); # delete stored filters if needed if ( $ParamObject->GetParam( Param => 'DeleteFilters' ) ) { $StoredFilters = {}; } # get the column filters from the web request or user preferences my %ColumnFilter; my %GetColumnFilter; COLUMNNAME: for my $ColumnName ( qw(Owner Responsible State Queue Priority Type Lock Service SLA CustomerID CustomerUserID) ) { # get column filter from web request my $FilterValue = $ParamObject->GetParam( Param => 'ColumnFilter' . $ColumnName ) || ''; # if filter is not present in the web request, try with the user preferences if ( $FilterValue eq '' ) { if ( $ColumnName eq 'CustomerID' ) { $FilterValue = $StoredFilters->{$ColumnName}->[0] || ''; } elsif ( $ColumnName eq 'CustomerUserID' ) { $FilterValue = $StoredFilters->{CustomerUserLogin}->[0] || ''; } else { $FilterValue = $StoredFilters->{ $ColumnName . 'IDs' }->[0] || ''; } } next COLUMNNAME if $FilterValue eq ''; next COLUMNNAME if $FilterValue eq 'DeleteFilter'; if ( $ColumnName eq 'CustomerID' ) { push @{ $ColumnFilter{$ColumnName} }, $FilterValue; push @{ $ColumnFilter{ $ColumnName . 'Raw' } }, $FilterValue; $GetColumnFilter{$ColumnName} = $FilterValue; } elsif ( $ColumnName eq 'CustomerUserID' ) { push @{ $ColumnFilter{CustomerUserLogin} }, $FilterValue; push @{ $ColumnFilter{CustomerUserLoginRaw} }, $FilterValue; $GetColumnFilter{$ColumnName} = $FilterValue; } else { push @{ $ColumnFilter{ $ColumnName . 'IDs' } }, $FilterValue; $GetColumnFilter{$ColumnName} = $FilterValue; } } # get all dynamic fields $Self->{DynamicField} = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldListGet( Valid => 1, ObjectType => ['Ticket'], ); DYNAMICFIELD: for my $DynamicFieldConfig ( @{ $Self->{DynamicField} } ) { next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig); next DYNAMICFIELD if !$DynamicFieldConfig->{Name}; # get filter from web request my $FilterValue = $ParamObject->GetParam( Param => 'ColumnFilterDynamicField_' . $DynamicFieldConfig->{Name} ); # if no filter from web request, try from user preferences if ( !defined $FilterValue || $FilterValue eq '' ) { $FilterValue = $StoredFilters->{ 'DynamicField_' . $DynamicFieldConfig->{Name} }->{Equals}; } next DYNAMICFIELD if !defined $FilterValue; next DYNAMICFIELD if $FilterValue eq ''; next DYNAMICFIELD if $FilterValue eq 'DeleteFilter'; $ColumnFilter{ 'DynamicField_' . $DynamicFieldConfig->{Name} } = { Equals => $FilterValue, }; $GetColumnFilter{ 'DynamicField_' . $DynamicFieldConfig->{Name} } = $FilterValue; } # starting with page ... my $Refresh = ''; if ( $Self->{UserRefreshTime} ) { $Refresh = 60 * $Self->{UserRefreshTime}; } my $Output; # get layout object my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout'); if ( $Self->{Subaction} ne 'AJAXFilterUpdate' ) { $Output = $LayoutObject->Header( Refresh => $Refresh, ); $Output .= $LayoutObject->NavigationBar(); } # Notify if there are tickets which are not updated. $Output .= $LayoutObject->NotifyNonUpdatedTickets() // ''; # get locked viewable tickets... my $SortByS = $SortBy; if ( $SortByS eq 'CreateTime' ) { $SortByS = 'Age'; } # define filter my %Filters = ( All => { Name => Translatable('All'), Prio => 1000, Search => { StateType => 'Open', ResponsibleIDs => [ $Self->{UserID} ], OrderBy => $OrderBy, SortBy => $SortByS, UserID => 1, Permission => 'ro', }, }, New => { Name => Translatable('New Article'), Prio => 1001, Search => { StateType => 'Open', ResponsibleIDs => [ $Self->{UserID} ], TicketFlag => { Seen => 1, }, TicketFlagUserID => $Self->{UserID}, OrderBy => $OrderBy, SortBy => $SortByS, UserID => 1, Permission => 'ro', }, }, Reminder => { Name => Translatable('Pending'), Prio => 1002, Search => { StateType => [ 'pending reminder', 'pending auto' ], ResponsibleIDs => [ $Self->{UserID} ], OrderBy => $OrderBy, SortBy => $SortByS, UserID => 1, Permission => 'ro', }, }, ReminderReached => { Name => Translatable('Reminder Reached'), Prio => 1003, Search => { StateType => ['pending reminder'], TicketPendingTimeOlderMinutes => 1, ResponsibleIDs => [ $Self->{UserID} ], OrderBy => $OrderBy, SortBy => $SortByS, UserID => 1, Permission => 'ro', }, }, ); my $Filter = $ParamObject->GetParam( Param => 'Filter' ) || 'All'; # check if filter is valid if ( !$Filters{$Filter} ) { $LayoutObject->FatalError( Message => $LayoutObject->{LanguageObject}->Translate( 'Invalid Filter: %s!', $Filter ), ); } # do shown tickets lookup my $Limit = 10_000; my $ElementChanged = $ParamObject->GetParam( Param => 'ElementChanged' ) || ''; my $HeaderColumn = $ElementChanged; $HeaderColumn =~ s{\A ColumnFilter }{}msxg; my @OriginalViewableTickets; my @ViewableTickets; my $ViewableTicketCount = 0; # get ticket object my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket'); # get ticket values if ( !IsStringWithData($HeaderColumn) || ( IsStringWithData($HeaderColumn) && ( $ConfigObject->Get('OnlyValuesOnTicket') || $HeaderColumn eq 'CustomerID' || $HeaderColumn eq 'CustomerUserID' ) ) ) { @OriginalViewableTickets = $TicketObject->TicketSearch( %{ $Filters{$Filter}->{Search} }, Limit => $Limit, Result => 'ARRAY', ); @ViewableTickets = $TicketObject->TicketSearch( %{ $Filters{$Filter}->{Search} }, %ColumnFilter, Result => 'ARRAY', Limit => 1_000, ); } # prepare shown tickets for new article tickets if ( $Filter eq 'New' ) { my @OriginalViewableTicketsAll = $TicketObject->TicketSearch( %{ $Filters{All}->{Search} }, Result => 'ARRAY', ); my %OriginalViewableTicketsNotNew; for my $TicketID (@OriginalViewableTickets) { $OriginalViewableTicketsNotNew{$TicketID} = 1; } my @OriginalViewableTicketsTmp; TICKETID: for my $TicketIDAll (@OriginalViewableTicketsAll) { next TICKETID if $OriginalViewableTicketsNotNew{$TicketIDAll}; push @OriginalViewableTicketsTmp, $TicketIDAll; } @OriginalViewableTickets = @OriginalViewableTicketsTmp; my @ViewableTicketsAll = $TicketObject->TicketSearch( %{ $Filters{'All'}->{Search} }, %ColumnFilter, Result => 'ARRAY', Limit => 1_000, ); my %ViewableTicketsNotNew; for my $TicketID (@ViewableTickets) { $ViewableTicketsNotNew{$TicketID} = 1; } my @ViewableTicketsTmp; TICKETID: for my $TicketIDAll (@ViewableTicketsAll) { next TICKETID if $ViewableTicketsNotNew{$TicketIDAll}; push @ViewableTicketsTmp, $TicketIDAll; } @ViewableTickets = @ViewableTicketsTmp; } my $View = $ParamObject->GetParam( Param => 'View' ) || ''; if ( $Self->{Subaction} eq 'AJAXFilterUpdate' ) { my $FilterContent = $LayoutObject->TicketListShow( FilterContentOnly => 1, HeaderColumn => $HeaderColumn, ElementChanged => $ElementChanged, OriginalTicketIDs => \@OriginalViewableTickets, Action => 'AgentTicketStatusView', Env => $Self, View => $View, EnableColumnFilters => 1, ); if ( !$FilterContent ) { $LayoutObject->FatalError( Message => $LayoutObject->{LanguageObject} ->Translate( 'Can\'t get filter content data of %s!', $HeaderColumn ), ); } return $LayoutObject->Attachment( ContentType => 'application/json; charset=' . $LayoutObject->{Charset}, Content => $FilterContent, Type => 'inline', NoCache => 1, ); } else { # store column filters my $StoredFilters = \%ColumnFilter; my $StoredFiltersKey = 'UserStoredFilterColumns-' . $Self->{Action}; $UserObject->SetPreferences( UserID => $Self->{UserID}, Key => $StoredFiltersKey, Value => $JSONObject->Encode( Data => $StoredFilters ), ); } my %NavBarFilter; for my $FilterColumn ( sort keys %Filters ) { my $Count = $TicketObject->TicketSearch( %{ $Filters{$FilterColumn}->{Search} }, %ColumnFilter, Result => 'COUNT', ) || 0; # prepare count for new article tickets if ( $FilterColumn eq 'New' ) { my $CountAll = $TicketObject->TicketSearch( %{ $Filters{All}->{Search} }, %ColumnFilter, Result => 'COUNT', ) || 0; $Count = $CountAll - $Count; } $NavBarFilter{ $Filters{$FilterColumn}->{Prio} } = { Count => $Count, Filter => $FilterColumn, %{ $Filters{$FilterColumn} }, %ColumnFilter, }; } my $ColumnFilterLink = ''; COLUMNNAME: for my $ColumnName ( sort keys %GetColumnFilter ) { next COLUMNNAME if !$ColumnName; next COLUMNNAME if !$GetColumnFilter{$ColumnName}; $ColumnFilterLink .= ';' . $LayoutObject->Ascii2Html( Text => 'ColumnFilter' . $ColumnName ) . '=' . $LayoutObject->Ascii2Html( Text => $GetColumnFilter{$ColumnName} ); } # show tickets my $LinkPage = 'Filter=' . $LayoutObject->Ascii2Html( Text => $Filter ) . ';View=' . $LayoutObject->Ascii2Html( Text => $View ) . ';SortBy=' . $LayoutObject->Ascii2Html( Text => $SortBy ) . ';OrderBy=' . $LayoutObject->Ascii2Html( Text => $OrderBy ) . $ColumnFilterLink . ';'; my $LinkSort = 'Filter=' . $LayoutObject->Ascii2Html( Text => $Filter ) . ';View=' . $LayoutObject->Ascii2Html( Text => $View ) . $ColumnFilterLink . ';'; my $LinkFilter = 'SortBy=' . $LayoutObject->Ascii2Html( Text => $SortBy ) . ';OrderBy=' . $LayoutObject->Ascii2Html( Text => $OrderBy ) . ';View=' . $LayoutObject->Ascii2Html( Text => $View ) . ';'; my $LastColumnFilter = $ParamObject->GetParam( Param => 'LastColumnFilter' ) || ''; if ( !$LastColumnFilter && $ColumnFilterLink ) { # is planned to have a link to go back here $LastColumnFilter = 1; } $Output .= $LayoutObject->TicketListShow( TicketIDs => \@ViewableTickets, OriginalTicketIDs => \@OriginalViewableTickets, GetColumnFilter => \%GetColumnFilter, LastColumnFilter => $LastColumnFilter, Action => 'AgentTicketResponsibleView', Total => scalar @ViewableTickets, RequestedURL => $Self->{RequestedURL}, View => $View, Filter => $Filter, Filters => \%NavBarFilter, LinkFilter => $LinkFilter, TitleName => Translatable('My Responsible Tickets'), TitleValue => $Filters{$Filter}->{Name}, Bulk => 1, Env => $Self, LinkPage => $LinkPage, LinkSort => $LinkSort, OrderBy => $OrderBy, SortBy => $SortBy, EnableColumnFilters => 1, ColumnFilterForm => { Filter => $Filter || '', }, # do not print the result earlier, but return complete content Output => 1, ); $Output .= $LayoutObject->Footer(); return $Output; } 1;