From 0d1d2630e726ab4ce32bab9c3e4a889eee43fcb4 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 2 Dec 2004 09:59:48 +0000 Subject: [PATCH] second big RT integration checkin, customer linking/delinking interface --- FS/FS/CGI.pm | 8 +-- FS/FS/ClientAPI/Agent.pm | 69 ++---------------------- FS/FS/Conf.pm | 14 +++++ FS/FS/TicketSystem.pm | 30 +++++++++++ FS/FS/TicketSystem/RT_Internal.pm | 9 ++++ FS/FS/TicketSystem/RT_Libs.pm | 1 + FS/FS/cust_main.pm | 93 ++++++++++++++++++++++++++++++++- htetc/global.asa | 1 + htetc/handler.pl | 3 +- httemplate/images/small-logo.png | Bin 5261 -> 4887 bytes httemplate/index.html | 12 +++-- httemplate/search/cust_main.cgi | 32 +++++++++++- rt/FREESIDE_MODIFIED | 7 +++ rt/html/Elements/Header | 8 ++- rt/html/Elements/PageLayout | 2 +- rt/html/Ticket/Elements/AddCustomers | 65 +++++++++++++++++++++++ rt/html/Ticket/Elements/EditCustomers | 79 ++++++++++++++++++++++++++++ rt/html/Ticket/Elements/ShowCustomers | 40 ++++++++++++++ rt/html/Ticket/Elements/ShowSummary | 9 ++++ rt/html/Ticket/Elements/Tabs | 2 + rt/html/Ticket/ModifyCustomers.html | 49 ++++++++++++++++++ rt/lib/RT/Interface/Web_Vendor.pm | 95 ++++++++++++++++++++++++++++++++++ rt/lib/RT/URI/freeside.pm | 80 ++++++++++++++++++++++++++-- 23 files changed, 623 insertions(+), 85 deletions(-) create mode 100644 FS/FS/TicketSystem.pm create mode 100644 rt/html/Ticket/Elements/AddCustomers create mode 100644 rt/html/Ticket/Elements/EditCustomers create mode 100644 rt/html/Ticket/Elements/ShowCustomers create mode 100644 rt/html/Ticket/ModifyCustomers.html create mode 100644 rt/lib/RT/Interface/Web_Vendor.pm diff --git a/FS/FS/CGI.pm b/FS/FS/CGI.pm index 9b406d346..a4fc42fe7 100644 --- a/FS/FS/CGI.pm +++ b/FS/FS/CGI.pm @@ -277,7 +277,7 @@ sub ntable { } -=item small_custview CUSTNUM || CUST_MAIN_OBJECT, COUNTRYDEFAULT +=item small_custview CUSTNUM || CUST_MAIN_OBJECT, COUNTRYDEFAULT, NOBALANCE_FLAG Sheesh. I should just switch to Mason. @@ -289,12 +289,13 @@ sub small_custview { my $arg = shift; my $countrydefault = shift || 'US'; + my $nobalance = shift; my $cust_main = ref($arg) ? $arg : qsearchs('cust_main', { 'custnum' => $arg } ) or die "unknown custnum $arg"; - my $html = 'Customer #'. $cust_main->custnum. ''. + my $html = 'Customer #'. $cust_main->custnum. ''. ' - '. ucfirst($cust_main->status). ''. ntable('#e8e8e8'). ''. ntable("#cccccc",2). @@ -366,7 +367,8 @@ sub small_custview { $html .= ''; - $html .= '
Balance: $'. $cust_main->balance. '
'; + $html .= '
Balance: $'. $cust_main->balance. '
' + unless $nobalance; # last payment might be good here too? diff --git a/FS/FS/ClientAPI/Agent.pm b/FS/FS/ClientAPI/Agent.pm index 1cc11d536..f534a8685 100644 --- a/FS/FS/ClientAPI/Agent.pm +++ b/FS/FS/ClientAPI/Agent.pm @@ -6,9 +6,9 @@ use strict; use vars qw($cache); use Digest::MD5 qw(md5_hex); use Cache::SharedMemoryCache; #store in db? -use FS::Record qw(qsearchs qsearch dbdef dbh); +use FS::Record qw(qsearchs); # qsearch dbdef dbh); use FS::agent; -use FS::cust_main; +use FS::cust_main qw(smart_search); use FS::ClientAPI; FS::ClientAPI->register_handlers( @@ -102,68 +102,9 @@ sub agent_list_customers { my $agent = qsearchs( 'agent', { 'agentnum' => $agentnum } ) or return { 'error' => "unknown agentnum $agentnum" }; - my @cust_main = (); - - #warn $p->{'search'}; - if ( $p->{'search'} =~ /^\s*(\d+)\s*$/ ) { # customer # search - push @cust_main, qsearch('cust_main', { 'agentnum' => $agentnum, - 'custnum' => $1 } ); - } elsif ( $p->{'search'} =~ /^\s*(\S.*\S)\s*$/ ) { #value search - my $value = lc($1); - my $q_value = dbh->quote($value); - - #exact - my $sql = " AND ( LOWER(last) = $q_value OR LOWER(company) = $q_value"; - $sql .= " OR LOWER(ship_last) = $q_value OR LOWER(ship_company) = $q_value" - if defined dbdef->table('cust_main')->column('ship_last'); - $sql .= ' )'; - - push @cust_main, qsearch( 'cust_main', - { 'agentnum' => $agentnum }, - '', - $sql - ); - - unless ( @cust_main ) { - warn "no exact match, trying substring/fuzzy\n"; - - #still some false laziness w/ search/cust_main.cgi - - #substring - push @cust_main, qsearch( 'cust_main', - { 'agentnum' => $agentnum, - 'last' => { 'op' => 'ILIKE', - 'value' => "%$q_value%" } } ); - - push @cust_main, qsearch( 'cust_main', - { 'agentnum' => $agentnum, - 'ship_last' => { 'op' => 'ILIKE', - 'value' => "%$q_value%" } } ) - if defined dbdef->table('cust_main')->column('ship_last'); - - push @cust_main, qsearch( 'cust_main', - { 'agentnum' => $agentnum, - 'company' => { 'op' => 'ILIKE', - 'value' => "%$q_value%" } } ); - - push @cust_main, qsearch( 'cust_main', - { 'agentnum' => $agentnum, - 'ship_company' => { 'op' => 'ILIKE', - 'value' => "%$q_value%" } } ) - if defined dbdef->table('cust_main')->column('ship_last'); - - #fuzzy - push @cust_main, FS::cust_main->fuzzy_search( - { 'last' => $value }, - { 'agentnum' => $agentnum } - ); - push @cust_main, FS::cust_main->fuzzy_search( - { 'company' => $value }, - { 'agentnum' => $agentnum } - ); - - } - } + my @cust_main = smart_search( 'search' => $p->{'search'}, + 'agentnum' => $agentnum, + ); #aggregate searches push @cust_main, diff --git a/FS/FS/Conf.pm b/FS/FS/Conf.pm index ccad607ca..1346796af 100644 --- a/FS/FS/Conf.pm +++ b/FS/FS/Conf.pm @@ -1328,6 +1328,20 @@ httemplate/docs/config.html 'select_enum' => [ '', qw(RT_Internal RT_Libs RT_External) ], }, + { + 'key' => 'ticket_system-custom_priority_field', + 'section' => '', + 'description' => 'Custom field from the ticketing system to use as a custom priority classification.', + 'type' => 'text', + }, + + { + 'key' => 'company_name', + 'section' => 'required', + 'description' => 'Your company name', + 'type' => 'text', + }, + ); 1; diff --git a/FS/FS/TicketSystem.pm b/FS/FS/TicketSystem.pm new file mode 100644 index 000000000..2a5c68f7d --- /dev/null +++ b/FS/FS/TicketSystem.pm @@ -0,0 +1,30 @@ +package FS::TicketSystem; + +use strict; +use vars qw( $system $AUTOLOAD ); +use FS::Conf; +use FS::UID; + +install_callback FS::UID sub { + my $conf = new FS::Conf; + $system = $conf->config('ticket_system'); +}; + +sub AUTOLOAD { + my $self = shift; + + my($sub)=$AUTOLOAD; + $sub =~ s/.*://; + + my $conf = new FS::Conf; + die "FS::TicketSystem::$AUTOLOAD called, but no ticket system configured\n" + unless $system; + + eval "use FS::TicketSystem::$system;"; + die $@ if $@; + + $self .= "::$system"; + $self->$sub(@_); +} + +1; diff --git a/FS/FS/TicketSystem/RT_Internal.pm b/FS/FS/TicketSystem/RT_Internal.pm index a4ecd6a66..ec0c3f7be 100644 --- a/FS/FS/TicketSystem/RT_Internal.pm +++ b/FS/FS/TicketSystem/RT_Internal.pm @@ -1,8 +1,17 @@ package FS::TicketSystem::RT_Internal; use strict; +use vars qw( @ISA ); @ISA = qw( FS::TicketSystem::RT_Libs ); +sub sql_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 + )"; +} + 1; diff --git a/FS/FS/TicketSystem/RT_Libs.pm b/FS/FS/TicketSystem/RT_Libs.pm index b71763237..aba783fdc 100644 --- a/FS/FS/TicketSystem/RT_Libs.pm +++ b/FS/FS/TicketSystem/RT_Libs.pm @@ -1,6 +1,7 @@ package FS::TicketSystem::RT_Libs.pm use strict; +use vars qw( @ISA ); @ISA = qw( FS::TicketSystem::RT_External ); diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index d8dbd5297..27f97f30e 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -1,10 +1,11 @@ package FS::cust_main; use strict; -use vars qw( @ISA $conf $DEBUG $import ); +use vars qw( @ISA @EXPORT_OK $conf $DEBUG $import ); use vars qw( $realtime_bop_decline_quiet ); #ugh use Safe; use Carp; +use Exporter; BEGIN { eval "use Time::Local;"; die "Time::Local minimum version 1.05 required with Perl versions before 5.6" @@ -43,6 +44,8 @@ use FS::Msgcat qw(gettext); @ISA = qw( FS::Record ); +@EXPORT_OK = qw( smart_search ); + $realtime_bop_decline_quiet = 0; $DEBUG = 0; @@ -2977,6 +2980,94 @@ sub fuzzy_search { =over 4 +=item smart_search OPTION => VALUE ... + +Accepts the following options: I, the string to search for. The string +will be searched for as a customer number, last name or company name, first +searching for an exact match then fuzzy and substring matches. + +Any additional options treated as an additional qualifier on the search +(i.e. I). + +Returns a (possibly empty) array of FS::cust_main objects. + +=cut + +sub smart_search { + my %options = @_; + my $search = delete $options{'search'}; + my @cust_main = (); + + if ( $search =~ /^\s*(\d+)\s*$/ ) { # customer # search + + push @cust_main, qsearch('cust_main', { 'custnum' => $1, %options } ); + + } elsif ( $search =~ /^\s*(\S.*\S)\s*$/ ) { #value search + + my $value = lc($1); + my $q_value = dbh->quote($value); + + #exact + my $sql = scalar(keys %options) ? ' AND ' : ' WHERE '; + $sql .= " ( LOWER(last) = $q_value OR LOWER(company) = $q_value"; + $sql .= " OR LOWER(ship_last) = $q_value OR LOWER(ship_company) = $q_value" + if defined dbdef->table('cust_main')->column('ship_last'); + $sql .= ' )'; + + push @cust_main, qsearch( 'cust_main', \%options, '', $sql ); + + unless ( @cust_main ) { #no exact match, trying substring/fuzzy + + #still some false laziness w/ search/cust_main.cgi + + #substring + push @cust_main, qsearch( 'cust_main', + { 'last' => { 'op' => 'ILIKE', + 'value' => "%$q_value%" }, + %options, + } + ); + push @cust_main, qsearch( 'cust_main', + { 'ship_last' => { 'op' => 'ILIKE', + 'value' => "%$q_value%" }, + %options, + + } + ) + if defined dbdef->table('cust_main')->column('ship_last'); + + push @cust_main, qsearch( 'cust_main', + { 'company' => { 'op' => 'ILIKE', + 'value' => "%$q_value%" }, + %options, + } + ); + push @cust_main, qsearch( 'cust_main', + { 'ship_company' => { 'op' => 'ILIKE', + 'value' => "%$q_value%" }, + %options, + } + ) + if defined dbdef->table('cust_main')->column('ship_last'); + + #fuzzy + push @cust_main, FS::cust_main->fuzzy_search( + { 'last' => $value }, + \%options, + ); + push @cust_main, FS::cust_main->fuzzy_search( + { 'company' => $value }, + \%options, + ); + + } + + } + + @cust_main; + +} + =item check_and_rebuild_fuzzyfiles =cut diff --git a/htetc/global.asa b/htetc/global.asa index 5cfcca6b4..612f6f4af 100644 --- a/htetc/global.asa +++ b/htetc/global.asa @@ -32,6 +32,7 @@ use FS::CGI qw(header menubar popurl table itable ntable idiot eidiot use FS::Msgcat qw(gettext geterror); use FS::Misc qw( send_email ); use FS::Report::Table::Monthly; +use FS::TicketSystem; use FS::agent; use FS::agent_type; diff --git a/htetc/handler.pl b/htetc/handler.pl index a17aff10e..c91a0ecba 100644 --- a/htetc/handler.pl +++ b/htetc/handler.pl @@ -115,6 +115,7 @@ sub handler use FS::Msgcat qw(gettext geterror); use FS::Misc qw( send_email ); use FS::Report::Table::Monthly; + use FS::TicketSystem; use FS::agent; use FS::agent_type; @@ -123,7 +124,7 @@ sub handler use FS::cust_bill_pay; use FS::cust_credit; use FS::cust_credit_bill; - use FS::cust_main; + use FS::cust_main qw(smart_search); use FS::cust_main_county; use FS::cust_pay; use FS::cust_pkg; diff --git a/httemplate/images/small-logo.png b/httemplate/images/small-logo.png index a8fe80791a236c6f3db1a897a3d5d8c33f3a4132..1e415e6d855d08db32c5d806c44ca9ca5812b314 100644 GIT binary patch literal 4887 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 JPDHLkV1oSof|dXP literal 5261 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 - Billing + <%= $conf->config('company_name') %> Billing Logged in as <%= getotaker %> @@ -25,8 +25,7 @@ - Freeside <%= $FS::VERSION %>
- Freeside home page
+ Freeside v<%= $FS::VERSION %>
Documentation
@@ -35,8 +34,7 @@ - RT <%= $RT::VERSION %>
- RT home page
+ RT v<%= $RT::VERSION %>
Documentation
@@ -93,6 +91,10 @@
Ticketing Main
+
    +
  • Customers sorted by active tickets +
  • Active tickets not assigned to a customer +
  • diff --git a/httemplate/search/cust_main.cgi b/httemplate/search/cust_main.cgi index 27f23de36..c4b0ce0cd 100755 --- a/httemplate/search/cust_main.cgi +++ b/httemplate/search/cust_main.cgi @@ -48,6 +48,9 @@ $limit .= " OFFSET $offset" if $offset; my $total = 0; my(@cust_main, $sortby, $orderby); +my @select = (); +my @addl_headers = (); +my @addl_cols = (); if ( $cgi->param('browse') || $cgi->param('otaker_on') || $cgi->param('agentnum_on') @@ -65,6 +68,12 @@ if ( $cgi->param('browse') } elsif ( $query eq 'company' ) { $sortby=\*company_sort; $orderby = "ORDER BY LOWER(company || ' ' || last || ' ' || first )"; + } elsif ( $query eq 'tickets' ) { + $sortby = \*tickets_sort; + $orderby = "ORDER BY tickets DESC"; + push @select, FS::TicketSystem->sql_customer_tickets. " as tickets"; + push @addl_headers, 'Tickets'; + push @addl_cols, 'tickets'; } else { die "unknown browse field $query"; } @@ -136,7 +145,14 @@ if ( $cgi->param('browse') } } - @cust_main = qsearch('cust_main', \%search, '', + my $select; + if ( @select ) { + $select = 'cust_main.*, '. join (', ', @select); + } else { + $select = '*'; + } + + @cust_main = qsearch('cust_main', \%search, $select, "$addl_qual $orderby $limit" ); # foreach my $cust_main ( @just_cust_main ) { @@ -312,6 +328,10 @@ if ( defined dbdef->table('cust_main')->column('ship_last') ) { END } +foreach my $addl_header ( @addl_headers ) { + print "$addl_header"; +} + print <Packages Services @@ -370,6 +390,12 @@ END END } + foreach my $addl_col ( @addl_cols ) { + print qq!!. + $cust_main->get($addl_col). + ""; + } + my($n1)=''; foreach ( @{$all_pkgs{$custnum}} ) { my $pkgnum = $_->pkgnum; @@ -424,6 +450,10 @@ sub custnum_sort { $a->getfield('custnum') <=> $b->getfield('custnum'); } +sub tickets_sort { + $a->getfield('tickets') <=> $b->getfield('tickets'); +} + sub custnumsearch { my $custnum = $cgi->param('custnum_text'); diff --git a/rt/FREESIDE_MODIFIED b/rt/FREESIDE_MODIFIED index 1f3f55c62..67bcfecb8 100644 --- a/rt/FREESIDE_MODIFIED +++ b/rt/FREESIDE_MODIFIED @@ -3,11 +3,18 @@ sbin/rt-setup-database.in config.layout config.layout.in etc/RT_SiteConfig.pm +lib/RT/Interface/Web_Vendor.pm lib/RT/URI/freeside.pm html/Elements/Header html/Elements/PageLayout html/Elements/SimpleSearch html/Elements/Tabs html/Elements/Footer +html/Ticket/Elements/AddCustomers +html/Ticket/Elements/EditCustomers +html/Ticket/Elements/ShowCustomers +html/Ticket/Elements/ShowSummary +html/Ticket/Elements/Tabs +html/Ticket/ModifyCustomers.html html/NoAuth/images/small-logo.png html/NoAuth/webrt.css diff --git a/rt/html/Elements/Header b/rt/html/Elements/Header index 92c186bd5..38cb4bd6b 100644 --- a/rt/html/Elements/Header +++ b/rt/html/Elements/Header @@ -43,7 +43,7 @@ ONLOAD=" - + diff --git a/rt/html/Elements/PageLayout b/rt/html/Elements/PageLayout index 86b6b565e..6146b807c 100644 --- a/rt/html/Elements/PageLayout +++ b/rt/html/Elements/PageLayout @@ -46,7 +46,7 @@ -
    freesideTicketing<% FS::Conf->new->config('company_name') %> Ticketing % if ($session{'CurrentUser'} && $session{'CurrentUser'}->Id && $LoggedIn) { <&|/l&>Skip Menu | @@ -67,16 +67,14 @@ ONLOAD="
    - Freeside <% $FS::VERSION %>
    - Freeside home page
    + Freeside v<% $FS::VERSION %>
    Documentation
    - RT <% $RT::VERSION %>
    - RT home page
    + RT v<% $RT::VERSION %>
    Documentation
    + % if ($actions) { % my @actions; diff --git a/rt/html/Ticket/Elements/AddCustomers b/rt/html/Ticket/Elements/AddCustomers new file mode 100644 index 000000000..b26b3a638 --- /dev/null +++ b/rt/html/Ticket/Elements/AddCustomers @@ -0,0 +1,65 @@ +%# BEGIN LICENSE BLOCK +%# +%# 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 +
    +<%$msg%>
    + +% if (@Customers) { + +
    (Check box to link) + +% foreach my $customer (@Customers) { + + + +% } + +% } + +<%INIT> +my ($msg); + +my @Customers = (); +if ( $CustomerString ) { + @Customers = smart_search( 'search' => $CustomerString ); + warn scalar(@Customers); +} + +my @Services = (); +if ($ServiceString) { + @Services = (); #service_search(); +} + +eval { use FS::CGI qw( popurl small_custview ); }; +my $p = eval { popurl(3); }; + + + +<%ARGS> +$CustomerString => undef +$ServiceString => undef + diff --git a/rt/html/Ticket/Elements/EditCustomers b/rt/html/Ticket/Elements/EditCustomers new file mode 100644 index 000000000..49edb27b3 --- /dev/null +++ b/rt/html/Ticket/Elements/EditCustomers @@ -0,0 +1,79 @@ +%# BEGIN LICENSE BLOCK +%# +%# 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 +
    + > +%# <% $customer->name %> + <% small_custview( $customer, scalar(FS::Conf->new->config('countrydefault')), 1 ) |n %> +
    + + + + + +
    +

    <&|/l&>Current Customers

    + + + + + + + + +
    <&|/l&>(Check box to disassociate)
    +% #while (my $link = $Ticket->MemberOf->Next) { +% foreach my $link ( +% grep { $_->TargetURI->Resolver->{'fstable'} eq 'cust_main' } +% grep { $_->TargetURI->Scheme eq 'freeside' } +% @{ $Ticket->_Links('Base')->ItemsArrayRef } +% ) { + + +%# <& ShowLink, URI => $link->TargetURI &>
    + <% $link->TargetURI->Resolver->AsStringLong |n %> +
    +% } +
    + +
    +

    <&|/l&>New Customer Links

    +<&|/l&>Find customer
    + + +
    cust #, last name, or company +
    +%#
    +%#<&|/l&>Find service
    +%# +%# +%#
    username, username@domain, domain, or IP address +%#
    + +<& AddCustomers, Ticket => $Ticket, + CustomerString => $CustomerString, + ServiceString => $ServiceString, &> + +
    + +<%ARGS> +$CustomerString => undef +$ServiceString => undef +$Ticket => undef + diff --git a/rt/html/Ticket/Elements/ShowCustomers b/rt/html/Ticket/Elements/ShowCustomers new file mode 100644 index 000000000..5519d24cf --- /dev/null +++ b/rt/html/Ticket/Elements/ShowCustomers @@ -0,0 +1,40 @@ +%# Copyright (c) 2004 Ivan Kohler +%# +%# 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. + +% my $cust = 0; +% foreach my $customerURI ( +% grep { $_->Resolver->{'fstable'} eq 'cust_main' } +% grep { $_->Scheme eq 'freeside' } +% map { $_->TargetURI } +% @{ $Ticket->_Links('Base')->ItemsArrayRef } +% ) { +% $cust++; +% my $cust_main = ''; + + + +% } +% unless ( $cust ) { + + + + +% } +
    + <% $customerURI->Resolver->AsStringLong |n %> +
    + (none) +
    +<%ARGS> +$Ticket => undef + + diff --git a/rt/html/Ticket/Elements/ShowSummary b/rt/html/Ticket/Elements/ShowSummary index 5bcc94b41..1b9f62908 100644 --- a/rt/html/Ticket/Elements/ShowSummary +++ b/rt/html/Ticket/Elements/ShowSummary @@ -47,6 +47,15 @@ color => "#333399" &> <& /Ticket/Elements/ShowPeople, Ticket => $Ticket &> <& /Elements/TitleBoxEnd &> +
    + + <& /Elements/TitleBoxStart, title => loc('Customers'), + title_href =>"$RT::WebPath/Ticket/ModifyCustomers.html?id=".$Ticket->Id, + title_class=> 'inverse', + color => "#7f007b" &> + <& /Ticket/Elements/ShowCustomers, Ticket => $Ticket &> + <& /Elements/TitleBoxEnd &> +
    diff --git a/rt/html/Ticket/Elements/Tabs b/rt/html/Ticket/Elements/Tabs index cba45df91..26b252707 100644 --- a/rt/html/Ticket/Elements/Tabs +++ b/rt/html/Ticket/Elements/Tabs @@ -101,6 +101,8 @@ my $ticket_page_tabs = { { title => loc('People'), path => "Ticket/ModifyPeople.html?id=" . $id, }, _E => { title => loc('Links'), path => "Ticket/ModifyLinks.html?id=" . $id, }, + _Eb=> { title => loc('Customers'), + path => "Ticket/ModifyCustomers.html?id=" . $id, }, _F => { title => loc('Jumbo'), path => "Ticket/ModifyAll.html?id=" . $id, seperator => 1 diff --git a/rt/html/Ticket/ModifyCustomers.html b/rt/html/Ticket/ModifyCustomers.html new file mode 100644 index 000000000..72d103b23 --- /dev/null +++ b/rt/html/Ticket/ModifyCustomers.html @@ -0,0 +1,49 @@ +%# Copyright (c) 2004 Ivan Kohler +%# +%# 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. +<& /Elements/Header, Title => loc("Customers for ticket #[_1]", $Ticket->Id) &> +<& /Ticket/Elements/Tabs, + Ticket => $Ticket, + current_tab => "Ticket/ModifyCustomers.html?id=".$Ticket->Id, + Title => loc("Customers for ticket #[_1]", $Ticket->Id) &> + +<& /Elements/ListActions, actions => \@results &> + +
    + + +<& /Elements/TitleBoxStart, title => loc('Edit Customer Links'), color => "#7f007b"&> +<& Elements/EditCustomers, Ticket => $Ticket, CustomerString => $CustomerString, ServiceString => $ServiceString &> +<& /Elements/TitleBoxEnd &> +<& /Elements/Submit, color => "#7f007b", Label => loc('Save Changes') &> +
    + + +<%INIT> + +my @results = (); +my $Ticket = LoadTicket($id); + +# if we're trying to search for customers/services and nothing else +unless ( $OnlySearchForCustomers || $OnlySearchForServices) { + @results = ProcessTicketCustomers( TicketObj => $Ticket, ARGSRef => \%ARGS); +} + + + + +<%ARGS> +$OnlySearchForCustomers => undef +$OnlySearchForServices => undef +$CustomerString => undef +$ServiceString => undef +$id => undef + diff --git a/rt/lib/RT/Interface/Web_Vendor.pm b/rt/lib/RT/Interface/Web_Vendor.pm new file mode 100644 index 000000000..5be20e6b9 --- /dev/null +++ b/rt/lib/RT/Interface/Web_Vendor.pm @@ -0,0 +1,95 @@ +# Copyright (c) 2004 Ivan Kohler +# +# 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. + +=head1 NAME + +RT::Interface::Web_Vendor + +=head1 SYNOPSIS + +=head1 DESCRIPTION + +Freeside vendor overlay for RT::Interface::Web. + +=begin testing + +use_ok(RT::Interface::Web_Vendor); + +=end testing + +=cut + +#package RT::Interface::Web; +#use strict; + +package HTML::Mason::Commands; +use strict; + +=head2 ProcessTicketCustomers + +=cut + +sub ProcessTicketCustomers { + my %args = ( + TicketObj => undef, + ARGSRef => undef, + @_ + ); + my @results = (); + + my $Ticket = $args{'TicketObj'}; + my $ARGSRef = $args{'ARGSRef'}; + + ### false laziness w/RT::Interface::Web::ProcessTicketLinks + # Delete links that are gone gone gone. + foreach my $arg ( keys %$ARGSRef ) { + if ( $arg =~ /DeleteLink-(.*?)-(DependsOn|MemberOf|RefersTo)-(.*)$/ ) { + my $base = $1; + my $type = $2; + my $target = $3; + + push @results, + "Trying to delete: Base: $base Target: $target Type $type"; + my ( $val, $msg ) = $Ticket->DeleteLink( Base => $base, + Type => $type, + Target => $target ); + + push @results, $msg; + + } + + } + ### + + my @delete_custnums = + map { /^Ticket-AddCustomer-(\d+)$/; $1 } + grep { /^Ticket-AddCustomer-(\d+)$/ && $ARGSRef->{$_} } + keys %$ARGSRef; + + my @custnums = map { /^Ticket-AddCustomer-(\d+)$/; $1 } + grep { /^Ticket-AddCustomer-(\d+)$/ && $ARGSRef->{$_} } + keys %$ARGSRef; + + foreach my $custnum ( @custnums ) { + my( $val, $msg ) = + $Ticket->AddLink( 'Type' => 'MemberOf', + 'Target' => "freeside://freeside/cust_main/$custnum", + ); + push @results, $msg; + } + + return @results; + +} + +1; + diff --git a/rt/lib/RT/URI/freeside.pm b/rt/lib/RT/URI/freeside.pm index bfb514df8..ebd24ad60 100644 --- a/rt/lib/RT/URI/freeside.pm +++ b/rt/lib/RT/URI/freeside.pm @@ -82,10 +82,11 @@ sub FreesideURILabel { $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}" : ''; + #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}"; } @@ -103,6 +104,61 @@ sub FreesideURILabel { } +sub FreesideURILabelLong { + + my $self = shift; + + return(undef) 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}"; + #} + $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 = ''; + } + + #... other cases + + }; + + if ($label and !$@) { + return($label); + } else { + warn $@; + return(undef); + } + + +} + sub ParseURI { my $self = shift; my $uri = shift; @@ -180,6 +236,22 @@ sub AsString { } } +=head2 AsStringLong + +Return a longer (HTML) string representing the URI object. + +=cut + +sub AsStringLong { + my $self = shift; + my $prettystring; + 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"; -- 2.11.0