avoid creating Set TimeWorked transactions where new value is empty, #28459
[freeside.git] / rt / lib / RT / Interface / Web_Vendor.pm
index 27c647f..245df12 100644 (file)
@@ -76,12 +76,32 @@ sub ProcessTicketCustomers {
     ###
 
     ###
+    #find new services
+    ###
+    
+    my @svcnums = map  { /^Ticket-AddService-(\d+)$/; $1 }
+                  grep { /^Ticket-AddService-(\d+)$/ && $ARGSRef->{$_} }
+                  keys %$ARGSRef;
+
+    my @custnums;
+    foreach my $svcnum (@svcnums) {
+        my @link = ( 'Type'   => 'MemberOf',
+                     'Target' => "freeside://freeside/cust_svc/$svcnum",
+                   );
+
+        my( $val, $msg ) = $Ticket->AddLink(@link);
+        push @results, $msg;
+        next if !$val;
+
+    }
+
+    ###
     #find new customers
     ###
 
-    my @custnums = map  { /^Ticket-AddCustomer-(\d+)$/; $1 }
-                   grep { /^Ticket-AddCustomer-(\d+)$/ && $ARGSRef->{$_} }
-                   keys %$ARGSRef;
+    push @custnums, map  { /^Ticket-AddCustomer-(\d+)$/; $1 }
+                    grep { /^Ticket-AddCustomer-(\d+)$/ && $ARGSRef->{$_} }
+                    keys %$ARGSRef;
 
     #my @delete_custnums =
     #  map  { /^Ticket-AddCustomer-(\d+)$/; $1 }
@@ -118,6 +138,14 @@ sub ProcessTicketCustomers {
     }
 
     ###
+    #remove any declared non-customer addresses
+    ###
+
+    my $exclude_regexp = RT->Config->Get('NonCustomerEmailRegexp');
+    @Requestors = grep { not $_->EmailAddress =~ $exclude_regexp } @Requestors
+      if defined $exclude_regexp;
+
+    ###
     #link ticket (and requestors) to customers
     ###
 
@@ -226,8 +254,28 @@ sub ProcessTicketBasics {
         TimeLeft
         Type
         Queue
+        WillResolve
     );
 
+    # the UI for editing WillResolve through Ticket Basics should allow 
+    # setting it to null
+    if ( exists $ARGSRef->{'WillResolve_Date'} ) {
+      my $to_date = delete($ARGSRef->{'WillResolve_Date'});
+      my $DateObj = RT::Date->new($session{'CurrentUser'});
+      if ( $to_date ) {
+          $DateObj->Set(Format => 'unknown', Value => $to_date);
+          if ( $DateObj->Unix > time ) {
+            $ARGSRef->{'WillResolve'} = $DateObj->ISO;
+          } else {
+            warn "Ticket ".$TicketObj->Id.": WillResolve date '$to_date' not accepted.\n";
+            # and then don't set it in ARGSRef
+          }
+      } elsif ( $TicketObj and $TicketObj->WillResolveObj->Unix > 0 ) {
+          $DateObj->Set(Value => 0);
+          $ARGSRef->{'WillResolve'} = $DateObj->ISO;
+      }
+    }
+
     if ( $ARGSRef->{'Queue'} and ( $ARGSRef->{'Queue'} !~ /^(\d+)$/ ) ) {
         my $tempqueue = RT::Queue->new($RT::SystemUser);
         $tempqueue->Load( $ARGSRef->{'Queue'} );
@@ -236,6 +284,14 @@ sub ProcessTicketBasics {
         }
     }
 
+    # RT core _will_ allow Set transactions that change these 
+    # fields to empty strings, but internally change the values 
+    # to zero.  This is sloppy and causes some problems.
+    foreach my $field (qw(TimeWorked TimeEstimated TimeLeft)) {
+      $ARGSRef->{$field} =~ s/\s//g;
+      $ARGSRef->{$field} ||= 0;
+    }
+
     my @results = UpdateRecordObject(
         AttributesRef => \@attribs,
         Object        => $TicketObj,
@@ -300,6 +356,13 @@ sub ProcessTicketDates {
             Value  => $ARGSRef->{ $field . '_Date' }
         );
 
+        if ( $field eq 'WillResolve'
+              and $DateObj->Unix > 0 
+              and $DateObj->Unix <= time ) {
+            push @results, "Can't set WillResolve date in the past.";
+            next;
+        }
+
         my $obj = $field . "Obj";
         if (    ( defined $DateObj->Unix )
             and ( $DateObj->Unix != $Ticket->$obj()->Unix() ) )
@@ -352,5 +415,32 @@ sub ProcessTicketStatus {
     );
 }
 
+sub default_FormatDate { $_[0]->AsString }
+
+sub ProcessColumnMapValue {
+    my $value = shift;
+    my %args = ( Arguments => [],
+                 Escape => 1,
+                 FormatDate => \&default_FormatDate,
+                 @_ );
+
+    if ( ref $value ) {
+        if ( ref $value eq 'RT::Date' ) {
+            return $args{FormatDate}->($value);
+        } elsif ( UNIVERSAL::isa( $value, 'CODE' ) ) {
+            my @tmp = $value->( @{ $args{'Arguments'} } );
+            return ProcessColumnMapValue( ( @tmp > 1 ? \@tmp : $tmp[0] ), %args );
+        } elsif ( UNIVERSAL::isa( $value, 'ARRAY' ) ) {
+            return join '', map ProcessColumnMapValue( $_, %args ), @$value;
+        } elsif ( UNIVERSAL::isa( $value, 'SCALAR' ) ) {
+            return $$value;
+        }
+    }
+
+    return $m->interp->apply_escapes( $value, 'h' ) if $args{'Escape'};
+    return $value;
+}
+
+
 1;