This commit is contained in:
2024-10-14 00:08:40 +02:00
parent dbfba56f66
commit 1462d52e13
4572 changed files with 2658864 additions and 0 deletions

View File

@@ -0,0 +1,244 @@
# --
# 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::ITSMChange::Event::Condition;
use strict;
use warnings;
our @ObjectDependencies = (
'Kernel::System::ITSMChange::ITSMCondition',
'Kernel::System::ITSMChange::ITSMWorkOrder',
'Kernel::System::Log',
);
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Data Event Config UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# to store the change id
my $ChangeID;
# to store the object were the data comes from
my $Object;
# handle change events
if ( $Param{Event} =~ m{ \A Change }xms ) {
# set the change id
$ChangeID = $Param{Data}->{ChangeID};
# set the object
$Object = 'ITSMChange';
}
# handle workorder events
elsif ( $Param{Event} =~ m{ \A WorkOrder }xms ) {
# get workorder
my $WorkOrder = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMWorkOrder')->WorkOrderGet(
WorkOrderID => $Param{Data}->{WorkOrderID},
UserID => $Param{UserID},
);
# set the change id from workorder data
$ChangeID = $WorkOrder->{ChangeID};
# set the object
$Object = 'ITSMWorkOrder';
}
# show error for unknown events
else {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Can not handle event '$Param{Event}'!",
);
return;
}
# in case of an update event or a time reached event, store the updated attributes
my @AttributesChanged;
if ( $Param{Event} eq 'ChangeUpdatePost' ) {
# get old data
my $OldData = $Param{Data}->{OldChangeData};
FIELD:
for my $Field ( sort keys %{ $Param{Data} } ) {
# avoid recursion
next FIELD if $Field eq 'OldChangeData';
# we do not track the user id and "plain" columns
next FIELD if $Field eq 'UserID';
next FIELD if $Field eq 'JustificationPlain';
next FIELD if $Field eq 'DescriptionPlain';
# check if field has changed
my $FieldHasChanged = $Self->_HasFieldChanged(
New => $Param{Data}->{$Field},
Old => $OldData->{$Field},
);
next FIELD if !$FieldHasChanged;
# remember changed field name
push @AttributesChanged, $Field;
}
}
elsif ( $Param{Event} eq 'WorkOrderUpdatePost' ) {
# get old data
my $OldData = $Param{Data}->{OldWorkOrderData};
FIELD:
for my $Field ( sort keys %{ $Param{Data} } ) {
# avoid recursion
next FIELD if $Field eq 'OldWorkOrderData';
# we do not track the user id and "plain" columns
next FIELD if $Field eq 'UserID';
next FIELD if $Field eq 'ReportPlain';
next FIELD if $Field eq 'InstructionPlain';
# special handling for accounted time
if ( $Field eq 'AccountedTime' ) {
# we do not track if accounted time was empty or zero
next FIELD if !$Param{Data}->{AccountedTime};
# remember changed field name
push @AttributesChanged, $Field;
next FIELD;
}
# check if field has changed
my $FieldHasChanged = $Self->_HasFieldChanged(
New => $Param{Data}->{$Field},
Old => $OldData->{$Field},
);
next FIELD if !$FieldHasChanged;
# remember changed field name
push @AttributesChanged, $Field;
}
}
# all kind of change and workorder time reached events
elsif ( $Param{Event} =~ m{ \A (?: Change | WorkOrder ) ( .+ Time ) ReachedPost \z }xms ) {
# get the name of the reached time field
my $Field = $1;
# remember changed field name
push @AttributesChanged, $Field;
}
# match all conditions for this change and execute all actions
my $Success = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMCondition')->ConditionMatchExecuteAll(
ChangeID => $ChangeID,
AttributesChanged => { $Object => \@AttributesChanged },
Event => $Param{Event},
UserID => $Param{UserID},
);
# check errors
if ( !$Success ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "ConditionMatchExecuteAll could not be "
. "executed successfully for event '$Param{Event}' on ChangeID '$ChangeID'!",
);
return;
}
return 1;
}
=head1 PRIVATE INTERFACE
=head2 _HasFieldChanged()
This method checks whether a field was changed or not. It returns 1 when field
was changed, 0 otherwise
my $FieldHasChanged = $ConditionObject->_HasFieldChanged(
Old => 'old value', # can be array reference or hash reference as well
New => 'new value', # can be array reference or hash reference as well
);
=cut
sub _HasFieldChanged {
my ( $Self, %Param ) = @_;
# field has changed when either 'new' or 'old is not set
return 1 if !( $Param{New} && $Param{Old} ) && ( $Param{New} || $Param{Old} );
# field has not changed when both values are empty
return if !$Param{New} && !$Param{Old};
# return result of 'eq' when both params are scalars
return $Param{New} ne $Param{Old} if !ref( $Param{New} ) && !ref( $Param{Old} );
# a field has changed when 'ref' is different
return 1 if ref( $Param{New} ) ne ref( $Param{Old} );
# check hashes
if ( ref $Param{New} eq 'HASH' ) {
# field has changed when number of keys are different
return 1 if scalar keys %{ $Param{New} } != scalar keys %{ $Param{Old} };
# check the values for each key
for my $Key ( sort keys %{ $Param{New} } ) {
return 1 if $Param{New}->{$Key} ne $Param{Old}->{$Key};
}
}
# check arrays
if ( ref $Param{New} eq 'ARRAY' ) {
# changed when number of elements differ
return 1 if scalar @{ $Param{New} } != scalar @{ $Param{Old} };
# check each element
for my $Index ( 0 .. $#{ $Param{New} } ) {
return 1 if $Param{New}->[$Index] ne $Param{Old}->[$Index];
}
}
# field has not been changed
return 0;
}
1;

