[otrs-cvs] CVS: ITSMCMDB/Kernel/Modules AgentLinkObject.pm, NONE,
1.1 AgentTicketZoom.pm,NONE,1.1
cvs-log at otrs.org
cvs-log at otrs.org
Tue Dec 12 17:30:31 CET 2006
Update of /home/cvs/ITSMCMDB/Kernel/Modules
In directory lancelot:/tmp/cvs-serv1329/Kernel/Modules
Added Files:
AgentLinkObject.pm AgentTicketZoom.pm
Log Message:
add ticket link mechanism
--- NEW FILE ---
# --
# Kernel/Modules/AgentLinkObject.pm - the ticket link frontend module
# Copyright (C) 2003-2006 OTRS GmbH, http://otrs.com/
# --
# $Id: AgentLinkObject.pm,v 1.1 2006/12/12 16:30:29 mh Exp $
# --
# 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 http://www.gnu.org/licenses/gpl.txt.
# --
package Kernel::Modules::AgentLinkObject;
use strict;
use Kernel::System::ITSMCMDB;
use Kernel::System::LinkObject2;
use Kernel::System::CustomerUser;
use vars qw($VERSION);
$VERSION = '$Revision: 1.1 $';
$VERSION =~ s/^\$.*:\W(.*)\W.+?$/$1/;
sub new {
my $Type = shift;
my %Param = @_;
# allocate new hash for object
my $Self = {};
bless ($Self, $Type);
foreach (keys %Param) {
$Self->{$_} = $Param{$_};
}
# check needed Opjects
foreach (qw(ParamObject DBObject LayoutObject LogObject ConfigObject TicketObject)) {
if (!$Self->{$_}) {
$Self->{LayoutObject}->FatalError(Message => "Got no $_!")
}
}
$Self->{ITSMCMDBObject} = Kernel::System::ITSMCMDB->new(%Param);
$Self->{LinkObject2Object} = Kernel::System::LinkObject2->new(%Param);
$Self->{CustomerUserObject} = Kernel::System::CustomerUser->new(%Param);
return $Self;
}
sub Run {
my $Self = shift;
my %Param = @_;
my $Output;
# ------------------------------------------------------------ #
# record link save
# ------------------------------------------------------------ #
if ($Self->{Subaction} eq 'RecordLinkSave') {
my $ConfigItem = $Self->{ParamObject}->GetParam(Param => "ConfigItem");
my $RecordID = $Self->{ParamObject}->GetParam(Param => "RecordID");
my $BObject = $Self->{ParamObject}->GetParam(Param => "BObject");
my @BKeys = $Self->{ParamObject}->GetArray(Param => "BKey");
my $RelationType = $Self->{ParamObject}->GetParam(Param => "RelationType");
# check needed stuff
if (!$ConfigItem || !$RecordID || !$BObject) {
$Self->{LogObject}->Log(Priority => 'error', Message => "Need ConfigItem, RecordID and BObject!");
return $Self->{LayoutObject}->Redirect(OP => "Action=$Self->{Action}");
}
foreach my $BKey (@BKeys) {
my %LinkData;
if ($RelationType =~ /^Parent\:\:(.*)$/) {
$LinkData{LinkType} = $1,
$LinkData{ParentObject} = $ConfigItem,
$LinkData{ParentKey} = $RecordID,
$LinkData{ChildObject} = $BObject,
$LinkData{ChildKey} = $BKey,
}
elsif ($RelationType =~ /^Child\:\:(.*)$/) {
$LinkData{LinkType} = $1,
$LinkData{ParentObject} = $BObject,
$LinkData{ParentKey} = $BKey,
$LinkData{ChildObject} = $ConfigItem,
$LinkData{ChildKey} = $RecordID,
}
else {
last;
next;
}
$Self->{LinkObject2Object}->LinkAdd(
ValidID => 1,
%LinkData,
);
}
# redirect
return $Self->{LayoutObject}->Redirect(
OP => "Action=AgentTicketZoom&TicketID=$RecordID"
);
}
# ------------------------------------------------------------ #
# overview
# ------------------------------------------------------------ #
my $ConfigItem = $Self->{ParamObject}->GetParam(Param => "SourceObject");
my $RecordID = $Self->{ParamObject}->GetParam(Param => "SourceID");
my $BObject = $Self->{ParamObject}->GetParam(Param => "BObject");
my $Search = $Self->{ParamObject}->GetParam(Param => "Search");
# check needed stuff
if (!$ConfigItem || !$RecordID) {
$Self->{LogObject}->Log(Priority => 'error', Message => "Need SourceObject and SourceID!");
return $Self->{LayoutObject}->Redirect(OP => "");
}
$Output = $Self->{LayoutObject}->Header(Title => 'Record Link');
$Output .= $Self->{LayoutObject}->NavigationBar();
my $RecordIDHuman = '';
if ($ConfigItem eq 'Ticket') {
my %SourceTicket = $Self->{TicketObject}->TicketGet(
TicketID => $RecordID,
);
$RecordIDHuman = $SourceTicket{TicketNumber};
}
# get link partner
my @LinkMapPartnerObject = $Self->{LinkObject2Object}->LinkMapPartnerObjectGet(
Object => $ConfigItem,
);
my %LinkMapPartnerObject;
foreach (@LinkMapPartnerObject) {
$LinkMapPartnerObject{$_} = $_;
}
# create pulldown
my $BObjectStr = $Self->{LayoutObject}->OptionStrgHashRef(
Name => 'BObject',
SelectedID => $BObject || '',
Data => \%LinkMapPartnerObject,
);
# output block
$Self->{LayoutObject}->Block(
Name => 'RecordLink',
Data => {
ConfigItem => $ConfigItem,
RecordID => $RecordID,
RecordIDHuman => $RecordIDHuman,
BObjectStr => $BObjectStr,
},
);
if ($BObject) {
# output block
$Self->{LayoutObject}->Block(
Name => 'RecordLinkSearch',
Data => {
ConfigItem => $ConfigItem,
RecordID => $RecordID,
BObject => $BObject,
},
);
my $SearchAttributeRef = $Self->{LinkObject2Object}->LinkPartnerSearchAttributeGet(
Object => $BObject,
);
foreach my $Attribute (@{$SearchAttributeRef}) {
if ($Attribute->{InputType} eq 'SelectMulti') {
my @SelectedID;
if ($Search) {
@SelectedID = $Self->{ParamObject}->GetArray(Param => $Attribute->{InputName});
$Attribute->{SearchData} = \@SelectedID;
}
my $InputStr = $Self->{LayoutObject}->OptionStrgHashRef(
Name => $Attribute->{InputName},
Data => \%{$Attribute->{InputData}},
Multiple => 1,
Size => 5,
SelectedIDRefArray => \@SelectedID,
);
# output block
$Self->{LayoutObject}->Block(
Name => 'RecordLinkSearchRow',
Data => {
InputStr => $InputStr,
Name => $Attribute->{Name},
},
);
}
else {
my $Value;
if ($Search) {
$Value = $Self->{ParamObject}->GetParam(Param => $Attribute->{InputName});
$Attribute->{SearchData} = $Value;
}
# output block
$Self->{LayoutObject}->Block(
Name => 'RecordLinkSearchRowTextInput',
Data => {
InputName => $Attribute->{InputName},
Name => $Attribute->{Name},
Value => $Value,
},
);
}
}
if ($Search) {
my $ResultIDs = $Self->{LinkObject2Object}->LinkPartnerSearch(
Object => $BObject,
SearchAttributeRef => $SearchAttributeRef,
);
my @LinkTypes = $Self->{LinkObject2Object}->LinkMapLinkTypeGet(
AObject => $ConfigItem,
BObject => $BObject,
);
my %RelationTypesTmp;
foreach (@LinkTypes) {
my %LinkType = $Self->{LinkObject2Object}->LinkTypeLookup(
LinkType => $_,
);
$RelationTypesTmp{'Parent::' . $_} = $LinkType{ParentName};
$RelationTypesTmp{'Child::' . $_} = $LinkType{ChildName};
}
my %RelationTypesTmp2;
foreach (sort keys %RelationTypesTmp) {
$RelationTypesTmp2{$RelationTypesTmp{$_}} = $_;
}
my %RelationTypes;
foreach (sort keys %RelationTypesTmp2) {
$RelationTypes{$RelationTypesTmp2{$_}} = $_;
}
my $RelationTypeStr = $Self->{LayoutObject}->OptionStrgHashRef(
Data => \%RelationTypes,
Name => 'RelationType',
);
# output block
$Self->{LayoutObject}->Block(
Name => 'RecordLinkResult',
Data => {
ConfigItem => $ConfigItem,
RecordID => $RecordID,
RelationTypeStr => $RelationTypeStr,
BObject => $BObject,
},
);
# get output attributes
my $OutputAttributes = $Self->{ConfigObject}->Get('CMDB::OutputAttributes::AgentITSMCMDB')->{$BObject};
if ($OutputAttributes && ref($OutputAttributes) eq 'ARRAY') {
# output header columns
foreach my $Attribute (@{$OutputAttributes}) {
if (!$Attribute->{Attribute} || ($Attribute->{Type} && $Attribute->{Type} eq 'RelationType')) {
next;
}
if ($Attribute && ref($Attribute) eq 'HASH') {
# output row column
$Self->{LayoutObject}->Block(
Name => 'RecordLinkResultColumn',
Data => {
Content => $Attribute->{Output} || $Attribute->{Attribute},
}
);
}
}
}
# output records
foreach my $BKey (@{$ResultIDs}) {
if ($ConfigItem eq $BObject && $RecordID eq $BKey) {
next;
}
# set output class
if ($Param{Class} && $Param{Class} eq 'searchpassive') {
$Param{Class} = 'searchactive';
}
else {
$Param{Class} = 'searchpassive';
}
# get partner data
my %Partner = $Self->{LinkObject2Object}->LinkPartnerGet(
Object => $BObject,
Key => $BKey,
);
# next LinkID, if no partner found
if (!%Partner) {
next;
}
# output record
$Self->{LayoutObject}->Block(
Name => 'RecordLinkResultRow',
Data => {
ConfigItem => $BObject,
BKey => $BKey,
Class => $Param{Class},
},
);
foreach my $Attribute (@{$OutputAttributes}) {
if ($Attribute && ref($Attribute) eq 'HASH') {
if (!$Attribute->{Attribute} || ($Attribute->{Type} && $Attribute->{Type} eq 'RelationType')) {
next;
}
if ($Attribute->{Type} && $Attribute->{Type} eq 'ID') {
# get idhyperlink
my $IDHyperlink = $Self->{LinkObject2Object}->LinkPartnerKeyHyperlinkGet(
Object => $BObject,
Key => $BKey,
);
# output hyperlink
$Self->{LayoutObject}->Block(
Name => 'RecordLinkResultRowHyperlink',
Data => {
Key => $Partner{$Attribute->{Attribute}} || '',
KeyHyperlink => $IDHyperlink,
Class => $Param{Class},
}
);
}
else {
# output row column
$Self->{LayoutObject}->Block(
Name => 'RecordLinkResultRowColumn',
Data => {
Content => $Partner{$Attribute->{Attribute}} || '-',
Class => $Param{Class},
}
);
}
}
}
}
}
}
$Output .= $Self->{LayoutObject}->Output(
TemplateFile => 'AgentLinkObject',
Data => {
%Param,
},
);
$Output .= $Self->{LayoutObject}->Footer();
return $Output;
}
1;
--- NEW FILE ---
# --
# Kernel/Modules/AgentTicketZoom.pm - to get a closer view
# Copyright (C) 2003-2006 OTRS GmbH, http://otrs.com/
# --
# $Id: AgentTicketZoom.pm,v 1.1 2006/12/12 16:30:29 mh Exp $
# $OldId: AgentTicketZoom.pm,v 1.30 2006/12/07 14:03:58 martin Exp $
# --
# 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 http://www.gnu.org/licenses/gpl.txt.
# --
package Kernel::Modules::AgentTicketZoom;
use strict;
use Kernel::System::CustomerUser;
# ---
# ITSM
# ---
#use Kernel::System::LinkObject;
use Kernel::System::LinkObject2;
# ---
use vars qw($VERSION);
$VERSION = '$Revision: 1.1 $';
$VERSION =~ s/^\$.*:\W(.*)\W.+?$/$1/;
sub new {
my $Type = shift;
my %Param = @_;
# allocate new hash for object
my $Self = {};
bless ($Self, $Type);
foreach (keys %Param) {
$Self->{$_} = $Param{$_};
}
# check needed Opjects
foreach (qw(ParamObject DBObject TicketObject LayoutObject LogObject
QueueObject ConfigObject UserObject SessionObject)) {
if (!$Self->{$_}) {
$Self->{LayoutObject}->FatalError(Message => "Got no $_!");
}
}
# set debug
$Self->{Debug} = 0;
# get params
$Self->{ArticleID} = $Self->{ParamObject}->GetParam(Param => 'ArticleID');
$Self->{ZoomExpand} = $Self->{ParamObject}->GetParam(Param => 'ZoomExpand');
$Self->{ZoomExpandSort} = $Self->{ParamObject}->GetParam(Param => 'ZoomExpandSort');
if (!defined($Self->{ZoomExpand})) {
$Self->{ZoomExpand} = $Self->{ConfigObject}->Get('Ticket::Frontend::ZoomExpand');
}
if (!defined($Self->{ZoomExpandSort})) {
$Self->{ZoomExpandSort} = $Self->{ConfigObject}->Get('Ticket::Frontend::ZoomExpandSort');
}
$Self->{HighlightColor1} = $Self->{ConfigObject}->Get('HighlightColor1');
$Self->{HighlightColor2} = $Self->{ConfigObject}->Get('HighlightColor2');
# ticket id lookup
if (!$Self->{TicketID} && $Self->{ParamObject}->GetParam(Param => 'TicketNumber')) {
$Self->{TicketID} = $Self->{TicketObject}->TicketIDLookup(
TicketNumber => $Self->{ParamObject}->GetParam(Param => 'TicketNumber'),
UserID => $Self->{UserID},
);
}
# customer user object
$Self->{CustomerUserObject} = Kernel::System::CustomerUser->new(%Param);
# link object
# ---
# ITSM
# ---
# $Self->{LinkObjectObject} = Kernel::System::LinkObject->new(%Param);
$Self->{LinkObject2Object} = Kernel::System::LinkObject2->new(%Param);
# ---
return $Self;
}
sub Run {
my $Self = shift;
my %Param = @_;
my $Output;
# check needed stuff
if (!$Self->{TicketID}) {
return $Self->{LayoutObject}->ErrorScreen(
Message => "No TicketID is given!",
Comment => 'Please contact the admin.',
);
}
# check permissions
if (!$Self->{TicketObject}->Permission(
Type => 'ro',
TicketID => $Self->{TicketID},
UserID => $Self->{UserID})) {
# error screen, don't show ticket
return $Self->{LayoutObject}->NoPermission(WithHeader => 'yes');
}
# store last screen
if ($Self->{Subaction} ne 'ShowHTMLeMail') {
$Self->{SessionObject}->UpdateSessionID(
SessionID => $Self->{SessionID},
Key => 'LastScreenView',
Value => $Self->{RequestedURL},
);
}
# get content
my %Ticket = $Self->{TicketObject}->TicketGet(TicketID => $Self->{TicketID});
my @ArticleBox = $Self->{TicketObject}->ArticleContentIndex(TicketID => $Self->{TicketID});
# return if HTML email
if ($Self->{Subaction} eq 'ShowHTMLeMail') {
# check needed ArticleID
if (!$Self->{ArticleID}) {
return $Self->{LayoutObject}->ErrorScreen(Message => 'Need ArticleID!');
}
# get article data
my %Article = ();
foreach my $ArticleTmp (@ArticleBox) {
if ($ArticleTmp->{ArticleID} eq $Self->{ArticleID}) {
%Article = %{$ArticleTmp};
}
}
# check if article data exists
if (!%Article) {
return $Self->{LayoutObject}->ErrorScreen(Message => 'Invalid ArticleID!');
}
# if it is a html email, return here
return $Self->{LayoutObject}->Attachment(
Filename => $Self->{ConfigObject}->Get('Ticket::Hook')."-$Article{TicketNumber}-$Article{TicketID}-$Article{ArticleID}",
Type => 'inline',
ContentType => "$Article{MimeType}; charset=$Article{ContentCharset}",
Content => $Article{Body},
);
}
# else show normal ticket zoom view
# fetch all move queues
my %MoveQueues = $Self->{TicketObject}->MoveList(
TicketID => $Self->{TicketID},
UserID => $Self->{UserID},
Action => $Self->{Action},
Type => 'move_into',
);
# fetch all std. responses
my %StdResponses = $Self->{QueueObject}->GetStdResponses(QueueID => $Ticket{QueueID});
# customer info
my %CustomerData = ();
if ($Self->{ConfigObject}->Get('Ticket::Frontend::CustomerInfoZoom')) {
if ($Ticket{CustomerUserID}) {
%CustomerData = $Self->{CustomerUserObject}->CustomerUserDataGet(
User => $Ticket{CustomerUserID},
);
}
elsif ($Ticket{CustomerID}) {
%CustomerData = $Self->{CustomerUserObject}->CustomerUserDataGet(
CustomerID => $Ticket{CustomerID},
);
}
}
# generate output
$Output .= $Self->{LayoutObject}->Header(Value => $Ticket{TicketNumber});
$Output .= $Self->{LayoutObject}->NavigationBar();
# show ticket
$Output .= $Self->MaskAgentZoom(
MoveQueues => \%MoveQueues,
StdResponses => \%StdResponses,
ArticleBox => \@ArticleBox,
CustomerData => \%CustomerData,
TicketTimeUnits => $Self->{TicketObject}->TicketAccountedTimeGet(%Ticket),
%Ticket,
);
# add footer
$Output .= $Self->{LayoutObject}->Footer();
# return output
return $Output;
}
sub MaskAgentZoom {
my $Self = shift;
my %Param = @_;
# owner info
my %UserInfo = $Self->{UserObject}->GetUserData(
UserID => $Param{OwnerID},
Cached => 1
);
# responsible info
my %ResponsibleInfo = $Self->{UserObject}->GetUserData(
UserID => $Param{ResponsibleID} || 1,
Cached => 1
);
# get ack actions
$Self->{TicketObject}->TicketAcl(
Data => '-',
Action => $Self->{Action},
TicketID => $Self->{TicketID},
ReturnType => 'Action',
ReturnSubType => '-',
UserID => $Self->{UserID},
);
my %AclAction = $Self->{TicketObject}->TicketAclActionData();
# age design
$Param{Age} = $Self->{LayoutObject}->CustomerAge(Age => $Param{Age}, Space => ' ');
if ($Param{UntilTime}) {
if ($Param{UntilTime} < -1) {
$Param{PendingUntil} = "<font color='$Self->{HighlightColor2}'>";
}
$Param{PendingUntil} .= $Self->{LayoutObject}->CustomerAge(Age => $Param{UntilTime}, Space => '<br>');
if ($Param{UntilTime} < -1) {
$Param{PendingUntil} .= "</font>";
}
}
$Self->{LayoutObject}->Block(
Name => 'Header',
Data => {%Param, %AclAction},
);
# ticket title
if ($Self->{ConfigObject}->Get('Ticket::Frontend::Title')) {
$Self->{LayoutObject}->Block(
Name => 'Title',
Data => {%Param, %AclAction},
);
}
# run ticket menu modules
if (ref($Self->{ConfigObject}->Get('Ticket::Frontend::MenuModule')) eq 'HASH') {
my %Menus = %{$Self->{ConfigObject}->Get('Ticket::Frontend::MenuModule')};
my $Counter = 0;
foreach my $Menu (sort keys %Menus) {
# load module
if ($Self->{MainObject}->Require($Menus{$Menu}->{Module})) {
my $Object = $Menus{$Menu}->{Module}->new(
%{$Self},
TicketID => $Self->{TicketID},
);
# run module
$Counter = $Object->Run(
%Param,
Ticket => \%Param,
Counter => $Counter,
ACL => \%AclAction,
Config => $Menus{$Menu},
);
}
else {
return $Self->{LayoutObject}->FatalError();
}
}
}
# build article stuff
my $BaseLink = $Self->{LayoutObject}->{Baselink}."TicketID=$Self->{TicketID}&";
my @ArticleBox = @{$Param{ArticleBox}};
# get selected or last customer article
my $CounterArray = 0;
my $ArticleID;
if ($Self->{ArticleID}) {
$ArticleID = $Self->{ArticleID};
}
else {
# set first article
if (@ArticleBox) {
$ArticleID = $ArticleBox[0]->{ArticleID};
}
# get last customer article
foreach my $ArticleTmp (@ArticleBox) {
if ($ArticleTmp->{SenderType} eq 'customer') {
$ArticleID = $ArticleTmp->{ArticleID};
}
}
}
# build thread string
my $Counter = '';
my $Space = '';
my $LastSenderType = '';
my $TicketOverTime = 0;
my $TicketOverTimeLong = 0;
my $TicketOverDate = 0;
foreach my $ArticleTmp (@ArticleBox) {
my %Article = %$ArticleTmp;
$TicketOverTime = $Article{TicketOverTime};
$TicketOverTimeLong = $Article{TicketOverTimeLong};
$TicketOverDate = $Article{TicketOverDate};
}
# prepare escalation time (if needed)
if ($TicketOverTime) {
# colloring
if ($TicketOverTimeLong <= -60*20) {
$Param{TicketOverTimeFont} = "<font color='$Self->{HighlightColor2}'>";
$Param{TicketOverTimeFontEnd} = '</font>';
}
elsif ($TicketOverTimeLong <= -60*40) {
$Param{TicketOverTimeFont} = "<font color='$Self->{HighlightColor1}'>";
$Param{TicketOverTimeFontEnd} = '</font>';
}
$Param{TicketOverTime} = $Self->{LayoutObject}->CustomerAge(
Age => $TicketOverTime,
Space => ' ',
);
$Param{TicketOverTimeLong} = $Self->{LayoutObject}->CustomerAge(
Age => $TicketOverTimeLong,
Space => ' ',
);
if ($Param{TicketOverTimeFont} && $Param{TicketOverTimeFontEnd}) {
$Param{TicketOverTime} = $Param{TicketOverTimeFont}.$Param{TicketOverTimeLong}.'<br>'.
'<div title="$Text{"Serivce Time"}: '.$Param{TicketOverTime}.'">$TimeShort{"'.$TicketOverDate.'"}</div>'.$Param{TicketOverTimeFontEnd};
}
else {
$Param{TicketOverTime} = $Param{TicketOverTimeLong}.'<br>'.
'<div title="$Text{"Serivce Time"}: '.$Param{TicketOverTime}.'">$TimeShort{"'.$TicketOverDate.'"}</div>';
}
}
else {
$Param{TicketOverTime} = '-';
}
# get shown article(s)
my @NewArticleBox = ();
if (!$Self->{ZoomExpand}) {
foreach my $ArticleTmp (@ArticleBox) {
if ($ArticleID eq $ArticleTmp->{ArticleID}) {
push(@NewArticleBox, $ArticleTmp);
}
}
}
else {
# resort article order
if ($Self->{ZoomExpandSort} eq 'reverse') {
@ArticleBox = reverse(@ArticleBox);
}
# show no email-notification* article
foreach my $ArticleTmp (@ArticleBox) {
my %Article = %$ArticleTmp;
if ($Article{ArticleType} !~ /^email-notification/i) {
push (@NewArticleBox, $ArticleTmp);
}
}
}
# build shown article(s)
my $Count = 0;
my $BodyOutput = '';
foreach my $ArticleTmp (@NewArticleBox) {
$Count++;
my %Article = %$ArticleTmp;
# check if just a only html email
if (my $MimeTypeText = $Self->{LayoutObject}->CheckMimeType(%Param, %Article)) {
$Article{"BodyNote"} = $MimeTypeText;
$Article{"Body"} = '';
}
else {
# html quoting
$Article{"BodyHTML"} = $Self->{LayoutObject}->Ascii2Html(
NewLine => $Self->{ConfigObject}->Get('DefaultViewNewLine') || 85,
Text => $Article{Body},
VMax => $Self->{ConfigObject}->Get('DefaultViewLines') || 5000,
HTMLResultMode => 1,
LinkFeature => 1,
);
# do charset check
if (my $CharsetText = $Self->{LayoutObject}->CheckCharset(
ContentCharset => $Article{ContentCharset},
TicketID => $Param{TicketID},
ArticleID => $Article{ArticleID} )) {
$Article{"BodyNote"} = $CharsetText;
}
}
$Self->{LayoutObject}->Block(
Name => 'Body',
Data => {%Param, %Article, Body => $Article{"BodyHTML"}, %AclAction},
);
# ---
# ITSM
# ---
# delete a link
if ($Self->{ParamObject}->GetParam(Param => "LinkIDDelete")) {
my $LinkIDDelete = $Self->{ParamObject}->GetParam(Param => "LinkIDDelete");
$Self->{LinkObject2Object}->LinkDelete(
LinkID => $LinkIDDelete,
);
}
# get link partners
my @LinkPartnerObjects = $Self->{LinkObject2Object}->LinkMapPartnerObjectGet(
Object => 'Ticket',
);
my $HROutput = 1;
foreach my $LinkPartnerObject (@LinkPartnerObjects) {
# get existing links
my @LinkIDs = $Self->{LinkObject2Object}->LinkSearch(
AObject => 'Ticket',
AKey => $Self->{TicketID},
BObject => $LinkPartnerObject,
);
if (@LinkIDs) {
if ($HROutput) {
$Self->{LayoutObject}->Block(
Name => 'HR',
);
$HROutput = 0;
}
# output linked objects
$Self->{LayoutObject}->Block(
Name => 'Link',
Data => {
LinkType => $LinkPartnerObject,
},
);
# get output attributes
my $OutputAttributes = $Self->{ConfigObject}->Get('CMDB::OutputAttributes::AgentITSMCMDB')->{$LinkPartnerObject};
if ($OutputAttributes && ref($OutputAttributes) eq 'ARRAY') {
# output header columns
foreach my $Attribute (@{$OutputAttributes}) {
if (!$Attribute->{Attribute}) {
next;
}
if ($Attribute && ref($Attribute) eq 'HASH') {
# output row column
$Self->{LayoutObject}->Block(
Name => 'LinkColumn',
Data => {
Content => $Attribute->{Output} || $Attribute->{Attribute},
}
);
}
}
}
else {
next;
}
my $Class;
foreach my $LinkID (@LinkIDs) {
# set output class
if ($Class && $Class eq 'searchpassive') {
$Class = 'searchactive';
}
else {
$Class = 'searchpassive';
}
# lookup Link
my %Link = $Self->{LinkObject2Object}->LinkLookup(
LinkID => $LinkID,
);
# lookup LinkType
my %LinkType = $Self->{LinkObject2Object}->LinkTypeLookup(
LinkType => $Link{LinkType},
);
# find partner
my $LinkTypeName = $LinkType{ParentName};
my $PartnerObject = $Link{ChildObject};
my $PartnerKey = $Link{ChildKey};
if ($Link{ChildObject} eq 'Ticket' &&
$Link{ChildKey} eq $Self->{TicketID}
) {
$LinkTypeName = $LinkType{ChildName};
$PartnerObject = $Link{ParentObject};
$PartnerKey = $Link{ParentKey};
}
# get partner data
my %Partner = $Self->{LinkObject2Object}->LinkPartnerGet(
Object => $PartnerObject,
Key => $PartnerKey,
);
# next LinkID, if no partner found
if (!%Partner) {
next;
}
# output row
$Self->{LayoutObject}->Block(
Name => 'LinkRow',
Data => {
ConfigItem => 'Ticket',
TicketID => $Self->{TicketID},
LinkID => $LinkID,
Class => $Class,
}
);
foreach my $Attribute (@{$OutputAttributes}) {
if ($Attribute && ref($Attribute) eq 'HASH') {
if (!$Attribute->{Attribute}) {
next;
}
if ($Attribute->{Type} && $Attribute->{Type} eq 'ID') {
# get idhyperlink
my $IDHyperlink = $Self->{LinkObject2Object}->LinkPartnerKeyHyperlinkGet(
Object => $PartnerObject,
Key => $PartnerKey,
);
# output hyperlink
$Self->{LayoutObject}->Block(
Name => 'LinkRowHyperlink',
Data => {
Key => $Partner{$Attribute->{Attribute}} || '',
KeyHyperlink => $IDHyperlink,
Class => $Class,
}
);
}
elsif ($Attribute->{Type} && $Attribute->{Type} eq 'RelationType') {
# output row column
$Self->{LayoutObject}->Block(
Name => 'LinkRowColumn',
Data => {
Content => $LinkTypeName,
Class => $Class,
}
);
}
else {
# output row column
$Self->{LayoutObject}->Block(
Name => 'LinkRowColumn',
Data => {
Content => $Partner{$Attribute->{Attribute}} || '-',
Class => $Class,
}
);
}
}
}
}
}
}
# ---
# show article tree
if ($Count == 1) {
# show status info
$Self->{LayoutObject}->Block(
Name => 'Status',
Data => {%Param, %AclAction},
);
# customer info string
if ($Self->{ConfigObject}->Get('Ticket::Frontend::CustomerInfoZoom')) {
$Param{CustomerTable} = $Self->{LayoutObject}->AgentCustomerViewTable(
Data => {
%Param,
%{$Param{CustomerData}},
},
Max => $Self->{ConfigObject}->Get('Ticket::Frontend::CustomerInfoZoomMaxSize'),
);
$Self->{LayoutObject}->Block(
Name => 'CustomerTable',
Data => \%Param,
);
}
$Self->{LayoutObject}->Block(
Name => 'Owner',
Data => {%Param, %UserInfo, %AclAction},
);
if ($Self->{ConfigObject}->Get('Ticket::Responsible')) {
$Self->{LayoutObject}->Block(
Name => 'Responsible',
Data => {%Param, %ResponsibleInfo, %AclAction},
);
}
# ---
# ITSM
# ---
# # get linked objects
# my %Links = $Self->{LinkObject}->AllLinkedObjects(
# Object => 'Ticket',
# ObjectID => $Self->{TicketID},
# UserID => $Self->{UserID},
# );
# foreach my $LinkType (sort keys %Links) {
# my %ObjectType = %{$Links{$LinkType}};
# foreach my $Object (sort keys %ObjectType) {
# my %Data = %{$ObjectType{$Object}};
# foreach my $Item (sort keys %Data) {
# $Self->{LayoutObject}->Block(
# Name => "Link$LinkType",
# Data => $Data{$Item},
# );
# }
# }
# }
# ---
$Self->{LayoutObject}->Block(
Name => 'Tree',
Data => {%Param, %Article, %AclAction},
);
# build thread string
my $CounterTree = 0;
my $Counter = '';
my $Space = '';
my $LastSenderType = '';
foreach my $ArticleTmp (@ArticleBox) {
my %Article = %$ArticleTmp;
my $Start = '';
my $Stop = '';
if ($Article{ArticleType} !~ /^email-notification/i) {
$CounterTree++;
my $TmpSubject = $Self->{TicketObject}->TicketSubjectClean(
TicketNumber => $Article{TicketNumber},
Subject => $Article{Subject} || '',
);
if ($LastSenderType ne $Article{SenderType}) {
$Counter .= " ";
$Space = "$Counter |-->";
}
$LastSenderType = $Article{SenderType};
# if this is the shown article -=> add <b>
if ($ArticleID eq $Article{ArticleID}) {
$Start = '>><i><b><u>';
}
# if this is the shown article -=> add </b>
if ($ArticleID eq $Article{ArticleID}) {
$Stop = '</u></b></i>';
}
$Self->{LayoutObject}->Block(
Name => 'TreeItem',
Data => {
%Article,
Subject => $TmpSubject,
Space => $Space,
Start => $Start,
Stop => $Stop,
Count => $CounterTree,
},
);
if ($Article{ArticleType} =~ /^email/) {
$Self->{LayoutObject}->Block(
Name => 'TreeItemEmail',
Data => {
%Article,
},
);
}
# add attachment icon
if ($Article{Atms}->{1} && $Self->{ConfigObject}->Get('Ticket::ZoomAttachmentDisplay')) {
my $Title = '';
# download type
my $Type = $Self->{ConfigObject}->Get('AttachmentDownloadType') || 'attachment';
# if attachment will be forced to download, don't open a new download window!
my $Target = '';
if ($Type =~ /inline/i) {
$Target = 'target="attachment" ';
}
foreach my $Count (1..($Self->{ConfigObject}->Get('Ticket::ZoomAttachmentDisplayCount')+1)) {
if ($Article{Atms}->{$Count}) {
if ($Count > $Self->{ConfigObject}->Get('Ticket::ZoomAttachmentDisplayCount')) {
$Self->{LayoutObject}->Block(
Name => 'TreeItemAttachmentMore',
Data => {
%Article,
%{$Article{Atms}->{$Count}},
FileID => $Count,
Target => $Target,
},
);
}
elsif ($Article{Atms}->{$Count}) {
$Self->{LayoutObject}->Block(
Name => 'TreeItemAttachment',
Data => {
%Article,
%{$Article{Atms}->{$Count}},
FileID => $Count,
Target => $Target,
},
);
}
}
}
}
}
}
}
# do some strips && quoting
foreach (qw(From To Cc Subject)) {
if ($Article{$_}) {
$Self->{LayoutObject}->Block(
Name => 'Row',
Data => {
Key => $_,
Value => $Article{$_},
},
);
}
}
# show accounted article time
if ($Self->{ConfigObject}->Get('Ticket::ZoomTimeDisplay')) {
my $ArticleTime = $Self->{TicketObject}->ArticleAccountedTimeGet(
ArticleID => $Article{ArticleID},
);
$Self->{LayoutObject}->Block(
Name => "Row",
Data => {
Key => 'Time',
Value => $ArticleTime,
},
);
}
# show article free text
foreach (1..3) {
if ($Article{"ArticleFreeText$_"}) {
$Self->{LayoutObject}->Block(
Name => 'ArticleFreeText',
Data => {
Key => $Article{"ArticleFreeKey$_"},
Value => $Article{"ArticleFreeText$_"},
},
);
}
}
# run article modules
if (ref($Self->{ConfigObject}->Get('Ticket::Frontend::ArticleViewModule')) eq 'HASH') {
my %Jobs = %{$Self->{ConfigObject}->Get('Ticket::Frontend::ArticleViewModule')};
foreach my $Job (sort keys %Jobs) {
# load module
if ($Self->{MainObject}->Require($Jobs{$Job}->{Module})) {
my $Object = $Jobs{$Job}->{Module}->new(
%{$Self},
TicketID => $Self->{TicketID},
ArticleID => $Article{ArticleID},
);
# run module
my @Data = $Object->Check(Article=> \%Article, %Param, Config => $Jobs{$Job});
foreach my $DataRef (@Data) {
$Self->{LayoutObject}->Block(
Name => 'ArticleOption',
Data => $DataRef,
);
}
# filter option
$Object->Filter(Article=> \%Article, %Param, Config => $Jobs{$Job});
}
else {
return $Self->{LayoutObject}->ErrorScreen();
}
}
}
# get StdResponsesStrg
$Param{StdResponsesStrg} = $Self->{LayoutObject}->TicketStdResponseString(
StdResponsesRef => $Param{StdResponses},
TicketID => $Param{TicketID},
ArticleID => $Article{ArticleID},
);
# get attacment string
my %AtmIndex = ();
if ($Article{Atms}) {
%AtmIndex = %{$Article{Atms}};
}
# add block for attachments
if (%AtmIndex) {
$Self->{LayoutObject}->Block(
Name => 'ArticleAttachment',
Data => {
Key => 'Attachment',
},
);
}
foreach my $FileID (sort keys %AtmIndex) {
my %File = %{$AtmIndex{$FileID}};
$Self->{LayoutObject}->Block(
Name => 'ArticleAttachmentRow',
Data => {
%File,
},
);
# run article attachment modules
if (ref($Self->{ConfigObject}->Get('Ticket::Frontend::ArticleAttachmentModule')) eq 'HASH') {
my %Jobs = %{$Self->{ConfigObject}->Get('Ticket::Frontend::ArticleAttachmentModule')};
foreach my $Job (sort keys %Jobs) {
# load module
if ($Self->{MainObject}->Require($Jobs{$Job}->{Module})) {
my $Object = $Jobs{$Job}->{Module}->new(
%{$Self},
TicketID => $Self->{TicketID},
ArticleID => $Article{ArticleID},
);
# run module
my %Data = $Object->Run(
File => {
%File,
FileID => $FileID,
},
Article => \%Article,
);
if (%Data) {
$Self->{LayoutObject}->Block(
Name => $Data{Block} || 'ArticleAttachmentRowLink',
Data => { %Data },
);
}
}
else {
return $Self->{LayoutObject}->ErrorScreen();
}
}
}
}
# select the output template
if ($Article{ArticleType} =~ /^note/i) {
# without compose links!
if ($Param{CustomerUserID} &&
$Param{CustomerUserID} =~ /^$Self->{UserLogin}$/i &&
$Self->{ConfigObject}->Get('Ticket::AgentCanBeCustomer')
) {
$Self->{LayoutObject}->Block(
Name => 'AgentIsCustomer',
Data => {%Param, %Article, %AclAction},
);
}
$Self->{LayoutObject}->Block(
Name => 'AgentArticleCom',
Data => {%Param, %Article, %AclAction},
);
}
else {
# without all!
if ($Param{CustomerUserID} &&
$Param{CustomerUserID} =~ /^$Self->{UserLogin}$/i &&
$Self->{ConfigObject}->Get('Ticket::AgentCanBeCustomer')
) {
$Self->{LayoutObject}->Block(
Name => 'AgentIsCustomer',
Data => {%Param, %Article, %AclAction},
);
}
else {
$Self->{LayoutObject}->Block(
Name => 'AgentAnswer',
Data => {%Param, %Article, %AclAction},
);
if (!defined($AclAction{AgentTicketCompose}) || $AclAction{AgentTicketCompose}) {
$Self->{LayoutObject}->Block(
Name => 'AgentAnswerCompose',
Data => {%Param, %Article, %AclAction},
);
}
if (!defined($AclAction{AgentTicketPhoneOutbound}) || $AclAction{AgentTicketPhoneOutbound}) {
$Self->{LayoutObject}->Block(
Name => 'AgentAnswerPhoneOutbound',
Data => {%Param, %Article, %AclAction},
);
}
}
$Self->{LayoutObject}->Block(
Name => 'AgentArticleCom',
Data => {%Param, %Article, %AclAction},
);
if (!defined($AclAction{AgentTicketForward}) || $AclAction{AgentTicketForward}) {
$Self->{LayoutObject}->Block(
Name => 'AgentArticleComForward',
Data => {%Param, %Article, %AclAction},
);
}
if (!defined($AclAction{AgentTicketBounce}) || $AclAction{AgentTicketBounce}) {
$Self->{LayoutObject}->Block(
Name => 'AgentArticleComBounce',
Data => {%Param, %Article, %AclAction},
);
}
if (!defined($AclAction{AgentTicketPhone}) || $AclAction{AgentTicketPhone}) {
$Self->{LayoutObject}->Block(
Name => 'AgentArticleComPhone',
Data => {%Param, %Article, %AclAction},
);
}
}
}
# get MoveQueuesStrg
if ($Self->{ConfigObject}->Get('Ticket::Frontend::MoveType') =~ /^form$/i) {
$Param{MoveQueuesStrg} = $Self->{LayoutObject}->AgentQueueListOption(
Name => 'DestQueueID',
Data => $Param{MoveQueues},
SelectedID => $Param{QueueID},
);
}
if (!defined($AclAction{AgentTicketMove}) || $AclAction{AgentTicketMove}) {
$Self->{LayoutObject}->Block(
Name => 'Move',
Data => {%Param, %AclAction},
);
}
$Self->{LayoutObject}->Block(
Name => 'Footer',
Data => {%Param, %AclAction},
);
# return output
return $Self->{LayoutObject}->Output(
TemplateFile => 'AgentTicketZoom',
Data => {%Param, %AclAction},
);
}
1;
More information about the cvs-log
mailing list