1# --
2# Copyright (C) 2001-2020 OTRS AG, https://otrs.com/
3# --
4# This software comes with ABSOLUTELY NO WARRANTY. For details, see
5# the enclosed file COPYING for license information (GPL). If you
6# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
7# --
8
9package Kernel::Modules::AdminSystemMaintenance;
10
11use strict;
12use warnings;
13
14use Kernel::System::VariableCheck qw(:all);
15use Kernel::Language qw(Translatable);
16
17our $ObjectManagerDisabled = 1;
18
19sub new {
20    my ( $Type, %Param ) = @_;
21
22    # allocate new hash for object
23    my $Self = {%Param};
24    bless( $Self, $Type );
25
26    return $Self;
27}
28
29sub Run {
30    my ( $Self, %Param ) = @_;
31
32    my $LayoutObject            = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
33    my $ParamObject             = $Kernel::OM->Get('Kernel::System::Web::Request');
34    my $SessionObject           = $Kernel::OM->Get('Kernel::System::AuthSession');
35    my $SystemMaintenanceObject = $Kernel::OM->Get('Kernel::System::SystemMaintenance');
36
37    my $SystemMaintenanceID = $ParamObject->GetParam( Param => 'SystemMaintenanceID' ) || '';
38    my $WantSessionID       = $ParamObject->GetParam( Param => 'WantSessionID' )       || '';
39
40    my $SessionVisibility = 'Collapsed';
41
42    # ------------------------------------------------------------ #
43    # kill session id
44    # ------------------------------------------------------------ #
45    if ( $Self->{Subaction} eq 'Kill' ) {
46
47        # challenge token check for write action
48        $LayoutObject->ChallengeTokenCheck();
49
50        $SessionObject->RemoveSessionID( SessionID => $WantSessionID );
51        return $LayoutObject->Redirect(
52            OP =>
53                "Action=AdminSystemMaintenance;Subaction=SystemMaintenanceEdit;SystemMaintenanceID=$SystemMaintenanceID;Kill=1"
54        );
55    }
56
57    # ------------------------------------------------------------ #
58    # kill all session ids
59    # ------------------------------------------------------------ #
60    elsif ( $Self->{Subaction} eq 'KillAll' ) {
61
62        # challenge token check for write action
63        $LayoutObject->ChallengeTokenCheck();
64
65        my @Sessions = $SessionObject->GetAllSessionIDs();
66        SESSIONS:
67        for my $Session (@Sessions) {
68            next SESSIONS if $Session eq $WantSessionID;
69            $SessionObject->RemoveSessionID( SessionID => $Session );
70        }
71
72        return $LayoutObject->Redirect(
73            OP =>
74                "Action=AdminSystemMaintenance;Subaction=SystemMaintenanceEdit;SystemMaintenanceID=$SystemMaintenanceID;KillAll=1"
75        );
76    }
77
78    # ------------------------------------------------------------ #
79    # SystemMaintenanceNew
80    # ------------------------------------------------------------ #
81    elsif ( $Self->{Subaction} eq 'SystemMaintenanceNew' ) {
82
83        return $Self->_ShowEdit(
84            %Param,
85            Action => 'New',
86        );
87    }
88
89    # ------------------------------------------------------------ #
90    # SystemMaintenanceNewAction
91    # ------------------------------------------------------------ #
92    elsif ( $Self->{Subaction} eq 'SystemMaintenanceNewAction' ) {
93
94        # challenge token check for write action
95        $LayoutObject->ChallengeTokenCheck();
96
97        # check required parameters
98        my %Error;
99        my @NotifyData;
100
101        # get SystemMaintenance parameters from web browser
102        my $SystemMaintenanceData = $Self->_GetParams(
103            Error => \%Error,
104        );
105
106        # a StartDate should always be defined before StopDate
107        if (
108            (
109                defined $SystemMaintenanceData->{StartDate}
110                && defined $SystemMaintenanceData->{StopDate}
111            )
112            && $SystemMaintenanceData->{StartDate} > $SystemMaintenanceData->{StopDate}
113            )
114        {
115
116            # set server error
117            $Error{StartDateServerError} = 'ServerError';
118
119            # add notification
120            push @NotifyData, {
121                Priority => 'Error',
122                Info     => Translatable('Start date shouldn\'t be defined after Stop date!'),
123            };
124        }
125
126        if ( !$SystemMaintenanceData->{Comment} ) {
127
128            # add server error class
129            $Error{CommentServerError} = 'ServerError';
130
131        }
132
133        # Trigger server error if 'Login message' or 'Notify message' is longer then 250 characters.
134        #   See bug#13366 (https://bugs.otrs.org/show_bug.cgi?id=13366)
135        if ( $SystemMaintenanceData->{LoginMessage} && length $SystemMaintenanceData->{LoginMessage} > 250 ) {
136
137            $Error{LoginMessageServerError} = 'ServerError';
138        }
139        if ( $SystemMaintenanceData->{NotifyMessage} && length $SystemMaintenanceData->{NotifyMessage} > 250 ) {
140
141            $Error{NotifyMessageServerError} = 'ServerError';
142        }
143
144        if ( !$SystemMaintenanceData->{ValidID} ) {
145
146            # add server error class
147            $Error{ValidIDServerError} = 'ServerError';
148        }
149
150        # if there is an error return to edit screen
151        if ( IsHashRefWithData( \%Error ) ) {
152
153            return $Self->_ShowEdit(
154                %Error,
155                %Param,
156                NotifyData            => \@NotifyData,
157                SystemMaintenanceData => $SystemMaintenanceData,
158                Action                => 'New',
159            );
160        }
161
162        my $SystemMaintenanceID = $SystemMaintenanceObject->SystemMaintenanceAdd(
163            StartDate        => $SystemMaintenanceData->{StartDate},
164            StopDate         => $SystemMaintenanceData->{StopDate},
165            Comment          => $SystemMaintenanceData->{Comment},
166            LoginMessage     => $SystemMaintenanceData->{LoginMessage},
167            ShowLoginMessage => $SystemMaintenanceData->{ShowLoginMessage},
168            NotifyMessage    => $SystemMaintenanceData->{NotifyMessage},
169            ValidID          => $SystemMaintenanceData->{ValidID},
170            UserID           => $Self->{UserID},
171        );
172
173        # show error if can't create
174        if ( !$SystemMaintenanceID ) {
175            return $LayoutObject->ErrorScreen(
176                Message => Translatable('There was an error creating the System Maintenance'),
177            );
178        }
179
180        # redirect to edit screen
181        if (
182            defined $ParamObject->GetParam( Param => 'ContinueAfterSave' )
183            && ( $ParamObject->GetParam( Param => 'ContinueAfterSave' ) eq '1' )
184            )
185        {
186            return $LayoutObject->Redirect(
187                OP =>
188                    "Action=$Self->{Action};Subaction=SystemMaintenanceEdit;SystemMaintenanceID=$SystemMaintenanceID;Notification=Add"
189            );
190        }
191        else {
192            return $LayoutObject->Redirect( OP => "Action=$Self->{Action};Notification=Add" );
193        }
194    }
195
196    # ------------------------------------------------------------ #
197    # Edit View
198    # ------------------------------------------------------------ #
199    elsif ( $Self->{Subaction} eq 'SystemMaintenanceEdit' ) {
200
201        # initialize notify container
202        my @NotifyData;
203
204        # check for SystemMaintenanceID
205        if ( !$SystemMaintenanceID ) {
206            return $LayoutObject->ErrorScreen(
207                Message => Translatable('Need SystemMaintenanceID!'),
208            );
209        }
210
211        # get system maintenance data
212        my $SystemMaintenanceData = $SystemMaintenanceObject->SystemMaintenanceGet(
213            ID     => $SystemMaintenanceID,
214            UserID => $Self->{UserID},
215        );
216
217        # include time stamps on the correct key
218        for my $Key (qw(StartDate StopDate)) {
219
220            # try to convert to TimeStamp
221            my $DateTimeObject = $Kernel::OM->Create(
222                'Kernel::System::DateTime',
223                ObjectParams => {
224                    Epoch => $SystemMaintenanceData->{$Key},
225                }
226            );
227            $SystemMaintenanceData->{ $Key . 'TimeStamp' } =
228                $DateTimeObject ? $DateTimeObject->ToString() : undef;
229        }
230
231        # check for valid system maintenance data
232        if ( !IsHashRefWithData($SystemMaintenanceData) ) {
233            return $LayoutObject->ErrorScreen(
234                Message => $LayoutObject->{LanguageObject}->Translate(
235                    'Could not get data for SystemMaintenanceID %s',
236                    $SystemMaintenanceID
237                ),
238            );
239        }
240
241        if ( $ParamObject->GetParam( Param => 'Notification' ) eq 'Add' ) {
242
243            # add notification
244            push @NotifyData, {
245                Priority => 'Notice',
246                Info     => Translatable('System Maintenance was added successfully!'),
247            };
248        }
249
250        if ( $ParamObject->GetParam( Param => 'Notification' ) eq 'Update' ) {
251
252            # add notification
253            push @NotifyData, {
254                Priority => 'Notice',
255                Info     => Translatable('System Maintenance was updated successfully!'),
256            };
257        }
258
259        if ( $ParamObject->GetParam( Param => 'Kill' ) ) {
260
261            # add notification
262            push @NotifyData, {
263                Priority => 'Notice',
264                Info     => Translatable('Session has been killed!'),
265            };
266
267            # set class for expanding sessions widget
268            $SessionVisibility = 'Expanded';
269        }
270
271        if ( $ParamObject->GetParam( Param => 'KillAll' ) ) {
272
273            # add notification
274            push @NotifyData, {
275                Priority => 'Notice',
276                Info     => Translatable('All sessions have been killed, except for your own.'),
277            };
278
279            # set class for expanding sessions widget
280            $SessionVisibility = 'Expanded';
281        }
282
283        return $Self->_ShowEdit(
284            %Param,
285            SystemMaintenanceID   => $SystemMaintenanceID,
286            SystemMaintenanceData => $SystemMaintenanceData,
287            NotifyData            => \@NotifyData,
288            SessionVisibility     => $SessionVisibility,
289            Action                => 'Edit',
290        );
291
292    }
293
294    # ------------------------------------------------------------ #
295    # System Maintenance edit action
296    # ------------------------------------------------------------ #
297    elsif ( $Self->{Subaction} eq 'SystemMaintenanceEditAction' ) {
298
299        # challenge token check for write action
300        $LayoutObject->ChallengeTokenCheck();
301
302        # check required parameters
303        my %Error;
304        my @NotifyData;
305
306        # get SystemMaintenance parameters from web browser
307        my $SystemMaintenanceData = $Self->_GetParams(
308            Error => \%Error,
309        );
310
311        # a StartDate should always be defined before StopDate
312        if (
313            (
314                defined $SystemMaintenanceData->{StartDate}
315                && defined $SystemMaintenanceData->{StopDate}
316            )
317            && $SystemMaintenanceData->{StartDate} > $SystemMaintenanceData->{StopDate}
318            )
319        {
320            $Error{StartDateServerError} = 'ServerError';
321
322            # add notification
323            push @NotifyData, {
324                Priority => 'Error',
325                Info     => Translatable('Start date shouldn\'t be defined after Stop date!'),
326            };
327        }
328
329        if ( !$SystemMaintenanceData->{Comment} ) {
330
331            # add server error class
332            $Error{CommentServerError} = 'ServerError';
333
334        }
335
336        # Trigger server error if 'Login message' or 'Notify message' is longer then 250 characters.
337        #   See bug#13366 (https://bugs.otrs.org/show_bug.cgi?id=13366)
338        if ( $SystemMaintenanceData->{LoginMessage} && length $SystemMaintenanceData->{LoginMessage} > 250 ) {
339
340            $Error{LoginMessageServerError} = 'ServerError';
341        }
342        if ( $SystemMaintenanceData->{NotifyMessage} && length $SystemMaintenanceData->{NotifyMessage} > 250 ) {
343
344            $Error{NotifyMessageServerError} = 'ServerError';
345        }
346
347        if ( !$SystemMaintenanceData->{ValidID} ) {
348
349            # add server error class
350            $Error{ValidIDServerError} = 'ServerError';
351        }
352
353        # if there is an error return to edit screen
354        if ( IsHashRefWithData( \%Error ) ) {
355
356            return $Self->_ShowEdit(
357                %Error,
358                %Param,
359                NotifyData            => \@NotifyData,
360                SystemMaintenanceID   => $SystemMaintenanceID,
361                SystemMaintenanceData => $SystemMaintenanceData,
362                Action                => 'Edit',
363            );
364        }
365
366        # otherwise update configuration and return to edit screen
367        my $UpdateResult = $SystemMaintenanceObject->SystemMaintenanceUpdate(
368            ID               => $SystemMaintenanceID,
369            StartDate        => $SystemMaintenanceData->{StartDate},
370            StopDate         => $SystemMaintenanceData->{StopDate},
371            Comment          => $SystemMaintenanceData->{Comment},
372            LoginMessage     => $SystemMaintenanceData->{LoginMessage},
373            ShowLoginMessage => $SystemMaintenanceData->{ShowLoginMessage},
374            NotifyMessage    => $SystemMaintenanceData->{NotifyMessage},
375            ValidID          => $SystemMaintenanceData->{ValidID},
376            UserID           => $Self->{UserID},
377        );
378
379        # show error if can't create
380        if ( !$UpdateResult ) {
381            return $LayoutObject->ErrorScreen(
382                Message => Translatable('There was an error updating the System Maintenance'),
383            );
384        }
385
386        # redirect to edit screen
387        if (
388            defined $ParamObject->GetParam( Param => 'ContinueAfterSave' )
389            && ( $ParamObject->GetParam( Param => 'ContinueAfterSave' ) eq '1' )
390            )
391        {
392            return $LayoutObject->Redirect(
393                OP =>
394                    "Action=$Self->{Action};Subaction=SystemMaintenanceEdit;SystemMaintenanceID=$SystemMaintenanceID;Notification=Update"
395            );
396        }
397        else {
398            return $LayoutObject->Redirect( OP => "Action=$Self->{Action};Notification=Update" );
399        }
400
401    }
402
403    # ------------------------------------------------------------ #
404    # System Maintenance Delete
405    # ------------------------------------------------------------ #
406    elsif ( $Self->{Subaction} eq 'Delete' ) {
407
408        # challenge token check for write action
409        $LayoutObject->ChallengeTokenCheck();
410
411        if ( !$SystemMaintenanceID ) {
412            $Kernel::OM->Get('Kernel::System::Log')->Log(
413                Message  => "No System Maintenance ID $SystemMaintenanceID",
414                Priority => 'error',
415            );
416        }
417
418        my $Delete = $SystemMaintenanceObject->SystemMaintenanceDelete(
419            ID     => $SystemMaintenanceID,
420            UserID => $Self->{UserID},
421        );
422        if ( !$Delete ) {
423            return $LayoutObject->ErrorScreen(
424                Message => $LayoutObject->{LanguageObject}->Translate(
425                    'Was not possible to delete the SystemMaintenance entry: %s!',
426                    $SystemMaintenanceID
427                ),
428            );
429        }
430        return $LayoutObject->Redirect( OP => 'Action=AdminSystemMaintenance' );
431
432    }
433
434    # ------------------------------------------------------------ #
435    # else, show system maintenance list
436    # ------------------------------------------------------------ #
437    else {
438
439        my $SystemMaintenanceList = $SystemMaintenanceObject->SystemMaintenanceListGet(
440            UserID => $Self->{UserID},
441        );
442
443        if ( !scalar @{$SystemMaintenanceList} ) {
444
445            # no data found block
446            $LayoutObject->Block(
447                Name => 'NoDataRow',
448            );
449        }
450        else {
451
452            for my $SystemMaintenance ( @{$SystemMaintenanceList} ) {
453
454                # set the valid state
455                $SystemMaintenance->{ValidID} = $Kernel::OM->Get('Kernel::System::Valid')
456                    ->ValidLookup( ValidID => $SystemMaintenance->{ValidID} );
457
458                # include time stamps on the correct key
459                for my $Key (qw(StartDate StopDate)) {
460
461                    my $DateTimeObject = $Kernel::OM->Create(
462                        'Kernel::System::DateTime',
463                        ObjectParams => {
464                            Epoch => $SystemMaintenance->{$Key},
465                        },
466                    );
467                    $DateTimeObject->ToTimeZone( TimeZone => $Self->{UserTimeZone} );
468
469                    $SystemMaintenance->{ $Key . 'TimeStamp' } = $DateTimeObject->ToString();
470                }
471
472                # create blocks
473                $LayoutObject->Block(
474                    Name => 'ViewRow',
475                    Data => {
476                        %{$SystemMaintenance},
477                    },
478                );
479            }
480        }
481
482        # generate output
483        my $Output = $LayoutObject->Header();
484        $Output .= $LayoutObject->NavigationBar();
485
486        if ( ( $ParamObject->GetParam( Param => 'Notification' ) || '' ) eq 'Update' ) {
487            $Output .= $LayoutObject->Notify(
488                Info => Translatable('System Maintenance was updated successfully!')
489            );
490        }
491        elsif ( ( $ParamObject->GetParam( Param => 'Notification' ) || '' ) eq 'Add' ) {
492            $Output .= $LayoutObject->Notify(
493                Info => Translatable('System Maintenance was added successfully!')
494            );
495        }
496
497        $Output .= $LayoutObject->Output(
498            TemplateFile => 'AdminSystemMaintenance',
499        );
500        $Output .= $LayoutObject->Footer();
501        return $Output;
502    }
503
504}
505
506sub _ShowEdit {
507    my ( $Self, %Param ) = @_;
508
509    my $LayoutObject  = $Kernel::OM->Get('Kernel::Output::HTML::Layout');
510    my $SessionObject = $Kernel::OM->Get('Kernel::System::AuthSession');
511
512    # get SystemMaintenance information
513    my $SystemMaintenanceData = $Param{SystemMaintenanceData} || {};
514
515    my %TimeConfig;
516    for my $Prefix (qw(StartDate StopDate)) {
517
518        # time setting if available
519        if (
520            $SystemMaintenanceData->{ $Prefix . 'TimeStamp' }
521            && $SystemMaintenanceData->{ $Prefix . 'TimeStamp' }
522            =~ m{^(\d\d\d\d)-(\d\d)-(\d\d)\s(\d\d):(\d\d):(\d\d)$}xi
523            )
524        {
525            $TimeConfig{$Prefix}->{ $Prefix . 'Year' }   = $1;
526            $TimeConfig{$Prefix}->{ $Prefix . 'Month' }  = $2;
527            $TimeConfig{$Prefix}->{ $Prefix . 'Day' }    = $3;
528            $TimeConfig{$Prefix}->{ $Prefix . 'Hour' }   = $4;
529            $TimeConfig{$Prefix}->{ $Prefix . 'Minute' } = $5;
530            $TimeConfig{$Prefix}->{ $Prefix . 'Second' } = $6;
531        }
532    }
533
534    # start date info
535    $Param{StartDateString} = $LayoutObject->BuildDateSelection(
536        %{$SystemMaintenanceData},
537        %{ $TimeConfig{StartDate} },
538        Prefix           => 'StartDate',
539        Format           => 'DateInputFormatLong',
540        YearPeriodPast   => 0,
541        YearPeriodFuture => 1,
542        StartDateClass   => $Param{StartDateInvalid} || ' ',
543        Validate         => 1,
544    );
545
546    # stop date info
547    $Param{StopDateString} = $LayoutObject->BuildDateSelection(
548        %{$SystemMaintenanceData},
549        %{ $TimeConfig{StopDate} },
550        Prefix           => 'StopDate',
551        Format           => 'DateInputFormatLong',
552        YearPeriodPast   => 0,
553        YearPeriodFuture => 1,
554        StopDateClass    => $Param{StopDateInvalid} || ' ',
555        Validate         => 1,
556    );
557
558    # get valid list
559    my %ValidList = $Kernel::OM->Get('Kernel::System::Valid')->ValidList();
560
561    $Param{ValidOption} = $LayoutObject->BuildSelection(
562        Data       => \%ValidList,
563        Name       => 'ValidID',
564        SelectedID => $SystemMaintenanceData->{ValidID} || 1,
565        Class      => 'Modernize Validate_Required ' . ( $Param{ValidIDServerError} || '' ),
566    );
567
568    if (
569        defined $SystemMaintenanceData->{ShowLoginMessage}
570        && $SystemMaintenanceData->{ShowLoginMessage} == '1'
571        )
572    {
573        $Param{Checked} = 'checked="checked"';
574    }
575
576    my $Output = $LayoutObject->Header();
577    $Output .= $LayoutObject->NavigationBar();
578
579    # show notifications if any
580    if ( $Param{NotifyData} ) {
581        for my $Notification ( @{ $Param{NotifyData} } ) {
582            $Output .= $LayoutObject->Notify(
583                %{$Notification},
584            );
585        }
586    }
587
588    # get all sessions
589    my @List     = $SessionObject->GetAllSessionIDs();
590    my $Table    = '';
591    my $Counter  = @List;
592    my %MetaData = ();
593    my @UserSessions;
594    $MetaData{UserSession}         = 0;
595    $MetaData{CustomerSession}     = 0;
596    $MetaData{UserSessionUniq}     = 0;
597    $MetaData{CustomerSessionUniq} = 0;
598
599    if ( $Param{Action} eq 'Edit' ) {
600
601        for my $SessionID (@List) {
602            my $List = '';
603            my %Data = $SessionObject->GetSessionIDData( SessionID => $SessionID );
604            if ( $Data{UserType} && $Data{UserLogin} ) {
605                $MetaData{"$Data{UserType}Session"}++;
606                if ( !$MetaData{"$Data{UserLogin}"} ) {
607                    $MetaData{"$Data{UserType}SessionUniq"}++;
608                    $MetaData{"$Data{UserLogin}"} = 1;
609                }
610            }
611
612            $Data{UserType} = 'Agent' if ( !$Data{UserType} || $Data{UserType} ne 'Customer' );
613
614            # store data to be used later for showing a users session table
615            push @UserSessions, {
616                SessionID     => $SessionID,
617                UserFirstname => $Data{UserFirstname},
618                UserLastname  => $Data{UserLastname},
619                UserFullname  => $Data{UserFullname},
620                UserType      => $Data{UserType},
621            };
622        }
623
624        # show users session table
625        for my $UserSession (@UserSessions) {
626
627            # create blocks
628            $LayoutObject->Block(
629                Name => $UserSession->{UserType} . 'Session',
630                Data => {
631                    %{$UserSession},
632                    %Param,
633                },
634            );
635        }
636
637        # no customer sessions found
638        if ( !$MetaData{CustomerSession} ) {
639
640            $LayoutObject->Block(
641                Name => 'CustomerNoDataRow',
642            );
643        }
644
645        # no agent sessions found
646        if ( !$MetaData{UserSession} ) {
647
648            $LayoutObject->Block(
649                Name => 'AgentNoDataRow',
650            );
651        }
652    }
653
654    $Output .= $LayoutObject->Output(
655        TemplateFile => "AdminSystemMaintenance$Param{Action}",
656        Data         => {
657            Counter => $Counter,
658            %Param,
659            %{$SystemMaintenanceData},
660            %MetaData
661        },
662    );
663
664    $Output .= $LayoutObject->Footer();
665
666    return $Output;
667}
668
669sub _GetParams {
670    my ( $Self, %Param ) = @_;
671
672    my $GetParam;
673
674    # get parameters from web browser
675    for my $ParamName (
676        qw(
677        StartDateYear StartDateMonth StartDateDay StartDateHour StartDateMinute
678        StopDateYear StopDateMonth StopDateDay StopDateHour StopDateMinute
679        Comment LoginMessage ShowLoginMessage NotifyMessage ValidID )
680        )
681    {
682        $GetParam->{$ParamName} = $Kernel::OM->Get('Kernel::System::Web::Request')->GetParam( Param => $ParamName );
683    }
684    $Param{ShowLoginMessage} ||= 0;
685
686    ITEM:
687    for my $Item (qw(StartDate StopDate)) {
688
689        my %DateStructure;
690
691        # check needed stuff
692        PERIOD:
693        for my $Period (qw(Year Month Day Hour Minute)) {
694
695            if ( !defined $GetParam->{ $Item . $Period } ) {
696                $Param{Error}->{ $Item . 'Invalid' } = 'ServerError';
697                next ITEM;
698            }
699
700            $DateStructure{$Period} = $GetParam->{ $Item . $Period };
701        }
702
703        my $DateTimeObject = $Kernel::OM->Create(
704            'Kernel::System::DateTime',
705            ObjectParams => {
706                %DateStructure,
707                TimeZone => $Self->{UserTimeZone},
708            },
709        );
710        if ( !$DateTimeObject ) {
711            $Param{Error}->{ $Item . 'Invalid' } = 'ServerError';
712            next ITEM;
713        }
714
715        $GetParam->{$Item} = $DateTimeObject->ToEpoch();
716        $GetParam->{ $Item . 'TimeStamp' } = $DateTimeObject->ToString();
717    }
718
719    return $GetParam;
720}
721
7221;
723