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 a5f5b88..d157733 100644 (file)
@@ -164,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;
+        }
       }
 
     }
@@ -259,14 +295,22 @@ sub ProcessTicketBasics {
 
     # the UI for editing WillResolve through Ticket Basics should allow 
     # setting it to null
-    my $to_date = delete($ARGSRef->{'WillResolve_Date'});
-    my $DateObj = RT::Date->new($session{'CurrentUser'});
-    if ( $to_date ) {
-        $DateObj->Set(Format => 'unknown', Value => $to_date);
-    } else {
-        $DateObj->Set(Value => 0);
+    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;
+      }
     }
-    $ARGSRef->{'WillResolve'} = $DateObj->ISO;
 
     if ( $ARGSRef->{'Queue'} and ( $ARGSRef->{'Queue'} !~ /^(\d+)$/ ) ) {
         my $tempqueue = RT::Queue->new($RT::SystemUser);
@@ -276,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,
@@ -340,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() ) )
@@ -392,179 +453,6 @@ sub ProcessTicketStatus {
     );
 }
 
-=head2 ProcessUpdateMessage
-
-Takes paramhash with fields ARGSRef, TicketObj and SkipSignatureOnly.
-
-Don't write message if it only contains current user's signature and
-SkipSignatureOnly argument is true. Function anyway adds attachments
-and updates time worked field even if skips message. The default value
-is true.
-
-=cut
-
-# change from stock: if txn custom fields are set but there's no content
-# or attachment, create a Touch txn instead of doing nothing
-
-sub ProcessUpdateMessage {
-
-    my %args = (
-        ARGSRef           => undef,
-        TicketObj         => undef,
-        SkipSignatureOnly => 1,
-        @_
-    );
-
-    if ( $args{ARGSRef}->{'UpdateAttachments'}
-        && !keys %{ $args{ARGSRef}->{'UpdateAttachments'} } )
-    {
-        delete $args{ARGSRef}->{'UpdateAttachments'};
-    }
-
-    # Strip the signature
-    $args{ARGSRef}->{UpdateContent} = RT::Interface::Web::StripContent(
-        Content        => $args{ARGSRef}->{UpdateContent},
-        ContentType    => $args{ARGSRef}->{UpdateContentType},
-        StripSignature => $args{SkipSignatureOnly},
-        CurrentUser    => $args{'TicketObj'}->CurrentUser,
-    );
-
-    my %txn_customfields;
-
-    foreach my $key ( keys %{ $args{ARGSRef} } ) {
-      if ( $key =~ /^(?:Object-RT::Transaction--)?CustomField-(\d+)/ ) {
-        next if $key =~ /(TimeUnits|Magic)$/;
-        $txn_customfields{$key} = $args{ARGSRef}->{$key};
-      }
-    }
-
-    # If, after stripping the signature, we have no message, create a 
-    # Touch transaction if necessary
-    if (    not $args{ARGSRef}->{'UpdateAttachments'}
-        and not length $args{ARGSRef}->{'UpdateContent'} )
-    {
-        #if ( $args{ARGSRef}->{'UpdateTimeWorked'} ) {
-        #      $args{ARGSRef}->{TimeWorked} = $args{TicketObj}->TimeWorked +
-        #          delete $args{ARGSRef}->{'UpdateTimeWorked'};
-        #  }
-
-        my $timetaken = $args{ARGSRef}->{'UpdateTimeWorked'};
-        if ( $timetaken or grep {length $_} values %txn_customfields ) {
-            my ( $Transaction, $Description, $Object ) =
-                $args{TicketObj}->Touch( 
-                  CustomFields => \%txn_customfields,
-                  TimeTaken => $timetaken
-                );
-            return $Description;
-        }
-
-        return;
-    }
-
-    if ( $args{ARGSRef}->{'UpdateSubject'} eq $args{'TicketObj'}->Subject ) {
-        $args{ARGSRef}->{'UpdateSubject'} = undef;
-    }
-
-    my $Message = MakeMIMEEntity(
-        Subject => $args{ARGSRef}->{'UpdateSubject'},
-        Body    => $args{ARGSRef}->{'UpdateContent'},
-        Type    => $args{ARGSRef}->{'UpdateContentType'},
-    );
-
-    $Message->head->add( 'Message-ID' => Encode::encode_utf8(
-        RT::Interface::Email::GenMessageId( Ticket => $args{'TicketObj'} )
-    ) );
-    my $old_txn = RT::Transaction->new( $session{'CurrentUser'} );
-    if ( $args{ARGSRef}->{'QuoteTransaction'} ) {
-        $old_txn->Load( $args{ARGSRef}->{'QuoteTransaction'} );
-    } else {
-        $old_txn = $args{TicketObj}->Transactions->First();
-    }
-
-    if ( my $msg = $old_txn->Message->First ) {
-        RT::Interface::Email::SetInReplyTo(
-            Message   => $Message,
-            InReplyTo => $msg
-        );
-    }
-
-    if ( $args{ARGSRef}->{'UpdateAttachments'} ) {
-        $Message->make_multipart;
-        $Message->add_part($_) foreach values %{ $args{ARGSRef}->{'UpdateAttachments'} };
-    }
-
-    if ( $args{ARGSRef}->{'AttachTickets'} ) {
-        require RT::Action::SendEmail;
-        RT::Action::SendEmail->AttachTickets( RT::Action::SendEmail->AttachTickets,
-            ref $args{ARGSRef}->{'AttachTickets'}
-            ? @{ $args{ARGSRef}->{'AttachTickets'} }
-            : ( $args{ARGSRef}->{'AttachTickets'} ) );
-    }
-
-    my $bcc = $args{ARGSRef}->{'UpdateBcc'};
-    my $cc  = $args{ARGSRef}->{'UpdateCc'};
-
-    my %message_args = (
-        CcMessageTo  => $cc,
-        BccMessageTo => $bcc,
-        Sign         => $args{ARGSRef}->{'Sign'},
-        Encrypt      => $args{ARGSRef}->{'Encrypt'},
-        MIMEObj      => $Message,
-        TimeTaken    => $args{ARGSRef}->{'UpdateTimeWorked'},
-        CustomFields => \%txn_customfields,
-    );
-
-    my @temp_squelch;
-    foreach my $type (qw(Cc AdminCc)) {
-        if (grep $_ eq $type || $_ eq ( $type . 's' ), @{ $args{ARGSRef}->{'SkipNotification'} || [] }) {
-            push @temp_squelch, map $_->address, Email::Address->parse( $message_args{$type} );
-            push @temp_squelch, $args{TicketObj}->$type->MemberEmailAddresses;
-            push @temp_squelch, $args{TicketObj}->QueueObj->$type->MemberEmailAddresses;
-        }
-    }
-    if (grep $_ eq 'Requestor' || $_ eq 'Requestors', @{ $args{ARGSRef}->{'SkipNotification'} || [] }) {
-            push @temp_squelch, map $_->address, Email::Address->parse( $message_args{Requestor} );
-            push @temp_squelch, $args{TicketObj}->Requestors->MemberEmailAddresses;
-    }
-
-    if (@temp_squelch) {
-        require RT::Action::SendEmail;
-        RT::Action::SendEmail->SquelchMailTo( RT::Action::SendEmail->SquelchMailTo, @temp_squelch );
-    }
-
-    unless ( $args{'ARGSRef'}->{'UpdateIgnoreAddressCheckboxes'} ) {
-        foreach my $key ( keys %{ $args{ARGSRef} } ) {
-            next unless $key =~ /^Update(Cc|Bcc)-(.*)$/;
-
-            my $var   = ucfirst($1) . 'MessageTo';
-            my $value = $2;
-            if ( $message_args{$var} ) {
-                $message_args{$var} .= ", $value";
-            } else {
-                $message_args{$var} = $value;
-            }
-        }
-    }
-
-    my @results;
-    # Do the update via the appropriate Ticket method
-    if ( $args{ARGSRef}->{'UpdateType'} =~ /^(private|public)$/ ) {
-        my ( $Transaction, $Description, $Object ) =
-            $args{TicketObj}->Comment(%message_args);
-        push( @results, $Description );
-        #$Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object;
-    } elsif ( $args{ARGSRef}->{'UpdateType'} eq 'response' ) {
-        my ( $Transaction, $Description, $Object ) =
-            $args{TicketObj}->Correspond(%message_args);
-        push( @results, $Description );
-        #$Object->UpdateCustomFields( ARGSRef => $args{ARGSRef} ) if $Object;
-    } else {
-        push( @results,
-            loc("Update type was neither correspondence nor comment.") . " " . loc("Update not recorded.") );
-    }
-    return @results;
-}
-
 sub default_FormatDate { $_[0]->AsString }
 
 sub ProcessColumnMapValue {