# -- # 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::AgentAppointmentEdit; use strict; use warnings; use Kernel::System::VariableCheck qw(:all); use Kernel::Language qw(Translatable); our $ObjectManagerDisabled = 1; sub new { my ( $Type, %Param ) = @_; my $Self = {%Param}; bless( $Self, $Type ); $Self->{EmptyString} = '-'; return $Self; } sub Run { my ( $Self, %Param ) = @_; my $Output; # get param object my $ParamObject = $Kernel::OM->Get('Kernel::System::Web::Request'); # get names of all parameters my @ParamNames = $ParamObject->GetParamNames(); # get params my %GetParam; PARAMNAME: for my $Key (@ParamNames) { # skip the Action parameter, it's giving BuildDateSelection problems for some reason next PARAMNAME if $Key eq 'Action'; $GetParam{$Key} = $ParamObject->GetParam( Param => $Key ); } my $ConfigObject = $Kernel::OM->Get('Kernel::Config'); my $LayoutObject = $Kernel::OM->Get('Kernel::Output::HTML::Layout'); my $CalendarObject = $Kernel::OM->Get('Kernel::System::Calendar'); my $AppointmentObject = $Kernel::OM->Get('Kernel::System::Calendar::Appointment'); my $PluginObject = $Kernel::OM->Get('Kernel::System::Calendar::Plugin'); my $JSON = $LayoutObject->JSONEncode( Data => [] ); my %PermissionLevel = ( 'ro' => 1, 'move_into' => 2, 'create' => 3, 'note' => 4, 'owner' => 5, 'priority' => 6, 'rw' => 7, ); my $Permissions = 'rw'; # challenge token check $LayoutObject->ChallengeTokenCheck(); # ------------------------------------------------------------ # # edit mask # ------------------------------------------------------------ # if ( $Self->{Subaction} eq 'EditMask' ) { # get all user's valid calendars my $ValidID = $Kernel::OM->Get('Kernel::System::Valid')->ValidLookup( Valid => 'valid', ); my @Calendars = $CalendarObject->CalendarList( UserID => $Self->{UserID}, ValidID => $ValidID, ); # transform data for select box my @CalendarData = map { { Key => $_->{CalendarID}, Value => $_->{CalendarName}, } } @Calendars; # transform data for ID lookup my %CalendarLookup = map { $_->{CalendarID} => $_->{CalendarName} } @Calendars; for my $Calendar (@CalendarData) { # check permissions my $CalendarPermission = $CalendarObject->CalendarPermissionGet( CalendarID => $Calendar->{Key}, UserID => $Self->{UserID}, ); if ( $PermissionLevel{$CalendarPermission} < 3 ) { # permissions < create $Calendar->{Disabled} = 1; } } # define year boundaries my ( %YearPeriodPast, %YearPeriodFuture ); for my $Field (qw (Start End RecurrenceUntil)) { $YearPeriodPast{$Field} = $YearPeriodFuture{$Field} = 5; } # do not use date selection time zone calculation by default my $OverrideTimeZone = 1; my %Appointment; if ( $GetParam{AppointmentID} ) { %Appointment = $AppointmentObject->AppointmentGet( AppointmentID => $GetParam{AppointmentID}, ); # non-existent appointment if ( !$Appointment{AppointmentID} ) { my $Output = $LayoutObject->Error( Message => Translatable('Appointment not found!'), ); return $LayoutObject->Attachment( NoCache => 1, ContentType => 'text/html', Charset => $LayoutObject->{UserCharset}, Content => $Output, Type => 'inline', ); } # use time zone calculation if editing existing appointments # but only if not dealing with an all day appointment else { $OverrideTimeZone = $Appointment{AllDay} || 0; } # check permissions $Permissions = $CalendarObject->CalendarPermissionGet( CalendarID => $Appointment{CalendarID}, UserID => $Self->{UserID}, ); # Get start time components. my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $Appointment{StartTime}, }, ); my $StartTimeSettings = $StartTimeObject->Get(); my $StartTimeComponents; for my $Key ( sort keys %{$StartTimeSettings} ) { $StartTimeComponents->{"Start$Key"} = $StartTimeSettings->{$Key}; } # Get end time components. my $EndTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $Appointment{EndTime}, }, ); # End times for all day appointments are inclusive, subtract whole day. if ( $Appointment{AllDay} ) { $EndTimeObject->Subtract( Days => 1, ); if ( $EndTimeObject < $StartTimeObject ) { $EndTimeObject = $StartTimeObject->Clone(); } } my $EndTimeSettings = $EndTimeObject->Get(); my $EndTimeComponents; for my $Key ( sort keys %{$EndTimeSettings} ) { $EndTimeComponents->{"End$Key"} = $EndTimeSettings->{$Key}; } %Appointment = ( %Appointment, %{$StartTimeComponents}, %{$EndTimeComponents} ); # Get recurrence until components. if ( $Appointment{RecurrenceUntil} ) { my $RecurrenceUntilTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $Appointment{RecurrenceUntil}, }, ); my $RecurrenceUntilSettings = $RecurrenceUntilTimeObject->Get(); my $RecurrenceUntilComponents; for my $Key ( sort keys %{$EndTimeSettings} ) { $RecurrenceUntilComponents->{"RecurrenceUntil$Key"} = $RecurrenceUntilSettings->{$Key}; } %Appointment = ( %Appointment, %{$RecurrenceUntilComponents} ); } # Recalculate year boundaries for build selection method. my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime'); my $DateTimeSettings = $DateTimeObject->Get(); for my $Field (qw(Start End RecurrenceUntil)) { if ( $Appointment{"${Field}Year"} ) { my $Diff = $Appointment{"${Field}Year"} - $DateTimeSettings->{Year}; if ( $Diff > 0 && abs $Diff > $YearPeriodFuture{$Field} ) { $YearPeriodFuture{$Field} = abs $Diff; } elsif ( $Diff < 0 && abs $Diff > $YearPeriodPast{$Field} ) { $YearPeriodPast{$Field} = abs $Diff; } } } if ( $Appointment{Recurring} ) { my $RecurrenceType = $GetParam{RecurrenceType} || $Appointment{RecurrenceType}; if ( $RecurrenceType eq 'CustomWeekly' ) { my $DayOffset = $Self->_DayOffsetGet( Time => $Appointment{StartTime}, ); if ( defined $GetParam{Days} ) { # check parameters $Appointment{Days} = $GetParam{Days}; } else { my @Days = @{ $Appointment{RecurrenceFrequency} }; # display selected days according to user timezone if ($DayOffset) { for my $Day (@Days) { $Day += $DayOffset; if ( $Day == 8 ) { $Day = 1; } } } $Appointment{Days} = join( ",", @Days ); } } elsif ( $RecurrenceType eq 'CustomMonthly' ) { my $DayOffset = $Self->_DayOffsetGet( Time => $Appointment{StartTime}, ); if ( defined $GetParam{MonthDays} ) { # check parameters $Appointment{MonthDays} = $GetParam{MonthDays}; } else { my @MonthDays = @{ $Appointment{RecurrenceFrequency} }; # display selected days according to user timezone if ($DayOffset) { for my $MonthDay (@MonthDays) { $MonthDay += $DayOffset; if ( $DateTimeSettings->{Day} == 32 ) { $MonthDay = 1; } } } $Appointment{MonthDays} = join( ",", @MonthDays ); } } elsif ( $RecurrenceType eq 'CustomYearly' ) { my $DayOffset = $Self->_DayOffsetGet( Time => $Appointment{StartTime}, ); if ( defined $GetParam{Months} ) { # check parameters $Appointment{Months} = $GetParam{Months}; } else { my @Months = @{ $Appointment{RecurrenceFrequency} }; $Appointment{Months} = join( ",", @Months ); } } } # Check if dealing with ticket appointment. if ( $Appointment{TicketAppointmentRuleID} ) { $GetParam{TicketID} = $CalendarObject->TicketAppointmentTicketID( AppointmentID => $Appointment{AppointmentID}, ); my $Rule = $CalendarObject->TicketAppointmentRuleGet( CalendarID => $Appointment{CalendarID}, RuleID => $Appointment{TicketAppointmentRuleID}, ); # Get date types from the ticket appointment rule. if ( IsHashRefWithData($Rule) ) { for my $Type (qw(StartDate EndDate)) { if ( $Rule->{$Type} eq 'FirstResponseTime' || $Rule->{$Type} eq 'UpdateTime' || $Rule->{$Type} eq 'SolutionTime' || $Rule->{$Type} eq 'PendingTime' ) { $GetParam{ReadOnlyStart} = 1 if $Type eq 'StartDate'; $GetParam{ReadOnlyDuration} = 1 if $Type eq 'EndDate'; } elsif ( $Rule->{$Type} =~ /^Plus_[0-9]+$/ ) { $GetParam{ReadOnlyDuration} = 1; } } } } } # get selected timestamp my $SelectedTimestamp = sprintf( "%04d-%02d-%02d 00:00:00", $Appointment{StartYear} // $GetParam{StartYear}, $Appointment{StartMonth} // $GetParam{StartMonth}, $Appointment{StartDay} // $GetParam{StartDay} ); # Get current date components. my $SelectedSystemTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $SelectedTimestamp, }, ); my $SelectedSystemTimeSettings = $SelectedSystemTimeObject->Get(); # Set current date components if not defined. $Appointment{Days} //= $SelectedSystemTimeSettings->{DayOfWeek}; $Appointment{MonthDays} //= $SelectedSystemTimeSettings->{Day}; $Appointment{Months} //= $SelectedSystemTimeSettings->{Month}; # calendar ID selection my $CalendarID = $Appointment{CalendarID} // $GetParam{CalendarID}; # calendar name if ($CalendarID) { $Param{CalendarName} = $CalendarLookup{$CalendarID}; } # calendar selection $Param{CalendarIDStrg} = $LayoutObject->BuildSelection( Data => \@CalendarData, SelectedID => $CalendarID, Name => 'CalendarID', Multiple => 0, Class => 'Modernize Validate_Required', PossibleNone => 1, ); # all day if ( $GetParam{AllDay} || ( $GetParam{AppointmentID} && $Appointment{AllDay} ) ) { $Param{AllDayString} = Translatable('Yes'); $Param{AllDayChecked} = 'checked="checked"'; # start date $Param{StartDate} = sprintf( "%04d-%02d-%02d", $Appointment{StartYear} // $GetParam{StartYear}, $Appointment{StartMonth} // $GetParam{StartMonth}, $Appointment{StartDay} // $GetParam{StartDay}, ); # end date $Param{EndDate} = sprintf( "%04d-%02d-%02d", $Appointment{EndYear} // $GetParam{EndYear}, $Appointment{EndMonth} // $GetParam{EndMonth}, $Appointment{EndDay} // $GetParam{EndDay}, ); } else { $Param{AllDayString} = Translatable('No'); $Param{AllDayChecked} = ''; # start date $Param{StartDate} = sprintf( "%04d-%02d-%02d %02d:%02d:00", $Appointment{StartYear} // $GetParam{StartYear}, $Appointment{StartMonth} // $GetParam{StartMonth}, $Appointment{StartDay} // $GetParam{StartDay}, $Appointment{StartHour} // $GetParam{StartHour}, $Appointment{StartMinute} // $GetParam{StartMinute}, ); # end date $Param{EndDate} = sprintf( "%04d-%02d-%02d %02d:%02d:00", $Appointment{EndYear} // $GetParam{EndYear}, $Appointment{EndMonth} // $GetParam{EndMonth}, $Appointment{EndDay} // $GetParam{EndDay}, $Appointment{EndHour} // $GetParam{EndHour}, $Appointment{EndMinute} // $GetParam{EndMinute}, ); } # start date string $Param{StartDateString} = $LayoutObject->BuildDateSelection( %GetParam, %Appointment, Prefix => 'Start', StartHour => $Appointment{StartHour} // $GetParam{StartHour}, StartMinute => $Appointment{StartMinute} // $GetParam{StartMinute}, Format => 'DateInputFormatLong', ValidateDateBeforePrefix => 'End', Validate => $Appointment{TicketAppointmentRuleID} && $GetParam{ReadOnlyStart} ? 0 : 1, YearPeriodPast => $YearPeriodPast{Start}, YearPeriodFuture => $YearPeriodFuture{Start}, OverrideTimeZone => $OverrideTimeZone, ); # end date string $Param{EndDateString} = $LayoutObject->BuildDateSelection( %GetParam, %Appointment, Prefix => 'End', EndHour => $Appointment{EndHour} // $GetParam{EndHour}, EndMinute => $Appointment{EndMinute} // $GetParam{EndMinute}, Format => 'DateInputFormatLong', ValidateDateAfterPrefix => 'Start', Validate => $Appointment{TicketAppointmentRuleID} && $GetParam{ReadOnlyDuration} ? 0 : 1, YearPeriodPast => $YearPeriodPast{End}, YearPeriodFuture => $YearPeriodFuture{End}, OverrideTimeZone => $OverrideTimeZone, ); # get main object my $MainObject = $Kernel::OM->Get('Kernel::System::Main'); # check if team object is registered if ( $MainObject->Require( 'Kernel::System::Calendar::Team', Silent => 1 ) ) { my $TeamIDs = $Appointment{TeamID}; if ( !$TeamIDs ) { my @TeamIDs = $ParamObject->GetArray( Param => 'TeamID[]' ); $TeamIDs = \@TeamIDs; } my $ResourceIDs = $Appointment{ResourceID}; if ( !$ResourceIDs ) { my @ResourceIDs = $ParamObject->GetArray( Param => 'ResourceID[]' ); $ResourceIDs = \@ResourceIDs; } # get needed objects my $TeamObject = $Kernel::OM->Get('Kernel::System::Calendar::Team'); my $UserObject = $Kernel::OM->Get('Kernel::System::User'); # get allowed team list for current user my %TeamList = $TeamObject->AllowedTeamList( PreventEmpty => 1, UserID => $Self->{UserID}, ); # team names my @TeamNames; for my $TeamID ( @{$TeamIDs} ) { push @TeamNames, $TeamList{$TeamID} if $TeamList{$TeamID}; } if ( scalar @TeamNames ) { $Param{TeamNames} = join( '
', @TeamNames ); } else { $Param{TeamNames} = $Self->{EmptyString}; } # team list string $Param{TeamIDStrg} = $LayoutObject->BuildSelection( Data => \%TeamList, SelectedID => $TeamIDs, Name => 'TeamID', Multiple => 1, Class => 'Modernize', PossibleNone => 1, ); # iterate through selected teams my %TeamUserListAll; TEAMID: for my $TeamID ( @{$TeamIDs} ) { next TEAMID if !$TeamID; # get list of team members my %TeamUserList = $TeamObject->TeamUserList( TeamID => $TeamID, UserID => $Self->{UserID}, ); # get user data for my $UserID ( sort keys %TeamUserList ) { my %User = $UserObject->GetUserData( UserID => $UserID, ); $TeamUserList{$UserID} = $User{UserFullname}; } %TeamUserListAll = ( %TeamUserListAll, %TeamUserList ); } # resource names my @ResourceNames; for my $ResourceID ( @{$ResourceIDs} ) { push @ResourceNames, $TeamUserListAll{$ResourceID} if $TeamUserListAll{$ResourceID}; } if ( scalar @ResourceNames ) { $Param{ResourceNames} = join( '
', @ResourceNames ); } else { $Param{ResourceNames} = $Self->{EmptyString}; } # team user list string $Param{ResourceIDStrg} = $LayoutObject->BuildSelection( Data => \%TeamUserListAll, SelectedID => $ResourceIDs, Name => 'ResourceID', Multiple => 1, Class => 'Modernize', PossibleNone => 1, ); } my $SelectedRecurrenceType = 0; my $SelectedRecurrenceCustomType = 'CustomDaily'; # default if ( $Appointment{Recurring} ) { # from appointment $SelectedRecurrenceType = $GetParam{RecurrenceType} || $Appointment{RecurrenceType}; if ( $SelectedRecurrenceType =~ /Custom/ ) { $SelectedRecurrenceCustomType = $SelectedRecurrenceType; $SelectedRecurrenceType = 'Custom'; } } # recurrence type my @RecurrenceTypes = ( { Key => '0', Value => Translatable('Never'), }, { Key => 'Daily', Value => Translatable('Every Day'), }, { Key => 'Weekly', Value => Translatable('Every Week'), }, { Key => 'Monthly', Value => Translatable('Every Month'), }, { Key => 'Yearly', Value => Translatable('Every Year'), }, { Key => 'Custom', Value => Translatable('Custom'), }, ); my %RecurrenceTypeLookup = map { $_->{Key} => $_->{Value} } @RecurrenceTypes; $Param{RecurrenceValue} = $LayoutObject->{LanguageObject}->Translate( $RecurrenceTypeLookup{$SelectedRecurrenceType}, ); # recurrence type selection $Param{RecurrenceTypeString} = $LayoutObject->BuildSelection( Data => \@RecurrenceTypes, SelectedID => $SelectedRecurrenceType, Name => 'RecurrenceType', Multiple => 0, Class => 'Modernize', PossibleNone => 0, ); # recurrence custom type my @RecurrenceCustomTypes = ( { Key => 'CustomDaily', Value => Translatable('Daily'), }, { Key => 'CustomWeekly', Value => Translatable('Weekly'), }, { Key => 'CustomMonthly', Value => Translatable('Monthly'), }, { Key => 'CustomYearly', Value => Translatable('Yearly'), }, ); my %RecurrenceCustomTypeLookup = map { $_->{Key} => $_->{Value} } @RecurrenceCustomTypes; my $RecurrenceCustomType = $RecurrenceCustomTypeLookup{$SelectedRecurrenceCustomType}; $Param{RecurrenceValue} .= ', ' . $LayoutObject->{LanguageObject}->Translate( lc $RecurrenceCustomType, ) if $RecurrenceCustomType && $SelectedRecurrenceType eq 'Custom'; # recurrence custom type selection $Param{RecurrenceCustomTypeString} = $LayoutObject->BuildSelection( Data => \@RecurrenceCustomTypes, SelectedID => $SelectedRecurrenceCustomType, Name => 'RecurrenceCustomType', Class => 'Modernize', ); # recurrence interval my $SelectedInterval = $GetParam{RecurrenceInterval} || $Appointment{RecurrenceInterval} || 1; if ( $Appointment{RecurrenceInterval} ) { my %RecurrenceIntervalLookup = ( 'CustomDaily' => $LayoutObject->{LanguageObject}->Translate( 'day(s)', ), 'CustomWeekly' => $LayoutObject->{LanguageObject}->Translate( 'week(s)', ), 'CustomMonthly' => $LayoutObject->{LanguageObject}->Translate( 'month(s)', ), 'CustomYearly' => $LayoutObject->{LanguageObject}->Translate( 'year(s)', ), ); if ( $RecurrenceCustomType && $SelectedRecurrenceType eq 'Custom' ) { $Param{RecurrenceValue} .= ', ' . $LayoutObject->{LanguageObject}->Translate('every') . ' ' . $Appointment{RecurrenceInterval} . ' ' . $RecurrenceIntervalLookup{$SelectedRecurrenceCustomType}; } } # add interval selection (1-31) my @RecurrenceCustomInterval; for ( my $DayNumber = 1; $DayNumber < 32; $DayNumber++ ) { push @RecurrenceCustomInterval, { Key => $DayNumber, Value => $DayNumber, }; } $Param{RecurrenceIntervalString} = $LayoutObject->BuildSelection( Data => \@RecurrenceCustomInterval, SelectedID => $SelectedInterval, Name => 'RecurrenceInterval', ); # recurrence limit my $RecurrenceLimit = 1; if ( $Appointment{RecurrenceCount} ) { $RecurrenceLimit = 2; if ($SelectedRecurrenceType) { $Param{RecurrenceValue} .= ', ' . $LayoutObject->{LanguageObject}->Translate( 'for %s time(s)', $Appointment{RecurrenceCount}, ); } } # recurrence limit string $Param{RecurrenceLimitString} = $LayoutObject->BuildSelection( Data => [ { Key => 1, Value => Translatable('until ...'), }, { Key => 2, Value => Translatable('for ... time(s)'), }, ], SelectedID => $RecurrenceLimit, Name => 'RecurrenceLimit', Multiple => 0, Class => 'Modernize', PossibleNone => 0, ); my $RecurrenceUntilDiffTime = 0; if ( !$Appointment{RecurrenceUntil} ) { # Get current and start time for difference. my $SystemTime = $Kernel::OM->Create('Kernel::System::DateTime')->ToEpoch(); my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { Year => $Appointment{StartYear} // $GetParam{StartYear}, Month => $Appointment{StartMonth} // $GetParam{StartMonth}, Day => $Appointment{StartDay} // $GetParam{StartDay}, Hour => $Appointment{StartHour} // $GetParam{StartHour}, Minute => $Appointment{StartMinute} // $GetParam{StartMinute}, Second => 0, }, ); my $StartTime = $StartTimeObject->ToEpoch(); $RecurrenceUntilDiffTime = $StartTime - $SystemTime + 60 * 60 * 24 * 3; # start +3 days } else { $Param{RecurrenceUntil} = sprintf( "%04d-%02d-%02d", $Appointment{RecurrenceUntilYear}, $Appointment{RecurrenceUntilMonth}, $Appointment{RecurrenceUntilDay}, ); if ($SelectedRecurrenceType) { $Param{RecurrenceValue} .= ', ' . $LayoutObject->{LanguageObject}->Translate( 'until %s', $Param{RecurrenceUntil}, ); } } # recurrence until date string $Param{RecurrenceUntilString} = $LayoutObject->BuildDateSelection( %Appointment, %GetParam, Prefix => 'RecurrenceUntil', Format => 'DateInputFormat', DiffTime => $RecurrenceUntilDiffTime, ValidateDateAfterPrefix => 'Start', Validate => 1, YearPeriodPast => $YearPeriodPast{RecurrenceUntil}, YearPeriodFuture => $YearPeriodFuture{RecurrenceUntil}, OverrideTimeZone => $OverrideTimeZone, ); # notification template my @NotificationTemplates = ( { Key => '0', Value => $LayoutObject->{LanguageObject}->Translate('No notification'), }, { Key => 'Start', Value => $LayoutObject->{LanguageObject}->Translate( '%s minute(s) before', 0 ), }, { Key => '300', Value => $LayoutObject->{LanguageObject}->Translate( '%s minute(s) before', 5 ), }, { Key => '900', Value => $LayoutObject->{LanguageObject}->Translate( '%s minute(s) before', 15 ), }, { Key => '1800', Value => $LayoutObject->{LanguageObject}->Translate( '%s minute(s) before', 30 ), }, { Key => '3600', Value => $LayoutObject->{LanguageObject}->Translate( '%s hour(s) before', 1 ), }, { Key => '7200', Value => $LayoutObject->{LanguageObject}->Translate( '%s hour(s) before', 2 ), }, { Key => '43200', Value => $LayoutObject->{LanguageObject}->Translate( '%s hour(s) before', 12 ), }, { Key => '86400', Value => $LayoutObject->{LanguageObject}->Translate( '%s day(s) before', 1 ), }, { Key => '172800', Value => $LayoutObject->{LanguageObject}->Translate( '%s day(s) before', 2 ), }, { Key => '604800', Value => $LayoutObject->{LanguageObject}->Translate( '%s week before', 1 ), }, { Key => 'Custom', Value => $LayoutObject->{LanguageObject}->Translate('Custom'), }, ); my %NotificationTemplateLookup = map { $_->{Key} => $_->{Value} } @NotificationTemplates; my $SelectedNotificationTemplate = $Appointment{NotificationTemplate} || '0'; $Param{NotificationValue} = $NotificationTemplateLookup{$SelectedNotificationTemplate}; # notification selection $Param{NotificationStrg} = $LayoutObject->BuildSelection( Data => \@NotificationTemplates, SelectedID => $SelectedNotificationTemplate, Name => 'NotificationTemplate', Multiple => 0, Class => 'Modernize', PossibleNone => 0, ); # notification custom units my @NotificationCustomUnits = ( { Key => 'minutes', Value => $LayoutObject->{LanguageObject}->Translate('minute(s)'), }, { Key => 'hours', Value => $LayoutObject->{LanguageObject}->Translate('hour(s)'), }, { Key => 'days', Value => $LayoutObject->{LanguageObject}->Translate('day(s)'), }, ); my %NotificationCustomUnitLookup = map { $_->{Key} => $_->{Value} } @NotificationCustomUnits; my $SelectedNotificationCustomUnit = $Appointment{NotificationCustomRelativeUnit} || 'minutes'; # notification custom units selection $Param{NotificationCustomUnitsStrg} = $LayoutObject->BuildSelection( Data => \@NotificationCustomUnits, SelectedID => $SelectedNotificationCustomUnit, Name => 'NotificationCustomRelativeUnit', Multiple => 0, Class => 'Modernize', PossibleNone => 0, ); # notification custom units point of time my @NotificationCustomUnitsPointOfTime = ( { Key => 'beforestart', Value => $LayoutObject->{LanguageObject}->Translate('before the appointment starts'), }, { Key => 'afterstart', Value => $LayoutObject->{LanguageObject}->Translate('after the appointment has been started'), }, { Key => 'beforeend', Value => $LayoutObject->{LanguageObject}->Translate('before the appointment ends'), }, { Key => 'afterend', Value => $LayoutObject->{LanguageObject}->Translate('after the appointment has been ended'), }, ); my %NotificationCustomUnitPointOfTimeLookup = map { $_->{Key} => $_->{Value} } @NotificationCustomUnitsPointOfTime; my $SelectedNotificationCustomUnitPointOfTime = $Appointment{NotificationCustomRelativePointOfTime} || 'beforestart'; # notification custom units point of time selection $Param{NotificationCustomUnitsPointOfTimeStrg} = $LayoutObject->BuildSelection( Data => \@NotificationCustomUnitsPointOfTime, SelectedID => $SelectedNotificationCustomUnitPointOfTime, Name => 'NotificationCustomRelativePointOfTime', Multiple => 0, Class => 'Modernize', PossibleNone => 0, ); # Extract the date units for the custom date selection. my $NotificationCustomDateTimeSettings = {}; if ( $Appointment{NotificationCustomDateTime} ) { my $NotificationCustomDateTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $Appointment{NotificationCustomDateTime}, }, ); $NotificationCustomDateTimeSettings = $NotificationCustomDateTimeObject->Get(); } # notification custom date selection $Param{NotificationCustomDateTimeStrg} = $LayoutObject->BuildDateSelection( Prefix => 'NotificationCustomDateTime', NotificationCustomDateTimeYear => $NotificationCustomDateTimeSettings->{Year}, NotificationCustomDateTimeMonth => $NotificationCustomDateTimeSettings->{Month}, NotificationCustomDateTimeDay => $NotificationCustomDateTimeSettings->{Day}, NotificationCustomDateTimeHour => $NotificationCustomDateTimeSettings->{Hour}, NotificationCustomDateTimeMinute => $NotificationCustomDateTimeSettings->{Minute}, Format => 'DateInputFormatLong', YearPeriodPast => $YearPeriodPast{Start}, YearPeriodFuture => $YearPeriodFuture{Start}, ); # prepare radio button for custom date time and relative input $Appointment{NotificationCustom} ||= ''; if ( $Appointment{NotificationCustom} eq 'datetime' ) { $Param{NotificationCustomDateTimeInputRadio} = 'checked="checked"'; } elsif ( $Appointment{NotificationCustom} eq 'relative' ) { $Param{NotificationCustomRelativeInputRadio} = 'checked="checked"'; } else { $Param{NotificationCustomRelativeInputRadio} = 'checked="checked"'; } # notification custom string value if ( $Appointment{NotificationCustom} eq 'datetime' ) { $Param{NotificationValue} .= ', ' . $LayoutObject->{LanguageObject}->FormatTimeString( $Appointment{NotificationCustomDateTime}, 'DateFormat' ); } elsif ( $Appointment{NotificationCustom} eq 'relative' ) { if ( $Appointment{NotificationCustomRelativeUnit} && $Appointment{NotificationCustomRelativePointOfTime} ) { $Appointment{NotificationCustomRelativeUnitCount} ||= 0; $Param{NotificationValue} .= ', ' . $Appointment{NotificationCustomRelativeUnitCount} . ' ' . $NotificationCustomUnitLookup{$SelectedNotificationCustomUnit} . ' ' . $NotificationCustomUnitPointOfTimeLookup{$SelectedNotificationCustomUnitPointOfTime}; } } # get plugin list $Param{PluginList} = $PluginObject->PluginList(); # new appointment plugin search if ( $GetParam{PluginKey} && ( $GetParam{Search} || $GetParam{ObjectID} ) ) { if ( grep { $_ eq $GetParam{PluginKey} } keys %{ $Param{PluginList} } ) { # search using plugin my $ResultList = $PluginObject->PluginSearch( %GetParam, UserID => $Self->{UserID}, ); $Param{PluginData}->{ $GetParam{PluginKey} } = []; my @LinkArray = sort keys %{$ResultList}; # add possible links for my $LinkID (@LinkArray) { push @{ $Param{PluginData}->{ $GetParam{PluginKey} } }, { LinkID => $LinkID, LinkName => $ResultList->{$LinkID}, LinkURL => sprintf( $Param{PluginList}->{ $GetParam{PluginKey} }->{PluginURL}, $LinkID ), }; } $Param{PluginList}->{ $GetParam{PluginKey} }->{LinkList} = $LayoutObject->JSONEncode( Data => \@LinkArray, ); } } # edit appointment plugin links elsif ( $GetParam{AppointmentID} ) { for my $PluginKey ( sort keys %{ $Param{PluginList} } ) { my $LinkList = $PluginObject->PluginLinkList( AppointmentID => $GetParam{AppointmentID}, PluginKey => $PluginKey, UserID => $Self->{UserID}, ); my @LinkArray; $Param{PluginData}->{$PluginKey} = []; for my $LinkID ( sort keys %{$LinkList} ) { push @{ $Param{PluginData}->{$PluginKey} }, $LinkList->{$LinkID}; push @LinkArray, $LinkList->{$LinkID}->{LinkID}; } $Param{PluginList}->{$PluginKey}->{LinkList} = $LayoutObject->JSONEncode( Data => \@LinkArray, ); } } # html mask output $LayoutObject->Block( Name => 'EditMask', Data => { %Param, %GetParam, %Appointment, PermissionLevel => $PermissionLevel{$Permissions}, }, ); $LayoutObject->AddJSData( Key => 'CalendarPermissionLevel', Value => $PermissionLevel{$Permissions}, ); $LayoutObject->AddJSData( Key => 'EditAppointmentID', Value => $Appointment{AppointmentID} // '', ); $LayoutObject->AddJSData( Key => 'EditParentID', Value => $Appointment{ParentID} // '', ); # get registered location links my $LocationLinkConfig = $ConfigObject->Get('AgentAppointmentEdit::Location::Link') // {}; for my $ConfigKey ( sort keys %{$LocationLinkConfig} ) { # show link icon $LayoutObject->Block( Name => 'LocationLink', Data => { Location => $Appointment{Location} // '', %{ $LocationLinkConfig->{$ConfigKey} }, }, ); } my $Output = $LayoutObject->Output( TemplateFile => 'AgentAppointmentEdit', Data => { %Param, %GetParam, %Appointment, }, AJAX => 1, ); return $LayoutObject->Attachment( NoCache => 1, ContentType => 'text/html', Charset => $LayoutObject->{UserCharset}, Content => $Output, Type => 'inline', ); } # ------------------------------------------------------------ # # add/edit appointment # ------------------------------------------------------------ # elsif ( $Self->{Subaction} eq 'EditAppointment' ) { my %Appointment; if ( $GetParam{AppointmentID} ) { %Appointment = $AppointmentObject->AppointmentGet( AppointmentID => $GetParam{AppointmentID}, ); # check permissions $Permissions = $CalendarObject->CalendarPermissionGet( CalendarID => $Appointment{CalendarID}, UserID => $Self->{UserID}, ); my $RequiredPermission = 2; if ( $GetParam{CalendarID} && $GetParam{CalendarID} != $Appointment{CalendarID} ) { # in order to move appointment to another calendar, user needs "create" permission $RequiredPermission = 3; } if ( $PermissionLevel{$Permissions} < $RequiredPermission ) { # no permission # build JSON output $JSON = $LayoutObject->JSONEncode( Data => { Success => 0, Error => Translatable('No permission!'), }, ); # send JSON response return $LayoutObject->Attachment( ContentType => 'application/json; charset=' . $LayoutObject->{Charset}, Content => $JSON, Type => 'inline', NoCache => 1, ); } } if ( $GetParam{AllDay} ) { $GetParam{StartTime} = sprintf( "%04d-%02d-%02d 00:00:00", $GetParam{StartYear}, $GetParam{StartMonth}, $GetParam{StartDay} ); $GetParam{EndTime} = sprintf( "%04d-%02d-%02d 00:00:00", $GetParam{EndYear}, $GetParam{EndMonth}, $GetParam{EndDay} ); my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{StartTime}, }, ); my $EndTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{EndTime}, }, ); # Prevent storing end time before start time. if ( $EndTimeObject < $StartTimeObject ) { $EndTimeObject = $StartTimeObject->Clone(); } # Make end time inclusive, add whole day. $EndTimeObject->Add( Days => 1, ); $GetParam{EndTime} = $EndTimeObject->ToString(); } elsif ( $GetParam{Recurring} && $GetParam{UpdateType} && $GetParam{UpdateDelta} ) { my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $Appointment{StartTime}, }, ); my $EndTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $Appointment{EndTime}, }, ); # Calculate new start/end times. if ( $GetParam{UpdateType} eq 'StartTime' ) { $StartTimeObject->Add( Seconds => $GetParam{UpdateDelta}, ); $GetParam{StartTime} = $StartTimeObject->ToString(); } elsif ( $GetParam{UpdateType} eq 'EndTime' ) { $EndTimeObject->Add( Seconds => $GetParam{UpdateDelta}, ); $GetParam{EndTime} = $EndTimeObject->ToString(); } else { $StartTimeObject->Add( Seconds => $GetParam{UpdateDelta}, ); $EndTimeObject->Add( Seconds => $GetParam{UpdateDelta}, ); $GetParam{StartTime} = $StartTimeObject->ToString(); $GetParam{EndTime} = $EndTimeObject->ToString(); } } else { if ( defined $GetParam{StartYear} && defined $GetParam{StartMonth} && defined $GetParam{StartDay} && defined $GetParam{StartHour} && defined $GetParam{StartMinute} ) { $GetParam{StartTime} = sprintf( "%04d-%02d-%02d %02d:%02d:00", $GetParam{StartYear}, $GetParam{StartMonth}, $GetParam{StartDay}, $GetParam{StartHour}, $GetParam{StartMinute} ); # Convert start time to local time. my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{StartTime}, TimeZone => $Self->{UserTimeZone}, }, ); if ( $Self->{UserTimeZone} ) { $StartTimeObject->ToOTRSTimeZone(); } $GetParam{StartTime} = $StartTimeObject->ToString(); } else { $GetParam{StartTime} = $Appointment{StartTime}; } if ( defined $GetParam{EndYear} && defined $GetParam{EndMonth} && defined $GetParam{EndDay} && defined $GetParam{EndHour} && defined $GetParam{EndMinute} ) { $GetParam{EndTime} = sprintf( "%04d-%02d-%02d %02d:%02d:00", $GetParam{EndYear}, $GetParam{EndMonth}, $GetParam{EndDay}, $GetParam{EndHour}, $GetParam{EndMinute} ); # Convert end time to local time. my $EndTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{EndTime}, TimeZone => $Self->{UserTimeZone}, }, ); if ( $Self->{UserTimeZone} ) { $EndTimeObject->ToOTRSTimeZone(); } # Get already calculated local start time. my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{StartTime}, }, ); # Prevent storing end time before start time. if ( $EndTimeObject < $StartTimeObject ) { $EndTimeObject = $StartTimeObject->Clone(); } $GetParam{EndTime} = $EndTimeObject->ToString(); } else { $GetParam{EndTime} = $Appointment{EndTime}; } } # Prevent recurrence until dates before start time. if ( $Appointment{Recurring} && $Appointment{RecurrenceUntil} ) { my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{StartTime}, }, ); my $RecurrenceUntilObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $Appointment{RecurrenceUntil}, }, ); if ( $RecurrenceUntilObject < $StartTimeObject ) { $Appointment{RecurrenceUntil} = $GetParam{StartTime}; } } # recurring appointment if ( $GetParam{Recurring} && $GetParam{RecurrenceType} ) { if ( $GetParam{RecurrenceType} eq 'Daily' || $GetParam{RecurrenceType} eq 'Weekly' || $GetParam{RecurrenceType} eq 'Monthly' || $GetParam{RecurrenceType} eq 'Yearly' ) { $GetParam{RecurrenceInterval} = 1; } elsif ( $GetParam{RecurrenceType} eq 'Custom' ) { if ( $GetParam{RecurrenceCustomType} eq 'CustomWeekly' ) { if ( $GetParam{Days} ) { my @Days = split( ",", $GetParam{Days} ); $GetParam{RecurrenceFrequency} = \@Days; } else { my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{StartTime}, }, ); my $StartTimeSettings = $StartTimeObject->Get(); $GetParam{RecurrenceFrequency} = [ $StartTimeSettings->{DayOfWeek} ]; } } elsif ( $GetParam{RecurrenceCustomType} eq 'CustomMonthly' ) { if ( $GetParam{MonthDays} ) { my @MonthDays = split( ",", $GetParam{MonthDays} ); $GetParam{RecurrenceFrequency} = \@MonthDays; } else { my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{StartTime}, }, ); my $StartTimeSettings = $StartTimeObject->Get(); $GetParam{RecurrenceFrequency} = [ $StartTimeSettings->{Day} ]; } } elsif ( $GetParam{RecurrenceCustomType} eq 'CustomYearly' ) { if ( $GetParam{Months} ) { my @Months = split( ",", $GetParam{Months} ); $GetParam{RecurrenceFrequency} = \@Months; } else { my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{StartTime}, }, ); my $StartTimeSettings = $StartTimeObject->Get(); $GetParam{RecurrenceFrequency} = [ $StartTimeSettings->{Month} ]; } } $GetParam{RecurrenceType} = $GetParam{RecurrenceCustomType}; } # until ... if ( $GetParam{RecurrenceLimit} eq '1' && $GetParam{RecurrenceUntilYear} && $GetParam{RecurrenceUntilMonth} && $GetParam{RecurrenceUntilDay} ) { $GetParam{RecurrenceUntil} = sprintf( "%04d-%02d-%02d 00:00:00", $GetParam{RecurrenceUntilYear}, $GetParam{RecurrenceUntilMonth}, $GetParam{RecurrenceUntilDay} ); # Prevent recurrence until dates before start time. my $StartTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{StartTime}, }, ); my $RecurrenceUntilObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{RecurrenceUntil}, }, ); if ( $RecurrenceUntilObject < $StartTimeObject ) { $GetParam{RecurrenceUntil} = $GetParam{StartTime}; } $GetParam{RecurrenceCount} = undef; } # for ... time(s) elsif ( $GetParam{RecurrenceLimit} eq '2' ) { $GetParam{RecurrenceUntil} = undef; } } # Determine notification custom type, if supplied. if ( defined $GetParam{NotificationTemplate} ) { if ( $GetParam{NotificationTemplate} ne 'Custom' ) { $GetParam{NotificationCustom} = ''; } elsif ( $GetParam{NotificationCustomRelativeInput} ) { $GetParam{NotificationCustom} = 'relative'; } elsif ( $GetParam{NotificationCustomDateTimeInput} ) { $GetParam{NotificationCustom} = 'datetime'; $GetParam{NotificationCustomDateTime} = sprintf( "%04d-%02d-%02d %02d:%02d:00", $GetParam{NotificationCustomDateTimeYear}, $GetParam{NotificationCustomDateTimeMonth}, $GetParam{NotificationCustomDateTimeDay}, $GetParam{NotificationCustomDateTimeHour}, $GetParam{NotificationCustomDateTimeMinute} ); my $NotificationCustomDateTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{NotificationCustomDateTime}, TimeZone => $Self->{UserTimeZone}, }, ); if ( $Self->{UserTimeZone} ) { $NotificationCustomDateTimeObject->ToOTRSTimeZone(); } $GetParam{NotificationCustomDateTime} = $NotificationCustomDateTimeObject->ToString(); } } # team if ( $GetParam{'TeamID[]'} ) { my @TeamIDs = $ParamObject->GetArray( Param => 'TeamID[]' ); $GetParam{TeamID} = \@TeamIDs; } else { $GetParam{TeamID} = undef; } # resources if ( $GetParam{'ResourceID[]'} ) { my @ResourceID = $ParamObject->GetArray( Param => 'ResourceID[]' ); $GetParam{ResourceID} = \@ResourceID; } else { $GetParam{ResourceID} = undef; } # Check if dealing with ticket appointment. if ( $Appointment{TicketAppointmentRuleID} ) { # Make sure readonly values stay unchanged. $GetParam{Title} = $Appointment{Title}; $GetParam{CalendarID} = $Appointment{CalendarID}; $GetParam{AllDay} = undef; $GetParam{Recurring} = undef; my $Rule = $CalendarObject->TicketAppointmentRuleGet( CalendarID => $Appointment{CalendarID}, RuleID => $Appointment{TicketAppointmentRuleID}, ); # Recalculate end time based on time preset. if ( IsHashRefWithData($Rule) ) { if ( $Rule->{EndDate} =~ /^Plus_([0-9]+)$/ && $GetParam{StartTime} ) { my $Preset = int $1; my $EndTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $GetParam{StartTime}, # base on start time }, ); # Calculate end time using preset value. $EndTimeObject->Add( Minutes => $Preset, ); $GetParam{EndTime} = $EndTimeObject->ToString(); } } } my $Success; # reset empty parameters for my $Param ( sort keys %GetParam ) { if ( !$GetParam{$Param} ) { $GetParam{$Param} = undef; } } # pass current user ID $GetParam{UserID} = $Self->{UserID}; # Get passed plugin parameters. my @PluginParams = grep { $_ =~ /^Plugin_/ } keys %GetParam; if (%Appointment) { # Continue only if coming from edit screen # (there is at least one passed plugin parameter). if (@PluginParams) { # Get all related appointments before the update. my @RelatedAppointments = ( $Appointment{AppointmentID} ); my @CalendarAppointments = $AppointmentObject->AppointmentList( CalendarID => $Appointment{CalendarID}, ); # If we are dealing with a parent, include any child appointments. push @RelatedAppointments, map { $_->{AppointmentID} } grep { defined $_->{ParentID} && $_->{ParentID} eq $Appointment{AppointmentID} } @CalendarAppointments; # Remove all existing links. for my $CurrentAppointmentID (@RelatedAppointments) { my $Success = $PluginObject->PluginLinkDelete( AppointmentID => $CurrentAppointmentID, UserID => $Self->{UserID}, ); if ( !$Success ) { $Kernel::OM->Get('Kernel::System::Log')->Log( Priority => 'error', Message => "Links could not be deleted for appointment $CurrentAppointmentID!", ); } } } $Success = $AppointmentObject->AppointmentUpdate( %Appointment, %GetParam, ); } else { $Success = $AppointmentObject->AppointmentCreate( %GetParam, ); } my $AppointmentID = $GetParam{AppointmentID} ? $GetParam{AppointmentID} : $Success; if ($AppointmentID) { # Continue only if coming from edit screen # (there is at least one passed plugin parameter). if (@PluginParams) { # Get fresh appointment data. %Appointment = $AppointmentObject->AppointmentGet( AppointmentID => $AppointmentID, ); # Process all related appointments. my @RelatedAppointments = ($AppointmentID); my @CalendarAppointments = $AppointmentObject->AppointmentList( CalendarID => $Appointment{CalendarID}, ); # If we are dealing with a parent, include any child appointments as well. push @RelatedAppointments, map { $_->{AppointmentID} } grep { defined $_->{ParentID} && $_->{ParentID} eq $AppointmentID } @CalendarAppointments; # Process passed plugin parameters. for my $PluginParam (@PluginParams) { my $PluginData = $Kernel::OM->Get('Kernel::System::JSON')->Decode( Data => $GetParam{$PluginParam}, ); my $PluginKey = $PluginParam; $PluginKey =~ s/^Plugin_//; # Execute link add method of the plugin. if ( IsArrayRefWithData($PluginData) ) { for my $LinkID ( @{$PluginData} ) { for my $CurrentAppointmentID (@RelatedAppointments) { my $Link = $PluginObject->PluginLinkAdd( AppointmentID => $CurrentAppointmentID, PluginKey => $PluginKey, PluginData => $LinkID, UserID => $Self->{UserID}, ); if ( !$Link ) { $Kernel::OM->Get('Kernel::System::Log')->Log( Priority => 'error', Message => "Link could not be created for appointment $CurrentAppointmentID!", ); } } } } } } } # build JSON output $JSON = $LayoutObject->JSONEncode( Data => { Success => $Success ? 1 : 0, AppointmentID => $AppointmentID, }, ); } # ------------------------------------------------------------ # # delete mask # ------------------------------------------------------------ # elsif ( $Self->{Subaction} eq 'DeleteAppointment' ) { if ( $GetParam{AppointmentID} ) { my %Appointment = $AppointmentObject->AppointmentGet( AppointmentID => $GetParam{AppointmentID}, ); my $Success = 0; my $Error = ''; # Prevent deleting ticket appointment. if ( $Appointment{TicketAppointmentRuleID} ) { $Error = Translatable('Cannot delete ticket appointment!'); } else { # Get all related appointments before the deletion. my @RelatedAppointments = ( $Appointment{AppointmentID} ); my @CalendarAppointments = $AppointmentObject->AppointmentList( CalendarID => $Appointment{CalendarID}, ); # If we are dealing with a parent, include any child appointments. push @RelatedAppointments, map { $_->{AppointmentID} } grep { defined $_->{ParentID} && $_->{ParentID} eq $Appointment{AppointmentID} } @CalendarAppointments; # Remove all existing links. for my $CurrentAppointmentID (@RelatedAppointments) { my $Success = $PluginObject->PluginLinkDelete( AppointmentID => $CurrentAppointmentID, UserID => $Self->{UserID}, ); if ( !$Success ) { $Kernel::OM->Get('Kernel::System::Log')->Log( Priority => 'error', Message => "Links could not be deleted for appointment $CurrentAppointmentID!", ); } } $Success = $AppointmentObject->AppointmentDelete( %GetParam, UserID => $Self->{UserID}, ); if ( !$Success ) { $Error = Translatable('No permissions!'); } } # build JSON output $JSON = $LayoutObject->JSONEncode( Data => { Success => $Success, Error => $Error, AppointmentID => $GetParam{AppointmentID}, }, ); } } # ------------------------------------------------------------ # # update preferences # ------------------------------------------------------------ # elsif ( $Self->{Subaction} eq 'UpdatePreferences' ) { my $Success = 0; if ( $GetParam{OverviewScreen} && ( $GetParam{DefaultView} || $GetParam{CalendarSelection} || ( $GetParam{ShownResources} && $GetParam{TeamID} ) || $GetParam{ShownAppointments} ) ) { my $PreferenceKey; my $PreferenceKeySuffix = ''; if ( $GetParam{DefaultView} ) { $PreferenceKey = 'DefaultView'; } elsif ( $GetParam{CalendarSelection} ) { $PreferenceKey = 'CalendarSelection'; } elsif ( $GetParam{ShownResources} && $GetParam{TeamID} ) { $PreferenceKey = 'ShownResources'; $PreferenceKeySuffix = "-$GetParam{TeamID}"; } elsif ( $GetParam{ShownAppointments} ) { $PreferenceKey = 'ShownAppointments'; } # set user preferences $Success = $Kernel::OM->Get('Kernel::System::User')->SetPreferences( Key => 'User' . $GetParam{OverviewScreen} . $PreferenceKey . $PreferenceKeySuffix, Value => $GetParam{$PreferenceKey}, UserID => $Self->{UserID}, ); } elsif ( $GetParam{OverviewScreen} && $GetParam{RestoreDefaultSettings} ) { my $PreferenceKey; my $PreferenceKeySuffix = ''; if ( $GetParam{RestoreDefaultSettings} eq 'ShownResources' && $GetParam{TeamID} ) { $PreferenceKey = 'ShownResources'; $PreferenceKeySuffix = "-$GetParam{TeamID}"; } # blank user preferences $Success = $Kernel::OM->Get('Kernel::System::User')->SetPreferences( Key => 'User' . $GetParam{OverviewScreen} . $PreferenceKey . $PreferenceKeySuffix, Value => '', UserID => $Self->{UserID}, ); } # build JSON output $JSON = $LayoutObject->JSONEncode( Data => { Success => $Success, }, ); } # ------------------------------------------------------------ # # team list selection update # ------------------------------------------------------------ # elsif ( $Self->{Subaction} eq 'TeamUserList' ) { my @TeamIDs = $ParamObject->GetArray( Param => 'TeamID[]' ); my %TeamUserListAll; # Check if team object is registered. if ( $Kernel::OM->Get('Kernel::System::Main')->Require( 'Kernel::System::Calendar::Team', Silent => 1 ) ) { my $TeamObject = $Kernel::OM->Get('Kernel::System::Calendar::Team'); my $UserObject = $Kernel::OM->Get('Kernel::System::User'); TEAMID: for my $TeamID (@TeamIDs) { next TEAMID if !$TeamID; # get list of team members my %TeamUserList = $TeamObject->TeamUserList( TeamID => $TeamID, UserID => $Self->{UserID}, ); # get user data for my $UserID ( sort keys %TeamUserList ) { my %User = $UserObject->GetUserData( UserID => $UserID, ); $TeamUserList{$UserID} = $User{UserFullname}; } %TeamUserListAll = ( %TeamUserListAll, %TeamUserList ); } } # build JSON output $JSON = $LayoutObject->JSONEncode( Data => { TeamUserList => \%TeamUserListAll, }, ); } # send JSON response return $LayoutObject->Attachment( ContentType => 'application/json; charset=' . $LayoutObject->{Charset}, Content => $JSON, Type => 'inline', NoCache => 1, ); } sub _DayOffsetGet { my ( $Self, %Param ) = @_; # check needed stuff for my $Needed (qw(Time)) { if ( !$Param{$Needed} ) { $Kernel::OM->Get('Kernel::System::Log')->Log( Priority => 'error', Message => "Need $Needed!", ); return; } } # Get original date components. my $OriginalTimeObject = $Kernel::OM->Create( 'Kernel::System::DateTime', ObjectParams => { String => $Param{Time}, }, ); my $OriginalTimeSettings = $OriginalTimeObject->Get(); # Get destination time according to user timezone. my $DestinationTimeObject = $OriginalTimeObject->Clone(); $DestinationTimeObject->ToTimeZone( TimeZone => $Self->{UserTimeZone} ); my $DestinationTimeSettings = $DestinationTimeObject->Get(); # Compare days of two times. if ( $OriginalTimeSettings->{Day} == $DestinationTimeSettings->{Day} ) { return 0; # same day } elsif ( $OriginalTimeObject > $DestinationTimeObject ) { return -1; } return 1; } 1;