Merge branch 'master' of git.freeside.biz:/home/git/freeside
authorIvan Kohler <ivan@freeside.biz>
Tue, 10 Mar 2015 18:51:18 +0000 (11:51 -0700)
committerIvan Kohler <ivan@freeside.biz>
Tue, 10 Mar 2015 18:51:18 +0000 (11:51 -0700)
FS/FS/Schema.pm
FS/FS/Template_Mixin.pm
FS/FS/cust_bill_pkg_tax_location_void.pm
FS/FS/cust_main.pm
FS/FS/part_event/Action/Mixin/credit_bill.pm
FS/FS/part_event/Action/bill_sales_credit.pm
FS/FS/part_export/voip_ms.pm
httemplate/search/cust_bill_pkg.cgi

index e7b3b6f..378a521 100644 (file)
@@ -1283,9 +1283,6 @@ sub tables_hashref {
                           { columns    => [ 'billpkgnum' ],
                             table      => 'cust_bill_pkg_void',
                           },
-                          { columns    => [ 'pkgnum' ],
-                            table      => 'cust_pkg',
-                          },
                           { columns    => [ 'locationnum' ],
                             table      => 'cust_location',
                           },
index 17863a1..fce1a3f 100644 (file)
@@ -3012,7 +3012,22 @@ sub _items_cust_bill_pkg {
   my $maxlength = $conf->config('cust_bill-latex_lineitem_maxlength') || 50;
 
   my $cust_main = $self->cust_main;#for per-agent cust_bill-line_item-ate_style
-                                   # and location labels
+
+  # for location labels: use default location on the invoice date
+  my $default_locationnum;
+  if ( $self->custnum ) {
+    my $h_cust_main;
+    my @h_search = FS::h_cust_main->sql_h_search($self->_date);
+    $h_cust_main = qsearchs({
+        'table'     => 'h_cust_main',
+        'hashref'   => { custnum => $self->custnum },
+        'extra_sql' => $h_search[1],
+        'addl_from' => $h_search[3],
+    }) || $cust_main;
+    $default_locationnum = $h_cust_main->ship_locationnum;
+  } elsif ( $self->prospectnum ) {
+    $default_locationnum = $self->prospect_main->cust_location->locationnum;
+  }
 
   my @b = (); # accumulator for the line item hashes that we'll return
   my ($s, $r, $u, $d) = ( undef, undef, undef, undef );
@@ -3197,11 +3212,10 @@ sub _items_cust_bill_pkg {
 
             push @d, @svc_labels
               unless $cust_bill_pkg->pkgpart_override; #don't redisplay services
-            my $lnum = $cust_main ? $cust_main->ship_locationnum
-                                  : $self->prospect_main->locationnum;
             # show the location label if it's not the customer's default
             # location, and we're not grouping items by location already
-            if ( $cust_pkg->locationnum != $lnum and !defined($locationnum) ) {
+            if ( $cust_pkg->locationnum != $default_locationnum
+                  and !defined($locationnum) ) {
               my $loc = $cust_pkg->location_label;
               $loc = substr($loc, 0, $maxlength). '...'
                 if $format eq 'latex' && length($loc) > $maxlength;
@@ -3299,11 +3313,10 @@ sub _items_cust_bill_pkg {
             warn "$me _items_cust_bill_pkg done adding service details\n"
               if $DEBUG > 1;
 
-            my $lnum = $cust_main ? $cust_main->ship_locationnum
-                                  : $self->prospect_main->locationnum;
             # show the location label if it's not the customer's default
             # location, and we're not grouping items by location already
-            if ( $cust_pkg->locationnum != $lnum and !defined($locationnum) ) {
+            if ( $cust_pkg->locationnum != $default_locationnum
+                  and !defined($locationnum) ) {
               my $loc = $cust_pkg->location_label;
               $loc = substr($loc, 0, $maxlength). '...'
                 if $format eq 'latex' && length($loc) > $maxlength;
index a683227..7b79e6f 100644 (file)
@@ -116,7 +116,7 @@ sub check {
     || $self->ut_foreign_key('billpkgnum', 'cust_bill_pkg_void', 'billpkgnum' )
     || $self->ut_number('taxnum') #cust_bill_pkg/tax_rate key, based on taxtype
     || $self->ut_enum('taxtype', [ qw( FS::cust_main_county FS::tax_rate ) ] )
-    || $self->ut_foreign_key('pkgnum', 'cust_pkg', 'pkgnum' )
+    || $self->ut_number('pkgnum', 'cust_pkg', 'pkgnum' )
     || $self->ut_foreign_key('locationnum', 'cust_location', 'locationnum' )
     || $self->ut_money('amount')
     || $self->ut_foreign_key('taxable_billpkgnum', 'cust_bill_pkg_void', 'billpkgnum')
index 427112a..74433d7 100644 (file)
@@ -464,8 +464,6 @@ sub insert {
     }
   }
 
-  $self->_loc_change();
-
   warn "  inserting $self\n"
     if $DEBUG > 1;
 
@@ -1338,8 +1336,6 @@ sub replace {
     $self->set($l.'num', $new_loc->locationnum);
   } #for $l
 
-  $self->_loc_change($old);
-
   # replace the customer record
   my $error = $self->SUPER::replace($old);
 
@@ -1642,6 +1638,11 @@ sub check {
     $self->ss("$1-$2-$3");
   }
 
+  #turn off invoice_ship_address if ship & bill are the same
+  if ($self->bill_locationnum eq $self->ship_locationnum) {
+    $self->invoice_ship_address('');
+  }
+
   # cust_main_county verification now handled by cust_location check
 
   $error =
@@ -1922,6 +1923,21 @@ sub check {
   $self->SUPER::check;
 }
 
+=item replace_check
+
+Additional checks for replace only.
+
+=cut
+
+sub replace_check {
+  my ($new,$old) = @_;
+  #preserve old value if global config is set
+  if ($old && $conf->exists('invoice-ship_address')) {
+    $new->invoice_ship_address($old->invoice_ship_address);
+  }
+  return '';
+}
+
 =item addr_fields 
 
 Returns a list of fields which have ship_ duplicates.
@@ -4782,22 +4798,6 @@ sub process_bill_and_collect {
   $cust_main->bill_and_collect( %$param );
 }
 
-#hook for insert/replace
-#runs after locations have been set
-#but before custnum has been set (for insert)
-sub _loc_change {
-  my $self = shift;
-  my $old = shift;
-  #turn off invoice_ship_address if ship & bill are the same
-  if ($self->bill_locationnum eq $self->ship_locationnum) {
-    $self->invoice_ship_address('');
-  }
-  #preserve old value if global config is set (replace only)
-  elsif ($old && $conf->exists('invoice-ship_address')) {
-    $self->invoice_ship_address($old->invoice_ship_address);
-  }
-}
-
 #starting to take quite a while for big dbs
 #   (JRNL: journaled so it only happens once per database)
 # - seq scan of h_cust_main (yuck), but not going to index paycvv, so
index 82b215d..694f965 100644 (file)
@@ -54,6 +54,9 @@ our %part_pkg_cache;
 sub _calc_credit {
   my $self = shift;
   my $cust_bill_pkg = shift;
+  my $who = shift;
+  my $warnref = shift;
+  my $warning = '';
 
   my $what = $self->option('what');
   my $cost = ($what =~ /_cost/ ? 1 : 0);
@@ -64,9 +67,11 @@ sub _calc_credit {
 
   my $percent;
   if ( $self->can('_calc_credit_percent') ) {
-    $percent = $self->_calc_credit_percent($cust_pkg, @_);
+    $percent = $self->_calc_credit_percent($cust_pkg, $who);
+    $warning = 'Percent calculated to zero ' unless $percent+0;
   } else {
     $percent = $self->option('percent') || 0;
+    $warning = 'Percent set to zero ' unless $percent+0;
   }
 
   my $charge = 0;
@@ -83,20 +88,26 @@ sub _calc_credit {
     }
 
     $charge = ($charge || 0) * ($cust_pkg->quantity || 1);
+    $warning .= 'Charge calculated to zero ' unless $charge+0;
 
   } else { # setup, recur, or setuprecur
 
     if ( $what eq 'setup' ) {
       $charge = $cust_bill_pkg->get('setup');
+      $warning .= 'Setup is zero ' unless $charge+0;
     } elsif ( $what eq 'recur' ) {
       $charge = $cust_bill_pkg->get('recur');
+      $warning .= 'Recur is zero ' unless $charge+0;
     } elsif ( $what eq 'setuprecur' ) {
       $charge = $cust_bill_pkg->get('setup') + $cust_bill_pkg->get('recur');
+      $warning .= 'Setup and recur are zero ' unless $charge+0;
     }
 
     # don't multiply by quantity here; it's already included
   }
 
+  $$warnref .= $warning if ref($warnref);
+
   $charge = 0 if $charge < 0; # e.g. prorate
   return ($percent * $charge / 100);
 }
index 3193a81..ab69375 100644 (file)
@@ -38,6 +38,7 @@ sub do_action {
                                          pkgnum => { op => '>', value => '0' }
                                        });
 
+  my $warning = '';
   foreach my $cust_bill_pkg (@items) {
     my $pkgnum = $cust_bill_pkg->pkgnum;
     my $cust_pkg = $pkgnum_pkg{$pkgnum} ||= $cust_bill_pkg->cust_pkg;
@@ -50,7 +51,7 @@ sub do_action {
 
     next if !$sales; #no sales person, no credit
 
-    my $amount = $self->_calc_credit($cust_bill_pkg, $sales);
+    my $amount = $self->_calc_credit($cust_bill_pkg, $sales, \$warning);
 
     if ($amount > 0) {
       $salesnum_amount{$salesnum} ||= 0;
@@ -86,6 +87,8 @@ sub do_action {
       if $error;
   } # foreach $salesnum
 
+  return $warning;
+
 }
 
 1;
index 7766eac..a23345c 100644 (file)
@@ -408,6 +408,7 @@ sub subacct_content {
   }
   return {
     username            => $svc_acct->username,
+    protocol            => $self->option('protocol'),
     description         => $desc,
     %auth,
     device_type         => $self->option('device_type'),
index fa6dabc..91fe4e0 100644 (file)
@@ -106,11 +106,7 @@ Output control parameters:
   range of the report.  Line items will be limited to those for which this 
   portion is > 0.  This disables filtering on invoice date.
 
-- usage: Separate usage (cust_bill_pkg_detail records) from
-  recurring charges.  If set to "usage", will show usage instead of 
-  recurring charges.  If set to "recurring", will deduct usage and only
-  show the flat rate charge.  If not passed, the "recurring charge" column
-  will include usage charges also.
+- charges: 'S'etup, 'R'ecur, 'U'sage, or any string combination of those.
 
 Filtering parameters:
 - begin, end: Date range.  Applies to invoice date, not necessarily package
@@ -201,7 +197,7 @@ my @total = ( 'COUNT(*)', 'SUM(cust_bill_pkg.setup + cust_bill_pkg.recur)');
 my @total_desc = ( $money_char.'%.2f total' ); # sprintf strings
 
 my @peritem = ( 'setup', 'recur' );
-my @peritem_desc = ( 'Setup charge', 'Recurring charge' );
+my @peritem_desc = ( 'Setup charges', 'Recurring charges' );
 
 my @currency_desc = ();
 my @currency_sub = ();
@@ -517,16 +513,32 @@ if ( $cgi->param('nottax') ) {
 
   } # handle all joins to cust_main_county
 
-  # recur/usage separation
-  if ( $cgi->param('usage') eq 'recurring' ) {
+  # setup/recur/usage separation
+  my %charges = map { $_ => 1 } split('', $cgi->param('charges') || 'SRU');
 
-    my $recur_no_usage = FS::cust_bill_pkg->charged_sql('', '', no_usage => 1);
+  if ( $charges{R} and $charges{U} ) {
+
+    # default, don't change @peritem or @total
+    if ( !$charges{S} ) {
+      push @where, 'cust_bill_pkg.recur > 0';
+      $total[1] = "SUM(cust_bill_pkg.recur)";
+      $total_desc[0] = "$money_char%.2f recurring";
+    }
+
+  } elsif ( $charges{R} and !$charges{U} ) {
+
+    my $recur_no_usage = FS::cust_bill_pkg->charged_sql('', '', 
+      setuprecur => 'recur', no_usage => 1);
     push @select, "($recur_no_usage) AS recur_no_usage";
     $peritem[1] = 'recur_no_usage';
-    $total[1] = "SUM(cust_bill_pkg.setup + $recur_no_usage)";
-    $total_desc[0] .= ' (excluding usage)';
+    $peritem_desc[1] = 'Recurring charges (excluding usage)';
+    $total[1] = "SUM($recur_no_usage)";
+    $total_desc[0] = "$money_char%.2f recurring";
+    if ( !$charges{S} ) {
+      push @where, "($recur_no_usage) > 0";
+    }
 
-  } elsif ( $cgi->param('usage') eq 'usage' ) {
+  } elsif ( !$charges{R} and $charges{U} ) {
 
     my $usage = FS::cust_bill_pkg->usage_sql();
     push @select, "($usage) AS _usage";
@@ -534,8 +546,18 @@ if ( $cgi->param('nottax') ) {
     $peritem[1] = '_usage';
     $peritem_desc[1] = 'Usage charge';
     $total[1] = "SUM($usage)";
-    $total_desc[0] .= ' usage charges';
-  }
+    $total_desc[0] = "$money_char%.2f usage charges";
+    if ( !$charges{S} ) {
+      push @where, "($usage) > 0";
+    }
+
+  } elsif ( $charges{S} ) {
+
+    push @where, "cust_bill_pkg.setup > 0";
+    $total[1] = "SUM(cust_bill_pkg.setup)";
+    $total_desc[0] = "$money_char%.2f setup";
+
+  } # else huh? you have to have SOME charges
 
 } elsif ( $cgi->param('istax') ) {