X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2FTicketSystem%2FRT_Internal.pm;h=6ae8881a4a6f2d034899488aac6a818ce20f4443;hb=b5c4237a34aef94976bc343c8d9e138664fc3984;hp=033c746ba78b420d5deb3563ec50bb6f32ab0e48;hpb=40a7b3dc653e099f7bd0bd762b649b04c4432db2;p=freeside.git diff --git a/FS/FS/TicketSystem/RT_Internal.pm b/FS/FS/TicketSystem/RT_Internal.pm index 033c746ba..6ae8881a4 100644 --- a/FS/FS/TicketSystem/RT_Internal.pm +++ b/FS/FS/TicketSystem/RT_Internal.pm @@ -1,21 +1,23 @@ package FS::TicketSystem::RT_Internal; use strict; -use vars qw( @ISA $DEBUG ); +use vars qw( @ISA $DEBUG $me ); +use Data::Dumper; +use MIME::Entity; use FS::UID qw(dbh); use FS::CGI qw(popurl); use FS::TicketSystem::RT_Libs; -use RT::CurrentUser; @ISA = qw( FS::TicketSystem::RT_Libs ); $DEBUG = 0; +$me = '[FS::TicketSystem::RT_Internal]'; sub sql_num_customer_tickets { - "( select count(*) from tickets - join links on ( tickets.id = links.localbase ) - where ( status = 'new' or status = 'open' or status = 'stalled' ) - and target = 'freeside://freeside/cust_main/' || custnum + "( select count(*) from Tickets + join Links on ( Tickets.id = Links.LocalBase ) + where ( Status = 'new' or Status = 'open' or Status = 'stalled' ) + and Target = 'freeside://freeside/cust_main/' || custnum )"; } @@ -36,24 +38,313 @@ sub access_right { #return '' unless $conf->config('ticket_system'); return '' unless FS::Conf->new->config('ticket_system'); - $self->_web_external_auth($session) - unless $session - && $session->{'CurrentUser'}; + $session = $self->session($session); + + #warn "$me access_right: CurrentUser ". $session->{'CurrentUser'}. ":\n". + # ( $DEBUG>1 ? Dumper($session->{'CurrentUser'}) : '' ) + # if $DEBUG > 1; $session->{'CurrentUser'}->HasRight( Right => $right, Object => $RT::System ); } -#shameless false laziness w/rt/html/autohandler to get logged into RT from afar +sub session { + my( $self, $session ) = @_; + + if ( $session && $session->{'Current_User'} ) { + warn "$me session: using existing session and CurrentUser: \n". + Dumper($session->{'CurrentUser'}) + if $DEBUG; + } else { + warn "$me session: loading session and CurrentUser\n" if $DEBUG > 1; + $session = $self->_web_external_auth($session); + } + + $session; +} + +sub init { + my $self = shift; + + warn "$me init: loading RT libraries\n" if $DEBUG; + eval ' + use lib ( "/opt/rt3/local/lib", "/opt/rt3/lib" ); + use RT; + #it looks like the rest are taken care of these days in RT::InitClasses + #use RT::Ticket; + #use RT::Transactions; + #use RT::Users; + #use RT::CurrentUser; + #use RT::Templates; + #use RT::Queues; + #use RT::ScripActions; + #use RT::ScripConditions; + #use RT::Scrips; + #use RT::Groups; + #use RT::GroupMembers; + #use RT::CustomFields; + #use RT::CustomFieldValues; + #use RT::ObjectCustomFieldValues; + + #for web external auth... + use RT::Interface::Web; + '; + die $@ if $@; + + warn "$me init: loading RT config\n" if $DEBUG; + { + local $SIG{__DIE__}; + eval 'RT::LoadConfig();'; + } + die $@ if $@; + + warn "$me init: initializing RT\n" if $DEBUG; + { + local $SIG{__DIE__}; + eval 'RT::Init("NoSignalHandlers"=>1);'; + } + die $@ if $@; + + warn "$me init: complete" if $DEBUG; +} + +=item create_ticket SESSION_HASHREF, OPTION => VALUE ... + +Class method. Creates a ticket. If there is an error, returns the scalar +error, otherwise returns the newly created RT::Ticket object. + +Accepts the following options: + +=over 4 + +=item queue + +Queue name or Id + +=item subject + +Ticket subject + +=item requestor + +Requestor email address or arrayref of addresses + +=item cc + +Cc: email address or arrayref of addresses + +=item message + +Ticket message + +=item mime_type + +MIME type to use for message. Defaults to text/plain. Specifying text/html +can be useful to use HTML markup in message. + +=item custnum + +Customer number (see L) to associate with ticket. + +=item svcnum + +Service number (see L) to associate with ticket. Will also +associate the customer who has this service (unless the service is unlinked). + +=back + +=cut + +sub create_ticket { + my($self, $session, %param) = @_; + + $session = $self->session($session); + + my $Queue = RT::Queue->new($session->{'CurrentUser'}); + $Queue->Load( $param{'queue'} ); + + my $req = ref($param{'requestor'}) + ? $param{'requestor'} + : ( $param{'requestor'} ? [ $param{'requestor'} ] : [] ); + + my $cc = ref($param{'cc'}) + ? $param{'cc'} + : ( $param{'cc'} ? [ $param{'cc'} ] : [] ); + + my $mimeobj = MIME::Entity->build( + 'Data' => $param{'message'}, + 'Type' => ( $param{'mime_type'} || 'text/plain' ), + ); + + my %ticket = ( + 'Queue' => $Queue->Id, + 'Subject' => $param{'subject'}, + 'Requestor' => $req, + 'Cc' => $cc, + 'MIMEObj' => $mimeobj, + ); + warn Dumper(\%ticket) if $DEBUG > 1; + + my $Ticket = RT::Ticket->new($session->{'CurrentUser'}); + my( $id, $Transaction, $ErrStr ); + { + local $SIG{__DIE__}; + ( $id, $Transaction, $ErrStr ) = $Ticket->Create( %ticket ); + } + return $ErrStr if $id == 0; + + warn "ticket got id $id\n" if $DEBUG; + + #XXX check errors adding custnum/svcnum links (put it in a transaction)... + # but we do already know they're good + + if ( $param{'custnum'} ) { + my( $val, $msg ) = $Ticket->_AddLink( + 'Type' => 'MemberOf', + 'Target' => 'freeside://freeside/cust_main/'. $param{'custnum'}, + ); + } + + if ( $param{'svcnum'} ) { + my( $val, $msg ) = $Ticket->_AddLink( + 'Type' => 'MemberOf', + 'Target' => 'freeside://freeside/cust_svc/'. $param{'svcnum'}, + ); + } + + $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, + type => $transaction->Type, + }; + 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'} ); +} + +=item queues SESSION_HASHREF [, ACL ] + +Retrieve a list of queues. Pass the name of an RT access control right, +such as 'CreateTicket', to return only queues on which the current user +has that right. Otherwise this will return all queues with the 'SeeQueue' +right. + +=cut + +sub queues { + my( $self, $session, $acl ) = @_; + $session = $self->session($session); + + my $showall = $acl ? 0 : 1; + my @result = (); + my $q = new RT::Queues($session->{'CurrentUser'}); + $q->UnLimit; + while (my $queue = $q->Next) { + if ($showall || $queue->CurrentUserHasRight($acl)) { + push @result, { + Id => $queue->Id, + Name => $queue->Name, + Description => $queue->Description, + }; + } + } + return map { $_->{Id} => $_->{Name} } @result; +} + +#shameless false laziness w/RT::Interface::Web::AttemptExternalAuth +# to get logged into RT from afar sub _web_external_auth { my( $self, $session ) = @_; my $user = $FS::CurrentUser::CurrentUser->username; + eval 'use RT::CurrentUser;'; + die $@ if $@; + + $session ||= {}; $session->{'CurrentUser'} = RT::CurrentUser->new(); - warn "loading RT user for $user\n" - if $DEBUG; + warn "$me _web_external_auth loading RT user for $user\n" + if $DEBUG > 1; $session->{'CurrentUser'}->Load($user); @@ -132,6 +423,8 @@ sub _web_external_auth { #} } + $session; + } 1;