import rt 3.4.6
[freeside.git] / rt / lib / RT / Action / CreateTickets.pm
index 4e72e11..b708f2e 100644 (file)
@@ -2,7 +2,7 @@
 # 
 # COPYRIGHT:
 #  
-# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC 
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC 
 #                                          <jesse@bestpractical.com>
 # 
 # (Except where explicitly superseded by other copyright notices)
@@ -22,9 +22,7 @@
 # 
 # You should have received a copy of the GNU General Public License
 # along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301 or visit their web page on the internet at
-# http://www.gnu.org/copyleft/gpl.html.
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 # 
 # 
 # CONTRIBUTION SUBMISSION POLICY:
@@ -190,7 +188,7 @@ A complete list of acceptable fields for this beastie:
        Started         => 
        Resolved        => 
        Owner           => Username or id of an RT user who can and should own 
-                          this ticket; forces the owner if necessary
+                          this ticket
    +   Requestor       => Email address
    +   Cc              => Email address 
    +   AdminCc         => Email address 
@@ -210,15 +208,8 @@ A complete list of acceptable fields for this beastie:
                           within a template after a Content: header is treated
                           as content until we hit a line containing only 
                           ENDOFCONTENT
-       ContentType     => the content-type of the Content field.  Defaults to
-                          'text/plain'
-       UpdateType      => 'correspond' or 'comment'; used in conjunction with
-                          'content' if this is an update.  Defaults to
-                          'correspond'
-
+       ContentType     => the content-type of the Content field
        CustomField-<id#> => custom field value
-       CF-name           => custom field value
-       CustomField-name  => custom field value
 
 Fields marked with an * are required.
 
@@ -554,10 +545,7 @@ sub Prepare {
 
     }
 
-    $self->Parse(
-        Content        => $self->TemplateObj->Content,
-        _ActiveContent => 1
-    );
+    $self->Parse( Content => $self->TemplateObj->Content, _ActiveContent => 1);
     return 1;
 
 }
