[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 .= "&nbsp;";
                        $Space = "$Counter&nbsp;|--&gt;";
                    }
                    $LastSenderType = $Article{SenderType};
                    # if this is the shown article -=> add <b>
                    if ($ArticleID eq $Article{ArticleID}) {
                        $Start = '&gt;&gt;<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