From b594ce910540fae472cfa1fb132f658d4846c638 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Sat, 27 Apr 2013 13:22:24 -0700 Subject: [PATCH] allow service smart_search to find unlinked svc_* records, related to #22385 --- FS/FS/cust_svc.pm | 20 +++++++++-------- httemplate/misc/cancel-unaudited.cgi | 37 +++++++++++++++++++++----------- httemplate/search/cust_svc.html | 24 ++++++++++++--------- httemplate/view/elements/svc_Common.html | 36 +++++++++++++++++++++---------- httemplate/view/svc_Common.html | 2 +- 5 files changed, 76 insertions(+), 43 deletions(-) diff --git a/FS/FS/cust_svc.pm b/FS/FS/cust_svc.pm index 165384048..cab80a871 100644 --- a/FS/FS/cust_svc.pm +++ b/FS/FS/cust_svc.pm @@ -863,32 +863,34 @@ sub smart_search_param { my @or = map { my $table = $_; my $search_sql = "FS::$table"->search_sql($string); - " ( svcdb = '$table' - AND 0 < ( SELECT COUNT(*) FROM $table - WHERE $table.svcnum = cust_svc.svcnum - AND $search_sql - ) - ) "; + + "SELECT $table.svcnum AS svcnum, '$table' AS svcdb ". + "FROM $table WHERE $search_sql"; } FS::part_svc->svc_tables; if ( $string =~ /^(\d+)$/ ) { - unshift @or, " ( agent_svcid IS NOT NULL AND agent_svcid = $1 ) "; + unshift @or, "SELECT cust_svc.svcnum, NULL FROM cust_svc WHERE agent_svcid = $1"; } - my @extra_sql = ' ( '. join(' OR ', @or). ' ) '; + my $addl_from = " RIGHT JOIN (\n" . join("\nUNION\n", @or) . "\n) AS svc_all ". + " ON (svc_all.svcnum = cust_svc.svcnum) "; + + my @extra_sql; push @extra_sql, $FS::CurrentUser::CurrentUser->agentnums_sql( 'null_right' => 'View/link unlinked services' ); my $extra_sql = ' WHERE '.join(' AND ', @extra_sql); #for agentnum - my $addl_from = ' LEFT JOIN cust_pkg USING ( pkgnum )'. + $addl_from .= ' LEFT JOIN cust_pkg USING ( pkgnum )'. FS::UI::Web::join_cust_main('cust_pkg', 'cust_pkg'). ' LEFT JOIN part_svc USING ( svcpart )'; ( 'table' => 'cust_svc', + 'select' => 'svc_all.svcnum AS svcnum, '. + 'COALESCE(svc_all.svcdb, part_svc.svcdb) AS svcdb', 'addl_from' => $addl_from, 'hashref' => {}, 'extra_sql' => $extra_sql, diff --git a/httemplate/misc/cancel-unaudited.cgi b/httemplate/misc/cancel-unaudited.cgi index 4919c6632..4b3084f00 100755 --- a/httemplate/misc/cancel-unaudited.cgi +++ b/httemplate/misc/cancel-unaudited.cgi @@ -15,19 +15,32 @@ my($query) = $cgi->keywords; $query =~ /^(\d+)$/; my $svcnum = $1; -#my $svc_acct = qsearchs('svc_acct',{'svcnum'=>$svcnum}); -#die "Unknown svcnum!" unless $svc_acct; - +my $error = ''; my $cust_svc = qsearchs('cust_svc',{'svcnum'=>$svcnum}); -die "Unknown svcnum!" unless $cust_svc; -my $cust_pkg = $cust_svc->cust_pkg; -if ( $cust_pkg ) { - errorpage( 'This account has already been audited. Cancel the '. - qq!'. - 'package instead.'); -} +if ( $cust_svc ) { + my $cust_pkg = $cust_svc->cust_pkg; + if ( $cust_pkg ) { + errorpage( 'This account has already been audited. Cancel the '. + qq!'. + 'package instead.'); #' + } -my $error = $cust_svc->cancel; + $error = $cust_svc->cancel; +} else { + # the rare obscure case: svc_x without cust_svc + my $svc_x; + foreach my $svcdb (FS::part_svc->svc_tables) { + $svc_x = qsearchs($svcdb, { 'svcnum' => $svcnum }); + last if $svc_x; + } + if ( $svc_x ) { + $error = $svc_x->return_inventory + || $svc_x->FS::Record::delete; + } else { + # the svcnum really doesn't exist + $error = "svcnum $svcnum not found"; + } +} diff --git a/httemplate/search/cust_svc.html b/httemplate/search/cust_svc.html index e2a83b7de..b245d3114 100644 --- a/httemplate/search/cust_svc.html +++ b/httemplate/search/cust_svc.html @@ -96,6 +96,7 @@ if ( length( $cgi->param('search_svc') ) ) { my $extra_sql = ' WHERE '. join(' AND ', @extra_sql ); $sql_query = { + 'select' => 'svcnum', 'table' => 'cust_svc', 'addl_from' => $addl_from, 'hashref' => {}, @@ -105,8 +106,8 @@ if ( length( $cgi->param('search_svc') ) ) { } $sql_query->{'select'} = join(', ', - 'cust_svc.*', - 'part_svc.*', + $sql_query->{'select'}, + #'part_svc.*', 'cust_main.custnum', FS::UI::Web::cust_sql_fields(), ); @@ -117,14 +118,17 @@ my $count_query = "SELECT COUNT(*) FROM cust_svc ". $sql_query->{addl_from}. my $link = sub { my $cust_svc = shift; - my $url = svc_url( - 'm' => $m, - 'action' => 'view', - #'part_svc' => $cust_svc->part_svc, - 'svcdb' => $cust_svc->svcdb, #we have it from the joined search - #'svc' => $cust_svc, #redundant - 'query' => '', - ); + my $url; + if ( $cust_svc->svcpart ) { + $url = svc_url( + 'm' => $m, + 'action' => 'view', + 'svcdb' => $cust_svc->svcdb, #we have it from the joined search + 'query' => '', + ); + } else { # bizarre unlinked service case + $url = $p.'view/svc_Common.html?svcdb='.$cust_svc->svcdb.';svcnum='; + } [ $url, 'svcnum' ]; }; diff --git a/httemplate/view/elements/svc_Common.html b/httemplate/view/elements/svc_Common.html index d735195fe..997ac142a 100644 --- a/httemplate/view/elements/svc_Common.html +++ b/httemplate/view/elements/svc_Common.html @@ -51,8 +51,10 @@ function areyousure(href) { % } <% mt('Service #') |h %><% $svcnum %> -% my $url = $opt{'edit_url'} || $p. 'edit/'. $opt{'table'}. '.cgi?'; +% if ( $custnum ) { +% my $url = $opt{'edit_url'} || $p. 'edit/'. $opt{'table'}. '.cgi?'; <& /view/elements/svc_edit_link.html, 'svc' => $svc_x, 'edit_url' => $url &> +% }
<% ntable("#cccccc") %><% ntable("#cccccc",2) %> @@ -127,7 +129,9 @@ function areyousure(href) { % } +% if ( $cust_svc ) { <& /elements/table-tickets.html, object => $cust_svc &> +% } <% joblisting({'svcnum'=>$svcnum}, 1) %> @@ -150,7 +154,7 @@ my $fields = $opt{'fields'} my $svcnum; if ( $cgi->param('svcnum') ) { - $cgi->param('svcnum') =~ /^(\d+)$/ or die "unparsable svcnum"; + $cgi->param('svcnum') =~ /^(\d+)$/ or die "unparseable svcnum"; $svcnum = $1; } else { my($query) = $cgi->keywords; @@ -170,19 +174,29 @@ my $svc_x = qsearchs({ }) or die "Unknown svcnum $svcnum in ". $opt{'table'}. " table\n"; my $cust_svc = $svc_x->cust_svc; -my($label, $value, $svcdb) = $cust_svc->label; +my ($label, $value, $svcdb, $part_svc ); +my $labels = $opt{labels}; #not -> here -my $part_svc = $cust_svc->part_svc; +if ( $cust_svc ) { + ($label, $value, $svcdb) = $cust_svc->label; -#false laziness w/edit/svc_Common.html -#override default labels with service-definition labels if applicable -my $labels = $opt{labels}; #not -> here -foreach my $field ( keys %$labels ) { - my $col = $part_svc->part_svc_column($field); - $labels->{$field} = $col->columnlabel if $col->columnlabel !~ /^\s*$/; + $part_svc = $cust_svc->part_svc; + + #false laziness w/edit/svc_Common.html + #override default labels with service-definition labels if applicable + foreach my $field ( keys %$labels ) { + my $col = $part_svc->part_svc_column($field); + $labels->{$field} = $col->columnlabel if $col->columnlabel !~ /^\s*$/; + } +} else { + $label = "Unlinked $table"; + $value = $svc_x->label; + $svcdb = $table; + # just to satisfy callbacks + $part_svc = FS::part_svc->new({ svcpart => 0, svcdb => $table }); } -my $pkgnum = $cust_svc->pkgnum; +my $pkgnum = $cust_svc->pkgnum if $cust_svc; my($cust_pkg, $custnum); if ($pkgnum) { diff --git a/httemplate/view/svc_Common.html b/httemplate/view/svc_Common.html index 7b46dc9c9..7e300b049 100644 --- a/httemplate/view/svc_Common.html +++ b/httemplate/view/svc_Common.html @@ -7,7 +7,7 @@ # false laziness w/edit/svc_Common.html -$cgi->param('svcdb') =~ /^(svc_\w+)$/ or die "unparsable svcdb"; +$cgi->param('svcdb') =~ /^(svc_\w+)$/ or die "unparseable svcdb"; my $table = $1; require "FS/$table.pm"; -- 2.11.0