change invoice terms for one-time charges (& bill them immediately), RT#5891
authorivan <ivan>
Sat, 10 Oct 2009 00:00:32 +0000 (00:00 +0000)
committerivan <ivan>
Sat, 10 Oct 2009 00:00:32 +0000 (00:00 +0000)
FS/FS/Schema.pm
FS/FS/cust_bill.pm
FS/FS/cust_main.pm
httemplate/edit/cust_main/billing.html
httemplate/edit/process/quick-charge.cgi
httemplate/edit/quick-charge.html
httemplate/elements/select-terms.html [new file with mode: 0644]

index 70f3250..6f53b2a 100644 (file)
@@ -390,15 +390,23 @@ sub tables_hashref {
 
     'cust_bill' => {
       'columns' => [
 
     'cust_bill' => {
       'columns' => [
+        #regular fields
         'invnum',    'serial',     '', '', '', '', 
         'custnum',      'int',     '', '', '', '', 
         '_date',        @date_type,        '', '', 
         'charged',      @money_type,       '', '', 
         'invnum',    'serial',     '', '', '', '', 
         'custnum',      'int',     '', '', '', '', 
         '_date',        @date_type,        '', '', 
         'charged',      @money_type,       '', '', 
+        'invoice_terms', 'varchar', 'NULL', $char_d, '', '',
+
+        #customer balance info at invoice generation time
         'previous_balance',   @money_typen, '', '',  #eventually not nullable
         'billing_balance',    @money_typen, '', '',  #eventually not nullable
         'previous_balance',   @money_typen, '', '',  #eventually not nullable
         'billing_balance',    @money_typen, '', '',  #eventually not nullable
+
+        #deprecated (unused by now, right?)
         'printed',      'int',     '', '', '', '', 
         'printed',      'int',     '', '', '', '', 
+
+        #specific use cases
         'closed',      'char', 'NULL',  1, '', '', 
         'closed',      'char', 'NULL',  1, '', '', 
-        'statementnum', 'int', 'NULL', '', '', '',
+        'statementnum', 'int', 'NULL', '', '', '', #invoice aggregate statements
       ],
       'primary_key' => 'invnum',
       'unique' => [],
       ],
       'primary_key' => 'invnum',
       'unique' => [],
index ac1e450..493bc09 100644 (file)
@@ -96,6 +96,18 @@ L<Time::Local> and L<Date::Parse> for conversion functions.
 
 =item charged - amount of this invoice
 
 
 =item charged - amount of this invoice
 
+=item invoice_terms - optional terms override for this specific invoice
+
+=back
+
+Customer info at invoice generation time
+
+=over 4
+
+=item previous_balance
+
+=item billing_balance
+
 =back
 
 Deprecated
 =back
 
 Deprecated
@@ -2989,10 +3001,10 @@ sub _translate_old_latex_format {
         $line_item_line =~ s/\$(\w+)/'. \$_tr_line->{$1}. '/g;
         push @template, "    \$OUT .= '$line_item_line';";
       }
         $line_item_line =~ s/\$(\w+)/'. \$_tr_line->{$1}. '/g;
         push @template, "    \$OUT .= '$line_item_line';";
       }
-  
+
       push @template, '}',
                       '--@]';
       push @template, '}',
                       '--@]';
-
+      #' doh, gvim
     } elsif ( $line =~ /^%%TotalDetails\s*$/ ) {
 
       push @template, '[@--',
     } elsif ( $line =~ /^%%TotalDetails\s*$/ ) {
 
       push @template, '[@--',
@@ -3026,11 +3038,12 @@ sub _translate_old_latex_format {
 sub terms {
   my $self = shift;
 
 sub terms {
   my $self = shift;
 
-  #check for an invoice- specific override (eventually)
+  #check for an invoice-specific override
+  return $self->invoice_terms if $self->invoice_terms;
   
   #check for a customer- specific override
   
   #check for a customer- specific override
-  return $self->cust_main->invoice_terms
-    if $self->cust_main->invoice_terms;
+  my $cust_main = $self->cust_main;
+  return $cust_main->invoice_terms if $cust_main->invoice_terms;
 
   #use configured default
   $conf->config('invoice_default_terms') || '';
 
   #use configured default
   $conf->config('invoice_default_terms') || '';
index 9d40e73..c83acc6 100644 (file)
@@ -2475,6 +2475,11 @@ typically might mean not charging the normal recurring fee but only usage
 fees since the last billing. Setup charges may be charged.  Not all package
 plans support this feature (they tend to charge 0).
 
 fees since the last billing. Setup charges may be charged.  Not all package
 plans support this feature (they tend to charge 0).
 
+=item invoice_terms
+
+Options terms to be printed on this invocice.  Otherwise, customer-specific
+terms or the default terms are used.
+
 =back
 
 =cut
 =back
 
 =cut
@@ -2801,6 +2806,7 @@ sub bill {
     'charged'             => $charged,
     'billing_balance'     => $balance,
     'previous_balance'    => $previous_balance,
     'charged'             => $charged,
     'billing_balance'     => $balance,
     'previous_balance'    => $previous_balance,
+    'invoice_terms'       => $options{'invoice_terms'},
   } );
   $error = $cust_bill->insert;
   if ( $error ) {
   } );
   $error = $cust_bill->insert;
   if ( $error ) {
@@ -7172,6 +7178,10 @@ New-style, with a hashref of options:
 
                                     #will be filled in with the new object
                                     'cust_pkg_ref' => \$cust_pkg,
 
                                     #will be filled in with the new object
                                     'cust_pkg_ref' => \$cust_pkg,
+
+                                    #generate an invoice immediately
+                                    'bill_now' => 0,
+                                    'invoice_terms' => '', #with these terms
                                   }
                                 );
 
                                   }
                                 );
 
