#ask FS::UID to run this stuff for us later
$FS::UID::callback{'FS::cust_bill'} = sub {
$conf = new FS::Conf;
- ( $add1, $add2, $add3, $add4 ) = $conf->config('address');
+ ( $add1, $add2, $add3, $add4 ) = ( $conf->config('address'), '', '', '', '' );
};
=head1 NAME
sub replace {
my( $new, $old ) = ( shift, shift );
- return "Can't change custnum!" unless $old->custnum eq $new->custnum;
- return "Can't change _date!" unless $old->_date eq $new->_date;
- return "Can't change charged!" unless $old->charged eq $new->charged;
+ return "Can't change custnum!" unless $old->custnum == $new->custnum;
+ #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;
return "(New) owed can't be > (new) charged!" if $new->owed > $new->charged;
$new->SUPER::replace($old);
#printing bits here (yuck!)
- local($SIG{CHLD}) = sub { wait() };
- $|=1;
- my($pid)=open(CHILD,"-|");
- die "Can't fork: $!" unless defined($pid);
+ my @collect = ();
- if ($pid) { #parent
- my(@collect)=<CHILD>;
- close CHILD;
- return @collect;
- } else { #child
+ my($description,$amount);
+ my(@buf);
- my($description,$amount);
- my(@buf);
-
- #define format stuff
- $%=0;
- $= = 35;
- local($^L) = <<END;
-
-
-
-
-
-
-
-END
+ #format address
+ my($l,@address)=(0,'','','','','','','');
+ $address[$l++] =
+ $cust_main->payname.
+ ( ( $cust_main->payby eq 'BILL' ) && $cust_main->payinfo
+ ? " (P.O. #". $cust_main->payinfo. ")"
+ : ''
+ )
+ ;
+ $address[$l++]=$cust_main->company if $cust_main->company;
+ $address[$l++]=$cust_main->address1;
+ $address[$l++]=$cust_main->address2 if $cust_main->address2;
+ $address[$l++]=$cust_main->city. ", ". $cust_main->state. " ".
+ $cust_main->zip;
+ $address[$l++]=$cust_main->country unless $cust_main->country eq 'US';
+
+ #previous balance
+ foreach ( @pr_cust_bill ) {
+ push @buf, (
+ "Previous Balance, Invoice #". $_->invnum.
+ " (". time2str("%x",$_->_date). ")",
+ '$'. sprintf("%10.2f",$_->owed)
+ );
+ }
+ if (@pr_cust_bill) {
+ push @buf,('','-----------');
+ push @buf,('Total Previous Balance','$' . sprintf("%10.2f",$pr_total ) );
+ push @buf,('','');
+ }
- #format address
- my($l,@address)=(0,'','','','','');
- $address[$l++]=$cust_main->company if $cust_main->company;
- $address[$l++]=$cust_main->address1;
- $address[$l++]=$cust_main->address2 if $cust_main->address2;
- $address[$l++]=$cust_main->city. ", ". $cust_main->state. " ".
- $cust_main->zip;
- $address[$l++]=$cust_main->country unless $cust_main->country eq 'US';
-
- #previous balance
- foreach ( @pr_cust_bill ) {
- push @buf, (
- "Previous Balance, Invoice #". $_->invnum.
- " (". time2str("%x",$_->_date). ")",
- '$'. sprintf("%10.2f",$_->owed)
- );
- }
- if (@pr_cust_bill) {
- push @buf,('','-----------');
- push @buf,('Total Previous Balance','$' . sprintf("%10.2f",$pr_total ) );
- push @buf,('','');
- }
+ #new charges
+ foreach ( $self->cust_bill_pkg ) {
- #new charges
- foreach ( $self->cust_bill_pkg ) {
+ if ( $_->pkgnum ) {
- if ( $_->pkgnum ) {
+ my($cust_pkg)=qsearchs('cust_pkg', { 'pkgnum', $_->pkgnum } );
+ my($part_pkg)=qsearchs('part_pkg',{'pkgpart'=>$cust_pkg->pkgpart});
+ my($pkg)=$part_pkg->pkg;
- my($cust_pkg)=qsearchs('cust_pkg', { 'pkgnum', $_->pkgnum } );
- my($part_pkg)=qsearchs('part_pkg',{'pkgpart'=>$cust_pkg->pkgpart});
- my($pkg)=$part_pkg->pkg;
+ if ( $_->setup != 0 ) {
+ push @buf, ( "$pkg Setup",'$' . sprintf("%10.2f",$_->setup) );
+ push @buf, map { " ". $_->[0]. ": ". $_->[1], '' } $cust_pkg->labels;
+ }
- push @buf, ( "$pkg Setup",'$' . sprintf("%10.2f",$_->setup) )
- if $_->setup != 0;
+ if ( $_->recur != 0 ) {
push @buf, (
"$pkg (" . time2str("%x",$_->sdate) . " - " .
time2str("%x",$_->edate) . ")",
'$' . sprintf("%10.2f",$_->recur)
- ) if $_->recur != 0;
-
- } else { #pkgnum Tax
- push @buf,("Tax",'$' . sprintf("%10.2f",$_->setup) )
- if $_->setup != 0;
+ );
+ push @buf, map { " ". $_->[0]. ": ". $_->[1], '' } $cust_pkg->labels;
}
- }
-
- push @buf,('','-----------');
- push @buf,('Total New Charges',
- '$' . sprintf("%10.2f",$self->charged) );
- push @buf,('','');
-
- push @buf,('','-----------');
- push @buf,('Total Charges',
- '$' . sprintf("%10.2f",$self->charged + $pr_total) );
- push @buf,('','');
-
- #credits
- foreach ( @cr_cust_credit ) {
- push @buf,(
- "Credit #". $_->crednum. " (" . time2str("%x",$_->_date) .")",
- '$' . sprintf("%10.2f",$_->credited)
- );
- }
- #get & print payments
- foreach ( $self->cust_pay ) {
- push @buf,(
- "Payment received ". time2str("%x",$_->_date ),
- '$' . sprintf("%10.2f",$_->paid )
- );
+ } else { #pkgnum Tax
+ push @buf,("Tax",'$' . sprintf("%10.2f",$_->setup) )
+ if $_->setup != 0;
}
-
- #balance due
- push @buf,('','-----------');
- push @buf,('Balance Due','$' .
- sprintf("%10.2f",$self->owed + $pr_total - $cr_total ) );
-
- #now print
-
- my($tot_pages)=int(scalar(@buf)/30); #15 lines, 2 values per line
- $tot_pages++ if scalar(@buf) % 30;
-
- while (@buf) {
+ }
+
+ push @buf,('','-----------');
+ push @buf,('Total New Charges',
+ '$' . sprintf("%10.2f",$self->charged) );
+ push @buf,('','');
+
+ push @buf,('','-----------');
+ push @buf,('Total Charges',
+ '$' . sprintf("%10.2f",$self->charged + $pr_total) );
+ push @buf,('','');
+
+ #credits
+ foreach ( @cr_cust_credit ) {
+ push @buf,(
+ "Credit #". $_->crednum. " (" . time2str("%x",$_->_date) .")",
+ '$' . sprintf("%10.2f",$_->credited)
+ );
+ }
+
+ #get & print payments
+ foreach ( $self->cust_pay ) {
+ push @buf,(
+ "Payment received ". time2str("%x",$_->_date ),
+ '$' . sprintf("%10.2f",$_->paid )
+ );
+ }
+
+ #balance due
+ push @buf,('','-----------');
+ push @buf,('Balance Due','$' .
+ sprintf("%10.2f",$self->owed + $pr_total - $cr_total ) );
+
+ #now print
+
+ my $tot_lines = 50; #should be configurable
+ #header is 17 lines
+ my $tot_pages = int( scalar(@buf) / ( 2 * ( $tot_lines - 17 ) ) );
+ $tot_pages++ if scalar(@buf) % ( 2 * ( $tot_lines - 17 ) );
+
+ my $page = 1;
+ my $lines;
+ while (@buf) {
+ $lines = $tot_lines;
+ my @header = &header(
+ $page, $tot_pages, $self->_date, $self->invnum, @address
+ );
+ push @collect, @header;
+ $lines -= scalar(@header);
+
+ while ( $lines-- && @buf ) {
$description=shift(@buf);
$amount=shift(@buf);
- write;
+ push @collect, myswrite($description, $amount);
}
- ($description,$amount)=('','');
- write while ( $- );
- print $^L;
-
- exit; #kid
-
- format STDOUT_TOP =
-
- @|||||||||||||||||||
- "Invoice"
- @||||||||||||||||||| @<<<<<<< @<<<<<<<<<<<
-{
- ( $tot_pages != 1 ) ? "Page $% of $tot_pages" : '',
- time2str("%x",( $self->_date )), "FS-$invnum"
-}
-
-
-@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-$add1
-@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-$add2
-@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-$add3
-@>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
-$add4
-
- @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-{ $cust_main->payname,
- ( ( $cust_main->payby eq 'BILL' ) && $cust_main->payinfo )
- ? "P.O. #". $cust_main->payinfo : ''
-}
- @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-$address[0],''
- @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-$address[1],$overdue ? "* This invoice is now PAST DUE! *" : ''
- @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-$address[2],$overdue ? " Please forward payment promptly " : ''
- @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-$address[3],$overdue ? "to avoid interruption of service." : ''
- @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
-$address[4],''
-
-
-
-.
-
- format STDOUT =
+ $page++;
+ }
+ while ( $lines-- ) {
+ push @collect, myswrite('', '');
+ }
+
+ return @collect;
+
+ sub header { #17 lines
+ my ( $page, $tot_pages, $date, $invnum, @address ) = @_ ;
+ push @address, '', '', '', '';
+
+ my @return = ();
+ my $i = ' 'x32;
+ push @return,
+ '',
+ $i. 'Invoice',
+ $i. substr("Page $page of $tot_pages".' 'x10, 0, 20).
+ time2str("%x", $date ). " FS-". $invnum,
+ '',
+ '',
+ $add1,
+ $add2,
+ $add3,
+ $add4,
+ '',
+ splice @address, 0, 7;
+ ;
+ return map $_. "\n", @return;
+ }
+
+ sub myswrite {
+ my $format = <<END;
@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<
- $description,$amount
-.
-
- } #endchild
+END
+ $^A = '';
+ formline( $format, @_ );
+ return $^A;
+ }
}
=head1 VERSION
-$Id: cust_bill.pm,v 1.4 1998-12-29 11:59:36 ivan Exp $
+$Id: cust_bill.pm,v 1.7 1999-02-09 09:55:05 ivan Exp $
=head1 BUGS
The delete method.
-print_text formatting (and some logic :/) is in source as a format declaration,
-which needs to be slurped in from a file. the fork is rather kludgy as well.
-It could be cleaned with swrite from man perlform, and the picture could be
-put in a /var/spool/freeside/conf file. Also number of lines ($=).
+print_text formatting (and some logic :/) is in source, but needs to be
+slurped in from a file. Also number of lines ($=).
missing print_ps for a nice postscript copy (maybe HylaFAX-cover-page-style
or something similar so the look can be completely customized?)
-There is an off-by-one error in print_text which causes a visual error: "Page 1
-of 2" printed on some single-page invoices?
-
=head1 SEE ALSO
L<FS::Record>, L<FS::cust_main>, L<FS::cust_pay>, L<FS::cust_bill_pkg>,
pod, ingegrate with FS::Invoice ivan@sisd.com 98-sep-20
$Log: cust_bill.pm,v $
-Revision 1.4 1998-12-29 11:59:36 ivan
+Revision 1.7 1999-02-09 09:55:05 ivan
+invoices show line items for each service in a package (see the label method
+of FS::cust_svc)
+
+Revision 1.6 1999/01/25 12:26:07 ivan
+yet more mod_perl stuff
+
+Revision 1.5 1999/01/18 21:58:03 ivan
+esthetic: eq and ne were used in a few places instead of == and !=
+
+Revision 1.4 1998/12/29 11:59:36 ivan
mostly properly OO, some work still to be done with svc_ stuff
Revision 1.3 1998/11/13 09:56:53 ivan