add northern cyprus, RT#39335
[freeside.git] / FS / FS / Template_Mixin.pm
index e9b60a8..65a8484 100644 (file)
@@ -13,7 +13,6 @@ use Date::Language;
 use Text::Template 1.20;
 use File::Temp 0.14;
 use HTML::Entities;
-use Locale::Country;
 use Cwd;
 use FS::UID;
 use FS::Misc qw( send_email );
@@ -648,7 +647,7 @@ sub print_generic {
   if ( $cust_main->country eq $countrydefault ) {
     $invoice_data{'country'} = '';
   } else {
-    $invoice_data{'country'} = &$escape_function(code2country($cust_main->country));
+    $invoice_data{'country'} = &$escape_function($cust_main->bill_country_full);
   }
 
   my @address = ();
@@ -684,7 +683,12 @@ sub print_generic {
   my( $pr_total, @pr_cust_bill ) = $self->previous; #previous balance
 #  my( $cr_total, @cr_cust_credit ) = $self->cust_credit; #credits
   #my $balance_due = $self->owed + $pr_total - $cr_total;
-  my $balance_due = $self->owed + $pr_total;
+  my $balance_due = $self->owed;
+  if ( $self->enable_previous ) {
+    $balance_due += $pr_total;
+  }
+  # otherwise the previous balance is not shown, so including it in the
+  # balance due is just confusing
 
   # the sum of amount owed on all invoices
   # (this is used in the summary & on the payment coupon)
@@ -707,6 +711,8 @@ 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.
+      #
+      # still do this for the "Previous Balance" line of the summary block
       my @sql =
         map "$_ WHERE _date <= ? AND custnum = ?", (
           "SELECT      COALESCE( SUM(charged), 0 ) FROM cust_bill",
@@ -739,19 +745,31 @@ sub print_generic {
       # longer stored in the database)
       $invoice_data{'true_previous_balance'} = $last_bill_balance;
 
-      # the change in balance from immediately after that invoice
-      # to immediately before this one
-      my $before_this_bill_balance = 0;
+      # Now, get all applications of credits/payments dated on or after the
+      # previous bill, to invoices before the current bill. (The
+      # credit/payment date restriction prevents these from intersecting
+      # the "Previous Balance" set.)
+      # These are "adjustments". The past due balance will be shown as
+      # Previous Balance - Adjustments.
+      my $adjustments = 0;
+      @sql = map {
+        "SELECT COALESCE(SUM(y.amount),0) FROM $_ JOIN cust_bill USING (invnum)
+         WHERE cust_bill._date < ?
+           AND x._date >= ?
+           AND cust_bill.custnum = ?"
+        } "cust_credit AS x JOIN cust_credit_bill y USING (crednum)",
+          "cust_pay    AS x JOIN cust_bill_pay    y USING (paynum)"
+      ;
       foreach (@sql) {
         my $delta = FS::Record->scalar_sql(
           $_,
-          $self->_date - 1,
+          $self->_date,
+          $last_bill->_date,
           $self->custnum,
         );
-        $before_this_bill_balance += $delta;
+        $adjustments += $delta;
       }
-      $invoice_data{'balance_adjustments'} =
-        sprintf("%.2f", $last_bill_balance - $before_this_bill_balance);
+      $invoice_data{'balance_adjustments'} = sprintf("%.2f", $adjustments);
 
       warn sprintf("BALANCE ADJUSTMENTS: %.2f\n\n",
                    $invoice_data{'balance_adjustments'}
@@ -1519,7 +1537,7 @@ sub print_generic {
   # usage subtotals
   if ( $conf->exists('usage_class_summary')
        and $self->can('_items_usage_class_summary') ) {
-    my @usage_subtotals = $self->_items_usage_class_summary(escape => $escape_function);
+    my @usage_subtotals = $self->_items_usage_class_summary(escape => $escape_function, 'money_char' => $other_money_char);
     if ( @usage_subtotals ) {
       unshift @sections, $usage_subtotals[0]->{section}; # do not summarize
       unshift @detail_items, @usage_subtotals;
@@ -2981,9 +2999,6 @@ location (whichever is defined).
 multisection: a flag indicating that this is a multisection invoice,
 which does something complicated.
 
-preref_callback: coderef run for each line item, code should return HTML to be
-displayed before that line item (quotations only)
-
 Returns a list of hashrefs, each of which may contain:
 
 pkgnum, description, amount, unit_amount, quantity, pkgpart, _is_setup, and 
@@ -3045,6 +3060,9 @@ sub _items_cust_bill_pkg {
     # 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.
+    if ( $d ) {
+      $d->{amount} = $d->{setup_amount} + $d->{recur_amount};
+    }
     foreach ( $s, $r, ($opt{skip_usage} ? () : $u ), $d ) {
       if ( $_ && !$cust_bill_pkg->hidden ) {
         $_->{amount}      = sprintf( "%.2f", $_->{amount} );
@@ -3117,51 +3135,7 @@ sub _items_cust_bill_pkg {
                           'no_usage'        => $opt{'no_usage'},
                         );
 
-      if ( ref($cust_bill_pkg) eq 'FS::quotation_pkg' ) {
-        # XXX this should be pulled out into quotation_pkg
-
-        warn "$me _items_cust_bill_pkg cust_bill_pkg is quotation_pkg\n"
-          if $DEBUG > 1;
-        # quotation_pkgs are never fees, so don't worry about the case where
-        # part_pkg is undefined
-
-        # and I guess they're never bundled either?
-        if ( $cust_bill_pkg->setup != 0 ) {
-          my $description = $desc;
-          $description .= ' Setup'
-            if $cust_bill_pkg->recur != 0
-            || $discount_show_always
-            || $cust_bill_pkg->recur_show_zero;
-          #push @b, {
-          # keep it consistent, please
-          $s = {
-            '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),
-            'quantity'    => $cust_bill_pkg->quantity,
-            'preref_html' => ( $opt{preref_callback}
-                                 ? &{ $opt{preref_callback} }( $cust_bill_pkg )
-                                 : ''
-                             ),
-          };
-        }
-        if ( $cust_bill_pkg->recur != 0 ) {
-          #push @b, {
-          $r = {
-            '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),
-            'quantity'    => $cust_bill_pkg->quantity,
-           'preref_html'  => ( $opt{preref_callback}
-                                 ? &{ $opt{preref_callback} }( $cust_bill_pkg )
-                                 : ''
-                             ),
-          };
-        }
-
-      } elsif ( $cust_bill_pkg->pkgnum > 0 ) {
+      if ( $cust_bill_pkg->pkgnum > 0 ) {
         # a "normal" package line item (not a quotation, not a fee, not a tax)
 
         warn "$me _items_cust_bill_pkg cust_bill_pkg is non-tax\n"
@@ -3461,7 +3435,7 @@ sub _items_cust_bill_pkg {
                                            + $cust_bill_pkg->recur)
         };
 
-      } # if quotation / package line item / other line item
+      } # if package line item / other line item
 
       # decide whether to show active discounts here
       if (
@@ -3480,7 +3454,8 @@ sub _items_cust_bill_pkg {
           # $item_discount->{amount} is negative
 
           if ( $d and $cust_bill_pkg->hidden ) {
-            $d->{amount}      += $item_discount->{amount};
+            $d->{setup_amount} += $item_discount->{setup_amount};
+            $d->{recur_amount} += $item_discount->{recur_amount};
           } else {
             $d = $item_discount;
             $_ = &{$escape_function}($_) foreach @{ $d->{ext_description} };
@@ -3488,27 +3463,9 @@ sub _items_cust_bill_pkg {
 
           # update the active line (before the discount) to show the 
           # original price (whether this is a hidden line or not)
-          #
-          # quotation discounts keep track of setup and recur; invoice 
-          # discounts currently don't
-          if ( exists $item_discount->{setup_amount} ) {
-
-            $s->{amount} -= $item_discount->{setup_amount} if $s;
-            $r->{amount} -= $item_discount->{recur_amount} if $r;
-
-          } else {
-
-            # $active_line is 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;
-            }
-            $active_line->{amount} -= $item_discount->{amount};
 
-          }
+          $s->{amount} -= $item_discount->{setup_amount} if $s;
+          $r->{amount} -= $item_discount->{recur_amount} if $r;
 
         } # if there are any discounts
       } # if this is an appropriate place to show discounts
@@ -3517,6 +3474,11 @@ sub _items_cust_bill_pkg {
 
   }
 
+  # discount amount is internally split up
+  if ( $d ) {
+    $d->{amount} = $d->{setup_amount} + $d->{recur_amount};
+  }
+
   foreach ( $s, $r, ($opt{skip_usage} ? () : $u ), $d ) {
     if ( $_  ) {
       $_->{amount}      = sprintf( "%.2f", $_->{amount} ),