correct invoice package address display and reduce false laziness
[freeside.git] / FS / FS / cust_pkg.pm
index e4846ec..fa0fa69 100644 (file)
@@ -1,7 +1,7 @@
 package FS::cust_pkg;
 
 use strict;
-use vars qw(@ISA $disable_agentcheck $DEBUG);
+use vars qw(@ISA $disable_agentcheck $DEBUG $me);
 use Carp qw(cluck);
 use Scalar::Util qw( blessed );
 use List::Util qw(max);
@@ -41,6 +41,7 @@ use FS::Conf;
 @ISA = qw( FS::m2m_Common FS::cust_main_Mixin FS::option_Common FS::Record );
 
 $DEBUG = 0;
+$me = '[FS::cust_pkg]';
 
 $disable_agentcheck = 0;
 
@@ -1207,11 +1208,21 @@ sub change {
   #Good to go, cancel old package.
   $error = $self->cancel( quiet=>1 );
   if ($error) {
-    $dbh->rollback;
+    $dbh->rollback if $oldAutoCommit;
     return $error;
   }
 
+  if ( $conf->exists('cust_pkg-change_pkgpart-bill_now') ) {
+    #$self->cust_main
+    my $error = $cust_pkg->cust_main->bill( 'pkg_list' => [ $cust_pkg ] );
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }
+  }
+
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
   $cust_pkg;
 
 }
@@ -1935,6 +1946,18 @@ sub cust_location_or_main {
   $self->cust_location || $self->cust_main;
 }
 
+=item location_label [ OPTION => VALUE ... ]
+
+Returns the label of the location object (see L<FS::cust_location>).
+
+=cut
+
+sub location_label {
+  my $self = shift;
+  my $object = $self->cust_location_or_main;
+  $object->location_label(@_);
+}
+
 =item seconds_since TIMESTAMP
 
 Returns the number of seconds all accounts (see L<FS::svc_acct>) in this
