Files
scripts/Perl OTRS/Kernel/Output/HTML/Dashboard/EventsTicketCalendar.pm
2024-10-14 00:08:40 +02:00

376 lines
13 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::Output::HTML::Dashboard::EventsTicketCalendar;
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 );
# get needed parameters
for my $Needed (qw(Config Name UserID)) {
die "Got no $Needed!" if ( !$Self->{$Needed} );
}
# get dynamic fields list
my $DynamicFieldsList = $Kernel::OM->Get('Kernel::System::DynamicField')->DynamicFieldListGet(
Valid => 0,
ObjectType => ['Ticket'],
);
if ( !IsArrayRefWithData($DynamicFieldsList) ) {
$DynamicFieldsList = [];
}
# create a dynamic field lookup table (by name)
DYNAMICFIELD:
for my $DynamicField ( @{$DynamicFieldsList} ) {
next DYNAMICFIELD if !$DynamicField;
next DYNAMICFIELD if !IsHashRefWithData($DynamicField);
next DYNAMICFIELD if !$DynamicField->{Name};
$Self->{DynamicFieldLookup}->{ $DynamicField->{Name} } = $DynamicField;
}
return $Self;
}
sub Preferences {
my ( $Self, %Param ) = @_;
return;
}
sub Config {
my ( $Self, %Param ) = @_;
return (
%{ $Self->{Config} }
);
}
sub Run {
my ( $Self, %Param ) = @_;
# get config object
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
my $Queues = $ConfigObject->{DashboardEventsTicketCalendar}->{Queues};
# get start and end time from config
my $StartTimeDynamicField = $ConfigObject->Get('DashboardEventsTicketCalendar::DynamicFieldStartTime')
|| 'TicketCalendarStartTime';
my $EndTimeDynamicField =
$ConfigObject->Get('DashboardEventsTicketCalendar::DynamicFieldEndTime')
|| 'TicketCalendarEndTime';
$Param{CalendarWidth} = $ConfigObject->{DashboardEventsTicketCalendar}->{CalendarWidth};
my %QueuesAll = $Kernel::OM->Get('Kernel::System::Queue')->GetAllQueues(
UserID => $Self->{UserID},
);
my $EventTicketFields = $ConfigObject->Get('DashboardEventsTicketCalendar::TicketFieldsForEvents');
my $EventDynamicFields = $ConfigObject->Get('DashboardEventsTicketCalendar::DynamicFieldsForEvents');
my %DynamicFieldTimeSearch = (
'DynamicField_' . $StartTimeDynamicField => {
GreaterThanEquals => '1970-01-01 00:00:00',
},
'DynamicField_' . $EndTimeDynamicField => {
GreaterThanEquals => '1970-01-01 00:00:00',
},
);
my @ViewableStateIDs = $Kernel::OM->Get('Kernel::System::State')->StateGetStatesByType(
Type => 'Viewable',
Result => 'ID',
);
my %QueuesConfigured;
for my $Queue ( @{$Queues} ) {
for my $QueueID ( sort keys %QueuesAll ) {
if ( $QueuesAll{$QueueID} eq $Queue ) {
$QueuesConfigured{$QueueID} = $QueuesAll{$QueueID};
}
}
}
# get ticket object
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
my %Tickets;
if (%QueuesConfigured) {
%Tickets = $TicketObject->TicketSearch(
SortBy => $ConfigObject->{'SortBy::Default'} || 'Age',
QueueIDs => [ sort keys %QueuesConfigured ],
UserID => $Self->{UserID},
StateIDs => \@ViewableStateIDs,
Result => 'HASH',
%DynamicFieldTimeSearch,
);
}
my @EventsDisplayed;
my $Counter = 1;
my $Limit = scalar keys %Tickets;
# get needed objects
my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
my $UserObject = $Kernel::OM->Get('Kernel::System::User');
my $CustomerUserObject = $Kernel::OM->Get('Kernel::System::CustomerUser');
my $CustomerCompanyObject = $Kernel::OM->Get('Kernel::System::CustomerCompany');
my $Content;
if (%Tickets) {
TICKET:
for my $TicketID ( sort keys %Tickets ) {
my %TicketDetail = $TicketObject->TicketGet(
TicketID => $TicketID,
DynamicFields => 1,
UserID => $Self->{UserID},
);
if (
%TicketDetail &&
$TicketDetail{ 'DynamicField_' . $StartTimeDynamicField } &&
$TicketDetail{ 'DynamicField_' . $EndTimeDynamicField }
)
{
# end time should be greater than start time
my $StartTimeObject = $Kernel::OM->Create(
'Kernel::System::DateTime',
ObjectParams => {
String => $TicketDetail{ 'DynamicField_' . $StartTimeDynamicField }
},
);
my $EndTimeObject = $Kernel::OM->Create(
'Kernel::System::DateTime',
ObjectParams => {
String => $TicketDetail{ 'DynamicField_' . $EndTimeDynamicField }
},
);
# check if start time is after end time
if ( $StartTimeObject > $EndTimeObject ) {
# turn start and end time around for the calendar view
my $NewStartTimeObject = $EndTimeObject;
my $NewEndTimeObject = $StartTimeObject;
$StartTimeObject = $NewStartTimeObject;
$EndTimeObject = $NewEndTimeObject;
# we also need to turn the time in the tooltip around, otherwiese the time bar display would be wrong
$TicketDetail{ 'DynamicField_' . $StartTimeDynamicField } = $StartTimeObject->ToString();
$TicketDetail{ 'DynamicField_' . $EndTimeDynamicField } = $EndTimeObject->ToString();
# show a notification bar to indicate that the start and end time are set in a wrong way
$Content .= $LayoutObject->Notify(
Priority => 'Warning',
Info => Translatable('The start time of a ticket has been set after the end time!'),
Link => "index.pl?Action=AgentTicketZoom;TicketID=$TicketID",
);
}
my %Data;
# set start/end time individual units
# ex: SYear; EMinute
my $SetDataDateTimeUnits = sub {
my ( $Type, $Details ) = @_;
my $Prefix = substr( $Type, 0, 1 );
for my $Unit (qw(Year Month Day Hour Minute Second)) {
my $Value = $Details->{$Unit};
if ( $Unit eq 'Month' ) {
$Value -= 1;
}
$Data{"${Prefix}${Unit}"} = $Value;
}
return;
};
$SetDataDateTimeUnits->( Start => $StartTimeObject->Get() );
$SetDataDateTimeUnits->( End => $EndTimeObject->Get() );
#
$Data{ID} = $TicketID;
$Data{Title} = $TicketDetail{Title};
$Data{Color} = $Self->{TicketColors}->{$TicketID};
$Data{AllDay} = 'false';
$Data{Url} = "index.pl?Action=AgentTicketZoom;TicketID=$TicketID";
$Data{QueueName} = $QueuesAll{ $TicketDetail{QueueID} };
$Data{QueueName} =~ s/.*[\:]([^\:]+)$/$1/;
$Data{Description} = "";
# add 1 second to end date as workaround
# for a bug on full calendar when start and end
# dates are exactly the same (ESecond is 00 normally)
$Data{ESecond}++;
push @{ $Self->{EventsTicketCalendar} }, \%Data;
# add ticket info container
$LayoutObject->Block(
Name => 'EventInfo',
Data => \%Data,
);
# define container for dynamic fields
my @EventTicketDynamicFields;
# add ticket field for the event
if ( IsHashRefWithData($EventTicketFields) ) {
# include dynamic fields container
$LayoutObject->Block(
Name => 'EventTicketFieldContainer',
Data => \%Data,
);
# include dynamic fields
TICKETFIELD:
for my $Key ( sort keys %{$EventTicketFields} ) {
next TICKETFIELD if !$Key;
next TICKETFIELD if !$EventTicketFields->{$Key};
# skip dynamic fields, will them added later
if ( $Key =~ m{\A DynamicField_(.*) \z}msx ) {
my $DynamicFieldName = $Key;
$DynamicFieldName =~ s{\A DynamicField_ }{}msxg;
push @EventTicketDynamicFields, $DynamicFieldName;
next TICKETFIELD;
}
if ( $Key eq 'CustomerName' && $TicketDetail{CustomerUserID} ) {
$TicketDetail{$Key} = $CustomerUserObject->CustomerName(
UserLogin => $TicketDetail{CustomerUserID},
);
}
if ( $Key eq 'CustomerCompanyName' && $TicketDetail{CustomerID} ) {
my %CustomerCompany = $CustomerCompanyObject->CustomerCompanyGet(
CustomerID => $TicketDetail{CustomerID},
);
$TicketDetail{$Key} = $CustomerCompany{$Key};
}
if ( ( $Key eq 'Owner' || $Key eq 'Responsible' ) && $TicketDetail{$Key} ) {
my %UserData = $UserObject->GetUserData(
User => $TicketDetail{$Key},
);
$TicketDetail{$Key} = $UserData{UserFullname};
}
# translate state and priority name
if ( ( $Key eq 'State' || $Key eq 'Priority' ) && $TicketDetail{$Key} ) {
$TicketDetail{$Key} = $LayoutObject->{LanguageObject}->Translate( $TicketDetail{$Key} );
}
$LayoutObject->Block(
Name => 'CalendarEventInfoTicketFieldElement',
Data => {
InfoLabel => $EventTicketFields->{$Key},
InfoValue => $TicketDetail{$Key},
},
);
}
}
# merge event ticket dynamic fields
my $DynamicFieldsForEvent = [ @{$EventDynamicFields}, @EventTicketDynamicFields ];
# add dynamic field for the event
if ( IsArrayRefWithData($DynamicFieldsForEvent) ) {
# include dynamic fields container
$LayoutObject->Block(
Name => 'EventDynamicFieldContainer',
Data => \%Data,
);
# include dynamic fields
DYNAMICFIELD:
for my $Item ( @{$DynamicFieldsForEvent} ) {
next DYNAMICFIELD if !$Item;
next DYNAMICFIELD if !$Self->{DynamicFieldLookup}->{$Item}->{Label};
# check if we need to format the date
my $DisplayValue
= $Kernel::OM->Get('Kernel::System::DynamicField::Backend')->DisplayValueRender(
DynamicFieldConfig => $Self->{DynamicFieldLookup}->{$Item},
Value => $TicketDetail{ 'DynamicField_' . $Item },
LayoutObject => $LayoutObject,
);
$LayoutObject->Block(
Name => 'CalendarEventInfoDynamicFieldElement',
Data => {
InfoLabel => $Self->{DynamicFieldLookup}->{$Item}->{Label},
InfoValue => $DisplayValue->{Value},
},
);
}
}
$Counter++;
}
else {
$Limit-- if ( $Limit > 0 );
}
}
}
$LayoutObject->Block(
Name => 'CalendarDiv',
Data => {
CalendarWidth => $ConfigObject->{DashboardEventsTicketCalendar}->{CalendarWidth}
|| 95,
}
);
# send data to JS
$LayoutObject->AddJSData(
Key => 'EventsTicketCalendar',
Value => $Self->{EventsTicketCalendar},
);
$LayoutObject->AddJSData(
Key => 'FirstDay',
Value => $ConfigObject->Get('CalendarWeekDayStart') || 0,
);
$Content .= $LayoutObject->Output(
TemplateFile => 'DashboardEventsTicketCalendar',
Data => {},
);
return $Content;
}
1;