+%my $curuser = $FS::CurrentUser::CurrentUser;
%
+%die "access denied"
+% unless $curuser->access_right('List customers');
%
%my $conf = new FS::Conf;
%my $maxrecords = $conf->config('maxsearchrecordsperpage');
+%my $large_pkg_size = $conf->config('cust_pkg-large_pkg_size') || 0;
%
%#my $cache;
%
% if ( $cgi->param('browse') ) {
% my $query = $cgi->param('browse');
% if ( $query eq 'custnum' ) {
-% $sortby=\*custnum_sort;
-% $orderby = "ORDER BY custnum";
+% if ( $conf->exists('cust_main-default_agent_custid') ) {
+% $sortby=\*display_custnum_sort;
+% $orderby = "ORDER BY CASE WHEN agent_custid IS NOT NULL AND agent_custid != '' THEN CAST(agent_custid AS BIGINT) ELSE custnum END";
+% } else {
+% $sortby=\*custnum_sort;
+% $orderby = "ORDER BY custnum";
+% }
% } elsif ( $query eq 'last' ) {
% $sortby=\*last_sort;
% $orderby = "ORDER BY LOWER(last || ' ' || first)";
% push @select, FS::TicketSystem->sql_num_customer_tickets. " as tickets";
% push @addl_headers, 'Tickets';
% push @addl_cols, 'tickets';
+% } elsif ( $query eq 'uspsunvalid' ) {
+% $search{'country'} = 'US';
+% $sortby=\*custnum_sort;
+% $orderby = "ORDER BY custnum";
% } else {
% die "unknown browse field $query";
% }
% }
%
% if ( $cgi->param('otaker_on') ) {
-% $cgi->param('otaker') =~ /^(\w{1,32})$/ or eidiot "Illegal otaker\n";
+% die "access denied"
+% unless $FS::CurrentUser::CurrentUser->access_right('Configuration');
+% $cgi->param('otaker') =~ /^(\w{1,32})$/ or errorpage("Illegal otaker");
% $search{otaker} = $1;
% } elsif ( $cgi->param('agentnum_on') ) {
-% $cgi->param('agentnum') =~ /^(\d+)$/ or eidiot "Illegal agentnum\n";
+% $cgi->param('agentnum') =~ /^(\d+)$/ or errorpage("Illegal agentnum");
% $search{agentnum} = $1;
%# } else {
%# die "unknown query...";
% $addl_qual .= ( $addl_qual ? ' AND ' : '' ).
% $FS::CurrentUser::CurrentUser->agentnums_sql;
%
+% if ( $cgi->param('browse') && $cgi->param('browse') eq 'uspsunvalid' ) {
+% $addl_qual .= ' AND ( length(zip) < 9 OR upper(address1) != address1 OR upper(city) != city ) ';
+% }
+%
% if ( $addl_qual ) {
% $qual .= ' AND ' if $qual;
% $qual .= $addl_qual;
% if ( $cgi->param('search_cust') ) {
% $sortby = \*company_sort;
% $orderby = "ORDER BY LOWER(company || ' ' || last || ' ' || first )";
-% push @cust_main, smart_search( 'search' => $cgi->param('search_cust') );
+% push @cust_main, smart_search( 'search' => scalar($cgi->param('search_cust')),
+% 'no_fuzzy_on_exact' => 1, #pref?
+% );
% }
%
% @cust_main = grep { $_->ncancelled_pkgs || ! $_->all_pkgs } @cust_main
<!-- mason kludge -->
%
-% eidiot "No matching customers found!\n";
+% errorpage("No matching customers found!");
%} else {
%
% $cgi->param('offset', 0);
% print qq!( <a href="!. $cgi->self_url. qq!">hide!;
% }
-% print ' cancelled customers</a> )';
+% print ' canceled customers</a> )';
% }
%
% if ( $cgi->param('referral_custnum') ) {
% $cgi->param('referral_custnum') =~ /^(\d+)$/
-% or eidiot "Illegal referral_custnum\n";
+% or errorpage("Illegal referral_custnum");
% my $referral_custnum = $1;
% my $cust_main = qsearchs('cust_main', { custnum => $referral_custnum } );
% print '<FORM METHOD="GET">'.
% print ' <SELECT NAME="referral_depth" SIZE="1" onChange="changed(this)">';
% my $max = 8; #config file
% $cgi->param('referral_depth') =~ /^(\d*)$/
-% or eidiot "Illegal referral_depth";
+% or errorpage("Illegal referral_depth");
% my $referral_depth = $1;
%
% foreach my $depth ( 1 .. $max ) {
%
% print "<BR><BR>". $pager. include('/elements/table-grid.html'). <<END;
% <TR>
-% <TH CLASS="grid" BGCOLOR="#cccccc"></TH>
+% <TH CLASS="grid" BGCOLOR="#cccccc">#</TH>
+% <TH CLASS="grid" BGCOLOR="#cccccc">Status</TH>
% <TH CLASS="grid" BGCOLOR="#cccccc">(bill) name</TH>
% <TH CLASS="grid" BGCOLOR="#cccccc">company</TH>
%END
% $cust_main->company,
% );
%
-% my(@lol_cust_svc);
-% my($rowspan)=0;#scalar( @{$all_pkgs{$custnum}} );
-% foreach ( @{$all_pkgs{$custnum}} ) {
-% #my(@cust_svc) = qsearch( 'cust_svc', { 'pkgnum' => $_->pkgnum } );
-% my @cust_svc = $_->cust_svc;
-% push @lol_cust_svc, \@cust_svc;
-% $rowspan += scalar(@cust_svc) || 1;
-% }
+% my @all_cust_svc;
+% my @pkg_rowspans;
+% foreach my $cust_pkg ( @{$all_pkgs{$custnum}} ) {
+% my %cust_svc_by_svcpart;
+% my $rows = 0;
+% foreach my $part_svc ( $cust_pkg->part_svc ) {
+% my $svcpart = $part_svc->svcpart;
+% my $num_cust_svc = $cust_pkg->num_cust_svc($svcpart);
+% if ( $large_pkg_size > 0 and $num_cust_svc >= $large_pkg_size ) {
+% # don't retrieve the cust_svc records, just stash the
+% # part_svc and num_cust_svc for later
+% $cust_svc_by_svcpart{$svcpart} =
+% [ 'summarize', $part_svc, $num_cust_svc ];
+% $rows += 2;
+% }
+% elsif ( $num_cust_svc ) {
+% $cust_svc_by_svcpart{$svcpart} = [ $cust_pkg->cust_svc($svcpart) ];
+% $rows += $num_cust_svc;
+% } #if summarize
+% } #foreach $part_svc
+% $rows ||= 1; # in case the package has no services
+% push @all_cust_svc, \%cust_svc_by_svcpart;
+% push @pkg_rowspans, $rows;
+% } #foreach $cust_pkg
+% my $rowspan = List::Util::sum(@pkg_rowspans) || 1;
%
-% #my($rowspan) = scalar(@{$all_pkgs{$custnum}});
% my $view;
% if ( defined $cgi->param('quickpay') && $cgi->param('quickpay') eq 'yes' ) {
% $view = $p. 'edit/cust_pay.cgi?quickpay=yes;custnum='. $custnum;
% ? qq!<A HREF="$view"><FONT SIZE=-1>$company</FONT></A>!
% : '<FONT SIZE=-1> </FONT>';
%
-
+% my $status = $cust_main->status;
+% my $statuscol = $cust_main->statuscolor;
<TR>
- <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan || 1 %>><A HREF="<% $view %>"><FONT SIZE=-1><% $custnum %></FONT></A></TD>
- <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan || 1 %>><A HREF="<% $view %>"><FONT SIZE=-1><% "$last, $first" %></FONT></A></TD>
- <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan || 1 %>><% $pcompany %></TD>
+ <TD CLASS="grid" ALIGN="right" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan %>><A HREF="<% $view %>"><FONT SIZE=-1><% $cust_main->display_custnum %></FONT></A></TD>
+ <TD CLASS="grid" ALIGN="center" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan %>><FONT SIZE="-1" COLOR="#<% $statuscol %>"><B><% ucfirst($status) %></B></FONT></TD>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan %>><A HREF="<% $view %>"><FONT SIZE=-1><% "$last, $first" %></FONT></A></TD>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan %>><% $pcompany %></TD>
%
% if ( defined dbdef->table('cust_main')->column('ship_last') ) {
% my($ship_last,$ship_first,$ship_company)=(
%
- <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan || 1 %>><A HREF="<% $view %>"><FONT SIZE=-1><% "$ship_last, $ship_first" %></FONT></A></TD>
- <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan || 1 %>><% $pship_company %></A></TD>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan %>><A HREF="<% $view %>"><FONT SIZE=-1><% "$ship_last, $ship_first" %></FONT></A></TD>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan %>><% $pship_company %></A></TD>
% }
%
% foreach my $addl_col ( @addl_cols ) {
% if ( @custom_priorities ) {
- <TD CLASS="inv" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan || 1 %> ALIGN=right><FONT SIZE=-1>
+ <TD CLASS="inv" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan %> ALIGN=right><FONT SIZE=-1>
<TABLE CLASS="inv" CELLSPACING=0 CELLPADDING=0>
% foreach my $priority ( @custom_priorities, '' ) {
% } else {
- <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan || 1 %> ALIGN=right><FONT SIZE=-1>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan %> ALIGN=right><FONT SIZE=-1>
% }
%
% my $ahref = '';
% } else {
- <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan || 1 %> ALIGN=right><FONT SIZE=-1>
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN=<% $rowspan %> ALIGN=right><FONT SIZE=-1>
<% $cust_main->get($addl_col) %>
</FONT></TD>
%
%# my $part_pkg = qsearchs( 'part_pkg', { pkgpart => $_->pkgpart } );
% my $part_pkg = $_->part_pkg;
%
-% my $pkg = $part_pkg->pkg;
-% my $comment = $part_pkg->comment;
-% my $pkgview = "${p}view/cust_main.cgi?$custnum#cust_pkg$pkgnum";
-% my @cust_svc = @{shift @lol_cust_svc};
-% #my(@cust_svc) = qsearch( 'cust_svc', { 'pkgnum' => $_->pkgnum } );
-% my $rowspan = scalar(@cust_svc) || 1;
-%
-% print $n1, qq!<TD CLASS="grid" BGCOLOR="$bgcolor" ROWSPAN=$rowspan><A HREF="$pkgview"><FONT SIZE=-1>$pkg - $comment</FONT></A></TD>!;
-%
-% my($n2)='';
-% foreach my $cust_svc ( @cust_svc ) {
-% my($label, $value, $svcdb) = $cust_svc->label;
-% my($svcnum) = $cust_svc->svcnum;
-% my($sview) = $p.'view';
-% print $n2,qq!<TD CLASS="grid" BGCOLOR="$bgcolor" ><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$label</FONT></A></TD>!,
-% qq!<TD CLASS="grid" BGCOLOR="$bgcolor" ><A HREF="$sview/$svcdb.cgi?$svcnum"><FONT SIZE=-1>$value</FONT></A></TD>!;
-% $n2="</TR><TR>";
-% }
-%
-% unless ( @cust_svc ) {
-% print qq!<TD CLASS="grid" BGCOLOR="$bgcolor" COLSPAN=2> </TD>!;
+% my $pkg_comment = $part_pkg->pkg_comment(nopkgpart => 1);
+% my $show = $curuser->default_customer_view =~ /^(jumbo|packages)$/
+% ? ''
+% : ';show=packages';
+% my $frag = "cust_pkg$pkgnum"; #hack for IE ignoring real #fragment
+% my $pkgview = "${p}view/cust_main.cgi?custnum=$custnum$show;fragment=$frag#$frag";
+% # cust_svc stuff, built earlier
+% my %cust_svc_by_svcpart = %{ shift @all_cust_svc };
+% my $pkg_rowspan = shift @pkg_rowspans;
+
+ <% $n1 %><TD CLASS="grid" BGCOLOR="<% $bgcolor %>" ROWSPAN="<% $pkg_rowspan %>">
+ <A HREF="<% $pkgview %>"><FONT SIZE=-1><% $pkg_comment %></FONT></A></TD>
+
+% my $n2 = '';
+% my $td = '<TD CLASS="grid" BGCOLOR="'.$bgcolor.'">';
+%
+% foreach my $svcpart ( sort keys %cust_svc_by_svcpart ) { #sort order?
+% my $these = $cust_svc_by_svcpart{$svcpart};
+% if ( $these->[0] eq 'summarize' ) {
+% my $part_svc = $these->[1];
+% my $num_cust_svc = $these->[2];
+ <% $n2 %>
+% # summarize
+% # link opens a new search for this pkgnum/svcnum combo
+% my $href = $p.'search/cust_pkg_svc.html?svcpart='.$svcpart.
+% ';pkgnum='.$pkgnum;
+ <% $td %>
+ <A HREF="<% $href %>"><% $part_svc->svc %></A>
+ </TD>
+ <% $td %>
+ <A HREF="<% $href %>"><B>(view all <% $num_cust_svc %>)</B></A>
+ </TD>
+ </TR><TR>
+ <% $td %></TD>
+ <% $td %><& /elements/search-cust_svc.html,
+ 'svcpart' => $svcpart,
+ 'pkgnum' => $pkgnum,
+ 'svcdb' => $part_svc->svcdb,
+ &></TD>
+% $n2="</TR><TR>";
+% }
+% elsif ( scalar @$these ) { # do not summarize
+% foreach my $cust_svc ( @$these ) {
+ <% $n2 %>
+ <% $td %>
+ <% FS::UI::Web::svc_link($m, $cust_svc->part_svc, $cust_svc) %>
+ </TD>
+ <% $td %>
+ <% FS::UI::Web::svc_label_link($m, $cust_svc->part_svc, $cust_svc) %>
+ </TD>
+% $n2 = "</TR><TR>";
+% } # foreach $cust_svc
+% }
+% } # foreach $svcpart
+%
+% unless ( %cust_svc_by_svcpart ) {
+ <TD CLASS="grid" BGCOLOR="<% $bgcolor %>" COLSPAN=2> </TD>
% }
%
% #print qq!</TR><TR>\n!;
% || lc($a->first) cmp lc($b->first);;
%}
%
+%sub display_custnum_sort {
+% $a->display_custnum <=> $b->display_custnum;
+%}
+%
%sub custnum_sort {
% $a->getfield('custnum') <=> $b->getfield('custnum');
%}
%
% my $custnum = $cgi->param('custnum_text');
% $custnum =~ s/\D//g;
-% $custnum =~ /^(\d{1,23})$/ or eidiot "Illegal customer number\n";
+% $custnum =~ /^(\d{1,23})$/ or errorpage("Illegal customer number");
% $custnum = $1;
%
% [ qsearchs('cust_main', { 'custnum' => $custnum } ) ];
%
% my($card)=$cgi->param('card');
% $card =~ s/\D//g;
-% $card =~ /^(\d{13,16})$/ or eidiot "Illegal card number\n";
+% $card =~ /^(\d{13,16})$/ or errorpage("Illegal card number");
% my($payinfo)=$1;
%
% [ qsearch('cust_main',{'payinfo'=>$payinfo, 'payby'=>'CARD'}),
%
%sub referralsearch {
% $cgi->param('referral_custnum') =~ /^(\d+)$/
-% or eidiot "Illegal referral_custnum";
+% or errorpage("Illegal referral_custnum");
% my $cust_main = qsearchs('cust_main', { 'custnum' => $1 } )
-% or eidiot "Customer $1 not found";
+% or errorpage("Customer $1 not found");
% my $depth;
% if ( $cgi->param('referral_depth') ) {
% $cgi->param('referral_depth') =~ /^(\d+)$/
-% or eidiot "Illegal referral_depth";
+% or errorpage("Illegal referral_depth");
% $depth = $1;
% } else {
% $depth = 1;
% }
%
% $cgi->param('last_text') =~ /^([\w \,\.\-\']*)$/
-% or eidiot "Illegal last name";
+% or errorpage("Illegal last name");
% my($last)=$1;
%
% if ( $last_type{'Exact'} || $last_type{'Fuzzy'} ) {
% }
%
% if ( $last_type{'Fuzzy'} || $last_type{'All'} ) {
-% push @cust_main, FS::cust_main->fuzzy_search( { 'last' => $last } );
+% push @cust_main, FS::cust_main::Search->fuzzy_search( { 'last' => $last } );
% }
%
% #if ($last_type{'Sound-alike'}) {
%
% $cgi->param('company_text') =~
% /^([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=]*)$/
-% or eidiot "Illegal company";
+% or errorpage("Illegal company");
% my $company = $1;
%
% if ( $company_type{'Exact'} || $company_type{'Fuzzy'} ) {
% }
%
% if ( $company_type{'Fuzzy'} || $company_type{'All'} ) {
-% push @cust_main, FS::cust_main->fuzzy_search( { 'company' => $company } );
+% push @cust_main, FS::cust_main::Search->fuzzy_search( { 'company' => $company } );
% }
%
% if ($company_type{'Sound-alike'}) {
%
% $cgi->param('address2_text') =~
% /^([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=]*)$/
-% or eidiot "Illegal address2";
+% or errorpage("Illegal address2");
% my $address2 = $1;
%
% push @cust_main, qsearch( 'cust_main',
% { 'address2' => { 'op' => 'ILIKE',
% 'value' => $address2 } } );
% push @cust_main, qsearch( 'cust_main',
-% { 'address2' => { 'op' => 'ILIKE',
-% 'value' => $address2 } } )
-% if defined dbdef->table('cust_main')->column('ship_last');
+% { 'ship_address2' => { 'op' => 'ILIKE',
+% 'value' => $address2 } } );
%
% \@cust_main;
%}
% } elsif ( $phone =~ /^(\d{3,4})$/ ) {
% $phone = $1;
% } else {
-% eidiot gettext('illegal_phone'). ": $phone";
+% errorpage(gettext('illegal_phone'). ": $phone");
% }
%
% my @fields = qw(daytime night fax);
%
% \@cust_main;
%}
-%
-%
-