@@ -2221,6 +2244,7 @@ Returns an SQL expression identifying active packages.
 
 sub active_sql { "
   ". $_[0]->recurring_sql(). "
+  AND cust_pkg.setup IS NOT NULL AND cust_pkg.setup != 0
   AND ( cust_pkg.cancel IS NULL OR cust_pkg.cancel = 0 )
   AND ( cust_pkg.susp   IS NULL OR cust_pkg.susp   = 0 )
 "; }
@@ -2280,7 +2304,7 @@ sub cancel_sql {
   "cust_pkg.cancel IS NOT NULL AND cust_pkg.cancel != 0";
 }
 
-=item search_sql HASHREF
+=item search HASHREF
 
 (Class method)
 
@@ -2353,7 +2377,7 @@ specifies the user for agent virtualization
 
 =cut
 
-sub search_sql { 
+sub search {
   my ($class, $params) = @_;
   my @where = ();
 
@@ -2384,8 +2408,8 @@ sub search_sql {
 
     push @where, FS::cust_pkg->active_sql();
 
-  } elsif (    $params->{'magic'}  eq 'not yet billed'
-            || $params->{'status'} eq 'not yet billed' ) {
+  } elsif (    $params->{'magic'}  =~ /^not[ _]yet[ _]billed$/
+            || $params->{'status'} =~ /^not[ _]yet[ _]billed$/ ) {
 
     push @where, FS::cust_pkg->not_yet_billed_sql();
 
@@ -2419,7 +2443,7 @@ sub search_sql {
   {
     $classnum = $1;
     if ( $classnum ) { #a specific class
-      push @where, "classnum = $classnum";
+      push @where, "part_pkg.classnum = $classnum";
 
       #@pkg_class = ( qsearchs('pkg_class', { 'classnum' => $classnum } ) );
       #die "classnum $classnum not found!" unless $pkg_class[0];
@@ -2427,7 +2451,7 @@ sub search_sql {
 
     } elsif ( $classnum eq '' ) { #the empty class
 
-      push @where, "classnum IS NULL";
+      push @where, "part_pkg.classnum IS NULL";
       #$title .= 'Empty class ';
       #@pkg_class = ( '(empty class)' );
     } elsif ( $classnum eq '0' ) {
@@ -2582,10 +2606,10 @@ sub search_sql {
 
     if ($access_user) {
       push @where, $access_user->agentnums_sql('table'=>'cust_main');
-    }else{
+    } else {
       push @where, "1=0";
     }
-  }else{
+  } else {
     push @where, $FS::CurrentUser::CurrentUser->agentnums_sql('table'=>'cust_main');
   }
 
@@ -2593,7 +2617,7 @@ sub search_sql {
 
   my $addl_from = 'LEFT JOIN cust_main USING ( custnum  ) '.
                   'LEFT JOIN part_pkg  USING ( pkgpart  ) '.
-                  'LEFT JOIN pkg_class USING ( classnum ) ';
+                  'LEFT JOIN pkg_class ON ( part_pkg.classnum = pkg_class.classnum ) ';
 
   my $count_query = "SELECT COUNT(*) FROM cust_pkg $addl_from $extra_sql";
 
@@ -2632,13 +2656,8 @@ sub location_sql {
   my $conf = new FS::Conf;
 
   # '?' placeholders in _location_sql_where
-  my @bill_param;
-  if ( $ornull ) {
-    @bill_param = qw( county county state state state country );
-  } else {
-    @bill_param = qw( county state state country );
-  }
-  unshift @bill_param, 'county'; # unless $nec;
+  my $x = $ornull ? 3 : 2;
+  my @bill_param = ( ('city')x3, ('county')x$x, ('state')x$x, 'country' );
 
   my $main_where;
   my @main_param;
@@ -2697,11 +2716,14 @@ sub _location_sql_where {
 
   $ornull = $ornull ? ' OR ? IS NULL ' : '';
 
+  my $or_empty_city   = " OR ( ? = '' AND $table.${prefix}city   IS NULL ) ";
   my $or_empty_county = " OR ( ? = '' AND $table.${prefix}county IS NULL ) ";
   my $or_empty_state =  " OR ( ? = '' AND $table.${prefix}state  IS NULL ) ";
 
+#        ( $table.${prefix}city    = ? $or_empty_city   $ornull )
   "
-        ( $table.${prefix}county  = ? $or_empty_county $ornull )
+        ( $table.${prefix}city    = ? OR ? = '' OR CAST(? AS text) IS NULL )
+    AND ( $table.${prefix}county  = ? $or_empty_county $ornull )
     AND ( $table.${prefix}state   = ? $or_empty_state  $ornull )
     AND   $table.${prefix}country = ?
   ";
@@ -2757,6 +2779,9 @@ sub order {
 #  my $cust_main = qsearchs('cust_main', { custnum => $custnum });
 #  return "Customer not found: $custnum" unless $cust_main;
 
+  warn "$me order: pkgnums to remove: ". join(',', @$remove_pkgnum). "\n"
+    if $DEBUG;
+
   my @old_cust_pkg = map { qsearchs('cust_pkg', { pkgnum => $_ }) }
                          @$remove_pkgnum;
 
@@ -2765,6 +2790,10 @@ sub order {
   my %hash = (); 
   if ( scalar(@old_cust_pkg) == 1 && scalar(@$pkgparts) == 1 ) {
 
+    warn "$me order: changing pkgnum ". $old_cust_pkg[0]->pkgnum.
+         " to pkgpart ". $pkgparts->[0]. "\n"
+      if $DEBUG;
+
     my $err_or_cust_pkg =
       $old_cust_pkg[0]->change( 'pkgpart' => $pkgparts->[0],
                                 'refnum'  => $refnum,
@@ -2776,12 +2805,16 @@ sub order {
     }
 
     push @$return_cust_pkg, $err_or_cust_pkg;
+    $dbh->commit or die $dbh->errstr if $oldAutoCommit;
     return '';
 
   }
 
   # Create the new packages.
   foreach my $pkgpart (@$pkgparts) {
+
+    warn "$me order: inserting pkgpart $pkgpart\n" if $DEBUG;
+
     my $cust_pkg = new FS::cust_pkg { custnum => $custnum,
                                       pkgpart => $pkgpart,
                                       refnum  => $refnum,
@@ -2800,6 +2833,9 @@ sub order {
   # Transfer services and cancel old packages.
   foreach my $old_pkg (@old_cust_pkg) {
 
+    warn "$me order: transferring services from pkgnum ". $old_pkg->pkgnum. "\n"
+      if $DEBUG;
+
     foreach my $new_pkg (@$return_cust_pkg) {
       $error = $old_pkg->transfer($new_pkg);
       if ($error and $error == 0) {