X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_bill.pm;h=e7c799fb6272807f8a538818b1966009c7d6a5d3;hb=7516e3da0f17eeecba27219ef96a8b5f46af2083;hp=cd85f6755e96ce23ff043ca4ad544e58ba7131dc;hpb=bf53da6deb6f4e2e71f60224c27863940b8de3d6;p=freeside.git diff --git a/FS/FS/cust_bill.pm b/FS/FS/cust_bill.pm index cd85f6755..e7c799fb6 100644 --- a/FS/FS/cust_bill.pm +++ b/FS/FS/cust_bill.pm @@ -41,11 +41,6 @@ use FS::L10N; $DEBUG = 0; $me = '[FS::cust_bill]'; -#ask FS::UID to run this stuff for us later -FS::UID->install_callback( sub { - my $conf = new FS::Conf; #global -} ); - =head1 NAME FS::cust_bill - Object methods for cust_bill records @@ -102,23 +97,19 @@ L and L for conversion functions. =back -Customer info at invoice generation time +Deprecated fields =over 4 -=item billing_balance - the customer's balance at the time the invoice was -generated (not including charges on this invoice) - -=item previous_balance - the billing_balance of this customer's previous -invoice plus the charges on that invoice +=item billing_balance - the customer's balance immediately before generating +this invoice. DEPRECATED. Use the L method +to determine the customer's balance at a specific time. -=back +=item previous_balance - the customer's balance immediately after generating +the invoice before this one. DEPRECATED. -Deprecated - -=over 4 - -=item printed - deprecated +=item printed - formerly used to track the number of times an invoice had +been printed; no longer used. =back @@ -134,6 +125,8 @@ Specific use cases =item promised_date - customer promised payment date, for collection +=item pending - invoice is still being generated, empty or 'Y' + =back =head1 METHODS @@ -343,6 +336,7 @@ sub replace_check { #return "Can't change _date!" unless $old->_date eq $new->_date; return "Can't change _date" unless $old->_date == $new->_date; return "Can't change charged" unless $old->charged == $new->charged + || $old->pending eq 'Y' || $old->charged == 0 || $new->{'Hash'}{'cc_surcharge_replace_hack'}; @@ -397,6 +391,7 @@ sub check { || $self->ut_enum('closed', [ '', 'Y' ]) || $self->ut_foreign_keyn('statementnum', 'cust_statement', 'statementnum' ) || $self->ut_numbern('agent_invid') #varchar? + || $self->ut_flag('pending') ; return $error if $error; @@ -416,8 +411,8 @@ cust_bill-default_agent_invid is set and it has a value, invnum otherwise. sub display_invnum { my $self = shift; - my $conf = $self->conf; - if ( $conf->exists('cust_bill-default_agent_invid') && $self->agent_invid ){ + if ( $self->agent_invid + && FS::Conf->new->exists('cust_bill-default_agent_invid') ) { return $self->agent_invid; } else { return $self->invnum; @@ -1516,6 +1511,8 @@ sub fax_invoice { Place this invoice into the open batch (see C). If there isn't an open batch, one will be created. +HASHREF may contain any options to be passed to C. + =cut sub batch_invoice { @@ -2405,13 +2402,20 @@ sub invoice_barcode { =item invnum_date_pretty Returns a string with the invoice number and date, for example: -"Invoice #54 (3/20/2008)" +"Invoice #54 (3/20/2008)". + +Intended for back-end context, with regard to translation and date formatting. =cut +#note: this uses _date_pretty_unlocalized because _date_pretty is too expensive +# for backend use (and also does the wrong thing, localizing for end customer +# instead of backoffice configured date format) sub invnum_date_pretty { my $self = shift; - $self->mt('Invoice #'). $self->invnum. ' ('. $self->_date_pretty. ')'; + #$self->mt('Invoice #'). + 'Invoice #'. #XXX should be translated ala web UI user (not invoice customer) + $self->invnum. ' ('. $self->_date_pretty_unlocalized. ')'; } #sub _items_extra_usage_sections { @@ -2919,6 +2923,49 @@ sub _items_svc_phone_sections { } +=sub _items_usage_class_summary OPTIONS + +Returns a list of detail items summarizing the usage charges on this +invoice. Each one will have 'amount', 'description' (the usage charge name), +and 'usage_classnum'. + +OPTIONS can include 'escape' (a function to escape the descriptions). + +=cut + +sub _items_usage_class_summary { + my $self = shift; + my %opt = @_; + + my $escape = $opt{escape} || sub { $_[0] }; + my $invnum = $self->invnum; + my @classes = qsearch({ + 'table' => 'usage_class', + 'select' => 'classnum, classname, SUM(amount) AS amount', + 'addl_from' => ' LEFT JOIN cust_bill_pkg_detail USING (classnum)' . + ' LEFT JOIN cust_bill_pkg USING (billpkgnum)', + 'extra_sql' => " WHERE cust_bill_pkg.invnum = $invnum". + ' GROUP BY classnum, classname, weight'. + ' HAVING (usage_class.disabled IS NULL OR SUM(amount) > 0)'. + ' ORDER BY weight ASC', + }); + my @l; + my $section = { + description => &{$escape}($self->mt('Usage Summary')), + no_subtotal => 1, + usage_section => 1, + }; + foreach my $class (@classes) { + push @l, { + 'description' => &{$escape}($class->classname), + 'amount' => sprintf('%.2f', $class->amount), + 'usage_classnum' => $class->classnum, + 'section' => $section, + }; + } + return @l; +} + sub _items_previous { my $self = shift; my $conf = $self->conf; @@ -3130,14 +3177,12 @@ sub process_respool { process_re_X('spool', @_); } -use Storable qw(thaw); use Data::Dumper; -use MIME::Base64; sub process_re_X { my( $method, $job ) = ( shift, shift ); warn "$me process_re_X $method for job $job\n" if $DEBUG; - my $param = thaw(decode_base64(shift)); + my $param = shift; warn Dumper($param) if $DEBUG; re_X( @@ -3198,6 +3243,14 @@ sub re_X { } +sub API_getinfo { + my $self = shift; + +{ ( map { $_=>$self->$_ } $self->fields ), + 'owed' => $self->owed, + #XXX last payment applied date + }; +} + =back =head1 CLASS METHODS @@ -3317,6 +3370,22 @@ flag, return net invoices only =item newest_percust +=item custnum + +Return only invoices belonging to that customer. + +=item cust_classnum + +Limit to that customer class (single value or arrayref). + +=item payby + +Limit to customers with that payment method (single value or arrayref). + +=item refnum + +Limit to customers with that advertising source. + =back Note: validates all passed-in data; i.e. safe to use with unchecked CGI params. @@ -3368,6 +3437,14 @@ sub search_sql_where { } + #payby + if ( $param->{payby} ) { + my $payby = $param->{payby}; + $payby = [ $payby ] unless ref $payby; + my $payby_in = join(',', map {dbh->quote($_)} @$payby); + push @search, "cust_main.payby IN($payby_in)" if length($payby_in); + } + #_date if ( $param->{_date} ) { my($beginning, $ending) = @{$param->{_date}};