stray closing /TABLE in the no-ticket case
[freeside.git] / FS / FS / part_fee.pm
index 186fb34..1d4682c 100644 (file)
@@ -2,10 +2,11 @@ package FS::part_fee;
 
 use strict;
 use base qw( FS::o2m_Common FS::Record );
-use vars qw( $DEBUG );
 use FS::Record qw( qsearch qsearchs );
+use FS::cust_bill_pkg_display;
 
-$DEBUG = 0;
+our $DEBUG = 0;
+our $default_class;
 
 =head1 NAME
 
@@ -49,6 +50,9 @@ the invoice
 =item disabled - 'Y' if the fee is disabled
 
 =item classnum - the L<FS::pkg_class> that the fee belongs to, for reporting
+and placement on multisection invoices. Unlike packages, fees I<must> be 
+assigned to a class; they will default to class named "Fees", which belongs 
+to the same invoice section that normally contains taxes.
 
 =item taxable - 'Y' if this fee should be considered a taxable sale.  
 Currently, taxable fees will be treated like they exist at the customer's
@@ -129,6 +133,13 @@ sub check {
   $self->set('amount', 0) unless $self->amount;
   $self->set('percent', 0) unless $self->percent;
 
+  $default_class ||= qsearchs('pkg_class', { classname => 'Fees' })
+    or die "default package fee class not found; run freeside-upgrade to continue.\n";
+
+  if (!$self->get('classnum')) {
+    $self->set('classnum', $default_class->classnum);
+  }
+
   my $error = 
     $self->ut_numbern('feepart')
     || $self->ut_textn('comment')
@@ -265,6 +276,8 @@ sub lineitem {
                 ' FROM cust_bill_pkg WHERE billpkgnum = ?';
       @item_base = map { FS::Record->scalar_sql($sql, $_->billpkgnum) }
                     @items;
+
+      $amount += $total_base * $self->percent / 100;
     }
   } else {
     # the fee applies to _this_ invoice.  It has no payments or credits, so
@@ -275,6 +288,8 @@ sub lineitem {
       $total_base = $cust_bill->charged;
       @item_base = map { $_->setup + $_->recur }
                     @items;
+
+      $amount += $total_base * $self->percent / 100;
     }
   }
 
@@ -371,15 +386,24 @@ sub lineitem {
   # set the amount that we'll charge
   $cust_bill_pkg->set( $self->setuprecur, $amount );
 
+  # create display record
+  my $categoryname = '';
   if ( $self->classnum ) {
     my $pkg_category = $self->pkg_class->pkg_category;
-    $cust_bill_pkg->set('section' => $pkg_category->categoryname)
-      if $pkg_category;
+    $categoryname = $pkg_category->categoryname if $pkg_category;
   }
+  my $displaytype = ($self->setuprecur eq 'setup') ? 'S' : 'R';
+  my $display = FS::cust_bill_pkg_display->new({
+      type    => $displaytype,
+      section => $categoryname,
+      # post_total? summary? who the hell knows?
+  });
+  $cust_bill_pkg->set('display', [ $display ]);
 
   # if this is a percentage fee and has line item fractions,
   # adjust them to be proportional and to add up correctly.
-  if ( @item_base ) {
+  # don't try this if we're charging on a zero-amount set of line items.
+  if ( scalar(@item_base) > 0 and $total_base > 0 ) {
     my $cents = $amount * 100;
     # not necessarily the same as percent
     my $multiplier = $amount / $total_base;
@@ -480,6 +504,19 @@ sub tax_rates {
   return @taxes;
 }
 
+=item categoryname 
+
+Returns the package category name, or the empty string if there is no package
+category.
+
+=cut
+
+sub categoryname {
+  my $self = shift;
+  my $pkg_class = $self->pkg_class;
+  $pkg_class ? $pkg_class->categoryname : '';
+}
+
 sub part_pkg_taxoverride {} # we don't do overrides here
 
 sub has_taxproduct {
@@ -487,6 +524,11 @@ sub has_taxproduct {
   return ($self->taxproductnum ? 1 : 0);
 }
 
+sub taxproduct { # compat w/ part_pkg
+  my $self = shift;
+  $self->part_pkg_taxproduct;
+}
+
 =back
 
 =head1 BUGS