self-service improvements, RT10883
authorlevinse <levinse>
Fri, 17 Dec 2010 01:16:04 +0000 (01:16 +0000)
committerlevinse <levinse>
Fri, 17 Dec 2010 01:16:04 +0000 (01:16 +0000)
FS/FS/ClientAPI/MyAccount.pm
FS/FS/TicketSystem/RT_Internal.pm
fs_selfservice/FS-SelfService/SelfService.pm
fs_selfservice/FS-SelfService/cgi/myaccount.html
fs_selfservice/FS-SelfService/cgi/selfservice.cgi
fs_selfservice/FS-SelfService/cgi/tktview.html [new file with mode: 0644]

index 21a923f..5e5972e 100644 (file)
@@ -1773,6 +1773,59 @@ sub create_ticket {
 
 }
 
+sub get_ticket {
+  my $p = shift;
+  my($context, $session, $custnum) = _custoragent_session_custnum($p);
+  return { 'error' => $session } if $context eq 'error';
+
+  warn "$me get_ticket: initializing ticket system\n" if $DEBUG;
+  FS::TicketSystem->init();
+
+  if(length($p->{'reply'})) {
+      my @err_or_res = FS::TicketSystem->correspond_ticket(
+       '', #create RT session based on FS CurrentUser (fs_selfservice)
+       'ticket_id' => $p->{'ticket_id'},
+       'content' => $p->{'reply'},
+      );
+    
+    return { 'error' => 'unable to reply to ticket' } 
+       unless ( $err_or_res[0] != 0 && defined $err_or_res[2] );
+  }
+
+  warn "$me get_ticket: getting ticket\n" if $DEBUG;
+  my $err_or_ticket = FS::TicketSystem->get_ticket(
+    '', #create RT session based on FS CurrentUser (fs_selfservice)
+    'ticket_id' => $p->{'ticket_id'},
+  );
+
+  if ( ref($err_or_ticket) ) {
+
+# since we're bypassing the RT security/permissions model by always using
+# fs_selfservice as the RT user (as opposed to a requestor, which we
+# can't do since we want all tickets linked to a cust), we check below whether
+# the requested ticket was actually linked to this customer
+    my @custs = @{$err_or_ticket->{'custs'}};
+    my @txns = @{$err_or_ticket->{'txns'}};
+
+    return { 'error' => 'no customer' } unless ( $custnum && scalar(@custs) );
+
+    return { 'error' => 'invalid ticket requested' } 
+       unless grep($_ eq $custnum, @custs);
+
+    warn "$me get_ticket: sucessful: \n"
+      if $DEBUG;
+    return { 'error'     => '',
+             'transactions' => \@txns,
+            'ticket_id' => $p->{'ticket_id'},
+           };
+  } else {
+    warn "$me create_ticket: unsucessful: $err_or_ticket\n"
+      if $DEBUG;
+    return { 'error' => $err_or_ticket };
+  }
+}
+
+
 #--
 
 sub _custoragent_session_custnum {
index 4036d90..6fc2bb6 100644 (file)
@@ -215,6 +215,91 @@ sub create_ticket {
   $Ticket;
 }
 
+=item get_ticket SESSION_HASHREF, OPTION => VALUE ...
+
+Class method. Retrieves a ticket. If there is an error, returns the scalar
+error. Otherwise, currently returns a slightly tricky data structure containing
+a list of the linked customers and each transaction's content, description, and
+create time.
+
+Accepts the following options:
+
+=over 4
+
+=item ticket_id 
+
+The ticket id
+
+=back
+
+=cut
+
+sub get_ticket {
+  my($self, $session, %param) = @_;
+
+  $session = $self->session($session);
+
+  my $Ticket = RT::Ticket->new($session->{'CurrentUser'});
+  my $ticketid = $Ticket->Load( $param{'ticket_id'} );
+  return 'Could not load ticket' unless $ticketid;
+
+  my @custs = ();
+  foreach my $link ( @{ $Ticket->Customers->ItemsArrayRef } ) {
+    my $cust = $link->Target;
+    push @custs, $1 if $cust =~ /\/(\d+)$/;
+  }
+
+  my @txns = ();
+  my $transactions = $Ticket->Transactions;
+  while ( my $transaction = $transactions->Next ) {
+    my $t = { created => $transaction->Created,
+       content => $transaction->Content,
+       description => $transaction->Description,
+    };
+    push @txns, $t;
+  }
+
+  { txns => [ @txns ],
+    custs => [ @custs ],
+  };
+}
+
+
+=item correspond_ticket SESSION_HASHREF, OPTION => VALUE ...
+
+Class method. Correspond on a ticket. If there is an error, returns the scalar
+error. Otherwise, returns the transaction id, error message, and
+RT::Transaction object.
+
+Accepts the following options:
+
+=over 4
+
+=item ticket_id 
+
+The ticket id
+
+=item content
+
+Correspondence content
+
+=back
+
+=cut
+
+sub correspond_ticket {
+  my($self, $session, %param) = @_;
+
+  $session = $self->session($session);
+
+  my $Ticket = RT::Ticket->new($session->{'CurrentUser'});
+  my $ticketid = $Ticket->Load( $param{'ticket_id'} );
+  return 'Could not load ticket' unless $ticketid;
+  return 'No content' unless $param{'content'};
+
+  $Ticket->Correspond( Content => $param{'content'} );
+}
+
 #shameless false laziness w/RT::Interface::Web::AttemptExternalAuth
 # to get logged into RT from afar
 sub _web_external_auth {
index 9e6fe68..135feeb 100644 (file)
@@ -61,6 +61,7 @@ $socket .= '.'.$tag if defined $tag && length($tag);
   'unprovision_svc'           => 'MyAccount/unprovision_svc',
   'myaccount_passwd'          => 'MyAccount/myaccount_passwd',
   'create_ticket'             => 'MyAccount/create_ticket',
+  'get_ticket'             => 'MyAccount/get_ticket',
   'signup_info'               => 'Signup/signup_info',
   'skin_info'                 => 'MyAccount/skin_info',
   'access_info'               => 'MyAccount/access_info',
index db95f33..eaf4164 100644 (file)
@@ -94,8 +94,9 @@ Hello <%= $name %>!<BR><BR>
 
     foreach my $ticket ( @tickets ) {
       my $td = qq!<TD BGCOLOR="#$col">!;
+      my $link = qq!<A HREF="${url}tktview;ticket_id=$ticket->{id}">!;
       $OUT .=
-        "<TR>$td". $ticket->{'id'}. "</TD>".
+        "<TR>$td $link". $ticket->{'id'}. "</A></TD>".
         $td. $ticket->{'subject'}. "</TD>".
         $td. ($ticket->{'content'} || $ticket->{'priority'}). "</TD>".
         $td. $ticket->{'queue'}. "</TD>".
index 0ef4e9a..acd6414 100644 (file)
@@ -16,7 +16,7 @@ use FS::SelfService qw(
   part_svc_info provision_acct provision_external
   unprovision_svc change_pkg suspend_pkg domainselector
   list_svcs list_svc_usage list_cdr_usage list_support_usage
-  myaccount_passwd list_invoices create_ticket
+  myaccount_passwd list_invoices create_ticket get_ticket
   mason_comp
 );
 
@@ -73,7 +73,7 @@ $session_id = $cgi->param('session');
 
 #order|pw_list XXX ???
 $cgi->param('action') =~
-    /^(myaccount|tktcreate|invoices|view_invoice|make_payment|make_ach_payment|make_term_payment|make_thirdparty_payment|payment_results|ach_payment_results|recharge_prepay|recharge_results|logout|change_bill|change_ship|change_pay|process_change_bill|process_change_ship|process_change_pay|customer_order_pkg|process_order_pkg|customer_change_pkg|process_change_pkg|process_order_recharge|provision|provision_svc|process_svc_acct|process_svc_external|delete_svc|view_usage|view_usage_details|view_cdr_details|view_support_details|change_password|process_change_password|customer_suspend_pkg|process_suspend_pkg)$/
+    /^(myaccount|tktcreate|tktview|invoices|view_invoice|make_payment|make_ach_payment|make_term_payment|make_thirdparty_payment|payment_results|ach_payment_results|recharge_prepay|recharge_results|logout|change_bill|change_ship|change_pay|process_change_bill|process_change_ship|process_change_pay|customer_order_pkg|process_order_pkg|customer_change_pkg|process_change_pkg|process_order_recharge|provision|provision_svc|process_svc_acct|process_svc_external|delete_svc|view_usage|view_usage_details|view_cdr_details|view_support_details|change_password|process_change_password|customer_suspend_pkg|process_suspend_pkg)$/
   or die "unknown action ". $cgi->param('action');
 my $action = $1;
 
@@ -224,6 +224,13 @@ sub tktcreate {
            );
 }
 
+sub tktview {
+ get_ticket(   'session_id' => $session_id,
+               'ticket_id' => $cgi->param('ticket_id'),
+               'reply' => $cgi->param('reply'),
+           );
+}
+
 sub customer_order_pkg {
   my $init_data = signup_info( 'customer_session_id' => $session_id );
   return $init_data if ( $init_data->{'error'} );
diff --git a/fs_selfservice/FS-SelfService/cgi/tktview.html b/fs_selfservice/FS-SelfService/cgi/tktview.html
new file mode 100644 (file)
index 0000000..6f540bc
--- /dev/null
@@ -0,0 +1,31 @@
+<%= $url = "$selfurl?session=$session_id;action="; ''; %>
+<%= include('header', "View ticket #$ticket_id") %>
+
+<%=
+if($error) {
+    $OUT .= qq! <div style="font-weight: bold; color: red; font-size: 110%">Error: $error</div> !;
+}
+elsif(@transactions) {
+    $OUT .= qq! <TABLE border="1">!;
+    foreach my $txn ( @transactions ) {
+       next if $txn->{content} eq 'This transaction appears to have no content';
+       $OUT .= "<TR><TD><B>$txn->{created} &nbsp; $txn->{description}</B>";
+       $OUT .= "<PRE>$txn->{content}</PRE></TD></TR>";
+    }
+    $OUT .= "</TABLE>";
+}
+else {
+    $OUT .= "No transactions on this ticket";
+}
+%>
+<BR><BR><BR>
+<FORM ACTION="<%=$selfurl%>" METHOD=POST>
+    <input type="hidden" name="session" value="<%=$session_id%>">
+    <input type="hidden" name="ticket_id" value="<%=$ticket_id%>">
+    <input type="hidden" name="action" value="tktview">
+    Add reply to ticket:
+    <BR><textarea name="reply" cols="60" rows="10"></textarea>
+    <BR><input type="submit" value="Reply">
+</form> 
+
+<%= include('footer') %>