show credit balance on invoices, #11564
[freeside.git] / FS / FS / bill_batch.pm
1 package FS::bill_batch;
2
3 use strict;
4 use vars qw( @ISA $me $DEBUG );
5 use FS::Record qw( qsearch qsearchs dbh );
6 use FS::cust_bill_batch;
7 use CAM::PDF;
8
9 @ISA = qw( FS::Record );
10 $me = '[ FS::bill_batch ]';
11 $DEBUG=0;
12
13 sub table { 'bill_batch' }
14
15 sub nohistory_fields { 'pdf' }
16
17 =head1 NAME
18
19 FS::bill_batch - Object methods for bill_batch records
20
21 =head1 SYNOPSIS
22
23   use FS::bill_batch;
24
25   $open_batch = FS::bill_batch->get_open_batch;
26   
27   my $pdf = $open_batch->print_pdf;
28   
29   $error = $open_batch->close;
30   
31 =head1 DESCRIPTION
32
33 An FS::bill_batch object represents a batch of invoices.  FS::bill_batch 
34 inherits from FS::Record.  The following fields are currently supported:
35
36 =over 4
37
38 =item batchnum - primary key
39
40 =item status - either 'O' (open) or 'R' (resolved/closed).
41
42 =item pdf - blob field for temporarily storing the invoice as a PDF.
43
44 =back
45
46 =head1 METHODS
47
48 =over 4
49
50 =item print_pdf
51
52 Typeset the entire batch as a PDF file.  Returns the PDF as a string.
53
54 =cut
55
56 sub print_pdf {
57   my $self = shift;
58   my $job = shift;
59   $job->update_statustext(0) if $job;
60   my @invoices = sort { $a->invnum <=> $b->invnum }
61                  qsearch('cust_bill_batch', { batchnum => $self->batchnum });
62   return "No invoices in batch ".$self->batchnum.'.' if !@invoices;
63
64   my $pdf_out;
65   my $num = 0;
66   foreach my $invoice (@invoices) {
67     my $part = $invoice->cust_bill->print_pdf({$invoice->options});
68     die 'Failed creating PDF from invoice '.$invoice->invnum.'\n' if !$part;
69
70     if($pdf_out) {
71       $pdf_out->appendPDF(CAM::PDF->new($part));
72     }
73     else {
74       $pdf_out = CAM::PDF->new($part);
75     }
76     if($job) {
77       # update progressbar
78       $num++;
79       my $error = $job->update_statustext(int(100 * $num/scalar(@invoices)));
80       die $error if $error;
81     }
82   }
83
84   return $pdf_out->toPDF;
85 }
86
87 =item close
88
89 Set the status of the batch to 'R' (resolved).
90
91 =cut
92
93 sub close {
94   my $self = shift;
95   $self->status('R');
96   return $self->replace;
97 }
98
99 =back
100
101 =head1 CLASS METHODS
102
103 =item get_open_batch
104
105 Returns the currently open batch.  There should only be one at a time.
106
107 =cut
108
109 sub get_open_batch {
110   my $class = shift;
111   my $batch = qsearchs('bill_batch', { status => 'O' });
112   return $batch if $batch;
113   $batch = FS::bill_batch->new({status => 'O'});
114   my $error = $batch->insert;
115   die $error if $error;
116   return $batch;
117 }
118
119 use Storable 'thaw';
120 use Data::Dumper;
121 use MIME::Base64;
122
123 sub process_print_pdf {
124   my $job = shift;
125   my $param = thaw(decode_base64(shift));
126   warn Dumper($param) if $DEBUG;
127   die "no batchnum specified!\n" if ! exists($param->{batchnum});
128   my $batch = FS::bill_batch->by_key($param->{batchnum});
129   die "batch '$param->{batchnum}' not found!\n" if !$batch;
130
131   my $pdf = $batch->print_pdf($job);
132   $batch->pdf($pdf);
133   my $error = $batch->replace;
134   die $error if $error;
135 }
136
137
138 =back
139
140 =head1 BUGS
141
142 =head1 SEE ALSO
143
144 L<FS::Record>, schema.html from the base documentation.
145
146 =cut
147
148 1;
149