X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_main%2FBilling.pm;h=b710f33266308d5b46ce5b1a66327e6e2ab05677;hb=b5c4237a34aef94976bc343c8d9e138664fc3984;hp=4b727bb7c53bb8973cccbe035b43f7d79ea42003;hpb=aa93abfbe3967fdc6b6c01636c02b8340d261c40;p=freeside.git diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm index 4b727bb7c..b710f3326 100644 --- a/FS/FS/cust_main/Billing.pm +++ b/FS/FS/cust_main/Billing.pm @@ -547,7 +547,7 @@ sub bill { #create the new invoice my $cust_bill = new FS::cust_bill ( { 'custnum' => $self->custnum, - '_date' => ( $invoice_time ), + '_date' => $invoice_time, 'charged' => $charged, 'billing_balance' => $balance, 'previous_balance' => $previous_balance, @@ -584,17 +584,23 @@ sub _omit_zero_value_bundles { my @cust_bill_pkg = (); my @cust_bill_pkg_bundle = (); my $sum = 0; + my $discount_show_always = 0; foreach my $cust_bill_pkg ( @_ ) { + $discount_show_always = ($cust_bill_pkg->get('discounts') + && scalar(@{$cust_bill_pkg->get('discounts')}) + && $conf->exists('discount-show-always')); if (scalar(@cust_bill_pkg_bundle) && !$cust_bill_pkg->pkgpart_override) { - push @cust_bill_pkg, @cust_bill_pkg_bundle if $sum > 0; + push @cust_bill_pkg, @cust_bill_pkg_bundle + if ($sum > 0 || ($sum == 0 && $discount_show_always)); @cust_bill_pkg_bundle = (); $sum = 0; } $sum += $cust_bill_pkg->setup + $cust_bill_pkg->recur; push @cust_bill_pkg_bundle, $cust_bill_pkg; } - push @cust_bill_pkg, @cust_bill_pkg_bundle if $sum > 0; + push @cust_bill_pkg, @cust_bill_pkg_bundle + if ($sum > 0 || ($sum == 0 && $discount_show_always)); (@cust_bill_pkg); @@ -720,8 +726,16 @@ sub calculate_taxes { foreach my $tax ( keys %$taxlisthash ) { foreach ( @{ $taxlisthash->{$tax} }[1 ... scalar(@{ $taxlisthash->{$tax} })] ) { next unless ref($_) eq 'FS::cust_bill_pkg'; - push @{ $packagemap{$_->pkgnum}->_cust_tax_exempt_pkg }, - splice( @{ $_->_cust_tax_exempt_pkg } ); + + my @cust_tax_exempt_pkg = splice( @{ $_->_cust_tax_exempt_pkg } ); + + next unless @cust_tax_exempt_pkg; #just avoiding the prob when irrelevant? + die "can't distribute tax exemptions: no line item for ". Dumper($_). + " in packagemap ". join(',', sort {$a<=>$b} keys %packagemap). "\n" + unless $packagemap{$_->pkgnum}; + + push @{ $packagemap{$_->pkgnum}->_cust_tax_exempt_pkg }, + @cust_tax_exempt_pkg; } } @@ -814,19 +828,21 @@ sub _make_lines { my $setup = 0; my $unitsetup = 0; - if ( $options{'resetup'} - || ( ! $cust_pkg->setup - && ( ! $cust_pkg->start_date - || $cust_pkg->start_date <= $time - ) - && ( ! $conf->exists('disable_setup_suspended_pkgs') - || ( $conf->exists('disable_setup_suspended_pkgs') && - ! $cust_pkg->getfield('susp') - ) - ) - ) - and !$options{recurring_only} - ) + if ( ! $options{recurring_only} + and ! $options{cancel} + and ( $options{'resetup'} + || ( ! $cust_pkg->setup + && ( ! $cust_pkg->start_date + || $cust_pkg->start_date <= $time + ) + && ( ! $conf->exists('disable_setup_suspended_pkgs') + || ( $conf->exists('disable_setup_suspended_pkgs') && + ! $cust_pkg->getfield('susp') + ) + ) + ) + ) + ) { warn " bill setup\n" if $DEBUG > 1; @@ -891,6 +907,7 @@ sub _make_lines { 'discounts' => \@discounts, 'real_pkgpart' => $real_pkgpart, 'freq_override' => $options{freq_override} || '', + 'setup_fee' => 0, ); my $method = $options{cancel} ? 'calc_cancel' : 'calc_recur'; @@ -899,6 +916,11 @@ sub _make_lines { # which can_discount are supported. # (the UI should prevent adding discounts to these at the moment) + warn "calling $method on cust_pkg ". $cust_pkg->pkgnum. + " for pkgpart ". $cust_pkg->pkgpart. + " with params ". join(' / ', map "$_=>$param{$_}", keys %param). "\n" + if $DEBUG > 2; + $recur = eval { $cust_pkg->$method( \$sdate, \@details, \%param ) }; return "$@ running $method for $cust_pkg\n" if ( $@ ); @@ -920,6 +942,14 @@ sub _make_lines { } + if ( $param{'setup_fee'} ) { + # Add an additional setup fee at the billing stage. + # Used for prorate_defer_bill. + $setup += $param{'setup_fee'}; + $unitsetup += $param{'setup_fee'}; + $lineitems++; + } + } warn "\$setup is undefined" unless defined($setup); @@ -940,6 +970,7 @@ sub _make_lines { if $DEBUG >1; my $error = $cust_pkg->replace( $old_cust_pkg, + 'depend_jobnum'=>$options{depend_jobnum}, 'options' => { $cust_pkg->options }, ) unless $options{no_commit}; @@ -956,9 +987,13 @@ sub _make_lines { return "negative recur $recur for pkgnum ". $cust_pkg->pkgnum; } + my $discount_show_always = ($recur == 0 && scalar(@discounts) + && $conf->exists('discount-show-always')); + if ( $setup != 0 || $recur != 0 || - !$part_pkg->hidden && $options{has_hidden} ) #include some $0 lines + (!$part_pkg->hidden && $options{has_hidden}) || #include some $0 lines + $discount_show_always ) { warn " charges (setup=$setup, recur=$recur); adding line items\n" @@ -984,11 +1019,11 @@ sub _make_lines { 'freq' => $part_pkg->freq, }; - if ( $part_pkg->option('recur_temporality', 1) eq 'preceding' ) { + if ( $part_pkg->recur_temporality eq 'preceding' ) { $cust_bill_pkg->sdate( $hash{last_bill} ); $cust_bill_pkg->edate( $sdate - 86399 ); #60s*60m*24h-1 $cust_bill_pkg->edate( $time ) if $options{cancel}; - } else { #if ( $part_pkg->option('recur_temporality', 1) eq 'upcoming' ) { + } else { #if ( $part_pkg->recur_temporality eq 'upcoming' ) { $cust_bill_pkg->sdate( $sdate ); $cust_bill_pkg->edate( $cust_pkg->bill ); #$cust_bill_pkg->edate( $time ) if $options{cancel}; @@ -1004,9 +1039,11 @@ sub _make_lines { # handle taxes ### - my $error = - $self->_handle_taxes($part_pkg, $taxlisthash, $cust_bill_pkg, $cust_pkg, $options{invoice_time}, $real_pkgpart, \%options); - return $error if $error; + unless ( $discount_show_always ) { + my $error = + $self->_handle_taxes($part_pkg, $taxlisthash, $cust_bill_pkg, $cust_pkg, $options{invoice_time}, $real_pkgpart, \%options); + return $error if $error; + } push @$cust_bill_pkgs, $cust_bill_pkg; @@ -2080,6 +2117,26 @@ sub apply_payments { =back +=head1 FLOW + + bill_and_collect + + cancel_expired_pkgs + suspend_adjourned_pkgs + + bill + (do_cust_event pre-bill) + _make_lines + _handle_taxes + (vendor-only) _gather_taxes + _omit_zero_value_bundles + calculate_taxes + + apply_payments_and_credits + collect + do_cust_event + due_cust_event + =head1 BUGS =head1 SEE ALSO