show discounts on invoices as negative line items, #31273
[freeside.git] / FS / FS / Template_Mixin.pm
index 2fae464..ebc977a 100644 (file)
@@ -346,8 +346,8 @@ sub print_generic {
 
   if ( $format eq 'latex' && grep { /^%%Detail/ } @invoice_template ) {
     #change this to a die when the old code is removed
-    # it's been almost ten years, changing it to a die.
-    die "old-style invoice template $templatefile; ".
+    # it's been almost ten years, changing it to a die on the next release.
+    warn "old-style invoice template $templatefile; ".
          "patch with conf/invoice_latex.diff or use new conf/invoice_latex*\n";
          #$old_latex = 'true';
          #@invoice_template = _translate_old_latex_format(@invoice_template);
@@ -702,25 +702,24 @@ sub print_generic {
       # "balance_date_range" unfortunately is unsuitable for this, since it
       # cares about application dates.  We want to know the sum of all 
       # _top-level transactions_ dated before the last invoice.
-      my @sql = (
-        'SELECT SUM(charged) FROM cust_bill WHERE _date <= ? AND custnum = ?',
-        'SELECT -1*SUM(amount) FROM cust_credit WHERE _date <= ? AND custnum = ?',
-        'SELECT -1*SUM(paid) FROM cust_pay  WHERE _date <= ? AND custnum = ?',
-        'SELECT SUM(refund) FROM cust_refund WHERE _date <= ? AND custnum = ?',
-      );
+      my @sql =
+        map "$_ WHERE _date <= ? AND custnum = ?", (
+          "SELECT      COALESCE( SUM(charged), 0 ) FROM cust_bill",
+          "SELECT -1 * COALESCE( SUM(amount),  0 ) FROM cust_credit",
+          "SELECT -1 * COALESCE( SUM(paid),    0 ) FROM cust_pay",
+          "SELECT      COALESCE( SUM(refund),  0 ) FROM cust_refund",
+        );
 
       # the customer's current balance immediately after generating the last 
       # bill
 
       my $last_bill_balance = $last_bill->charged;
       foreach (@sql) {
-        #warn "$_\n";
         my $delta = FS::Record->scalar_sql(
           $_,
           $last_bill->_date - 1,
           $self->custnum,
         );
-        #warn "$delta\n";
         $last_bill_balance += $delta;
       }
 
@@ -739,13 +738,11 @@ sub print_generic {
       # to immediately before this one
       my $before_this_bill_balance = 0;
       foreach (@sql) {
-        #warn "$_\n";
         my $delta = FS::Record->scalar_sql(
           $_,
           $self->_date - 1,
           $self->custnum,
         );
-        #warn "$delta\n";
         $before_this_bill_balance += $delta;
       }
       $invoice_data{'balance_adjustments'} =
@@ -1859,8 +1856,15 @@ sub terms {
   my $cust_main = $self->cust_main;
   return $cust_main->invoice_terms if $cust_main && $cust_main->invoice_terms;
 
+  my $agentnum = '';
+  if ( $cust_main ) {
+    $agentnum = $cust_main->agentnum;
+  } elsif ( my $prospect_main = $self->prospect_main ) {
+    $agentnum = $prospect_main->agentnum;
+  }
+
   #use configured default
-  $conf->config('invoice_default_terms') || '';
+  $conf->config('invoice_default_terms', $agentnum) || '';
 }
 
 sub due_date {
@@ -1894,8 +1898,8 @@ sub balance_due_date {
   my $self = shift;
   my $conf = $self->conf;
   my $duedate = '';
-  if (    $conf->exists('invoice_default_terms') 
-       && $conf->config('invoice_default_terms')=~ /^\s*Net\s*(\d+)\s*$/ ) {
+  my $terms = $self->terms;
+  if ( $terms =~ /^\s*Net\s*(\d+)\s*$/ ) {
     $duedate = $self->time2str_local('rdate', $self->_date + ($1*86400) );
   }
   $duedate;
@@ -2153,9 +2157,9 @@ sub _items_sections {
         } else {
           $section->{'category'} = $sectionname;
           $section->{'description'} = &{ $escape }($sectionname);
-          if ( _pkg_category($_) ) {
-            $section->{'sort_weight'} = _pkg_category($_)->weight;
-            if ( _pkg_category($_)->condense ) {
+          if ( _pkg_category($sectionname) ) {
+            $section->{'sort_weight'} = _pkg_category($sectionname)->weight;
+            if ( _pkg_category($sectionname)->condense ) {
               $section = { %$section, $self->_condense_section($opt{format}) };
             }
           }
@@ -2634,14 +2638,14 @@ sub _items_cust_bill_pkg {
                                    # and location labels
 
   my @b = (); # accumulator for the line item hashes that we'll return
-  my ($s, $r, $u, $d) = ( undef, undef, undef );
+  my ($s, $r, $u, $d) = ( undef, undef, undef, undef );
             # the 'current' line item hashes for setup, recur, usage, discount
   foreach my $cust_bill_pkg ( @$cust_bill_pkgs )
   {
     # if the current line item is waiting to go out, and the one we're about
     # to start is not bundled, then push out the current one and start a new
     # one.
-    foreach ( $s, $r, ($opt{skip_usage} ? () : $u ) , $d ) {
+    foreach ( $s, $r, ($opt{skip_usage} ? () : $u ), $d ) {
       if ( $_ && !$cust_bill_pkg->hidden ) {
         $_->{amount}      = sprintf( "%.2f", $_->{amount} );
         $_->{amount}      =~ s/^\-0\.00$/0.00/;
@@ -2729,7 +2733,7 @@ sub _items_cust_bill_pkg {
             'pkgnum'      => $cust_bill_pkg->pkgpart, #so it displays in Ref
             'description' => $description,
             'amount'      => sprintf("%.2f", $cust_bill_pkg->setup),
-            'unit_amount'   => sprintf("%.2f", $cust_bill_pkg->unitsetup),
+            'unit_amount' => sprintf("%.2f", $cust_bill_pkg->unitsetup),
             'quantity'    => $cust_bill_pkg->quantity,
             'preref_html' => ( $opt{preref_callback}
                                  ? &{ $opt{preref_callback} }( $cust_bill_pkg )
@@ -2742,9 +2746,9 @@ sub _items_cust_bill_pkg {
             'pkgnum'      => $cust_bill_pkg->pkgpart, #so it displays in Ref
             'description' => "$desc (". $cust_bill_pkg->part_pkg->freq_pretty.")",
             'amount'      => sprintf("%.2f", $cust_bill_pkg->recur),
-            'unit_amount'   => sprintf("%.2f", $cust_bill_pkg->unitrecur),
+            'unit_amount' => sprintf("%.2f", $cust_bill_pkg->unitrecur),
             'quantity'    => $cust_bill_pkg->quantity,
-           'preref_html' => ( $opt{preref_callback}
+           'preref_html'  => ( $opt{preref_callback}
                                  ? &{ $opt{preref_callback} }( $cust_bill_pkg )
                                  : ''
                              ),
@@ -3043,6 +3047,15 @@ sub _items_cust_bill_pkg {
             or ( $type eq 'R' and $cust_bill_pkg->unitrecur > 0 )
         ) {
 
+          # the line item hashref for the line that will show the original
+          # price
+          # (use the recur or single line for the package, unless we're 
+          # showing a setup line for a package with no recurring fee)
+          my $active_line = $r;
+          if ( $type eq 'S' ) {
+            $active_line = $s;
+          }
+
           my @discounts = $cust_bill_pkg->cust_bill_pkg_discount;
           # special case: if there are old "discount details" on this line 
           # item, don't show discount line items
@@ -3057,23 +3070,18 @@ sub _items_cust_bill_pkg {
               $cust_bill_pkg->billpkgnum."\n"
               if $DEBUG;
             my $discount_amount = sum( map {$_->amount} @discounts );
-            my $orig_amount = $cust_bill_pkg->setup + $cust_bill_pkg->recur
-                              + $discount_amount;
             # if multiple discounts apply to the same package, how to display
             # them? ext_description lines, apparently
+            #
+            # # discount amounts are negative
             if ( $d and $cust_bill_pkg->hidden ) {
-              $d->{amount}      += $discount_amount;
-              $d->{orig_amount} += $orig_amount;
+              $d->{amount}      -= $discount_amount;
             } else {
               my @ext;
-              # make a placeholder for the original price, if necessary
-              # (if unit prices are enabled, it won't be necessary)
-              push @ext, '' if !$conf->exists('invoice-unitprice');
               $d = {
                 _is_discount    => 1,
-                description     => $self->mt('Discount included'),
-                amount          => $discount_amount,
-                orig_amount     => $orig_amount,
+                description     => $self->mt('Discount'),
+                amount          => -1 * $discount_amount,
                 ext_description => \@ext,
               };
               foreach my $cust_bill_pkg_discount (@discounts) {
@@ -3082,12 +3090,10 @@ sub _items_cust_bill_pkg {
               }
             }
 
-            # update the placeholder to show the original price in the 
-            # first ext_description line
-            if ( !$conf->exists('invoice-unitprice') ) {
-              $d->{ext_description}->[0] =
-                sprintf('Original price: %.2f', $d->{orig_amount});
-            }
+            # update the active line (before the discount) to show the 
+            # original price (whether this is a hidden line or not)
+            $active_line->{amount} += $discount_amount;
+            
           } # if there are any discounts
         } # if this is an appropriate place to show discounts
 
@@ -3112,7 +3118,7 @@ sub _items_cust_bill_pkg {
 
   }
 
-  foreach ( $s, $r, ($opt{skip_usage} ? () : $u, $d ) ) {
+  foreach ( $s, $r, ($opt{skip_usage} ? () : $u ), $d ) {
     if ( $_  ) {
       $_->{amount}      = sprintf( "%.2f", $_->{amount} ),
         if exists($_->{amount});