diff options
-rw-r--r-- | FS/FS/CGI.pm | 8 | ||||
-rw-r--r-- | FS/FS/ClientAPI/Agent.pm | 69 | ||||
-rw-r--r-- | FS/FS/Conf.pm | 14 | ||||
-rw-r--r-- | FS/FS/TicketSystem.pm | 30 | ||||
-rw-r--r-- | FS/FS/TicketSystem/RT_Internal.pm | 9 | ||||
-rw-r--r-- | FS/FS/TicketSystem/RT_Libs.pm | 1 | ||||
-rw-r--r-- | FS/FS/cust_main.pm | 93 | ||||
-rw-r--r-- | htetc/global.asa | 1 | ||||
-rw-r--r-- | htetc/handler.pl | 3 | ||||
-rw-r--r-- | httemplate/images/small-logo.png | bin | 5261 -> 4887 bytes | |||
-rw-r--r-- | httemplate/index.html | 12 | ||||
-rwxr-xr-x | httemplate/search/cust_main.cgi | 32 | ||||
-rw-r--r-- | rt/FREESIDE_MODIFIED | 7 | ||||
-rw-r--r-- | rt/html/Elements/Header | 8 | ||||
-rw-r--r-- | rt/html/Elements/PageLayout | 2 | ||||
-rw-r--r-- | rt/html/Ticket/Elements/AddCustomers | 65 | ||||
-rw-r--r-- | rt/html/Ticket/Elements/EditCustomers | 79 | ||||
-rw-r--r-- | rt/html/Ticket/Elements/ShowCustomers | 40 | ||||
-rw-r--r-- | rt/html/Ticket/Elements/ShowSummary | 9 | ||||
-rw-r--r-- | rt/html/Ticket/Elements/Tabs | 2 | ||||
-rw-r--r-- | rt/html/Ticket/ModifyCustomers.html | 49 | ||||
-rw-r--r-- | rt/lib/RT/Interface/Web_Vendor.pm | 95 | ||||
-rw-r--r-- | rt/lib/RT/URI/freeside.pm | 80 |
23 files changed, 623 insertions, 85 deletions
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 #<B>'. $cust_main->custnum. '</B>'. + my $html = 'Customer #<B>'. $cust_main->custnum. '</B></A>'. ' - <B><FONT COLOR="'. $cust_main->statuscolor. '">'. ucfirst($cust_main->status). '</FONT></B>'. ntable('#e8e8e8'). '<TR><TD>'. ntable("#cccccc",2). @@ -366,7 +367,8 @@ sub small_custview { $html .= '</TR></TABLE>'; - $html .= '<BR>Balance: <B>$'. $cust_main->balance. '</B><BR>'; + $html .= '<BR>Balance: <B>$'. $cust_main->balance. '</B><BR>' + 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<search>, 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<agentnum>). + +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 Binary files differindex a8fe80791..1e415e6d8 100644 --- a/httemplate/images/small-logo.png +++ b/httemplate/images/small-logo.png diff --git a/httemplate/index.html b/httemplate/index.html index 6283c2217..360cc55e9 100644 --- a/httemplate/index.html +++ b/httemplate/index.html @@ -13,7 +13,7 @@ <IMG BORDER=0 ALT="freeside" SRC="images/small-logo.png"> </td> <td align=left rowspan=2> <!-- valign="top" --> - <font size=7>Billing</font> + <font size=6><%= $conf->config('company_name') %> Billing</font> </td> <td align=right valign=top>Logged in as <b><%= getotaker %></b> </td> @@ -25,8 +25,7 @@ <tr> <td align=right> <FONT SIZE="-2"> - Freeside <%= $FS::VERSION %><BR> - <A HREF="http://www.sisd.com/freeside">Freeside home page</A><BR> + <A HREF="http://www.sisd.com/freeside">Freeside</A> v<%= $FS::VERSION %><BR> <A HREF="docs/">Documentation</A><BR> </FONT> </td> @@ -35,8 +34,7 @@ <td bgcolor=#000000></td> <td align=left> <FONT SIZE="-2"> - RT <%= $RT::VERSION %><BR> - <A HREF="http://www.bestpractical.com/rt">RT home page</A><BR> + <A HREF="http://www.bestpractical.com/rt">RT<A> v<%= $RT::VERSION %><BR> <A HREF="http://wiki.bestpractical.com/">Documentation</A><BR> </FONT> </td> @@ -93,6 +91,10 @@ <TR><TD> <BR><FONT SIZE="+1"><A HREF="rt/">Ticketing Main</A></FONT> <BR> + <UL> + <LI><A HREF="search/cust_main.cgi?browse=tickets">Customers sorted by active tickets</A> + <LI><A HREF="">Active tickets not assigned to a customer</A> + <LI> </TD></TR> </TABLE> 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 "<TH>$addl_header</TH>"; +} + print <<END; <TH>Packages</TH> <TH COLSPAN=2>Services</TH> @@ -370,6 +390,12 @@ END END } + foreach my $addl_col ( @addl_cols ) { + print qq!<TD ROWSPAN=$rowspan><A HREF="XXXnotyetXXX">!. + $cust_main->get($addl_col). + "</A></TD>"; + } + 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=" <table width="100%" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF"> <tr> <td rowspan=2><img border=0 alt="freeside" src="<%$RT::WebImagesURL%>/small-logo.png" width="92" height="62"></td> - <td align="left" rowspan=2><font size=7>Ticketing</font></td> + <td align="left" rowspan=2><font size=6><% FS::Conf->new->config('company_name') %> Ticketing</font></td> <td align="right" valign="top"> % if ($session{'CurrentUser'} && $session{'CurrentUser'}->Id && $LoggedIn) { <SPAN STYLE="display: none"><A HREF="#skipnav"><&|/l&>Skip Menu</&></A> |</SPAN> @@ -67,16 +67,14 @@ ONLOAD=" <tr> <td align=right> <FONT SIZE="-3"> - Freeside <% $FS::VERSION %><BR> - <A HREF="http://www.sisd.com/freeside">Freeside home page</A><BR> + <A HREF="http://www.sisd.com/freeside">Freeside</A> v<% $FS::VERSION %><BR> <A HREF="docs/">Documentation</A><BR> </FONT> </td> <td bgcolor=#000000></td> <td align=left> <FONT SIZE="-3"> - RT <% $RT::VERSION %><BR> - <A HREF="http://www.bestpractical.com/rt">RT home page</A><BR> + <A HREF="http://www.bestpractical.com/rt">RT</A> v<% $RT::VERSION %><BR> <A HREF="http://wiki.bestpractical.com/">Documentation</A><BR> </FONT> </td> 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 @@ </td> </tr> <tr> -<td class="whiteright" valign="top"> +<td class="mediumgrayright" valign="top"> <span class="nav"> % 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 <jesse@bestpractical.com> +%# +%# (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 +<BR> +<%$msg%><br> + +% if (@Customers) { + +<br><i>(Check box to link)<i> +<table> +% foreach my $customer (@Customers) { +<tr> + <td> + <input type="checkbox" name="Ticket-AddCustomer-<% $customer->custnum %>" VALUE="1" <% scalar(@Customers) == 1 ? 'CHECKED' : '' %>> +%# <% $customer->name %> + <A HREF="<% $p %>view/cust_main.cgi?<% $customer->custnum %>"><% small_custview( $customer, scalar(FS::Conf->new->config('countrydefault')), 1 ) |n %> + </td> +</tr> +% } + +% } + +<%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); }; + +</%INIT> + +<%ARGS> +$CustomerString => undef +$ServiceString => undef +</%ARGS> 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 <jesse@bestpractical.com> +%# +%# (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 +<TABLE width=100%> + <TR> + <TD VALIGN=TOP WIDTH=50%> + <h3><&|/l&>Current Customers</&></h3> + +<table> + <tr> + <td><i><&|/l&>(Check box to disassociate)</&></i></td> + </tr> + <tr> + <td class="value"> +% #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 } +% ) { + + <INPUT TYPE=CHECKBOX NAME="DeleteLink--<%$link->Type%>-<%$link->Target%>"> +%# <& ShowLink, URI => $link->TargetURI &><br> + <A HREF="<% $link->TargetURI->Resolver->HREF %>"><% $link->TargetURI->Resolver->AsStringLong |n %> + <BR> +% } + </td> + </tr> +</table> + +</TD> + +<TD VALIGN=TOP> +<h3><&|/l&>New Customer Links</&></h3> +<&|/l&>Find customer</&><BR> +<input name="CustomerString"> +<input type=submit name="OnlySearchForCustomers" value="<&|/l&>Go!</&>"> +<br><i>cust #, last name, or company</i> +<BR> +%#<BR> +%#<&|/l&>Find service</&><BR> +%#<input name="ServiceString"> +%#<input type=submit name="OnlySearchForServices" value="<&|/l&>Go!</&>"> +%#<br><i>username, username@domain, domain, or IP address</i> +%#<BR> + +<& AddCustomers, Ticket => $Ticket, + CustomerString => $CustomerString, + ServiceString => $ServiceString, &> + +</TD> +</TR> +</TABLE> + +<%ARGS> +$CustomerString => undef +$ServiceString => undef +$Ticket => undef +</%ARGS> 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 <ivan-rt@420.am> +%# +%# 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. +<table> +% 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 = ''; + <tr> + <td class="value"> + <A HREF="<% $customerURI->Resolver->HREF %>"><% $customerURI->Resolver->AsStringLong |n %> + </td> + </tr> +% } +% unless ( $cust ) { + <tr> + <td class="labeltop"> + <i>(none)<i> + </td> + </tr> + +% } +</table> +<%ARGS> +$Ticket => undef +</%ARGS> + 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 &> + <br> + + <& /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 &> + <BR> </TD> <TD VALIGN=TOP WIDTH="50%"> 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 <ivan-rt@420.am> +%# +%# 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 &> + +<form action="ModifyCustomers.html" method="post"> +<input type="hidden" name="id" value="<%$Ticket->id%>"> + +<& /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') &> +</form> + + +<%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); +} + +</%INIT> + + +<%ARGS> +$OnlySearchForCustomers => undef +$OnlySearchForServices => undef +$CustomerString => undef +$ServiceString => undef +$id => undef +</%ARGS> 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 <ivan-rt@420.am> +# +# 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"; |