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::System::ProcessManagement::DB::TransitionAction;
10
11use strict;
12use warnings;
13
14use Kernel::System::VariableCheck qw(:all);
15
16our @ObjectDependencies = (
17    'Kernel::Config',
18    'Kernel::System::Cache',
19    'Kernel::System::DB',
20    'Kernel::System::Log',
21    'Kernel::System::YAML',
22);
23
24=head1 NAME
25
26Kernel::System::ProcessManagement::DB::TransitionAction
27
28=head1 DESCRIPTION
29
30Process Management DB TransitionAction backend
31
32=head1 PUBLIC INTERFACE
33
34=head2 new()
35
36Don't use the constructor directly, use the ObjectManager instead:
37
38    my $TransitionActionObject = $Kernel::OM->Get('Kernel::System::ProcessManagement::DB::TransitionAction');
39
40=cut
41
42sub new {
43    my ( $Type, %Param ) = @_;
44
45    # allocate new hash for object
46    my $Self = {};
47    bless( $Self, $Type );
48
49    # get the cache TTL (in seconds)
50    $Self->{CacheTTL} = int( $Kernel::OM->Get('Kernel::Config')->Get('Process::CacheTTL') || 3600 );
51
52    # set lower if database is case sensitive
53    $Self->{Lower} = '';
54    if ( $Kernel::OM->Get('Kernel::System::DB')->GetDatabaseFunction('CaseSensitive') ) {
55        $Self->{Lower} = 'LOWER';
56    }
57
58    return $Self;
59}
60
61=head2 TransitionActionAdd()
62
63add new TransitionAction
64
65returns the id of the created TransitionAction if success or undef otherwise
66
67    my $ID = $TransitionActionObject->TransitionActionAdd(
68        EntityID    => 'TA1'                     # mandatory, exportable unique identifier
69        Name        => 'NameOfTransitionAction', # mandatory
70        Config      => $ConfigHashRef,           # mandatory, transition action configuration to be
71                                                 #    stored in YAML format
72        UserID      => 123,                      # mandatory
73    );
74
75Returns:
76
77    $ID = 567;
78
79=cut
80
81sub TransitionActionAdd {
82    my ( $Self, %Param ) = @_;
83
84    # check needed stuff
85    for my $Key (qw(EntityID Name Config UserID)) {
86        if ( !$Param{$Key} ) {
87            $Kernel::OM->Get('Kernel::System::Log')->Log(
88                Priority => 'error',
89                Message  => "Need $Key!",
90            );
91            return;
92        }
93    }
94
95    # get database object
96    my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
97
98    # check if EntityID already exists
99    return if !$DBObject->Prepare(
100        SQL => "
101            SELECT id
102            FROM pm_transition_action
103            WHERE $Self->{Lower}(entity_id) = $Self->{Lower}(?)",
104        Bind  => [ \$Param{EntityID} ],
105        Limit => 1,
106    );
107
108    my $EntityExists;
109    while ( my @Data = $DBObject->FetchrowArray() ) {
110        $EntityExists = 1;
111    }
112
113    if ($EntityExists) {
114        $Kernel::OM->Get('Kernel::System::Log')->Log(
115            Priority => 'error',
116            Message  => "The EntityID:$Param{EntityID} already exists for a transition action!"
117        );
118        return;
119    }
120
121    # check config valid format (at least it must contain another config hash inside)
122    if ( !IsHashRefWithData( $Param{Config} ) ) {
123        $Kernel::OM->Get('Kernel::System::Log')->Log(
124            Priority => 'error',
125            Message  => "Config needs to be a valid Hash reference!",
126        );
127        return;
128    }
129    for my $Needed (qw(Module Config)) {
130        if ( !$Param{Config}->{$Needed} ) {
131            $Kernel::OM->Get('Kernel::System::Log')->Log(
132                Priority => 'error',
133                Message  => "Need $Needed in Config!",
134            );
135            return;
136        }
137    }
138
139    # check config formats
140    if ( !IsStringWithData( $Param{Config}->{Module} ) ) {
141        $Kernel::OM->Get('Kernel::System::Log')->Log(
142            Priority => 'error',
143            Message  => "Config Module must be a non empty String!",
144        );
145        return;
146    }
147    if ( ref $Param{Config}->{Config} ne 'HASH' ) {
148        $Kernel::OM->Get('Kernel::System::Log')->Log(
149            Priority => 'error',
150            Message  => "Config Config must be a Hash!",
151        );
152        return;
153    }
154
155    # dump layout and config as string
156    my $Config = $Kernel::OM->Get('Kernel::System::YAML')->Dump( Data => $Param{Config} );
157
158    # Make sure the resulting string has the UTF-8 flag. YAML only sets it if
159    #   part of the data already had it.
160    utf8::upgrade($Config);
161
162    # sql
163    return if !$DBObject->Do(
164        SQL => '
165            INSERT INTO pm_transition_action ( entity_id, name, config, create_time,
166                create_by, change_time, change_by )
167            VALUES (?, ?, ?, current_timestamp, ?, current_timestamp, ?)',
168        Bind => [
169            \$Param{EntityID}, \$Param{Name}, \$Config, \$Param{UserID}, \$Param{UserID},
170        ],
171    );
172
173    return if !$DBObject->Prepare(
174        SQL  => 'SELECT id FROM pm_transition_action WHERE entity_id = ?',
175        Bind => [ \$Param{EntityID} ],
176    );
177
178    my $ID;
179    while ( my @Row = $DBObject->FetchrowArray() ) {
180        $ID = $Row[0];
181    }
182
183    # delete cache
184    $Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
185        Type => 'ProcessManagement_TransitionAction',
186    );
187
188    return if !$ID;
189
190    return $ID;
191}
192
193=head2 TransitionActionDelete()
194
195delete an TransitionAction
196
197returns 1 if success or undef otherwise
198
199    my $Success = $TransitionActionObject->TransitionActionDelete(
200        ID      => 123,
201        UserID  => 123,
202    );
203
204=cut
205
206sub TransitionActionDelete {
207    my ( $Self, %Param ) = @_;
208
209    # check needed stuff
210    for my $Key (qw(ID UserID)) {
211        if ( !$Param{$Key} ) {
212            $Kernel::OM->Get('Kernel::System::Log')->Log(
213                Priority => 'error',
214                Message  => "Need $Key!"
215            );
216            return;
217        }
218    }
219
220    # check if exists
221    my $TransitionAction = $Self->TransitionActionGet(
222        ID     => $Param{ID},
223        UserID => 1,
224    );
225    return if !IsHashRefWithData($TransitionAction);
226
227    # delete transition action
228    return if !$Kernel::OM->Get('Kernel::System::DB')->Do(
229        SQL  => 'DELETE FROM pm_transition_action WHERE id = ?',
230        Bind => [ \$Param{ID} ],
231    );
232
233    # delete cache
234    $Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
235        Type => 'ProcessManagement_TransitionAction',
236    );
237
238    return 1;
239}
240
241=head2 TransitionActionGet()
242
243get TransitionAction attributes
244
245    my $TransitionAction = $TransitionActionObject->TransitionActionGet(
246        ID            => 123,            # ID or EntityID is needed
247        EntityID      => 'P1',
248        UserID        => 123,            # mandatory
249    );
250
251Returns:
252
253    $TransitionAction = {
254        ID           => 123,
255        EntityID     => 'TA1',
256        Name         => 'some name',
257        Config       => $ConfigHashRef,
258        CreateTime   => '2012-07-04 15:08:00',
259        ChangeTime   => '2012-07-04 15:08:00',
260    };
261
262=cut
263
264sub TransitionActionGet {
265    my ( $Self, %Param ) = @_;
266
267    # check needed stuff
268    if ( !$Param{ID} && !$Param{EntityID} ) {
269        $Kernel::OM->Get('Kernel::System::Log')->Log(
270            Priority => 'error',
271            Message  => 'Need ID or EntityID!'
272        );
273        return;
274    }
275
276    if ( !$Param{UserID} ) {
277        $Kernel::OM->Get('Kernel::System::Log')->Log(
278            Priority => 'error',
279            Message  => 'Need UserID!',
280        );
281        return;
282    }
283
284    # get cache object
285    my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
286
287    # check cache
288    my $CacheKey;
289    if ( $Param{ID} ) {
290        $CacheKey = 'TransitionActionGet::ID::' . $Param{ID};
291    }
292    else {
293        $CacheKey = 'TransitionActionGet::EntityID::' . $Param{EntityID};
294    }
295
296    my $Cache = $CacheObject->Get(
297        Type => 'ProcessManagement_TransitionAction',
298        Key  => $CacheKey,
299    );
300    return $Cache if $Cache;
301
302    # get database object
303    my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
304
305    # sql
306    if ( $Param{ID} ) {
307        return if !$DBObject->Prepare(
308            SQL => '
309                SELECT id, entity_id, name, config, create_time, change_time
310                FROM pm_transition_action
311                WHERE id = ?',
312            Bind  => [ \$Param{ID} ],
313            Limit => 1,
314        );
315    }
316    else {
317        return if !$DBObject->Prepare(
318            SQL => '
319                SELECT id, entity_id, name, config, create_time, change_time
320                FROM pm_transition_action
321                WHERE entity_id = ?',
322            Bind  => [ \$Param{EntityID} ],
323            Limit => 1,
324        );
325    }
326
327    # get yaml object
328    my $YAMLObject = $Kernel::OM->Get('Kernel::System::YAML');
329
330    my %Data;
331    while ( my @Data = $DBObject->FetchrowArray() ) {
332
333        my $Config = $YAMLObject->Load( Data => $Data[3] );
334
335        %Data = (
336            ID         => $Data[0],
337            EntityID   => $Data[1],
338            Name       => $Data[2],
339            Config     => $Config,
340            CreateTime => $Data[4],
341            ChangeTime => $Data[5],
342
343        );
344    }
345
346    return if !$Data{ID};
347
348    # set cache
349    $CacheObject->Set(
350        Type  => 'ProcessManagement_TransitionAction',
351        Key   => $CacheKey,
352        Value => \%Data,
353        TTL   => $Self->{CacheTTL},
354    );
355
356    return \%Data;
357}
358
359=head2 TransitionActionUpdate()
360
361update TransitionAction attributes
362
363returns 1 if success or undef otherwise
364
365    my $Success = $TransitionActionObject->TransitionActionUpdate(
366        ID          => 123,                      # mandatory
367        EntityID    => 'TA1'                     # mandatory, exportable unique identifier
368        Name        => 'NameOfTransitionAction', # mandatory
369        Config      => $ConfigHashRef,           # mandatory, actvity dialog configuration to be
370                                                 #   stored in YAML format
371        UserID      => 123,                      # mandatory
372    );
373
374=cut
375
376sub TransitionActionUpdate {
377    my ( $Self, %Param ) = @_;
378
379    # check needed stuff
380    for my $Key (qw(ID EntityID Name Config UserID)) {
381        if ( !$Param{$Key} ) {
382            $Kernel::OM->Get('Kernel::System::Log')->Log(
383                Priority => 'error',
384                Message  => "Need $Key!"
385            );
386            return;
387        }
388    }
389
390    # get database object
391    my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
392
393    # check if EntityID already exists
394    return if !$DBObject->Prepare(
395        SQL => "
396            SELECT id FROM pm_transition_action
397            WHERE $Self->{Lower}(entity_id) = $Self->{Lower}(?)
398            AND id != ?",
399        Bind  => [ \$Param{EntityID}, \$Param{ID} ],
400        LIMIT => 1,
401    );
402
403    my $EntityExists;
404    while ( my @Data = $DBObject->FetchrowArray() ) {
405        $EntityExists = 1;
406    }
407
408    if ($EntityExists) {
409        $Kernel::OM->Get('Kernel::System::Log')->Log(
410            Priority => 'error',
411            Message  => "The EntityID:$Param{Name} already exists for a TransitionAction!",
412        );
413        return;
414    }
415
416    # check config valid format (at least it must contain another config hash)
417    if ( !IsHashRefWithData( $Param{Config} ) ) {
418        $Kernel::OM->Get('Kernel::System::Log')->Log(
419            Priority => 'error',
420            Message  => "Config needs to be a valid Hash reference!",
421        );
422        return;
423    }
424    for my $Needed (qw(Module Config)) {
425        if ( !$Param{Config}->{$Needed} ) {
426            $Kernel::OM->Get('Kernel::System::Log')->Log(
427                Priority => 'error',
428                Message  => "Need $Needed in Config!",
429            );
430            return;
431        }
432    }
433
434    # check config formats
435    if ( !IsStringWithData( $Param{Config}->{Module} ) ) {
436        $Kernel::OM->Get('Kernel::System::Log')->Log(
437            Priority => 'error',
438            Message  => "Config->Config must be a non empty string!",
439        );
440        return;
441    }
442    if ( ref $Param{Config}->{Config} ne 'HASH' ) {
443        $Kernel::OM->Get('Kernel::System::Log')->Log(
444            Priority => 'error',
445            Message  => "Config->Config must be a Hash!",
446        );
447        return;
448    }
449
450    # dump layout and config as string
451    my $Config = $Kernel::OM->Get('Kernel::System::YAML')->Dump( Data => $Param{Config} );
452
453    # Make sure the resulting string has the UTF-8 flag. YAML only sets it if
454    #   part of the data already had it.
455    utf8::upgrade($Config);
456
457    # check if need to update db
458    return if !$DBObject->Prepare(
459        SQL => '
460            SELECT entity_id, name, config
461            FROM pm_transition_action
462            WHERE id = ?',
463        Bind  => [ \$Param{ID} ],
464        Limit => 1,
465    );
466
467    my $CurrentEntityID;
468    my $CurrentName;
469    my $CurrentConfig;
470    while ( my @Data = $DBObject->FetchrowArray() ) {
471        $CurrentEntityID = $Data[0];
472        $CurrentName     = $Data[1];
473        $CurrentConfig   = $Data[2];
474    }
475
476    if ($CurrentEntityID) {
477
478        return 1 if $CurrentEntityID eq $Param{EntityID}
479            && $CurrentName eq $Param{Name}
480            && $CurrentConfig eq $Config;
481    }
482
483    # sql
484    return if !$DBObject->Do(
485        SQL => '
486            UPDATE pm_transition_action
487            SET entity_id = ?, name = ?,  config = ?, change_time = current_timestamp,
488                change_by = ?
489            WHERE id = ?',
490        Bind => [
491            \$Param{EntityID}, \$Param{Name}, \$Config, \$Param{UserID}, \$Param{ID},
492        ],
493    );
494
495    # delete cache
496    $Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
497        Type => 'ProcessManagement_TransitionAction',
498    );
499
500    return 1;
501}
502
503=head2 TransitionActionList()
504
505get an TransitionAction list
506
507    my $List = $TransitionActionObject->TransitionActionList(
508        UseEntities => 0,                       # default 0, 1 || 0. if 0 the return hash keys are
509                                                #    the transition action IDs otherwise keys are
510                                                #    the transition action entity IDs
511        UserID      => 1,
512    );
513
514    Returns:
515
516    $List = {
517        1 => 'NameOfTransitionAction',
518    }
519
520    or
521
522    $List = {
523        'AD1' => 'NameOfTransitionAction',
524    }
525
526=cut
527
528sub TransitionActionList {
529    my ( $Self, %Param ) = @_;
530
531    # check needed
532    if ( !$Param{UserID} ) {
533        $Kernel::OM->Get('Kernel::System::Log')->Log(
534            Priority => 'error',
535            Message  => "Need UserID!"
536        );
537        return;
538    }
539
540    # check cache
541    my $UseEntities = 0;
542    if ( defined $Param{UseEntities} && $Param{UseEntities} ) {
543        $UseEntities = 1;
544    }
545
546    # get cache object
547    my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
548
549    my $CacheKey = 'TransitionActionList::UseEntities::' . $UseEntities;
550    my $Cache    = $CacheObject->Get(
551        Type => 'ProcessManagement_TransitionAction',
552        Key  => $CacheKey,
553    );
554    return $Cache if ref $Cache;
555
556    # get database object
557    my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
558
559    my $SQL = '
560            SELECT id, entity_id, name
561            FROM pm_transition_action';
562
563    return if !$DBObject->Prepare( SQL => $SQL );
564
565    my %Data;
566    while ( my @Row = $DBObject->FetchrowArray() ) {
567        if ( !$UseEntities ) {
568            $Data{ $Row[0] } = $Row[2];
569        }
570        else {
571            $Data{ $Row[1] } = $Row[2];
572        }
573    }
574
575    # set cache
576    $CacheObject->Set(
577        Type  => 'ProcessManagement_TransitionAction',
578        Key   => $CacheKey,
579        Value => \%Data,
580        TTL   => $Self->{CacheTTL},
581    );
582
583    return \%Data;
584}
585
586=head2 TransitionActionListGet()
587
588get an Transition Action list with all Transition Action details
589
590    my $List = $TransitionActionObject->TransitionActionListGet(
591        UserID      => 1,
592    );
593
594Returns:
595
596    $List = [
597        {
598            ID             => 123,
599            EntityID       => 'TA1',
600            Name           => 'some name',
601            Config         => $ConfigHashRef,
602            CreateTime     => '2012-07-04 15:08:00',
603            ChangeTime     => '2012-07-04 15:08:00',
604        }
605        {
606            ID             => 456,
607            EntityID       => 'TA2',
608            Name           => 'some name',
609            Config         => $ConfigHashRef,
610            CreateTime     => '2012-07-04 15:09:00',
611            ChangeTime     => '2012-07-04 15:09:00',
612        }
613    ];
614
615=cut
616
617sub TransitionActionListGet {
618    my ( $Self, %Param ) = @_;
619
620    # check needed stuff
621    if ( !$Param{UserID} ) {
622        $Kernel::OM->Get('Kernel::System::Log')->Log(
623            Priority => 'error',
624            Message  => 'Need UserID!',
625        );
626        return;
627    }
628
629    # get cache object
630    my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
631
632    # check cache
633    my $CacheKey = 'TransitionActionListGet';
634
635    my $Cache = $CacheObject->Get(
636        Type => 'ProcessManagement_TransitionAction',
637        Key  => $CacheKey,
638    );
639    return $Cache if $Cache;
640
641    # get database object
642    my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
643
644    # sql
645    return if !$DBObject->Prepare(
646        SQL => '
647            SELECT id, entity_id
648            FROM pm_transition_action
649            ORDER BY id',
650    );
651
652    my @TransitionActionIDs;
653    while ( my @Row = $DBObject->FetchrowArray() ) {
654        push @TransitionActionIDs, $Row[0];
655    }
656
657    my @Data;
658    for my $ItemID (@TransitionActionIDs) {
659
660        my $TransitionActionData = $Self->TransitionActionGet(
661            ID     => $ItemID,
662            UserID => 1,
663        );
664        push @Data, $TransitionActionData;
665    }
666
667    # set cache
668    $CacheObject->Set(
669        Type  => 'ProcessManagement_TransitionAction',
670        Key   => $CacheKey,
671        Value => \@Data,
672        TTL   => $Self->{CacheTTL},
673    );
674
675    return \@Data;
676}
677
6781;
679
680=head1 TERMS AND CONDITIONS
681
682This software is part of the OTRS project (L<https://otrs.org/>).
683
684This software comes with ABSOLUTELY NO WARRANTY. For details, see
685the enclosed file COPYING for license information (GPL). If you
686did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>.
687
688=cut
689