View File

@@ -0,0 +1,79 @@
# --
# 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::ITSMChange::Event::ConditionDelete;
use strict;
use warnings;
our @ObjectDependencies = (
'Kernel::System::ITSMChange::ITSMCondition',
'Kernel::System::Log',
);
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Data Event Config UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# handle deletion of a change
if ( $Param{Event} eq 'ChangeDeletePost' ) {
# delete all conditions (and expressions and actions) for this change id
my $Success = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMCondition')->ConditionDeleteAll(
ChangeID => $Param{Data}->{ChangeID},
UserID => $Param{UserID},
);
# handle error
if ( !$Success ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "ConditionDeleteAll() failed for ChangeID '$Param{Data}->{ChangeID}'!"
);
return;
}
return 1;
}
# error
else {
# an unknown event
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "$Param{Event} is an unknown event!",
);
return;
}
return 1;
}
1;

View File

@@ -0,0 +1,685 @@
# --
# 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::ITSMChange::Event::HistoryAdd;
use strict;
use warnings;
our @ObjectDependencies = (
'Kernel::System::ITSMChange::History',
'Kernel::System::ITSMChange::ITSMWorkOrder',
'Kernel::System::Log',
);
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Needed (qw(Data Event Config UserID)) {
if ( !$Param{$Needed} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Needed!",
);
return;
}
}
# do not modify the original event, because we need this unmodified in later event modules
my $Event = $Param{Event};
# in history event handling we use Event name without the trailing 'Post'
$Event =~ s{ Post \z }{}xms;
# distinguish between Change and WorkOrder events, based on naming convention
my ($Type) = $Event =~ m{ \A ( Change | WorkOrder | Condition | Expression | Action ) }xms;
if ( !$Type ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Could not determine the object type for the event '$Event'!"
);
return;
}
# store all history add data
my @HistoryAddData;
# do history stuff
if ( $Event eq 'ChangeAdd' || $Event eq 'WorkOrderAdd' ) {
# tell history that a change was added
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
WorkOrderID => $Param{Data}->{WorkOrderID},
HistoryType => $Event,
ContentNew => $Param{Data}->{ $Type . 'ID' },
UserID => $Param{UserID},
};
}
elsif ( $Event eq 'ChangeUpdate' || $Event eq 'WorkOrderUpdate' ) {
# get old data, either from change or workorder
my $OldData = $Param{Data}->{"Old${Type}Data"};
my $ChangeID = $OldData->{ChangeID}; # works for change and workorder events
FIELD:
for my $Field ( sort keys %{ $Param{Data} } ) {
# do not track special fields 'OldChangeData' or 'OldWorkOrderData'
next FIELD if $Field eq "Old${Type}Data";
# we do not track the user id
next FIELD if $Field eq 'UserID';
# we do not track the "plain" columns, only the non-plain columns
next FIELD if $Field eq 'JustificationPlain'; # change
next FIELD if $Field eq 'DescriptionPlain'; # change
next FIELD if $Field eq 'ReportPlain'; # workorder
next FIELD if $Field eq 'InstructionPlain'; # workorder
# we do no want to track the internal field "NoNumberCalc"
next FIELD if $Field eq 'NoNumberCalc'; # workorder
# The history of CAB updates is not tracked here,
# but in the handler for ChangeCABUpdate.
next FIELD if $Field eq 'CABAgents'; # change
next FIELD if $Field eq 'CABCustomers'; # change
# special handling for accounted time
if ( $Type eq 'WorkOrder' && $Field eq 'AccountedTime' ) {
# we do not track if accounted time was empty
next FIELD if !$Param{Data}->{$Field};
# if accounted time is not empty, we always track the history
# get workorder data
my $WorkOrder = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMWorkOrder')->WorkOrderGet(
WorkOrderID => $Param{Data}->{WorkOrderID},
UserID => $Param{UserID},
);
# save history if accounted time has changed
push @HistoryAddData, {
ChangeID => $ChangeID,
WorkOrderID => $Param{Data}->{WorkOrderID},
HistoryType => $Event,
Fieldname => $Field,
ContentNew => $WorkOrder->{$Field},
ContentOld => $OldData->{$Field},
UserID => $Param{UserID},
};
next FIELD;
}
# check if field has changed
my $FieldHasChanged = $Self->_HasFieldChanged(
New => $Param{Data}->{$Field},
Old => $OldData->{$Field},
);
# save history if field has changed
if ($FieldHasChanged) {
push @HistoryAddData, {
ChangeID => $ChangeID,
WorkOrderID => $Param{Data}->{WorkOrderID},
HistoryType => $Event,
Fieldname => $Field,
ContentNew => $Param{Data}->{$Field},
ContentOld => $OldData->{$Field},
UserID => $Param{UserID},
};
}
}
}
elsif ( $Event eq 'WorkOrderDelete' ) {
# get old data
my $OldData = $Param{Data}->{OldWorkOrderData};
# get existing history entries for this workorder
my $HistoryEntries = $Kernel::OM->Get('Kernel::System::ITSMChange::History')->WorkOrderHistoryGet(
WorkOrderID => $OldData->{WorkOrderID},
UserID => $Param{UserID},
);
# update history entries: delete workorder id
HISTORYENTRY:
for my $HistoryEntry ( @{$HistoryEntries} ) {
$Kernel::OM->Get('Kernel::System::ITSMChange::History')->HistoryUpdate(
HistoryEntryID => $HistoryEntry->{HistoryEntryID},
WorkOrderID => undef,
UserID => $Param{UserID},
);
}
# add history entry for WorkOrder deletion
# call HistoryAdd directly from here instead of using the @HistoryAddData
# as we want this to appear next to the line in history that HistoryUpdate
# just added in the code block before
return if !$Kernel::OM->Get('Kernel::System::ITSMChange::History')->HistoryAdd(
ChangeID => $OldData->{ChangeID},
HistoryType => $Event,
ContentNew => $OldData->{WorkOrderID},
UserID => $Param{UserID},
);
}
# handle ChangeCAB events
elsif ( $Event eq 'ChangeCABUpdate' || $Event eq 'ChangeCABDelete' ) {
# get old data
my $OldData = $Param{Data}->{OldChangeCABData};
FIELD:
for my $Field (qw(CABAgents CABCustomers)) {
# we do not track when the param has not been passed
next FIELD if !$Param{Data}->{$Field};
# check if field has changed
my $FieldHasChanged = $Self->_HasFieldChanged(
New => $Param{Data}->{$Field},
Old => $OldData->{$Field},
);
# save history if field has changed
if ($FieldHasChanged) {
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
Fieldname => $Field,
ContentNew => join( '%%', @{ $Param{Data}->{$Field} } ),
ContentOld => join( '%%', @{ $OldData->{$Field} } ),
UserID => $Param{UserID},
};
}
}
}
# handle link events
elsif (
$Event eq 'ChangeLinkAdd'
|| $Event eq 'ChangeLinkDelete'
|| $Event eq 'WorkOrderLinkAdd'
|| $Event eq 'WorkOrderLinkDelete'
)
{
# for workorder links get the change id
if ( $Param{Data}->{WorkOrderID} ) {
my $WorkOrder = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMWorkOrder')->WorkOrderGet(
WorkOrderID => $Param{Data}->{WorkOrderID},
UserID => $Param{UserID},
);
$Param{Data}->{ChangeID} = $WorkOrder->{ChangeID};
}
my $ContentNew = join '%%',
$Param{Data}->{SourceObject} || $Param{Data}->{TargetObject},
$Param{Data}->{SourceKey} || $Param{Data}->{TargetKey};
# tell history that a link was added
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
WorkOrderID => $Param{Data}->{WorkOrderID},
HistoryType => $Event,
ContentNew => $ContentNew,
UserID => $Param{UserID},
};
}
# handle attachment events
elsif (
$Event eq 'ChangeAttachmentAdd'
|| $Event eq 'ChangeAttachmentDelete'
|| $Event eq 'WorkOrderAttachmentAdd'
|| $Event eq 'WorkOrderAttachmentDelete'
|| $Event eq 'WorkOrderReportAttachmentAdd'
|| $Event eq 'WorkOrderReportAttachmentDelete'
)
{
# tell history that an attachment event was triggered
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
WorkOrderID => $Param{Data}->{WorkOrderID},
HistoryType => $Event,
ContentNew => $Param{Data}->{Filename},
UserID => $Param{UserID},
};
}
# handle xxxTimeReached events
elsif ( $Event =~ m{ TimeReached \z }xms ) {
# get either WorkOrderID or ChangeID
my $ID = $Param{Data}->{WorkOrderID} || $Param{Data}->{ChangeID};
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
WorkOrderID => $Param{Data}->{WorkOrderID},
HistoryType => $Event,
ContentNew => $ID . '%%Notification Sent',
UserID => $Param{UserID},
};
}
# add history entry when notification was sent
elsif ( $Event =~ m{ NotificationSent \z }xms ) {
# get either WorkOrderID or ChangeID
my $ID = $Param{Data}->{WorkOrderID} || $Param{Data}->{ChangeID};
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
WorkOrderID => $Param{Data}->{WorkOrderID},
HistoryType => $Event,
ContentNew => $Param{Data}->{To} . '%%' . $Param{Data}->{EventType},
UserID => $Param{UserID},
};
}
# handle condition events
elsif ( $Event eq 'ConditionAdd' ) {
# create history for condition
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
ContentNew => $Param{Data}->{ConditionID},
UserID => $Param{UserID},
};
# create history for all condition fields
my @ConditionStatic = qw(ConditionID UserID ChangeID);
CONDITIONFIELD:
for my $ConditionField ( sort keys %{ $Param{Data} } ) {
# check for static fields
next CONDITIONFIELD if grep { $_ eq $ConditionField } @ConditionStatic;
# do not add empty fields to history
next CONDITIONFIELD if !$Param{Data}->{$ConditionField};
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
Fieldname => $ConditionField,
ContentNew => $Param{Data}->{$ConditionField},
UserID => $Param{UserID},
};
}
}
# handle condition update events
elsif ( $Event eq 'ConditionUpdate' ) {
# get old data
my $OldData = $Param{Data}->{OldConditionData};
# create history for all condition fields
my @ConditionStatic = qw(ConditionID UserID ChangeID OldConditionData);
CONDITIONFIELD:
for my $ConditionField ( sort keys %{ $Param{Data} } ) {
# check for static fields
next CONDITIONFIELD if grep { $_ eq $ConditionField } @ConditionStatic;
# do not add empty fields to history
next CONDITIONFIELD if !$Param{Data}->{$ConditionField};
# check if field has changed
my $FieldHasChanged = $Self->_HasFieldChanged(
New => $Param{Data}->{$ConditionField},
Old => $OldData->{$ConditionField},
);
# create history only for changed fields
next CONDITIONFIELD if !$FieldHasChanged;
push @HistoryAddData, {
ChangeID => $OldData->{ChangeID},
HistoryType => $Event,
Fieldname => $ConditionField,
ContentNew => $Param{Data}->{ConditionID} . '%%' . $Param{Data}->{$ConditionField},
ContentOld => $Param{Data}->{ConditionID} . '%%' . $OldData->{$ConditionField},
UserID => $Param{UserID},
};
}
}
# handle condition delete events
elsif ( $Event eq 'ConditionDelete' ) {
# get old data
my $OldData = $Param{Data}->{OldConditionData};
push @HistoryAddData, {
ChangeID => $OldData->{ChangeID},
HistoryType => $Event,
ContentNew => $OldData->{ConditionID},
UserID => $Param{UserID},
};
}
# handle condition delete events
elsif ( $Event eq 'ConditionDeleteAll' ) {
return if !$Kernel::OM->Get('Kernel::System::ITSMChange::History')->HistoryAdd(
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
ContentNew => $Param{Data}->{ChangeID},
UserID => $Param{UserID},
);
}
# handle expression events
elsif ( $Event eq 'ExpressionAdd' ) {
# create history for expression
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
ContentNew => $Param{Data}->{ExpressionID},
UserID => $Param{UserID},
};
# create history for all expression fields
my @ExpressionStatic = qw( ExpressionID UserID ChangeID);
EXPRESSIONFIELD:
for my $ExpressionField ( sort keys %{ $Param{Data} } ) {
# check for static fields
next EXPRESSIONFIELD if grep { $_ eq $ExpressionField } @ExpressionStatic;
# do not add empty fields to history
next EXPRESSIONFIELD if !$Param{Data}->{$ExpressionField};
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
Fieldname => $ExpressionField,
ContentNew => $Param{Data}->{$ExpressionField},
UserID => $Param{UserID},
};
}
}
# handle expression update events
elsif ( $Event eq 'ExpressionUpdate' ) {
# get old data
my $OldData = $Param{Data}->{OldExpressionData};
# create history for all expression fields
my @ExpressionStatic = qw( ExpressionID UserID ChangeID OldExpressionData );
EXPRESSIONFIELD:
for my $ExpressionField ( sort keys %{ $Param{Data} } ) {
# check for static fields
next EXPRESSIONFIELD if grep { $_ eq $ExpressionField } @ExpressionStatic;
# do not add empty fields to history
next EXPRESSIONFIELD if !$Param{Data}->{$ExpressionField};
# check if field has changed
my $FieldHasChanged = $Self->_HasFieldChanged(
New => $Param{Data}->{$ExpressionField},
Old => $OldData->{$ExpressionField},
);
# create history only for changed fields
next EXPRESSIONFIELD if !$FieldHasChanged;
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
Fieldname => $ExpressionField,
ContentNew => $Param{Data}->{ExpressionID} . '%%'
. $Param{Data}->{$ExpressionField},
ContentOld => $Param{Data}->{ExpressionID} . '%%' . $OldData->{$ExpressionField},
UserID => $Param{UserID},
};
}
}
# handle expression delete events
elsif ( $Event eq 'ExpressionDelete' ) {
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
ContentNew => $Param{Data}->{ExpressionID},
UserID => $Param{UserID},
};
}
# handle delete all expressions events
elsif ( $Event eq 'ExpressionDeleteAll' ) {
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
ContentNew => $Param{Data}->{ConditionID},
UserID => $Param{UserID},
};
}
# handle action events
elsif ( $Event eq 'ActionAdd' ) {
# create history for action
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
ContentNew => $Param{Data}->{ActionID},
UserID => $Param{UserID},
};
# create history for all action fields
my @ActionStatic = qw( ActionID UserID ChangeID);
ACTIONFIELD:
for my $ActionField ( sort keys %{ $Param{Data} } ) {
# check for static fields
next ACTIONFIELD if grep { $_ eq $ActionField } @ActionStatic;
# do not add empty fields to history
next ACTIONFIELD if !$Param{Data}->{$ActionField};
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
Fieldname => $ActionField,
ContentNew => $Param{Data}->{$ActionField},
UserID => $Param{UserID},
};
}
}
# handle action update events
elsif ( $Event eq 'ActionUpdate' ) {
# get old data
my $OldData = $Param{Data}->{OldActionData};
# create history for all expression fields
my @ActionStatic = qw( ActionID UserID ChangeID OldActionData );
ACTIONFIELD:
for my $ActionField ( sort keys %{ $Param{Data} } ) {
# check for static fields
next ACTIONFIELD if grep { $_ eq $ActionField } @ActionStatic;
# do not add empty fields to history
next ACTIONFIELD if !$Param{Data}->{$ActionField};
# check if field has changed
my $FieldHasChanged = $Self->_HasFieldChanged(
New => $Param{Data}->{$ActionField},
Old => $OldData->{$ActionField},
);
# create history only for changed fields
next ACTIONFIELD if !$FieldHasChanged;
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
Fieldname => $ActionField,
ContentNew => $Param{Data}->{ActionID} . '%%' . $Param{Data}->{$ActionField},
ContentOld => $Param{Data}->{ActionID} . '%%' . $OldData->{$ActionField},
UserID => $Param{UserID},
};
}
}
# handle action delete events
elsif ( $Event eq 'ActionDelete' ) {
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
ContentNew => $Param{Data}->{ActionID},
UserID => $Param{UserID},
};
}
# handle delete all actions events
elsif ( $Event eq 'ActionDeleteAll' ) {
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
ContentNew => $Param{Data}->{ConditionID},
UserID => $Param{UserID},
};
}
# handle action execute events
elsif ( $Event eq 'ActionExecute' ) {
push @HistoryAddData, {
ChangeID => $Param{Data}->{ChangeID},
HistoryType => $Event,
ContentNew => $Param{Data}->{ActionID} . '%%' . $Param{Data}->{ActionResult},
UserID => $Param{UserID},
};
}
# error
else {
# an unknown event
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "$Event is an unknown event!",
);
return;
}
# if there is nothing to write to the history
return 1 if !@HistoryAddData;
# if there is just one history entry to write
if ( scalar @HistoryAddData == 1 ) {
# write the first and only entry of the array to the history
$Kernel::OM->Get('Kernel::System::ITSMChange::History')->HistoryAdd(
%{ $HistoryAddData[0] },
);
}
# there is more than one entry to write
# let the HistoryAddMultiple function handle that
else {
$Kernel::OM->Get('Kernel::System::ITSMChange::History')->HistoryAddMultiple(
Data => \@HistoryAddData,
);
}
return 1;
}
=head1 PRIVATE INTERFACE
=head2 _HasFieldChanged()
This method checks whether a field was changed or not. It returns 1 when field
was changed, undef otherwise.
my $FieldHasChanged = $HistoryObject->_HasFieldChanged(
Old => 'old value', # can be array reference or hash reference as well
New => 'new value', # can be array reference or hash reference as well
);
=cut
sub _HasFieldChanged {
my ( $Self, %Param ) = @_;
# field has changed when either 'new' or 'old is not set
return 1 if !( $Param{New} && $Param{Old} ) && ( $Param{New} || $Param{Old} );
# field has not changed when both values are empty
return if !$Param{New} && !$Param{Old};
# return result of 'eq' when both params are scalars
return $Param{New} ne $Param{Old} if !ref( $Param{New} ) && !ref( $Param{Old} );
# a field has changed when 'ref' is different
return 1 if ref( $Param{New} ) ne ref( $Param{Old} );
# check hashes
if ( ref $Param{New} eq 'HASH' ) {
# field has changed when number of keys are different
return 1 if scalar keys %{ $Param{New} } != scalar keys %{ $Param{Old} };
# check the values for each key
for my $Key ( sort keys %{ $Param{New} } ) {
return 1 if $Param{New}->{$Key} ne $Param{Old}->{$Key};
}
}
# check arrays
if ( ref $Param{New} eq 'ARRAY' ) {
# changed when number of elements differ
return 1 if scalar @{ $Param{New} } != scalar @{ $Param{Old} };
# check each element
for my $Index ( 0 .. $#{ $Param{New} } ) {
return 1 if $Param{New}->[$Index] ne $Param{Old}->[$Index];
}
}
# field has not been changed
return;
}
1;

