From: khoff Date: Fri, 11 Mar 2005 01:34:31 +0000 (+0000) Subject: Reorganized RT->Freeside integration to support Internal (single RT/Freeside database... X-Git-Tag: BEFORE_FINAL_MASONIZE~656 X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=commitdiff_plain;h=7c04e83390fd815fbf75a22118728b2eb6b4f7ad Reorganized RT->Freeside integration to support Internal (single RT/Freeside database) and XMLRPC interfaces. All the UI stuff is handled the same either way. Integration type is changed by setting $RT::URI::freeside::IntegrationType to either 'Internal' or 'XMLRPC' in your RT_SiteConfig.pm. --- diff --git a/rt/etc/RT_SiteConfig.pm b/rt/etc/RT_SiteConfig.pm index 572a2baf6..3c37a41bf 100644 --- a/rt/etc/RT_SiteConfig.pm +++ b/rt/etc/RT_SiteConfig.pm @@ -10,4 +10,6 @@ $RT::WebExternalAuth = 1; $RT::WebFallbackToInternal = 1; #no $RT::WebExternalAuto = 1; +$RT::URI::freeside::IntegrationType = 'Internal'; + 1; diff --git a/rt/html/Elements/Header b/rt/html/Elements/Header index 27658df42..4a16d5667 100644 --- a/rt/html/Elements/Header +++ b/rt/html/Elements/Header @@ -78,7 +78,7 @@ ONLOAD=" - + @@ -124,6 +124,7 @@ ONLOAD=" $r->headers_out->{'Pragma'} = 'no-cache'; $r->headers_out->{'Cache-control'} = 'no-cache'; +require RT::URI::freeside; <%ARGS> diff --git a/rt/html/Elements/Menu b/rt/html/Elements/Menu index 0e57585c5..e933fb4f0 100644 --- a/rt/html/Elements/Menu +++ b/rt/html/Elements/Menu @@ -78,7 +78,7 @@ % } else { % $sep=0; % } -
  • <%$toptabs->{$tab}->{'path'}%>" style="font-size: <%$size%>;" class="<%$class%>" <%($class eq 'currenttopnav') ? "name='focus'" : ""|n %> <% !$level && "accesskey='".$accesskey++."'" |n%>><% $toptabs->{$tab}->{'title'}%> %# Second-level items diff --git a/rt/html/Elements/Tabs b/rt/html/Elements/Tabs index 4fc229b84..4a018bfad 100644 --- a/rt/html/Elements/Tabs +++ b/rt/html/Elements/Tabs @@ -64,7 +64,7 @@ my $basetopactions = { }; my $basetabs = { ' A'=> { title => 'Billing Main', - path => '../', + path => &RT::URI::freeside::FreesideURL(), }, A => { #title => loc('Homepage'), title => 'Ticketing Main', @@ -93,6 +93,8 @@ if (!defined $toptabs) { if (!defined $topactions) { $topactions = $basetopactions; } + + require RT::URI::freeside; # Now let callbacks add their extra tabs $m->comp('/Elements/Callback', diff --git a/rt/html/Ticket/Elements/AddCustomers b/rt/html/Ticket/Elements/AddCustomers index 66480e2f1..bfa6de9c6 100644 --- a/rt/html/Ticket/Elements/AddCustomers +++ b/rt/html/Ticket/Elements/AddCustomers @@ -19,9 +19,8 @@ % foreach my $customer (@Customers) {
  • % } @@ -31,9 +30,11 @@ <%INIT> my ($msg); +my $freeside_url = &RT::URI::freeside::FreesideURL(); + my @Customers = (); if ( $CustomerString ) { - @Customers = smart_search( 'search' => $CustomerString ); + @Customers = &RT::URI::freeside::smart_search( 'search' => $CustomerString ); warn scalar(@Customers); } @@ -42,9 +43,6 @@ if ($ServiceString) { @Services = (); #service_search(); } -eval { use FS::CGI qw( popurl small_custview ); }; -my $p = eval { popurl(3); }; - <%ARGS> diff --git a/rt/html/Ticket/Elements/ShowCustomers b/rt/html/Ticket/Elements/ShowCustomers index 5519d24cf..612727ede 100644 --- a/rt/html/Ticket/Elements/ShowCustomers +++ b/rt/html/Ticket/Elements/ShowCustomers @@ -21,7 +21,7 @@ % my $cust_main = ''; % } diff --git a/rt/lib/RT/URI/freeside.pm b/rt/lib/RT/URI/freeside.pm index ebd24ad60..bd617f907 100644 --- a/rt/lib/RT/URI/freeside.pm +++ b/rt/lib/RT/URI/freeside.pm @@ -28,143 +28,170 @@ package RT::URI::freeside; use RT::URI::base; use strict; -use vars qw(@ISA); - +use vars qw(@ISA $IntegrationType); @ISA = qw/RT::URI::base/; =head1 NAME -RT::URI::base +RT::URI::freeside =head1 DESCRIPTION URI handler for freeside URIs. See http://www.sisd.com/freeside/ for more information on freeside. + +=head1 Public subroutines + +=over 4 + +=item FreesideGetConfig CONFKEY + +Subroutine that returns the freeside's configuration value(s) for CONFKEY +as a scalar or list. + +=cut + +sub FreesideGetConfig { return undef; } + + +=item FreesideURL + +Returns the URL for freeside's web interface. + +=cut + +sub FreesideURL { return undef; } + + +=item FreesideVersion + +Returns a string describing the freeside version being used. + +=cut + +sub FreesideVersion { return undef; } + + +=item smart_search + +A wrapper for the FS::cust_main::smart_search subroutine. + +=cut + +sub smart_search { return undef; } + + +=item small_custview + +A wrapper for the FS::CGI::small_custview subroutine. + +=cut + +sub small_custview { return 'Freeside integration error!'; } + + +=back + +=head1 Private methods + +=over 4 + +=item _FreesideGetRecord + +Method returns a hashref of the freeside record referenced in the URI. +Must be called after ParseURI. + =cut +sub _FreesideGetRecord { return undef; } -sub FreesideURIPrefix { + +=item _FreesideURIPrefix + +Method that returns the URI prefix for freeside URIs. + +=cut + +sub _FreesideURIPrefix { my $self = shift; return($self->Scheme . '://freeside'); } -sub FreesideURILabel { +=item _FreesideURILabel + +Method that returns a short string describing the customer referenced +in the URI. + +=cut + +sub _FreesideURILabel { my $self = shift; - return(undef) unless (exists($self->{'fstable'}) and - exists($self->{'fspkey'})); + $RT::Logger->debug("Called _FreesideURILabel()"); + + return unless (exists($self->{'fstable'}) and + exists($self->{'fspkey'})); my $label; my ($table, $pkey) = ($self->{'fstable'}, $self->{'fspkey'}); - eval { - use FS::UID qw(dbh); - use FS::Record qw(qsearchs qsearch dbdef); - eval "use FS::$table;"; - use FS::cust_svc; - - my $dbdef = dbdef or die "No dbdef"; - my $pkeyfield = $dbdef->table($table)->primary_key - or die "No primary key for table $table"; - - my $rec = qsearchs($table, { $pkeyfield => $pkey }) - or die "Record with $pkeyfield == $pkey does not exist in table $table"; - - if ($table =~ /^svc_/) { - if ($rec->can('cust_svc')) { - my $cust_svc = $rec->cust_svc or die '$rec->cust_svc failed'; - my ($svc, $tag, $svcdb) = $cust_svc->label; - $label = "Freeside service ${svc}: ${tag}"; - } - } elsif ($table eq 'cust_main') { - #my ($last, $first, $company) = map { $rec->getfield($_) } - # qw(last first company); - #$label = "Freeside customer ${last}, ${first}"; - #$label .= ($company ne '') ? " with ${company}" : ''; - $label = "$pkey: ". $rec->name; - } else { - $label = "Freeside ${table}, ${pkeyfield} == ${pkey}"; - } + if ($table ne 'cust_main') { + warn "FS::${table} not currently supported"; + return; + } - #... other cases + my $rec = $self->_FreesideGetRecord(); - }; + if (ref($rec) eq 'HASH' and $table eq 'cust_main') { + my $name = $rec->{'last'} . ', ' . $rec->{'first'}; + $name = $rec->{'company'} . " ($name)" if $rec->{'company'}; + $label = "$pkey: $name"; + } else { + $label = "$pkey: $table"; + } if ($label and !$@) { return($label); } else { - return(undef); + return; } - } -sub FreesideURILabelLong { +=item _FreesideURILabel - my $self = shift; +Method that returns a longer string describing the customer referenced +in the URI. - return(undef) unless (exists($self->{'fstable'}) and - exists($self->{'fspkey'})); +=cut - my $label; - my ($table, $pkey) = ($self->{'fstable'}, $self->{'fspkey'}); +sub _FreesideURILabelLong { - eval { - use FS::UID qw(dbh); - use FS::Record qw(qsearchs qsearch dbdef); - eval "use FS::$table;"; - use FS::cust_svc; - - my $dbdef = dbdef or die "No dbdef"; - my $pkeyfield = $dbdef->table($table)->primary_key - or die "No primary key for table $table"; - - my $rec = qsearchs($table, { $pkeyfield => $pkey }) - or die "Record with $pkeyfield == $pkey does not exist in table $table"; - - if ($table =~ /^svc_/) { - #if ($rec->can('cust_svc')) { - # my $cust_svc = $rec->cust_svc or die '$rec->cust_svc failed'; - # my ($svc, $tag, $svcdb) = $cust_svc->label; - # $label = "Freeside service ${svc}: ${tag}"; - #} - $label = ''; - } elsif ($table eq 'cust_main') { - use FS::CGI qw(small_custview); - $label = small_custview( $rec, - scalar(FS::Conf->new->config('countrydefault')), - 1 #nobalance - ); - } else { - #$label = "Freeside ${table}, ${pkeyfield} == ${pkey}"; - $label = ''; - } + my $self = shift; - #... other cases + return $self->_FreesideURILabel(); - }; +} - if ($label and !$@) { - return($label); - } else { - warn $@; - return(undef); - } - +=back -} +=head1 Public methods + +=over 4 + +=cut sub ParseURI { my $self = shift; my $uri = shift; my ($table, $pkey); - my $uriprefix = $self->FreesideURIPrefix; + my $uriprefix = $self->_FreesideURIPrefix; if ($uri =~ /^$uriprefix\/(\w+)\/(\d+)$/) { $table = $1; $pkey = $2; @@ -177,22 +204,13 @@ sub ParseURI { $self->{'fstable'} = $table; $self->{'fspkey'} = $pkey; - my $p; - - eval { - use FS::UID qw(dbh); - use FS::CGI qw(popurl); - if (dbh) { - $p = popurl(3); - } + my $url = $self->FreesideURL(); - }; - - if ($@ or (!$p)) { - $self->{'href'} = $self->{'uri'}; + if ($url ne '') { + $self->{'href'} = "${url}/view/${table}.cgi?${pkey}"; } else { - $self->{'href'} = "${p}view/${table}.cgi?${pkey}"; + $self->{'href'} = $self->{'uri'}; } $self->{'uri'}; @@ -215,7 +233,7 @@ sub IsLocal { return undef; } -=head2 AsString +=item AsString Return a "pretty" string representing the URI object. @@ -229,14 +247,14 @@ This is meant to be used like this: sub AsString { my $self = shift; my $prettystring; - if ($prettystring = $self->FreesideURILabel) { + if ($prettystring = $self->_FreesideURILabel) { return $prettystring; } else { return $self->URI; } } -=head2 AsStringLong +=item AsStringLong Return a longer (HTML) string representing the URI object. @@ -245,16 +263,23 @@ Return a longer (HTML) string representing the URI object. sub AsStringLong { my $self = shift; my $prettystring; - if ($prettystring = $self->FreesideURILabelLong || $self->FreesideURILabel){ + if ($prettystring = $self->_FreesideURILabelLong || $self->_FreesideURILabel){ return $prettystring; } else { return $self->URI; } } -eval "require RT::URI::base_Vendor"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/URI/base_Vendor.pm}); -eval "require RT::URI::base_Local"; -die $@ if ($@ && $@ !~ qr{^Can't locate RT/URI/base_Local.pm}); +$IntegrationType ||= 'Internal'; +eval "require RT::URI::freeside::${RT::URI::freeside::IntegrationType}"; +warn $@ if $@; +if ($@ && + $@ !~ qr(^Can't locate RT/URI/freeside/${RT::URI::freeside::IntegrationType}.pm)) { + die $@; +}; + +=back + +=cut 1; diff --git a/rt/lib/RT/URI/freeside/Internal.pm b/rt/lib/RT/URI/freeside/Internal.pm new file mode 100644 index 000000000..cdadd1ed1 --- /dev/null +++ b/rt/lib/RT/URI/freeside/Internal.pm @@ -0,0 +1,121 @@ +# BEGIN LICENSE BLOCK +# +# Copyright (c) 2004 Kristian Hoffmann +# Based on the original RT::URI::base and RT::URI::fsck_com_rt. +# +# Copyright (c) 1996-2003 Jesse Vincent +# +# (Except where explictly superceded by other copyright notices) +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK +# +use strict; +no warnings qw(redefine); + +use vars qw($conf); + +use FS; +use FS::UID qw(dbh); +use FS::CGI qw(popurl); +use FS::Conf; +use FS::Record qw(qsearchs qsearch dbdef); +use FS::cust_main; +use FS::cust_svc; + +=head1 NAME + +RT::URI::freeside::Internal + +=head1 DESCRIPTION + +Overlay for the RT::URI::freeside URI handler implementing the Internal integration type. + +See L for public/private interface documentation. + +=cut + + + +sub _FreesideGetRecord { + + my $self = shift; + my ($table, $pkey) = ($self->{'fstable'}, $self->{'fspkey'}); + + $RT::Logger->debug("Called _FreesideGetRecord()"); + + #eval "use FS::$table;"; + + my $dbdef = dbdef; + unless ($dbdef) { + $RT::Logger->error("Using Internal freeside integration type, ". + "but it doesn't look like we're running under ". + "freeside's Mason handler."); + return; + } + + my $pkeyfield = $dbdef->table($table)->primary_key; + unless ($pkeyfield) { + $RT::Logger->error("No primary key for freeside table '$table'"); + return; + } + + my $fsrec = qsearchs($table, { $pkeyfield => $pkey }); + unless ($fsrec) { + $RT::Logger->error("Record with '$pkeyfield' == '$pkey' does " . + "not exist in table $table"); + return; + } + + return { $fsrec->hash }; + +} + +sub FreesideURL { + + return popurl(3); + +} + +sub FreesideVersion { + + return $FS::VERSION; + +} + +sub FreesideGetConfig { + + $conf = new FS::Conf unless ref($conf); + + return $conf->config(@_); + +} + +sub smart_search { #Subroutine + + return map { { $_->hash } } &FS::cust_main::smart_search(@_); + +} + +sub small_custview { + + return &FS::CGI::small_custview(@_); + +} + +1; diff --git a/rt/lib/RT/URI/freeside/XMLRPC.pm b/rt/lib/RT/URI/freeside/XMLRPC.pm new file mode 100644 index 000000000..618364c00 --- /dev/null +++ b/rt/lib/RT/URI/freeside/XMLRPC.pm @@ -0,0 +1,128 @@ +# BEGIN LICENSE BLOCK +# +# Copyright (c) 2004 Kristian Hoffmann +# Based on the original RT::URI::base and RT::URI::fsck_com_rt. +# +# Copyright (c) 1996-2003 Jesse Vincent +# +# (Except where explictly superceded by other copyright notices) +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# Unless otherwise specified, all modifications, corrections or +# extensions to this work which alter its source code become the +# property of Best Practical Solutions, LLC when submitted for +# inclusion in the work. +# +# +# END LICENSE BLOCK + +use strict; +no warnings qw(redefine); + +use vars qw($URL $XMLRPC_URL $_FS_VERSION); + +use Frontier::Client; + +=head1 NAME + +RT::URI::freeside::XMLRPC + +=head1 DESCRIPTION + +Overlay for the RT::URI::freeside URI handler implementing the XMLRPC integration type. + +See L for public/private interface documentation. + +=cut + + +sub _XMLRPCRequest { #Subroutine + + my $method = shift; + my @args = @_; + + my $result; + eval { + my $server = new Frontier::Client ( url => $XMLRPC_URL ); + $result = $server->call($method, @args); + }; + + if (not $@ and ref($result) eq 'ARRAY') { + return (scalar(@$result) == 1) ? @$result[0] : @$result; + } else { + $RT::Logger->debug("Freeside XMLRPC: " . $result || $@); + return (); + } + +} + +sub _FreesideGetRecord { + + my $self = shift; + my ($table, $pkey) = ($self->{'fstable'}, $self->{'fspkey'}); + my $record; + + $RT::Logger->debug("Called XMLRPC::_FreesideGetRecord()"); + + #FIXME: Need a better way to get primary keys. + # Maybe create a method for it and cache them like version? + my %table_pkeys = ( + cust_main => 'custnum', + ); + + my $method = 'Record.qsearchs'; + my @args = ($table, { $table_pkeys{$table} => $pkey }); + my ($record) = &_XMLRPCRequest($method, @args); + + return $record; + +} + + +sub FreesideGetConfig { + + return _XMLRPCRequest('Conf.config', @_); + +} + + +sub FreesideURL { + + return $URL; + +} + +sub FreesideVersion { + + return $_FS_VERSION if ($_FS_VERSION =~ /^\d+\.\d+\.\d+/); + + $RT::Logger->debug("Requesting freeside version..."); + ($_FS_VERSION) = &_XMLRPCRequest('version'); + $RT::Logger->debug("Cached freeside version: ${_FS_VERSION}"); + + return $_FS_VERSION; + +} + +sub smart_search { #Subroutine + + return _XMLRPCRequest('cust_main.smart_search', @_); + +} + +sub small_custview { + + return _XMLRPCRequest('CGI.small_custview', @_); + +} + +1;
    freeside<% FS::Conf->new->config('company_name') %> Ticketing<% &RT::URI::freeside::FreesideGetConfig('company_name') %> Ticketing % if ($session{'CurrentUser'} && $session{'CurrentUser'}->Id && $LoggedIn) { <&|/l&>Skip Menu | @@ -102,7 +102,7 @@ ONLOAD="
    - Freeside v<% $FS::VERSION %>
    + Freeside v<% &RT::URI::freeside::FreesideVersion() %>
    Documentation
    - > -%# <% $customer->name %> - <% small_custview( $customer, scalar(FS::Conf->new->config('countrydefault')), 1 ) |n %> + > + <% &RT::URI::freeside::small_custview($customer->{'custnum'}, &RT::URI::freeside::FreesideGetConfig('countrydefault'), 1) |n %>
    - <% $customerURI->Resolver->AsStringLong |n %> + <% $customerURI->Resolver->AsStringLong |n %>