new tax rating engine
[freeside.git] / FS / FS / cust_bill.pm
index ee95be8..f536c97 100644 (file)
@@ -1635,7 +1635,7 @@ sub print_generic {
   $templatefile .= "_$template"
     if length($template);
   my @invoice_template = map "$_\n", $conf->config($templatefile)
-    or die "cannot load config file $templatefile";
+    or die "cannot load config data $templatefile";
 
   my $old_latex = '';
   if ( $format eq 'latex' && grep { /^%%Detail/ } @invoice_template ) {
@@ -1653,7 +1653,7 @@ sub print_generic {
   );
 
   $text_template->compile()
-    or die 'While compiling ' . $templatefile . ': ' . $Text::Template::ERROR;
+    or die "Can't compile $templatefile: $Text::Template::ERROR\n";
 
 
   # additional substitution could possibly cause breakage in existing templates
@@ -1674,8 +1674,10 @@ sub print_generic {
                        s/\\item /  <li>/g;
                        s/\\end\{enumerate\}/<\/ol>/g;
                        s/\\textbf\{(.*)\}/<b>$1<\/b>/g;
-                       s/\\\\\*/ /;
+                       s/\\\\\*/<br>/g;
                        s/\\dollar ?/\$/g;
+                       s/\\#/#/g;
+                       s/~/&nbsp;/g;
                        $_;
                      }  @_
                    },
@@ -1861,33 +1863,38 @@ sub print_generic {
   #do variable substitution in notes, footer, smallfooter
   foreach my $include (qw( notes footer smallfooter )) {
 
-    my @inc_src = $conf->config_orbase("invoice_latex$include", $template );
-    my $convert_map = $convert_maps{$format}{$include};
+    my $inc_file = $conf->key_orbase("invoice_${format}$include", $template);
+    my @inc_src;
+
+    if ( $conf->exists($inc_file) && length( $conf->config($inc_file) ) ) {
+
+      @inc_src = $conf->config($inc_file);
 
-    if (
-           defined( $conf->config_orbase("invoice_${format}$include", $template) )
-        && length(  $conf->config_orbase('invoice_${format}$include', $template) )
-    ) {
-      @inc_src = $conf->config_orbase("invoice_${format}$include", $template );
     } else {
-      @inc_src =
-        map { s/\[@--/$delimiters{$format}[0]/g;
-              s/--@]/$delimiters{$format}[1]/g;
-              $_;
-            } 
-        &$convert_map(
-                       $conf->config_orbase("invoice_latex$include", $template )
-                     );
+
+      $inc_file = $conf->key_orbase("invoice_latex$include", $template);
+
+      my $convert_map = $convert_maps{$format}{$include};
+
+      @inc_src = map { s/\[\@--/$delimiters{$format}[0]/g;
+                       s/--\@\]/$delimiters{$format}[1]/g;
+                       $_;
+                     } 
+                 &$convert_map( $conf->config($inc_file) );
+
     }
 
     my $inc_tt = new Text::Template (
       TYPE       => 'ARRAY',
       SOURCE     => [ map "$_\n", @inc_src ],
       DELIMITERS => $delimiters{$format},
-    ) or die "can't create new Text::Template object: $Text::Template::ERROR";
+    ) or die "Can't create new Text::Template object: $Text::Template::ERROR";
 
-    $inc_tt->compile()
-      or die "can't compile template: $Text::Template::ERROR";
+    unless ( $inc_tt->compile() ) {
+      my $error = "Can't compile $inc_file template: $Text::Template::ERROR\n";
+      warn $error. "Template:\n". join('', map "$_\n", @inc_src);
+      die $error;
+    }
 
     $invoice_data{$include} = $inc_tt->fill_in( HASH => \%invoice_data );
 
@@ -2479,9 +2486,18 @@ sub _items_pkg {
   $self->_items_cust_bill_pkg(\@cust_bill_pkg, %options);
 }
 
+sub _taxsort {
+  return 0 unless $a cmp $b;
+  return -1 if $b eq 'Tax';
+  return 1 if $a eq 'Tax';
+  return -1 if $b eq 'Other surcharges';
+  return 1 if $a eq 'Other surcharges';
+  $a cmp $b;
+}
+
 sub _items_tax {
   my $self = shift;
-  my @cust_bill_pkg = grep { ! $_->pkgnum } $self->cust_bill_pkg;
+  my @cust_bill_pkg = sort _taxsort grep { ! $_->pkgnum } $self->cust_bill_pkg;
   $self->_items_cust_bill_pkg(\@cust_bill_pkg, @_);
 }
 
@@ -2492,6 +2508,8 @@ sub _items_cust_bill_pkg {
   my @b = ();
   foreach my $cust_bill_pkg ( @$cust_bill_pkg ) {
 
+    my $cust_pkg = $cust_bill_pkg->cust_pkg;
+
     my $desc = $cust_bill_pkg->desc;
 
     if ( $cust_bill_pkg->pkgnum > 0 ) {
@@ -2499,7 +2517,7 @@ sub _items_cust_bill_pkg {
       if ( $cust_bill_pkg->setup != 0 ) {
         my $description = $desc;
         $description .= ' Setup' if $cust_bill_pkg->recur != 0;
-        my @d = $cust_bill_pkg->cust_pkg->h_labels_short($self->_date);
+        my @d = $cust_pkg->h_labels_short($self->_date);
         push @d, $cust_bill_pkg->details if $cust_bill_pkg->recur == 0;
         push @b, {
           description     => $description,
@@ -2522,8 +2540,11 @@ sub _items_cust_bill_pkg {
           pkgnum          => $cust_bill_pkg->pkgnum,
           amount          => sprintf("%.2f", $cust_bill_pkg->recur),
           ext_description =>
-            [ $cust_bill_pkg->cust_pkg->h_labels_short( $cust_bill_pkg->edate,
-                                                        $cust_bill_pkg->sdate),
+            #at least until cust_bill_pkg has "past" ranges in addition to
+            #the "future" sdate/edate ones... see #3032
+            [ $cust_pkg->h_labels_short( $self->_date ),
+                                         #$cust_bill_pkg->edate,
+                                         #$cust_bill_pkg->sdate),
               $cust_bill_pkg->details,
             ],
         };
@@ -2643,7 +2664,7 @@ use Data::Dumper;
 use MIME::Base64;
 sub process_re_X {
   my( $method, $job ) = ( shift, shift );
-  warn "process_re_X $method for job $job\n" if $DEBUG;
+  warn "$me process_re_X $method for job $job\n" if $DEBUG;
 
   my $param = thaw(decode_base64(shift));
   warn Dumper($param) if $DEBUG;
@@ -2669,16 +2690,20 @@ sub re_X {
 
   my $extra_sql = ' WHERE '. FS::cust_bill->search_sql(\%param);
 
-  my $addl_from = 'left join cust_main using ( custnum )';
+  my $addl_from = 'LEFT JOIN cust_main USING ( custnum )';
      
-  my @cust_bill = qsearch( 'cust_bill',
-                           {},
-                           #"$distinct cust_bill.*",
-                           "cust_bill.*",
-                           $extra_sql,
-                           '',
-                           $addl_from
-                         );
+  my @cust_bill = qsearch( {
+    #'select'    => "cust_bill.*",
+    'table'     => 'cust_bill',
+    'addl_from' => $addl_from,
+    'hashref'   => {},
+    'extra_sql' => $extra_sql,
+    'order_by'  => $orderby,
+    'debug' => 1,
+  } );
+
+  warn " $me re_X $method: ". scalar(@cust_bill). " invoices found\n"
+    if $DEBUG;
 
   my( $num, $last, $min_sec ) = (0, time, 5); #progresbar foo
   foreach my $cust_bill ( @cust_bill ) {
@@ -2788,6 +2813,11 @@ Note: validates all passed-in data; i.e. safe to use with unchecked CGI params.
 
 sub search_sql {
   my($class, $param) = @_;
+  if ( $DEBUG ) {
+    warn "$me search_sql called with params: \n".
+         join("\n", map { "  $_: ". $param->{$_} } keys %$param ). "\n";
+  }
+
   my @search = ();
 
   if ( $param->{'begin'} =~ /^(\d+)$/ ) {
@@ -2838,7 +2868,22 @@ sub search_sql {
 
   }
 
-  push @search, $FS::CurrentUser::CurrentUser->agentnums_sql;
+  my $curuser = $FS::CurrentUser::CurrentUser;
+  if ( $curuser->username eq 'fs_queue'
+       && $param->{'CurrentUser'} =~ /^(\w+)$/ ) {
+    my $username = $1;
+    my $newuser = qsearchs('access_user', {
+      'username' => $username,
+      'disabled' => '',
+    } );
+    if ( $newuser ) {
+      $curuser = $newuser;
+    } else {
+      warn "$me WARNING: (fs_queue) can't find CurrentUser $username\n";
+    }
+  }
+
+  push @search, $curuser->agentnums_sql;
 
   join(' AND ', @search );