@@ -7188,6 +7198,7 @@ sub charge {
   my ( $setuptax, $taxclass );   #internal taxes
   my ( $taxproduct, $override ); #vendor (CCH) taxes
   my $cust_pkg_ref = '';
   my ( $setuptax, $taxclass );   #internal taxes
   my ( $taxproduct, $override ); #vendor (CCH) taxes
   my $cust_pkg_ref = '';
+  my ( $bill_now, $invoice_terms ) = ( 0, '' );
   if ( ref( $_[0] ) ) {
     $amount     = $_[0]->{amount};
     $quantity   = exists($_[0]->{quantity}) ? $_[0]->{quantity} : 1;
   if ( ref( $_[0] ) ) {
     $amount     = $_[0]->{amount};
     $quantity   = exists($_[0]->{quantity}) ? $_[0]->{quantity} : 1;
@@ -7202,6 +7213,8 @@ sub charge {
     $taxproduct = $_[0]->{taxproductnum};
     $override   = { '' => $_[0]->{tax_override} };
     $cust_pkg_ref = exists($_[0]->{cust_pkg_ref}) ? $_[0]->{cust_pkg_ref} : '';
     $taxproduct = $_[0]->{taxproductnum};
     $override   = { '' => $_[0]->{tax_override} };
     $cust_pkg_ref = exists($_[0]->{cust_pkg_ref}) ? $_[0]->{cust_pkg_ref} : '';
+    $bill_now = exists($_[0]->{bill_now}) ? $_[0]->{bill_now} : '';
+    $invoice_terms = exists($_[0]->{invoice_terms}) ? $_[0]->{invoice_terms} : '';
   } else {
     $amount     = shift;
     $quantity   = 1;
   } else {
     $amount     = shift;
     $quantity   = 1;
@@ -7277,8 +7290,18 @@ sub charge {
     ${$cust_pkg_ref} = $cust_pkg;
   }
 
     ${$cust_pkg_ref} = $cust_pkg;
   }
 
+  if ( $bill_now ) {
+    my $error = $self->bill( 'invoice_terms' => $invoice_terms,
+                             'pkg_list'      => [ $cust_pkg ],
+                           );
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return $error;
+    }   
+  }
+
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
-  '';
+  return '';
 
 }
 
 
 }
 
