use FS::cust_bill;
use FS::cust_bill_pkg_detail;
use FS::cust_bill_pkg_display;
+use FS::cust_bill_pkg_discount;
use FS::cust_bill_pay_pkg;
use FS::cust_credit_bill_pkg;
use FS::cust_tax_exempt_pkg;
'amount' => (ref($detail) ? $detail->[2] : '' ),
'classnum' => (ref($detail) ? $detail->[3] : '' ),
'phonenum' => (ref($detail) ? $detail->[4] : '' ),
+ 'duration' => (ref($detail) ? $detail->[5] : '' ),
+ 'regionname' => (ref($detail) ? $detail->[6] : '' ),
};
$error = $cust_bill_pkg_detail->insert;
if ( $error ) {
}
}
+ if ( $self->get('discounts') ) {
+ foreach my $cust_bill_pkg_discount ( @{$self->get('discounts')} ) {
+ $cust_bill_pkg_discount->billpkgnum($self->billpkgnum);
+ $error = $cust_bill_pkg_discount->insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "error inserting cust_bill_pkg_discount: $error";
+ }
+ }
+ }
+
if ( $self->_cust_tax_exempt_pkg ) {
foreach my $cust_tax_exempt_pkg ( @{$self->_cust_tax_exempt_pkg} ) {
$cust_tax_exempt_pkg->billpkgnum($self->billpkgnum);
Returns an array of detail information for the invoice line item.
-Currently available options are: I<format> I<escape_function>
+Currently available options are: I<format>, I<escape_function> and
+I<format_function>.
If I<format> is set to html or latex then the array members are improved
for tabular appearance in those environments if possible.
If I<escape_function> is set then the array members are processed by this
function before being returned.
+I<format_function> overrides the normal HTML or LaTeX function for returning
+formatted CDRs. It can be set to a subroutine which returns an empty list
+to skip usage detail:
+
+ 'format_function' => sub { () },
+
=cut
sub details {
#qsearch ( 'cust_bill_pkg_detail', { 'lineitemnum' => $self->lineitemnum });
}
+=item details_header [ OPTION => VALUE ... ]
+
+Returns a list representing an invoice line item detail header, if any.
+This relies on the behavior of voip_cdr in that it expects the header
+to be the first CSV formatted detail (as is expected by invoice generation
+routines). Returns the empty list otherwise.
+
+=cut
+
+sub details_header {
+ my $self = shift;
+ return '' unless defined dbdef->table('cust_bill_pkg_detail');
+
+ eval "use Text::CSV_XS;";
+ die $@ if $@;
+ my $csv = new Text::CSV_XS;
+
+ my @detail =
+ qsearch ({ 'table' => 'cust_bill_pkg_detail',
+ 'hashref' => { 'billpkgnum' => $self->billpkgnum,
+ 'format' => 'C',
+ },
+ 'order_by' => 'ORDER BY detailnum LIMIT 1',
+ });
+ return() unless scalar(@detail);
+ $csv->parse($detail[0]->detail) or return ();
+ $csv->fields;
+}
+
=item desc
Returns a description for this line item. For typical line items, this is the
$balance;
}
+#modeled after owed
+sub payable {
+ my( $self, $field ) = @_;
+ my $balance = $self->$field();
+ $balance -= $_->amount foreach ( $self->cust_credit_bill_pkg($field) );
+ $balance = sprintf( '%.2f', $balance );
+ $balance =~ s/^\-0\.00$/0.00/; #yay ieee fp
+ $balance;
+}
+
sub cust_bill_pay_pkg {
my( $self, $field ) = @_;
qsearch( 'cust_bill_pay_pkg', { 'billpkgnum' => $self->billpkgnum,
$cust_bill_pkg{''}->recur( $classless );
$cust_bill_pkg{$class} = $cust_bill_pkg_usage;
}
- delete $cust_bill_pkg{''} unless $cust_bill_pkg{''}->recur;
+ warn "Unexpected classless usage value: ". $cust_bill_pkg{''}->recur
+ if ($cust_bill_pkg{''}->recur && $cust_bill_pkg{''}->recur < 0);
+ delete $cust_bill_pkg{''}
+ unless ($cust_bill_pkg{''}->recur && $cust_bill_pkg{''}->recur > 0);
}
# # sort setup,recur,'', and the rest numeric && return
my $type = $opt{type} if exists $opt{type};
my @result;
- if ( scalar( $self->get('display') ) ) {
+ if ( $self->get('display') ) {
@result = grep { defined($type) ? ($type eq $_->type) : 1 }
@{ $self->get('display') };
- }else{
+ } else {
my $hashref = { 'billpkgnum' => $self->billpkgnum };
$hashref->{type} = $type if defined($type);
}
+=item cust_bill_pkg_detail [ CLASSNUM ]
+
+Returns the list of associated cust_bill_pkg_detail objects
+The optional CLASSNUM argument will limit the details to the specified usage
+class.
+
+=cut
+
+sub cust_bill_pkg_detail {
+ my $self = shift;
+ my $classnum = shift || '';
+
+ my %hash = ( 'billpkgnum' => $self->billpkgnum );
+ $hash{classnum} = $classnum if $classnum;
+
+ qsearch( 'cust_bill_pkg_detail', \%hash ),
+
+}
+
+=item cust_bill_pkg_discount
+
+Returns the list of associated cust_bill_pkg_discount objects.
+
+=cut
+
+sub cust_bill_pkg_discount {
+ my $self = shift;
+ qsearch( 'cust_bill_pkg_discount', { 'billpkgnum' => $self->billpkgnum } );
+}
+
+=item recur_show_zero
+
+=cut
+
+sub recur_show_zero {
+ my $self = shift;
+
+ $self->recur == 0
+ && $self->pkgnum
+ && $self->cust_pkg->part_pkg->recur_show_zero;
+
+}
+
=back
=head1 BUGS