X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fcust_bill_pkg.pm;h=a83af1326cf7aede788956ac8f9cd8ca0dda4526;hb=431c9ca4fab151862bd24322bf8a1f9252fb38fc;hp=b8ae81d86c11a88ca60ee252c768c091fcf9f1e6;hpb=3185fe4edea62dd3fa9818cf80902e96fe2a2d21;p=freeside.git diff --git a/FS/FS/cust_bill_pkg.pm b/FS/FS/cust_bill_pkg.pm index b8ae81d86..a83af1326 100644 --- a/FS/FS/cust_bill_pkg.pm +++ b/FS/FS/cust_bill_pkg.pm @@ -581,9 +581,10 @@ appropriate FS::cust_bill_pkg_display objects. Options are passed as a list of name/value pairs. Options are: -part_pkg: FS::part_pkg object from the +part_pkg: FS::part_pkg object from this line item's package. -real_pkgpart: if this line item comes from a bundled package, the pkgpart of the owning package. Otherwise the same as the part_pkg's pkgpart above. +real_pkgpart: if this line item comes from a bundled package, the pkgpart +of the owning package. Otherwise the same as the part_pkg's pkgpart above. =cut @@ -594,13 +595,19 @@ sub set_display { my $conf = new FS::Conf; + # whether to break this down into setup/recur/usage my $separate = $conf->exists('separate_usage'); + my $usage_mandate = $part_pkg->option('usage_mandate', 'Hush!') || $cust_pkg->part_pkg->option('usage_mandate', 'Hush!'); # or use the category from $opt{'part_pkg'} if its not bundled? my $categoryname = $cust_pkg->part_pkg->categoryname; + # if we don't have to separate setup/recur/usage, or put this in a + # package-specific section, or display a usage summary, then don't + # even create one of these. The item will just display in the unnamed + # section as a single line plus details. return $self->set('display', []) unless $separate || $categoryname || $usage_mandate; @@ -608,34 +615,46 @@ sub set_display { my %hash = ( 'section' => $categoryname ); + # whether to put usage details in a separate section, and if so, which one my $usage_section = $part_pkg->option('usage_section', 'Hush!') || $cust_pkg->part_pkg->option('usage_section', 'Hush!'); + # whether to show a usage summary line (total usage charges, no details) my $summary = $part_pkg->option('summarize_usage', 'Hush!') || $cust_pkg->part_pkg->option('summarize_usage', 'Hush!'); if ( $separate ) { + # create lines for setup and (non-usage) recur, in the main section push @display, new FS::cust_bill_pkg_display { type => 'S', %hash }; push @display, new FS::cust_bill_pkg_display { type => 'R', %hash }; } else { + # display everything in a single line push @display, new FS::cust_bill_pkg_display { type => '', %hash, + # and if usage_mandate is enabled, hide details + # (this only works on multisection invoices...) ( ( $usage_mandate ) ? ( 'summary' => 'Y' ) : () ), }; } if ($separate && $usage_section && $summary) { + # create a line for the usage summary in the main section push @display, new FS::cust_bill_pkg_display { type => 'U', summary => 'Y', %hash, }; } + if ($usage_mandate || ($usage_section && $summary) ) { $hash{post_total} = 'Y'; } if ($separate || $usage_mandate) { + # show call details for this line item in the usage section. + # if usage_mandate is on, this will display below the section subtotal. + # this also happens if usage is in a separate section and there's a + # summary in the main section, though I'm not sure why. $hash{section} = $usage_section if $usage_section; push @display, new FS::cust_bill_pkg_display { type => 'U', %hash }; } @@ -646,8 +665,9 @@ sub set_display { =item disintegrate -Returns a list of cust_bill_pkg objects each with no more than a single class -(including setup or recur) of charge. +Returns a hash: keys are "setup", "recur" or usage classnum, values are +FS::cust_bill_pkg objects, each with no more than a single class (setup or +recur) of charge. =cut @@ -824,6 +844,18 @@ sub _X_show_zero { $self->cust_pkg->_X_show_zero($what); } +=item credited [ BEFORE, AFTER, OPTIONS ] + +Returns the sum of credits applied to this item. Arguments are the same as +owed_sql/paid_sql/credited_sql. + +=cut + +sub credited { + my $self = shift; + $self->scalar_sql('SELECT '. $self->credited_sql(@_).' FROM cust_bill_pkg WHERE billpkgnum = ?', $self->billpkgnum); +} + =back =head1 CLASS METHODS @@ -894,7 +926,7 @@ sub paid_sql { my $paid = "( SELECT COALESCE(SUM(cust_bill_pay_pkg.amount),0) FROM cust_bill_pay_pkg JOIN cust_bill_pay USING (billpaynum) WHERE cust_bill_pay_pkg.billpkgnum = cust_bill_pkg.billpkgnum - $s $e$setuprecur )"; + $s $e $setuprecur )"; if ( $opt{no_usage} ) { # cap the amount paid at the sum of non-usage charges, @@ -940,15 +972,14 @@ sub upgrade_tax_location { # they were calculated on a package-location basis. Create them here, # along with any necessary cust_location records and any tax exemption # records. - # - # This probably shouldn't run from freeside-upgrade. my ($class, %opt) = @_; # %opt may include 's' and 'e': start and end date ranges # and 'X': abort on any error, instead of just rolling back changes to # that invoice my $dbh = dbh; - $FS::UID::AutoCommit = 0; + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; eval { use FS::h_cust_main; @@ -1108,7 +1139,8 @@ sub upgrade_tax_location { push @{ $nontax_items{$taxclass} }, $item; } } - printf("%d tax items: \$%.2f\n", scalar(@tax_items), map {$_->setup} @tax_items); + printf("%d tax items: \$%.2f\n", scalar(@tax_items), map {$_->setup} @tax_items) + if @tax_items; # Use a variation on the procedure in # FS::cust_main::Billing::_handle_taxes to identify taxes that apply @@ -1378,21 +1410,41 @@ sub upgrade_tax_location { } #foreach (@tax_links) } #foreach $tax_item - $dbh->commit if $commit_each_invoice; + $dbh->commit if $commit_each_invoice and $oldAutoCommit; $committed = 1; } #foreach $invnum continue { if (!$committed) { - $dbh->rollback; + $dbh->rollback if $oldAutoCommit; die "Upgrade halted.\n" unless $commit_each_invoice; } } - $dbh->commit unless $commit_each_invoice; + $dbh->commit if $oldAutoCommit and !$commit_each_invoice; ''; } +sub _upgrade_data { + # Create a queue job to run upgrade_tax_location from January 1, 2012 to + # the present date. + eval { + use FS::queue; + use Date::Parse 'str2time'; + }; + my $class = shift; + my $upgrade = 'tax_location_2012'; + return if FS::upgrade_journal->is_done($upgrade); + my $job = FS::queue->new({ + 'job' => 'FS::cust_bill_pkg::upgrade_tax_location' + }); + # call it kind of like a class method, not that it matters much + $job->insert($class, 's' => str2time('2012-01-01')); + # Then mark the upgrade as done, so that we don't queue the job twice + # and somehow run two of them concurrently. + FS::upgrade_journal->set_done($upgrade); +} + =back =head1 BUGS