index 363dd04..ad83778 100644 (file)
     <TR>
       <TD ALIGN="right" WIDTH="200">Invoice terms </TD>
       <TD WIDTH="408">
     <TR>
       <TD ALIGN="right" WIDTH="200">Invoice terms </TD>
       <TD WIDTH="408">
-        <SELECT NAME="invoice_terms">
-          <OPTION VALUE="">Default (<% $conf->config('invoice_default_terms') || 'Payable upon receipt' %>)
-%         foreach my $term ( 'Payable upon receipt',
-%                            ( map "Net $_", 0, 10, 15, 20, 30, 45, 60 ),
-%                          ) {
-            <OPTION VALUE="<% $term %>" <% $cust_main->invoice_terms eq $term ? ' SELECTED' : '' %>><% $term %>
-%         }
-        </SELECT>
+        <% include('/elements/select-terms.html',
+                     'curr_value' => $cust_main->invoice_terms,
+                  )
+        %>
       </TD>
     </TR>
 
       </TD>
     </TR>
 
index 8f0e424..827530e 100644 (file)
@@ -55,6 +55,8 @@ unless ( $error ) {
   $error ||= $cust_main->charge( {
     'amount'        => $amount,
     'quantity'      => $quantity,
   $error ||= $cust_main->charge( {
     'amount'        => $amount,
     'quantity'      => $quantity,
+    'bill_now'      => scalar($cgi->param('bill_now')),
+    'invoice_terms' => scalar($cgi->param('invoice_terms')),
     'start_date'    => ( scalar($cgi->param('start_date'))
                            ? str2time($cgi->param('start_date'))
                            : ''
     'start_date'    => ( scalar($cgi->param('start_date'))
                            ? str2time($cgi->param('start_date'))
                            : ''
index 75e3fee..c96fa6c 100644 (file)
@@ -3,10 +3,10 @@
           )
 %>
 
           )
 %>
 
-<LINK REL="stylesheet" TYPE="text/css" HREF="../elements/calendar-win2k-2.css" TITLE="win2k-2">
-<SCRIPT TYPE="text/javascript" SRC="../elements/calendar_stripped.js"></SCRIPT>
-<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-en.js"></SCRIPT>
-<SCRIPT TYPE="text/javascript" SRC="../elements/calendar-setup.js"></SCRIPT>
+<LINK REL="stylesheet" TYPE="text/css" HREF="<%$fsurl%>elements/calendar-win2k-2.css" TITLE="win2k-2">
+<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/calendar_stripped.js"></SCRIPT>
+<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/calendar-en.js"></SCRIPT>
+<SCRIPT TYPE="text/javascript" SRC="<%$fsurl%>elements/calendar-setup.js"></SCRIPT>
 
 <% include('/elements/error.html') %>
 
 
 <% include('/elements/error.html') %>
 
@@ -58,6 +58,23 @@ function validate_quick_charge () {
   return false;
 }
 
   return false;
 }
 
+function bill_now_changed (what) {
+  var form = what.form;
+  if ( what.checked ) {
+    form.start_date_text.disabled = true;
+    form.start_date.style.backgroundColor = '#dddddd';
+    form.start_date_button.style.display = 'none';
+    form.start_date_button_disabled.style.display = '';
+    form.invoice_terms.disabled = false;
+  } else {
+    form.start_date_text.disabled = false;
+    form.start_date.style.backgroundColor = '#ffffff';
+    form.start_date_button.style.display = '';
+    form.start_date_button_disabled.style.display = 'none';
+    form.invoice_terms.disabled = true;
+  }
+}
+
 </SCRIPT>
 
 <FORM ACTION="process/quick-charge.cgi" NAME="QuickChargeForm" ID="QuickChargeForm" METHOD="POST" onsubmit="document.QuickChargeForm.submit.disabled=true;return validate_quick_charge();">
 </SCRIPT>
 
 <FORM ACTION="process/quick-charge.cgi" NAME="QuickChargeForm" ID="QuickChargeForm" METHOD="POST" onsubmit="document.QuickChargeForm.submit.disabled=true;return validate_quick_charge();">
@@ -84,6 +101,25 @@ function validate_quick_charge () {
 
 <% include('/elements/tr-select-pkg_class.html', 'curr_value' => $cgi->param('classnum') ) %>
 
 
 <% include('/elements/tr-select-pkg_class.html', 'curr_value' => $cgi->param('classnum') ) %>
 
+<TR>
+  <TD ALIGN="right">Invoice now</TD>
+  <TD>
+    <INPUT TYPE  = "checkbox"
+           NAME  = "bill_now"
+           VALUE = "1"
+           <% $cgi->param('bill_now') ? 'CHECKED' : '' %>
+           onChange = "bill_now_changed(this);"
+    >
+    with terms 
+    <% include('/elements/select-terms.html',
+                 'curr_value'  => scalar($cgi->param('invoice_terms')),
+                 'empty_value' => $default_terms,
+                 'disabled'    => ( $cgi->param('bill_now') ? 0 : 1 ),
+              )
+    %>
+  </TD>
+</TR>
+
 %# false laziness w/misc/order_pkg.html
 <TR>
   <TD ALIGN="right">Charge date </TD>
 %# false laziness w/misc/order_pkg.html
 <TR>
   <TD ALIGN="right">Charge date </TD>
@@ -93,11 +129,16 @@ function validate_quick_charge () {
            SIZE  = 32
            ID    = "start_date_text"
            VALUE = "<% $start_date %>"
            SIZE  = 32
            ID    = "start_date_text"
            VALUE = "<% $start_date %>"
+           <% $cgi->param('bill_now') ? 'STYLE = "background-color:#dddddd" DISABLED' : '' %>
     >
     >
-    <IMG SRC   = "../images/calendar.png"
+    <IMG SRC   = "<%$fsurl%>images/calendar.png"
          ID    = "start_date_button"
          ID    = "start_date_button"
-         STYLE = "cursor: pointer"
          TITLE = "Select date"
          TITLE = "Select date"
+         STYLE = "cursor:pointer<% $cgi->param('bill_now') ? ';display:none' : '' %>"
+    >
+    <IMG SRC   = "<%$fsurl%>images/calendar-disabled.png"
+         ID    = "start_date_button_disabled"
+         <% $cgi->param('bill_now') ? '' : 'STYLE="display:none"' %>
     >
     <FONT SIZE=-1>(leave blank to charge immediately)</FONT>
   </TD>
     >
     <FONT SIZE=-1>(leave blank to charge immediately)</FONT>
   </TD>
@@ -232,4 +273,14 @@ $cgi->param('pkg') =~ /^([\w \!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\=\[\]]*)$/
   or die 'illegal description';
 my $pkg = $1;
 
   or die 'illegal description';
 my $pkg = $1;
 
+my $default_terms;
+if ( $cust_main->invoice_terms ) {
+  $default_terms = 'Customer default ('. $cust_main->invoice_terms. ')';
+} else {
+  $default_terms =
+    'Default ('.
+       ($conf->config('invoice_default_terms') || 'Payable upon receipt').
+    ')';
+}
+
 </%init>
 </%init>
diff --git a/httemplate/elements/select-terms.html b/httemplate/elements/select-terms.html
new file mode 100644 (file)
index 0000000..629d1e4
--- /dev/null
@@ -0,0 +1,26 @@
+<SELECT NAME = "invoice_terms"
+        ID   = "invoice_terms"
+        <% $opt{'disabled'} ? 'DISABLED' : ''%>
+>
+  <OPTION VALUE=""><% $empty_label %>
+% foreach my $term ( @terms ) {
+    <OPTION VALUE="<% $term %>" <% $curr_value eq $term ? ' SELECTED' : '' %>><% $term %>
+% }
+</SELECT>
+<%init>
+
+my %opt = @_;
+my $curr_value = $opt{'curr_value'};
+my $conf = new FS::Conf;
+
+my $empty_label =
+  $opt{'empty_label'}
+  || 'Default ('.
+       ($conf->config('invoice_default_terms') || 'Payable upon receipt').
+     ')';
+
+my @terms = ( 'Payable upon receipt',
+              ( map "Net $_", 0, 10, 15, 20, 30, 45, 60 ),
+            );
+
+</%init>