View File

@@ -0,0 +1,79 @@
# --
# 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::ITSMChange::Event::HistoryDelete;
use strict;
use warnings;
our @ObjectDependencies = (
'Kernel::System::ITSMChange::History',
'Kernel::System::Log',
);
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Data Event Config UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# handle deletion of a change
if ( $Param{Event} eq 'ChangeDeletePost' ) {
# delete history of change
my $Success = $Kernel::OM->Get('Kernel::System::ITSMChange::History')->ChangeHistoryDelete(
ChangeID => $Param{Data}->{ChangeID},
UserID => $Param{UserID},
);
# handle error
if ( !$Success ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "ChangeDelete() failed for ChangeID '$Param{Data}->{ChangeID}'!",
);
return;
}
return 1;
}
# error
else {
# an unknown event
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "$Param{Event} is an unknown event!",
);
return;
}
return 1;
}
1;

View File

@@ -0,0 +1,452 @@
# --
# 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::ITSMChange::Event::Notification;
use strict;
use warnings;
our @ObjectDependencies = (
'Kernel::System::Group',
'Kernel::System::ITSMChange',
'Kernel::System::ITSMChange::History',
'Kernel::System::ITSMChange::ITSMWorkOrder',
'Kernel::System::ITSMChange::Notification',
'Kernel::System::LinkObject',
'Kernel::System::Log',
);
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Data Event Config UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# do not modify the original event, because we need this unmodified in later event modules
my $Event = $Param{Event};
# in history event handling we use Event name without the trailing 'Post'
$Event =~ s{ Post \z }{}xms;
# distinguish between Change and WorkOrder events, based on naming convention
my $Type;
if ( $Event =~ m{ \A (Change|ActionExecute) }xms ) {
$Type = 'Change';
}
elsif ( $Event =~ m{ \A WorkOrder }xms ) {
$Type = 'WorkOrder';
}
else {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Could not determine the object type for the event '$Event'!",
);
return;
}
# get the event id, for looking up the list of relevant rules
my $EventID = $Kernel::OM->Get('Kernel::System::ITSMChange::History')->HistoryTypeLookup(
HistoryType => $Event,
);
if ( !$EventID ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Encountered unknown event '$Event'!",
);
return;
}
my $NotificationRuleIDs = $Kernel::OM->Get('Kernel::System::ITSMChange::Notification')->NotificationRuleSearch(
EventID => $EventID,
);
if ( !$NotificationRuleIDs ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Could not get notification rules for the event '$Event'!",
);
return;
}
# in case of an update, we have the old data for comparison
my $OldData = $Param{Data}->{"Old${Type}Data"};
# The notification rules are based on names, while the ChangeUpdate-Function
# primarily cares about IDs. So there needs to be a mapping.
my %Name2ID = (
ChangeState => 'ChangeStateID',
WorkOrderState => 'WorkOrderStateID',
);
# loop over the notification rules and check the condition
RULEID:
for my $RuleID ( @{$NotificationRuleIDs} ) {
my $Rule = $Kernel::OM->Get('Kernel::System::ITSMChange::Notification')->NotificationRuleGet(
ID => $RuleID,
);
my $Attribute = $Rule->{Attribute} || '';
if ( $Name2ID{$Attribute} ) {
$Attribute = $Name2ID{$Attribute};
}
# no notification if the attribute is not relevant
if ( $Attribute && !exists $Param{Data}->{$Attribute} ) {
next RULEID;
}
# in case of an update, check whether the attribute has changed
if (
$Attribute
&& ( $Event eq 'ChangeUpdate' || $Event eq 'WorkOrderUpdate' )
)
{
my $HasChanged = $Self->_HasFieldChanged(
New => $Param{Data}->{$Attribute},
Old => $OldData->{$Attribute},
);
next RULEID if !$HasChanged;
}
# get the string to match against
# TODO: support other combinations, maybe use GeneralCatalog directly
my $NewFieldContent = $Attribute ? $Param{Data}->{$Attribute} : '';
if ( $Attribute eq 'ChangeStateID' ) {
$NewFieldContent = $Kernel::OM->Get('Kernel::System::ITSMChange')->ChangeStateLookup(
ChangeStateID => $NewFieldContent,
);
}
elsif ( $Attribute eq 'WorkOrderStateID' ) {
$NewFieldContent = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMWorkOrder')->WorkOrderStateLookup(
WorkOrderStateID => $NewFieldContent,
);
}
# should the notification be sent ?
# the x-modifier is harmful here, as $Rule->{Rule} can contain spaces
if (
defined $Rule->{Rule}
&& defined $NewFieldContent
&& $NewFieldContent !~ m/^$Rule->{Rule}$/
)
{
next RULEID;
}
# determine list of agents and customers
my $AgentAndCustomerIDs = $Self->_AgentAndCustomerIDsGet(
Recipients => $Rule->{Recipients},
Type => $Type,
Event => $Event,
ChangeID => $Param{Data}->{ChangeID},
WorkOrderID => $Param{Data}->{WorkOrderID},
OldData => $OldData,
UserID => $Param{UserID},
);
next RULEID if !$AgentAndCustomerIDs;
$Kernel::OM->Get('Kernel::System::ITSMChange::Notification')->NotificationSend(
%{$AgentAndCustomerIDs},
Type => $Type,
Event => $Event,
UserID => $Param{UserID},
Data => {
%{ $Param{Data} }, # do not pass as reference, as it would influence later events!
},
Message => $Rule->{Message},
);
}
return 1;
}
=begin Internal:
=head2 _HasFieldChanged()
This method checks whether a field was changed or not. It returns 1 when field
was changed, 0 otherwise
my $FieldHasChanged = $NotificationEventObject->_HasFieldChanged(
Old => 'old value', # can be array reference or hash reference as well
New => 'new value', # can be array reference or hash reference as well
);
=cut
sub _HasFieldChanged {
my ( $Self, %Param ) = @_;
# field has changed when either 'new' or 'old is not set
return 1 if !( $Param{New} && $Param{Old} ) && ( $Param{New} || $Param{Old} );
# field has not changed when both values are empty
return if !$Param{New} && !$Param{Old};
# return result of 'eq' when both params are scalars
return $Param{New} ne $Param{Old} if !ref( $Param{New} ) && !ref( $Param{Old} );
# a field has changed when 'ref' is different
return 1 if ref( $Param{New} ) ne ref( $Param{Old} );
# check hashes
if ( ref $Param{New} eq 'HASH' ) {
# field has changed when number of keys are different
return 1 if scalar keys %{ $Param{New} } != scalar keys %{ $Param{Old} };
# check the values for each key
for my $Key ( sort keys %{ $Param{New} } ) {
return 1 if $Param{New}->{$Key} ne $Param{Old}->{$Key};
}
}
# check arrays
if ( ref $Param{New} eq 'ARRAY' ) {
# changed when number of elements differ
return 1 if scalar @{ $Param{New} } != scalar @{ $Param{Old} };
# check each element
for my $Index ( 0 .. $#{ $Param{New} } ) {
return 1 if $Param{New}->[$Index] ne $Param{Old}->[$Index];
}
}
# field has not been changed
return 0;
}
=head2 _AgentAndCustomerIDsGet()
Get the agent and customer IDs from the recipient list.
my $AgentAndCustomerIDs = $HistoryObject->_AgentAndCustomerIDsGet(
Recipients => ['ChangeBuilder', 'ChangeManager'],
);
returns
$AgentAndCustomerIDs = {
AgentIDs => [ 2, 4 ],
CustomerIDs => [],
};
=cut
sub _AgentAndCustomerIDsGet {
my ( $Self, %Param ) = @_;
my $WorkOrderAgentID;
if ( $Param{Type} eq 'WorkOrder' ) {
# check WorkOrderID
if ( !$Param{WorkOrderID} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "The param 'WorkOrderID' is required for WorkOrder events!",
);
}
elsif ( $Param{Event} eq 'WorkOrderDelete' ) {
# the workorder is already deleted, so we look at the OldData
$Param{ChangeID} = $Param{OldData}->{ChangeID};
$WorkOrderAgentID = $Param{OldData}->{WorkOrderAgentID};
}
else {
# get ChangeID and WorkOrderAgentID from the WorkOrder,
# the WorkOrderAgent might have been recently updated
my $WorkOrder = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMWorkOrder')->WorkOrderGet(
WorkOrderID => $Param{WorkOrderID},
UserID => $Param{UserID},
);
$Param{ChangeID} = $WorkOrder->{ChangeID};
$WorkOrderAgentID = $WorkOrder->{WorkOrderAgentID};
}
}
# these arrays will be returned
my ( @AgentIDs, @CustomerIDs );
# needed for determining the actual recipients
my $Change = $Kernel::OM->Get('Kernel::System::ITSMChange')->ChangeGet(
ChangeID => $Param{ChangeID},
UserID => $Param{UserID},
);
return if !$Change;
return if ref $Change ne 'HASH';
return if !%{$Change};
for my $Recipient ( @{ $Param{Recipients} } ) {
if ( $Recipient eq 'ChangeBuilder' || $Recipient eq 'ChangeManager' ) {
# take the builder or manager from the current change data
push @AgentIDs, $Change->{ $Recipient . 'ID' };
}
elsif ( $Recipient eq 'OldChangeBuilder' || $Recipient eq 'OldChangeManager' ) {
if ( $Param{Event} ne 'ChangeUpdate' ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Recipient $Recipient is only valid for ChangeUpdate events, "
. "but the event was a '$Param{Event}' event!",
);
}
else {
# take the builder or manager from the original change data
$Recipient =~ s{ \A Old }{}xms;
push @AgentIDs, $Param{OldData}->{ $Recipient . 'ID' };
}
}
elsif ( $Recipient eq 'CABCustomers' ) {
push @CustomerIDs, @{ $Change->{CABCustomers} };
}
elsif ( $Recipient eq 'CABAgents' ) {
push @AgentIDs, @{ $Change->{CABAgents} };
}
elsif ( $Recipient eq 'WorkOrderAgent' ) {
if ( $Param{Type} ne 'WorkOrder' ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Recipient $Recipient is only valid for workorder events "
. "but the event was a '$Param{Event}' event!",
);
}
else {
push @AgentIDs, $WorkOrderAgentID;
}
}
elsif ( $Recipient eq 'OldWorkOrderAgent' ) {
if ( $Param{Event} ne 'WorkOrderUpdate' ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Recipient $Recipient is only valid for WorkOrderUpdate events "
. "but the event was a '$Param{Event}' event!",
);
}
else {
# take the workorder agent from the original workorder data
$Recipient =~ s{ \A Old }{}xms;
push @AgentIDs, $Param{OldData}->{ $Recipient . 'ID' };
}
}
elsif ( $Recipient eq 'WorkOrderAgents' ) {
# loop over the workorders of a change and get their workorder agents
for my $WorkOrderID ( @{ $Change->{WorkOrderIDs} } ) {
my $WorkOrder = $Kernel::OM->Get('Kernel::System::ITSMChange::ITSMWorkOrder')->WorkOrderGet(
WorkOrderID => $WorkOrderID,
UserID => $Param{UserID},
);
push @AgentIDs, $WorkOrder->{WorkOrderAgentID};
}
}
elsif ( $Recipient eq 'ChangeInitiators' ) {
# get linked objects which are directly linked with this change object
my $LinkListWithData = $Kernel::OM->Get('Kernel::System::LinkObject')->LinkListWithData(
Object => 'ITSMChange',
Key => $Param{ChangeID},
State => 'Valid',
UserID => $Param{UserID},
);
# get change initiators (customer users of linked tickets)
# This should be the same list a displayed in ChangeZoom.
my $LinkList = $LinkListWithData->{Ticket} || {};
for my $LinkType ( sort keys %{$LinkList} ) {
# the linked tickets are always the 'Source'.
for my $TicketData ( values %{ $LinkList->{$LinkType}->{Source} } ) {
# The data for the linked ticket can have a customer id.
# If it doesn't, fall back to the owner.
if ( $TicketData->{CustomerUserID} ) {
push @CustomerIDs, $TicketData->{CustomerUserID};
}
else {
push @AgentIDs, $TicketData->{OwnerID};
}
}
}
}
elsif ( $Recipient =~ m{ \A GroupITSMChange(|Builder|Manager) \z }xms ) {
my %Recipient2Group = (
GroupITSMChange => 'itsm-change',
GroupITSMChangeBuilder => 'itsm-change-builder',
GroupITSMChangeManager => 'itsm-change-manager',
);
# get group id
my $GroupID = $Kernel::OM->Get('Kernel::System::Group')->GroupLookup(
Group => $Recipient2Group{$Recipient}
);
# get members of group
my %Users = $Kernel::OM->Get('Kernel::System::Group')->GroupMemberList(
GroupID => $GroupID,
Type => 'ro',
Result => 'HASH',
Cached => 1,
);
push @AgentIDs, keys %Users;
}
else {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Unknown recipient '$Recipient'!",
);
return;
}
}
# no need to eliminate duplicates, NotificationSend() takes care of that
# remove empty IDs
@AgentIDs = grep {$_} @AgentIDs;
@CustomerIDs = grep {$_} @CustomerIDs;
my %AgentAndCustomerIDs = (
AgentIDs => \@AgentIDs,
CustomerIDs => \@CustomerIDs,
);
return \%AgentAndCustomerIDs;
}
1;
=end Internal:

