invoice past due event, RT#9931
[freeside.git] / FS / FS / cust_bill.pm
index 56099cc..bb392e8 100644 (file)
@@ -2386,7 +2386,8 @@ sub print_generic {
       qsearchs('pkg_class', { classnum => $conf->config('finance_pkgclass') });
     $invoice_data{finance_section} = $pkg_class->categoryname;
   } 
- $invoice_data{finance_amount} = '0.00';
+  $invoice_data{finance_amount} = '0.00';
+  $invoice_data{finance_section} ||= 'Finance Charges'; #avoid config confusion
 
   my $countrydefault = $conf->config('countrydefault') || 'US';
   my $prefix = $cust_main->has_ship_address ? 'ship_' : '';
@@ -2657,6 +2658,7 @@ sub print_generic {
     $options{'skip_usage'} =
       scalar(@$extra_sections) && !grep{$section == $_} @$extra_sections;
     $options{'multilocation'} = $multilocation;
+    $options{'multisection'} = $multisection;
 
     foreach my $line_item ( $self->_items_pkg(%options) ) {
       my $detail = {
@@ -3039,6 +3041,7 @@ sub print_ps {
 
   my ($file, $lfile) = $self->print_latex(@_);
   my $ps = generate_ps($file);
+  unlink($file.'.tex');
   unlink($lfile);
 
   $ps;
@@ -3067,6 +3070,7 @@ sub print_pdf {
 
   my ($file, $lfile) = $self->print_latex(@_);
   my $pdf = generate_pdf($file);
+  unlink($file.'.tex');
   unlink($lfile);
 
   $pdf;
@@ -3356,6 +3360,7 @@ sub _items_sections {
   if ( $summarypage ) {
     @sections = grep { exists($subtotal{$_}) || ! _pkg_category($_)->disabled }
                 map { $_->categoryname } qsearch('pkg_category', {});
+    push @sections, '' if exists($subtotal{''});
   } else {
     @sections = keys %subtotal;
   }
@@ -3397,7 +3402,9 @@ my %condensed_format = (
   'fields' => [
                 sub { shift->{description} },
                 sub { shift->{quantity} },
-                sub { shift->{amount} },
+                sub { my($href, %opt) = @_;
+                      ($opt{dollar} || ''). $href->{amount};
+                    },
               ],
   'align'  => [ qw( l r r ) ],
   'span'   => [ qw( 5 1 1 ) ],            # unitprices?
@@ -3471,6 +3478,7 @@ sub _condensed_description_generator {
   my ( $f, $prefix, $suffix, $separator, $column ) =
     _condensed_generator_defaults($format);
 
+  my $money_char = '$';
   if ($format eq 'latex') {
     $prefix = "\\hline\n\\multicolumn{1}{c}{\\rule{0pt}{2.5ex}~} &\n";
     $suffix = '\\\\';
@@ -3479,6 +3487,7 @@ sub _condensed_description_generator {
       sub { my ($d,$a,$s,$w) = @_;
             return "\\multicolumn{$s}{$a}{\\makebox[$w][$a]{\\textbf{$d}}}";
           };
+    $money_char = '\\dollar';
   }elsif ( $format eq 'html' ) {
     $prefix = '"><td align="center"></td>';
     $suffix = '';
@@ -3487,16 +3496,22 @@ sub _condensed_description_generator {
       sub { my ($d,$a,$s,$w) = @_;
             return qq!<td align="$html_align{$a}">$d</td>!;
       };
+    #$money_char = $conf->config('money_char') || '$';
+    $money_char = '';  # this is madness
   }
 
   sub {
-    my @args = @_;
+    #my @args = @_;
+    my $href = shift;
     my @result = ();
 
     foreach  (my $i = 0; $f->{label}->[$i]; $i++) {
-      push @result, &{$column}( &{$f->{fields}->[$i]}(@args),
-                                map { $f->{$_}->[$i] } qw(align span width)
-                              );
+      my $dollar = '';
+      $dollar = $money_char if $i == scalar(@{$f->{label}})-1;
+      push @result,
+        &{$column}( &{$f->{fields}->[$i]}($href, 'dollar' => $dollar),
+                    map { $f->{$_}->[$i] } qw(align span width)
+                  );
     }
 
     $prefix. join( $separator, @result ). $suffix;
@@ -3737,6 +3752,7 @@ sub _items_svc_phone_sections {
   my %lines = ();
 
   my %usage_class =  map { $_->classnum => $_ } qsearch( 'usage_class', {} );
+  $usage_class{''} ||= new FS::usage_class { 'classname' => '', 'weight' => 0 };
 
   foreach my $cust_bill_pkg ( $self->cust_bill_pkg ) {
     next unless $cust_bill_pkg->pkgnum > 0;
@@ -3979,6 +3995,7 @@ sub _items_cust_bill_pkg {
   my $section = $opt{section}->{description} if $opt{section};
   my $summary_page = $opt{summary_page} || '';
   my $multilocation = $opt{multilocation} || '';
+  my $multisection = $opt{multisection} || '';
 
   my @b = ();
   my ($s, $r, $u) = ( undef, undef, undef );
@@ -4000,7 +4017,8 @@ sub _items_cust_bill_pkg {
                                  ? $_->section eq $section
                                  : 1
                                }
-                          grep { !$_->summary || !$summary_page }
+                          #grep { !$_->summary || !$summary_page } # bunk!
+                          grep { !$_->summary || $multisection }
                           $cust_bill_pkg->cust_bill_pkg_display
                         )
     {
@@ -4059,7 +4077,7 @@ sub _items_cust_bill_pkg {
 
         }
 
-        if ( $cust_bill_pkg->recur != 0 &&
+        if ( ( $cust_bill_pkg->recur != 0  || $cust_bill_pkg->setup == 0 ) &&
              ( !$type || $type eq 'R' || $type eq 'U' )
            )
         {
@@ -4129,7 +4147,7 @@ sub _items_cust_bill_pkg {
               };
             }
 
-          } elsif ( $amount ) {  # && $type eq 'U'
+          } else {  # $type eq 'U'
 
             if ( $cust_bill_pkg->hidden ) {
               $u->{amount}      += $amount;
@@ -4444,6 +4462,25 @@ sub credited_sql {
        WHERE cust_bill.invnum = cust_credit_bill.invnum $start $end  )";
 }
 
+=item due_date_sql
+
+Returns an SQL fragment to retrieve the due date of an invoice.
+Currently only supported on PostgreSQL.
+
+=cut
+
+sub due_date_sql {
+'COALESCE(
+  SUBSTRING(
+    COALESCE(
+      cust_bill.invoice_terms,
+      cust_main.invoice_terms,
+      \''.($conf->config('invoice_default_terms') || '').'\'
+    ), E\'Net (\\\\d+)\'
+  )::INTEGER, 0
+) * 86400 + cust_bill._date'
+}
+
 =item search_sql_where HASHREF
 
 Class method which returns an SQL WHERE fragment to search for parameters