=item pkgnum - package (see L<FS::cust_pkg>) or 0 for the special virtual sales tax package, or -1 for the virtual line item (itemdesc is used for the line)
=item pkgpart_override - optional package definition (see L<FS::part_pkg>) override
+=item type - can be set to U for usage; more later
+
=item setup - setup fee
=item recur - recurring fee
=item itemdesc - Line item description (overrides normal package description)
+=item section - Invoice section (overrides normal package section)
+
+=duplicate - Indicates this item appears elsewhere on the invoice
+ (and should not be retaxed or reincluded in totals)
+
+=post_total - A hint that this item should appear after invoice totals
+
+=cut
+
+sub section {
+ my ( $self, $value ) = @_;
+ if ( defined($value) ) {
+ $self->setfield('section', $value);
+ } else {
+ $self->getfield('section') || $self->part_pkg->categoryname;
+ }
+}
+
=item quantity - If not set, defaults to 1
=item unitsetup - If not set, defaults to setup
'billpkgnum' => $self->billpkgnum,
'format' => (ref($detail) ? $detail->[0] : '' ),
'detail' => (ref($detail) ? $detail->[1] : $detail ),
+ 'charge' => (ref($detail) ? $detail->[2] : '' ),
+ 'classnum' => (ref($detail) ? $detail->[3] : '' ),
};
$error = $cust_bill_pkg_detail->insert;
if ( $error ) {
|| $self->ut_numbern('sdate')
|| $self->ut_numbern('edate')
|| $self->ut_textn('itemdesc')
+ || $self->ut_textn('section')
+ || $self->ut_enum('duplicate', [ '', 'Y' ])
+ || $self->ut_enum('post_total', [ '', 'Y' ])
+ || $self->ut_enum('type', [ '', 'U' ]) #only usage for now
;
return $error if $error;
# modeled after cust_bill::owed...
sub owed {
my( $self, $field ) = @_;
- my $balance = $self->$field();
+ my $balance = $self->duplicate ? 0 : $self->$field();
$balance -= $_->amount foreach ( $self->cust_bill_pay_pkg($field) );
$balance -= $_->amount foreach ( $self->cust_credit_bill_pkg($field) );
$balance = sprintf( '%.2f', $balance );
sub units {
my $self = shift;
- $self->part_pkg->calc_units($self->cust_pkg);
+ $self->pkgnum ? $self->part_pkg->calc_units($self->cust_pkg) : 0; # 1?
}
=item quantity
: $self->getfield('unitrecur');
}
+=item separate_cdr
+
+Returns true if this line item represents a cdr line item in its own section.
+
+=cut
+
+# lame, but works for now
+sub separate_cdr {
+ my( $self ) = shift;
+ $self->pkgnum && $self->section ne $self->part_pkg->categoryname;
+}
+
+=item usage CLASSNUM
+
+Returns the amount of the charge associated with usage class CLASSNUM if
+CLASSNUM is defined. Otherwise returns the total charge associated with
+usage.
+
+=cut
+
+sub usage {
+ my( $self, $classnum ) = @_;
+ my $sum = 0;
+ my @values = ();
+
+ if ( $self->get('details') ) {
+
+ @values =
+ map { $_->[2] }
+ grep { ref($_) && ( defined($classnum) ? $_->[3] eq $classnum : 1 ) }
+ $self->get('details');
+
+ }else{
+
+ my $hashref = { 'billpkgnum' => $self->billpkgnum };
+ $hashref->{ 'classnum' } = $classnum if defined($classnum);
+ @values = map { $_->charge } qsearch('cust_bill_pkg_detail', $hashref);
+
+ }
+
+ foreach ( @values ) {
+ $sum += $_ if $_;
+ }
+ $sum;
+}
+
+=item usage_classes
+
+Returns a list of usage classnums associated with this invoice line's
+details.
+
+=cut
+
+sub usage_classes {
+ my( $self ) = @_;
+
+ if ( $self->get('details') ) {
+
+ my %seen = ();
+ foreach my $detail ( grep { ref($_) } @{$self->get('details')} ) {
+ $seen{ $detail->[3] } = 1;
+ }
+ keys %seen;
+
+ }else{
+
+ map { $_->classnum }
+ qsearch({ table => 'cust_bill_pkg_detail',
+ hashref => { billpkgnum => $self->billpkgnum },
+ select => 'DISTINCT classnum',
+ });
+
+ }
+
+}
+
=back
=head1 BUGS