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