non-package fees, "hold until next bill" option, #25899
authorMark Wells <mark@freeside.biz>
Wed, 26 Feb 2014 01:57:20 +0000 (17:57 -0800)
committerMark Wells <mark@freeside.biz>
Wed, 26 Feb 2014 07:08:30 +0000 (23:08 -0800)
FS/FS/Schema.pm
FS/FS/cust_main/Billing.pm
FS/FS/part_fee.pm
httemplate/edit/part_fee.html

index bf516b2..69681d0 100644 (file)
@@ -3148,6 +3148,7 @@ sub tables_hashref {
         'limit_credit',  'char',    'NULL',  1, '', '',
         'setuprecur',    'char',     '',     5, '', '',
         'taxable',       'char',    'NULL',  1, '', '',
+        'nextbill',      'char',    'NULL',  1, '', '',
       ],
       'primary_key'  => 'feepart',
       'unique'       => [],
index f4c30ce..1703aec 100644 (file)
@@ -533,8 +533,6 @@ sub bill {
 
     my @cust_bill_pkg = _omit_zero_value_bundles(@{ $cust_bill_pkg{$pass} });
 
-    next unless @cust_bill_pkg; #don't create an invoice w/o line items
-
     warn "$me billing pass $pass\n"
            #.Dumper(\@cust_bill_pkg)."\n"
       if $DEBUG > 2;
@@ -549,9 +547,15 @@ sub bill {
     warn "$me found pending fee events:\n".Dumper(\@pending_event_fees)."\n"
       if @pending_event_fees;
 
+    # whether to generate an invoice
+    my $generate_bill = scalar(@cust_bill_pkg) > 0;
+
+    # calculate fees...
     my @fee_items;
     foreach my $event_fee (@pending_event_fees) {
       my $object = $event_fee->cust_event->cust_X;
+      my $part_fee = $event_fee->part_fee;
+
       my $cust_bill;
       if ( $object->isa('FS::cust_main') ) {
         # Not the real cust_bill object that will be inserted--in particular
@@ -569,7 +573,6 @@ sub bill {
         # etc.)
         $cust_bill = $object;
       }
-      my $part_fee = $event_fee->part_fee;
       # if the fee def belongs to a different agent, don't charge the fee.
       # event conditions should prevent this, but just in case they don't,
       # skip the fee.
@@ -585,7 +588,15 @@ sub bill {
       # link this so that we can clear the marker on inserting the line item
       $fee_item->set('cust_event_fee', $event_fee);
       push @fee_items, $fee_item;
+
+      $generate_bill = 1 unless $part_fee->nextbill;
     }
+    
+    # don't create an invoice with no line items, or where the only line 
+    # items are fees that are supposed to be held until the next invoice
+    next if !$generate_bill;
+
+    # add fees to the invoice
     foreach my $fee_item (@fee_items) {
 
       push @cust_bill_pkg, $fee_item;
index 9605d61..d1e6477 100644 (file)
@@ -54,6 +54,9 @@ the invoice
 Currently, taxable fees will be treated like they exist at the customer's
 default service location.
 
+=item nextbill - 'Y' if this fee should be delayed until the customer is 
+billed for a package.
+
 =item taxclass - the tax class the fee belongs to, as a string, for the 
 internal tax system
 
@@ -127,6 +130,7 @@ sub check {
   my $self = shift;
 
   $self->set('amount', 0) unless $self->amount;
+  $self->set('percent', 0) unless $self->percent;
 
   my $error = 
     $self->ut_numbern('feepart')
@@ -134,14 +138,15 @@ sub check {
     || $self->ut_flag('disabled')
     || $self->ut_foreign_keyn('classnum', 'pkg_class', 'classnum')
     || $self->ut_flag('taxable')
+    || $self->ut_flag('nextbill')
     || $self->ut_textn('taxclass')
     || $self->ut_numbern('taxproductnum')
     || $self->ut_floatn('pay_weight')
     || $self->ut_floatn('credit_weight')
     || $self->ut_agentnum_acl('agentnum',
                               [ 'Edit global package definitions' ])
-    || $self->ut_moneyn('amount')
-    || $self->ut_floatn('percent')
+    || $self->ut_money('amount')
+    || $self->ut_float('percent')
     || $self->ut_moneyn('minimum')
     || $self->ut_moneyn('maximum')
     || $self->ut_flag('limit_credit')
index dada233..b1044c9 100644 (file)
@@ -20,6 +20,7 @@
     'minimum'       => 'Minimum fee',
     'maximum'       => 'Maximum fee',
     'limit_credit'  => 'Limit to customer credit balance',
+    'nextbill'      => 'Hold until the customer\'s next invoice',
     %locale_labels
   },
   'fields'        => \@fields,
@@ -86,6 +87,11 @@ my @fields = (
     value   => 'Y',
   },
 
+  { field   => 'nextbill',
+    type    => 'checkbox',
+    value   => 'Y',
+  },
+
   { field   => 'setuprecur',
     type    => 'select',
     options => [ 'setup', 'recur' ],