X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_main.pm;h=1e43519312ac3edf0258109d4497432c9413cfd2;hb=a67fd3bbfeec137ebf494e36eaa920145b8509a1;hp=e7cdd21d4476506148948201492b3a118dc961aa;hpb=73e346e819dc56fb4447f9eb1624a49df1f58ab7;p=freeside.git diff --git a/FS/FS/cust_main.pm b/FS/FS/cust_main.pm index e7cdd21d4..1e4351931 100644 --- a/FS/FS/cust_main.pm +++ b/FS/FS/cust_main.pm @@ -9,6 +9,7 @@ use Safe; use Carp; use Exporter; use Scalar::Util qw( blessed ); +use List::Util qw( min ); use Time::Local qw(timelocal); use Data::Dumper; use Tie::IxHash; @@ -41,6 +42,7 @@ use FS::part_referral; use FS::cust_main_county; use FS::cust_location; use FS::cust_main_exemption; +use FS::cust_tax_adjustment; use FS::tax_rate; use FS::tax_rate_location; use FS::cust_tax_location; @@ -1551,6 +1553,7 @@ sub check { || $self->ut_textn('stateid_state') || $self->ut_textn('invoice_terms') || $self->ut_alphan('geocode') + || $self->ut_floatn('cdr_termination_percentage') ; #barf. need message catalogs. i18n. etc. @@ -2055,6 +2058,18 @@ sub unsuspended_pkgs { grep { ! $_->susp } $self->ncancelled_pkgs; } +=item next_bill_date + +Returns the next date this customer will be billed, as a UNIX timestamp, or +undef if no active package has a next bill date. + +=cut + +sub next_bill_date { + my $self = shift; + min( map $_->get('bill'), grep $_->get('bill'), $self->unsuspended_pkgs ); +} + =item num_cancelled_pkgs Returns the number of cancelled packages (see L) for this @@ -2661,6 +2676,35 @@ sub bill { } + #add tax adjustments + warn "adding tax adjustments...\n" if $DEBUG > 2; + foreach my $cust_tax_adjustment ( + qsearch('cust_tax_adjustment', { 'custnum' => $self->custnum, + 'billpkgnum' => '', + } + ) + ) { + + my $tax = sprintf('%.2f', $cust_tax_adjustment->amount ); + $total_setup = sprintf('%.2f', $total_setup+$tax ); + + my $itemdesc = $cust_tax_adjustment->taxname; + $itemdesc = '' if $itemdesc eq 'Tax'; + + push @cust_bill_pkg, new FS::cust_bill_pkg { + 'pkgnum' => 0, + 'setup' => $tax, + 'recur' => 0, + 'sdate' => '', + 'edate' => '', + 'itemdesc' => $itemdesc, + 'itemcomment' => $cust_tax_adjustment->comment, + 'cust_tax_adjustment' => $cust_tax_adjustment, + #'cust_bill_pkg_tax_location' => \@cust_bill_pkg_tax_location, + }; + + } + my $charged = sprintf('%.2f', $total_setup + $total_recur ); #create the new invoice @@ -2730,14 +2774,19 @@ sub _make_lines { my $setup = 0; my $unitsetup = 0; - if ( ! $cust_pkg->setup && - ( - ( $conf->exists('disable_setup_suspended_pkgs') && - ! $cust_pkg->getfield('susp') - ) || ! $conf->exists('disable_setup_suspended_pkgs') - ) - || $options{'resetup'} - ) { + 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') + ) + ) + ) + ) + { warn " bill setup\n" if $DEBUG > 1; $lineitems++; @@ -2753,6 +2802,9 @@ sub _make_lines { #do need it, but it won't get written to the db #|| $cust_pkg->pkgpart != $real_pkgpart; + $cust_pkg->setfield('start_date', '') + if $cust_pkg->start_date; + } ### @@ -6688,21 +6740,50 @@ sub credit { } -=item charge AMOUNT [ PKG [ COMMENT [ TAXCLASS ] ] ] +=item charge HASHREF || AMOUNT [ PKG [ COMMENT [ TAXCLASS ] ] ] Creates a one-time charge for this customer. If there is an error, returns the error, otherwise returns false. +New-style, with a hashref of options: + + my $error = $cust_main->charge( + { + 'amount' => 54.32, + 'quantity' => 1, + 'start_date' => str2time('7/4/2009'), + 'pkg' => 'Description', + 'comment' => 'Comment', + 'additional' => [], #extra invoice detail + 'classnum' => 1, #pkg_class + + 'setuptax' => '', # or 'Y' for tax exempt + + #internal taxation + 'taxclass' => 'Tax class', + + #vendor taxation + 'taxproduct' => 2, #part_pkg_taxproduct + 'override' => {}, #XXX describe + } + ); + +Old-style: + + my $error = $cust_main->charge( 54.32, 'Description', 'Comment', 'Tax class' ); + =cut sub charge { my $self = shift; - my ( $amount, $quantity, $pkg, $comment, $classnum, $additional ); + my ( $amount, $quantity, $start_date, $classnum ); + my ( $pkg, $comment, $additional ); my ( $setuptax, $taxclass ); #internal taxes my ( $taxproduct, $override ); #vendor (CCH) taxes if ( ref( $_[0] ) ) { $amount = $_[0]->{amount}; $quantity = exists($_[0]->{quantity}) ? $_[0]->{quantity} : 1; + $start_date = exists($_[0]->{start_date}) ? $_[0]->{start_date} : ''; $pkg = exists($_[0]->{pkg}) ? $_[0]->{pkg} : 'One-time charge'; $comment = exists($_[0]->{comment}) ? $_[0]->{comment} : '$'. sprintf("%.2f",$amount); @@ -6712,9 +6793,10 @@ sub charge { $additional = $_[0]->{additional}; $taxproduct = $_[0]->{taxproductnum}; $override = { '' => $_[0]->{tax_override} }; - }else{ + } else { $amount = shift; $quantity = 1; + $start_date = ''; $pkg = @_ ? shift : 'One-time charge'; $comment = @_ ? shift : '$'. sprintf("%.2f",$amount); $setuptax = ''; @@ -6772,9 +6854,10 @@ sub charge { } my $cust_pkg = new FS::cust_pkg ( { - 'custnum' => $self->custnum, - 'pkgpart' => $pkgpart, - 'quantity' => $quantity, + 'custnum' => $self->custnum, + 'pkgpart' => $pkgpart, + 'quantity' => $quantity, + 'start_date' => $start_date, } ); $error = $cust_pkg->insert; @@ -7543,6 +7626,13 @@ sub search_sql { unless $params->{'cancelled_pkgs'}; ## + # parse without census tract checkbox + ## + + push @where, "(censustract = '' or censustract is null)" + if $params->{'no_censustract'}; + + ## # dates ## @@ -8080,12 +8170,12 @@ sub smart_search { } - #eliminate duplicates - my %saw = (); - @cust_main = grep { !$saw{$_->custnum}++ } @cust_main; - } + #eliminate duplicates + my %saw = (); + @cust_main = grep { !$saw{$_->custnum}++ } @cust_main; + @cust_main; }