View File

@@ -0,0 +1,119 @@
# --
# 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::ITSMChange::Event::ToolBarChangeManagerCacheDelete;
use strict;
use warnings;
our @ObjectDependencies = (
'Kernel::System::Cache',
'Kernel::System::Log',
);
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Data Event Config UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# set the cache type prefix
my $CacheTypePrefix = 'ITSMChangeManagementToolBarChangeManager';
# handle adding of a change
if ( $Param{Event} eq 'ChangeAddPost' ) {
# do nothing if the ChangeManagerID was not set
return 1 if !$Param{Data}->{ChangeManagerID};
# set the cache type
my $CacheType = $CacheTypePrefix . $Param{Data}->{ChangeManagerID};
# delete the cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $CacheType,
);
return 1;
}
# handle update of a change
elsif ( $Param{Event} eq 'ChangeUpdatePost' ) {
# make sure the data is initialized
$Param{Data}->{ChangeManagerID} ||= '';
$Param{Data}->{OldChangeData}->{ChangeManagerID} ||= '';
# do nothing if the ChangeManagerID did not change
return 1
if $Param{Data}->{ChangeManagerID} eq $Param{Data}->{OldChangeData}->{ChangeManagerID};
# set the cache type postfix
my @CacheTypePostfixes = (
$Param{Data}->{ChangeManagerID},
$Param{Data}->{OldChangeData}->{ChangeManagerID},
);
# delete the cache for the old and the current change manager
CACHETYPEPOSTFIX:
for my $CacheTypePostfix (@CacheTypePostfixes) {
# do nothing if the ChangeManagerID was not set
next CACHETYPEPOSTFIX if !$CacheTypePostfix;
# set the cache type
my $CacheType = $CacheTypePrefix . $CacheTypePostfix;
# delete the cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $CacheType,
);
}
return 1;
}
# handle deleting a change
elsif ( $Param{Event} eq 'ChangeDeletePost' ) {
# do nothing if the ChangeManagerID was not set
return 1 if !$Param{Data}->{OldChangeData}->{ChangeManagerID};
# set the cache type
my $CacheType = $CacheTypePrefix . $Param{Data}->{OldChangeData}->{ChangeManagerID};
# delete the cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $CacheType,
);
return 1;
}
return 1;
}
1;

