1554 lines
50 KiB
Perl
1554 lines
50 KiB
Perl
# --
|
|
# 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::GenericAgent;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use Time::HiRes qw(usleep);
|
|
|
|
use Kernel::System::VariableCheck qw(:all);
|
|
|
|
our @ObjectDependencies = (
|
|
'Kernel::Config',
|
|
'Kernel::System::Cache',
|
|
'Kernel::System::DateTime',
|
|
'Kernel::System::DB',
|
|
'Kernel::System::DynamicField',
|
|
'Kernel::System::DynamicField::Backend',
|
|
'Kernel::System::Log',
|
|
'Kernel::System::Main',
|
|
'Kernel::System::Queue',
|
|
'Kernel::System::State',
|
|
'Kernel::System::Ticket',
|
|
'Kernel::System::Ticket::Article',
|
|
'Kernel::System::TemplateGenerator',
|
|
'Kernel::System::CustomerUser',
|
|
);
|
|
|
|
=head1 NAME
|
|
|
|
Kernel::System::GenericAgent - to manage the generic agent jobs
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
All functions to manage the generic agent and the generic agent jobs.
|
|
|
|
=head1 PUBLIC INTERFACE
|
|
|
|
=head2 new()
|
|
|
|
Don't use the constructor directly, use the ObjectManager instead:
|
|
|
|
my $GenericAgentObject = $Kernel::OM->Get('Kernel::System::GenericAgent');
|
|
|
|
=cut
|
|
|
|
sub new {
|
|
my ( $Type, %Param ) = @_;
|
|
|
|
# allocate new hash for object
|
|
my $Self = {};
|
|
bless( $Self, $Type );
|
|
|
|
# get dynamic field objects
|
|
my $DynamicFieldObject = $Kernel::OM->Get('Kernel::System::DynamicField');
|
|
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
|
|
|
|
# get the dynamic fields for ticket object
|
|
$Self->{DynamicField} = $DynamicFieldObject->DynamicFieldListGet(
|
|
Valid => 1,
|
|
ObjectType => ['Ticket'],
|
|
);
|
|
|
|
# debug
|
|
$Self->{Debug} = $Param{Debug} || 0;
|
|
|
|
# notice on STDOUT
|
|
$Self->{NoticeSTDOUT} = $Param{NoticeSTDOUT} || 0;
|
|
|
|
my %Map = (
|
|
TicketNumber => 'SCALAR',
|
|
Title => 'SCALAR',
|
|
MIMEBase_From => 'SCALAR',
|
|
MIMEBase_To => 'SCALAR',
|
|
MIMEBase_Cc => 'SCALAR',
|
|
MIMEBase_Subject => 'SCALAR',
|
|
MIMEBase_Body => 'SCALAR',
|
|
TimeUnit => 'SCALAR',
|
|
CustomerID => 'SCALAR',
|
|
CustomerUserLogin => 'SCALAR',
|
|
Agent => 'SCALAR',
|
|
StateIDs => 'ARRAY',
|
|
StateTypeIDs => 'ARRAY',
|
|
QueueIDs => 'ARRAY',
|
|
PriorityIDs => 'ARRAY',
|
|
OwnerIDs => 'ARRAY',
|
|
LockIDs => 'ARRAY',
|
|
TypeIDs => 'ARRAY',
|
|
ResponsibleIDs => 'ARRAY',
|
|
ServiceIDs => 'ARRAY',
|
|
SLAIDs => 'ARRAY',
|
|
NewTitle => 'SCALAR',
|
|
NewCustomerID => 'SCALAR',
|
|
NewCustomerUserLogin => 'SCALAR',
|
|
NewStateID => 'SCALAR',
|
|
NewQueueID => 'SCALAR',
|
|
NewPriorityID => 'SCALAR',
|
|
NewOwnerID => 'SCALAR',
|
|
NewLockID => 'SCALAR',
|
|
NewTypeID => 'SCALAR',
|
|
NewResponsibleID => 'SCALAR',
|
|
NewServiceID => 'SCALAR',
|
|
NewSLAID => 'SCALAR',
|
|
ScheduleLastRun => 'SCALAR',
|
|
ScheduleLastRunUnixTime => 'SCALAR',
|
|
Valid => 'SCALAR',
|
|
ScheduleDays => 'ARRAY',
|
|
ScheduleMinutes => 'ARRAY',
|
|
ScheduleHours => 'ARRAY',
|
|
EventValues => 'ARRAY',
|
|
);
|
|
|
|
# add time attributes
|
|
for my $Type (
|
|
qw(Time ChangeTime CloseTime TimePending EscalationTime EscalationResponseTime EscalationUpdateTime EscalationSolutionTime)
|
|
)
|
|
{
|
|
my $Key = $Type . 'SearchType';
|
|
$Map{$Key} = 'SCALAR';
|
|
}
|
|
for my $Type (
|
|
qw(TicketCreate TicketChange TicketClose TicketLastChange TicketPending TicketEscalation TicketEscalationResponse TicketEscalationUpdate TicketEscalationSolution)
|
|
)
|
|
{
|
|
for my $Attribute (
|
|
qw(PointFormat Point PointStart Start StartDay StartMonth StartYear Stop StopDay StopMonth StopYear)
|
|
)
|
|
{
|
|
my $Key = $Type . 'Time' . $Attribute;
|
|
$Map{$Key} = 'SCALAR';
|
|
}
|
|
}
|
|
|
|
# Add Dynamic Fields attributes
|
|
DYNAMICFIELD:
|
|
for my $DynamicFieldConfig ( @{ $Self->{DynamicField} } ) {
|
|
next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig);
|
|
|
|
# get the field type of the dynamic fields for edit and search
|
|
my $FieldValueType = $DynamicFieldBackendObject->TemplateValueTypeGet(
|
|
DynamicFieldConfig => $DynamicFieldConfig,
|
|
FieldType => 'All',
|
|
);
|
|
|
|
# Add field type to Map
|
|
if ( IsHashRefWithData($FieldValueType) ) {
|
|
for my $FieldName ( sort keys %{$FieldValueType} ) {
|
|
$Map{$FieldName} = $FieldValueType->{$FieldName};
|
|
}
|
|
}
|
|
}
|
|
|
|
$Self->{Map} = \%Map;
|
|
|
|
return $Self;
|
|
}
|
|
|
|
=head2 JobRun()
|
|
|
|
run a generic agent job
|
|
|
|
$GenericAgentObject->JobRun(
|
|
Job => 'JobName',
|
|
OnlyTicketID => 123, # (optional) for event based Job execution
|
|
SleepTime => 100_000 # (optional) sleeptime per ticket in microseconds
|
|
UserID => 1,
|
|
);
|
|
|
|
=cut
|
|
|
|
sub JobRun {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
for (qw(Job UserID)) {
|
|
if ( !$Param{$_} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $_!"
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print "Job: '$Param{Job}'\n";
|
|
}
|
|
|
|
# get job from param
|
|
my %Job;
|
|
my %DynamicFieldSearchTemplate;
|
|
if ( $Param{Config} ) {
|
|
%Job = %{ $Param{Config} };
|
|
|
|
# log event
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'notice',
|
|
Message => "Run GenericAgent Job '$Param{Job}' from config file.",
|
|
);
|
|
}
|
|
|
|
# get db job
|
|
else {
|
|
|
|
# log event
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'notice',
|
|
Message => "Run GenericAgent Job '$Param{Job}' from db.",
|
|
);
|
|
|
|
# get job data
|
|
my %DBJobRaw = $Self->JobGet( Name => $Param{Job} );
|
|
|
|
# updated last run time
|
|
$Self->_JobUpdateRunTime(
|
|
Name => $Param{Job},
|
|
UserID => $Param{UserID}
|
|
);
|
|
|
|
# rework
|
|
for my $Key ( sort keys %DBJobRaw ) {
|
|
if ( $Key =~ /^New/ ) {
|
|
my $NewKey = $Key;
|
|
$NewKey =~ s/^New//;
|
|
$Job{New}->{$NewKey} = $DBJobRaw{$Key};
|
|
}
|
|
else {
|
|
|
|
# skip dynamic fields
|
|
if ( $Key !~ m{ DynamicField_ }xms ) {
|
|
$Job{$Key} = $DBJobRaw{$Key};
|
|
}
|
|
}
|
|
|
|
# convert dynamic fields
|
|
if ( $Key =~ m{ \A DynamicField_ }xms ) {
|
|
$Job{New}->{$Key} = $DBJobRaw{$Key};
|
|
}
|
|
elsif ( $Key =~ m{ \A Search_DynamicField_ }xms ) {
|
|
$DynamicFieldSearchTemplate{$Key} = $DBJobRaw{$Key};
|
|
}
|
|
}
|
|
|
|
# Pass module parameters directly to the module in %Param,
|
|
# but don't overwrite existing keys
|
|
for my $Counter ( 1 .. 6 ) {
|
|
if ( $Job{New}->{"ParamKey$Counter"} ) {
|
|
$Job{New}->{ $Job{New}->{"ParamKey$Counter"} } //= $Job{New}->{"ParamValue$Counter"};
|
|
}
|
|
}
|
|
|
|
if ( exists $Job{SearchInArchive} && $Job{SearchInArchive} eq 'ArchivedTickets' ) {
|
|
$Job{ArchiveFlags} = ['y'];
|
|
}
|
|
if ( exists $Job{SearchInArchive} && $Job{SearchInArchive} eq 'AllTickets' ) {
|
|
$Job{ArchiveFlags} = [ 'y', 'n' ];
|
|
}
|
|
}
|
|
|
|
# get dynamic field backend objects
|
|
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
|
|
|
|
# set dynamic fields search parameters
|
|
my %DynamicFieldSearchParameters;
|
|
DYNAMICFIELD:
|
|
for my $DynamicFieldConfig ( @{ $Self->{DynamicField} } ) {
|
|
|
|
next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig);
|
|
|
|
# get search field preferences
|
|
my $SearchFieldPreferences = $DynamicFieldBackendObject->SearchFieldPreferences(
|
|
DynamicFieldConfig => $DynamicFieldConfig,
|
|
);
|
|
|
|
next DYNAMICFIELD if !IsArrayRefWithData($SearchFieldPreferences);
|
|
|
|
PREFERENCE:
|
|
for my $Preference ( @{$SearchFieldPreferences} ) {
|
|
|
|
my $DynamicFieldTemp = $DynamicFieldSearchTemplate{
|
|
'Search_DynamicField_'
|
|
. $DynamicFieldConfig->{Name}
|
|
. $Preference->{Type}
|
|
};
|
|
|
|
next PREFERENCE if !defined $DynamicFieldTemp;
|
|
|
|
# extract the dynamic field value from the profile
|
|
my $SearchParameter = $DynamicFieldBackendObject->SearchFieldParameterBuild(
|
|
DynamicFieldConfig => $DynamicFieldConfig,
|
|
Profile => \%DynamicFieldSearchTemplate,
|
|
Type => $Preference->{Type},
|
|
);
|
|
|
|
# set search parameter
|
|
if ( defined $SearchParameter ) {
|
|
$DynamicFieldSearchParameters{ 'DynamicField_' . $DynamicFieldConfig->{Name} }
|
|
= $SearchParameter->{Parameter};
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( $Param{OnlyTicketID} ) {
|
|
$Job{TicketID} = $Param{OnlyTicketID};
|
|
}
|
|
|
|
# get needed objects
|
|
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
|
my $ConfigObject = $Kernel::OM->Get('Kernel::Config');
|
|
|
|
# escalation tickets
|
|
my %Tickets;
|
|
|
|
# get ticket limit on job run
|
|
my $RunLimit = $ConfigObject->Get('Ticket::GenericAgentRunLimit');
|
|
if ( $Job{Escalation} ) {
|
|
|
|
# Find all tickets which will escalate within the next five days.
|
|
# The notification module will determine if a notification must be sent out or not.
|
|
my @Tickets = $TicketObject->TicketSearch(
|
|
%Job,
|
|
Result => 'ARRAY',
|
|
Limit => $Job{Limit} || $Param{Limit} || 100,
|
|
TicketEscalationTimeOlderMinutes => $Job{TicketEscalationTimeOlderMinutes}
|
|
|| -( 5 * 24 * 60 ),
|
|
Permission => 'rw',
|
|
UserID => $Param{UserID} || 1,
|
|
);
|
|
|
|
for (@Tickets) {
|
|
if ( !$Job{Queue} ) {
|
|
$Tickets{$_} = $TicketObject->TicketNumberLookup( TicketID => $_ );
|
|
}
|
|
else {
|
|
my %Ticket = $TicketObject->TicketGet(
|
|
TicketID => $_,
|
|
DynamicFields => 0,
|
|
);
|
|
if ( $Ticket{Queue} eq $Job{Queue} ) {
|
|
$Tickets{$_} = $Ticket{TicketNumber};
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# pending tickets
|
|
elsif ( $Job{PendingReminder} || $Job{PendingAuto} ) {
|
|
my $Type = '';
|
|
if ( $Job{PendingReminder} ) {
|
|
$Type = 'PendingReminder';
|
|
}
|
|
else {
|
|
$Type = 'PendingAuto';
|
|
}
|
|
if ( !$Job{Queue} ) {
|
|
%Tickets = (
|
|
$TicketObject->TicketSearch(
|
|
%Job,
|
|
%DynamicFieldSearchParameters,
|
|
ConditionInline => 1,
|
|
StateType => $Type,
|
|
Limit => $Param{Limit} || $RunLimit,
|
|
UserID => $Param{UserID},
|
|
),
|
|
%Tickets
|
|
);
|
|
}
|
|
elsif ( ref $Job{Queue} eq 'ARRAY' ) {
|
|
for ( @{ $Job{Queue} } ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " For Queue: $_\n";
|
|
}
|
|
%Tickets = (
|
|
$TicketObject->TicketSearch(
|
|
%Job,
|
|
%DynamicFieldSearchParameters,
|
|
ConditionInline => 1,
|
|
Queues => [$_],
|
|
StateType => $Type,
|
|
Limit => $Param{Limit} || $RunLimit,
|
|
UserID => $Param{UserID},
|
|
),
|
|
%Tickets
|
|
);
|
|
}
|
|
}
|
|
else {
|
|
%Tickets = (
|
|
$TicketObject->TicketSearch(
|
|
%Job,
|
|
%DynamicFieldSearchParameters,
|
|
ConditionInline => 1,
|
|
StateType => $Type,
|
|
Queues => [ $Job{Queue} ],
|
|
Limit => $Param{Limit} || $RunLimit,
|
|
UserID => $Param{UserID},
|
|
),
|
|
%Tickets
|
|
);
|
|
}
|
|
for ( sort keys %Tickets ) {
|
|
my %Ticket = $TicketObject->TicketGet(
|
|
TicketID => $_,
|
|
DynamicFields => 0,
|
|
);
|
|
if ( $Ticket{UntilTime} > 1 ) {
|
|
delete $Tickets{$_};
|
|
}
|
|
}
|
|
}
|
|
|
|
# get regular tickets
|
|
else {
|
|
if ( !$Job{Queue} ) {
|
|
|
|
# check min. one search arg
|
|
my $Count = 0;
|
|
for ( sort keys %Job ) {
|
|
if ( $_ !~ /^(New|Name|Valid|Schedule|Event)/ && $Job{$_} ) {
|
|
$Count++;
|
|
}
|
|
}
|
|
|
|
# also search in Dynamic fields search attributes
|
|
for my $DynamicFieldName ( sort keys %DynamicFieldSearchParameters ) {
|
|
$Count++;
|
|
}
|
|
|
|
# log no search attribute
|
|
if ( !$Count ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Attention: Can't run GenericAgent Job '$Param{Job}' because no "
|
|
. "search attributes are used!.",
|
|
);
|
|
return;
|
|
}
|
|
|
|
# search tickets
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " For all Queues: \n";
|
|
}
|
|
my $GenericAgentTicketSearch = $ConfigObject->Get("Ticket::GenericAgentTicketSearch") || {};
|
|
%Tickets = $TicketObject->TicketSearch(
|
|
%Job,
|
|
%DynamicFieldSearchParameters,
|
|
ConditionInline => $GenericAgentTicketSearch->{ExtendedSearchCondition},
|
|
Limit => $Param{Limit} || $RunLimit,
|
|
UserID => $Param{UserID},
|
|
);
|
|
}
|
|
elsif ( ref $Job{Queue} eq 'ARRAY' ) {
|
|
for ( @{ $Job{Queue} } ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " For Queue: $_\n";
|
|
}
|
|
%Tickets = (
|
|
$TicketObject->TicketSearch(
|
|
%Job,
|
|
%DynamicFieldSearchParameters,
|
|
ConditionInline => 1,
|
|
Queues => [$_],
|
|
Limit => $Param{Limit} || $RunLimit,
|
|
UserID => $Param{UserID},
|
|
),
|
|
%Tickets
|
|
);
|
|
}
|
|
}
|
|
else {
|
|
%Tickets = $TicketObject->TicketSearch(
|
|
%Job,
|
|
%DynamicFieldSearchParameters,
|
|
ConditionInline => 1,
|
|
Queues => [ $Job{Queue} ],
|
|
Limit => $Param{Limit} || $RunLimit,
|
|
UserID => $Param{UserID},
|
|
);
|
|
}
|
|
}
|
|
|
|
# process each ticket
|
|
TICKETID:
|
|
for my $TicketID ( sort keys %Tickets ) {
|
|
|
|
$Self->_JobRunTicket(
|
|
Config => \%Job,
|
|
Job => $Param{Job},
|
|
TicketID => $TicketID,
|
|
TicketNumber => $Tickets{$TicketID},
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
next TICKETID if !$Param{SleepTime};
|
|
|
|
Time::HiRes::usleep( $Param{SleepTime} );
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
=head2 JobList()
|
|
|
|
returns a hash of jobs
|
|
|
|
my %List = $GenericAgentObject->JobList();
|
|
|
|
=cut
|
|
|
|
sub JobList {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# get cache object
|
|
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
|
|
|
|
# check cache
|
|
my $CacheKey = "JobList";
|
|
my $Cache = $CacheObject->Get(
|
|
Type => 'GenericAgent',
|
|
Key => $CacheKey,
|
|
);
|
|
return %{$Cache} if ref $Cache;
|
|
|
|
# get database object
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
return if !$DBObject->Prepare(
|
|
SQL => 'SELECT DISTINCT(job_name) FROM generic_agent_jobs',
|
|
);
|
|
|
|
my %Data;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
$Data{ $Row[0] } = $Row[0];
|
|
}
|
|
|
|
$CacheObject->Set(
|
|
Type => 'GenericAgent',
|
|
Key => $CacheKey,
|
|
Value => \%Data,
|
|
TTL => 24 * 60 * 60,
|
|
);
|
|
|
|
return %Data;
|
|
}
|
|
|
|
=head2 JobGet()
|
|
|
|
returns a hash of the job data
|
|
|
|
my %Job = $GenericAgentObject->JobGet(Name => 'JobName');
|
|
|
|
=cut
|
|
|
|
sub JobGet {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
for (qw(Name)) {
|
|
if ( !$Param{$_} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $_!"
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
# get cache object
|
|
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
|
|
|
|
# check cache
|
|
my $CacheKey = 'JobGet::' . $Param{Name};
|
|
my $Cache = $CacheObject->Get(
|
|
Type => 'GenericAgent',
|
|
Key => $CacheKey,
|
|
);
|
|
return %{$Cache} if ref $Cache;
|
|
|
|
# get database object
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
return if !$DBObject->Prepare(
|
|
SQL => '
|
|
SELECT job_key, job_value
|
|
FROM generic_agent_jobs
|
|
WHERE job_name = ?',
|
|
Bind => [ \$Param{Name} ],
|
|
);
|
|
|
|
my %Data;
|
|
while ( my @Row = $DBObject->FetchrowArray() ) {
|
|
if ( $Self->{Map}->{ $Row[0] } && $Self->{Map}->{ $Row[0] } eq 'ARRAY' ) {
|
|
push @{ $Data{ $Row[0] } }, $Row[1];
|
|
}
|
|
else {
|
|
$Data{ $Row[0] } = $Row[1];
|
|
}
|
|
}
|
|
|
|
# get time settings
|
|
my %Map = (
|
|
TicketCreate => 'Time',
|
|
TicketChange => 'ChangeTime',
|
|
TicketClose => 'CloseTime',
|
|
TicketLastChange => 'LastChangeTime',
|
|
TicketPending => 'TimePending',
|
|
TicketEscalation => 'EscalationTime',
|
|
TicketEscalationResponse => 'EscalationResponseTime',
|
|
TicketEscalationUpdate => 'EscalationUpdateTime',
|
|
TicketEscalationSolution => 'EscalationSolutionTime',
|
|
);
|
|
|
|
for my $Type (
|
|
qw(TicketCreate TicketChange TicketClose TicketLastChange TicketPending TicketEscalation TicketEscalationResponse TicketEscalationUpdate TicketEscalationSolution)
|
|
)
|
|
{
|
|
my $SearchType = $Map{$Type} . 'SearchType';
|
|
|
|
if ( !$Data{$SearchType} || $Data{$SearchType} eq 'None' ) {
|
|
|
|
# do nothing on time stuff
|
|
for (
|
|
qw(TimeStartMonth TimeStopMonth TimeStopDay
|
|
TimeStartDay TimeStopYear TimePoint
|
|
TimeStartYear TimePointFormat TimePointStart)
|
|
)
|
|
{
|
|
delete $Data{ $Type . $_ };
|
|
}
|
|
}
|
|
elsif ( $Data{$SearchType} && $Data{$SearchType} eq 'TimeSlot' ) {
|
|
for (qw(TimePoint TimePointFormat TimePointStart)) {
|
|
delete $Data{ $Type . $_ };
|
|
}
|
|
for (qw(Month Day)) {
|
|
$Data{ $Type . "TimeStart$_" } = sprintf( '%02d', $Data{ $Type . "TimeStart$_" } );
|
|
$Data{ $Type . "TimeStop$_" } = sprintf( '%02d', $Data{ $Type . "TimeStop$_" } );
|
|
}
|
|
if (
|
|
$Data{ $Type . 'TimeStartDay' }
|
|
&& $Data{ $Type . 'TimeStartMonth' }
|
|
&& $Data{ $Type . 'TimeStartYear' }
|
|
)
|
|
{
|
|
$Data{ $Type . 'TimeNewerDate' } = $Data{ $Type . 'TimeStartYear' } . '-'
|
|
. $Data{ $Type . 'TimeStartMonth' } . '-'
|
|
. $Data{ $Type . 'TimeStartDay' }
|
|
. ' 00:00:01';
|
|
}
|
|
if (
|
|
$Data{ $Type . 'TimeStopDay' }
|
|
&& $Data{ $Type . 'TimeStopMonth' }
|
|
&& $Data{ $Type . 'TimeStopYear' }
|
|
)
|
|
{
|
|
$Data{ $Type . 'TimeOlderDate' } = $Data{ $Type . 'TimeStopYear' } . '-'
|
|
. $Data{ $Type . 'TimeStopMonth' } . '-'
|
|
. $Data{ $Type . 'TimeStopDay' }
|
|
. ' 23:59:59';
|
|
}
|
|
}
|
|
elsif ( $Data{$SearchType} && $Data{$SearchType} eq 'TimePoint' ) {
|
|
for (
|
|
qw(TimeStartMonth TimeStopMonth TimeStopDay
|
|
TimeStartDay TimeStopYear TimeStartYear)
|
|
)
|
|
{
|
|
delete $Data{ $Type . $_ };
|
|
}
|
|
if (
|
|
$Data{ $Type . 'TimePoint' }
|
|
&& $Data{ $Type . 'TimePointStart' }
|
|
&& $Data{ $Type . 'TimePointFormat' }
|
|
)
|
|
{
|
|
my $Time = 0;
|
|
if ( $Data{ $Type . 'TimePointFormat' } eq 'minute' ) {
|
|
$Time = $Data{ $Type . 'TimePoint' };
|
|
}
|
|
elsif ( $Data{ $Type . 'TimePointFormat' } eq 'hour' ) {
|
|
$Time = $Data{ $Type . 'TimePoint' } * 60;
|
|
}
|
|
elsif ( $Data{ $Type . 'TimePointFormat' } eq 'day' ) {
|
|
$Time = $Data{ $Type . 'TimePoint' } * 60 * 24;
|
|
}
|
|
elsif ( $Data{ $Type . 'TimePointFormat' } eq 'week' ) {
|
|
$Time = $Data{ $Type . 'TimePoint' } * 60 * 24 * 7;
|
|
}
|
|
elsif ( $Data{ $Type . 'TimePointFormat' } eq 'month' ) {
|
|
$Time = $Data{ $Type . 'TimePoint' } * 60 * 24 * 30;
|
|
}
|
|
elsif ( $Data{ $Type . 'TimePointFormat' } eq 'year' ) {
|
|
$Time = $Data{ $Type . 'TimePoint' } * 60 * 24 * 365;
|
|
}
|
|
if ( $Data{ $Type . 'TimePointStart' } eq 'Before' ) {
|
|
|
|
# more than ... ago
|
|
$Data{ $Type . 'TimeOlderMinutes' } = $Time;
|
|
}
|
|
elsif ( $Data{ $Type . 'TimePointStart' } eq 'Next' ) {
|
|
|
|
# within the next ...
|
|
$Data{ $Type . 'TimeNewerMinutes' } = 0;
|
|
$Data{ $Type . 'TimeOlderMinutes' } = -$Time;
|
|
}
|
|
else {
|
|
|
|
# within the last ...
|
|
$Data{ $Type . 'TimeOlderMinutes' } = 0;
|
|
$Data{ $Type . 'TimeNewerMinutes' } = $Time;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
# check valid
|
|
if ( %Data && !defined $Data{Valid} ) {
|
|
$Data{Valid} = 1;
|
|
}
|
|
if (%Data) {
|
|
$Data{Name} = $Param{Name};
|
|
}
|
|
|
|
$CacheObject->Set(
|
|
Type => 'GenericAgent',
|
|
Key => $CacheKey,
|
|
Value => \%Data,
|
|
TTL => 24 * 60 * 60,
|
|
);
|
|
|
|
return %Data;
|
|
}
|
|
|
|
=head2 JobAdd()
|
|
|
|
adds a new job to the database
|
|
|
|
$GenericAgentObject->JobAdd(
|
|
Name => 'JobName',
|
|
Data => {
|
|
Queue => 'SomeQueue',
|
|
...
|
|
Valid => 1,
|
|
},
|
|
UserID => 123,
|
|
);
|
|
|
|
=cut
|
|
|
|
sub JobAdd {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
for (qw(Name Data UserID)) {
|
|
if ( !$Param{$_} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $_!"
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
# check if job name already exists
|
|
my %Check = $Self->JobGet( Name => $Param{Name} );
|
|
if (%Check) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "A job with the name '$Param{Name}' already exists.",
|
|
);
|
|
return;
|
|
}
|
|
|
|
# get database object
|
|
my $DBObject = $Kernel::OM->Get('Kernel::System::DB');
|
|
|
|
# insert data into db
|
|
for my $Key ( sort keys %{ $Param{Data} } ) {
|
|
if ( ref $Param{Data}->{$Key} eq 'ARRAY' ) {
|
|
for my $Item ( @{ $Param{Data}->{$Key} } ) {
|
|
if ( defined $Item ) {
|
|
$DBObject->Do(
|
|
SQL => 'INSERT INTO generic_agent_jobs '
|
|
. '(job_name, job_key, job_value) VALUES (?, ?, ?)',
|
|
Bind => [ \$Param{Name}, \$Key, \$Item ],
|
|
);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
if ( defined $Param{Data}->{$Key} ) {
|
|
$DBObject->Do(
|
|
SQL => 'INSERT INTO generic_agent_jobs '
|
|
. '(job_name, job_key, job_value) VALUES (?, ?, ?)',
|
|
Bind => [ \$Param{Name}, \$Key, \$Param{Data}->{$Key} ],
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'notice',
|
|
Message => "New GenericAgent job '$Param{Name}' added (UserID=$Param{UserID}).",
|
|
);
|
|
|
|
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
|
|
Type => 'GenericAgent',
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
|
|
=head2 JobDelete()
|
|
|
|
deletes a job from the database
|
|
|
|
my $Success = $GenericAgentObject->JobDelete(
|
|
Name => 'JobName',
|
|
UserID => 123,
|
|
);
|
|
|
|
returns:
|
|
|
|
$Success = 1; # or false in case of a failure
|
|
|
|
=cut
|
|
|
|
sub JobDelete {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
for (qw(Name UserID)) {
|
|
if ( !$Param{$_} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $_!"
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
# delete job
|
|
$Kernel::OM->Get('Kernel::System::DB')->Do(
|
|
SQL => 'DELETE FROM generic_agent_jobs WHERE job_name = ?',
|
|
Bind => [ \$Param{Name} ],
|
|
);
|
|
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'notice',
|
|
Message => "GenericAgent job '$Param{Name}' deleted (UserID=$Param{UserID}).",
|
|
);
|
|
|
|
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
|
|
Type => 'GenericAgent',
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
|
|
=head2 JobEventList()
|
|
|
|
returns a hash of events for each job
|
|
|
|
my %List = $GenericAgentObject->JobEventList();
|
|
|
|
=cut
|
|
|
|
sub JobEventList {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# get cache object
|
|
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
|
|
|
|
# check cache
|
|
my $CacheKey = "JobEventList";
|
|
my $Cache = $CacheObject->Get(
|
|
Type => 'GenericAgent',
|
|
Key => $CacheKey,
|
|
);
|
|
return %{$Cache} if ref $Cache;
|
|
|
|
my %JobList = $Self->JobList();
|
|
my %Data;
|
|
JOB_NAME:
|
|
for my $JobName ( sort keys %JobList ) {
|
|
my %Job = $Self->JobGet( Name => $JobName );
|
|
next JOB_NAME if !$Job{Valid};
|
|
$Data{$JobName} = $Job{EventValues};
|
|
}
|
|
|
|
$CacheObject->Set(
|
|
Type => 'GenericAgent',
|
|
Key => $CacheKey,
|
|
Value => \%Data,
|
|
TTL => 24 * 60 * 60,
|
|
);
|
|
|
|
return %Data;
|
|
}
|
|
|
|
=begin Internal:
|
|
|
|
=cut
|
|
|
|
=head2 _JobRunTicket()
|
|
|
|
run a generic agent job on a ticket
|
|
|
|
$GenericAgentObject->_JobRunTicket(
|
|
TicketID => 123,
|
|
TicketNumber => '2004081400001',
|
|
Config => {
|
|
%Job,
|
|
},
|
|
UserID => 1,
|
|
);
|
|
|
|
=cut
|
|
|
|
sub _JobRunTicket {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
for (qw(TicketID TicketNumber Config UserID)) {
|
|
if ( !$Param{$_} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Need $_!"
|
|
);
|
|
return;
|
|
}
|
|
}
|
|
|
|
# get ticket object
|
|
my $TicketObject = $Kernel::OM->Get('Kernel::System::Ticket');
|
|
|
|
my $Ticket = "($Param{TicketNumber}/$Param{TicketID})";
|
|
|
|
# disable sending emails
|
|
$TicketObject->{SendNoNotification} = $Param{Config}->{New}->{SendNoNotification} ? 1 : 0;
|
|
|
|
# move ticket
|
|
if ( $Param{Config}->{New}->{Queue} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - Move Ticket $Ticket to Queue '$Param{Config}->{New}->{Queue}'\n";
|
|
}
|
|
$TicketObject->TicketQueueSet(
|
|
QueueID => $Kernel::OM->Get('Kernel::System::Queue')->QueueLookup(
|
|
Queue => $Param{Config}->{New}->{Queue},
|
|
Cache => 1,
|
|
),
|
|
UserID => $Param{UserID},
|
|
TicketID => $Param{TicketID},
|
|
);
|
|
}
|
|
if ( $Param{Config}->{New}->{QueueID} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - Move Ticket $Ticket to QueueID '$Param{Config}->{New}->{QueueID}'\n";
|
|
}
|
|
$TicketObject->TicketQueueSet(
|
|
QueueID => $Param{Config}->{New}->{QueueID},
|
|
UserID => $Param{UserID},
|
|
TicketID => $Param{TicketID},
|
|
);
|
|
}
|
|
|
|
my $ContentType = 'text/plain';
|
|
|
|
# add note if wanted
|
|
if ( $Param{Config}->{New}->{Note}->{Body} || $Param{Config}->{New}->{NoteBody} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - Add note to Ticket $Ticket\n";
|
|
}
|
|
|
|
my %Ticket = $TicketObject->TicketGet(
|
|
TicketID => $Param{TicketID},
|
|
DynamicFields => 0,
|
|
);
|
|
|
|
my %CustomerUserData;
|
|
|
|
# We can only do OTRS Tag replacement if we have a CustomerUserID (langauge settings...)
|
|
if ( IsHashRefWithData( \%Ticket ) && IsStringWithData( $Ticket{CustomerUserID} ) ) {
|
|
my %CustomerUserData = $Kernel::OM->Get('Kernel::System::CustomerUser')->CustomerUserDataGet(
|
|
User => $Ticket{CustomerUserID},
|
|
);
|
|
|
|
my %Notification = (
|
|
Subject => $Param{Config}->{New}->{NoteSubject},
|
|
Body => $Param{Config}->{New}->{NoteBody},
|
|
ContentType => 'text/plain',
|
|
);
|
|
|
|
my %GenericAgentArticle = $Kernel::OM->Get('Kernel::System::TemplateGenerator')->GenericAgentArticle(
|
|
TicketID => $Param{TicketID},
|
|
Recipient => \%CustomerUserData, # Agent or Customer data get result
|
|
Notification => \%Notification,
|
|
UserID => $Param{UserID},
|
|
);
|
|
|
|
if (
|
|
IsStringWithData( $GenericAgentArticle{Body} )
|
|
|| IsHashRefWithData( $GenericAgentArticle{Subject} )
|
|
)
|
|
{
|
|
$Param{Config}->{New}->{Note}->{Subject} = $GenericAgentArticle{Subject} || '';
|
|
$Param{Config}->{New}->{Note}->{Body} = $GenericAgentArticle{Body} || '';
|
|
$ContentType = $GenericAgentArticle{ContentType};
|
|
}
|
|
}
|
|
|
|
my $ArticleBackendObject = $Kernel::OM->Get('Kernel::System::Ticket::Article')->BackendForChannel(
|
|
ChannelName => 'Internal',
|
|
);
|
|
|
|
my $ArticleID = $ArticleBackendObject->ArticleCreate(
|
|
TicketID => $Param{TicketID},
|
|
SenderType => 'agent',
|
|
IsVisibleForCustomer => $Param{Config}->{New}->{Note}->{IsVisibleForCustomer}
|
|
// $Param{Config}->{New}->{NoteIsVisibleForCustomer}
|
|
// 0,
|
|
From => $Param{Config}->{New}->{Note}->{From}
|
|
|| $Param{Config}->{New}->{NoteFrom}
|
|
|| 'GenericAgent',
|
|
Subject => $Param{Config}->{New}->{Note}->{Subject}
|
|
|| $Param{Config}->{New}->{NoteSubject}
|
|
|| 'Note',
|
|
Body => $Param{Config}->{New}->{Note}->{Body} || $Param{Config}->{New}->{NoteBody},
|
|
MimeType => $ContentType,
|
|
Charset => 'utf-8',
|
|
UserID => $Param{UserID},
|
|
HistoryType => 'AddNote',
|
|
HistoryComment => 'Generic Agent note added.',
|
|
NoAgentNotify => $Param{Config}->{New}->{SendNoNotification} || 0,
|
|
);
|
|
my $TimeUnits = $Param{Config}->{New}->{Note}->{TimeUnits}
|
|
|| $Param{Config}->{New}->{NoteTimeUnits};
|
|
if ( $ArticleID && $TimeUnits ) {
|
|
$TicketObject->TicketAccountTime(
|
|
TicketID => $Param{TicketID},
|
|
ArticleID => $ArticleID,
|
|
TimeUnit => $TimeUnits,
|
|
UserID => $Param{UserID},
|
|
);
|
|
}
|
|
}
|
|
|
|
my %PendingStates = $Kernel::OM->Get('Kernel::System::State')->StateGetStatesByType(
|
|
StateType => [ 'pending auto', 'pending reminder' ],
|
|
Result => 'HASH',
|
|
);
|
|
|
|
$Self->{PendingStateList} = \%PendingStates || {};
|
|
|
|
# set new state
|
|
my $IsPendingState;
|
|
if ( $Param{Config}->{New}->{State} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - changed state of Ticket $Ticket to '$Param{Config}->{New}->{State}'\n";
|
|
}
|
|
$TicketObject->TicketStateSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
State => $Param{Config}->{New}->{State},
|
|
);
|
|
|
|
$IsPendingState = grep { $_ eq $Param{Config}->{New}->{State} } values %{ $Self->{PendingStateList} };
|
|
}
|
|
if ( $Param{Config}->{New}->{StateID} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - changed state id of ticket $Ticket to '$Param{Config}->{New}->{StateID}'\n";
|
|
}
|
|
$TicketObject->TicketStateSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
StateID => $Param{Config}->{New}->{StateID},
|
|
);
|
|
|
|
$IsPendingState = grep { $_ == $Param{Config}->{New}->{StateID} } keys %{ $Self->{PendingStateList} };
|
|
}
|
|
|
|
if (
|
|
$Param{Config}->{New}->{PendingTime}
|
|
&& !$Param{Config}->{New}->{State}
|
|
&& !$Param{Config}->{New}->{StateID}
|
|
)
|
|
{
|
|
# if pending time is provided, but there is no new ticket state provided,
|
|
# check if ticket is already in pending state
|
|
my %Ticket = $TicketObject->TicketGet(
|
|
TicketID => $Param{TicketID},
|
|
DynamicFields => 0,
|
|
);
|
|
|
|
$IsPendingState = grep { $_ eq $Ticket{State} } values %{ $Self->{PendingStateList} };
|
|
}
|
|
|
|
# set pending time, if new state is pending state
|
|
if ( $IsPendingState && $Param{Config}->{New}->{PendingTime} ) {
|
|
|
|
# pending time
|
|
my $PendingTime = $Param{Config}->{New}->{PendingTime};
|
|
|
|
# calculate pending time based on hours, minutes, years...
|
|
if ( $Param{Config}->{New}->{PendingTimeType} ) {
|
|
$PendingTime *= $Param{Config}->{New}->{PendingTimeType};
|
|
}
|
|
|
|
# add systemtime
|
|
my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime');
|
|
$DateTimeObject->Add( Seconds => $PendingTime );
|
|
|
|
# set pending time
|
|
$TicketObject->TicketPendingTimeSet(
|
|
Year => $DateTimeObject->Format( Format => '%Y' ),
|
|
Month => $DateTimeObject->Format( Format => '%m' ),
|
|
Day => $DateTimeObject->Format( Format => '%d' ),
|
|
Hour => $DateTimeObject->Format( Format => '%H' ),
|
|
Minute => $DateTimeObject->Format( Format => '%M' ),
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
);
|
|
}
|
|
|
|
# set customer id and customer user
|
|
if ( $Param{Config}->{New}->{CustomerID} || $Param{Config}->{New}->{CustomerUserLogin} ) {
|
|
if ( $Param{Config}->{New}->{CustomerID} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print
|
|
" - set customer id of Ticket $Ticket to '$Param{Config}->{New}->{CustomerID}'\n";
|
|
}
|
|
}
|
|
if ( $Param{Config}->{New}->{CustomerUserLogin} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print
|
|
" - set customer user id of Ticket $Ticket to '$Param{Config}->{New}->{CustomerUserLogin}'\n";
|
|
}
|
|
}
|
|
$TicketObject->TicketCustomerSet(
|
|
TicketID => $Param{TicketID},
|
|
No => $Param{Config}->{New}->{CustomerID} || '',
|
|
User => $Param{Config}->{New}->{CustomerUserLogin} || '',
|
|
UserID => $Param{UserID},
|
|
);
|
|
}
|
|
|
|
# set new title
|
|
if ( $Param{Config}->{New}->{Title} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set title of Ticket $Ticket to '$Param{Config}->{New}->{Title}'\n";
|
|
}
|
|
$TicketObject->TicketTitleUpdate(
|
|
Title => $Param{Config}->{New}->{Title},
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
);
|
|
}
|
|
|
|
# set new type
|
|
if ( $Param{Config}->{New}->{Type} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set type of Ticket $Ticket to '$Param{Config}->{New}->{Type}'\n";
|
|
}
|
|
$TicketObject->TicketTypeSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
Type => $Param{Config}->{New}->{Type},
|
|
);
|
|
}
|
|
if ( $Param{Config}->{New}->{TypeID} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set type id of Ticket $Ticket to '$Param{Config}->{New}->{TypeID}'\n";
|
|
}
|
|
$TicketObject->TicketTypeSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
TypeID => $Param{Config}->{New}->{TypeID},
|
|
);
|
|
}
|
|
|
|
# set new service
|
|
if ( $Param{Config}->{New}->{Service} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set service of Ticket $Ticket to '$Param{Config}->{New}->{Service}'\n";
|
|
}
|
|
$TicketObject->TicketServiceSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
Service => $Param{Config}->{New}->{Service},
|
|
);
|
|
}
|
|
if ( $Param{Config}->{New}->{ServiceID} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set service id of Ticket $Ticket to '$Param{Config}->{New}->{ServiceID}'\n";
|
|
}
|
|
$TicketObject->TicketServiceSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
ServiceID => $Param{Config}->{New}->{ServiceID},
|
|
);
|
|
}
|
|
|
|
# set new sla
|
|
if ( $Param{Config}->{New}->{SLA} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set sla of Ticket $Ticket to '$Param{Config}->{New}->{SLA}'\n";
|
|
}
|
|
$TicketObject->TicketSLASet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
SLA => $Param{Config}->{New}->{SLA},
|
|
);
|
|
}
|
|
if ( $Param{Config}->{New}->{SLAID} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set sla id of Ticket $Ticket to '$Param{Config}->{New}->{SLAID}'\n";
|
|
}
|
|
$TicketObject->TicketSLASet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
SLAID => $Param{Config}->{New}->{SLAID},
|
|
);
|
|
}
|
|
|
|
# set new priority
|
|
if ( $Param{Config}->{New}->{Priority} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set priority of Ticket $Ticket to '$Param{Config}->{New}->{Priority}'\n";
|
|
}
|
|
$TicketObject->TicketPrioritySet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
Priority => $Param{Config}->{New}->{Priority},
|
|
);
|
|
}
|
|
if ( $Param{Config}->{New}->{PriorityID} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print
|
|
" - set priority id of Ticket $Ticket to '$Param{Config}->{New}->{PriorityID}'\n";
|
|
}
|
|
$TicketObject->TicketPrioritySet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
PriorityID => $Param{Config}->{New}->{PriorityID},
|
|
);
|
|
}
|
|
|
|
# set new owner
|
|
if ( $Param{Config}->{New}->{Owner} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set owner of Ticket $Ticket to '$Param{Config}->{New}->{Owner}'\n";
|
|
}
|
|
$TicketObject->TicketOwnerSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
NewUser => $Param{Config}->{New}->{Owner},
|
|
);
|
|
}
|
|
if ( $Param{Config}->{New}->{OwnerID} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set owner id of Ticket $Ticket to '$Param{Config}->{New}->{OwnerID}'\n";
|
|
}
|
|
$TicketObject->TicketOwnerSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
NewUserID => $Param{Config}->{New}->{OwnerID},
|
|
);
|
|
}
|
|
|
|
# set new responsible
|
|
if ( $Param{Config}->{New}->{Responsible} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print
|
|
" - set responsible of Ticket $Ticket to '$Param{Config}->{New}->{Responsible}'\n";
|
|
}
|
|
$TicketObject->TicketResponsibleSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
NewUser => $Param{Config}->{New}->{Responsible},
|
|
);
|
|
}
|
|
if ( $Param{Config}->{New}->{ResponsibleID} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print
|
|
" - set responsible id of Ticket $Ticket to '$Param{Config}->{New}->{ResponsibleID}'\n";
|
|
}
|
|
$TicketObject->TicketResponsibleSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
NewUserID => $Param{Config}->{New}->{ResponsibleID},
|
|
);
|
|
}
|
|
|
|
# set new lock
|
|
if ( $Param{Config}->{New}->{Lock} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set lock of Ticket $Ticket to '$Param{Config}->{New}->{Lock}'\n";
|
|
}
|
|
$TicketObject->TicketLockSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
Lock => $Param{Config}->{New}->{Lock},
|
|
);
|
|
}
|
|
if ( $Param{Config}->{New}->{LockID} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - set lock id of Ticket $Ticket to '$Param{Config}->{New}->{LockID}'\n";
|
|
}
|
|
$TicketObject->TicketLockSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
LockID => $Param{Config}->{New}->{LockID},
|
|
);
|
|
}
|
|
|
|
# get dynamic field backend objects
|
|
my $DynamicFieldBackendObject = $Kernel::OM->Get('Kernel::System::DynamicField::Backend');
|
|
|
|
# set new dynamic fields options
|
|
# cycle trough the activated Dynamic Fields for this screen
|
|
DYNAMICFIELD:
|
|
for my $DynamicFieldConfig ( @{ $Self->{DynamicField} } ) {
|
|
|
|
next DYNAMICFIELD if !IsHashRefWithData($DynamicFieldConfig);
|
|
|
|
# extract the dynamic field value from the web request
|
|
my $Value = $DynamicFieldBackendObject->EditFieldValueGet(
|
|
DynamicFieldConfig => $DynamicFieldConfig,
|
|
Template => $Param{Config}->{New},
|
|
TransformDates => 0,
|
|
);
|
|
|
|
# check if we got a value or an empty value if
|
|
# an empty value is configured as valid (PossibleNone)
|
|
# for the current dynamic field
|
|
if (
|
|
defined $Value
|
|
&& (
|
|
$DynamicFieldConfig->{Config}->{PossibleNone}
|
|
|| $Value ne ''
|
|
)
|
|
)
|
|
{
|
|
my $Success = $DynamicFieldBackendObject->ValueSet(
|
|
DynamicFieldConfig => $DynamicFieldConfig,
|
|
ObjectID => $Param{TicketID},
|
|
Value => $Value,
|
|
UserID => 1,
|
|
);
|
|
|
|
if ($Success) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
my $ValueStrg = $DynamicFieldBackendObject->ReadableValueRender(
|
|
DynamicFieldConfig => $DynamicFieldConfig,
|
|
Value => $Value,
|
|
);
|
|
print " - set ticket dynamic field $DynamicFieldConfig->{Name} "
|
|
. "of Ticket $Ticket to $ValueStrg->{Title} '\n";
|
|
}
|
|
}
|
|
else {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Could not set dynamic field $DynamicFieldConfig->{Name} "
|
|
. "for Ticket $Ticket.",
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
# run module
|
|
my $AllowCustomModuleExecution
|
|
= $Kernel::OM->Get('Kernel::Config')->Get('Ticket::GenericAgentAllowCustomModuleExecution') || 0;
|
|
|
|
if ( $Param{Config}->{New}->{Module} && $AllowCustomModuleExecution ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - Use module ($Param{Config}->{New}->{Module}) for Ticket $Ticket.\n";
|
|
}
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'notice',
|
|
Message => "Use module ($Param{Config}->{New}->{Module}) for Ticket $Ticket.",
|
|
);
|
|
if ( $Self->{Debug} ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'debug',
|
|
Message => "Try to load module: $Param{Config}->{New}->{Module}!",
|
|
);
|
|
}
|
|
|
|
if ( $Kernel::OM->Get('Kernel::System::Main')->Require( $Param{Config}->{New}->{Module} ) )
|
|
{
|
|
|
|
# protect parent process
|
|
eval {
|
|
my $Object = $Param{Config}->{New}->{Module}->new(
|
|
Debug => $Self->{Debug},
|
|
);
|
|
if ($Object) {
|
|
$Object->Run(
|
|
%{ $Param{Config} },
|
|
TicketID => $Param{TicketID},
|
|
);
|
|
}
|
|
};
|
|
|
|
if ($@) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => $@
|
|
);
|
|
}
|
|
}
|
|
}
|
|
elsif ( $Param{Config}->{New}->{Module} && !$AllowCustomModuleExecution ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - Use module ($Param{Config}->{New}->{Module}) is not allowed by the system configuration.\n";
|
|
}
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Use module ($Param{Config}->{New}->{Module}) is not allowed by the system configuration.",
|
|
);
|
|
}
|
|
|
|
# set new archive flag
|
|
if (
|
|
$Param{Config}->{New}->{ArchiveFlag}
|
|
&& $Kernel::OM->Get('Kernel::Config')->Get('Ticket::ArchiveSystem')
|
|
)
|
|
{
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print
|
|
" - set archive flag of Ticket $Ticket to '$Param{Config}->{New}->{ArchiveFlag}'\n";
|
|
}
|
|
$TicketObject->TicketArchiveFlagSet(
|
|
TicketID => $Param{TicketID},
|
|
UserID => $Param{UserID},
|
|
ArchiveFlag => $Param{Config}->{New}->{ArchiveFlag},
|
|
);
|
|
}
|
|
|
|
# cmd
|
|
my $AllowCustomScriptExecution
|
|
= $Kernel::OM->Get('Kernel::Config')->Get('Ticket::GenericAgentAllowCustomScriptExecution') || 0;
|
|
|
|
if ( $Param{Config}->{New}->{CMD} && $AllowCustomScriptExecution ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - Execute '$Param{Config}->{New}->{CMD}' for Ticket $Ticket.\n";
|
|
}
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'notice',
|
|
Message => "Execute '$Param{Config}->{New}->{CMD}' for Ticket $Ticket.",
|
|
);
|
|
system("$Param{Config}->{New}->{CMD} $Param{TicketNumber} $Param{TicketID} ");
|
|
|
|
if ( $? ne 0 ) {
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'notice',
|
|
Message => "Command returned a nonzero return code: rc=$?, err=$!",
|
|
);
|
|
}
|
|
}
|
|
elsif ( $Param{Config}->{New}->{CMD} && !$AllowCustomScriptExecution ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - Execute '$Param{Config}->{New}->{CMD}' is not allowed by the system configuration..\n";
|
|
}
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'error',
|
|
Message => "Execute '$Param{Config}->{New}->{CMD}' is not allowed by the system configuration..",
|
|
);
|
|
}
|
|
|
|
# delete ticket
|
|
if ( $Param{Config}->{New}->{Delete} ) {
|
|
if ( $Self->{NoticeSTDOUT} ) {
|
|
print " - Delete Ticket $Ticket.\n";
|
|
}
|
|
$Kernel::OM->Get('Kernel::System::Log')->Log(
|
|
Priority => 'notice',
|
|
Message => "Delete Ticket $Ticket.",
|
|
);
|
|
$TicketObject->TicketDelete(
|
|
UserID => $Param{UserID},
|
|
TicketID => $Param{TicketID},
|
|
);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
sub _JobUpdateRunTime {
|
|
my ( $Self, %Param ) = @_;
|
|
|
|
# check needed stuff
|
|
for (qw(Name 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');
|
|
|
|
# delete old run times
|
|
return if !$DBObject->Do(
|
|
SQL => 'DELETE FROM generic_agent_jobs WHERE job_name = ? AND job_key IN (?, ?)',
|
|
Bind => [ \$Param{Name}, \'ScheduleLastRun', \'ScheduleLastRunUnixTime' ],
|
|
);
|
|
|
|
# get time object
|
|
my $DateTimeObject = $Kernel::OM->Create('Kernel::System::DateTime');
|
|
|
|
# update new run time
|
|
my %Insert = (
|
|
ScheduleLastRun => $DateTimeObject->ToString(),
|
|
ScheduleLastRunUnixTime => $DateTimeObject->ToEpoch(),
|
|
);
|
|
|
|
for my $Key ( sort keys %Insert ) {
|
|
$DBObject->Do(
|
|
SQL => 'INSERT INTO generic_agent_jobs (job_name,job_key, job_value) VALUES (?, ?, ?)',
|
|
Bind => [ \$Param{Name}, \$Key, \$Insert{$Key} ],
|
|
);
|
|
}
|
|
|
|
$Kernel::OM->Get('Kernel::System::Cache')->Delete(
|
|
Key => 'JobGet::' . $Param{Name},
|
|
Type => 'GenericAgent',
|
|
);
|
|
|
|
return 1;
|
|
}
|
|
|
|
1;
|
|
|
|
=end Internal:
|
|
|
|
=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
|