X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_main%2FBilling.pm;h=0b421090425697a05206804d147cdccb0b3563c9;hb=67779831c7ac1bb6d65073a0e523453dacf751c6;hp=f6a60805344312d736be6635a6826aba7cd09ed6;hpb=27cfd639aa367ad8d878c71a9516bd913099d528;p=freeside.git diff --git a/FS/FS/cust_main/Billing.pm b/FS/FS/cust_main/Billing.pm index f6a608053..0b4210904 100644 --- a/FS/FS/cust_main/Billing.pm +++ b/FS/FS/cust_main/Billing.pm @@ -7,6 +7,7 @@ use Data::Dumper; use List::Util qw( min ); use FS::UID qw( dbh ); use FS::Record qw( qsearch qsearchs dbdef ); +use FS::Misc::DateTime qw( day_end ); use FS::cust_bill; use FS::cust_bill_pkg; use FS::cust_bill_pkg_display; @@ -20,7 +21,6 @@ use FS::cust_bill_pkg_tax_rate_location; use FS::part_event; use FS::part_event_condition; use FS::pkg_category; -use POSIX; # 1 is mostly method/subroutine entry and options # 2 traces progress of some operations @@ -113,7 +113,7 @@ sub bill_and_collect { my $job = $options{'job'}; $job->update_statustext('0,cleaning expired packages') if $job; - $error = $self->cancel_expired_pkgs( $self->day_end( $options{actual_time} ) ); + $error = $self->cancel_expired_pkgs( day_end( $options{actual_time} ) ); if ( $error ) { $error = "Error expiring custnum ". $self->custnum. ": $error"; if ( $options{fatal} && $options{fatal} eq 'return' ) { return $error; } @@ -121,7 +121,7 @@ sub bill_and_collect { else { warn $error; } } - $error = $self->suspend_adjourned_pkgs( $self->day_end( $options{actual_time} ) ); + $error = $self->suspend_adjourned_pkgs( day_end( $options{actual_time} ) ); if ( $error ) { $error = "Error adjourning custnum ". $self->custnum. ": $error"; if ( $options{fatal} && $options{fatal} eq 'return' ) { return $error; } @@ -165,19 +165,6 @@ sub bill_and_collect { } -sub day_end { - # XXX: sometimes "incorrect" if crossing DST boundaries? - - my $self = shift; - my $time = shift; - - return $time unless $conf->exists('next-bill-ignore-time'); - - my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = - localtime($time); - mktime(59,59,23,$mday,$mon,$year,$wday,$yday,$isdst); -} - sub cancel_expired_pkgs { my ( $self, $time, %options ) = @_; @@ -603,27 +590,52 @@ sub bill { #discard bundled packages of 0 value sub _omit_zero_value_bundles { + my @in = @_; my @cust_bill_pkg = (); my @cust_bill_pkg_bundle = (); my $sum = 0; my $discount_show_always = 0; - foreach my $cust_bill_pkg ( @_ ) { + foreach my $cust_bill_pkg ( @in ) { + $discount_show_always = ($cust_bill_pkg->get('discounts') && scalar(@{$cust_bill_pkg->get('discounts')}) && $conf->exists('discount-show-always')); + + warn " pkgnum ". $cust_bill_pkg->pkgnum. " sum $sum, ". + "setup_show_zero ". $cust_bill_pkg->setup_show_zero. + "recur_show_zero ". $cust_bill_pkg->recur_show_zero. "\n" + if $DEBUG > 0; + if (scalar(@cust_bill_pkg_bundle) && !$cust_bill_pkg->pkgpart_override) { push @cust_bill_pkg, @cust_bill_pkg_bundle - if ($sum > 0 || ($sum == 0 && $discount_show_always)); + if $sum > 0 + || ($sum == 0 && ( $discount_show_always + || grep {$_->recur_show_zero || $_->setup_show_zero} + @cust_bill_pkg_bundle + ) + ); @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 || ($sum == 0 && $discount_show_always)); + if $sum > 0 + || ($sum == 0 && ( $discount_show_always + || grep {$_->recur_show_zero || $_->setup_show_zero} + @cust_bill_pkg_bundle + ) + ); + + warn " _omit_zero_value_bundles: ". scalar(@in). + '->'. scalar(@cust_bill_pkg). "\n" #. Dumper(@cust_bill_pkg). "\n" + if $DEBUG > 2; (@cust_bill_pkg); @@ -857,7 +869,7 @@ sub _make_lines { and ( $options{'resetup'} || ( ! $cust_pkg->setup && ( ! $cust_pkg->start_date - || $cust_pkg->start_date <= $self->day_end($time) + || $cust_pkg->start_date <= day_end($time) ) && ( ! $conf->exists('disable_setup_suspended_pkgs') || ( $conf->exists('disable_setup_suspended_pkgs') && @@ -902,7 +914,7 @@ sub _make_lines { if ( ! $cust_pkg->start_date and ( ! $cust_pkg->susp || $part_pkg->option('suspend_bill', 1) ) and - ( $part_pkg->freq ne '0' && ( $cust_pkg->bill || 0 ) <= $self->day_end($time) ) + ( $part_pkg->freq ne '0' && ( $cust_pkg->bill || 0 ) <= day_end($time) ) || ( $part_pkg->plan eq 'voip_cdr' && $part_pkg->option('bill_every_call') ) @@ -926,7 +938,7 @@ sub _make_lines { #over two params! lets at least switch to a hashref for the rest... my $increment_next_bill = ( $part_pkg->freq ne '0' - && ( $cust_pkg->getfield('bill') || 0 ) <= $self->day_end($time) + && ( $cust_pkg->getfield('bill') || 0 ) <= day_end($time) && !$options{cancel} ); my %param = ( 'precommit_hooks' => $precommit_hooks, @@ -1024,10 +1036,13 @@ sub _make_lines { 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 - $discount_show_always ) + if ( $setup != 0 + || $recur != 0 + || (!$part_pkg->hidden && $options{has_hidden}) #include some $0 lines + || $discount_show_always + || ($setup == 0 && $cust_pkg->_X_show_zero('setup')) + || ($recur == 0 && $cust_pkg->_X_show_zero('recur')) + ) { warn " charges (setup=$setup, recur=$recur); adding line items\n" @@ -1193,46 +1208,12 @@ sub _handle_taxes { } #if $conf->exists('enable_taxproducts') ... } - - my @display = (); - my $separate = $conf->exists('separate_usage'); - my $temp_pkg = new FS::cust_pkg { pkgpart => $real_pkgpart }; - my $usage_mandate = $temp_pkg->part_pkg->option('usage_mandate', 'Hush!'); - my $section = $temp_pkg->part_pkg->categoryname; - if ( $separate || $section || $usage_mandate ) { - - my %hash = ( 'section' => $section ); - - $section = $temp_pkg->part_pkg->option('usage_section', 'Hush!'); - my $summary = $temp_pkg->part_pkg->option('summarize_usage', 'Hush!'); - if ( $separate ) { - push @display, new FS::cust_bill_pkg_display { type => 'S', %hash }; - push @display, new FS::cust_bill_pkg_display { type => 'R', %hash }; - } else { - push @display, new FS::cust_bill_pkg_display - { type => '', - %hash, - ( ( $usage_mandate ) ? ( 'summary' => 'Y' ) : () ), - }; - } - if ($separate && $section && $summary) { - push @display, new FS::cust_bill_pkg_display { type => 'U', - summary => 'Y', - %hash, - }; - } - if ($usage_mandate || $section && $summary) { - $hash{post_total} = 'Y'; - } - - if ($separate || $usage_mandate) { - $hash{section} = $section if ($separate || $usage_mandate); - push @display, new FS::cust_bill_pkg_display { type => 'U', %hash }; - } - - } - $cust_bill_pkg->set('display', \@display); + #what's this doing in the middle of _handle_taxes? probably should split + #this into three parts above in _make_lines + $cust_bill_pkg->set_display( part_pkg => $part_pkg, + real_pkgpart => $real_pkgpart, + ); my %tax_cust_bill_pkg = $cust_bill_pkg->disintegrate; foreach my $key (keys %tax_cust_bill_pkg) { @@ -1641,7 +1622,7 @@ sub do_cust_event { if $DEBUG > 1; #if ( my $error = $cust_event->do_event(%options) ) { #XXX %options? - if ( my $error = $cust_event->do_event() ) { + if ( my $error = $cust_event->do_event( 'time' => $time ) ) { #XXX wtf is this? figure out a proper dealio with return value #from do_event return $error; @@ -2125,11 +2106,14 @@ sub apply_payments { my $amount = min( $payment->unapplied, $owed ); - my $cust_bill_pay = new FS::cust_bill_pay ( { + my $cbp = { 'paynum' => $payment->paynum, 'invnum' => $cust_bill->invnum, 'amount' => $amount, - } ); + }; + $cbp->{_date} = $payment->_date + if $options{'manual'} && $options{'backdate_application'}; + my $cust_bill_pay = new FS::cust_bill_pay($cbp); $cust_bill_pay->pkgnum( $payment->pkgnum ) if $conf->exists('pkg-balances') && $payment->pkgnum; my $error = $cust_bill_pay->insert(%options);