optimize customer list, RT#20173
authorIvan Kohler <ivan@freeside.biz>
Thu, 24 Mar 2016 04:05:21 +0000 (21:05 -0700)
committerIvan Kohler <ivan@freeside.biz>
Thu, 24 Mar 2016 04:05:21 +0000 (21:05 -0700)
FS/FS/cust_main/Packages.pm
FS/FS/cust_pkg.pm
FS/FS/cust_svc.pm
FS/FS/part_pkg.pm
httemplate/search/cust_main.cgi

index 2b3634a..fc5927c 100644 (file)
@@ -10,6 +10,7 @@ use FS::contact;       # for attach_pkgs
 use FS::cust_location; #
 
 our ($DEBUG, $me) = (0, '[FS::cust_main::Packages]');
 use FS::cust_location; #
 
 our ($DEBUG, $me) = (0, '[FS::cust_main::Packages]');
+our $skip_label_sort = 0;
 
 =head1 NAME
 
 
 =head1 NAME
 
@@ -443,7 +444,9 @@ sub all_pkgs {
     @cust_pkg = $self->_cust_pkg($extra_qsearch);
   }
 
     @cust_pkg = $self->_cust_pkg($extra_qsearch);
   }
 
+  local($skip_label_sort) = 1 if $extra_qsearch->{skip_label_sort};
   map { $_ } sort sort_packages @cust_pkg;
   map { $_ } sort sort_packages @cust_pkg;
+
 }
 
 =item cust_pkg
 }
 
 =item cust_pkg
@@ -492,6 +495,7 @@ sub ncancelled_pkgs {
 
   }
 
 
   }
 
+  local($skip_label_sort) = 1 if $extra_qsearch->{skip_label_sort};
   sort sort_packages @cust_pkg;
 
 }
   sort sort_packages @cust_pkg;
 
 }
@@ -534,7 +538,8 @@ sub sort_packages {
     return 0  if !$a_num_cust_svc && !$b_num_cust_svc;
     return -1 if  $a_num_cust_svc && !$b_num_cust_svc;
     return 1  if !$a_num_cust_svc &&  $b_num_cust_svc;
     return 0  if !$a_num_cust_svc && !$b_num_cust_svc;
     return -1 if  $a_num_cust_svc && !$b_num_cust_svc;
     return 1  if !$a_num_cust_svc &&  $b_num_cust_svc;
-    return 0 if $a_num_cust_svc + $b_num_cust_svc > 20; #for perf, just give up
+    return 0 if $skip_label_sort
+             || $a_num_cust_svc + $b_num_cust_svc > 20; #for perf, just give up
     my @a_cust_svc = $a->cust_svc_unsorted;
     my @b_cust_svc = $b->cust_svc_unsorted;
     return 0  if !scalar(@a_cust_svc) && !scalar(@b_cust_svc);
     my @a_cust_svc = $a->cust_svc_unsorted;
     my @b_cust_svc = $b->cust_svc_unsorted;
     return 0  if !scalar(@a_cust_svc) && !scalar(@b_cust_svc);
index 85234cf..1bd18e0 100644 (file)
@@ -3261,16 +3261,15 @@ sub cust_svc_unsorted_arrayref {
   }
 
   my %search = (
   }
 
   my %search = (
-    'table'   => 'cust_svc',
-    'hashref' => { 'pkgnum' => $self->pkgnum },
+    'select'    => 'cust_svc.*, part_svc.*',
+    'table'     => 'cust_svc',
+    'hashref'   => { 'pkgnum' => $self->pkgnum },
+    'addl_from' => 'LEFT JOIN part_svc USING ( svcpart )',
   );
   );
-  if ( $opt{svcpart} ) {
-    $search{hashref}->{svcpart} = $opt{'svcpart'};
-  }
-  if ( $opt{'svcdb'} ) {
-    $search{addl_from} = ' LEFT JOIN part_svc USING ( svcpart ) ';
-    $search{extra_sql} = ' AND svcdb = '. dbh->quote( $opt{'svcdb'} );
-  }
+  $search{hashref}->{svcpart} = $opt{svcpart}
+    if $opt{svcpart};
+  $search{extra_sql} = ' AND svcdb = '. dbh->quote( $opt{svcdb} )
+    if $opt{svcdb};
 
   [ qsearch(\%search) ];
 
 
   [ qsearch(\%search) ];
 
index d432747..d91fa0d 100644 (file)
@@ -3,7 +3,7 @@ use base qw( FS::cust_main_Mixin FS::option_Common ); #FS::Record );
 
 use strict;
 use vars qw( $DEBUG $me $ignore_quantity $conf $ticket_system );
 
 use strict;
 use vars qw( $DEBUG $me $ignore_quantity $conf $ticket_system );
-use Carp;
+use Carp qw(cluck);
 #use Scalar::Util qw( blessed );
 use List::Util qw( max );
 use FS::Conf;
 #use Scalar::Util qw( blessed );
 use List::Util qw( max );
 use FS::Conf;
@@ -32,6 +32,15 @@ FS::UID->install_callback( sub {
   $ticket_system = $conf->config('ticket_system')
 });
 
   $ticket_system = $conf->config('ticket_system')
 });
 
