1036 lines
31 KiB
Perl
1036 lines
31 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::AdminCommunicationLog;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
our $ObjectManagerDisabled = 1;
|
|
|
|
use Kernel::System::VariableCheck qw(:all);
|
|
use Kernel::Language qw(Translatable);
|
|
|
|
sub new {
|
|
my ( $Type, %Param ) = @_;
|
|
|
|
my $Self = {%Param};
|
|
bless( $Self, $Type );
|
|
|
|
return $Self;
|
|
}
|
|
|
|
sub Run {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request');
|
|
|
|
my %GetParam;
|
|
for my $Param (
|
|
qw(
|
|
CommunicationID ObjectLogID StartTime Filter SortBy
|
|
OrderBy StartHit Expand AccountID Direct PriorityFilter
|
|
)
|
|
)
|
|
{
|
|
$GetParam{$Param} = $ParamObject->GetParam( Param => $Param );
|
|
}
|
|
|
|
my $Communication;
|
|
if ( $GetParam{CommunicationID} ) {
|
|
my $CommunicationLogDBObj = $Kernel::OM->Get('Kernel::System::CommunicationLog::DB');
|
|
$Communication = $CommunicationLogDBObj->CommunicationGet(
|
|
CommunicationID => $GetParam{CommunicationID},
|
|
);
|
|
|
|
if ( !IsHashRefWithData($Communication) ) {
|
|
return $LayoutObject->FatalError(
|
|
Message => Translatable('Invalid CommunicationID!'),
|
|
);
|
|
}
|
|
}
|
|
|
|
my %TimeRanges = (
|
|
0 => Translatable('All communications'),
|
|
3600 => Translatable('Last 1 hour'),
|
|
10800 => Translatable('Last 3 hours'),
|
|
21600 => Translatable('Last 6 hours'),
|
|
43200 => Translatable('Last 12 hours'),
|
|
86400 => Translatable('Last 24 hours'),
|
|
604800 => Translatable('Last week'),
|
|
2593000 => Translatable('Last month'),
|
|
);
|
|
|
|
$GetParam{TimeRanges} = \%TimeRanges;
|
|
|
|
$GetParam{StartHit} //= int( $Param{StartHit} || 1 );
|
|
$GetParam{SortBy} //= 'StartTime';
|
|
$GetParam{OrderBy} //= 'Down';
|
|
$GetParam{Filter} //= 'All';
|
|
$GetParam{StartTime} //= 86400;
|
|
|
|
if ( $GetParam{StartTime} && $GetParam{StartTime} !~ m{^\d+$} ) {
|
|
return $LayoutObject->FatalError(
|
|
Message => $LayoutObject->{LanguageObject}->Translate( 'Invalid StartTime: %s!', $GetParam{StartTime} ),
|
|
);
|
|
}
|
|
elsif ( $GetParam{StartTime} == 0 ) {
|
|
$GetParam{DateTime} = $GetParam{StartTime};
|
|
}
|
|
else {
|
|
my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime');
|
|
my $ValidDate = $DateTimeObject->Subtract(
|
|
Seconds => $GetParam{StartTime},
|
|
);
|
|
|
|
if ( !$ValidDate ) {
|
|
return $LayoutObject->FatalError(
|
|
Message => $LayoutObject->{LanguageObject}->Translate( 'Invalid StartTime: %s!', $GetParam{StartTime} ),
|
|
);
|
|
}
|
|
$GetParam{DateTime} = $DateTimeObject->ToString();
|
|
}
|
|
|
|
my %SubactionHandlerMap = (
|
|
Overview => '_ShowOverview',
|
|
Zoom => '_ZoomView',
|
|
Accounts => '_AccountsView',
|
|
GetObjectLog => '_GetObjectLog',
|
|
GetCommunicationLog => '_GetCommunicationLog',
|
|
);
|
|
|
|
my $Subaction = $Self->{Subaction};
|
|
if ( !( exists $SubactionHandlerMap{$Subaction} ) ) {
|
|
$Subaction = 'Overview';
|
|
}
|
|
|
|
my $SubactionHandler = $SubactionHandlerMap{$Subaction};
|
|
|
|
return $Self->$SubactionHandler(
|
|
%GetParam,
|
|
Action => $Subaction,
|
|
Communication => $Communication,
|
|
);
|
|
}
|
|
|
|
sub _ShowOverview {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
my $Output = $LayoutObject->Header();
|
|
$Output .= $LayoutObject->NavigationBar();
|
|
|
|
my $TimeRangeStrg = $LayoutObject->BuildSelection(
|
|
Data => $Param{TimeRanges},
|
|
Name => 'TimeRange',
|
|
ID => 'TimeRange',
|
|
SelectedID => $Param{StartTime} // 86400,
|
|
PossibleNone => 0,
|
|
Translation => 1,
|
|
Sort => 'NumericKey',
|
|
Class => 'Modernize W75pc',
|
|
);
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'TimeRange',
|
|
Data => {
|
|
TimeRange => $TimeRangeStrg,
|
|
},
|
|
);
|
|
|
|
# Get personal page shown count.
|
|
my $PageShownPreferencesKey = 'AdminCommunicationLogPageShown';
|
|
my $PageShown = $Self->{$PageShownPreferencesKey} || 25;
|
|
my $Group = 'CommunicationLogPageShown';
|
|
|
|
# Prepare filters.
|
|
my %Filters = (
|
|
All => {
|
|
Name => Translatable('All'),
|
|
Prio => 1000,
|
|
Filter => 'All',
|
|
Search => {
|
|
OrderBy => $Param{OrderBy},
|
|
SortBy => $Param{SortBy},
|
|
},
|
|
},
|
|
Successful => {
|
|
Name => Translatable('Successful'),
|
|
Prio => 1001,
|
|
Filter => 'Successful',
|
|
Search => {
|
|
OrderBy => $Param{OrderBy},
|
|
SortBy => $Param{SortBy},
|
|
Status => 'Successful',
|
|
},
|
|
},
|
|
Processing => {
|
|
Name => Translatable('Processing'),
|
|
Prio => 1002,
|
|
Filter => 'Processing',
|
|
Search => {
|
|
OrderBy => $Param{OrderBy},
|
|
SortBy => $Param{SortBy},
|
|
Status => 'Processing',
|
|
},
|
|
},
|
|
Failed => {
|
|
Name => Translatable('Failed'),
|
|
Prio => 1004,
|
|
Filter => 'Failed',
|
|
Search => {
|
|
OrderBy => $Param{OrderBy},
|
|
SortBy => $Param{SortBy},
|
|
Status => 'Failed',
|
|
},
|
|
},
|
|
);
|
|
|
|
if ( !$Filters{ $Param{Filter} } ) {
|
|
return $LayoutObject->FatalError(
|
|
Message => $LayoutObject->{LanguageObject}->Translate( 'Invalid Filter: %s!', $Param{Filter} ),
|
|
);
|
|
}
|
|
|
|
my $CommunicationLogDBObj = $Kernel::OM->Get('Kernel::System::CommunicationLog::DB');
|
|
|
|
my @CommunicationData;
|
|
for my $Filter ( values %Filters ) {
|
|
my @Communications = @{
|
|
$CommunicationLogDBObj->CommunicationList(
|
|
StartDate => $Param{DateTime},
|
|
%{ $Filter->{Search} },
|
|
)
|
|
|| []
|
|
};
|
|
|
|
$Filter->{Count} = scalar @Communications;
|
|
|
|
if ( $Filter->{Filter} eq $Param{Filter} ) {
|
|
@CommunicationData = @Communications;
|
|
}
|
|
}
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'CommunicationNavBarFilter',
|
|
Data => {
|
|
%Param,
|
|
},
|
|
);
|
|
|
|
# Generate human readable average processing time.
|
|
my $AverageSeconds = $CommunicationLogDBObj->CommunicationList(
|
|
StartDate => $Param{DateTime},
|
|
Result => 'AVERAGE',
|
|
);
|
|
|
|
my $AverageString = $AverageSeconds >= 1
|
|
? $Self->_HumanReadableAverage( Seconds => $AverageSeconds )
|
|
: $LayoutObject->{LanguageObject}->Translate('Less than a second');
|
|
|
|
my %Accounts = $Self->_AccountStatus(
|
|
StartDate => $Param{DateTime},
|
|
%Param,
|
|
);
|
|
|
|
my %AccountsOverview = (
|
|
Failed => 0,
|
|
Warning => 0,
|
|
Successful => 0,
|
|
);
|
|
|
|
my $Status = '';
|
|
|
|
# Assume all accounts are working.
|
|
if (%Accounts) {
|
|
$Status = 'Successful';
|
|
}
|
|
|
|
ACCOUNTS:
|
|
for my $AccountKey ( sort keys %Accounts ) {
|
|
|
|
my ( $Failed, $Successful );
|
|
if ( $Accounts{$AccountKey}->{Failed} ) {
|
|
$Failed = 1;
|
|
}
|
|
if ( $Accounts{$AccountKey}->{Successful} ) {
|
|
$Successful = 1;
|
|
}
|
|
|
|
# Set global account status.
|
|
if ($Failed) {
|
|
$Status = 'Failed';
|
|
if ($Successful) {
|
|
$Status = 'Warning';
|
|
}
|
|
}
|
|
|
|
$AccountsOverview{$Status}++;
|
|
}
|
|
|
|
my $StatusFilter = 'Successful';
|
|
if ( $Filters{Failed}->{Count} ) {
|
|
$StatusFilter = 'Failed';
|
|
}
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'StatusOverview',
|
|
Data => {
|
|
Successful => $Filters{Successful}->{Count},
|
|
Processing => $Filters{Processing}->{Count},
|
|
Failed => $Filters{Failed}->{Count},
|
|
StatusFilter => $StatusFilter,
|
|
StartTime => $Param{StartTime} || 0,
|
|
TimeRange => $LayoutObject->{LanguageObject}->Translate( $Param{TimeRanges}->{ $Param{StartTime} } ),
|
|
AverageString => $AverageString,
|
|
AccountsStatus => $Status,
|
|
AccountsOverview => \%AccountsOverview,
|
|
},
|
|
);
|
|
|
|
my $Total = scalar @CommunicationData;
|
|
|
|
# Get data selection.
|
|
my %Data;
|
|
my $Config = $Kernel::OM->Get('Kernel::Config')->Get('PreferencesGroups');
|
|
if ( $Config && $Config->{$Group} && $Config->{$Group}->{Data} ) {
|
|
%Data = %{ $Config->{$Group}->{Data} };
|
|
}
|
|
|
|
# Calculate max. shown per page.
|
|
if ( $Param{StartHit} > $Total ) {
|
|
my $Pages = int( ( $Total / $PageShown ) + 0.99999 );
|
|
$Param{StartHit} = ( ( $Pages - 1 ) * $PageShown ) + 1;
|
|
}
|
|
|
|
my $URLExtension = 'Expand=1;';
|
|
|
|
for my $URLPart (qw(Filter SortBy OrderBy StartTime)) {
|
|
$URLExtension .= "$URLPart=$Param{$URLPart};";
|
|
}
|
|
|
|
# Build nav bar.
|
|
my $Limit = $Param{Limit} || 20_000;
|
|
my %PageNav = $LayoutObject->PageNavBar(
|
|
Limit => $Limit,
|
|
StartHit => $Param{StartHit},
|
|
PageShown => $PageShown,
|
|
AllHits => $Total || 0,
|
|
Action => 'Action=' . $LayoutObject->{Action},
|
|
Link => $URLExtension,
|
|
IDPrefix => $LayoutObject->{Action},
|
|
);
|
|
|
|
# Build shown dynamic fields per page.
|
|
$Param{RequestedURL} = "Action=$Self->{Action};$URLExtension";
|
|
|
|
for my $URLPart (qw(Filter SortBy OrderBy StartTime)) {
|
|
$Param{RequestedURL} .= ";$URLPart=$Param{$URLPart}";
|
|
}
|
|
|
|
$Param{Group} = $Group;
|
|
$Param{PreferencesKey} = $PageShownPreferencesKey;
|
|
$Param{PageShownString} = $LayoutObject->BuildSelection(
|
|
Name => $PageShownPreferencesKey,
|
|
SelectedID => $PageShown,
|
|
Translation => 0,
|
|
Data => \%Data,
|
|
Sort => 'NumericValue',
|
|
Class => 'Modernize',
|
|
);
|
|
|
|
if (%PageNav) {
|
|
$LayoutObject->Block(
|
|
Name => 'OverviewNavBarPageNavBar',
|
|
Data => \%PageNav,
|
|
);
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'ContextSettings',
|
|
Data => { %PageNav, %Param, },
|
|
);
|
|
}
|
|
|
|
for my $FilterItem ( sort { $a->{Prio} <=> $b->{Prio} } values %Filters ) {
|
|
$LayoutObject->Block(
|
|
Name => 'CommunicationNavBarFilterItem',
|
|
Data => {
|
|
%Param,
|
|
%{$FilterItem},
|
|
Selected => ( $FilterItem->{Filter} eq $Param{Filter} ) ? 1 : 0,
|
|
},
|
|
);
|
|
}
|
|
|
|
my @TableHeaders = (
|
|
{
|
|
HeaderName => Translatable('Status'),
|
|
SortByName => 'Status',
|
|
Class => 'Status Center',
|
|
},
|
|
{
|
|
HeaderName => Translatable('Transport'),
|
|
SortByName => 'Transport',
|
|
Class => 'Transport',
|
|
},
|
|
{
|
|
HeaderName => Translatable('Direction'),
|
|
SortByName => 'Direction',
|
|
Class => 'Direction Center',
|
|
},
|
|
{
|
|
HeaderName => Translatable('Account'),
|
|
SortByName => 'Account',
|
|
Class => 'Account',
|
|
},
|
|
{
|
|
HeaderName => Translatable('Start Time'),
|
|
SortByName => 'StartTime',
|
|
Class => 'StartTime',
|
|
},
|
|
{
|
|
HeaderName => Translatable('End Time'),
|
|
SortByName => 'EndTime',
|
|
Class => 'EndTime',
|
|
},
|
|
{
|
|
HeaderName => Translatable('Duration'),
|
|
SortByName => 'Duration',
|
|
Class => 'Duration',
|
|
},
|
|
);
|
|
|
|
my $HeaderURL = 'Expand=1;';
|
|
|
|
for my $URLPart (qw(Filter StartTime)) {
|
|
$HeaderURL .= "$URLPart=$Param{$URLPart};";
|
|
}
|
|
|
|
for my $TableHeader (@TableHeaders) {
|
|
|
|
my $CSS = $TableHeader->{Class};
|
|
my $TranslatedTitle = $LayoutObject->{LanguageObject}->Translate( $TableHeader->{HeaderName} );
|
|
my $OrderBy;
|
|
|
|
if ( $Param{SortBy} eq $TableHeader->{SortByName} ) {
|
|
if ( $Param{OrderBy} eq 'Up' ) {
|
|
$OrderBy = 'Down';
|
|
$CSS .= ' SortAscendingLarge';
|
|
}
|
|
else {
|
|
$OrderBy = 'Up';
|
|
$CSS .= ' SortDescendingLarge';
|
|
}
|
|
|
|
# Set title description.
|
|
my $TitleDesc = $OrderBy eq 'Up'
|
|
? $LayoutObject->{LanguageObject}->Translate('sorted descending')
|
|
: $LayoutObject->{LanguageObject}->Translate('sorted ascending');
|
|
$TranslatedTitle .= ', ' . $TitleDesc;
|
|
}
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'TableHeader',
|
|
Data => {
|
|
HeaderName => $TableHeader->{HeaderName},
|
|
SortByName => $TableHeader->{SortByName},
|
|
OrderBy => $OrderBy,
|
|
CSS => $CSS,
|
|
Title => $TranslatedTitle,
|
|
HeaderLink => $HeaderURL,
|
|
},
|
|
);
|
|
}
|
|
|
|
# Prepare communication data.
|
|
if (@CommunicationData) {
|
|
my $Counter = 0;
|
|
|
|
for my $Communication (@CommunicationData) {
|
|
$Counter++;
|
|
|
|
if ( $Counter >= $Param{StartHit} && $Counter < ( $PageShown + $Param{StartHit} ) ) {
|
|
my $Account = '-';
|
|
if ( $Communication->{AccountID} ) {
|
|
$Account = $CommunicationLogDBObj->CommunicationAccountLabelGet(
|
|
AccountType => $Communication->{AccountType},
|
|
AccountID => $Communication->{AccountID},
|
|
Transport => $Communication->{Transport},
|
|
);
|
|
}
|
|
elsif ( $Communication->{AccountType} ) {
|
|
$Account = $Communication->{AccountType};
|
|
}
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'CommunicationRow',
|
|
Data => {
|
|
%{$Communication},
|
|
DisplayAccount => $Account,
|
|
},
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
$LayoutObject->Block(
|
|
Name => 'NoCommunicationsFound',
|
|
);
|
|
}
|
|
|
|
$Output .= $LayoutObject->Output(
|
|
TemplateFile => 'AdminCommunicationLog',
|
|
Data => {
|
|
%Param,
|
|
CommunicationCount => $Filters{All}->{Count},
|
|
},
|
|
);
|
|
|
|
$Output .= $LayoutObject->Footer();
|
|
return $Output;
|
|
}
|
|
|
|
sub _ZoomView {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
my $Output = $LayoutObject->Header();
|
|
$Output .= $LayoutObject->NavigationBar();
|
|
|
|
# Call all needed template blocks.
|
|
$LayoutObject->Block(
|
|
Name => 'Main',
|
|
Data => \%Param,
|
|
);
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'Hint',
|
|
Data => \%Param,
|
|
);
|
|
|
|
my $CommunicationLogDBObj = $Kernel::OM->Get('Kernel::System::CommunicationLog::DB');
|
|
my $Communication = $Param{Communication};
|
|
my $CommunicationObjects = $CommunicationLogDBObj->ObjectLogList(
|
|
CommunicationID => $Communication->{CommunicationID},
|
|
);
|
|
|
|
if ( !IsArrayRefWithData($CommunicationObjects) ) {
|
|
$LayoutObject->Block(
|
|
Name => 'NoCommunicationObjectsFound',
|
|
);
|
|
}
|
|
|
|
my $Direction = $Communication->{Direction};
|
|
|
|
for my $CommunicationObject ( @{$CommunicationObjects} ) {
|
|
$CommunicationObject->{Direction} = $Direction;
|
|
|
|
# Get account specific information.
|
|
if ( $Communication->{AccountType} && $Communication->{AccountID} ) {
|
|
|
|
$CommunicationObject->{AccountLabel} = $CommunicationLogDBObj->CommunicationAccountLabelGet(
|
|
AccountType => $Communication->{AccountType},
|
|
AccountID => $Communication->{AccountID},
|
|
Transport => $Communication->{Transport},
|
|
);
|
|
$CommunicationObject->{AccountLink} = $CommunicationLogDBObj->CommunicationAccountLinkGet(
|
|
AccountType => $Communication->{AccountType},
|
|
AccountID => $Communication->{AccountID},
|
|
Transport => $Communication->{Transport},
|
|
);
|
|
$CommunicationObject->{AccountType} = $Communication->{AccountType};
|
|
}
|
|
else {
|
|
$CommunicationObject->{AccountLabel} = $Communication->{AccountType};
|
|
$CommunicationObject->{AccountType} = $Communication->{AccountType};
|
|
}
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'CommunicationObjectRow',
|
|
Data => $CommunicationObject,
|
|
);
|
|
}
|
|
|
|
my $PriorityFilterStrg = $LayoutObject->BuildSelection(
|
|
Data => [
|
|
Translatable('Trace'),
|
|
Translatable('Debug'),
|
|
Translatable('Info'),
|
|
Translatable('Notice'),
|
|
Translatable('Warn'),
|
|
Translatable('Error'),
|
|
],
|
|
Name => 'PriorityFilter',
|
|
ID => 'PriorityFilter',
|
|
SelectedID => $Param{PriorityFilter} // 'Trace',
|
|
PossibleNone => 0,
|
|
Translation => 1,
|
|
Class => 'Modernize W75pc',
|
|
);
|
|
|
|
# Send CommunicationID to JS.
|
|
$LayoutObject->AddJSData(
|
|
Key => 'CommunicationID',
|
|
Value => $Param{CommunicationID},
|
|
);
|
|
|
|
# Send ObjectLogID to JS.
|
|
$LayoutObject->AddJSData(
|
|
Key => 'ObjectLogID',
|
|
Value => $Param{ObjectLogID},
|
|
);
|
|
|
|
$Output .= $LayoutObject->Output(
|
|
TemplateFile => 'AdminCommunicationLogZoom',
|
|
Data => {
|
|
%Param,
|
|
ObjectCount => scalar @{$CommunicationObjects},
|
|
PriorityFilter => $PriorityFilterStrg,
|
|
CommunicationLog => $Communication,
|
|
},
|
|
);
|
|
|
|
$Output .= $LayoutObject->Footer();
|
|
return $Output;
|
|
}
|
|
|
|
sub _AccountsView {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
if ( $Param{Direct} && $Param{AccountID} ) {
|
|
$LayoutObject->AddJSData(
|
|
Key => 'AccountID',
|
|
Value => $Param{AccountID},
|
|
);
|
|
}
|
|
|
|
my $Output = $LayoutObject->Header();
|
|
$Output .= $LayoutObject->NavigationBar();
|
|
|
|
my $TimeRangeStrg = $LayoutObject->BuildSelection(
|
|
Data => $Param{TimeRanges},
|
|
Name => 'TimeRangeAccounts',
|
|
ID => 'TimeRangeAccounts',
|
|
SelectedID => $Param{StartTime},
|
|
PossibleNone => 0,
|
|
Translation => 1,
|
|
Sort => 'NumericKey',
|
|
Class => 'Modernize W75pc',
|
|
);
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'TimeRange',
|
|
Data => {
|
|
TimeRange => $TimeRangeStrg,
|
|
},
|
|
);
|
|
|
|
my %Accounts = $Self->_AccountStatus(
|
|
StartDate => $Param{DateTime},
|
|
%Param,
|
|
);
|
|
|
|
my $CommunicationLogDBObj = $Kernel::OM->Get('Kernel::System::CommunicationLog::DB');
|
|
|
|
if ( !scalar keys %Accounts ) {
|
|
$LayoutObject->Block(
|
|
Name => 'NoAccountsFound',
|
|
);
|
|
}
|
|
else {
|
|
for my $AccountKey ( sort keys %Accounts ) {
|
|
|
|
my $Account = $Accounts{$AccountKey};
|
|
|
|
my $AccountLabel = $Account->{AccountType} // '-';
|
|
my ( $AccountLink, $AverageSeconds );
|
|
|
|
if ( $Account->{AccountID} ) {
|
|
$AccountLabel = $CommunicationLogDBObj->CommunicationAccountLabelGet(
|
|
AccountType => $Account->{AccountType},
|
|
AccountID => $Account->{AccountID},
|
|
Transport => $Account->{Transport},
|
|
);
|
|
$AccountLink = $CommunicationLogDBObj->CommunicationAccountLinkGet(
|
|
AccountType => $Account->{AccountType},
|
|
AccountID => $Account->{AccountID},
|
|
Transport => $Account->{Transport},
|
|
);
|
|
$AverageSeconds = $CommunicationLogDBObj->CommunicationList(
|
|
StartDate => $Param{DateTime},
|
|
AccountID => $Account->{AccountID},
|
|
Result => 'AVERAGE',
|
|
);
|
|
}
|
|
else {
|
|
$AverageSeconds = $CommunicationLogDBObj->CommunicationList(
|
|
StartDate => $Param{DateTime},
|
|
AccountType => $Account->{AccountType},
|
|
Result => 'AVERAGE',
|
|
);
|
|
}
|
|
|
|
# Generate human readable average processing time.
|
|
my $AverageString = $AverageSeconds >= 1
|
|
? $Self->_HumanReadableAverage( Seconds => $AverageSeconds )
|
|
: $LayoutObject->{LanguageObject}->Translate('Less than a second');
|
|
|
|
my $HealthStatus = $Self->_CheckHealth($Account);
|
|
|
|
my $AccountErrorLink;
|
|
if ( $HealthStatus ne 'Successful' ) {
|
|
my $CommunicationID = $Account->{Failed}[0];
|
|
if ($CommunicationID) {
|
|
$AccountErrorLink = "Subaction=Zoom;CommunicationID=$CommunicationID";
|
|
}
|
|
}
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'AccountRow',
|
|
Data => {
|
|
AccountLabel => $AccountLabel,
|
|
AccountLink => $AccountLink,
|
|
AccountStatus => $HealthStatus,
|
|
AccountErrorLink => $AccountErrorLink,
|
|
AccountKey => $AccountKey,
|
|
AverageSeconds => $AverageSeconds,
|
|
AverageString => $AverageString,
|
|
},
|
|
);
|
|
|
|
}
|
|
}
|
|
|
|
my $CommunicationLogCount = 0;
|
|
|
|
if ( $Param{Direct} ) {
|
|
$CommunicationLogCount = $Self->_GetCommunicationLog(%Param);
|
|
}
|
|
else {
|
|
$LayoutObject->Block(
|
|
Name => 'NoCommunicationLogsFound',
|
|
);
|
|
}
|
|
|
|
$Output .= $LayoutObject->Output(
|
|
TemplateFile => 'AdminCommunicationLogAccounts',
|
|
Data => {
|
|
%Param,
|
|
CommunicationLogCount => $CommunicationLogCount,
|
|
TimeRange => $LayoutObject->{LanguageObject}->Translate( $Param{TimeRanges}->{ $Param{StartTime} } ),
|
|
},
|
|
);
|
|
|
|
$Output .= $LayoutObject->Footer();
|
|
return $Output;
|
|
}
|
|
|
|
sub _GetObjectLog {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
my $CommunicationLogDBObj = $Kernel::OM->Get('Kernel::System::CommunicationLog::DB');
|
|
my $CommunicationObjectLogs = $CommunicationLogDBObj->ObjectLogEntryList(
|
|
ObjectLogID => $Param{ObjectLogID},
|
|
OrderBy => 'up',
|
|
);
|
|
|
|
if ( !IsArrayRefWithData($CommunicationObjectLogs) ) {
|
|
$LayoutObject->Block(
|
|
Name => 'NoObjectLogsFound',
|
|
);
|
|
}
|
|
|
|
for my $CommunicationObjectLog ( @{$CommunicationObjectLogs} ) {
|
|
$LayoutObject->Block(
|
|
Name => 'ObjectLogEntry',
|
|
Data => $CommunicationObjectLog,
|
|
);
|
|
}
|
|
|
|
my $Output = $LayoutObject->Output(
|
|
TemplateFile => 'AdminCommunicationLogObjectLog',
|
|
Data => {
|
|
%Param,
|
|
ObjectLogCount => scalar @{$CommunicationObjectLogs},
|
|
},
|
|
);
|
|
|
|
return $LayoutObject->Attachment(
|
|
ContentType => 'application/json; charset=' . $LayoutObject->{Charset},
|
|
Content => $Output,
|
|
Type => 'inline',
|
|
NoCache => 1,
|
|
);
|
|
}
|
|
|
|
sub _GetCommunicationLog {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
# $Param{AccountID} can be like 'DoNotSendEmail' or 'IMAPS::1', for example.
|
|
my ( $AccountType, $AccountID ) = split '::', $Param{AccountID};
|
|
|
|
my $CommunicationLogDBObj = $Kernel::OM->Get('Kernel::System::CommunicationLog::DB');
|
|
my $CommunicationLogObjects = $CommunicationLogDBObj->ObjectLogList(
|
|
AccountID => $AccountID || $Param{AccountID},
|
|
StartDate => $Param{DateTime},
|
|
);
|
|
|
|
# Get personal page shown count.
|
|
my $PageShownPreferencesKey = 'AdminCommunicationLogPageShown';
|
|
my $PageShown = $Self->{$PageShownPreferencesKey} || 25;
|
|
my $Group = 'CommunicationLogPageShown';
|
|
|
|
my %CommunicationIDs;
|
|
my $Counter = 0;
|
|
|
|
COMMUNICATIONLOGOBJECT:
|
|
for my $LogObject ( @{$CommunicationLogObjects} ) {
|
|
|
|
next COMMUNICATIONLOGOBJECT if $CommunicationIDs{ $LogObject->{CommunicationID} };
|
|
|
|
$Counter++;
|
|
|
|
if ( $Counter >= $Param{StartHit} && $Counter < ( $PageShown + $Param{StartHit} ) ) {
|
|
|
|
my %CommunicationLog = %{
|
|
$CommunicationLogDBObj->CommunicationGet(
|
|
CommunicationID => $LogObject->{CommunicationID},
|
|
)
|
|
|| {}
|
|
};
|
|
|
|
next COMMUNICATIONLOGOBJECT if $CommunicationLog{AccountType} ne $AccountType;
|
|
|
|
next COMMUNICATIONLOGOBJECT if $AccountID && $CommunicationLog{AccountID} ne $AccountID;
|
|
|
|
$CommunicationIDs{ $LogObject->{CommunicationID} } = 1;
|
|
|
|
$LayoutObject->Block(
|
|
Name => 'CommunicationLogRow',
|
|
Data => \%CommunicationLog,
|
|
);
|
|
}
|
|
}
|
|
|
|
if ( !%CommunicationIDs ) {
|
|
$LayoutObject->Block(
|
|
Name => 'NoCommunicationLogsFound',
|
|
);
|
|
}
|
|
|
|
return scalar keys %CommunicationIDs if $Param{Direct};
|
|
|
|
my $Total = scalar keys %CommunicationIDs;
|
|
|
|
# Get data selection.
|
|
my %Data;
|
|
my $Config = $Kernel::OM->Get('Kernel::Config')->Get('PreferencesGroups');
|
|
if ( $Config && $Config->{$Group} && $Config->{$Group}->{Data} ) {
|
|
%Data = %{ $Config->{$Group}->{Data} };
|
|
}
|
|
|
|
# Calculate max. shown per page.
|
|
if ( $Param{StartHit} > $Total ) {
|
|
my $Pages = int( ( $Total / $PageShown ) + 0.99999 );
|
|
$Param{StartHit} = ( ( $Pages - 1 ) * $PageShown ) + 1;
|
|
}
|
|
|
|
my $URLExtension = 'Direct=1;';
|
|
|
|
for my $URLPart (qw(SortBy OrderBy StartTime AccountID)) {
|
|
$URLExtension .= "$URLPart=$Param{$URLPart};";
|
|
}
|
|
|
|
# Build nav bar.
|
|
my $Limit = $Param{Limit} || 20_000;
|
|
my %PageNav = $LayoutObject->PageNavBar(
|
|
Limit => $Limit,
|
|
StartHit => $Param{StartHit},
|
|
PageShown => $PageShown,
|
|
AllHits => $Total || 0,
|
|
Action => 'Action=' . $LayoutObject->{Action} . ';Subaction=Accounts',
|
|
Link => $URLExtension,
|
|
);
|
|
|
|
# Build shown dynamic fields per page.
|
|
$Param{RequestedURL} = "Action=$Self->{Action};$URLExtension";
|
|
|
|
for my $URLPart (qw(SortBy OrderBy StartTime)) {
|
|
$Param{RequestedURL} .= ";$URLPart=$Param{$URLPart}";
|
|
}
|
|
|
|
$Param{Group} = $Group;
|
|
$Param{PreferencesKey} = $PageShownPreferencesKey;
|
|
$Param{PageShownString} = $LayoutObject->BuildSelection(
|
|
Name => $PageShownPreferencesKey,
|
|
SelectedID => $PageShown,
|
|
Translation => 0,
|
|
Data => \%Data,
|
|
);
|
|
|
|
if (%PageNav) {
|
|
$LayoutObject->Block(
|
|
Name => 'OverviewNavBarPageNavBar',
|
|
Data => \%PageNav,
|
|
);
|
|
}
|
|
|
|
my $Output = $LayoutObject->Output(
|
|
TemplateFile => 'AdminCommunicationLogCommunications',
|
|
Data => {
|
|
%Param,
|
|
CommunicationLogCount => scalar keys %CommunicationIDs,
|
|
},
|
|
);
|
|
|
|
return $LayoutObject->Attachment(
|
|
ContentType => 'application/json; charset=' . $LayoutObject->{Charset},
|
|
Content => $Output,
|
|
Type => 'inline',
|
|
NoCache => 1,
|
|
);
|
|
}
|
|
|
|
sub _HumanReadableAverage {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
|
|
|
|
my $DateTimeAverageStart = $Kernel::OM->Create('Kernel::System::DateTime');
|
|
my $DateTimeAverageStop = $Kernel::OM->Create('Kernel::System::DateTime');
|
|
|
|
$DateTimeAverageStop->Add( Seconds => $Param{Seconds} );
|
|
|
|
my $AverageDelta = $DateTimeAverageStart->Delta( DateTimeObject => $DateTimeAverageStop );
|
|
|
|
my @HumanReadableUnits;
|
|
|
|
if ( $AverageDelta->{Days} ) {
|
|
push @HumanReadableUnits,
|
|
"$AverageDelta->{Days} " .
|
|
(
|
|
$AverageDelta->{Days} > 1
|
|
? $LayoutObject->{LanguageObject}->Translate('days')
|
|
: $LayoutObject->{LanguageObject}->Translate('day')
|
|
);
|
|
}
|
|
|
|
if ( $AverageDelta->{Hours} ) {
|
|
push @HumanReadableUnits,
|
|
"$AverageDelta->{Hours} " .
|
|
(
|
|
$AverageDelta->{Hours} > 1
|
|
? $LayoutObject->{LanguageObject}->Translate('hours')
|
|
: $LayoutObject->{LanguageObject}->Translate('hour')
|
|
);
|
|
}
|
|
|
|
if ( $AverageDelta->{Minutes} ) {
|
|
push @HumanReadableUnits,
|
|
"$AverageDelta->{Minutes} " .
|
|
(
|
|
$AverageDelta->{Minutes} > 1
|
|
? $LayoutObject->{LanguageObject}->Translate('minutes')
|
|
: $LayoutObject->{LanguageObject}->Translate('minute')
|
|
);
|
|
}
|
|
|
|
if ( $AverageDelta->{Seconds} ) {
|
|
push @HumanReadableUnits,
|
|
"$AverageDelta->{Seconds} " .
|
|
(
|
|
$AverageDelta->{Seconds} > 1
|
|
? $LayoutObject->{LanguageObject}->Translate('seconds')
|
|
: $LayoutObject->{LanguageObject}->Translate('second')
|
|
);
|
|
}
|
|
|
|
return if !@HumanReadableUnits;
|
|
|
|
return join ', ', @HumanReadableUnits;
|
|
}
|
|
|
|
sub _AccountStatus {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
my %Filter = (
|
|
ObjectLogStartDate => $Param{StartDate},
|
|
);
|
|
|
|
if ( $Param{Status} ) {
|
|
$Filter{ObjectLogStatus} = $Param{Status};
|
|
}
|
|
|
|
my $CommunicationLogDBObj = $Kernel::OM->Get('Kernel::System::CommunicationLog::DB');
|
|
my $Connections = $CommunicationLogDBObj->GetConnectionsObjectsAndCommunications(%Filter);
|
|
if ( !$Connections || !@{$Connections} ) {
|
|
return;
|
|
}
|
|
|
|
my %Account;
|
|
for my $Connection (@$Connections) {
|
|
|
|
my $AccountKey = $Connection->{AccountType};
|
|
if ( $Connection->{AccountID} ) {
|
|
$AccountKey .= "::$Connection->{AccountID}";
|
|
}
|
|
|
|
if ( !$Account{$AccountKey} ) {
|
|
$Account{$AccountKey} = {
|
|
AccountID => $Connection->{AccountID},
|
|
AccountType => $Connection->{AccountType},
|
|
Transport => $Connection->{Transport},
|
|
};
|
|
}
|
|
|
|
$Account{$AccountKey}->{ $Connection->{ObjectLogStatus} } ||= [];
|
|
|
|
push @{ $Account{$AccountKey}->{ $Connection->{ObjectLogStatus} } },
|
|
$Connection->{CommunicationID};
|
|
}
|
|
|
|
for my $AccountKey ( sort keys %Account ) {
|
|
$Account{$AccountKey}->{Status} =
|
|
$Self->_CheckHealth( $Account{$AccountKey} );
|
|
}
|
|
|
|
return %Account;
|
|
|
|
}
|
|
|
|
sub _CheckHealth {
|
|
my ( $Self, $Connections ) = @_;
|
|
|
|
# Success if all is Successful;
|
|
# Failed if all is Failed;
|
|
# Warning if has both Successful and Failed Connections;
|
|
|
|
my $Health = 'Success';
|
|
|
|
if ( scalar $Connections->{Failed} ) {
|
|
$Health = 'Failed';
|
|
if ( scalar $Connections->{Successful} ) {
|
|
$Health = 'Warning';
|
|
}
|
|
}
|
|
|
|
return $Health;
|
|
|
|
}
|
|
|
|
1;
|