@@ -578,41 +566,43 @@ sub CreateByTemplate {
     use bytes;
 
     local %T::Tickets = %T::Tickets;
-    local $T::TOP     = $T::TOP;
-    local $T::ID      = $T::ID;
+    local $T::TOP = $T::TOP;
+    local $T::ID = $T::ID;
     $T::Tickets{'TOP'} = $T::TOP = $top if $top;
 
     my $ticketargs;
     my ( @links, @postponed );
     foreach my $template_id ( @{ $self->{'create_tickets'} } ) {
         $RT::Logger->debug("Workflow: processing $template_id of $T::TOP")
-            if $T::TOP;
+          if $T::TOP;
 
         $T::ID    = $template_id;
         @T::AllID = @{ $self->{'create_tickets'} };
 
-        ( $T::Tickets{$template_id}, $ticketargs )
-            = $self->ParseLines( $template_id, \@links, \@postponed );
+        ( $T::Tickets{$template_id}, $ticketargs ) =
+          $self->ParseLines( $template_id, \@links, \@postponed );
 
         # Now we have a %args to work with.
         # Make sure we have at least the minimum set of
         # reasonable data and do our thang
 
-        my ( $id, $transid, $msg )
-            = $T::Tickets{$template_id}->Create(%$ticketargs);
+        my ( $id, $transid, $msg ) =
+          $T::Tickets{$template_id}->Create(%$ticketargs);
 
         foreach my $res ( split( '\n', $msg ) ) {
             push @results,
-                $T::Tickets{$template_id}
-                ->loc( "Ticket [_1]", $T::Tickets{$template_id}->Id ) . ': '
-                . $res;
+              $T::Tickets{$template_id}
+              ->loc( "Ticket [_1]", $T::Tickets{$template_id}->Id ) . ': '
+              . $res;
         }
         if ( !$id ) {
             if ( $self->TicketObj ) {
-                $msg = "Couldn't create related ticket $template_id for "
-                    . $self->TicketObj->Id . " "
-                    . $msg;
-            } else {
+                $msg =
+                    "Couldn't create related ticket $template_id for "
+                  . $self->TicketObj->Id . " "
+                  . $msg;
+            }
+            else {
                 $msg = "Couldn't create ticket $template_id " . $msg;
             }
 
@@ -622,8 +612,8 @@ sub CreateByTemplate {
 
         $RT::Logger->debug("Assigned $template_id with $id");
         $T::Tickets{$template_id}->SetOriginObj( $self->TicketObj )
-            if $self->TicketObj
-            && $T::Tickets{$template_id}->can('SetOriginObj');
+          if $self->TicketObj
+          && $T::Tickets{$template_id}->can('SetOriginObj');
 
     }
 
@@ -641,7 +631,7 @@ sub UpdateByTemplate {
 
     my @results;
     local %T::Tickets = %T::Tickets;
-    local $T::ID      = $T::ID;
+    local $T::ID = $T::ID;
 
     my $ticketargs;
     my ( @links, @postponed );
@@ -651,35 +641,37 @@ sub UpdateByTemplate {
         $T::ID    = $template_id;
         @T::AllID = @{ $self->{'update_tickets'} };
 
-        ( $T::Tickets{$template_id}, $ticketargs )
-            = $self->ParseLines( $template_id, \@links, \@postponed );
+        ( $T::Tickets{$template_id}, $ticketargs ) =
+          $self->ParseLines( $template_id, \@links, \@postponed );
 
         # Now we have a %args to work with.
         # Make sure we have at least the minimum set of
         # reasonable data and do our thang
 
         my @attribs = qw(
-            Subject
-            FinalPriority
-            Priority
-            TimeEstimated
-            TimeWorked
-            TimeLeft
-            Status
-            Queue
-            Due
-            Starts
-            Started
-            Resolved
+          Subject
+          FinalPriority
+          Priority
+          TimeEstimated
+          TimeWorked
+          TimeLeft
+          Status
+          Queue
+          Due
+          Starts
+          Started
+          Resolved
         );
 
         my $id = $template_id;
         $id =~ s/update-(\d+).*/$1/;
-        my ($loaded, $msg) = $T::Tickets{$template_id}->LoadById($id);
+        $T::Tickets{$template_id}->Load($id);
+
+        my $msg;
+        if ( !$T::Tickets{$template_id}->Id ) {
+            $msg = "Couldn't update ticket $template_id " . $msg;
 
-        unless ( $loaded ) {
-            $RT::Logger->error("Couldn't update ticket $template_id: " . $msg);
-            push @results, $self->loc( "Couldn't load ticket '[_1]'", $id );
+            $RT::Logger->error($msg);
             next;
         }
 
@@ -689,68 +681,60 @@ sub UpdateByTemplate {
         my $base_id = "base-$1";
         my $base    = $self->{'templates'}->{$base_id};
         if ($base) {
-            $base    =~ s/\r//g;
-            $base    =~ s/\n+$//;
-            $current =~ s/\n+$//;
-
-            # If we have no base template, set what we can.
-            if ( $base ne $current ) {
-                push @results,
-                    "Could not update ticket "
-                    . $T::Tickets{$template_id}->Id
-                    . ": Ticket has changed";
-                next;
-            }
+        $base    =~ s/\r//g;
+        $base    =~ s/\n+$//;
+        $current =~ s/\n+$//;
+
+        # If we have no base template, set what we can.
+        if ($base ne $current)  {
+            push @results,
+              "Could not update ticket "
+              . $T::Tickets{$template_id}->Id
+              . ": Ticket has changed";
+            next;
+        }
         }
         push @results, $T::Tickets{$template_id}->Update(
             AttributesRef => \@attribs,
             ARGSRef       => $ticketargs
         );
 
-        if ( $ticketargs->{'Owner'} ) {
-            ($id, $msg) = $T::Tickets{$template_id}->SetOwner($ticketargs->{'Owner'}, "Force");
-            push @results, $msg unless $msg eq $self->loc("That user already owns that ticket");
-        }
-
         push @results,
-            $self->UpdateWatchers( $T::Tickets{$template_id}, $ticketargs );
+          $self->UpdateWatchers( $T::Tickets{$template_id}, $ticketargs );
 
-        push @results,
-            $self->UpdateCustomFields( $T::Tickets{$template_id}, $ticketargs );
-
-        next unless $ticketargs->{'MIMEObj'};
-        if ( $ticketargs->{'UpdateType'} =~ /^(private|comment)$/i ) {
-            my ( $Transaction, $Description, $Object )
-                = $T::Tickets{$template_id}->Comment(
+        next unless exists $ticketargs->{'UpdateType'};
+        if ( $ticketargs->{'UpdateType'} =~ /^(private|public)$/ ) {
+            my ( $Transaction, $Description, $Object ) =
+              $T::Tickets{$template_id}->Comment(
+                CcMessageTo  => $ticketargs->{'Cc'},
                 BccMessageTo => $ticketargs->{'Bcc'},
                 MIMEObj      => $ticketargs->{'MIMEObj'},
                 TimeTaken    => $ticketargs->{'TimeWorked'}
-                );
+              );
             push( @results,
                 $T::Tickets{$template_id}
-                    ->loc( "Ticket [_1]", $T::Tickets{$template_id}->id )
-                    . ': '
-                    . $Description );
-        } elsif ( $ticketargs->{'UpdateType'} =~ /^(public|response|correspond)$/i ) {
-            my ( $Transaction, $Description, $Object )
-                = $T::Tickets{$template_id}->Correspond(
+                  ->loc( "Ticket [_1]", $T::Tickets{$template_id}->id ) . ': '
+                  . $Description );
+        }
+        elsif ( $ticketargs->{'UpdateType'} eq 'response' ) {
+            my ( $Transaction, $Description, $Object ) =
+              $T::Tickets{$template_id}->Correspond(
+                CcMessageTo  => $ticketargs->{'Cc'},
                 BccMessageTo => $ticketargs->{'Bcc'},
                 MIMEObj      => $ticketargs->{'MIMEObj'},
                 TimeTaken    => $ticketargs->{'TimeWorked'}
-                );
+              );
             push( @results,
                 $T::Tickets{$template_id}
-                    ->loc( "Ticket [_1]", $T::Tickets{$template_id}->id )
-                    . ': '
-                    . $Description );
-        } else {
-            push(
-                @results,
-                $T::Tickets{$template_id}->loc(
-                    "Update type was neither correspondence nor comment.")
-                    . " "
-                    . $T::Tickets{$template_id}->loc("Update not recorded.")
-            );
+                  ->loc( "Ticket [_1]", $T::Tickets{$template_id}->id ) . ': '
+                  . $Description );
+        }
+        else {
+            push( @results,
+                $T::Tickets{$template_id}
+                  ->loc("Update type was neither correspondence nor comment.")
+                  . " "
+                  . $T::Tickets{$template_id}->loc("Update not recorded.") );
         }
     }
 
@@ -769,58 +753,35 @@ allowing you to embed active perl in your templates.
 =cut
 
 sub Parse {
-    my $self = shift;
-    my %args = (
-        Content        => undef,
-        Queue          => undef,
-        Requestor      => undef,
-        _ActiveContent => undef,
-        @_
-    );
-
-    if ( $args{'_ActiveContent'} ) {
-        $self->{'UsePerlTextTemplate'} = 1;
+    my $self          = shift;
+    my %args = ( Content => undef,
+                 Queue => undef,
+                 Requestor => undef,
+                 _ActiveContent => undef,
+                @_);
+
+    if ($args{'_ActiveContent'}) {
+        $self->{'UsePerlTextTemplate'} =1;
     } else {
 
         $self->{'UsePerlTextTemplate'} = 0;
     }
 
-    if ( substr( $args{'Content'}, 0, 3 ) eq '===' ) {
-        $self->_ParseMultilineTemplate(%args);
-    } elsif ( $args{'Content'} =~ /(?:\t|,)/i ) {
-        $self->_ParseXSVTemplate(%args);
-
-    }
-}
-
-=head2 _ParseMultilineTemplate
-
-Parses mulitline templates. Things like:
-
- ===Create-Ticket ... 
-
-Takes the same arguments as Parse
-
-=cut
-
-sub _ParseMultilineTemplate {
-    my $self = shift;
-    my %args = (@_);
-
+    my @template_order;
     my $template_id;
     my ( $queue, $requestor );
+    if ( substr( $args{'Content'}, 0, 3 ) eq '===' ) {
         $RT::Logger->debug("Line: ===");
         foreach my $line ( split( /\n/, $args{'Content'} ) ) {
             $line =~ s/\r$//;
             $RT::Logger->debug("Line: $line");
             if ( $line =~ /^===/ ) {
                 if ( $template_id && !$queue && $args{'Queue'} ) {
-                    $self->{'templates'}->{$template_id}
-                        .= "Queue: $args{'Queue'}\n";
+                    $self->{'templates'}->{$template_id} .= "Queue: $args{'Queue'}\n";
                 }
                 if ( $template_id && !$requestor && $args{'Requestor'} ) {
-                    $self->{'templates'}->{$template_id}
-                        .= "Requestor: $args{'Requestor'}\n";
+                    $self->{'templates'}->{$template_id} .=
+                      "Requestor: $args{'Requestor'}\n";
                 }
                 $queue     = 0;
                 $requestor = 0;
@@ -829,33 +790,37 @@ sub _ParseMultilineTemplate {
                 $template_id = "create-$1";
                 $RT::Logger->debug("****  Create ticket: $template_id");
                 push @{ $self->{'create_tickets'} }, $template_id;
-            } elsif ( $line =~ /^===Update-Ticket: (.*)$/ ) {
+            }
+            elsif ( $line =~ /^===Update-Ticket: (.*)$/ ) {
                 $template_id = "update-$1";
                 $RT::Logger->debug("****  Update ticket: $template_id");
                 push @{ $self->{'update_tickets'} }, $template_id;
-            } elsif ( $line =~ /^===Base-Ticket: (.*)$/ ) {
+            }
+            elsif ( $line =~ /^===Base-Ticket: (.*)$/ ) {
                 $template_id = "base-$1";
                 $RT::Logger->debug("****  Base ticket: $template_id");
                 push @{ $self->{'base_tickets'} }, $template_id;
-            } elsif ( $line =~ /^===#.*$/ ) {    # a comment
+            }
+            elsif ( $line =~ /^===#.*$/ ) {    # a comment
                 next;
-            } else {
+            }
+            else {
                 if ( $line =~ /^Queue:(.*)/i ) {
                     $queue = 1;
                     my $value = $1;
                     $value =~ s/^\s//;
                     $value =~ s/\s$//;
-                    if ( !$value && $args{'Queue'} ) {
+                    if ( !$value && $args{'Queue'}) {
                         $value = $args{'Queue'};
                         $line  = "Queue: $value";
                     }
                 }
-                if ( $line =~ /^Requestors?:(.*)/i ) {
+                if ( $line =~ /^Requestor:(.*)/i ) {
                     $requestor = 1;
                     my $value = $1;
                     $value =~ s/^\s//;
                     $value =~ s/\s$//;
-                    if ( !$value && $args{'Requestor'} ) {
+                    if ( !$value && $args{'Requestor'}) {
                         $value = $args{'Requestor'};
                         $line  = "Requestor: $value";
                     }
@@ -863,10 +828,118 @@ sub _ParseMultilineTemplate {
                 $self->{'templates'}->{$template_id} .= $line . "\n";
             }
         }
-        if ( $template_id && !$queue && $args{'Queue'} ) {
-            $self->{'templates'}->{$template_id} .= "Queue: $args{'Queue'}\n";
+       if ( $template_id && !$queue && $args{'Queue'} ) {
+           $self->{'templates'}->{$template_id} .= "Queue: $args{'Queue'}\n";
+       }
+    }
+    elsif ( substr( $args{'Content'}, 0, 2 ) =~ /^id$/i ) {
+        $RT::Logger->debug("Line: id");
+        use Regexp::Common qw(delimited);
+        my $first = substr( $args{'Content'}, 0, index( $args{'Content'}, "\n" ) );
+        $first =~ s/\r$//;
+
+        my $delimiter;
+        if ( $first =~ /\t/ ) {
+            $delimiter = "\t";
+        }
+        else {
+            $delimiter = ',';
+        }
+        my @fields    = split( /$delimiter/, $first );
+        
+
+        my $delimiter_re = qr[$delimiter];
+
+        my $delimited = qr[[^$delimiter]+];
+        my $empty     = qr[^[$delimiter](?=[$delimiter])];
+        my $justquoted = qr[$RE{quoted}];
+
+        $args{'Content'} = substr( $args{'Content'}, index( $args{'Content'}, "\n" ) + 1 );
+        $RT::Logger->debug("First: $first");
+
+        my $queue;
+        foreach my $line ( split( /\n/, $args{'Content'} ) ) {
+            next unless $line;
+            $RT::Logger->debug("Line: $line");
+
+            # first item is $template_id
+            my $i = 0;
+            my $template_id;
+            while ($line && $line =~ s/^($justquoted|.*?)(?:$delimiter_re|$)//ix) {
+                if ( $i == 0 ) {
+                    $queue     = 0;
+                    $requestor = 0;
+                    my $tid = $1;
+                    $tid =~ s/^\s//;
+                    $tid =~ s/\s$//;
+                    next unless $tid;
+                   
+                     
+                    if ($tid =~ /^\d+$/) {
+                        $template_id = 'update-' . $tid;
+                        push @{ $self->{'update_tickets'} }, $template_id;
+
+                    } elsif ($tid =~ /^#base-(\d+)$/) {
+
+                        $template_id = 'base-' . $1;
+                        push @{ $self->{'base_tickets'} }, $template_id;
+
+                    } else {
+                        $template_id = 'create-' . $tid;
+                        push @{ $self->{'create_tickets'} }, $template_id;
+                    }
+                    $RT::Logger->debug("template_id: $tid");
+                }
+                else {
+                    my $value = $1;
+                    $value = '' if ( $value =~ /^$delimiter$/ );
+                    if ($value =~ /^$RE{delimited}{-delim=>qq{\'\"}}$/) {
+                        substr($value,0,1) = "";
+                    substr($value,-1,1) = "";
+                    }
+                    my $field = $fields[$i];
+                    next unless $field;
+                    $field =~ s/^\s//;
+                    $field =~ s/\s$//;
+                    if (   $field =~ /Body/i
+                        || $field =~ /Data/i
+                        || $field =~ /Message/i )
+                    {
+                        $field = 'Content';
+                    }
+                    if ( $field =~ /Summary/i ) {
+                        $field = 'Subject';
+                    }
+                    if ( $field =~ /Queue/i ) {
+                        $queue = 1;
+                        if ( !$value && $args{'Queue'} ) {
+                            $value = $args{'Queue'};
+                        }
+                    }
+                    if ( $field =~ /Requestor/i ) {
+                        $requestor = 1;
+                        if ( !$value && $args{'Requestor'} ) {
+                            $value = $args{'Requestor'};
+                        }
+                    }
+                    $self->{'templates'}->{$template_id} .= $field . ": ";
+                    $self->{'templates'}->{$template_id} .= $value || "";
+                    $self->{'templates'}->{$template_id} .= "\n";
+                    $self->{'templates'}->{$template_id} .= "ENDOFCONTENT\n"
+                      if $field =~ /content/i;
+                }
+                $i++;
+            }
+            if ( !$queue && $args{'Queue'} ) {
+                $self->{'templates'}->{$template_id} .= "Queue: $args{'Queue'}\n";
+            }
+            if ( !$requestor && $args{'Requestor'} ) {
+                $self->{'templates'}->{$template_id} .=
+                  "Requestor: $args{'Requestor'}\n";
+            }
         }
     }
+}
 
 sub ParseLines {
     my $self        = shift;
@@ -874,6 +947,7 @@ sub ParseLines {
     my $links       = shift;
     my $postponed   = shift;
 
+
     my $content = $self->{'templates'}->{$template_id};
 
     if ( $self->{'UsePerlTextTemplate'} ) {
@@ -906,77 +980,69 @@ sub ParseLines {
             next;
         }
     }
-
-    my $TicketObj ||= RT::Ticket->new( $self->CurrentUser );
+    
+    my $TicketObj ||= RT::Ticket->new($self->CurrentUser);
 
     my %args;
-    my %original_tags;
     my @lines = ( split( /\n/, $content ) );
     while ( defined( my $line = shift @lines ) ) {
         if ( $line =~ /^(.*?):(?:\s+)(.*?)(?:\s*)$/ ) {
             my $value = $2;
-            my $original_tag = $1;
-            my $tag   = lc($original_tag);
+            my $tag   = lc($1);
             $tag =~ s/-//g;
-            $tag =~ s/^(requestor|cc|admincc)s?$/$1/i;
-
-            $original_tags{$tag} = $original_tag;
 
             if ( ref( $args{$tag} ) )
             {    #If it's an array, we want to push the value
                 push @{ $args{$tag} }, $value;
-            } elsif ( defined( $args{$tag} ) )
+            }
+            elsif ( defined( $args{$tag} ) )
             {    #if we're about to get a second value, make it an array
                 $args{$tag} = [ $args{$tag}, $value ];
-            } else {    #if there's nothing there, just set the value
+            }
+            else {    #if there's nothing there, just set the value
                 $args{$tag} = $value;
             }
 
-            if ( $tag =~ /^content$/i ) {    #just build up the content
+            if ( $tag eq 'content' ) {    #just build up the content
                                           # convert it to an array
                 $args{$tag} = defined($value) ? [ $value . "\n" ] : [];
                 while ( defined( my $l = shift @lines ) ) {
                     last if ( $l =~ /^ENDOFCONTENT\s*$/ );
                     push @{ $args{'content'} }, $l . "\n";
                 }
-            } else {
+            }
+            else {
+
                 # if it's not content, strip leading and trailing spaces
                 if ( $args{$tag} ) {
                     $args{$tag} =~ s/^\s+//g;
                     $args{$tag} =~ s/\s+$//g;
                 }
-                if (($tag =~ /^(requestor|cc|admincc)$/i or grep {lc $_ eq $tag} keys %LINKTYPEMAP) and $args{$tag} =~ /,/) {
-                    $args{$tag} = [ split /,\s*/, $args{$tag} ];
-                }
             }
         }
     }
 
     foreach my $date qw(due starts started resolved) {
-        my $dateobj = RT::Date->new( $self->CurrentUser );
+        my $dateobj = RT::Date->new($self->CurrentUser);
         next unless $args{$date};
         if ( $args{$date} =~ /^\d+$/ ) {
             $dateobj->Set( Format => 'unix', Value => $args{$date} );
-        } else {
-            eval {
-                $dateobj->Set( Format => 'iso', Value => $args{$date} );
-            };
-            if ($@ or $dateobj->Unix <= 0) {
-                $dateobj->Set( Format => 'unknown', Value => $args{$date} );
-            }
+        }
+        else {
+            $dateobj->Set( Format => 'unknown', Value => $args{$date} );
         }
         $args{$date} = $dateobj->ISO;
     }
 
     $args{'requestor'} ||= $self->TicketObj->Requestors->MemberEmailAddresses
-        if $self->TicketObj;
+      if $self->TicketObj;
 
     $args{'type'} ||= 'ticket';
 
     my %ticketargs = (
         Queue           => $args{'queue'},
         Subject         => $args{'subject'},
-        Status          => $args{'status'} || 'new',
+        Status          => 'new',
         Due             => $args{'due'},
         Starts          => $args{'starts'},
         Started         => $args{'started'},
@@ -993,32 +1059,19 @@ sub ParseLines {
         Type            => $args{'type'},
     );
 
-    if ( $args{content} ) {
+    if ($args{content}) {
         my $mimeobj = MIME::Entity->new();
         $mimeobj->build(
-            Type => $args{'contenttype'} || 'text/plain',
+            Type => $args{'contenttype'},
             Data => $args{'content'}
         );
         $ticketargs{MIMEObj} = $mimeobj;
-        $ticketargs{UpdateType} = $args{'updatetype'} || 'correspond';
+        $ticketargs{UpdateType} = $args{'updatetype'} if $args{'updatetype'};
     }
 
-    foreach my $tag ( keys(%args) ) {
-        # if the tag was added later, skip it
-        my $orig_tag = $original_tags{$tag} or next;
-        if ( $orig_tag =~ /^customfield-?(\d+)$/i ) {
-            $ticketargs{ "CustomField-" . $1 } = $args{$tag};
-        } elsif ( $orig_tag =~ /^(?:customfield|cf)-?(.*)$/i ) {
-            my $cf = RT::CustomField->new( $self->CurrentUser );
-            $cf->LoadByName( Name => $1, Queue => $ticketargs{Queue} );
-            $ticketargs{ "CustomField-" . $cf->id } = $args{$tag};
-        } elsif ($orig_tag) {
-            my $cf = RT::CustomField->new( $self->CurrentUser );
-            $cf->LoadByName( Name => $orig_tag, Queue => $ticketargs{Queue} );
-            next unless ($cf->id) ;
-            $ticketargs{ "CustomField-" . $cf->id } = $args{$tag};
-
-        }
+    foreach my $key ( keys(%args) ) {
+        $key =~ /^customfield(\d+)$/ or next;
+        $ticketargs{ "CustomField-" . $1 } = $args{$key};
     }
 
     $self->GetDeferred( \%args, $template_id, $links, $postponed );
@@ -1026,137 +1079,6 @@ sub ParseLines {
     return $TicketObj, \%ticketargs;
 }
 
-
-=head2 _ParseXSVTemplate 
-
-Parses a tab or comma delimited template. Should only ever be called by Parse
-
-=cut
-
-sub _ParseXSVTemplate {
-    my $self = shift;
-    my %args = (@_);
-
-    use Regexp::Common qw(delimited);
-    my($first, $content) = split(/\r?\n/, $args{'Content'}, 2);
-
-    my $delimiter;
-    if ( $first =~ /\t/ ) {
-        $delimiter = "\t";
-    } else {
-        $delimiter = ',';
-    }
-    my @fields = split( /$delimiter/, $first );
-
-    my $delimiter_re = qr[$delimiter];
-    my $justquoted = qr[$RE{quoted}];
-
-    # Used to generate automatic template ids
-    my $autoid = 1;
-
-  LINE:
-    while ($content) {
-        $content =~ s/^(\s*\r?\n)+//;
-
-        # Keep track of Queue and Requestor, so we can provide defaults
-        my $queue;
-        my $requestor;
-
-        # The template for this line
-        my $template;
-
-        # What column we're on
-        my $i = 0;
-
-        # If the last iteration was the end of the line
-        my $EOL = 0;
-
-        # The template id
-        my $template_id;
-
-      COLUMN:
-        while (not $EOL and length $content and $content =~ s/^($justquoted|.*?)($delimiter_re|$)//smix) {
-            $EOL = not $2;
-
-            # Strip off quotes, if they exist
-            my $value = $1;
-            if ( $value =~ /^$RE{delimited}{-delim=>qq{\'\"}}$/ ) {
-                substr( $value, 0,  1 ) = "";
-                substr( $value, -1, 1 ) = "";
-            }
-
-            # What column is this?
-            my $field = $fields[$i++];
-            next COLUMN unless $field =~ /\S/;
-            $field =~ s/^\s//;
-            $field =~ s/\s$//;
-
-            if ( $field =~ /^id$/i ) {
-                # Special case if this is the ID column
-                if ( $value =~ /^\d+$/ ) {
-                    $template_id = 'update-' . $value;
-                    push @{ $self->{'update_tickets'} }, $template_id;
-                } elsif ( $value =~ /^#base-(\d+)$/ ) {
-                    $template_id = 'base-' . $1;
-                    push @{ $self->{'base_tickets'} }, $template_id;
-                } elsif ( $value =~ /\S/ ) {
-                    $template_id = 'create-' . $value;
-                    push @{ $self->{'create_tickets'} }, $template_id;
-                }
-            } else {
-                # Some translations
-                if (   $field =~ /^Body$/i
-                    || $field =~ /^Data$/i
-                    || $field =~ /^Message$/i )
-                  {
-                  $field = 'Content';
-                } elsif ( $field =~ /^Summary$/i ) {
-                    $field = 'Subject';
-                } elsif ( $field =~ /^Queue$/i ) {
-                    # Note that we found a queue
-                    $queue = 1;
-                    $value ||= $args{'Queue'};
-                } elsif ( $field =~ /^Requestors?$/i ) {
-                    $field = 'Requestor'; # Remove plural
-                    # Note that we found a requestor
-                    $requestor = 1;
-                    $value ||= $args{'Requestor'};
-                }
-
-                # Tack onto the end of the template
-                $template .= $field . ": ";
-                $template .= (defined $value ? $value : "");
-                $template .= "\n";
-                $template .= "ENDOFCONTENT\n"
-                  if $field =~ /^Content$/i;
-            }
-        }
-
-        # Ignore blank lines
-        next unless $template;
-        
-        # If we didn't find a queue of requestor, tack on the defaults
-        if ( !$queue && $args{'Queue'} ) {
-            $template .= "Queue: $args{'Queue'}\n";
-        }
-        if ( !$requestor && $args{'Requestor'} ) {
-            $template .= "Requestor: $args{'Requestor'}\n";
-        }
-
-        # If we never found an ID, come up with one
-        unless ($template_id) {
-            $autoid++ while exists $self->{'templates'}->{"create-auto-$autoid"};
-            $template_id = "create-auto-$autoid";
-            # Also, it's a ticket to create
-            push @{ $self->{'create_tickets'} }, $template_id;
-        }
-        
-        # Save the template we generated
-        $self->{'templates'}->{$template_id} = $template;
-
-    }
-}
-
 sub GetDeferred {
     my $self      = shift;
     my $args      = shift;
@@ -1166,16 +1088,17 @@ sub GetDeferred {
 
     # Deferred processing
     push @$links,
-        (
+      (
         $id,
-        {   DependsOn    => $args->{'dependson'},
+        {
+            DependsOn    => $args->{'dependson'},
             DependedOnBy => $args->{'dependedonby'},
             RefersTo     => $args->{'refersto'},
             ReferredToBy => $args->{'referredtoby'},
             Children     => $args->{'children'},
             Parents      => $args->{'parents'},
         }
-        );
+      );
 
     push @$postponed, (
 
@@ -1192,7 +1115,7 @@ sub GetUpdateTemplate {
     $string .= "Queue: " . $t->QueueObj->Name . "\n";
     $string .= "Subject: " . $t->Subject . "\n";
     $string .= "Status: " . $t->Status . "\n";
-    $string .= "UpdateType: correspond\n";
+    $string .= "UpdateType: response\n";
     $string .= "Content: \n";
     $string .= "ENDOFCONTENT\n";
     $string .= "Due: " . $t->DueObj->AsString . "\n";
@@ -1311,31 +1234,14 @@ sub UpdateWatchers {
     foreach my $type qw(Requestor Cc AdminCc) {
         my $method  = $type . 'Addresses';
         my $oldaddr = $ticket->$method;
-
+    
+    
         # Skip unless we have a defined field
         next unless defined $args->{$type};
         my $newaddr = $args->{$type};
 
-        my @old = split( /,\s*/, $oldaddr );
-        my @new;
-        for (ref $newaddr ? @{$newaddr} : split( /,\s*/, $newaddr )) {
-            # Sometimes these are email addresses, sometimes they're
-            # users.  Try to guess which is which, as we want to deal
-            # with email addresses if at all possible.
-            if (/^\S+@\S+$/) {
-                push @new, $_;
-            } else {
-                # It doesn't look like an email address.  Try to load it.
-                my $user = RT::User->new($self->CurrentUser);
-                $user->Load($_);
-                if ($user->Id) {
-                    push @new, $user->EmailAddress;
-                } else {
-                    push @new, $_;
-                }
-            }
-        }
-
+        my @old = split( ', ', $oldaddr );
+        my @new = split( ', ', $newaddr );
         my %oldhash = map { $_ => 1 } @old;
         my %newhash = map { $_ => 1 } @new;
 
@@ -1349,7 +1255,7 @@ sub UpdateWatchers {
             );
 
             push @results,
-                $ticket->loc( "Ticket [_1]", $ticket->Id ) . ': ' . $msg;
+              $ticket->loc( "Ticket [_1]", $ticket->Id ) . ': ' . $msg;
         }
 
         foreach (@delete) {
@@ -1358,47 +1264,7 @@ sub UpdateWatchers {
                 Email => $_
             );
             push @results,
-                $ticket->loc( "Ticket [_1]", $ticket->Id ) . ': ' . $msg;
-        }
-    }
-    return @results;
-}
-
-sub UpdateCustomFields {
-    my $self   = shift;
-    my $ticket = shift;
-    my $args   = shift;
-
-    my @results;
-    foreach my $arg (keys %{$args}) {
-        next unless $arg =~ /^CustomField-(\d+)$/;
-        my $cf = $1;
-
-        my $CustomFieldObj = RT::CustomField->new($self->CurrentUser);
-        $CustomFieldObj->LoadById($cf);
-
-        my @values;
-        if ($CustomFieldObj->Type =~ /text/i) { # Both Text and Wikitext
-            @values = ($args->{$arg});
-        } else {
-            @values = split /\n/, $args->{$arg};
-        }
-        
-        if ( ($CustomFieldObj->Type eq 'Freeform' 
-              && ! $CustomFieldObj->SingleValue) ||
-              $CustomFieldObj->Type =~ /text/i) {
-            foreach my $val (@values) {
-                $val =~ s/\r//g;
-            }
-        }
-
-        foreach my $value (@values) {
-            next unless length($value);
-            my ( $val, $msg ) = $ticket->AddCustomFieldValue(
-                Field => $cf,
-                Value => $value
-            );
-            push ( @results, $msg );
+              $ticket->loc( "Ticket [_1]", $ticket->Id ) . ': ' . $msg;
         }
     }
     return @results;
@@ -1423,22 +1289,21 @@ sub PostProcess {
             {
                 next unless $link;
 
-                if ( $link =~ /^TOP$/i ) {
-                    $RT::Logger->debug( "Building $type link for $link: "
-                            . $T::Tickets{TOP}->Id );
+                if ($link =~ /^TOP$/i) {
+                    $RT::Logger->debug( "Building $type link for $link: " . $T::Tickets{TOP}->Id );
                     $link = $T::Tickets{TOP}->Id;
 
-                } elsif ( $link !~ m/^\d+$/ ) {
+                } 
+                elsif ( $link !~ m/^\d+$/ ) {
                     my $key = "create-$link";
                     if ( !exists $T::Tickets{$key} ) {
-                        $RT::Logger->debug(
-                            "Skipping $type link for $key (non-existent)");
+                        $RT::Logger->debug( "Skipping $type link for $key (non-existent)");
                         next;
                     }
-                    $RT::Logger->debug( "Building $type link for $link: "
-                            . $T::Tickets{$key}->Id );
+                    $RT::Logger->debug( "Building $type link for $link: " . $T::Tickets{$key}->Id );
                     $link = $T::Tickets{$key}->Id;
-                } else {
+                }
+                else {
                     $RT::Logger->debug("Building $type link for $link");
                 }
 
@@ -1449,7 +1314,7 @@ sub PostProcess {
                 );
 
                 $RT::Logger->warning("AddLink thru $link failed: $wmsg")
-                    unless $wval;
+                  unless $wval;
 
                 # push @non_fatal_errors, $wmsg unless ($wval);
             }
@@ -1460,7 +1325,7 @@ sub PostProcess {
     # postponed actions -- Status only, currently
     while ( my $template_id = shift(@$postponed) ) {
         my $ticket = $T::Tickets{$template_id};
-        $RT::Logger->debug( "Handling postponed actions for " . $ticket->id );
+        $RT::Logger->debug("Handling postponed actions for ".$ticket->id);
         my %args = %{ shift(@$postponed) };
         $ticket->SetStatus( $args{Status} ) if defined $args{Status};
     }