+our $cache_enabled = 0;
+
+sub _simplecache {
+  my( $self, $hashref ) = @_;
+  if ( $cache_enabled && $hashref->{'svc'} ) {
+    $self->{'_svcpart'} = FS::part_svc->new($hashref);
+  }
+}
+
 sub _cache {
   my $self = shift;
   my ( $hashref, $cache ) = @_;
 sub _cache {
   my $self = shift;
   my ( $hashref, $cache ) = @_;
@@ -629,9 +638,9 @@ L<FS::part_svc>).
 
 sub part_svc {
   my $self = shift;
 
 sub part_svc {
   my $self = shift;
-  $self->{'_svcpart'}
-    ? $self->{'_svcpart'}
-    : qsearchs( 'part_svc', { 'svcpart' => $self->svcpart } );
+  return $self->{_svcpart} if $self->{_svcpart};
+  cluck 'cust_svc->part_svc called' if $DEBUG;
+  qsearchs( 'part_svc', { 'svcpart' => $self->svcpart } );
 }
 
 =item cust_pkg
 }
 
 =item cust_pkg
index 8f00304..9ed623f 100644 (file)
@@ -1119,14 +1119,11 @@ sub pkg_svc {
 #      qsearch( 'pkg_svc', { 'pkgpart' => $self->pkgpart } );
 
   my $opt = ref($_[0]) ? $_[0] : { @_ };
 #      qsearch( 'pkg_svc', { 'pkgpart' => $self->pkgpart } );
 
   my $opt = ref($_[0]) ? $_[0] : { @_ };
-  my %pkg_svc = map  { $_->svcpart => $_ }
-                grep { $_->quantity }
-                qsearch( 'pkg_svc', { 'pkgpart' => $self->pkgpart } );
+  my %pkg_svc = map  { $_->svcpart => $_ } $self->_pkg_svc;
 
   unless ( $opt->{disable_linked} ) {
     foreach my $dst_pkg ( map $_->dst_pkg, $self->svc_part_pkg_link ) {
 
   unless ( $opt->{disable_linked} ) {
     foreach my $dst_pkg ( map $_->dst_pkg, $self->svc_part_pkg_link ) {
-      my @pkg_svc = grep { $_->quantity }
-                    qsearch( 'pkg_svc', { pkgpart=>$dst_pkg->pkgpart } );
+      my @pkg_svc = $dst_pkg->_pkg_svc;
       foreach my $pkg_svc ( @pkg_svc ) {
         if ( $pkg_svc{$pkg_svc->svcpart} ) {
           my $quantity = $pkg_svc{$pkg_svc->svcpart}->quantity;
       foreach my $pkg_svc ( @pkg_svc ) {
         if ( $pkg_svc{$pkg_svc->svcpart} ) {
           my $quantity = $pkg_svc{$pkg_svc->svcpart}->quantity;
@@ -1146,6 +1143,17 @@ sub pkg_svc {
 
 }
 
 
 }
 
+sub _pkg_svc {
+  my $self = shift;
+  grep { $_->quantity }
+    qsearch({
+      'select'    => 'pkg_svc.*, part_svc.*',
+      'table'     => 'pkg_svc',
+      'addl_from' => 'LEFT JOIN part_svc USING ( svcpart )',
+      'hashref'   => { 'pkgpart' => $self->pkgpart },
+    });
+}
+
 =item svcpart [ SVCDB ]
 
 Returns the svcpart of the primary service definition (see L<FS::part_svc>)
 =item svcpart [ SVCDB ]
 
 Returns the svcpart of the primary service definition (see L<FS::part_svc>)
index 96f5af9..e6ab195 100755 (executable)
 %      my %cust_svc_by_svcpart;
 %      my $rows = 0;
 %      local($FS::part_pkg::cache_enabled) = 1; #for $cust_pkg->part_svc
 %      my %cust_svc_by_svcpart;
 %      my $rows = 0;
 %      local($FS::part_pkg::cache_enabled) = 1; #for $cust_pkg->part_svc
+%      local($FS::cust_svc::cache_enabled) = 1; #for $cust_svc->part_svc
+%      local($FS::pkg_svc::cache_enabled) = 1; #for $pkg_svc->part_svc
 %      foreach my $part_svc (
 %        $cust_pkg->part_svc( summarize_size=>$large_pkg_size )
 %      ) {
 %      foreach my $part_svc (
 %        $cust_pkg->part_svc( summarize_size=>$large_pkg_size )
 %      ) {
 %         }
 %         elsif ( scalar @$these ) { # do not summarize
 %           foreach my $cust_svc ( @$these ) {
 %         }
 %         elsif ( scalar @$these ) { # do not summarize
 %           foreach my $cust_svc ( @$these ) {
+%             my $part_svc = $cust_svc->part_svc;
           <% $n2 %>
             <% $td %>
           <% $n2 %>
             <% $td %>
-                <% FS::UI::Web::svc_link($m, $cust_svc->part_svc, $cust_svc) %>
+                <% FS::UI::Web::svc_link($m, $part_svc, $cust_svc) %>
             </TD> 
             <% $td %>
             </TD> 
             <% $td %>
-                <% FS::UI::Web::svc_label_link($m, $cust_svc->part_svc, $cust_svc) %>
+                <% FS::UI::Web::svc_label_link($m, $part_svc, $cust_svc) %>
             </TD>
 %             $n2="</TR><TR>";
 %           } #foreach $cust_svc
             </TD>
 %             $n2="</TR><TR>";
 %           } #foreach $cust_svc
@@ -517,8 +520,9 @@ if ( scalar(@cust_main) > 1 || $cgi->param('referral_custnum') ) {
 
   local($FS::cust_pkg::cache_enabled) = 1; #for $cust_pkg->part_pkg
   %all_pkgs = map { $_->custnum =>
 
   local($FS::cust_pkg::cache_enabled) = 1; #for $cust_pkg->part_pkg
   %all_pkgs = map { $_->custnum =>
-                      [ $_->$pkgs_method({ select    => $select,
-                                           addl_from => $addl_from,
+                      [ $_->$pkgs_method({ select          => $select,
+                                           addl_from       => $addl_from,
+                                           skip_label_sort => 1,
                                         })
                       ];
                   }
                                         })
                       ];
                   }