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
9use strict;
10use warnings;
11use utf8;
12
13use vars (qw($Self));
14
15use Kernel::System::VariableCheck qw(IsHashRefWithData);
16
17my $QueueObject          = $Kernel::OM->Get('Kernel::System::Queue');
18my $ServiceObject        = $Kernel::OM->Get('Kernel::System::Service');
19my $SLAObject            = $Kernel::OM->Get('Kernel::System::SLA');
20my $StateObject          = $Kernel::OM->Get('Kernel::System::State');
21my $TicketObject         = $Kernel::OM->Get('Kernel::System::Ticket');
22my $ArticleObject        = $Kernel::OM->Get('Kernel::System::Ticket::Article');
23my $ArticleBackendObject = $ArticleObject->BackendForChannel( ChannelName => 'Internal' );
24my $DateTimeObject       = $Kernel::OM->Create('Kernel::System::DateTime');
25my $TypeObject           = $Kernel::OM->Get('Kernel::System::Type');
26my $UserObject           = $Kernel::OM->Get('Kernel::System::User');
27
28$Kernel::OM->ObjectParamAdd(
29    'Kernel::System::UnitTest::Helper' => {
30        RestoreDatabase  => 1,
31        UseTmpArticleDir => 1,
32    },
33);
34my $Helper = $Kernel::OM->Get('Kernel::System::UnitTest::Helper');
35
36# set fixed time
37$Helper->FixedTimeSet();
38
39my $TicketID = $TicketObject->TicketCreate(
40    Title        => 'Some Ticket_Title',
41    Queue        => 'Raw',
42    Lock         => 'unlock',
43    Priority     => '3 normal',
44    State        => 'closed successful',
45    CustomerNo   => '123465',
46    CustomerUser => 'unittest@otrs.com',
47    OwnerID      => 1,
48    UserID       => 1,
49);
50$Self->True(
51    $TicketID,
52    'TicketCreate()',
53);
54
55my %Ticket = $TicketObject->TicketGet(
56    TicketID => $TicketID,
57    Extended => 1,
58);
59$Self->Is(
60    $Ticket{Title},
61    'Some Ticket_Title',
62    'TicketGet() (Title)',
63);
64$Self->Is(
65    $Ticket{Queue},
66    'Raw',
67    'TicketGet() (Queue)',
68);
69$Self->Is(
70    $Ticket{Priority},
71    '3 normal',
72    'TicketGet() (Priority)',
73);
74$Self->Is(
75    $Ticket{State},
76    'closed successful',
77    'TicketGet() (State)',
78);
79$Self->Is(
80    $Ticket{Owner},
81    'root@localhost',
82    'TicketGet() (Owner)',
83);
84$Self->Is(
85    $Ticket{CreateBy},
86    1,
87    'TicketGet() (CreateBy)',
88);
89$Self->Is(
90    $Ticket{ChangeBy},
91    1,
92    'TicketGet() (ChangeBy)',
93);
94$Self->Is(
95    $Ticket{Title},
96    'Some Ticket_Title',
97    'TicketGet() (Title)',
98);
99$Self->Is(
100    $Ticket{Responsible},
101    'root@localhost',
102    'TicketGet() (Responsible)',
103);
104$Self->Is(
105    $Ticket{Lock},
106    'unlock',
107    'TicketGet() (Lock)',
108);
109$Self->Is(
110    $Ticket{ServiceID},
111    '',
112    'TicketGet() (ServiceID)',
113);
114$Self->Is(
115    $Ticket{SLAID},
116    '',
117    'TicketGet() (SLAID)',
118);
119
120my $DefaultTicketType = $Kernel::OM->Get('Kernel::Config')->Get('Ticket::Type::Default');
121$Self->Is(
122    $Ticket{TypeID},
123    $TypeObject->TypeLookup( Type => $DefaultTicketType ),
124    'TicketGet() (TypeID)',
125);
126$Self->Is(
127    $Ticket{Closed},
128    $Ticket{Created},
129    'Ticket created as closed as Close Time = Creation Time',
130);
131
132my ( $TestUserLogin, $TestUserID ) = $Helper->TestUserCreate(
133    Groups => [ 'users', ],
134);
135
136my $TicketIDCreatedBy = $TicketObject->TicketCreate(
137    Title        => 'Some Ticket_Title',
138    Queue        => 'Raw',
139    Lock         => 'unlock',
140    Priority     => '3 normal',
141    State        => 'closed successful',
142    CustomerNo   => '123465',
143    CustomerUser => 'unittest@otrs.com',
144    OwnerID      => 1,
145    UserID       => $TestUserID,
146);
147
148my %CheckCreatedBy = $TicketObject->TicketGet(
149    TicketID => $TicketIDCreatedBy,
150    UserID   => $TestUserID,
151);
152
153$Self->Is(
154    $CheckCreatedBy{ChangeBy},
155    $TestUserID,
156    'TicketGet() (ChangeBy - not system ID 1 user)',
157);
158
159$Self->Is(
160    $CheckCreatedBy{CreateBy},
161    $TestUserID,
162    'TicketGet() (CreateBy - not system ID 1 user)',
163);
164
165$TicketObject->TicketOwnerSet(
166    TicketID  => $TicketIDCreatedBy,
167    NewUserID => $TestUserID,
168    UserID    => 1,
169);
170
171%CheckCreatedBy = $TicketObject->TicketGet(
172    TicketID => $TicketIDCreatedBy,
173    UserID   => $TestUserID,
174);
175
176$Self->Is(
177    $CheckCreatedBy{CreateBy},
178    $TestUserID,
179    'TicketGet() (CreateBy - still the same after OwnerSet)',
180);
181
182$Self->Is(
183    $CheckCreatedBy{OwnerID},
184    $TestUserID,
185    'TicketOwnerSet()',
186);
187
188$Self->Is(
189    $CheckCreatedBy{ChangeBy},
190    1,
191    'TicketOwnerSet() (ChangeBy - System ID 1 now)',
192);
193
194my $ArticleID = $ArticleBackendObject->ArticleCreate(
195    TicketID             => $TicketID,
196    SenderType           => 'agent',
197    IsVisibleForCustomer => 0,
198    From =>
199        'Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent <email@example.com>',
200    To =>
201        'Some Customer A Some Customer A Some Customer A Some Customer A Some Customer A Some Customer A  Some Customer ASome Customer A Some Customer A <customer-a@example.com>',
202    Cc =>
203        'Some Customer B Some Customer B Some Customer B Some Customer B Some Customer B Some Customer B Some Customer B Some Customer B Some Customer B <customer-b@example.com>',
204    ReplyTo =>
205        'Some Customer B Some Customer B Some Customer B Some Customer B Some Customer B Some Customer B Some Customer B Some Customer B Some Customer B <customer-b@example.com>',
206    Subject =>
207        'some short description some short description some short description some short description some short description some short description some short description some short description ',
208    Body => (
209        'the message text
210Perl modules provide a range of features to help you avoid reinventing the wheel, and can be downloaded from CPAN ( http://www.cpan.org/ ). A number of popular modules are included with the Perl distribution itself.
211
212Categories of modules range from text manipulation to network protocols to database integration to graphics. A categorized list of modules is also available from CPAN.
213
214To learn how to install modules you download from CPAN, read perlmodinstall
215
216To learn how to use a particular module, use perldoc Module::Name . Typically you will want to use Module::Name , which will then give you access to exported functions or an OO interface to the module.
217
218perlfaq contains questions and answers related to many common tasks, and often provides suggestions for good CPAN modules to use.
219
220perlmod describes Perl modules in general. perlmodlib lists the modules which came with your Perl installation.
221
222If you feel the urge to write Perl modules, perlnewmod will give you good advice.
223' x 200
224    ),    # create a really big string by concatenating 200 times
225
226    ContentType    => 'text/plain; charset=ISO-8859-15',
227    HistoryType    => 'OwnerUpdate',
228    HistoryComment => 'Some free text!',
229    UserID         => 1,
230    NoAgentNotify  => 1,                                   # if you don't want to send agent notifications
231);
232
233$Self->True(
234    $ArticleID,
235    'ArticleCreate()'
236);
237
238$Self->Is(
239    scalar $ArticleObject->ArticleList( TicketID => $TicketID ),
240    1,
241    'ArticleCount',
242);
243
244my %Article = $ArticleBackendObject->ArticleGet(
245    TicketID  => $TicketID,
246    ArticleID => $ArticleID,
247);
248$Self->True(
249    $Article{From} eq
250        'Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent Some Agent <email@example.com>',
251    'ArticleGet()',
252);
253
254for my $Key (qw( Body Subject From To ReplyTo )) {
255    my $Success = $ArticleBackendObject->ArticleUpdate(
256        TicketID  => $TicketID,
257        ArticleID => $ArticleID,
258        Key       => $Key,
259        Value     => "New $Key",
260        UserID    => 1,
261    );
262    $Self->True(
263        $Success,
264        'ArticleUpdate()'
265    );
266
267    my %Article2 = $ArticleBackendObject->ArticleGet(
268        TicketID  => $TicketID,
269        ArticleID => $ArticleID,
270    );
271    $Self->Is(
272        $Article2{$Key},
273        "New $Key",
274        'ArticleUpdate()'
275    );
276
277    # set old value
278    $Success = $ArticleBackendObject->ArticleUpdate(
279        TicketID  => $TicketID,
280        ArticleID => $ArticleID,
281        Key       => $Key,
282        Value     => $Article{$Key},
283        UserID    => 1,
284    );
285}
286
287$ArticleObject->ArticleSearchIndexBuild(
288    TicketID  => $TicketID,
289    ArticleID => $ArticleID,
290    UserID    => 1,
291);
292
293my $TicketSearchTicketNumber = substr $Ticket{TicketNumber}, 0, 10;
294my %TicketIDs = $TicketObject->TicketSearch(
295    Result       => 'HASH',
296    Limit        => 100,
297    TicketNumber => [ $TicketSearchTicketNumber . '%', '%not exisiting%' ],
298    UserID       => 1,
299    Permission   => 'rw',
300);
301$Self->True(
302    $TicketIDs{$TicketID},
303    'TicketSearch() (HASH:TicketNumber as HASHREF)',
304);
305
306%TicketIDs = $TicketObject->TicketSearch(
307    Result       => 'HASH',
308    Limit        => 100,
309    TicketNumber => $Ticket{TicketNumber},
310    UserID       => 1,
311    Permission   => 'rw',
312);
313$Self->True(
314    $TicketIDs{$TicketID},
315    'TicketSearch() (HASH:TicketNumber)',
316);
317
318# Test TicketNumber search condition '0', expecting no results, see bug#11461.
319%TicketIDs = $TicketObject->TicketSearch(
320    Result       => 'HASH',
321    Limit        => 100,
322    TicketNumber => 0,
323    UserID       => 1,
324    Permission   => 'rw',
325);
326$Self->True(
327    !$TicketIDs{$TicketID},
328    'TicketSearch() (HASH:TicketNumber eq 0)',
329);
330
331%TicketIDs = $TicketObject->TicketSearch(
332    Result     => 'HASH',
333    Limit      => 100,
334    TicketID   => $TicketID,
335    UserID     => 1,
336    Permission => 'rw',
337);
338
339$Self->True(
340    $TicketIDs{$TicketID},
341    'TicketSearch() (HASH:TicketID)',
342);
343
344%TicketIDs = $TicketObject->TicketSearch(
345    Result     => 'HASH',
346    Limit      => 100,
347    TicketID   => [ $TicketID, 42 ],
348    UserID     => 1,
349    Permission => 'rw',
350);
351
352$Self->True(
353    $TicketIDs{$TicketID},
354    'TicketSearch() (HASH:TicketID as ARRAYREF)',
355);
356
357my $ErrorOutput = '';
358
359{
360    local *STDERR;
361    open STDERR, ">>", \$ErrorOutput;
362
363    %TicketIDs = $TicketObject->TicketSearch(
364        TicketID => [],
365        UserID   => 1,
366    );
367}
368
369# Verify that search does not fail SQL syntax check when an empty array reference is passed for the TicketID param.
370#   Please see bug#14227 for more information.
371$Self->False(
372    ( $ErrorOutput =~ m{you have an error in your sql syntax}i ) // 1,
373    'TicketSearch() (HASH:TicketID as an empty ARRAYREF)'
374);
375
376my $Count = $TicketObject->TicketSearch(
377    Result       => 'COUNT',
378    TicketNumber => $Ticket{TicketNumber},
379    UserID       => 1,
380    Permission   => 'rw',
381);
382$Self->Is(
383    $Count,
384    1,
385    'TicketSearch() (COUNT:TicketNumber)',
386);
387
388%TicketIDs = $TicketObject->TicketSearch(
389    Result       => 'HASH',
390    Limit        => 100,
391    TicketNumber => [ $Ticket{TicketNumber}, '1234' ],
392    UserID       => 1,
393    Permission   => 'rw',
394);
395$Self->True(
396    $TicketIDs{$TicketID},
397    'TicketSearch() (HASH:TicketNumber[ARRAY])',
398);
399
400%TicketIDs = $TicketObject->TicketSearch(
401    Result     => 'HASH',
402    Limit      => 100,
403    Title      => $Ticket{Title},
404    UserID     => 1,
405    Permission => 'rw',
406);
407$Self->True(
408    $TicketIDs{$TicketID},
409    'TicketSearch() (HASH:Title)',
410);
411
412%TicketIDs = $TicketObject->TicketSearch(
413    Result     => 'HASH',
414    Limit      => 100,
415    Title      => [ $Ticket{Title}, 'SomeTitleABC' ],
416    UserID     => 1,
417    Permission => 'rw',
418);
419$Self->True(
420    $TicketIDs{$TicketID},
421    'TicketSearch() (HASH:Title[ARRAY])',
422);
423
424%TicketIDs = $TicketObject->TicketSearch(
425    Result     => 'HASH',
426    Limit      => 100,
427    CustomerID => $Ticket{CustomerID},
428    UserID     => 1,
429    Permission => 'rw',
430);
431$Self->True(
432    $TicketIDs{$TicketID},
433    'TicketSearch() (HASH:CustomerID)',
434);
435
436%TicketIDs = $TicketObject->TicketSearch(
437    Result     => 'HASH',
438    Limit      => 100,
439    CustomerID => [ $Ticket{CustomerID}, 'LULU' ],
440    UserID     => 1,
441    Permission => 'rw',
442);
443$Self->True(
444    $TicketIDs{$TicketID},
445    'TicketSearch() (HASH:CustomerID[ARRAY])',
446);
447
448%TicketIDs = $TicketObject->TicketSearch(
449    Result     => 'HASH',
450    Limit      => 100,
451    CustomerID => ['LULU'],
452    UserID     => 1,
453    Permission => 'rw',
454);
455$Self->False(
456    scalar $TicketIDs{$TicketID},
457    'TicketSearch() (HASH:CustomerID[ARRAY])',
458);
459
460%TicketIDs = $TicketObject->TicketSearch(
461    Result            => 'HASH',
462    Limit             => 100,
463    CustomerUserLogin => $Ticket{CustomerUser},
464    UserID            => 1,
465    Permission        => 'rw',
466);
467$Self->True(
468    $TicketIDs{$TicketID},
469    'TicketSearch() (HASH:CustomerUser)',
470);
471
472%TicketIDs = $TicketObject->TicketSearch(
473    Result            => 'HASH',
474    Limit             => 100,
475    CustomerUserLogin => [ $Ticket{CustomerUserID}, '1234' ],
476    UserID            => 1,
477    Permission        => 'rw',
478);
479$Self->True(
480    $TicketIDs{$TicketID},
481    'TicketSearch() (HASH:CustomerUser[ARRAY])',
482);
483
484%TicketIDs = $TicketObject->TicketSearch(
485    Result            => 'HASH',
486    Limit             => 100,
487    TicketNumber      => $Ticket{TicketNumber},
488    Title             => $Ticket{Title},
489    CustomerID        => $Ticket{CustomerID},
490    CustomerUserLogin => $Ticket{CustomerUserID},
491    UserID            => 1,
492    Permission        => 'rw',
493);
494$Self->True(
495    $TicketIDs{$TicketID},
496    'TicketSearch() (HASH:TicketNumber,Title,CustomerID,CustomerUserID)',
497);
498
499%TicketIDs = $TicketObject->TicketSearch(
500    Result            => 'HASH',
501    Limit             => 100,
502    TicketNumber      => [ $Ticket{TicketNumber}, 'ABC' ],
503    Title             => [ $Ticket{Title}, '123' ],
504    CustomerID        => [ $Ticket{CustomerID}, '1213421' ],
505    CustomerUserLogin => [ $Ticket{CustomerUserID}, 'iadasd' ],
506    UserID            => 1,
507    Permission        => 'rw',
508);
509$Self->True(
510    $TicketIDs{$TicketID},
511    'TicketSearch() (HASH:TicketNumber,Title,CustomerID,CustomerUser[ARRAY])',
512);
513
514%TicketIDs = $TicketObject->TicketSearch(
515    Result       => 'HASH',
516    Limit        => 100,
517    TicketNumber => [ $Ticket{TicketNumber}, 'ABC' ],
518    StateType    => 'Closed',
519    UserID       => 1,
520    Permission   => 'rw',
521);
522$Self->True(
523    $TicketIDs{$TicketID},
524    'TicketSearch() (HASH:TicketNumber,StateType:Closed)',
525);
526
527%TicketIDs = $TicketObject->TicketSearch(
528    Result       => 'HASH',
529    Limit        => 100,
530    TicketNumber => [ $Ticket{TicketNumber}, 'ABC' ],
531    StateType    => 'Open',
532    UserID       => 1,
533    Permission   => 'rw',
534);
535$Self->False(
536    $TicketIDs{$TicketID},
537    'TicketSearch() (HASH:TicketNumber,StateType:Open)',
538);
539
540%TicketIDs = $TicketObject->TicketSearch(
541    Result              => 'HASH',
542    Limit               => 100,
543    MIMEBase_Body       => 'write perl modules',
544    ConditionInline     => 1,
545    ContentSearchPrefix => '*',
546    ContentSearchSuffix => '*',
547    StateType           => 'Closed',
548    UserID              => 1,
549    Permission          => 'rw',
550);
551$Self->True(
552    $TicketIDs{$TicketID},
553    'TicketSearch() (HASH:MIMEBase_Body,StateType:Closed)',
554);
555
556%TicketIDs = $TicketObject->TicketSearch(
557    Result              => 'HASH',
558    Limit               => 100,
559    MIMEBase_Body       => 'write perl modules',
560    ConditionInline     => 1,
561    ContentSearchPrefix => '*',
562    ContentSearchSuffix => '*',
563    StateType           => 'Open',
564    UserID              => 1,
565    Permission          => 'rw',
566);
567$Self->True(
568    !$TicketIDs{$TicketID},
569    'TicketSearch() (HASH:MIMEBase_,StateType:Open)',
570);
571
572$TicketObject->MoveTicket(
573    Queue              => 'Junk',
574    TicketID           => $TicketID,
575    SendNoNotification => 1,
576    UserID             => 1,
577);
578
579$TicketObject->MoveTicket(
580    Queue              => 'Raw',
581    TicketID           => $TicketID,
582    SendNoNotification => 1,
583    UserID             => 1,
584);
585
586my %HD = $TicketObject->HistoryTicketGet(
587    StopYear  => 4000,
588    StopMonth => 1,
589    StopDay   => 1,
590    TicketID  => $TicketID,
591    Force     => 1,
592);
593my $QueueLookupID = $QueueObject->QueueLookup( Queue => $HD{Queue} );
594$Self->Is(
595    $QueueLookupID,
596    $HD{QueueID},
597    'HistoryTicketGet() Check history queue',
598);
599
600my $TicketMove = $TicketObject->MoveTicket(
601    Queue              => 'Junk',
602    TicketID           => $TicketID,
603    SendNoNotification => 1,
604    UserID             => 1,
605);
606$Self->True(
607    $TicketMove,
608    'MoveTicket()',
609);
610
611my $TicketState = $TicketObject->StateSet(
612    State    => 'open',
613    TicketID => $TicketID,
614    UserID   => 1,
615);
616$Self->True(
617    $TicketState,
618    'StateSet()',
619);
620
621%TicketIDs = $TicketObject->TicketSearch(
622    Result       => 'HASH',
623    Limit        => 100,
624    TicketNumber => [ $Ticket{TicketNumber}, 'ABC' ],
625    StateType    => 'Open',
626    UserID       => 1,
627    Permission   => 'rw',
628);
629$Self->True(
630    $TicketIDs{$TicketID},
631    'TicketSearch() (HASH:TicketNumber,StateType:Open)',
632);
633
634%TicketIDs = $TicketObject->TicketSearch(
635    Result       => 'HASH',
636    Limit        => 100,
637    TicketNumber => [ $Ticket{TicketNumber}, 'ABC' ],
638    StateType    => 'Closed',
639    UserID       => 1,
640    Permission   => 'rw',
641);
642$Self->False(
643    $TicketIDs{$TicketID},
644    'TicketSearch() (HASH:TicketNumber,StateType:Closed)',
645);
646
647for my $Condition (
648    '(Some&&Agent)',
649    'Some&&Agent',
650    '(Some+Agent)',
651    ' (Some+Agent)',
652    ' (Some+Agent)  ',
653    'Some&&Agent',
654    'Some+Agent',
655    ' Some+Agent',
656    'Some+Agent ',
657    ' Some+Agent ',
658    '(!SomeWordShouldNotFound||(Some+Agent))',
659    '((Some+Agent)||(SomeAgentNotFound||AgentNotFound))',
660    '"Some Agent Some"',
661    '("Some Agent Some")',
662    '!"Some Some Agent"',
663    '(!"Some Some Agent")',
664    )
665{
666    %TicketIDs = $TicketObject->TicketSearch(
667
668        # result (required)
669        Result => 'HASH',
670
671        # result limit
672        Limit               => 1000,
673        MIMEBase_From       => $Condition,
674        ConditionInline     => 1,
675        ContentSearchPrefix => '*',
676        ContentSearchSuffix => '*',
677        UserID              => 1,
678        Permission          => 'rw',
679    );
680    $Self->True(
681        $TicketIDs{$TicketID},
682        "TicketSearch() (HASH:MIMEBase_From,ConditionInline,MIMEBase_From='$Condition')",
683    );
684}
685
686for my $Condition (
687    '(SomeNotFoundWord&&AgentNotFoundWord)',
688    'SomeNotFoundWord||AgentNotFoundWord',
689    ' SomeNotFoundWord||AgentNotFoundWord',
690    'SomeNotFoundWord&&AgentNotFoundWord',
691    'SomeNotFoundWord&&AgentNotFoundWord  ',
692    '(SomeNotFoundWord AgentNotFoundWord)',
693    'SomeNotFoundWord&&AgentNotFoundWord',
694    '(SomeWordShouldNotFound||(!Some+!Agent))',
695    '((SomeNotFound&&Agent)||(SomeAgentNotFound||AgentNotFound))',
696    '!"Some Agent Some"',
697    '(!"Some Agent Some")',
698    '"Some Some Agent"',
699    '("Some Some Agent")',
700    )
701{
702    %TicketIDs = $TicketObject->TicketSearch(
703
704        # result (required)
705        Result => 'HASH',
706
707        # result limit
708        Limit               => 1000,
709        MIMEBase_From       => $Condition,
710        ConditionInline     => 1,
711        ContentSearchPrefix => '*',
712        ContentSearchSuffix => '*',
713        UserID              => 1,
714        Permission          => 'rw',
715    );
716
717    $Self->True(
718        ( !$TicketIDs{$TicketID} ),
719        "TicketSearch() (HASH:MIMEBase_From,ConditionInline,MIMEBase_From='$Condition')",
720    );
721}
722
723my $TicketPriority = $TicketObject->PrioritySet(
724    Priority => '2 low',
725    TicketID => $TicketID,
726    UserID   => 1,
727);
728$Self->True(
729    $TicketPriority,
730    'PrioritySet()',
731);
732
733# get ticket data
734my %TicketData = $TicketObject->TicketGet(
735    TicketID => $TicketID,
736    UserID   => 1,
737);
738
739# save current change_time
740my $ChangeTime = $TicketData{Changed};
741
742# wait 5 seconds
743$Helper->FixedTimeAddSeconds(5);
744
745my $TicketTitle = $TicketObject->TicketTitleUpdate(
746    Title => 'Very long title 01234567890123456789012345678901234567890123456789'
747        . '0123456789012345678901234567890123456789012345678901234567890123456789'
748        . '0123456789012345678901234567890123456789012345678901234567890123456789'
749        . '0123456789012345678901234567890123456789',
750    TicketID => $TicketID,
751    UserID   => 1,
752);
753$Self->True(
754    $TicketTitle,
755    'TicketTitleUpdate()',
756);
757
758# get updated ticket data
759%TicketData = $TicketObject->TicketGet(
760    TicketID => $TicketID,
761    UserID   => 1,
762);
763
764# compare current change_time with old one
765$Self->IsNot(
766    $ChangeTime,
767    $TicketData{Changed},
768    'Change_time updated in TicketTitleUpdate()',
769);
770
771# check if we have a Ticket Title Update history record
772my @HistoryLines = $TicketObject->HistoryGet(
773    TicketID => $TicketID,
774    UserID   => 1,
775);
776my $HistoryItem = pop @HistoryLines;
777$Self->Is(
778    $HistoryItem->{HistoryType},
779    'TitleUpdate',
780    "TicketTitleUpdate - found HistoryItem",
781);
782
783$Self->Is(
784    $HistoryItem->{Name},
785    '%%Some Ticket_Title%%Very long title 0123456789012345678901234567890123...',
786    "TicketTitleUpdate - Found new title",
787);
788
789# get updated ticket data
790%TicketData = $TicketObject->TicketGet(
791    TicketID => $TicketID,
792    UserID   => 1,
793);
794
795# save current change_time
796$ChangeTime = $TicketData{Changed};
797
798# wait 5 seconds
799$Helper->FixedTimeAddSeconds(5);
800
801# set unlock timeout
802my $UnlockTimeout = $TicketObject->TicketUnlockTimeoutUpdate(
803    UnlockTimeout => $DateTimeObject->ToEpoch() + 10000,
804    TicketID      => $TicketID,
805    UserID        => 1,
806);
807
808$Self->True(
809    $UnlockTimeout,
810    'TicketUnlockTimeoutUpdate()',
811);
812
813# get updated ticket data
814%TicketData = $TicketObject->TicketGet(
815    TicketID => $TicketID,
816    UserID   => 1,
817);
818
819# compare current change_time with old one
820$Self->IsNot(
821    $ChangeTime,
822    $TicketData{Changed},
823    'Change_time updated in TicketUnlockTimeoutUpdate()',
824);
825
826# save current change_time
827$ChangeTime = $TicketData{Changed};
828
829# save current queue
830my $CurrentQueueID = $TicketData{QueueID};
831
832# wait 5 seconds
833$Helper->FixedTimeAddSeconds(5);
834
835my $NewQueue = $CurrentQueueID != 1 ? 1 : 2;
836
837# set queue
838my $TicketQueueSet = $TicketObject->TicketQueueSet(
839    QueueID  => $NewQueue,
840    TicketID => $TicketID,
841    UserID   => 1,
842);
843
844$Self->True(
845    $TicketQueueSet,
846    'TicketQueueSet()',
847);
848
849# get updated ticket data
850%TicketData = $TicketObject->TicketGet(
851    TicketID => $TicketID,
852    UserID   => 1,
853);
854
855# compare current change_time with old one
856$Self->IsNot(
857    $ChangeTime,
858    $TicketData{Changed},
859    'Change_time updated in TicketQueueSet()',
860);
861
862# restore queue
863$TicketQueueSet = $TicketObject->TicketQueueSet(
864    QueueID  => $CurrentQueueID,
865    TicketID => $TicketID,
866    UserID   => 1,
867);
868
869# save current change_time
870$ChangeTime = $TicketData{Changed};
871
872# save current type
873my $CurrentTicketType = $TicketData{TypeID};
874
875# wait 5 seconds
876$Helper->FixedTimeAddSeconds(5);
877
878# create a test type
879my $TypeID = $TypeObject->TypeAdd(
880    Name    => 'Type' . $Helper->GetRandomID(),
881    ValidID => 1,
882    UserID  => 1,
883);
884
885# set type
886my $TicketTypeSet = $TicketObject->TicketTypeSet(
887    TypeID   => $TypeID,
888    TicketID => $TicketID,
889    UserID   => 1,
890);
891
892$Self->True(
893    $TicketTypeSet,
894    'TicketTypeSet()',
895);
896
897# get updated ticket data
898%TicketData = $TicketObject->TicketGet(
899    TicketID => $TicketID,
900    UserID   => 1,
901);
902
903# compare current change_time with old one
904$Self->IsNot(
905    $ChangeTime,
906    $TicketData{Changed},
907    'Change_time updated in TicketTypeSet()',
908);
909
910# restore type
911$TicketTypeSet = $TicketObject->TicketTypeSet(
912    TypeID   => $CurrentTicketType,
913    TicketID => $TicketID,
914    UserID   => 1,
915);
916
917# set as invalid the test type
918$TypeObject->TypeUpdate(
919    ID      => $TypeID,
920    Name    => 'Type' . $Helper->GetRandomID(),
921    ValidID => 2,
922    UserID  => 1,
923);
924
925# create a test service
926my $ServiceID = $ServiceObject->ServiceAdd(
927    Name    => 'Service' . $Helper->GetRandomID(),
928    ValidID => 1,
929    Comment => 'Unit Test Comment',
930    UserID  => 1,
931);
932
933# wait 1 seconds
934$Helper->FixedTimeAddSeconds(1);
935
936# set type
937my $TicketServiceSet = $TicketObject->TicketServiceSet(
938    ServiceID => $ServiceID,
939    TicketID  => $TicketID,
940    UserID    => 1,
941);
942
943$Self->True(
944    $TicketServiceSet,
945    'TicketServiceSet()',
946);
947
948# get updated ticket data
949%TicketData = $TicketObject->TicketGet(
950    TicketID => $TicketID,
951    UserID   => 1,
952);
953
954# compare current change_time with old one
955$Self->IsNot(
956    $ChangeTime,
957    $TicketData{Changed},
958    'Change_time updated in TicketServiceSet()',
959);
960
961# set as invalid the test service
962$ServiceObject->ServiceUpdate(
963    ServiceID => $ServiceID,
964    Name      => 'Service' . $Helper->GetRandomID(),
965    ValidID   => 2,
966    UserID    => 1,
967);
968
969# save current change_time
970$ChangeTime = $TicketData{Changed};
971
972# wait 5 seconds
973$Helper->FixedTimeAddSeconds(5);
974
975my $TicketEscalationIndexBuild = $TicketObject->TicketEscalationIndexBuild(
976    TicketID => $TicketID,
977    UserID   => 1,
978);
979
980$Self->True(
981    $TicketEscalationIndexBuild,
982    'TicketEscalationIndexBuild()',
983);
984
985# get updated ticket data
986%TicketData = $TicketObject->TicketGet(
987    TicketID => $TicketID,
988    UserID   => 1,
989);
990
991# compare current change_time with old one
992$Self->IsNot(
993    $ChangeTime,
994    $TicketData{Changed},
995    'Change_time updated in TicketEscalationIndexBuild()',
996);
997
998# save current change_time
999$ChangeTime = $TicketData{Changed};
1000
1001# create a test SLA
1002my $SLAID = $SLAObject->SLAAdd(
1003    Name    => 'SLA' . $Helper->GetRandomID(),
1004    ValidID => 1,
1005    Comment => 'Unit Test Comment',
1006    UserID  => 1,
1007);
1008
1009# wait 5 seconds
1010$Helper->FixedTimeAddSeconds(5);
1011
1012# set SLA
1013my $TicketSLASet = $TicketObject->TicketSLASet(
1014    SLAID    => $SLAID,
1015    TicketID => $TicketID,
1016    UserID   => 1,
1017);
1018
1019$Self->True(
1020    $TicketSLASet,
1021    'TicketSLASet()',
1022);
1023
1024# get updated ticket data
1025%TicketData = $TicketObject->TicketGet(
1026    TicketID => $TicketID,
1027    UserID   => 1,
1028);
1029
1030# compare current change_time with old one
1031$Self->IsNot(
1032    $ChangeTime,
1033    $TicketData{Changed},
1034    'Change_time updated in TicketSLASet()',
1035);
1036
1037# set as invalid the test SLA
1038$SLAObject->SLAUpdate(
1039    SLAID   => $SLAID,
1040    Name    => 'SLA' . $Helper->GetRandomID(),
1041    ValidID => 1,
1042    Comment => 'Unit Test Comment',
1043    UserID  => 1,
1044);
1045
1046my $TicketLock = $TicketObject->LockSet(
1047    Lock               => 'lock',
1048    TicketID           => $TicketID,
1049    SendNoNotification => 1,
1050    UserID             => 1,
1051);
1052$Self->True(
1053    $TicketLock,
1054    'LockSet()',
1055);
1056
1057# Test CreatedUserIDs
1058%TicketIDs = $TicketObject->TicketSearch(
1059    Result         => 'HASH',
1060    Limit          => 100,
1061    CreatedUserIDs => [ 1, 455, 32 ],
1062    UserID         => 1,
1063    Permission     => 'rw',
1064);
1065$Self->True(
1066    $TicketIDs{$TicketID},
1067    'TicketSearch() (HASH:CreatedUserIDs[Array])',
1068);
1069
1070# Test CreatedPriorities
1071%TicketIDs = $TicketObject->TicketSearch(
1072    Result            => 'HASH',
1073    Limit             => 100,
1074    CreatedPriorities => [ '2 low', '3 normal' ],
1075    UserID            => 1,
1076    Permission        => 'rw',
1077);
1078$Self->True(
1079    $TicketIDs{$TicketID},
1080    'TicketSearch() (HASH:CreatedPriorities[Array])',
1081);
1082
1083# Test CreatedPriorityIDs
1084%TicketIDs = $TicketObject->TicketSearch(
1085    Result             => 'HASH',
1086    Limit              => 100,
1087    CreatedPriorityIDs => [ 2, 3 ],
1088    UserID             => 1,
1089    Permission         => 'rw',
1090);
1091$Self->True(
1092    $TicketIDs{$TicketID},
1093    'TicketSearch() (HASH:CreatedPriorityIDs[Array])',
1094);
1095
1096# Test CreatedStates
1097%TicketIDs = $TicketObject->TicketSearch(
1098    Result        => 'HASH',
1099    Limit         => 100,
1100    CreatedStates => ['closed successful'],
1101    UserID        => 1,
1102    Permission    => 'rw',
1103);
1104$Self->True(
1105    $TicketIDs{$TicketID},
1106    'TicketSearch() (HASH:CreatedStates[Array])',
1107);
1108
1109# Test CreatedStateIDs
1110%TicketIDs = $TicketObject->TicketSearch(
1111    Result          => 'HASH',
1112    Limit           => 100,
1113    CreatedStateIDs => [2],
1114    UserID          => 1,
1115    Permission      => 'rw',
1116);
1117$Self->True(
1118    $TicketIDs{$TicketID},
1119    'TicketSearch() (HASH:CreatedStateIDs[Array])',
1120);
1121
1122# Test CreatedQueues
1123%TicketIDs = $TicketObject->TicketSearch(
1124    Result        => 'HASH',
1125    Limit         => 100,
1126    CreatedQueues => ['Raw'],
1127    UserID        => 1,
1128    Permission    => 'rw',
1129);
1130$Self->True(
1131    $TicketIDs{$TicketID},
1132    'TicketSearch() (HASH:CreatedQueues[Array])',
1133);
1134
1135# Test CreatedQueueIDs
1136%TicketIDs = $TicketObject->TicketSearch(
1137    Result          => 'HASH',
1138    Limit           => 100,
1139    CreatedQueueIDs => [ 2, 3 ],
1140    UserID          => 1,
1141    Permission      => 'rw',
1142);
1143$Self->True(
1144    $TicketIDs{$TicketID},
1145    'TicketSearch() (HASH:CreatedQueueIDs[Array])',
1146);
1147
1148# Test TicketCreateTimeNewerMinutes
1149%TicketIDs = $TicketObject->TicketSearch(
1150    Result                       => 'HASH',
1151    Limit                        => 100,
1152    TicketCreateTimeNewerMinutes => 60,
1153    UserID                       => 1,
1154    Permission                   => 'rw',
1155);
1156$Self->True(
1157    $TicketIDs{$TicketID},
1158    'TicketSearch() (HASH:TicketCreateTimeNewerMinutes => 60)',
1159);
1160
1161# Test TicketLastChangeTimeNewerMinutes
1162%TicketIDs = $TicketObject->TicketSearch(
1163    Result                           => 'HASH',
1164    Limit                            => 100,
1165    TicketLastChangeTimeNewerMinutes => 60,
1166    UserID                           => 1,
1167    Permission                       => 'rw',
1168);
1169$Self->True(
1170    $TicketIDs{$TicketID},
1171    'TicketSearch() (HASH:TicketLastChangeTimeNewerMinutes => 60)',
1172);
1173
1174# Test ArticleCreateTimeNewerMinutes
1175%TicketIDs = $TicketObject->TicketSearch(
1176    Result                        => 'HASH',
1177    Limit                         => 100,
1178    ArticleCreateTimeNewerMinutes => 60,
1179    UserID                        => 1,
1180    Permission                    => 'rw',
1181);
1182$Self->True(
1183    $TicketIDs{$TicketID},
1184    'TicketSearch() (HASH:ArticleCreateTimeNewerMinutes => 60)',
1185);
1186
1187# Test TicketCreateOlderMinutes
1188%TicketIDs = $TicketObject->TicketSearch(
1189    Result                       => 'HASH',
1190    Limit                        => 100,
1191    TicketCreateTimeOlderMinutes => 60,
1192    UserID                       => 1,
1193    Permission                   => 'rw',
1194);
1195$Self->False(
1196    $TicketIDs{$TicketID},
1197    'TicketSearch() (HASH:TicketCreateTimeOlderMinutes => 60)',
1198);
1199
1200# Test TicketLastChangeOlderMinutes
1201%TicketIDs = $TicketObject->TicketSearch(
1202    Result                           => 'HASH',
1203    Limit                            => 100,
1204    TicketLastChangeTimeOlderMinutes => 60,
1205    UserID                           => 1,
1206    Permission                       => 'rw',
1207);
1208$Self->False(
1209    $TicketIDs{$TicketID},
1210    'TicketSearch() (HASH:TicketLastChangeTimeOlderMinutes => 60)',
1211);
1212
1213# Test ArticleCreateOlderMinutes
1214%TicketIDs = $TicketObject->TicketSearch(
1215    Result                        => 'HASH',
1216    Limit                         => 100,
1217    ArticleCreateTimeOlderMinutes => 60,
1218    UserID                        => 1,
1219    Permission                    => 'rw',
1220);
1221$Self->False(
1222    $TicketIDs{$TicketID},
1223    'TicketSearch() (HASH:ArticleCreateTimeOlderMinutes => 60)',
1224);
1225
1226# Test TicketCreateTimeNewerDate
1227my $TicketCreateTimeNewerDate = $Kernel::OM->Create('Kernel::System::DateTime');
1228$TicketCreateTimeNewerDate->Subtract( Hours => 1 );
1229
1230%TicketIDs = $TicketObject->TicketSearch(
1231    Result                    => 'HASH',
1232    Limit                     => 100,
1233    TicketCreateTimeNewerDate => $TicketCreateTimeNewerDate->ToString(),
1234    UserID                    => 1,
1235    Permission                => 'rw',
1236);
1237$Self->True(
1238    $TicketIDs{$TicketID},
1239    'TicketSearch() (HASH:TicketCreateTimeNewerDate => 60)',
1240);
1241
1242# Test TicketLastChangeTimeNewerDate
1243my $TicketLastChangeTimeNewerDate = $Kernel::OM->Create('Kernel::System::DateTime');
1244$TicketLastChangeTimeNewerDate->Subtract( Hours => 1 );
1245
1246%TicketIDs = $TicketObject->TicketSearch(
1247    Result                        => 'HASH',
1248    Limit                         => 100,
1249    TicketLastChangeTimeNewerDate => $TicketLastChangeTimeNewerDate->ToString(),
1250    UserID                        => 1,
1251    Permission                    => 'rw',
1252);
1253$Self->True(
1254    $TicketIDs{$TicketID},
1255    'TicketSearch() (HASH:TicketLastChangeTimeNewerDate => 60)',
1256);
1257
1258# Test ArticleCreateTimeNewerDate
1259my $ArticleCreateTimeNewerDate = $Kernel::OM->Create('Kernel::System::DateTime');
1260$ArticleCreateTimeNewerDate->Subtract( Hours => 1 );
1261
1262%TicketIDs = $TicketObject->TicketSearch(
1263    Result                     => 'HASH',
1264    Limit                      => 100,
1265    ArticleCreateTimeNewerDate => $ArticleCreateTimeNewerDate->ToString(),
1266    UserID                     => 1,
1267    Permission                 => 'rw',
1268);
1269$Self->True(
1270    $TicketIDs{$TicketID},
1271    'TicketSearch() (HASH:ArticleCreateTimeNewerDate => 60)',
1272);
1273
1274# Test TicketLastChangeOlderDate
1275my $TicketLastChangeOlderDate = $Kernel::OM->Create('Kernel::System::DateTime');
1276$TicketLastChangeOlderDate->Subtract( Hours => 1 );
1277
1278%TicketIDs = $TicketObject->TicketSearch(
1279    Result                        => 'HASH',
1280    Limit                         => 100,
1281    TicketLastChangeTimeOlderDate => $TicketLastChangeOlderDate->ToString(),
1282    UserID                        => 1,
1283    Permission                    => 'rw',
1284);
1285$Self->False(
1286    $TicketIDs{$TicketID},
1287    'TicketSearch() (HASH:TicketLastChangeTimeOlderDate => 60)',
1288);
1289
1290# Test TicketCreateOlderDate
1291my $TicketCreateOlderDate = $Kernel::OM->Create('Kernel::System::DateTime');
1292$TicketCreateOlderDate->Subtract( Hours => 1 );
1293
1294%TicketIDs = $TicketObject->TicketSearch(
1295    Result                    => 'HASH',
1296    Limit                     => 100,
1297    TicketCreateTimeOlderDate => $TicketCreateOlderDate->ToString(),
1298    UserID                    => 1,
1299    Permission                => 'rw',
1300);
1301$Self->False(
1302    $TicketIDs{$TicketID},
1303    'TicketSearch() (HASH:TicketCreateTimeOlderDate => 60)',
1304);
1305
1306# Test ArticleCreateOlderDate
1307my $ArticleCreateOlderDate = $Kernel::OM->Create('Kernel::System::DateTime');
1308$ArticleCreateOlderDate->Subtract( Hours => 1 );
1309
1310%TicketIDs = $TicketObject->TicketSearch(
1311    Result                     => 'HASH',
1312    Limit                      => 100,
1313    ArticleCreateTimeOlderDate => $ArticleCreateOlderDate->ToString(),
1314    UserID                     => 1,
1315    Permission                 => 'rw',
1316);
1317$Self->False(
1318    $TicketIDs{$TicketID},
1319    'TicketSearch() (HASH:ArticleCreateTimeOlderDate => 60)',
1320);
1321
1322# Test TicketCloseTimeNewerDate
1323my $TicketCloseTimeNewerDate = $Kernel::OM->Create('Kernel::System::DateTime');
1324$TicketCloseTimeNewerDate->Subtract( Hours => 1 );
1325
1326%TicketIDs = $TicketObject->TicketSearch(
1327    Result                   => 'HASH',
1328    Limit                    => 100,
1329    TicketCloseTimeNewerDate => $TicketCloseTimeNewerDate->ToString(),
1330    UserID                   => 1,
1331    Permission               => 'rw',
1332);
1333$Self->True(
1334    $TicketIDs{$TicketID},
1335    'TicketSearch() (HASH:TicketCloseTimeNewerDate => 60)',
1336);
1337
1338# Test TicketCloseOlderDate
1339my $TicketCloseOlderDate = $Kernel::OM->Create('Kernel::System::DateTime');
1340$TicketCloseOlderDate->Subtract( Hours => 1 );
1341
1342%TicketIDs = $TicketObject->TicketSearch(
1343    Result                   => 'HASH',
1344    Limit                    => 100,
1345    TicketCloseTimeOlderDate => $TicketCloseOlderDate->ToString(),
1346    UserID                   => 1,
1347    Permission               => 'rw',
1348);
1349$Self->False(
1350    $TicketIDs{$TicketID},
1351    'TicketSearch() (HASH:TicketCloseTimeOlderDate => 60)',
1352);
1353
1354my %Ticket2 = $TicketObject->TicketGet( TicketID => $TicketID );
1355$Self->Is(
1356    $Ticket2{Title},
1357    'Very long title 01234567890123456789012345678901234567890123456789'
1358        . '0123456789012345678901234567890123456789012345678901234567890123456789'
1359        . '0123456789012345678901234567890123456789012345678901234567890123456789'
1360        . '0123456789012345678901234567890123456789',
1361    'TicketGet() (Title)',
1362);
1363$Self->Is(
1364    $Ticket2{Queue},
1365    'Junk',
1366    'TicketGet() (Queue)',
1367);
1368$Self->Is(
1369    $Ticket2{Priority},
1370    '2 low',
1371    'TicketGet() (Priority)',
1372);
1373$Self->Is(
1374    $Ticket2{State},
1375    'open',
1376    'TicketGet() (State)',
1377);
1378$Self->Is(
1379    $Ticket2{Lock},
1380    'lock',
1381    'TicketGet() (Lock)',
1382);
1383
1384my @MoveQueueList = $TicketObject->MoveQueueList(
1385    TicketID => $TicketID,
1386    Type     => 'Name',
1387);
1388
1389$Self->Is(
1390    $MoveQueueList[0],
1391    'Raw',
1392    'MoveQueueList() (Raw)',
1393);
1394$Self->Is(
1395    $MoveQueueList[-1],
1396    'Junk',
1397    'MoveQueueList() (Junk)',
1398);
1399
1400my $TicketAccountTime = $TicketObject->TicketAccountTime(
1401    TicketID  => $TicketID,
1402    ArticleID => $ArticleID,
1403    TimeUnit  => '4.5',
1404    UserID    => 1,
1405);
1406
1407$Self->True(
1408    $TicketAccountTime,
1409    'TicketAccountTime() 1',
1410);
1411
1412my $TicketAccountTime2 = $TicketObject->TicketAccountTime(
1413    TicketID  => $TicketID,
1414    ArticleID => $ArticleID,
1415    TimeUnit  => '4123.53',
1416    UserID    => 1,
1417);
1418
1419$Self->True(
1420    $TicketAccountTime2,
1421    'TicketAccountTime() 2',
1422);
1423
1424my $TicketAccountTime3 = $TicketObject->TicketAccountTime(
1425    TicketID  => $TicketID,
1426    ArticleID => $ArticleID,
1427    TimeUnit  => '4,53',
1428    UserID    => 1,
1429);
1430
1431$Self->True(
1432    $TicketAccountTime3,
1433    'TicketAccountTime() 3',
1434);
1435
1436my $AccountedTime = $TicketObject->TicketAccountedTimeGet( TicketID => $TicketID );
1437
1438$Self->Is(
1439    $AccountedTime,
1440    4132.56,
1441    'TicketAccountedTimeGet()',
1442);
1443
1444my $AccountedTime2 = $ArticleObject->ArticleAccountedTimeGet(
1445    ArticleID => $ArticleID,
1446);
1447
1448$Self->Is(
1449    $AccountedTime2,
1450    4132.56,
1451    'ArticleAccountedTimeGet()'
1452);
1453
1454my $HistoryTicketStatusGetStartObj    = $Kernel::OM->Create('Kernel::System::DateTime');
1455my $HistoryTicketStatusGetStartValues = $HistoryTicketStatusGetStartObj->Get();
1456
1457my $HistoryTicketStatusGetStopObj = $Kernel::OM->Create('Kernel::System::DateTime');
1458$HistoryTicketStatusGetStopObj->Subtract( Days => 1 );
1459my $HistoryTicketStatusGetStopValues = $HistoryTicketStatusGetStopObj->Get();
1460
1461my %TicketStatus = $TicketObject->HistoryTicketStatusGet(
1462    StopYear   => $HistoryTicketStatusGetStartValues->{Year},
1463    StopMonth  => $HistoryTicketStatusGetStartValues->{Month},
1464    StopDay    => $HistoryTicketStatusGetStartValues->{Day},
1465    StartYear  => $HistoryTicketStatusGetStopValues->{Year},
1466    StartMonth => $HistoryTicketStatusGetStopValues->{Month},
1467    StartDay   => $HistoryTicketStatusGetStopValues->{Day},
1468);
1469
1470if ( $TicketStatus{$TicketID} ) {
1471    my %TicketHistory = %{ $TicketStatus{$TicketID} };
1472    $Self->Is(
1473        $TicketHistory{TicketNumber},
1474        $Ticket{TicketNumber},
1475        "HistoryTicketStatusGet() (TicketNumber)",
1476    );
1477    $Self->Is(
1478        $TicketHistory{TicketID},
1479        $TicketID,
1480        "HistoryTicketStatusGet() (TicketID)",
1481    );
1482    $Self->Is(
1483        $TicketHistory{CreateUserID},
1484        1,
1485        "HistoryTicketStatusGet() (CreateUserID)",
1486    );
1487    $Self->Is(
1488        $TicketHistory{Queue},
1489        'Junk',
1490        "HistoryTicketStatusGet() (Queue)",
1491    );
1492    $Self->Is(
1493        $TicketHistory{CreateQueue},
1494        'Raw',
1495        "HistoryTicketStatusGet() (CreateQueue)",
1496    );
1497    $Self->Is(
1498        $TicketHistory{State},
1499        'open',
1500        "HistoryTicketStatusGet() (State)",
1501    );
1502    $Self->Is(
1503        $TicketHistory{CreateState},
1504        'closed successful',
1505        "HistoryTicketStatusGet() (CreateState)",
1506    );
1507    $Self->Is(
1508        $TicketHistory{Priority},
1509        '2 low',
1510        "HistoryTicketStatusGet() (Priority)",
1511    );
1512    $Self->Is(
1513        $TicketHistory{CreatePriority},
1514        '3 normal',
1515        "HistoryTicketStatusGet() (CreatePriority)",
1516    );
1517
1518}
1519else {
1520    $Self->True(
1521        0,
1522        'HistoryTicketStatusGet()',
1523    );
1524}
1525
1526my $Delete = $TicketObject->TicketDelete(
1527    TicketID => $TicketID,
1528    UserID   => 1,
1529);
1530$Self->True(
1531    $Delete,
1532    'TicketDelete()',
1533);
1534
1535my $DeleteCheck = $TicketObject->TicketGet(
1536    TicketID => $TicketID,
1537    UserID   => 1,
1538);
1539
1540$Self->False(
1541    $DeleteCheck,
1542    'TicketDelete() worked',
1543);
1544
1545my $CustomerNo = 'CustomerNo' . $Helper->GetRandomID();
1546
1547# ticket search sort/order test
1548my $TicketIDSortOrder1 = $TicketObject->TicketCreate(
1549    Title        => 'Some Ticket_Title - ticket sort/order by tests',
1550    Queue        => 'Raw',
1551    Lock         => 'unlock',
1552    Priority     => '3 normal',
1553    State        => 'new',
1554    CustomerNo   => $CustomerNo,
1555    CustomerUser => 'unittest@otrs.com',
1556    OwnerID      => 1,
1557    UserID       => 1,
1558);
1559
1560my %TicketCreated = $TicketObject->TicketGet(
1561    TicketID => $TicketIDSortOrder1,
1562    UserID   => 1,
1563);
1564
1565# wait 2 seconds
1566$Helper->FixedTimeAddSeconds(2);
1567
1568my $TicketIDSortOrder2 = $TicketObject->TicketCreate(
1569    Title        => 'Some Ticket_Title - ticket sort/order by tests2',
1570    Queue        => 'Raw',
1571    Lock         => 'unlock',
1572    Priority     => '3 normal',
1573    State        => 'new',
1574    CustomerNo   => $CustomerNo,
1575    CustomerUser => 'unittest@otrs.com',
1576    OwnerID      => 1,
1577    UserID       => 1,
1578);
1579
1580# wait 2 seconds
1581$Helper->FixedTimeAddSeconds(2);
1582
1583my $Success = $TicketObject->TicketStateSet(
1584    State    => 'open',
1585    TicketID => $TicketIDSortOrder1,
1586    UserID   => 1,
1587);
1588
1589my %TicketUpdated = $TicketObject->TicketGet(
1590    TicketID => $TicketIDSortOrder1,
1591    UserID   => 1,
1592);
1593
1594$Self->IsNot(
1595    $TicketCreated{Changed},
1596    $TicketUpdated{Changed},
1597    'TicketUpdated for sort - change time was updated'
1598        . " $TicketCreated{Changed} ne $TicketUpdated{Changed}",
1599);
1600
1601# find newest ticket by priority, age
1602my @TicketIDsSortOrder = $TicketObject->TicketSearch(
1603    Result       => 'ARRAY',
1604    Title        => '%sort/order by test%',
1605    Queues       => ['Raw'],
1606    CustomerID   => $CustomerNo,
1607    CustomerUser => 'unittest@otrs.com',
1608    OrderBy      => [ 'Down', 'Up' ],
1609    SortBy       => [ 'Priority', 'Age' ],
1610    UserID       => 1,
1611    Limit        => 1,
1612);
1613
1614$Self->Is(
1615    $TicketIDsSortOrder[0],
1616    $TicketIDSortOrder1,
1617    'TicketTicketSearch() - ticket sort/order by (Priority (Down), Age (Up))',
1618);
1619
1620# find oldest ticket by priority, age
1621@TicketIDsSortOrder = $TicketObject->TicketSearch(
1622    Result       => 'ARRAY',
1623    Title        => '%sort/order by test%',
1624    Queues       => ['Raw'],
1625    CustomerID   => $CustomerNo,
1626    CustomerUser => 'unittest@otrs.com',
1627    OrderBy      => [ 'Down', 'Down' ],
1628    SortBy       => [ 'Priority', 'Age' ],
1629    UserID       => 1,
1630    Limit        => 1,
1631);
1632$Self->Is(
1633    $TicketIDsSortOrder[0],
1634    $TicketIDSortOrder2,
1635    'TicketTicketSearch() - ticket sort/order by (Priority (Down), Age (Down))',
1636);
1637
1638# find last modified ticket by changed time
1639@TicketIDsSortOrder = $TicketObject->TicketSearch(
1640    Result       => 'ARRAY',
1641    Title        => '%sort/order by test%',
1642    Queues       => ['Raw'],
1643    CustomerID   => $CustomerNo,
1644    CustomerUser => 'unittest@otrs.com',
1645    OrderBy      => [ 'Down', ],
1646    SortBy       => ['Changed'],
1647    UserID       => 1,
1648    Limit        => 1,
1649);
1650$Self->Is(
1651    $TicketIDsSortOrder[0],
1652    $TicketIDSortOrder1,
1653    'TicketTicketSearch() - ticket sort/order by (Changed (Down))'
1654        . "$TicketIDsSortOrder[0] instead of $TicketIDSortOrder1",
1655);
1656
1657# find oldest modified by changed time
1658@TicketIDsSortOrder = $TicketObject->TicketSearch(
1659    Result       => 'ARRAY',
1660    Title        => '%sort/order by test%',
1661    Queues       => ['Raw'],
1662    CustomerID   => $CustomerNo,
1663    CustomerUser => 'unittest@otrs.com',
1664    OrderBy      => [ 'Up', ],
1665    SortBy       => [ 'Changed', ],
1666    UserID       => 1,
1667    Limit        => 1,
1668);
1669$Self->Is(
1670    $TicketIDsSortOrder[0],
1671    $TicketIDSortOrder2,
1672    'TicketTicketSearch() - ticket sort/order by (Changed (Up)))'
1673        . "$TicketIDsSortOrder[0]  instead of $TicketIDSortOrder2",
1674);
1675
1676my $TicketIDSortOrder3 = $TicketObject->TicketCreate(
1677    Title        => 'Some Ticket_Title - ticket sort/order by tests2',
1678    Queue        => 'Raw',
1679    Lock         => 'unlock',
1680    Priority     => '4 high',
1681    State        => 'new',
1682    CustomerNo   => $CustomerNo,
1683    CustomerUser => 'unittest@otrs.com',
1684    OwnerID      => 1,
1685    UserID       => 1,
1686);
1687
1688# wait 2 seconds
1689$Helper->FixedTimeAddSeconds(2);
1690
1691my $TicketIDSortOrder4 = $TicketObject->TicketCreate(
1692    Title        => 'Some Ticket_Title - ticket sort/order by tests2',
1693    Queue        => 'Raw',
1694    Lock         => 'unlock',
1695    Priority     => '4 high',
1696    State        => 'new',
1697    CustomerNo   => $CustomerNo,
1698    CustomerUser => 'unittest@otrs.com',
1699    OwnerID      => 1,
1700    UserID       => 1,
1701);
1702
1703# wait 2 seconds
1704$Helper->FixedTimeAddSeconds(2);
1705
1706my $TicketIDSortOrder5 = $TicketObject->TicketCreate(
1707    Title        => 'Some Ticket_Title - ticket sort/order by tests5 (with other queue)',
1708    Queue        => 'Misc',
1709    Lock         => 'unlock',
1710    Priority     => '3 normal',
1711    State        => 'new',
1712    CustomerNo   => $CustomerNo,
1713    CustomerUser => 'unittest@otrs.com',
1714    OwnerID      => 1,
1715    UserID       => 1,
1716);
1717
1718# find oldest ticket by priority, age
1719@TicketIDsSortOrder = $TicketObject->TicketSearch(
1720    Result       => 'ARRAY',
1721    Title        => '%sort/order by test%',
1722    Queues       => ['Raw'],
1723    CustomerID   => $CustomerNo,
1724    CustomerUser => 'unittest@otrs.com',
1725    OrderBy      => [ 'Down', 'Down' ],
1726    SortBy       => [ 'Priority', 'Age' ],
1727    UserID       => 1,
1728    Limit        => 1,
1729);
1730$Self->Is(
1731    $TicketIDsSortOrder[0],
1732    $TicketIDSortOrder4,
1733    'TicketTicketSearch() - ticket sort/order by (Priority (Down), Age (Down))',
1734);
1735
1736# find oldest ticket by priority, age
1737@TicketIDsSortOrder = $TicketObject->TicketSearch(
1738    Result       => 'ARRAY',
1739    Title        => '%sort/order by test%',
1740    Queues       => ['Raw'],
1741    CustomerID   => $CustomerNo,
1742    CustomerUser => 'unittest@otrs.com',
1743    OrderBy      => [ 'Up', 'Down' ],
1744    SortBy       => [ 'Priority', 'Age' ],
1745    UserID       => 1,
1746    Limit        => 1,
1747);
1748$Self->Is(
1749    $TicketIDsSortOrder[0],
1750    $TicketIDSortOrder2,
1751    'TicketTicketSearch() - ticket sort/order by (Priority (Up), Age (Down))',
1752);
1753
1754# find newest ticket
1755@TicketIDsSortOrder = $TicketObject->TicketSearch(
1756    Result       => 'ARRAY',
1757    Title        => '%sort/order by test%',
1758    Queues       => ['Raw'],
1759    CustomerID   => $CustomerNo,
1760    CustomerUser => 'unittest@otrs.com',
1761    OrderBy      => 'Down',
1762    SortBy       => 'Age',
1763    UserID       => 1,
1764    Limit        => 1,
1765);
1766$Self->Is(
1767    $TicketIDsSortOrder[0],
1768    $TicketIDSortOrder4,
1769    'TicketTicketSearch() - ticket sort/order by (Age (Down))',
1770);
1771
1772# find oldest ticket
1773@TicketIDsSortOrder = $TicketObject->TicketSearch(
1774    Result       => 'ARRAY',
1775    Title        => '%sort/order by test%',
1776    Queues       => ['Raw'],
1777    CustomerID   => $CustomerNo,
1778    CustomerUser => 'unittest@otrs.com',
1779    OrderBy      => 'Up',
1780    SortBy       => 'Age',
1781    UserID       => 1,
1782    Limit        => 1,
1783);
1784$Self->Is(
1785    $TicketIDsSortOrder[0],
1786    $TicketIDSortOrder1,
1787    'TicketTicketSearch() - ticket sort/order by (Age (Up))',
1788);
1789
1790# sort by ticket queue
1791@TicketIDsSortOrder = $TicketObject->TicketSearch(
1792    Result       => 'ARRAY',
1793    Title        => '%sort/order by test%',
1794    Queues       => [ 'Misc', 'Raw' ],
1795    CustomerID   => $CustomerNo,
1796    CustomerUser => 'unittest@otrs.com',
1797    OrderBy      => 'Up',
1798    SortBy       => 'Queue',
1799    UserID       => 1,
1800    Limit        => 1,
1801);
1802$Self->Is(
1803    $TicketIDsSortOrder[0],
1804    $TicketIDSortOrder5,
1805    'TicketTicketSearch() - ticket sort/order by (Queue (Up))',
1806);
1807
1808$Count = $TicketObject->TicketSearch(
1809    Result       => 'COUNT',
1810    Title        => '%sort/order by test%',
1811    Queues       => ['Raw'],
1812    CustomerID   => $CustomerNo,
1813    CustomerUser => 'unittest@otrs.com',
1814    UserID       => 1,
1815    Limit        => 1,
1816);
1817$Self->Is(
1818    $Count,
1819    4,
1820    'TicketTicketSearch() - ticket count for created tickets',
1821);
1822
1823for my $TicketIDDelete (
1824    $TicketIDSortOrder1, $TicketIDSortOrder2, $TicketIDSortOrder3,
1825    $TicketIDSortOrder4
1826    )
1827{
1828    $Self->True(
1829        $TicketObject->TicketDelete(
1830            TicketID => $TicketIDDelete,
1831            UserID   => 1,
1832        ),
1833        "TicketDelete()",
1834    );
1835}
1836
1837# avoid StateType and StateTypeID problems in TicketSearch()
1838
1839my %StateTypeList = $StateObject->StateTypeList(
1840    UserID => 1,
1841);
1842
1843# you need a hash with the state as key and the related StateType and StateTypeID as
1844# reference
1845my %StateAsKeyAndStateTypeAsValue;
1846for my $StateTypeID ( sort keys %StateTypeList ) {
1847    my @List = $StateObject->StateGetStatesByType(
1848        StateType => [ $StateTypeList{$StateTypeID} ],
1849        Result    => 'Name',                             # HASH|ID|Name
1850    );
1851    for my $Index (@List) {
1852        $StateAsKeyAndStateTypeAsValue{$Index}->{Name} = $StateTypeList{$StateTypeID};
1853        $StateAsKeyAndStateTypeAsValue{$Index}->{ID}   = $StateTypeID;
1854    }
1855}
1856
1857# to be sure that you have a result ticket create one
1858$TicketID = $TicketObject->TicketCreate(
1859    Title        => 'StateTypeTest',
1860    Queue        => 'Raw',
1861    Lock         => 'unlock',
1862    Priority     => '3 normal',
1863    State        => 'new',
1864    CustomerID   => '123465',
1865    CustomerUser => 'unittest@otrs.com',
1866    OwnerID      => 1,
1867    UserID       => 1,
1868);
1869
1870my %StateList = $StateObject->StateList( UserID => 1 );
1871
1872# now check every possible state
1873for my $State ( values %StateList ) {
1874    $TicketObject->StateSet(
1875        State              => $State,
1876        TicketID           => $TicketID,
1877        SendNoNotification => 1,
1878        UserID             => 1,
1879    );
1880
1881    my @TicketIDs = $TicketObject->TicketSearch(
1882        Result       => 'ARRAY',
1883        Title        => '%StateTypeTest%',
1884        Queues       => ['Raw'],
1885        StateTypeIDs => [ $StateAsKeyAndStateTypeAsValue{$State}->{ID} ],
1886        UserID       => 1,
1887    );
1888
1889    my @TicketIDsType = $TicketObject->TicketSearch(
1890        Result    => 'ARRAY',
1891        Title     => '%StateTypeTest%',
1892        Queues    => ['Raw'],
1893        StateType => [ $StateAsKeyAndStateTypeAsValue{$State}->{Name} ],
1894        UserID    => 1,
1895    );
1896
1897    if ( $TicketIDs[0] ) {
1898        my %Ticket = $TicketObject->TicketGet(
1899            TicketID => $TicketIDs[0],
1900            UserID   => 1,
1901        );
1902    }
1903
1904    # if there is no result the StateTypeID hasn't worked
1905    # Test if there is a result, if I use StateTypeID $StateAsKeyAndStateTypeAsValue{$State}->{ID}
1906    $Self->True(
1907        $TicketIDs[0],
1908        "TicketSearch() - StateTypeID - found ticket",
1909    );
1910
1911# if it is not equal then there is in the using of StateType or StateTypeID an error
1912# check if you get the same result if you use the StateType attribute or the StateTypeIDs attribute.
1913# State($State) StateType($StateAsKeyAndStateTypeAsValue{$State}->{Name}) and StateTypeIDs($StateAsKeyAndStateTypeAsValue{$State}->{ID})
1914    $Self->Is(
1915        scalar @TicketIDs,
1916        scalar @TicketIDsType,
1917        "TicketSearch() - StateType",
1918    );
1919}
1920
1921my %TicketPending = $TicketObject->TicketGet(
1922    TicketID => $TicketID,
1923    UserID   => 1,
1924);
1925
1926$Self->Is(
1927    $TicketPending{UntilTime},
1928    '0',
1929    "TicketPendingTimeSet() - Pending Time - not set",
1930);
1931
1932my $Diff               = 60;
1933my $CurrentSystemTime  = $Kernel::OM->Create('Kernel::System::DateTime')->ToEpoch();
1934my $PendingTimeSetDiff = $TicketObject->TicketPendingTimeSet(
1935    Diff     => $Diff,
1936    TicketID => $TicketID,
1937    UserID   => 1,
1938);
1939
1940$Self->True(
1941    $PendingTimeSetDiff,
1942    "TicketPendingTimeSet() - Pending Time - set diff",
1943);
1944
1945%TicketPending = $TicketObject->TicketGet(
1946    TicketID => $TicketID,
1947    UserID   => 1,
1948);
1949
1950$Self->Is(
1951    $TicketPending{RealTillTimeNotUsed},
1952    $CurrentSystemTime + $Diff * 60,
1953    "TicketPendingTimeSet() - diff time check",
1954);
1955
1956my $PendingTimeSet = $TicketObject->TicketPendingTimeSet(
1957    TicketID => $TicketID,
1958    UserID   => 1,
1959    Year     => '2003',
1960    Month    => '08',
1961    Day      => '14',
1962    Hour     => '22',
1963    Minute   => '05',
1964);
1965
1966$Self->True(
1967    $PendingTimeSet,
1968    "TicketPendingTimeSet() - Pending Time - set",
1969);
1970
1971%TicketPending = $TicketObject->TicketGet(
1972    TicketID => $TicketID,
1973    UserID   => 1,
1974);
1975
1976my $PendingUntilTime = $Kernel::OM->Create(
1977    'Kernel::System::DateTime',
1978    ObjectParams => {
1979        Year   => '2003',
1980        Month  => '08',
1981        Day    => '14',
1982        Hour   => '22',
1983        Minute => '05',
1984        Second => '00',
1985    }
1986)->ToEpoch();
1987
1988$PendingUntilTime = $Kernel::OM->Create('Kernel::System::DateTime')->ToEpoch() - $PendingUntilTime;
1989
1990$Self->Is(
1991    $TicketPending{UntilTime},
1992    '-' . $PendingUntilTime,
1993    "TicketPendingTimeSet() - Pending Time - read back",
1994);
1995
1996$PendingTimeSet = $TicketObject->TicketPendingTimeSet(
1997    TicketID => $TicketID,
1998    UserID   => 1,
1999    Year     => '0',
2000    Month    => '0',
2001    Day      => '0',
2002    Hour     => '0',
2003    Minute   => '0',
2004);
2005
2006$Self->True(
2007    $PendingTimeSet,
2008    "TicketPendingTimeSet() - Pending Time - reset",
2009);
2010
2011%TicketPending = $TicketObject->TicketGet(
2012    TicketID => $TicketID,
2013    UserID   => 1,
2014);
2015
2016$Self->Is(
2017    $TicketPending{UntilTime},
2018    '0',
2019    "TicketPendingTimeSet() - Pending Time - not set",
2020);
2021
2022$PendingTimeSet = $TicketObject->TicketPendingTimeSet(
2023    TicketID => $TicketID,
2024    UserID   => 1,
2025    String   => '2003-09-14 22:05:00',
2026);
2027
2028$Self->True(
2029    $PendingTimeSet,
2030    "TicketPendingTimeSet() - Pending Time - set string",
2031);
2032
2033%TicketPending = $TicketObject->TicketGet(
2034    TicketID => $TicketID,
2035    UserID   => 1,
2036);
2037
2038$PendingUntilTime = $Kernel::OM->Create(
2039    'Kernel::System::DateTime',
2040    ObjectParams => {
2041        String => '2003-09-14 22:05:00',
2042    }
2043)->ToEpoch();
2044
2045$PendingUntilTime = $Kernel::OM->Create('Kernel::System::DateTime')->ToEpoch() - $PendingUntilTime;
2046
2047$Self->Is(
2048    $TicketPending{UntilTime},
2049    '-' . $PendingUntilTime,
2050    "TicketPendingTimeSet() - Pending Time - read back",
2051);
2052
2053$PendingTimeSet = $TicketObject->TicketPendingTimeSet(
2054    TicketID => $TicketID,
2055    UserID   => 1,
2056    String   => '0000-00-00 00:00:00',
2057);
2058
2059$Self->True(
2060    $PendingTimeSet,
2061    "TicketPendingTimeSet() - Pending Time - reset string",
2062);
2063
2064%TicketPending = $TicketObject->TicketGet(
2065    TicketID => $TicketID,
2066    UserID   => 1,
2067);
2068
2069$Self->Is(
2070    $TicketPending{UntilTime},
2071    '0',
2072    "TicketPendingTimeSet() - Pending Time - not set",
2073);
2074
2075$PendingTimeSet = $TicketObject->TicketPendingTimeSet(
2076    TicketID => $TicketID,
2077    UserID   => 1,
2078    String   => '2003-09-14 22:05:00',
2079);
2080
2081$Self->True(
2082    $PendingTimeSet,
2083    "TicketPendingTimeSet() - Pending Time - set string",
2084);
2085
2086my $TicketStateUpdate = $TicketObject->TicketStateSet(
2087    TicketID => $TicketID,
2088    UserID   => 1,
2089    State    => 'pending reminder',
2090);
2091
2092%TicketPending = $TicketObject->TicketGet(
2093    TicketID => $TicketID,
2094    UserID   => 1,
2095);
2096
2097$Self->True(
2098    $TicketPending{UntilTime},
2099    "TicketPendingTimeSet() - Set to pending - time should still be there",
2100);
2101
2102$TicketStateUpdate = $TicketObject->TicketStateSet(
2103    TicketID => $TicketID,
2104    UserID   => 1,
2105    State    => 'new',
2106);
2107
2108%TicketPending = $TicketObject->TicketGet(
2109    TicketID => $TicketID,
2110    UserID   => 1,
2111);
2112
2113$Self->Is(
2114    $TicketPending{UntilTime},
2115    '0',
2116    "TicketPendingTimeSet() - Set to new - Pending Time not set",
2117);
2118
2119# check that searches with NewerDate in the future are not executed
2120$Helper->FixedTimeAddSeconds( -60 * 60 );
2121
2122# Test TicketCreateTimeNewerDate (future date)
2123$TicketCreateTimeNewerDate = $Kernel::OM->Create('Kernel::System::DateTime');
2124$TicketCreateTimeNewerDate->Add( Hours => 1 );
2125
2126%TicketIDs = $TicketObject->TicketSearch(
2127    Result                    => 'HASH',
2128    Limit                     => 100,
2129    TicketCreateTimeNewerDate => $TicketCreateTimeNewerDate->ToString(),
2130    UserID                    => 1,
2131    Permission                => 'rw',
2132);
2133$Self->False(
2134    $TicketIDs{$TicketID},
2135    'TicketSearch() (HASH:TicketCreateTimeNewerDate => -60)',
2136);
2137
2138# Test ArticleCreateTimeNewerDate (future date)
2139$ArticleCreateTimeNewerDate = $Kernel::OM->Create('Kernel::System::DateTime');
2140$ArticleCreateTimeNewerDate->Add( Hours => 1 );
2141
2142%TicketIDs = $TicketObject->TicketSearch(
2143    Result                     => 'HASH',
2144    Limit                      => 100,
2145    ArticleCreateTimeNewerDate => $ArticleCreateTimeNewerDate->ToString(),
2146    UserID                     => 1,
2147    Permission                 => 'rw',
2148);
2149$Self->False(
2150    $TicketIDs{$TicketID},
2151    'TicketSearch() (HASH:ArticleCreateTimeNewerDate => -60)',
2152);
2153
2154# Test TicketCloseTimeNewerDate (future date)
2155$TicketCloseTimeNewerDate = $Kernel::OM->Create('Kernel::System::DateTime');
2156$TicketCloseTimeNewerDate->Add( Hours => 1 );
2157
2158%TicketIDs = $TicketObject->TicketSearch(
2159    Result                   => 'HASH',
2160    Limit                    => 100,
2161    TicketCloseTimeNewerDate => $TicketCloseTimeNewerDate->ToString(),
2162    UserID                   => 1,
2163    Permission               => 'rw',
2164);
2165$Self->False(
2166    $TicketIDs{$TicketID},
2167    'TicketSearch() (HASH:TicketCloseTimeNewerDate => -60)',
2168);
2169
2170# the ticket is no longer needed
2171$TicketObject->TicketDelete(
2172    TicketID => $TicketID,
2173    UserID   => 1,
2174);
2175
2176# tests for searching StateTypes that might not have states
2177# this should return an empty list rather then a big SQL error
2178# the problem is, we can't really test if there is an SQL error or not
2179# ticket search returns an empty list anyway
2180
2181my @NewStates = $StateObject->StateGetStatesByType(
2182    StateType => ['new'],
2183    Result    => 'ID',
2184);
2185
2186# make sure we don't have valid states for state type new
2187for my $NewStateID (@NewStates) {
2188    my %State = $StateObject->StateGet(
2189        ID => $NewStateID,
2190    );
2191    $StateObject->StateUpdate(
2192        %State,
2193        ValidID => 2,
2194        UserID  => 1,
2195    );
2196}
2197
2198my @TicketIDs = $TicketObject->TicketSearch(
2199    Result       => 'LIST',
2200    Limit        => 100,
2201    TicketNumber => [ $Ticket{TicketNumber}, 'ABC' ],
2202    StateType    => 'New',
2203    UserID       => 1,
2204    Permission   => 'rw',
2205);
2206$Self->False(
2207    $TicketIDs[0],
2208    'TicketSearch() (LIST:TicketNumber,StateType:new (no valid states of state type new)',
2209);
2210
2211# activate states again
2212for my $NewStateID (@NewStates) {
2213    my %State = $StateObject->StateGet(
2214        ID => $NewStateID,
2215    );
2216    $StateObject->StateUpdate(
2217        %State,
2218        ValidID => 1,
2219        UserID  => 1,
2220    );
2221}
2222
2223# check response of ticket search for invalid timestamps
2224for my $SearchParam (qw(ArticleCreateTime TicketCreateTime TicketPendingTime)) {
2225    for my $ParamOption (qw(OlderDate NewerDate)) {
2226        $TicketObject->TicketSearch(
2227            $SearchParam . $ParamOption => '2000-02-31 00:00:00',
2228            UserID                      => 1,
2229        );
2230        my $ErrorMessage = $Kernel::OM->Get('Kernel::System::Log')->GetLogEntry(
2231            Type => 'error',
2232            What => 'Message',
2233        );
2234        $Self->Is(
2235            $ErrorMessage,
2236            "Search not executed due to invalid time '2000-02-31 00:00:00'!",
2237            "TicketSearch() (Handling invalid timestamp in '$SearchParam$ParamOption')",
2238        );
2239    }
2240}
2241
2242# Create enviroment for testing Escalation ORDER BY modification from the bug#13458.
2243# Create Queues with different Escalation times.
2244my @QueueConfig = (
2245    {
2246        # First created Queue does not have Update time set, value is 0 for created ticket.
2247        Name              => 'Queue' . $Helper->GetRandomID(),
2248        FirstResponseTime => 50,
2249        SolutionTime      => 60,
2250    },
2251    {
2252        # Second created Queue does not have First response time set, value is 0 for created ticket.
2253        Name         => 'Queue' . $Helper->GetRandomID(),
2254        UpdateTime   => 70,
2255        SolutionTime => 80,
2256    },
2257    {
2258        # Third created Queue does not have Solution time set, value is 0 for created ticket.
2259        Name              => 'Queue' . $Helper->GetRandomID(),
2260        FirstResponseTime => 60,
2261        UpdateTime        => 30,
2262    },
2263);
2264
2265my @QueueIDs;
2266for my $QueueCreate (@QueueConfig) {
2267    my $QueueID = $QueueObject->QueueAdd(
2268        ValidID         => 1,
2269        GroupID         => 1,
2270        FollowUpID      => 1,
2271        SystemAddressID => 1,
2272        SalutationID    => 1,
2273        SignatureID     => 1,
2274        Comment         => 'Some comment',
2275        UserID          => 1,
2276        %{$QueueCreate},
2277    );
2278    push @QueueIDs, $QueueID;
2279}
2280
2281# Create Tickets.
2282my @TestTicketIDs;
2283for my $QueueID (@QueueIDs) {
2284    my $TicketID = $TicketObject->TicketCreate(
2285        Title        => 'Some Ticket Title',
2286        QueueID      => $QueueID,
2287        Lock         => 'unlock',
2288        Priority     => '3 normal',
2289        State        => 'new',
2290        CustomerID   => '123465',
2291        CustomerUser => 'bugtest@otrs.com',
2292        OwnerID      => 1,
2293        UserID       => 1,
2294    );
2295    push @TestTicketIDs, $TicketID;
2296
2297    my $ArticleID = $ArticleBackendObject->ArticleCreate(
2298        TicketID             => $TicketID,
2299        IsVisibleForCustomer => 0,
2300        SenderType           => 'agent',
2301        From                 => 'Agent Some Agent Some Agent <email@example.com>',
2302        To                   => 'Customer A <customer-a@example.com>',
2303        Cc                   => 'Customer B <customer-b@example.com>',
2304        ReplyTo              => 'Customer B <customer-b@example.com>',
2305        Subject              => 'some short description',
2306        Body                 => 'the message text Perl modules provide a range of',
2307        ContentType          => 'text/plain; charset=ISO-8859-15',
2308        HistoryType          => 'AddNote',
2309        HistoryComment       => 'Some free text!',
2310        UserID               => 1,
2311        NoAgentNotify        => 1,
2312    );
2313
2314    my $TicketEscalationIndexBuild = $TicketObject->TicketEscalationIndexBuild(
2315        TicketID => $TicketID,
2316        UserID   => 1,
2317    );
2318
2319    # Wait 1 second to have escalations.
2320    $Helper->FixedTimeAddSeconds(1);
2321
2322    # Renew objects because of transaction.
2323    $Kernel::OM->ObjectsDiscard(
2324        Objects => [
2325            'Kernel::System::Ticket',
2326            'Kernel::System::Ticket::Article',
2327            'Kernel::System::Ticket::Article::Backend::Internal',
2328        ],
2329    );
2330    $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
2331}
2332
2333# Create TicketSearch by Escalations scenarios.
2334my @Tests = (
2335    {
2336        Config => {
2337            OrderBy => 'Up',
2338            SortBy  => 'EscalationResponseTime',
2339        },
2340        ExpectedResult => [ $TestTicketIDs[1], $TestTicketIDs[0], $TestTicketIDs[2] ],
2341    },
2342    {
2343        Config => {
2344            OrderBy => 'Down',
2345            SortBy  => 'EscalationResponseTime',
2346        },
2347        ExpectedResult => [ $TestTicketIDs[2], $TestTicketIDs[0], $TestTicketIDs[1] ],
2348    },
2349    {
2350        Config => {
2351            OrderBy => 'Up',
2352            SortBy  => 'EscalationUpdateTime',
2353        },
2354        ExpectedResult => [ $TestTicketIDs[0], $TestTicketIDs[2], $TestTicketIDs[1] ],
2355    },
2356    {
2357        Config => {
2358            OrderBy => 'Down',
2359            SortBy  => 'EscalationUpdateTime',
2360        },
2361        ExpectedResult => [ $TestTicketIDs[1], $TestTicketIDs[2], $TestTicketIDs[0] ],
2362    },
2363    {
2364        Config => {
2365            OrderBy => 'Up',
2366            SortBy  => 'EscalationSolutionTime',
2367        },
2368        ExpectedResult => [ $TestTicketIDs[2], $TestTicketIDs[0], $TestTicketIDs[1] ],
2369    },
2370    {
2371        Config => {
2372            OrderBy => 'Down',
2373            SortBy  => 'EscalationSolutionTime',
2374        },
2375        ExpectedResult => [ $TestTicketIDs[1], $TestTicketIDs[0], $TestTicketIDs[2] ],
2376    },
2377);
2378for my $Test (@Tests) {
2379    my @Tickets = $TicketObject->TicketSearch(
2380        Result            => 'ARRAY',
2381        CustomerUserLogin => 'bugtest@otrs.com',
2382        UserID            => 1,
2383        %{ $Test->{Config} },
2384    );
2385    $Self->IsDeeply(
2386        $Test->{ExpectedResult},
2387        \@Tickets,
2388        "TicketSearch() - SortBy $Test->{Config}{SortBy} - OrderBy $Test->{Config}{OrderBy}"
2389    );
2390}
2391
2392# cleanup is done by RestoreDatabase but we need to delete the tickets to cleanup the filesystem too
2393my @DeleteTicketList = $TicketObject->TicketSearch(
2394    Result            => 'ARRAY',
2395    CustomerUserLogin => [ 'unittest@otrs.com', 'bugtest@otrs.com' ],
2396    UserID            => 1,
2397);
2398for my $TicketID (@DeleteTicketList) {
2399    $TicketObject->TicketDelete(
2400        TicketID => $TicketID,
2401        UserID   => 1,
2402    );
2403}
2404
2405# Test ticket search by fulltext (see bug#13284).
2406#   Create a test ticket and add an article for this ticket.
2407#   Note that article subject and ticket title differ.
2408my $TestTicketTitle  = 'title' . $Helper->GetRandomID();
2409my $FulltextTicketID = $TicketObject->TicketCreate(
2410    Title        => $TestTicketTitle,
2411    Queue        => 'Raw',
2412    Lock         => 'unlock',
2413    Priority     => '3 normal',
2414    State        => 'open',
2415    CustomerID   => '123465',
2416    CustomerUser => 'bugtest@otrs.com',
2417    OwnerID      => 1,
2418    UserID       => 1,
2419);
2420
2421my $TestArticleSubject = 'subject' . $Helper->GetRandomID();
2422my $FulltextArticleID  = $ArticleBackendObject->ArticleCreate(
2423    TicketID             => $FulltextTicketID,
2424    IsVisibleForCustomer => 0,
2425    SenderType           => 'agent',
2426    From                 => 'Agent Some Agent Some Agent <email@example.com>',
2427    To                   => 'Customer A <customer-a@example.com>',
2428    Cc                   => 'Customer B <customer-b@example.com>',
2429    ReplyTo              => 'Customer B <customer-b@example.com>',
2430    Subject              => $TestArticleSubject,
2431    Body                 => 'Some text',
2432    ContentType          => 'text/plain; charset=ISO-8859-15',
2433    HistoryType          => 'AddNote',
2434    HistoryComment       => 'Some free text!',
2435    UserID               => 1,
2436    NoAgentNotify        => 1,
2437);
2438
2439$ArticleObject->ArticleSearchIndexBuild(
2440    TicketID  => $FulltextTicketID,
2441    ArticleID => $FulltextArticleID,
2442    UserID    => 1,
2443);
2444
2445# Search for ticket title as fulltext parameter.
2446@TicketIDs = $TicketObject->TicketSearch(
2447    Result     => 'ARRAY',
2448    Fulltext   => $TestTicketTitle,
2449    UserID     => 1,
2450    Permission => 'rw',
2451);
2452
2453# Verify result has one item and it's indeed the test ticket.
2454$Self->IsDeeply(
2455    \@TicketIDs,
2456    [$FulltextTicketID],
2457    "TicketSearch() - search ticket title '$TestTicketTitle' as fulltext - found only TicketID $FulltextTicketID"
2458);
2459
2460# Search for article subject as fulltext parameter.
2461@TicketIDs = $TicketObject->TicketSearch(
2462    Result     => 'ARRAY',
2463    Fulltext   => $TestArticleSubject,
2464    UserID     => 1,
2465    Permission => 'rw',
2466);
2467
2468# Verify result has one item and it's indeed the test ticket.
2469$Self->IsDeeply(
2470    \@TicketIDs,
2471    [$FulltextTicketID],
2472    "TicketSearch() - search article subject '$TestArticleSubject' as fulltext - found only TicketID $FulltextTicketID"
2473);
2474
2475$Success = $TicketObject->TicketDelete(
2476    TicketID => $FulltextTicketID,
2477    UserID   => 1,
2478);
2479$Self->True(
2480    $Success,
2481    "TicketID $FulltextTicketID - deleted",
2482);
2483
2484# Test TicketCountByAttribute() function.
2485# Enable Ticket Type.
2486$Kernel::OM->Get('Kernel::Config')->Set(
2487    Key   => 'Ticket::Type',
2488    Value => 1,
2489);
2490
2491# Create test environment.
2492my $PriorityObject = $Kernel::OM->Get('Kernel::System::Priority');
2493my $RandomID       = $Helper->GetRandomID();
2494my @Priorities;
2495my @Services;
2496my @SLAs;
2497my @States;
2498my @Types;
2499my @Queues;
2500
2501for my $Index ( 1 .. 3 ) {
2502
2503    # Create test queues.
2504    my $QueueName = $Index . 'Queue' . $RandomID;
2505    my $QueueID   = $QueueObject->QueueAdd(
2506        Name            => $QueueName,
2507        ValidID         => 1,
2508        GroupID         => 1,
2509        FollowUpID      => 1,
2510        SystemAddressID => 1,
2511        SalutationID    => 1,
2512        SignatureID     => 1,
2513        Comment         => 'Unit Test Comment',
2514        UserID          => 1,
2515    ) || die "QueueAdd() error.";
2516
2517    push @Queues, {
2518        ID   => $QueueID,
2519        Name => $QueueName,
2520    };
2521
2522    # Create test priorities.
2523    my $PriorityName = $Index . 'Prio' . $RandomID;
2524    my $PriorityID   = $PriorityObject->PriorityAdd(
2525        Name    => $PriorityName,
2526        ValidID => 1,
2527        UserID  => 1,
2528    ) || die "PriorityAdd() error.";
2529
2530    push @Priorities, {
2531        ID   => $PriorityID,
2532        Name => $PriorityName,
2533    };
2534
2535    # Create test services.
2536    my $ServiceName = $Index . 'Service' . $RandomID;
2537    my $ServiceID   = $ServiceObject->ServiceAdd(
2538        Name    => $ServiceName,
2539        ValidID => 1,
2540        Comment => 'Unit Test Comment',
2541        UserID  => 1,
2542    ) || die "ServiceAdd() error.";
2543
2544    push @Services, {
2545        ID   => $ServiceID,
2546        Name => $ServiceName,
2547    };
2548
2549    # Create test SLAs.
2550    my $SLAName = $Index . 'SLA' . $RandomID;
2551    my $SLAID   = $SLAObject->SLAAdd(
2552        Name    => $SLAName,
2553        ValidID => 1,
2554        Comment => 'Unit Test Comment',
2555        UserID  => 1,
2556    ) || die "SLAAdd() error.";
2557
2558    push @SLAs, {
2559        ID   => $SLAID,
2560        Name => $SLAName,
2561    };
2562
2563    # Create test states.
2564    my $StateName = $Index . 'State' . $RandomID;
2565    my $StateID   = $StateObject->StateAdd(
2566        Name    => $StateName,
2567        Comment => 'Unit Test Comment',
2568        ValidID => 1,
2569        TypeID  => 1,
2570        UserID  => 1,
2571    ) || die "StateAdd() error.";
2572
2573    push @States, {
2574        ID   => $StateID,
2575        Name => $StateName,
2576    };
2577
2578    # Create test types.
2579    my $TypeName = $Index . 'Type' . $RandomID;
2580    my $TypeID   = $TypeObject->TypeAdd(
2581        Name    => $TypeName,
2582        ValidID => 1,
2583        UserID  => 1,
2584    ) || die "TypeAdd() error.";
2585
2586    push @Types, {
2587        ID   => $TypeID,
2588        Name => $TypeName,
2589    };
2590}
2591
2592# Create test cases for different function outcome.
2593@Tests = (
2594    {
2595        QueueID    => $Queues[0]->{ID},
2596        PriorityID => $Priorities[0]->{ID},
2597        StateID    => $States[0]->{ID},
2598        ServiceID  => $Services[0]->{ID},
2599        SLAID      => $SLAs[2]->{ID},
2600        TypeID     => $Types[0]->{ID},
2601    },
2602    {
2603        QueueID    => $Queues[1]->{ID},
2604        PriorityID => $Priorities[2]->{ID},
2605        StateID    => $States[1]->{ID},
2606        ServiceID  => $Services[1]->{ID},
2607        SLAID      => $SLAs[2]->{ID},
2608        TypeID     => $Types[1]->{ID},
2609    },
2610    {
2611        QueueID    => $Queues[2]->{ID},
2612        PriorityID => $Priorities[2]->{ID},
2613        StateID    => $States[0]->{ID},
2614        ServiceID  => $Services[1]->{ID},
2615        SLAID      => $SLAs[2]->{ID},
2616        TypeID     => $Types[0]->{ID},
2617    },
2618    {
2619        QueueID    => $Queues[2]->{ID},
2620        PriorityID => $Priorities[0]->{ID},
2621        StateID    => $States[0]->{ID},
2622        ServiceID  => $Services[1]->{ID},
2623        SLAID      => $SLAs[2]->{ID},
2624        TypeID     => $Types[2]->{ID},
2625    },
2626    {
2627        QueueID    => $Queues[2]->{ID},
2628        PriorityID => $Priorities[2]->{ID},
2629        StateID    => $States[0]->{ID},
2630        ServiceID  => $Services[2]->{ID},
2631        SLAID      => $SLAs[2]->{ID},
2632        TypeID     => $Types[1]->{ID},
2633    },
2634    {
2635        QueueID    => $Queues[1]->{ID},
2636        PriorityID => $Priorities[0]->{ID},
2637        StateID    => $States[1]->{ID},
2638        ServiceID  => $Services[0]->{ID},
2639        SLAID      => $SLAs[2]->{ID},
2640        TypeID     => $Types[2]->{ID},
2641    },
2642    {
2643        QueueID    => $Queues[1]->{ID},
2644        PriorityID => $Priorities[0]->{ID},
2645        StateID    => $States[1]->{ID},
2646        ServiceID  => $Services[0]->{ID},
2647        SLAID      => $SLAs[2]->{ID},
2648        TypeID     => $Types[0]->{ID},
2649    },
2650    {
2651        QueueID    => $Queues[1]->{ID},
2652        PriorityID => $Priorities[2]->{ID},
2653        StateID    => $States[2]->{ID},
2654        ServiceID  => $Services[0]->{ID},
2655        SLAID      => $SLAs[2]->{ID},
2656        TypeID     => $Types[1]->{ID},
2657    },
2658    {
2659        QueueID    => $Queues[2]->{ID},
2660        PriorityID => $Priorities[2]->{ID},
2661        StateID    => $States[1]->{ID},
2662        ServiceID  => $Services[0]->{ID},
2663        SLAID      => $SLAs[2]->{ID},
2664        TypeID     => $Types[0]->{ID},
2665    },
2666    {
2667        QueueID    => $Queues[0]->{ID},
2668        PriorityID => $Priorities[2]->{ID},
2669        StateID    => $States[0]->{ID},
2670        ServiceID  => $Services[0]->{ID},
2671        SLAID      => $SLAs[2]->{ID},
2672        TypeID     => $Types[2]->{ID},
2673    },
2674);
2675
2676my %ExpectedResult;
2677undef @TicketIDs;
2678for my $Test (@Tests) {
2679    my $TicketID = $TicketObject->TicketCreate(
2680        %{$Test},
2681        Title        => 'Unit Test ticket',
2682        CustomerNo   => 'Unit Test customer',
2683        CustomerUser => 'unittest@otrs.com',
2684        Lock         => 'unlock',
2685        OwnerID      => 1,
2686        UserID       => 1,
2687    );
2688    push @TicketIDs, $TicketID;
2689
2690}
2691
2692# Create test expected outcome.
2693@Tests = (
2694    {
2695        Attribute     => 'Service',
2696        ExpectedCount => {
2697            $Services[0]->{Name} => 6,
2698            $Services[1]->{Name} => 3,
2699            $Services[2]->{Name} => 1,
2700        },
2701    },
2702    {
2703        Attribute     => 'ServiceID',
2704        ExpectedCount => {
2705            $Services[0]->{ID} => 6,
2706            $Services[1]->{ID} => 3,
2707            $Services[2]->{ID} => 1,
2708        },
2709    },
2710    {
2711        Attribute     => 'SLA',
2712        ExpectedCount => {
2713            $SLAs[2]->{Name} => 10,
2714        },
2715    },
2716    {
2717        Attribute     => 'SLAID',
2718        ExpectedCount => {
2719            $SLAs[2]->{ID} => 10,
2720        },
2721    },
2722    {
2723        Attribute     => 'Queue',
2724        ExpectedCount => {
2725            $Queues[0]->{Name} => 2,
2726            $Queues[1]->{Name} => 4,
2727            $Queues[2]->{Name} => 4,
2728        },
2729    },
2730    {
2731        Attribute     => 'QueueID',
2732        ExpectedCount => {
2733            $Queues[0]->{ID} => 2,
2734            $Queues[1]->{ID} => 4,
2735            $Queues[2]->{ID} => 4,
2736        },
2737    },
2738    {
2739        Attribute     => 'Priority',
2740        ExpectedCount => {
2741            $Priorities[0]->{Name} => 4,
2742            $Priorities[2]->{Name} => 6,
2743        },
2744    },
2745    {
2746        Attribute     => 'PriorityID',
2747        ExpectedCount => {
2748            $Priorities[0]->{ID} => 4,
2749            $Priorities[2]->{ID} => 6,
2750        },
2751    },
2752    {
2753        Attribute     => 'State',
2754        ExpectedCount => {
2755            $States[0]->{Name} => 5,
2756            $States[1]->{Name} => 4,
2757            $States[2]->{Name} => 1,
2758        },
2759    },
2760    {
2761        Attribute     => 'StateID',
2762        ExpectedCount => {
2763            $States[0]->{ID} => 5,
2764            $States[1]->{ID} => 4,
2765            $States[2]->{ID} => 1,
2766        },
2767    },
2768    {
2769        Attribute     => 'Type',
2770        ExpectedCount => {
2771            $Types[0]->{Name} => 4,
2772            $Types[1]->{Name} => 3,
2773            $Types[2]->{Name} => 3,
2774        },
2775    },
2776    {
2777        Attribute     => 'TypeID',
2778        ExpectedCount => {
2779            $Types[0]->{ID} => 4,
2780            $Types[1]->{ID} => 3,
2781            $Types[2]->{ID} => 3,
2782        },
2783    },
2784);
2785
2786# Check required params.
2787my $TicketCount = $TicketObject->TicketCountByAttribute(
2788    TicketIDs => \@TicketIDs,
2789);
2790$Self->False(
2791    $TicketCount,
2792    "TicketCountByAttribute() need Attribute param."
2793);
2794$TicketCount = $TicketObject->TicketCountByAttribute(
2795    Attribute => 'Service',
2796    TicketIDs => [],
2797);
2798$Self->True(
2799    !IsHashRefWithData($TicketCount),
2800    "TicketCountByAttribute() need TicketIDs array."
2801);
2802
2803# Run valid tests.
2804for my $Test (@Tests) {
2805    my $TicketCount = $TicketObject->TicketCountByAttribute(
2806        Attribute => $Test->{Attribute},
2807        TicketIDs => \@TicketIDs,
2808    );
2809    $Self->IsDeeply(
2810        $TicketCount,
2811        $Test->{ExpectedCount},
2812        "TicketCountByAttribute() for Attribute $Test->{Attribute} correct,"
2813    );
2814}
2815
2816# Test TicketCountByAttribute() function with more then 1000 entries.
2817@TicketIDs   = ( @TicketIDs, 100 .. 1100 );
2818$TicketCount = $TicketObject->TicketCountByAttribute(
2819    Attribute => 'Service',
2820    TicketIDs => \@TicketIDs,
2821);
2822$Self->True(
2823    IsHashRefWithData($TicketCount),
2824    "TicketCountByAttribute() for more then 1000 entries correct"
2825);
2826
28271;
2828