View File

@@ -0,0 +1,114 @@
# --
# 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::ITSMChange::Event::ToolBarMyCABCacheDelete;
use strict;
use warnings;
our @ObjectDependencies = (
'Kernel::System::Cache',
'Kernel::System::Log',
);
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Data Event Config UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# set the cache type prefix
my $CacheTypePrefix = 'ITSMChangeManagementToolBarMyCAB';
# handle update of a CAB
if ( $Param{Event} eq 'ChangeCABUpdatePost' ) {
# do nothing if the CABAgents were not updated
return 1 if !$Param{Data}->{CABAgents};
# make sure the data is initialized
$Param{Data}->{CABAgents} ||= [];
$Param{Data}->{OldChangeCABData}->{CABAgents} ||= [];
# build lookup hash for CABAgents from "new" and "old" Agents
my %ChangedCABAgentsLookup;
for my $CABAgent (
@{ $Param{Data}->{CABAgents} },
@{ $Param{Data}->{OldChangeCABData}->{CABAgents} }
)
{
$ChangedCABAgentsLookup{$CABAgent}++;
}
# find the CABAgents which have been changed, which are only agents with a count of exactly one
my @ChangedCABAgents;
for my $CABAgent ( sort keys %ChangedCABAgentsLookup ) {
if ( $ChangedCABAgentsLookup{$CABAgent} == 1 ) {
push @ChangedCABAgents, $CABAgent;
}
}
# delete cache for all changed CABAgents
for my $CABAgent (@ChangedCABAgents) {
# set the cache type
my $CacheType = $CacheTypePrefix . $CABAgent;
# delete the cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $CacheType,
);
}
return 1;
}
# handle deleting a CAB
elsif ( $Param{Event} eq 'ChangeCABDeletePost' ) {
# do nothing if there were no CABAgents set
return 1 if !$Param{Data}->{OldChangeCABData}->{CABAgents};
return 1 if !@{ $Param{Data}->{OldChangeCABData}->{CABAgents} };
# delete cache for all CABAgents
for my $CABAgent ( @{ $Param{Data}->{OldChangeCABData}->{CABAgents} } ) {
# set the cache type
my $CacheType = $CacheTypePrefix . $CABAgent;
# delete the cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $CacheType,
);
}
return 1;
}
return 1;
}
1;

