Advertisement
Guest User

OTRS

a guest
Jan 3rd, 2009
277
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 44.01 KB | None | 0 0
  1. # --
  2. # Kernel/Modules/AgentTicketCompose.pm - to compose and send a message
  3. # Copyright (C) 2001-2008 OTRS AG, http://otrs.org/
  4. # --
  5. # $Id: AgentTicketCompose.pm,v 1.44 2008/05/22 21:44:15 martin Exp $
  6. # --
  7. # This software comes with ABSOLUTELY NO WARRANTY. For details, see
  8. # the enclosed file COPYING for license information (GPL). If you
  9. # did not receive this file, see http://www.gnu.org/licenses/gpl-2.0.txt.
  10. # --
  11.  
  12. package Kernel::Modules::AgentTicketCompose;
  13.  
  14. use strict;
  15. use warnings;
  16.  
  17. use Kernel::System::CheckItem;
  18. use Kernel::System::StdAttachment;
  19. use Kernel::System::State;
  20. use Kernel::System::CustomerUser;
  21. use Kernel::System::Web::UploadCache;
  22. use Kernel::System::SystemAddress;
  23. use Mail::Address;
  24.  
  25.  
  26. use vars qw($VERSION);
  27. $VERSION = qw($Revision: 1.44 $) [1];
  28.  
  29. sub new {
  30.     my ( $Type, %Param ) = @_;
  31.  
  32.     # allocate new hash for object
  33.     my $Self = {%Param};
  34.     bless( $Self, $Type );
  35.  
  36.     $Self->{Debug} = $Param{Debug} || 0;
  37.  
  38.     # check all needed objects
  39.     for (qw(TicketObject ParamObject DBObject QueueObject LayoutObject ConfigObject LogObject)) {
  40.         if ( !$Self->{$_} ) {
  41.             $Self->{LayoutObject}->FatalError( Message => "Got no $_!" );
  42.         }
  43.     }
  44.  
  45.     # some new objects
  46.     $Self->{CustomerUserObject}  = Kernel::System::CustomerUser->new(%Param);
  47.     $Self->{CheckItemObject}     = Kernel::System::CheckItem->new(%Param);
  48.     $Self->{StdAttachmentObject} = Kernel::System::StdAttachment->new(%Param);
  49.     $Self->{StateObject}         = Kernel::System::State->new(%Param);
  50.     $Self->{UploadCachObject}    = Kernel::System::Web::UploadCache->new(%Param);
  51.     $Self->{SystemAddress}       = Kernel::System::SystemAddress->new(%Param);
  52.  
  53.     # get response format
  54.     $Self->{ResponseFormat} = $Self->{ConfigObject}->Get('Ticket::Frontend::ResponseFormat')
  55.         || '$Data{"Salutation"}
  56. $Data{"OrigFrom"} $Text{"wrote"}:
  57. $Data{"Body"}
  58.  
  59. $Data{"StdResponse"}
  60.  
  61. $Data{"Signature"}
  62. ';
  63.  
  64.     # get form id
  65.     $Self->{FormID} = $Self->{ParamObject}->GetParam( Param => 'FormID' );
  66.  
  67.     # create form id
  68.     if ( !$Self->{FormID} ) {
  69.         $Self->{FormID} = $Self->{UploadCachObject}->FormIDCreate();
  70.     }
  71.  
  72.     $Self->{Config} = $Self->{ConfigObject}->Get("Ticket::Frontend::$Self->{Action}");
  73.  
  74.     return $Self;
  75. }
  76.  
  77. sub Run {
  78.     my ( $Self, %Param ) = @_;
  79.  
  80.     # check needed stuff
  81.     if ( !$Self->{TicketID} ) {
  82.  
  83.         # error page
  84.         return $Self->{LayoutObject}->ErrorScreen(
  85.             Message => "Need TicketID is given!",
  86.             Comment => 'Please contact the admin.',
  87.         );
  88.     }
  89.  
  90.     # check permissions
  91.     if (
  92.         !$Self->{TicketObject}->Permission(
  93.             Type     => $Self->{Config}->{Permission},
  94.             TicketID => $Self->{TicketID},
  95.             UserID   => $Self->{UserID}
  96.         )
  97.         )
  98.     {
  99.  
  100.         # error screen, don't show ticket
  101.         return $Self->{LayoutObject}->NoPermission(
  102.             Message    => "You need $Self->{Config}->{Permission} permissions!",
  103.             WithHeader => 'yes',
  104.         );
  105.     }
  106.     my %Ticket = $Self->{TicketObject}->TicketGet( TicketID => $Self->{TicketID} );
  107.  
  108.     # get lock state
  109.     if ( $Self->{Config}->{RequiredLock} ) {
  110.         if ( !$Self->{TicketObject}->LockIsTicketLocked( TicketID => $Self->{TicketID} ) ) {
  111.             $Self->{TicketObject}->LockSet(
  112.                 TicketID => $Self->{TicketID},
  113.                 Lock     => 'lock',
  114.                 UserID   => $Self->{UserID}
  115.             );
  116.             if (
  117.                 $Self->{TicketObject}->OwnerSet(
  118.                     TicketID  => $Self->{TicketID},
  119.                     UserID    => $Self->{UserID},
  120.                     NewUserID => $Self->{UserID},
  121.                 )
  122.                 )
  123.             {
  124.  
  125.                 # show lock state
  126.                 $Self->{LayoutObject}->Block(
  127.                     Name => 'PropertiesLock',
  128.                     Data => { %Param, TicketID => $Self->{TicketID}, },
  129.                 );
  130.             }
  131.         }
  132.         else {
  133.             my $AccessOk = $Self->{TicketObject}->OwnerCheck(
  134.                 TicketID => $Self->{TicketID},
  135.                 OwnerID  => $Self->{UserID},
  136.             );
  137.             if ( !$AccessOk ) {
  138.                 my $Output = $Self->{LayoutObject}->Header( Value => $Ticket{Number} );
  139.                 $Output .= $Self->{LayoutObject}->Warning(
  140.                     Message => "Sorry, you need to be the owner to do this action!",
  141.                     Comment => 'Please change the owner first.',
  142.                 );
  143.                 $Output .= $Self->{LayoutObject}->Footer();
  144.                 return $Output;
  145.             }
  146.             else {
  147.                 $Self->{LayoutObject}->Block(
  148.                     Name => 'TicketBack',
  149.                     Data => { %Param, TicketID => $Self->{TicketID}, },
  150.                 );
  151.             }
  152.         }
  153.     }
  154.     else {
  155.         $Self->{LayoutObject}->Block(
  156.             Name => 'TicketBack',
  157.             Data => { %Param, %Ticket, },
  158.         );
  159.     }
  160.  
  161.     # get params
  162.     my %GetParam = ();
  163.     for (
  164.         qw(
  165.         From To Cc Bcc Subject Body InReplyTo ResponseID ReplyArticleID StateID
  166.         ArticleID TimeUnits Year Month Day Hour Minute AttachmentUpload
  167.         AttachmentDelete1 AttachmentDelete2 AttachmentDelete3 AttachmentDelete4
  168.         AttachmentDelete5 AttachmentDelete6 AttachmentDelete7 AttachmentDelete8
  169.         AttachmentDelete9 AttachmentDelete10 AttachmentDelete11 AttachmentDelete12
  170.         AttachmentDelete13 AttachmentDelete14 AttachmentDelete15 AttachmentDelete16
  171.         FormID
  172.         )
  173.         )
  174.     {
  175.         $GetParam{$_} = $Self->{ParamObject}->GetParam( Param => $_ );
  176.     }
  177.  
  178.     # get ticket free text params
  179.     for ( 1 .. 16 ) {
  180.         $GetParam{"TicketFreeKey$_"} = $Self->{ParamObject}->GetParam( Param => "TicketFreeKey$_" );
  181.         $GetParam{"TicketFreeText$_"}
  182.             = $Self->{ParamObject}->GetParam( Param => "TicketFreeText$_" );
  183.     }
  184.  
  185.     # get ticket free time params
  186.     for ( 1 .. 6 ) {
  187.         for my $Type (qw(Used Year Month Day Hour Minute)) {
  188.             $GetParam{ "TicketFreeTime" . $_ . $Type }
  189.                 = $Self->{ParamObject}->GetParam( Param => "TicketFreeTime" . $_ . $Type );
  190.         }
  191.         if ( !$Self->{ConfigObject}->Get( 'TicketFreeTimeOptional' . $_ ) ) {
  192.             $GetParam{ 'TicketFreeTime' . $_ . 'Used' } = 1;
  193.         }
  194.     }
  195.  
  196.     # get article free text params
  197.     for ( 1 .. 3 ) {
  198.         $GetParam{"ArticleFreeKey$_"}
  199.             = $Self->{ParamObject}->GetParam( Param => "ArticleFreeKey$_" );
  200.         $GetParam{"ArticleFreeText$_"}
  201.             = $Self->{ParamObject}->GetParam( Param => "ArticleFreeText$_" );
  202.     }
  203.  
  204.     # send email
  205.     if ( $Self->{Subaction} eq 'SendEmail' ) {
  206.         my %Error = ();
  207.         my %StateData = $Self->{TicketObject}->{StateObject}->StateGet( ID => $GetParam{StateID}, );
  208.  
  209.         # check pending date
  210.         if ( $StateData{TypeName} && $StateData{TypeName} =~ /^pending/i ) {
  211.             if ( !$Self->{TimeObject}->Date2SystemTime( %GetParam, Second => 0 ) ) {
  212.                 $Error{"Date invalid"} = 'invalid';
  213.             }
  214.         }
  215.  
  216.         # check required FreeTextField (if configured)
  217.         for ( 1 .. 16 ) {
  218.             if ( $Self->{Config}{'TicketFreeText'}{$_} == 2 && $GetParam{"TicketFreeText$_"} eq '' )
  219.             {
  220.                 $Error{"TicketFreeTextField$_ invalid"} = 'invalid';
  221.             }
  222.         }
  223.  
  224.         # attachment delete
  225.         for ( 1 .. 16 ) {
  226.             if ( $GetParam{"AttachmentDelete$_"} ) {
  227.                 $Error{AttachmentDelete} = 1;
  228.                 $Self->{UploadCachObject}->FormIDRemoveFile(
  229.                     FormID => $Self->{FormID},
  230.                     FileID => $_,
  231.                 );
  232.             }
  233.         }
  234.  
  235.         # attachment upload
  236.         if ( $GetParam{AttachmentUpload} ) {
  237.             $Error{AttachmentUpload} = 1;
  238.             my %UploadStuff = $Self->{ParamObject}->GetUploadAll(
  239.                 Param  => "file_upload",
  240.                 Source => 'string',
  241.             );
  242.             $Self->{UploadCachObject}->FormIDAddFile(
  243.                 FormID => $Self->{FormID},
  244.                 %UploadStuff,
  245.             );
  246.         }
  247.  
  248.         # get all attachments meta data
  249.         my @Attachments = $Self->{UploadCachObject}->FormIDGetAllFilesMeta(
  250.             FormID => $Self->{FormID},
  251.         );
  252.  
  253.         # check some values
  254.         for (qw(From To Cc Bcc)) {
  255.             if ( $GetParam{$_} ) {
  256.                 for my $Email ( Mail::Address->parse( $GetParam{$_} ) ) {
  257.                     if ( !$Self->{CheckItemObject}->CheckEmail( Address => $Email->address() ) ) {
  258.                         $Error{"$_ invalid"} .= $Self->{CheckItemObject}->CheckError();
  259.                     }
  260.                 }
  261.             }
  262.         }
  263.  
  264.         # prepare subject
  265.         my $Tn = $Self->{TicketObject}->TicketNumberLookup( TicketID => $Self->{TicketID} );
  266.         $GetParam{Subject} = $Self->{TicketObject}->TicketSubjectBuild(
  267.             TicketNumber => $Tn,
  268.             Subject => $GetParam{Subject} || '',
  269.         );
  270.  
  271.         my %ArticleParam = ();
  272.  
  273.         # run compose modules
  274.         if ( ref $Self->{ConfigObject}->Get('Ticket::Frontend::ArticleComposeModule') eq 'HASH' )
  275.         {
  276.             my %Jobs = %{ $Self->{ConfigObject}->Get('Ticket::Frontend::ArticleComposeModule') };
  277.             for my $Job ( sort keys %Jobs ) {
  278.  
  279.                 # load module
  280.                 if ( $Self->{MainObject}->Require( $Jobs{$Job}->{Module} ) ) {
  281.                     my $Object = $Jobs{$Job}->{Module}->new( %{$Self}, Debug => $Self->{Debug} );
  282.  
  283.                     # get params
  284.                     for ( $Object->Option( %GetParam, Config => $Jobs{$Job} ) ) {
  285.                         $GetParam{$_} = $Self->{ParamObject}->GetParam( Param => $_ );
  286.                     }
  287.  
  288.                     # run module
  289.                     $Object->Run( %GetParam, Config => $Jobs{$Job} );
  290.  
  291.                     # ticket params
  292.                     %ArticleParam = (
  293.                         %ArticleParam, $Object->ArticleOption( %GetParam, Config => $Jobs{$Job} )
  294.                     );
  295.  
  296.                     # get errors
  297.                     %Error = ( %Error, $Object->Error( %GetParam, Config => $Jobs{$Job} ) );
  298.                 }
  299.                 else {
  300.                     return $Self->{LayoutObject}->FatalError();
  301.                 }
  302.             }
  303.         }
  304.  
  305.         # check if there is an error
  306.         if (%Error) {
  307.  
  308.             # get free text config options
  309.             my %TicketFreeText = ();
  310.             for ( 1 .. 16 ) {
  311.                 $TicketFreeText{"TicketFreeKey$_"} = $Self->{TicketObject}->TicketFreeTextGet(
  312.                     TicketID => $Self->{TicketID},
  313.                     Type     => "TicketFreeKey$_",
  314.                     Action   => $Self->{Action},
  315.                     UserID   => $Self->{UserID},
  316.                 );
  317.                 $TicketFreeText{"TicketFreeText$_"} = $Self->{TicketObject}->TicketFreeTextGet(
  318.                     TicketID => $Self->{TicketID},
  319.                     Type     => "TicketFreeText$_",
  320.                     Action   => $Self->{Action},
  321.                     UserID   => $Self->{UserID},
  322.                 );
  323.             }
  324.             my %TicketFreeTextHTML = $Self->{LayoutObject}->AgentFreeText(
  325.                 Config => \%TicketFreeText,
  326.                 Ticket => \%GetParam,
  327.             );
  328.  
  329.             # ticket free time
  330.             my %TicketFreeTimeHTML
  331.                 = $Self->{LayoutObject}->AgentFreeDate( %Param, Ticket => \%GetParam, );
  332.  
  333.             # article free text
  334.             my %ArticleFreeText = ();
  335.             for ( 1 .. 3 ) {
  336.                 $ArticleFreeText{"ArticleFreeKey$_"} = $Self->{TicketObject}->ArticleFreeTextGet(
  337.                     TicketID => $Self->{TicketID},
  338.                     Type     => "ArticleFreeKey$_",
  339.                     Action   => $Self->{Action},
  340.                     UserID   => $Self->{UserID},
  341.                 );
  342.                 $ArticleFreeText{"ArticleFreeText$_"} = $Self->{TicketObject}->ArticleFreeTextGet(
  343.                     TicketID => $Self->{TicketID},
  344.                     Type     => "ArticleFreeText$_",
  345.                     Action   => $Self->{Action},
  346.                     UserID   => $Self->{UserID},
  347.                 );
  348.             }
  349.             my %ArticleFreeTextHTML = $Self->{LayoutObject}->TicketArticleFreeText(
  350.                 Config  => \%ArticleFreeText,
  351.                 Article => \%GetParam,
  352.             );
  353.             my $Output = $Self->{LayoutObject}->Header( Value => $Ticket{TicketNumber} );
  354.             $GetParam{StdResponse} = $GetParam{Body};
  355.             $Output .= $Self->_Mask(
  356.                 TicketID       => $Self->{TicketID},
  357.                 NextStates     => $Self->_GetNextStates(),
  358.                 ResponseFormat => $Self->{LayoutObject}->Ascii2Html( Text => $GetParam{Body} ),
  359.                 Errors         => \%Error,
  360.                 Attachments    => \@Attachments,
  361.                 Types      => $Self->_GetTypes( QueueID => $Self->{QueueID} || 1 ),
  362.                 %Ticket,
  363.                 %TicketFreeTextHTML,
  364.                 %TicketFreeTimeHTML,
  365.                 %ArticleFreeTextHTML,
  366.                 %GetParam,
  367.             );
  368.             $Output .= $Self->{LayoutObject}->Footer();
  369.             return $Output;
  370.         }
  371.  
  372.         # replace <OTRS_TICKET_STATE> with next ticket state name
  373.         if ( $StateData{Name} ) {
  374.             $GetParam{Body} =~ s/<OTRS_TICKET_STATE>/$StateData{Name}/g;
  375.         }
  376.  
  377.         # get pre loaded attachments
  378.         my @AttachmentData = $Self->{UploadCachObject}->FormIDGetAllFilesData(
  379.             FormID => $Self->{FormID},
  380.         );
  381.  
  382.         # get submit attachment
  383.         my %UploadStuff = $Self->{ParamObject}->GetUploadAll(
  384.             Param  => 'file_upload',
  385.             Source => 'String',
  386.         );
  387.         if (%UploadStuff) {
  388.             push( @AttachmentData, \%UploadStuff );
  389.         }
  390.  
  391.         # get recipients
  392.         my $Recipients = '';
  393.         for my $Line (qw(To Cc Bcc)) {
  394.             if ( $GetParam{$Line} ) {
  395.                 if ($Recipients) {
  396.                     $Recipients .= ',';
  397.                 }
  398.                 $Recipients .= $GetParam{$Line};
  399.             }
  400.         }
  401.  
  402.         # send email
  403.         my $ArticleID = $Self->{TicketObject}->ArticleSend(
  404.             ArticleType    => 'email-external',
  405.             SenderType     => 'agent',
  406.             TicketID       => $Self->{TicketID},
  407.             HistoryType    => 'SendAnswer',
  408.             HistoryComment => "\%\%$Recipients",
  409.             From           => $GetParam{From},
  410.             To             => $GetParam{To},
  411.             Cc             => $GetParam{Cc},
  412.             Bcc            => $GetParam{Bcc},
  413.             Subject        => $GetParam{Subject},
  414.             UserID         => $Self->{UserID},
  415.             Body           => $GetParam{Body},
  416.             InReplyTo      => $GetParam{InReplyTo},
  417.             Charset        => $Self->{LayoutObject}->{UserCharset},
  418.             Type           => 'text/plain',
  419.             Attachment     => \@AttachmentData,
  420.             %ArticleParam,
  421.         );
  422.         if ($ArticleID) {
  423.  
  424.             # time accounting
  425.             if ( $GetParam{TimeUnits} ) {
  426.                 $Self->{TicketObject}->TicketAccountTime(
  427.                     TicketID  => $Self->{TicketID},
  428.                     ArticleID => $ArticleID,
  429.                     TimeUnit  => $GetParam{TimeUnits},
  430.                     UserID    => $Self->{UserID},
  431.                 );
  432.             }
  433.  
  434.             # set ticket free text
  435.             for ( 1 .. 16 ) {
  436.                 if ( defined( $GetParam{"TicketFreeKey$_"} ) ) {
  437.                     $Self->{TicketObject}->TicketFreeTextSet(
  438.                         Key      => $GetParam{"TicketFreeKey$_"},
  439.                         Value    => $GetParam{"TicketFreeText$_"},
  440.                         Counter  => $_,
  441.                         TicketID => $Self->{TicketID},
  442.                         UserID   => $Self->{UserID},
  443.                     );
  444.                 }
  445.             }
  446.  
  447.             # set ticket free time
  448.             for ( 1 .. 6 ) {
  449.                 if (
  450.                     defined( $GetParam{ "TicketFreeTime" . $_ . "Year" } )
  451.                     && defined( $GetParam{ "TicketFreeTime" . $_ . "Month" } )
  452.                     && defined( $GetParam{ "TicketFreeTime" . $_ . "Day" } )
  453.                     && defined( $GetParam{ "TicketFreeTime" . $_ . "Hour" } )
  454.                     && defined( $GetParam{ "TicketFreeTime" . $_ . "Minute" } )
  455.                     )
  456.                 {
  457.                     my %Time;
  458.                     $Time{ "TicketFreeTime" . $_ . "Year" }    = 0;
  459.                     $Time{ "TicketFreeTime" . $_ . "Month" }   = 0;
  460.                     $Time{ "TicketFreeTime" . $_ . "Day" }     = 0;
  461.                     $Time{ "TicketFreeTime" . $_ . "Hour" }    = 0;
  462.                     $Time{ "TicketFreeTime" . $_ . "Minute" }  = 0;
  463.                     $Time{ "TicketFreeTime" . $_ . "Secunde" } = 0;
  464.  
  465.                     if ( $GetParam{ "TicketFreeTime" . $_ . "Used" } ) {
  466.                         %Time = $Self->{LayoutObject}->TransfromDateSelection(
  467.                             %GetParam,
  468.                             Prefix => "TicketFreeTime" . $_,
  469.                         );
  470.                     }
  471.                     $Self->{TicketObject}->TicketFreeTimeSet(
  472.                         %Time,
  473.                         Prefix   => "TicketFreeTime",
  474.                         TicketID => $Self->{TicketID},
  475.                         Counter  => $_,
  476.                         UserID   => $Self->{UserID},
  477.                     );
  478.                 }
  479.             }
  480.  
  481.             # set article free text
  482.             for ( 1 .. 3 ) {
  483.                 if ( defined( $GetParam{"ArticleFreeKey$_"} ) ) {
  484.                     $Self->{TicketObject}->ArticleFreeTextSet(
  485.                         TicketID  => $Self->{TicketID},
  486.                         ArticleID => $ArticleID,
  487.                         Key       => $GetParam{"ArticleFreeKey$_"},
  488.                         Value     => $GetParam{"ArticleFreeText$_"},
  489.                         Counter   => $_,
  490.                         UserID    => $Self->{UserID},
  491.                     );
  492.                 }
  493.             }
  494.  
  495.             # set state
  496.             $Self->{TicketObject}->StateSet(
  497.                 TicketID  => $Self->{TicketID},
  498.                 ArticleID => $ArticleID,
  499.                 StateID   => $GetParam{StateID},
  500.                 UserID    => $Self->{UserID},
  501.             );
  502.  
  503.             # should I set an unlock?
  504.             if ( $StateData{TypeName} =~ /^close/i ) {
  505.                 $Self->{TicketObject}->LockSet(
  506.                     TicketID => $Self->{TicketID},
  507.                     Lock     => 'unlock',
  508.                     UserID   => $Self->{UserID},
  509.                 );
  510.             }
  511.  
  512.             # set pending time
  513.             elsif ( $StateData{TypeName} =~ /^pending/i ) {
  514.                 $Self->{TicketObject}->TicketPendingTimeSet(
  515.                     UserID   => $Self->{UserID},
  516.                     TicketID => $Self->{TicketID},
  517.                     Year     => $GetParam{Year},
  518.                     Month    => $GetParam{Month},
  519.                     Day      => $GetParam{Day},
  520.                     Hour     => $GetParam{Hour},
  521.                     Minute   => $GetParam{Minute},
  522.                 );
  523.             }
  524.  
  525.             # log use response id and reply article id (useful for response diagnostics)
  526.             $Self->{TicketObject}->HistoryAdd(
  527.                 Name =>
  528.                     "ResponseTemplate ($GetParam{ResponseID}/$GetParam{ReplyArticleID}/$ArticleID)",
  529.                 HistoryType  => 'Misc',
  530.                 TicketID     => $Self->{TicketID},
  531.                 CreateUserID => $Self->{UserID},
  532.             );
  533.  
  534.             # remove pre submited attachments
  535.             $Self->{UploadCachObject}->FormIDRemove( FormID => $GetParam{FormID} );
  536.  
  537.             # redirect
  538.             if ( $StateData{TypeName} =~ /^close/i ) {
  539.                 return $Self->{LayoutObject}->Redirect( OP => $Self->{LastScreenOverview} );
  540.             }
  541.             else {
  542.                 return $Self->{LayoutObject}->Redirect(
  543.                     OP =>
  544.                         "Action=AgentTicketZoom&TicketID=$Self->{TicketID}&ArticleID=$ArticleID"
  545.                 );
  546.             }
  547.         }
  548.         else {
  549.  
  550.             # error page
  551.             return $Self->{LayoutObject}->ErrorScreen();
  552.         }
  553.     }
  554.     else {
  555.         my %Error = ();
  556.         my $Output = $Self->{LayoutObject}->Header( Value => $Ticket{TicketNumber} );
  557.  
  558.         # add std. attachments to email
  559.         if ( $GetParam{ResponseID} ) {
  560.             my %AllStdAttachments = $Self->{StdAttachmentObject}->StdAttachmentsByResponseID(
  561.                 ID => $GetParam{ResponseID},
  562.             );
  563.             for ( sort keys %AllStdAttachments ) {
  564.                 my %Data = $Self->{StdAttachmentObject}->StdAttachmentGet( ID => $_ );
  565.                 $Self->{UploadCachObject}->FormIDAddFile(
  566.                     FormID => $Self->{FormID},
  567.                     %Data,
  568.                 );
  569.             }
  570.         }
  571.  
  572.         # get all attachments meta data
  573.         my @Attachments
  574.             = $Self->{UploadCachObject}->FormIDGetAllFilesMeta( FormID => $Self->{FormID} );
  575.  
  576.         # get last customer article or selecte article ...
  577.         my %Data = ();
  578.         if ( $GetParam{ArticleID} ) {
  579.             %Data = $Self->{TicketObject}->ArticleGet( ArticleID => $GetParam{ArticleID} );
  580.         }
  581.         else {
  582.             %Data = $Self->{TicketObject}->ArticleLastCustomerArticle(
  583.                 TicketID => $Self->{TicketID}
  584.             );
  585.         }
  586.  
  587.         # check article type and replace To with From (in case)
  588.         if ( $Data{SenderType} !~ /customer/ ) {
  589.             my $To   = $Data{To};
  590.             my $From = $Data{From};
  591.  
  592.             # set OrigFrom for correct email quoteing (xxxx wrote)
  593.             $Data{OrigFrom} = $Data{From};
  594.  
  595.             # replace From/To, To/From because sender is agent
  596.             $Data{From}    = $To;
  597.             $Data{To}      = $Data{From};
  598.             $Data{ReplyTo} = '';
  599.         }
  600.         else {
  601.  
  602.             # set OrigFrom for correct email quoteing (xxxx wrote)
  603.             $Data{OrigFrom} = $Data{From};
  604.         }
  605.  
  606.         # build OrigFromName (to only use the realname)
  607.         $Data{OrigFromName} = $Data{OrigFrom};
  608.         $Data{OrigFromName} =~ s/<.*>|\(.*\)|\"|;|,//g;
  609.         $Data{OrigFromName} =~ s/( $)|(  $)//g;
  610.  
  611.         # get customer data
  612.         my %Customer = ();
  613.         if ( $Ticket{CustomerUserID} ) {
  614.             %Customer = $Self->{CustomerUserObject}->CustomerUserDataGet(
  615.                 User => $Ticket{CustomerUserID}
  616.             );
  617.         }
  618.  
  619.         # check if original content isn't text/plain or text/html, don't use it
  620.         if ( $Data{'ContentType'} ) {
  621.             if ( $Data{'ContentType'} =~ /text\/html/i ) {
  622.                 $Data{Body} =~ s/\<.+?\>//gs;
  623.             }
  624.             elsif ( $Data{'ContentType'} !~ /text\/plain/i ) {
  625.                 $Data{Body} = "-> no quotable message <-";
  626.             }
  627.         }
  628.  
  629.         # prepare body, subject, ReplyTo ...
  630.         # rewrap body if exists
  631.         if ( $Data{Body} ) {
  632.             $Data{Body} =~ s/\t/ /g;
  633.             my $Quote = $Self->{ConfigObject}->Get('Ticket::Frontend::Quote');
  634.             if ($Quote) {
  635.                 $Data{Body} =~ s/\n/\n$Quote /g;
  636.                 $Data{Body} = "\n$Quote " . $Data{Body};
  637.             }
  638.             else {
  639.                 $Data{Body} = "\n" . $Data{Body};
  640.                 if ( $Data{Created} ) {
  641.                     $Data{Body} = "Date: $Data{Created}\n" . $Data{Body};
  642.                 }
  643.                 for (qw(Subject ReplyTo Reply-To Cc To From)) {
  644.                     if ( $Data{$_} ) {
  645.                         $Data{Body} = "$_: $Data{$_}\n" . $Data{Body};
  646.                     }
  647.                 }
  648.                 $Data{Body} = "\n---- Message from $Data{From} ---\n\n" . $Data{Body};
  649.                 $Data{Body} .= "\n---- End Message ---\n";
  650.             }
  651.         }
  652.         $Data{Subject} = $Self->{TicketObject}->TicketSubjectBuild(
  653.             TicketNumber => $Ticket{TicketNumber},
  654.             Subject => $Data{Subject} || '',
  655.         );
  656.  
  657.         # check if Cc recipients should be used
  658.         if ( $Self->{ConfigObject}->Get('Ticket::Frontend::ComposeExcludeCcRecipients') ) {
  659.             $Data{Cc} = '';
  660.         }
  661.  
  662.         # add not local To addresses to Cc
  663.         for my $Email ( Mail::Address->parse( $Data{To} ) ) {
  664.             my $IsLocal = $Self->{SystemAddress}->SystemAddressIsLocalAddress(
  665.                 Address => $Email->address(),
  666.             );
  667.             if ( !$IsLocal ) {
  668.                 if ( $Data{Cc} ) {
  669.                     $Data{Cc} .= ', ';
  670.                 }
  671.                 $Data{Cc} .= $Email->format();
  672.             }
  673.         }
  674.  
  675.         # check ReplyTo
  676.         if ( $Data{ReplyTo} ) {
  677.             $Data{To} = $Data{ReplyTo};
  678.         }
  679.         else {
  680.             $Data{To} = $Data{From};
  681.  
  682.             # try to remove some wrong text to from line (by way of ...)
  683.             # added by some strange mail programs on bounce
  684.             $Data{To} =~ s/(.+?\<.+?\@.+?\>)\s+\(by\s+way\s+of\s+.+?\)/$1/ig;
  685.         }
  686.  
  687.         # get to email (just "some@example.com")
  688.         for my $Email ( Mail::Address->parse( $Data{To} ) ) {
  689.             $Data{ToEmail} = $Email->address();
  690.         }
  691.  
  692.         # use database email
  693.         if ( $Customer{UserEmail} && $Data{ToEmail} !~ /^\Q$Customer{UserEmail}\E$/i ) {
  694.             if ( $Self->{ConfigObject}->Get('Ticket::Frontend::ComposeReplaceSenderAddress') ) {
  695.                 $Self->{LayoutObject}->Block(
  696.                     Name => 'PropertiesRecipientTo',
  697.                     Data => { To => $Data{To} },
  698.                 );
  699.                 $Data{To} = $Customer{UserEmail};
  700.             }
  701.             else {
  702.                 $Self->{LayoutObject}->Block(
  703.                     Name => 'PropertiesRecipientCc',
  704.                     Data => { Cc => $Customer{UserEmail}, },
  705.                 );
  706.                 if ( $Data{Cc} ) {
  707.                     $Data{Cc} .= ', ' . $Customer{UserEmail};
  708.                 }
  709.                 else {
  710.                     $Data{Cc} = $Customer{UserEmail};
  711.                 }
  712.             }
  713.         }
  714.  
  715.         # find duplicate addresses
  716.         my %Recipient = ();
  717.         for my $Type (qw(To Cc Bcc)) {
  718.             if ( $Data{$Type} ) {
  719.                 my $NewLine = '';
  720.                 for my $Email ( Mail::Address->parse( $Data{$Type} ) ) {
  721.                     my $Address = lc $Email->address();
  722.  
  723.                     # only use email addresses with @ inside
  724.                     if ( $Address && $Address =~ /@/ && !$Recipient{$Address} ) {
  725.                         $Recipient{$Address} = 1;
  726.                         my $IsLocal = $Self->{SystemAddress}->SystemAddressIsLocalAddress(
  727.                             Address => $Address,
  728.                         );
  729.                         if ( !$IsLocal ) {
  730.                             if ($NewLine) {
  731.                                 $NewLine .= ', ';
  732.                             }
  733.                             $NewLine .= $Email->format();
  734.                         }
  735.                     }
  736.                 }
  737.                 $Data{$Type} = $NewLine;
  738.             }
  739.         }
  740.  
  741.         # find queue address
  742.         my %Address = $Self->{QueueObject}->GetSystemAddress(%Ticket);
  743.         $Data{From}        = "$Address{RealName} <$Address{Email}>";
  744.         $Data{Email}       = $Address{Email};
  745.         $Data{RealName}    = $Address{RealName};
  746.         $Data{StdResponse} = $Self->{QueueObject}->GetStdResponse( ID => $GetParam{ResponseID} );
  747.  
  748.         # prepare salutation & signature
  749.         $Data{Salutation} = $Self->{QueueObject}->GetSalutation(%Ticket);
  750.         $Data{Signature}  = $Self->{QueueObject}->GetSignature(%Ticket);
  751.         for (qw(Signature Salutation StdResponse)) {
  752.  
  753.             # get and prepare realname
  754.             if ( $Data{$_} =~ /<OTRS_CUSTOMER_REALNAME>/ ) {
  755.                 my $From = '';
  756.                 if ( $Ticket{CustomerUserID} ) {
  757.                     $From = $Self->{CustomerUserObject}->CustomerName(
  758.                         UserLogin => $Ticket{CustomerUserID}
  759.                     );
  760.                 }
  761.                 if ( !$From ) {
  762.                     $From = $Data{To} || '';
  763.                     $From =~ s/<.*>|\(.*\)|\"|;|,//g;
  764.                     $From =~ s/( $)|(  $)//g;
  765.                 }
  766.                 $Data{$_} =~ s/<OTRS_CUSTOMER_REALNAME>/$From/g;
  767.             }
  768.  
  769.             # current user
  770.             my %User = $Self->{UserObject}->GetUserData(
  771.                 UserID => $Self->{UserID},
  772.                 Cached => 1,
  773.             );
  774.             for my $UserKey ( keys %User ) {
  775.                 if ( $User{$UserKey} ) {
  776.                     $Data{$_} =~ s/<OTRS_Agent_$UserKey>/$User{$UserKey}/gi;
  777.                     $Data{$_} =~ s/<OTRS_CURRENT_$UserKey>/$User{$UserKey}/gi;
  778.                 }
  779.             }
  780.  
  781.             # replace other needed stuff
  782.             $Data{$_} =~ s/<OTRS_FIRST_NAME>/$Self->{UserFirstname}/g;
  783.             $Data{$_} =~ s/<OTRS_LAST_NAME>/$Self->{UserLastname}/g;
  784.  
  785.             # cleanup
  786.             $Data{$_} =~ s/<OTRS_Agent_.+?>/-/gi;
  787.             $Data{$_} =~ s/<OTRS_CURRENT_.+?>/-/gi;
  788.  
  789.             # owner user
  790.             my %OwnerUser = $Self->{UserObject}->GetUserData(
  791.                 UserID => $Ticket{OwnerID},
  792.                 Cached => 1,
  793.             );
  794.             for my $UserKey ( keys %OwnerUser ) {
  795.                 if ( $OwnerUser{$UserKey} ) {
  796.                     $Data{$_} =~ s/<OTRS_OWNER_$UserKey>/$OwnerUser{$UserKey}/gi;
  797.                 }
  798.             }
  799.  
  800.             # cleanup
  801.             $Data{$_} =~ s/<OTRS_OWNER_.+?>/-/gi;
  802.  
  803.             # responsible user
  804.             my %ResponsibleUser = $Self->{UserObject}->GetUserData(
  805.                 UserID => $Ticket{ResponsibleID},
  806.                 Cached => 1,
  807.             );
  808.             for my $UserKey ( keys %ResponsibleUser ) {
  809.                 if ( $ResponsibleUser{$UserKey} ) {
  810.                     $Data{$_} =~ s/<OTRS_RESPONSIBLE_$UserKey>/$ResponsibleUser{$UserKey}/gi;
  811.                 }
  812.             }
  813.  
  814.             # cleanup
  815.             $Data{$_} =~ s/<OTRS_RESPONSIBLE_.+?>/-/gi;
  816.  
  817.             # replace other needed stuff
  818.             # replace ticket data
  819.             for my $TicketKey ( keys %Ticket ) {
  820.                 if ( $Ticket{$TicketKey} ) {
  821.                     $Data{$_} =~ s/<OTRS_TICKET_$TicketKey>/$Ticket{$TicketKey}/gi;
  822.                 }
  823.             }
  824.  
  825.             # cleanup all not needed <OTRS_TICKET_ tags
  826.             $Data{$_} =~ s/<OTRS_TICKET_.+?>/-/gi;
  827.  
  828.             # replace customer data
  829.             for my $CustomerKey ( keys %Customer ) {
  830.                 if ( $Customer{$CustomerKey} ) {
  831.                     $Data{$_} =~ s/<OTRS_CUSTOMER_$CustomerKey>/$Customer{$CustomerKey}/gi;
  832.                     $Data{$_} =~ s/<OTRS_CUSTOMER_DATA_$CustomerKey>/$Customer{$CustomerKey}/gi;
  833.                 }
  834.             }
  835.  
  836.             # cleanup all not needed <OTRS_CUSTOMER_ tags
  837.             $Data{$_} =~ s/<OTRS_CUSTOMER_.+?>/-/gi;
  838.             $Data{$_} =~ s/<OTRS_CUSTOMER_DATA_.+?>/-/gi;
  839.  
  840.             # replace config options
  841.             $Data{$_} =~ s{<OTRS_CONFIG_(.+?)>}{$Self->{ConfigObject}->Get($1)}egx;
  842.             $Data{$_} =~ s/<OTRS_CONFIG_.+?>/-/gi;
  843.         }
  844.  
  845.         # check some values
  846.         for (qw(From To Cc Bcc)) {
  847.             if ( $Data{$_} ) {
  848.                 for my $Email ( Mail::Address->parse( $Data{$_} ) ) {
  849.                     if ( !$Self->{CheckItemObject}->CheckEmail( Address => $Email->address() ) ) {
  850.                         $Error{"$_ invalid"} .= $Self->{CheckItemObject}->CheckError();
  851.                     }
  852.                 }
  853.             }
  854.         }
  855.  
  856.         # get free text config options
  857.         my %TicketFreeText = ();
  858.         for ( 1 .. 16 ) {
  859.             $TicketFreeText{"TicketFreeKey$_"} = $Self->{TicketObject}->TicketFreeTextGet(
  860.                 TicketID => $Self->{TicketID},
  861.                 Type     => "TicketFreeKey$_",
  862.                 Action   => $Self->{Action},
  863.                 UserID   => $Self->{UserID},
  864.             );
  865.             $TicketFreeText{"TicketFreeText$_"} = $Self->{TicketObject}->TicketFreeTextGet(
  866.                 TicketID => $Self->{TicketID},
  867.                 Type     => "TicketFreeText$_",
  868.                 Action   => $Self->{Action},
  869.                 UserID   => $Self->{UserID},
  870.             );
  871.         }
  872.         my %TicketFreeTextHTML = $Self->{LayoutObject}->AgentFreeText(
  873.             Ticket => \%Ticket,
  874.             Config => \%TicketFreeText,
  875.         );
  876.  
  877.         # free time
  878.         my %TicketFreeTime = ();
  879.         for ( 1 .. 6 ) {
  880.             $TicketFreeTime{ "TicketFreeTime" . $_ . 'Optional' }
  881.                 = $Self->{ConfigObject}->Get( 'TicketFreeTimeOptional' . $_ ) || 0;
  882.             $TicketFreeTime{ "TicketFreeTime" . $_ . 'Used' }
  883.                 = $GetParam{ 'TicketFreeTime' . $_ . 'Used' };
  884.  
  885.             if ( $Ticket{ "TicketFreeTime" . $_ } ) {
  886.                 (
  887.                     $TicketFreeTime{ "TicketFreeTime" . $_ . 'Secunde' },
  888.                     $TicketFreeTime{ "TicketFreeTime" . $_ . 'Minute' },
  889.                     $TicketFreeTime{ "TicketFreeTime" . $_ . 'Hour' },
  890.                     $TicketFreeTime{ "TicketFreeTime" . $_ . 'Day' },
  891.                     $TicketFreeTime{ "TicketFreeTime" . $_ . 'Month' },
  892.                     $TicketFreeTime{ "TicketFreeTime" . $_ . 'Year' }
  893.                     )
  894.                     = $Self->{TimeObject}->SystemTime2Date(
  895.                     SystemTime => $Self->{TimeObject}->TimeStamp2SystemTime(
  896.                         String => $Ticket{ "TicketFreeTime" . $_ },
  897.                     ),
  898.                     );
  899.                 $TicketFreeTime{ "TicketFreeTime" . $_ . 'Used' } = 1;
  900.             }
  901.         }
  902.         my %TicketFreeTimeHTML
  903.             = $Self->{LayoutObject}->AgentFreeDate( Ticket => \%TicketFreeTime, );
  904.  
  905.         # article free text
  906.         my %ArticleFreeText = ();
  907.         for ( 1 .. 3 ) {
  908.             $ArticleFreeText{"ArticleFreeKey$_"} = $Self->{TicketObject}->ArticleFreeTextGet(
  909.                 TicketID => $Self->{TicketID},
  910.                 Type     => "ArticleFreeKey$_",
  911.                 Action   => $Self->{Action},
  912.                 UserID   => $Self->{UserID},
  913.             );
  914.             $ArticleFreeText{"ArticleFreeText$_"} = $Self->{TicketObject}->ArticleFreeTextGet(
  915.                 TicketID => $Self->{TicketID},
  916.                 Type     => "ArticleFreeText$_",
  917.                 Action   => $Self->{Action},
  918.                 UserID   => $Self->{UserID},
  919.             );
  920.         }
  921.         my %ArticleFreeTextHTML = $Self->{LayoutObject}->TicketArticleFreeText(
  922.             Config  => \%ArticleFreeText,
  923.             Article => \%GetParam,
  924.         );
  925.  
  926.         # build view ...
  927.         $Output .= $Self->_Mask(
  928.             TicketID       => $Self->{TicketID},
  929.             NextStates     => $Self->_GetNextStates(),
  930.             ResponseFormat => $Self->{ResponseFormat},
  931.             Attachments    => \@Attachments,
  932.             Errors         => \%Error,
  933.             GetParam       => \%GetParam,
  934.             ResponseID     => $GetParam{ResponseID},
  935.             ReplyArticleID => $GetParam{ArticleID},
  936.             Types      => $Self->_GetTypes( QueueID => $Self->{QueueID} || 1 ),
  937.             %Ticket,
  938.             %Data,
  939.             %TicketFreeTextHTML,
  940.             %TicketFreeTimeHTML,
  941.             %ArticleFreeTextHTML,
  942.         );
  943.         $Output .= $Self->{LayoutObject}->Footer();
  944.         return $Output;
  945.     }
  946. }
  947.  
  948. sub _GetTypes {
  949.     my ( $Self, %Param ) = @_;
  950.  
  951.     my %Type = ();
  952.     # get type
  953.     if ( $Param{QueueID} || $Param{TicketID} ) {
  954.  
  955.         %Type = $Self->{TicketObject}->TicketTypeList(
  956.             %Param,
  957.             Action => $Self->{Action},
  958.             UserID => $Self->{UserID},
  959.         );
  960.     }
  961.     return \%Type;
  962. }
  963.  
  964. sub _GetNextStates {
  965.     my ( $Self, %Param ) = @_;
  966.  
  967.     # get next states
  968.     my %NextStates = $Self->{TicketObject}->StateList(
  969.         Action   => $Self->{Action},
  970.         TicketID => $Self->{TicketID},
  971.         UserID   => $Self->{UserID},
  972.     );
  973.     return \%NextStates;
  974. }
  975.  
  976. sub _Mask {
  977.     my ( $Self, %Param ) = @_;
  978.  
  979.     # build next states string
  980.     if ( !$Self->{Config}->{StateDefault} ) {
  981.         $Param{NextStates}->{''} = '-';
  982.     }
  983.     $Param{'NextStatesStrg'} = $Self->{LayoutObject}->OptionStrgHashRef(
  984.         Data     => $Param{NextStates},
  985.         Name     => 'StateID',
  986.         Selected => $Param{NextState} || $Self->{Config}->{StateDefault},
  987.     );
  988.  
  989.     # prepare errors!
  990.     if ( $Param{Errors} ) {
  991.         for ( keys %{ $Param{Errors} } ) {
  992.             $Param{$_} = "* " . $Self->{LayoutObject}->Ascii2Html( Text => $Param{Errors}->{$_} );
  993.         }
  994.     }
  995.  
  996.     # pending data string
  997.     $Param{PendingDateString} = $Self->{LayoutObject}->BuildDateSelection(
  998.         %Param,
  999.         Format => 'DateInputFormatLong',
  1000.         DiffTime => $Self->{ConfigObject}->Get('Ticket::Frontend::PendingDiffTime') || 0,
  1001.     );
  1002.  
  1003.     # js for time accounting
  1004.     if ( $Self->{ConfigObject}->Get('Ticket::Frontend::AccountTime') ) {
  1005.         $Self->{LayoutObject}->Block(
  1006.             Name => 'TimeUnitsJs',
  1007.             Data => \%Param,
  1008.         );
  1009.     }
  1010.     $Self->{LayoutObject}->Block(
  1011.         Name => 'Content',
  1012.         Data => {
  1013.             FormID => $Self->{FormID},
  1014.             %Param,
  1015.         },
  1016.     );
  1017.  
  1018.     # run compose modules
  1019.     if ( ref $Self->{ConfigObject}->Get('Ticket::Frontend::ArticleComposeModule') eq 'HASH' ) {
  1020.         my %Jobs = %{ $Self->{ConfigObject}->Get('Ticket::Frontend::ArticleComposeModule') };
  1021.         for my $Job ( sort keys %Jobs ) {
  1022.  
  1023.             # load module
  1024.             if ( $Self->{MainObject}->Require( $Jobs{$Job}->{Module} ) ) {
  1025.                 my $Object = $Jobs{$Job}->{Module}->new( %{$Self}, Debug => $Self->{Debug}, );
  1026.  
  1027.                 # get params
  1028.                 for ( sort keys %{ $Param{GetParam} } ) {
  1029.                     if ( !$Param{GetParam}->{$_} && $Param{$_} ) {
  1030.                         $Param{GetParam}->{$_} = $Param{$_};
  1031.                     }
  1032.                 }
  1033.                 for ( $Object->Option( %Param, %{ $Param{GetParam} }, Config => $Jobs{$Job} ) ) {
  1034.                     $Param{GetParam}->{$_} = $Self->{ParamObject}->GetParam( Param => $_ );
  1035.                 }
  1036.  
  1037.                 # run module
  1038.                 $Object->Run( %Param, %{ $Param{GetParam} }, Config => $Jobs{$Job} );
  1039.  
  1040.                 # get errors
  1041.                 %{ $Param{Errors} } = (
  1042.                     %{ $Param{Errors} },
  1043.                     $Object->Error( %{ $Param{GetParam} }, Config => $Jobs{$Job} )
  1044.                 );
  1045.             }
  1046.             else {
  1047.                 return $Self->{LayoutObject}->FatalError();
  1048.             }
  1049.         }
  1050.     }
  1051.  
  1052.  
  1053. ###################################################
  1054. ## proove of concept that we get here ###
  1055. #exit;
  1056.  
  1057.  
  1058.     # types
  1059.     if ( $Self->{ConfigObject}->Get('Ticket::Type') && $Self->{Config}->{TicketType} ) {
  1060.     ### exit if we get here
  1061.     exit;
  1062.         my %Type = $Self->{TicketObject}->TicketTypeList(
  1063.             %Param,
  1064.             Action => $Self->{Action},
  1065.             UserID => $Self->{UserID},
  1066.         );
  1067.         $Param{TypeStrg} = $Self->{LayoutObject}->BuildSelection(
  1068.             Data         => \%Type,
  1069.             Name         => 'TypeID',
  1070.             SelectedID   => $Param{TypeID},
  1071.             PossibleNone => 1,
  1072.             Sort         => 'AlphanumericValue',
  1073.             Translation  => 0,
  1074.             OnChange =>
  1075.                 "document.compose.Expand.value='3'; document.compose.submit(); return false;",
  1076.         );
  1077.         $Self->{LayoutObject}->Block(
  1078.             Name => 'Type',
  1079.             Data => {%Param},
  1080.         );
  1081.     }
  1082. #######################################################
  1083.     # ticket free text
  1084.     for my $Count ( 1 .. 16 ) {
  1085.         if ( $Self->{Config}->{'TicketFreeText'}->{$Count} ) {
  1086.             $Self->{LayoutObject}->Block(
  1087.                 Name => 'TicketFreeText',
  1088.                 Data => {
  1089.                     TicketFreeKeyField  => $Param{ 'TicketFreeKeyField' . $Count },
  1090.                     TicketFreeTextField => $Param{ 'TicketFreeTextField' . $Count },
  1091.                     Count               => $Count,
  1092.                     %Param,
  1093.                 },
  1094.             );
  1095.             $Self->{LayoutObject}->Block(
  1096.                 Name => 'TicketFreeText' . $Count,
  1097.                 Data => { %Param, Count => $Count, },
  1098.             );
  1099.         }
  1100.     }
  1101.     for my $Count ( 1 .. 6 ) {
  1102.         if ( $Self->{Config}->{'TicketFreeTime'}->{$Count} ) {
  1103.             $Self->{LayoutObject}->Block(
  1104.                 Name => 'TicketFreeTime',
  1105.                 Data => {
  1106.                     TicketFreeTimeKey => $Self->{ConfigObject}->Get( 'TicketFreeTimeKey' . $Count ),
  1107.                     TicketFreeTime    => $Param{ 'TicketFreeTime' . $Count },
  1108.                     Count             => $Count,
  1109.                 },
  1110.             );
  1111.             $Self->{LayoutObject}->Block(
  1112.                 Name => 'TicketFreeTime' . $Count,
  1113.                 Data => { %Param, Count => $Count, },
  1114.             );
  1115.         }
  1116.     }
  1117.  
  1118.     # article free text
  1119.     for my $Count ( 1 .. 3 ) {
  1120.         if ( $Self->{Config}->{'ArticleFreeText'}->{$Count} ) {
  1121.             $Self->{LayoutObject}->Block(
  1122.                 Name => 'ArticleFreeText',
  1123.                 Data => {
  1124.                     ArticleFreeKeyField  => $Param{ 'ArticleFreeKeyField' . $Count },
  1125.                     ArticleFreeTextField => $Param{ 'ArticleFreeTextField' . $Count },
  1126.                     Count                => $Count,
  1127.                 },
  1128.             );
  1129.             $Self->{LayoutObject}->Block(
  1130.                 Name => 'ArticleFreeText' . $Count,
  1131.                 Data => { %Param, Count => $Count, },
  1132.             );
  1133.         }
  1134.     }
  1135.  
  1136.     # show time accounting box
  1137.     if ( $Self->{ConfigObject}->Get('Ticket::Frontend::AccountTime') ) {
  1138.         $Self->{LayoutObject}->Block(
  1139.             Name => 'TimeUnits',
  1140.             Data => \%Param,
  1141.         );
  1142.     }
  1143.  
  1144.     # show spell check
  1145.     if (
  1146.         $Self->{ConfigObject}->Get('SpellChecker')
  1147.         && $Self->{LayoutObject}->{BrowserJavaScriptSupport}
  1148.         )
  1149.     {
  1150.         $Self->{LayoutObject}->Block(
  1151.             Name => 'SpellCheck',
  1152.             Data => {},
  1153.         );
  1154.     }
  1155.  
  1156.     # show address book
  1157.     if ( $Self->{LayoutObject}->{BrowserJavaScriptSupport} ) {
  1158.         $Self->{LayoutObject}->Block(
  1159.             Name => 'AddressBook',
  1160.             Data => {},
  1161.         );
  1162.     }
  1163.  
  1164.     # show attachments
  1165.     for my $DataRef ( @{ $Param{Attachments} } ) {
  1166.         $Self->{LayoutObject}->Block(
  1167.             Name => 'Attachment',
  1168.             Data => $DataRef,
  1169.         );
  1170.     }
  1171.  
  1172.     # java script check for required free text fields by form submit
  1173.     for my $Key ( keys %{ $Self->{Config}->{TicketFreeText} } ) {
  1174.         if ( $Self->{Config}->{TicketFreeText}->{$Key} == 2 ) {
  1175.             $Self->{LayoutObject}->Block(
  1176.                 Name => 'TicketFreeTextCheckJs',
  1177.                 Data => {
  1178.                     TicketFreeTextField => "TicketFreeText$Key",
  1179.                     TicketFreeKeyField  => "TicketFreeKey$Key",
  1180.                 },
  1181.             );
  1182.         }
  1183.     }
  1184.  
  1185.     # java script check for required free time fields by form submit
  1186.     for my $Key ( keys %{ $Self->{Config}->{TicketFreeTime} } ) {
  1187.         if ( $Self->{Config}->{TicketFreeTime}->{$Key} == 2 ) {
  1188.             $Self->{LayoutObject}->Block(
  1189.                 Name => 'TicketFreeTimeCheckJs',
  1190.                 Data => {
  1191.                     TicketFreeTimeCheck => 'TicketFreeTime' . $Key . 'Used',
  1192.                     TicketFreeTimeField => 'TicketFreeTime' . $Key,
  1193.                     TicketFreeTimeKey   => $Self->{ConfigObject}->Get( 'TicketFreeTimeKey' . $Key ),
  1194.                 },
  1195.             );
  1196.         }
  1197.     }
  1198.  
  1199.  
  1200.  
  1201.  
  1202.  
  1203.     # create & return output
  1204.     return $Self->{LayoutObject}->Output( TemplateFile => 'AgentTicketCompose', Data => \%Param );
  1205. }
  1206.  
  1207. 1;
  1208.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement