RT# 38517 - Added Lingua::EN::NameParse to parse real name into first and last name.
[freeside.git] / rt / lib / RT / Interface / Web_Vendor.pm
index 27c647f..d157733 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
     ###
 
@@ -136,6 +164,42 @@ sub ProcessTicketCustomers {
         push @results, $msg;
         warn "$me: linking requestor to custnum $custnum: $msg\n"
           if $Debug > 1;
+
+        ## check if FS contact email exists, if not create it.
+        if ( !qsearchs( {
+            'table'     => 'contact_email',
+            'hashref'   => { 'emailaddress' => $Requestor->{'values'}->{'emailaddress'}, },
+           } ) ) {
+
+            ## get first and last name for contact.
+             my ($fname, $lname) = (
+                split (/\@/, substr($Requestor->{'values'}->{'emailaddress'}, 0, index($Requestor->{'values'}->{'emailaddress'}, ".")))
+             );
+
+             use Lingua::EN::NameParse;
+             my $name = Lingua::EN::NameParse->new();
+
+             my $error = $name->parse($Requestor->{'values'}->{'realname'})
+             unless !$Requestor->{'values'}->{'realname'};
+
+             my %name_comps = $name->components unless !$Requestor->{'values'}->{'realname'} || $error;
+
+             $fname = $name_comps{given_name_1} || $name_comps{initials_1} unless !$name_comps{given_name_1} && !$name_comps{initials_1};
+             $lname = $name_comps{surname_1} unless !$name_comps{surname_1};
+
+             ## create the contact.
+             use FS::contact;
+             my $contact = new FS::contact {
+                'custnum'       => $custnum,
+                'first'         => $fname,
+                'last'          => $lname,
+                'emailaddress'  => $Requestor->{'values'}->{'emailaddress'},
+                'comment'       => 'Auto created from RT requestor',
+             };
+             my $error = $contact->insert;
+             push @results, 'Created Freeside contact for requestor ' . $Requestor->{'values'}->{'emailaddress'}
+             unless $error;
+        }
       }
 
     }
@@ -226,8 +290,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 +320,16 @@ 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)) {
+      if (exists $ARGSRef->{$field}) {
+        $ARGSRef->{$field} =~ s/\s//g;
+        $ARGSRef->{$field} ||= 0;
+      }
+    }
+
     my @results = UpdateRecordObject(
         AttributesRef => \@attribs,
         Object        => $TicketObj,
@@ -300,6 +394,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 +453,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;