View File

@@ -0,0 +1,119 @@
# --
# 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::ITSMChange::Event::ToolBarMyChangesCacheDelete;
use strict;
use warnings;
our @ObjectDependencies = (
'Kernel::System::Cache',
'Kernel::System::Log',
);
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# check needed stuff
for my $Argument (qw(Data Event Config UserID)) {
if ( !$Param{$Argument} ) {
$Kernel::OM->Get('Kernel::System::Log')->Log(
Priority => 'error',
Message => "Need $Argument!",
);
return;
}
}
# set the cache type prefix
my $CacheTypePrefix = 'ITSMChangeManagementToolBarMyChanges';
# handle adding of a change
if ( $Param{Event} eq 'ChangeAddPost' ) {
# do nothing if the ChangeBuilderID was not set
return 1 if !$Param{Data}->{ChangeBuilderID};
# set the cache type
my $CacheType = $CacheTypePrefix . $Param{Data}->{ChangeBuilderID};
# delete the cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $CacheType,
);
return 1;
}
# handle update of a change
elsif ( $Param{Event} eq 'ChangeUpdatePost' ) {
# make sure the data is initialized
$Param{Data}->{ChangeBuilderID} ||= '';
$Param{Data}->{OldChangeData}->{ChangeBuilderID} ||= '';
# do nothing if the ChangeBuilderID did not change
return 1
if $Param{Data}->{ChangeBuilderID} eq $Param{Data}->{OldChangeData}->{ChangeBuilderID};
# set the cache type postfix
my @CacheTypePostfixes = (
$Param{Data}->{ChangeBuilderID},
$Param{Data}->{OldChangeData}->{ChangeBuilderID},
);
# delete the cache for the old and the current change builder
CACHETYPEPOSTFIX:
for my $CacheTypePostfix (@CacheTypePostfixes) {
# do nothing if the ChangeBuilderID was not set
next CACHETYPEPOSTFIX if !$CacheTypePostfix;
# set the cache type
my $CacheType = $CacheTypePrefix . $CacheTypePostfix;
# delete the cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $CacheType,
);
}
return 1;
}
# handle deleting a change
elsif ( $Param{Event} eq 'ChangeDeletePost' ) {
# do nothing if the ChangeBuilderID was not set
return 1 if !$Param{Data}->{OldChangeData}->{ChangeBuilderID};
# set the cache type
my $CacheType = $CacheTypePrefix . $Param{Data}->{OldChangeData}->{ChangeBuilderID};
# delete the cache
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => $CacheType,
);
return 1;
}
return 1;
}
1;