init III
This commit is contained in:
715
Perl OTRS/Kernel/System/State.pm
Normal file
715
Perl OTRS/Kernel/System/State.pm
Normal file
@@ -0,0 +1,715 @@
|
||||
# --
|
||||
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
|
||||
# --
|
||||
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
# the enclosed file COPYING for license information (GPL). If you
|
||||
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
|
||||
# --
|
||||
|
||||
package Kernel::System::State;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
our @ObjectDependencies = (
|
||||
'Kernel::Config',
|
||||
'Kernel::System::Cache',
|
||||
'Kernel::System::DB',
|
||||
'Kernel::System::Log',
|
||||
'Kernel::System::SysConfig',
|
||||
'Kernel::System::Valid',
|
||||
);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Kernel::System::State - state lib
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
All ticket state functions.
|
||||
|
||||
=head1 PUBLIC INTERFACE
|
||||
|
||||
=head2 new()
|
||||
|
||||
create an object
|
||||
|
||||
my $StateObject = $Kernel::OM->Get('Kernel::System::State');
|
||||
|
||||
=cut
|
||||
|
||||
sub new {
|
||||
my ( $Type, %Param ) = @_;
|
||||
|
||||
# allocate new hash for object
|
||||
my $Self = {};
|
||||
bless( $Self, $Type );
|
||||
|
||||
$Self->{CacheType} = 'State';
|
||||
$Self->{CacheTTL} = 60 * 60 * 24 * 20;
|
||||
|
||||
return $Self;
|
||||
}
|
||||
|
||||
=head2 StateAdd()
|
||||
|
||||
add new states
|
||||
|
||||
my $ID = $StateObject->StateAdd(
|
||||
Name => 'New State',
|
||||
Comment => 'some comment',
|
||||
ValidID => 1,
|
||||
TypeID => 1,
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub StateAdd {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for (qw(Name ValidID TypeID UserID)) {
|
||||
if ( !$Param{$_} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $_!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
# store data
|
||||
return if !$DBObject->Do(
|
||||
SQL => 'INSERT INTO ticket_state (name, valid_id, type_id, comments,'
|
||||
. ' create_time, create_by, change_time, change_by)'
|
||||
. ' VALUES (?, ?, ?, ?, current_timestamp, ?, current_timestamp, ?)',
|
||||
Bind => [
|
||||
\$Param{Name}, \$Param{ValidID}, \$Param{TypeID}, \$Param{Comment},
|
||||
\$Param{UserID}, \$Param{UserID},
|
||||
],
|
||||
);
|
||||
|
||||
# get new state id
|
||||
return if !$DBObject->Prepare(
|
||||
SQL => 'SELECT id FROM ticket_state WHERE name = ?',
|
||||
Bind => [ \$Param{Name} ],
|
||||
Limit => 1,
|
||||
);
|
||||
|
||||
# fetch the result
|
||||
my $ID;
|
||||
while ( my @Row = $DBObject->FetchrowArray() ) {
|
||||
$ID = $Row[0];
|
||||
}
|
||||
|
||||
return if !$ID;
|
||||
|
||||
# delete cache
|
||||
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
|
||||
Type => $Self->{CacheType},
|
||||
);
|
||||
|
||||
return $ID;
|
||||
}
|
||||
|
||||
=head2 StateGet()
|
||||
|
||||
get state attributes
|
||||
|
||||
my %State = $StateObject->StateGet(
|
||||
Name => 'New State',
|
||||
);
|
||||
|
||||
my %State = $StateObject->StateGet(
|
||||
ID => 123,
|
||||
);
|
||||
|
||||
returns
|
||||
|
||||
my %State = (
|
||||
Name => "new",
|
||||
ID => 1,
|
||||
TypeName => "new",
|
||||
TypeID => 1,
|
||||
ValidID => 1,
|
||||
CreateTime => "2010-11-29 11:04:04",
|
||||
ChangeTime => "2010-11-29 11:04:04",
|
||||
Comment => "New ticket created by customer.",
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub StateGet {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
if ( !$Param{ID} && !$Param{Name} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need ID or Name!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# check cache
|
||||
my $CacheKey;
|
||||
if ( $Param{Name} ) {
|
||||
$CacheKey = 'StateGet::Name::' . $Param{Name};
|
||||
}
|
||||
else {
|
||||
$CacheKey = 'StateGet::ID::' . $Param{ID};
|
||||
}
|
||||
my $Cache = $Kernel::OM->Get('Kernel::System::Cache')->Get(
|
||||
Type => $Self->{CacheType},
|
||||
Key => $CacheKey,
|
||||
);
|
||||
return %{$Cache} if $Cache;
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
# sql
|
||||
my @Bind;
|
||||
my $SQL = 'SELECT ts.id, ts.name, ts.valid_id, ts.comments, ts.type_id, tst.name,'
|
||||
. ' ts.change_time, ts.create_time'
|
||||
. ' FROM ticket_state ts, ticket_state_type tst WHERE ts.type_id = tst.id AND ';
|
||||
if ( $Param{Name} ) {
|
||||
$SQL .= ' ts.name = ?';
|
||||
push @Bind, \$Param{Name};
|
||||
}
|
||||
else {
|
||||
$SQL .= ' ts.id = ?';
|
||||
push @Bind, \$Param{ID};
|
||||
}
|
||||
|
||||
return if !$DBObject->Prepare(
|
||||
SQL => $SQL,
|
||||
Bind => \@Bind,
|
||||
Limit => 1,
|
||||
);
|
||||
|
||||
# fetch the result
|
||||
my %Data;
|
||||
while ( my @Data = $DBObject->FetchrowArray() ) {
|
||||
%Data = (
|
||||
ID => $Data[0],
|
||||
Name => $Data[1],
|
||||
Comment => $Data[3],
|
||||
ValidID => $Data[2],
|
||||
TypeID => $Data[4],
|
||||
TypeName => $Data[5],
|
||||
ChangeTime => $Data[6],
|
||||
CreateTime => $Data[7],
|
||||
);
|
||||
}
|
||||
|
||||
# set cache
|
||||
$Kernel::OM->Get('Kernel::System::Cache')->Set(
|
||||
Type => $Self->{CacheType},
|
||||
TTL => $Self->{CacheTTL},
|
||||
Key => $CacheKey,
|
||||
Value => \%Data,
|
||||
);
|
||||
|
||||
# no data found...
|
||||
if ( !%Data ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "State '$Param{Name}' not found!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
return %Data;
|
||||
}
|
||||
|
||||
=head2 StateUpdate()
|
||||
|
||||
update state attributes
|
||||
|
||||
$StateObject->StateUpdate(
|
||||
ID => 123,
|
||||
Name => 'New State',
|
||||
Comment => 'some comment',
|
||||
ValidID => 1,
|
||||
TypeID => 1,
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub StateUpdate {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
for (qw(ID Name ValidID TypeID UserID)) {
|
||||
if ( !$Param{$_} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Need $_!"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
# sql
|
||||
return if !$DBObject->Do(
|
||||
SQL => 'UPDATE ticket_state SET name = ?, comments = ?, type_id = ?, '
|
||||
. ' valid_id = ?, change_time = current_timestamp, change_by = ? '
|
||||
. ' WHERE id = ?',
|
||||
Bind => [
|
||||
\$Param{Name}, \$Param{Comment}, \$Param{TypeID}, \$Param{ValidID},
|
||||
\$Param{UserID}, \$Param{ID},
|
||||
],
|
||||
);
|
||||
|
||||
# delete cache
|
||||
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
|
||||
Type => $Self->{CacheType},
|
||||
);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 StateGetStatesByType()
|
||||
|
||||
get list of states for a type or a list of state types.
|
||||
|
||||
Get all states with state type open and new:
|
||||
(available: new, open, closed, pending reminder, pending auto, removed, merged)
|
||||
|
||||
my @List = $StateObject->StateGetStatesByType(
|
||||
StateType => ['open', 'new'],
|
||||
Result => 'ID', # HASH|ID|Name
|
||||
);
|
||||
|
||||
Get all state types used by config option named like
|
||||
Ticket::ViewableStateType for "Viewable" state types.
|
||||
|
||||
my %List = $StateObject->StateGetStatesByType(
|
||||
Type => 'Viewable',
|
||||
Result => 'HASH', # HASH|ID|Name
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub StateGetStatesByType {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
if ( !$Param{Result} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => 'Need Result!'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !$Param{Type} && !$Param{StateType} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => 'Need Type or StateType!'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# cache key
|
||||
my $CacheKey = 'StateGetStatesByType::';
|
||||
if ( $Param{Type} ) {
|
||||
$CacheKey .= 'Type::' . $Param{Type};
|
||||
}
|
||||
if ( $Param{StateType} ) {
|
||||
|
||||
my @StateType;
|
||||
if ( ref $Param{StateType} eq 'ARRAY' ) {
|
||||
@StateType = @{ $Param{StateType} };
|
||||
}
|
||||
else {
|
||||
push @StateType, $Param{StateType};
|
||||
}
|
||||
$CacheKey .= 'StateType::' . join ':', sort @StateType;
|
||||
}
|
||||
|
||||
# check cache
|
||||
my $Cache = $Kernel::OM->Get('Kernel::System::Cache')->Get(
|
||||
Type => $Self->{CacheType},
|
||||
Key => $CacheKey,
|
||||
);
|
||||
if ($Cache) {
|
||||
if ( $Param{Result} eq 'Name' ) {
|
||||
return @{ $Cache->{Name} };
|
||||
}
|
||||
elsif ( $Param{Result} eq 'HASH' ) {
|
||||
return %{ $Cache->{HASH} };
|
||||
}
|
||||
return @{ $Cache->{ID} };
|
||||
}
|
||||
|
||||
# sql
|
||||
my @StateType;
|
||||
my @Name;
|
||||
my @ID;
|
||||
my %Data;
|
||||
if ( $Param{Type} ) {
|
||||
|
||||
# get config object
|
||||
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
||||
|
||||
if ( $ConfigObject->Get( 'Ticket::' . $Param{Type} . 'StateType' ) ) {
|
||||
@StateType = @{ $ConfigObject->Get( 'Ticket::' . $Param{Type} . 'StateType' ) };
|
||||
}
|
||||
else {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "Type 'Ticket::$Param{Type}StateType' not found in Kernel/Config.pm!",
|
||||
);
|
||||
die;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( ref $Param{StateType} eq 'ARRAY' ) {
|
||||
@StateType = @{ $Param{StateType} };
|
||||
}
|
||||
else {
|
||||
push @StateType, $Param{StateType};
|
||||
}
|
||||
}
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
@StateType = map { $DBObject->Quote($_) } @StateType;
|
||||
|
||||
my $SQL = ''
|
||||
. 'SELECT ts.id, ts.name, tst.name'
|
||||
. ' FROM ticket_state ts, ticket_state_type tst'
|
||||
. ' WHERE tst.id = ts.type_id'
|
||||
. " AND tst.name IN ('${\(join '\', \'', sort @StateType)}' )"
|
||||
. " AND ts.valid_id IN ( ${\(join ', ', $Kernel::OM->Get('Kernel::System::Valid')->ValidIDsGet())} )";
|
||||
|
||||
return if !$DBObject->Prepare( SQL => $SQL );
|
||||
|
||||
# fetch the result
|
||||
while ( my @Data = $DBObject->FetchrowArray() ) {
|
||||
push @Name, $Data[1];
|
||||
push @ID, $Data[0];
|
||||
$Data{ $Data[0] } = $Data[1];
|
||||
}
|
||||
|
||||
# set runtime cache
|
||||
my $All = {
|
||||
Name => \@Name,
|
||||
ID => \@ID,
|
||||
HASH => \%Data,
|
||||
};
|
||||
|
||||
# set permanent cache
|
||||
$Kernel::OM->Get('Kernel::System::Cache')->Set(
|
||||
Type => $Self->{CacheType},
|
||||
TTL => $Self->{CacheTTL},
|
||||
Key => $CacheKey,
|
||||
Value => $All,
|
||||
);
|
||||
|
||||
if ( $Param{Result} eq 'Name' ) {
|
||||
return @Name;
|
||||
}
|
||||
elsif ( $Param{Result} eq 'HASH' ) {
|
||||
return %Data;
|
||||
}
|
||||
|
||||
return @ID;
|
||||
}
|
||||
|
||||
=head2 StateList()
|
||||
|
||||
get state list as a hash of ID, Name pairs
|
||||
|
||||
my %List = $StateObject->StateList(
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
my %List = $StateObject->StateList(
|
||||
UserID => 123,
|
||||
Valid => 1, # is default
|
||||
);
|
||||
|
||||
my %List = $StateObject->StateList(
|
||||
UserID => 123,
|
||||
Valid => 0,
|
||||
);
|
||||
|
||||
returns
|
||||
|
||||
my %List = (
|
||||
1 => "new",
|
||||
2 => "closed successful",
|
||||
3 => "closed unsuccessful",
|
||||
4 => "open",
|
||||
5 => "removed",
|
||||
6 => "pending reminder",
|
||||
7 => "pending auto close+",
|
||||
8 => "pending auto close-",
|
||||
9 => "merged",
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub StateList {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
if ( !$Param{UserID} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => 'UserID!'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
my $Valid = 1;
|
||||
if ( !$Param{Valid} && defined( $Param{Valid} ) ) {
|
||||
$Valid = 0;
|
||||
}
|
||||
|
||||
# check cache
|
||||
my $CacheKey = 'StateList::' . $Valid;
|
||||
my $Cache = $Kernel::OM->Get('Kernel::System::Cache')->Get(
|
||||
Type => $Self->{CacheType},
|
||||
Key => $CacheKey,
|
||||
);
|
||||
return %{$Cache} if $Cache;
|
||||
|
||||
# sql
|
||||
my $SQL = 'SELECT id, name FROM ticket_state';
|
||||
if ($Valid) {
|
||||
$SQL
|
||||
.= " WHERE valid_id IN ( ${\(join ', ', $Kernel::OM->Get('Kernel::System::Valid')->ValidIDsGet())} )";
|
||||
}
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
return if !$DBObject->Prepare( SQL => $SQL );
|
||||
|
||||
# fetch the result
|
||||
my %Data;
|
||||
while ( my @Row = $DBObject->FetchrowArray() ) {
|
||||
$Data{ $Row[0] } = $Row[1];
|
||||
}
|
||||
|
||||
# set cache
|
||||
$Kernel::OM->Get('Kernel::System::Cache')->Set(
|
||||
Type => $Self->{CacheType},
|
||||
TTL => $Self->{CacheTTL},
|
||||
Key => $CacheKey,
|
||||
Value => \%Data,
|
||||
);
|
||||
|
||||
return %Data;
|
||||
}
|
||||
|
||||
=head2 StateLookup()
|
||||
|
||||
returns the id or the name of a state
|
||||
|
||||
my $StateID = $StateObject->StateLookup(
|
||||
State => 'closed successful',
|
||||
);
|
||||
|
||||
my $State = $StateObject->StateLookup(
|
||||
StateID => 2,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub StateLookup {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
if ( !$Param{State} && !$Param{StateID} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => 'Need State or StateID!'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# get (already cached) state list
|
||||
my %StateList = $Self->StateList(
|
||||
Valid => 0,
|
||||
UserID => 1,
|
||||
);
|
||||
|
||||
my $Key;
|
||||
my $Value;
|
||||
my $ReturnData;
|
||||
if ( $Param{StateID} ) {
|
||||
$Key = 'StateID';
|
||||
$Value = $Param{StateID};
|
||||
$ReturnData = $StateList{ $Param{StateID} };
|
||||
}
|
||||
else {
|
||||
$Key = 'State';
|
||||
$Value = $Param{State};
|
||||
my %StateListReverse = reverse %StateList;
|
||||
$ReturnData = $StateListReverse{ $Param{State} };
|
||||
}
|
||||
|
||||
# check if data exists
|
||||
if ( !defined $ReturnData ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "No $Key for $Value found!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
return $ReturnData;
|
||||
}
|
||||
|
||||
=head2 StateTypeList()
|
||||
|
||||
get state type list as a hash of ID, Name pairs
|
||||
|
||||
my %ListType = $StateObject->StateTypeList(
|
||||
UserID => 123,
|
||||
);
|
||||
|
||||
returns
|
||||
|
||||
my %ListType = (
|
||||
1 => "new",
|
||||
2 => "open",
|
||||
3 => "closed",
|
||||
4 => "pending reminder",
|
||||
5 => "pending auto",
|
||||
6 => "removed",
|
||||
7 => "merged",
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub StateTypeList {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
if ( !$Param{UserID} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => 'UserID!'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# check cache
|
||||
my $CacheKey = 'StateTypeList';
|
||||
my $Cache = $Kernel::OM->Get('Kernel::System::Cache')->Get(
|
||||
Type => $Self->{CacheType},
|
||||
Key => $CacheKey,
|
||||
);
|
||||
return %{$Cache} if $Cache;
|
||||
|
||||
# get database object
|
||||
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
||||
|
||||
# sql
|
||||
return if !$DBObject->Prepare(
|
||||
SQL => 'SELECT id, name FROM ticket_state_type',
|
||||
);
|
||||
|
||||
# fetch the result
|
||||
my %Data;
|
||||
while ( my @Row = $DBObject->FetchrowArray() ) {
|
||||
$Data{ $Row[0] } = $Row[1];
|
||||
}
|
||||
|
||||
# set cache
|
||||
$Kernel::OM->Get('Kernel::System::Cache')->Set(
|
||||
Type => $Self->{CacheType},
|
||||
TTL => $Self->{CacheTTL},
|
||||
Key => $CacheKey,
|
||||
Value => \%Data,
|
||||
);
|
||||
|
||||
return %Data;
|
||||
}
|
||||
|
||||
=head2 StateTypeLookup()
|
||||
|
||||
returns the id or the name of a state type
|
||||
|
||||
my $StateTypeID = $StateObject->StateTypeLookup(
|
||||
StateType => 'pending auto',
|
||||
);
|
||||
|
||||
or
|
||||
|
||||
my $StateType = $StateObject->StateTypeLookup(
|
||||
StateTypeID => 1,
|
||||
);
|
||||
|
||||
=cut
|
||||
|
||||
sub StateTypeLookup {
|
||||
my ( $Self, %Param ) = @_;
|
||||
|
||||
# check needed stuff
|
||||
if ( !$Param{StateType} && !$Param{StateTypeID} ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
StateType => 'error',
|
||||
Message => 'Need StateType or StateTypeID!',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
# get (already cached) state type list
|
||||
my %StateTypeList = $Self->StateTypeList(
|
||||
UserID => 1,
|
||||
);
|
||||
|
||||
my $Key;
|
||||
my $Value;
|
||||
my $ReturnData;
|
||||
if ( $Param{StateTypeID} ) {
|
||||
$Key = 'StateTypeID';
|
||||
$Value = $Param{StateTypeID};
|
||||
$ReturnData = $StateTypeList{ $Param{StateTypeID} };
|
||||
}
|
||||
else {
|
||||
$Key = 'StateType';
|
||||
$Value = $Param{StateType};
|
||||
my %StateTypeListReverse = reverse %StateTypeList;
|
||||
$ReturnData = $StateTypeListReverse{ $Param{StateType} };
|
||||
}
|
||||
|
||||
# check if data exists
|
||||
if ( !defined $ReturnData ) {
|
||||
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
||||
Priority => 'error',
|
||||
Message => "No $Key for $Value found!",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
return $ReturnData;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
=head1 TERMS AND CONDITIONS
|
||||
|
||||
This software is part of the OTRS project (L<https://otrs.org/>).
|
||||
|
||||
This software comes with ABSOLUTELY NO WARRANTY. For details, see
|
||||
the enclosed file COPYING for license information (GPL). If you
|
||||
did not receive this file, see L<https://www.gnu.org/licenses/gpl-3.0.txt>.
|
||||
|
||||
=cut
|
||||
Reference in New Issue
Block a user