Ran into this topic aswell while searching for a solution:
I wanto update Parenttickets automatically when something is happening in their Childs. So Im working on implementing the solution from ndhvu275.
I understood your approach with the AgentTicketActionCommon.pm as one premature solution. So I was driving with you event approach from the beginning.
I created a file here:
OTRS path/Kernel/Config/Files/UpdateToParent.xml
Code: Select all
<?xml version="1.0" encoding="utf-8" ?>
<otrs_config version="1.0" init="Changes">
<ConfigItem Name="Ticket::EventModulePost###UpdateToParent"
Required="0" Valid="1">
<Description Lang="en">Description</Description>
<Group>UpdateToParent</Group>
<SubGroup>UpdateToParent</SubGroup>
<Setting>
<Hash>
<Item
Key="Module">Kernel::System::Ticket::Event::UpdateToParent</Item>
<Item Key="Event">(ArticleCreate|TicketOwnerUpdate|TicketMerge|TicketCustomerUpdate|TicketStateUpdate)</Item>
</Hash>
</Setting>
</ConfigItem>
</otrs_config>
and here:
OTRS path/Custom/Kernel/Modules/AgentTicketChecklist.pm
Code: Select all
# --
# Kernel/System/Ticket/Event/UpdateToParent.pm - event module
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information.
# --
package Kernel::System::Ticket::Event::UpdateToParent;
use strict;
use warnings;
use Kernel::System::LinkObject;
sub new {
my ( $Type, %Param ) = @_;
# allocate new hash for object
my $Self = {};
bless( $Self, $Type );
# get needed objects
for (qw(ConfigObject TicketObject LogObject UserObject)) {
$Self->{$_} = $Param{$_} || die "Got no $_!";
}
$Self->{LinkObject} = Kernel::System::LinkObject->new(%Param);
return $Self;
}
sub Run {
my ( $Self, %Param ) = @_;
# check needed stuff
for (qw(Data Event Config)) {
if ( !$Param{$_} ) {
$Self->{LogObject}->Log( Priority => 'error', Message => "Need $_!" );
return;
}
}
if ( $Param{Event} eq 'TicketStateUpdate' ) { #catch the event of updating ticket state
# check the existing of parent tickets
my %LinkList = $Self->{LinkObject}->LinkKeyListWithData(
Object1 => 'Ticket',
Key1 => $Param{Data}->{TicketID}, #current TicketID
Object2 => 'Ticket',
Type => 'ParentChild',
Direction => 'Source',
State => 'Valid',
UserID => 1,
);
if (%LinkList) {
# get child ticket object
my %ChildTicket = $Self->{TicketObject}->TicketGet(
TicketID => $Param{Data}->{TicketID},
UserID => 1,
);
# get Article Types will be migrated from sysconfig
my %ArticleTypes = %{ $Self->{ConfigObject}->Get("Ticket::ArticleTypeOnChild") };
my @TypeOfArticleConfig;
while (my ($key, $value) = each %ArticleTypes) {
if ($value) {
push(@TypeOfArticleConfig, $key);
}
}
# get all Articles of child ticket will be migrated
my @Articles = $Self->{TicketObject}->ArticleContentIndex(
TicketID => $Param{Data}->{TicketID},
UserID => 1,
ArticleType => \@TypeOfArticleConfig,
);
# get the number of Articles will be migrated from sysconfig
my $ArticleNumbers = 0;
if ($ChildTicket{StateType} eq 'closed') {
$ArticleNumbers = $Self->{ConfigObject}->Get("Ticket::NumberRecentArticleOnCloseChild");
}
else {
$ArticleNumbers = $Self->{ConfigObject}->Get("Ticket::NumberRecentArticleOnPendingChild");
}
# get number of recent articles in config
my @RecentArticles;
foreach (reverse @Articles) {
push(@RecentArticles, $_);
$ArticleNumbers--;
last if $ArticleNumbers<=0;
}
# get mapping states of parent and child ticket from sysconfig
my %MappingState = %{ $Self->{ConfigObject}->Get("Ticket::ChildParentStateMapping") };
# get state will be update for parent
my $StateParent;
if ($ChildTicket{State}) {
$StateParent = $MappingState{$ChildTicket{State}};
}
# performed by OTRS Event
#my %User = $Self->{UserObject}->GetUserData(UserID => $EventUserID,);
# performed by current user
my %User = $Self->{UserObject}->GetUserData(UserID => $Param{UserID},);
my $From = "$User{UserFirstname} $User{UserLastname} <$User{UserEmail}>";
# migrate foreach parent ticket
for my $ParentTicketID ( keys %LinkList ) {
# need to check parent ticket is not master ticket only, a slave is still accepted
my %ParentTicket = $Self->{TicketObject}->TicketGet(
TicketID => $ParentTicketID,
DynamicFields => 1,
UserID => 1,
);
next if (($ParentTicket{DynamicField_MasterSlave}) and ($ParentTicket{DynamicField_MasterSlave}) !~ m/^Slave.*/);
# push articles of child to parents
for my $Article (reverse @RecentArticles) {
# create article for parent ticket
my $ArticleID = $Self->{TicketObject}->ArticleCreate(
TicketID => $ParentTicketID,
ArticleType => $Article->{ArticleType}, # email-external|email-internal|phone|fax|...
SenderType => $Article->{SenderType}, # agent|system|customer
From => $From, # not required but useful
To => $Article->{To}, # not required but useful
Cc => $Article->{Cc}, # not required but useful
ReplyTo => $Article->{ReplyTo}, # not required
Subject => $Article->{Subject}." [Task#".$ChildTicket{TicketNumber}."]", # required
Body => $Article->{Body}, # required
MessageID => $Article->{MessageID}, # not required but useful
InReplyTo => $Article->{InReplyTo}, # not required but useful
References => $Article->{References}, # not required but useful
ContentType => $Article->{ContentType}, # or optional Charset & MimeType
HistoryType => 'OwnerUpdate', # EmailCustomer|Move|AddNote|PriorityUpdate|WebRequestCustomer|...
HistoryComment => 'Article from child ticket',
UserID => $Param{UserID},
NoAgentNotify => $Article->{NoAgentNotify}, # if you don't want to send agent notifications
AutoResponseType => $Article->{AutoResponseType}, # auto reject|auto follow up|auto reply/new ticket|auto remove
ForceNotificationToUserID => $Article->{ForceNotificationToUserID}, # if you want to force somebody
ExcludeNotificationToUserID => $Article->{ExcludeNotificationToUserID}, # if you want full exclude somebody from notfications,
# will also be removed in To: line of article,
# higher prio as ForceNotificationToUserID
ExcludeMuteNotificationToUserID => $Article->{ExcludeMuteNotificationToUserID}, # the same as ExcludeNotificationToUserID but only the
# sending gets muted, agent will still shown in To:
# line of article
);
}
# update state for parent ticket
if ($StateParent) {
$Self->{TicketObject}->TicketStateSet(
TicketID => $ParentTicketID,
State => $StateParent,
UserID => $Param{UserID},
);
}
}
}
}
return 1;
}
1;
In the SysConfig, I am able to select the new Event Module and see my config out of the XML file. All seems to look good from scratch, but still...
I see alot of Error entries in the SysLog:
[...]
Thu Oct 8 14:24:55 2015 error OTRS-CGI-25 Need module!
[...]
In the end, no update is made to the parent. Is it maybe due to the fact that the UpdateToParent module is using objects that are not standard?
Like
NumberRecentArticleOnCloseChildor other?
Is it even necessary to create the mentioned XML file? I read in the OTRS manual about custom Events that it may not be needed.
All in all im pretty newbie to the pearl modules.
Any reply, and if it is just a more informative logfile would be highly appreciated.
Thanks