fix multiple pkgpart search, RT#5924
[freeside.git] / FS / FS / cust_pkg.pm
index 4d44692..4e57fbf 100644 (file)
@@ -1188,13 +1188,14 @@ sub change {
   }
 
   #reset usage if changing pkgpart
+  # AND usage rollover is off (otherwise adds twice, now and at package bill)
   if ($self->pkgpart != $cust_pkg->pkgpart) {
     my $part_pkg = $cust_pkg->part_pkg;
     $error = $part_pkg->reset_usage($cust_pkg, $part_pkg->is_prepaid
                                                  ? ()
                                                  : ( 'null' => 1 )
                                    )
-      if $part_pkg->can('reset_usage');
+      if $part_pkg->can('reset_usage') && ! $part_pkg->option('usage_rollover');
 
     if ($error) {
       $dbh->rollback if $oldAutoCommit;
@@ -1750,6 +1751,63 @@ sub statuscolor {
   $statuscolor{$self->status};
 }
 
+=item pkg_label
+
+Returns a label for this package.  (Currently "pkgnum: pkg - comment" or
+"pkg-comment" depending on user preference).
+
+=cut
+
+sub pkg_label {
+  my $self = shift;
+  my $label = $self->part_pkg->pkg_comment( 'nopkgpart' => 1 );
+  $label = $self->pkgnum. ": $label"
+    if $FS::CurrentUser::CurrentUser->option('show_pkgnum');
+  $label;
+}
+
+=item pkg_label_long
+
+Returns a long label for this package, adding the primary service's label to
+pkg_label.
+
+=cut
+
+sub pkg_label_long {
+  my $self = shift;
+  my $label = $self->pkg_label;
+  my $cust_svc = $self->primary_cust_svc;
+  $label .= ' ('. ($cust_svc->label)[1]. ')' if $cust_svc;
+  $label;
+}
+
+=item primary_cust_svc
+
+Returns a primary service (as FS::cust_svc object) if one can be identified.
+
+=cut
+
+#for labeling purposes - might not 100% match up with part_pkg->svcpart's idea
+
+sub primary_cust_svc {
+  my $self = shift;
+
+  my @cust_svc = $self->cust_svc;
+
+  return '' unless @cust_svc; #no serivces - irrelevant then
+  
+  return $cust_svc[0] if scalar(@cust_svc) == 1; #always return a single service
+
+  # primary service as specified in the package definition
+  # or exactly one service definition with quantity one
+  my $svcpart = $self->part_pkg->svcpart;
+  @cust_svc = grep { $_->svcpart == $svcpart } @cust_svc;
+  return $cust_svc[0] if scalar(@cust_svc) == 1;
+
+  #couldn't identify one thing..
+  return '';
+}
+
 =item labels
 
 Returns a list of lists, calling the label method for all services
@@ -1778,6 +1836,19 @@ sub h_labels {
   map { [ $_->label(@_) ] } $self->h_cust_svc(@_);
 }
 
+=item labels_short
+
+Like labels, except returns a simple flat list, and shortens long
+(currently >5 or the cust_bill-max_same_services configuration value) lists of
+identical services to one line that lists the service label and the number of
+individual services rather than individual items.
+
+=cut
+
+sub labels_short {
+  shift->_labels_short( 'labels', @_ );
+}
+
 =item h_labels_short END_TIMESTAMP [ START_TIMESTAMP ]
 
 Like h_labels, except returns a simple flat list, and shortens long
@@ -1788,7 +1859,11 @@ individual services rather than individual items.
 =cut
 
 sub h_labels_short {
-  my $self = shift;
+  shift->_labels_short( 'h_labels', @_ );
+}
+
+sub _labels_short {
+  my( $self, $method ) = ( shift, shift );
 
   my $conf = new FS::Conf;
   my $max_same_services = $conf->config('cust_bill-max_same_services') || 5;
@@ -2220,7 +2295,7 @@ active, inactive, suspended, one-time charge, inactive, cancel (or cancelled)
 
 =item pkgpart
 
-list specified how?
+pkgpart or arrayref or hashref of pkgparts
 
 =item setup
 
@@ -2377,17 +2452,35 @@ sub search_sql {
   # parse censustract
   ###
 
-  if ( $params->{'censustract'} =~ /^([.\d]+)$/ and $1 ) {
-    push @where,  "cust_main.censustract = '". $params->{censustract}. "'";
+  if ( exists($params->{'censustract'}) ) {
+    $params->{'censustract'} =~ /^([.\d]*)$/;
+    my $censustract = "cust_main.censustract = '$1'";
+    $censustract .= ' OR cust_main.censustract is NULL' unless $1;
+    push @where,  "( $censustract )";
   }
 
   ###
   # parse part_pkg
   ###
 
-  my $pkgpart = join (' OR pkgpart=',
-                      grep {$_} map { /^(\d+)$/; } ($params->{'pkgpart'}));
-  push @where,  '(pkgpart=' . $pkgpart . ')' if $pkgpart;
+  if ( ref($params->{'pkgpart'}) ) {
+
+    my @pkgpart = ();
+    if ( ref($params->{'pkgpart'}) eq 'HASH' ) {
+      @pkgpart = grep $params->{'pkgpart'}{$_}, keys %{ $params->{'pkgpart'} };
+    } elsif ( ref($params->{'pkgpart'}) eq 'ARRAY' ) {
+      @pkgpart = @{ $params->{'pkgpart'} };
+    } else {
+      die 'unhandled pkgpart ref '. $params->{'pkgpart'};
+    }
+
+    @pkgpart = grep /^(\d+)$/, @pkgpart;
+
+    push @where, 'pkgpart IN ('. join(',', @pkgpart). ')';
+
+  } elsif ( $params->{'pkgpart'} =~ /^(\d+)$/ ) {
+    push @where, "pkgpart = $1";
+  } 
 
   ###
   # parse dates