fix 'Can't call method "setup" on an undefined value' error when using into rates...
[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 CAM::PDF;
6 use FS::Conf;
7 use FS::Record qw( qsearch qsearchs dbh );
8 use FS::agent;
9 use FS::cust_bill_batch;
10
11 @ISA = qw( FS::Record );
12 $me = '[ FS::bill_batch ]';
13 $DEBUG=0;
14
15 sub table { 'bill_batch' }
16
17 sub nohistory_fields { 'pdf' }
18
19 =head1 NAME
20
21 FS::bill_batch - Object methods for bill_batch records
22
23 =head1 SYNOPSIS
24
25   use FS::bill_batch;
26
27   $open_batch = FS::bill_batch->get_open_batch;
28   
29   my $pdf = $open_batch->print_pdf;
30   
31   $error = $open_batch->close;
32   
33 =head1 DESCRIPTION
34
35 An FS::bill_batch object represents a batch of invoices.  FS::bill_batch 
36 inherits from FS::Record.  The following fields are currently supported:
37
38 =over 4
39
40 =item batchnum - primary key
41
42 =item agentnum - empty for global batches or agent (see L<FS::agent>)
43
44 =item status - either 'O' (open) or 'R' (resolved/closed).
45
46 =item pdf - blob field for temporarily storing the invoice as a PDF.
47
48 =back
49
50 =head1 METHODS
51
52 =over 4
53
54 =item print_pdf
55
56 Typeset the entire batch as a PDF file.  Returns the PDF as a string.
57
58 =cut
59
60 sub print_pdf {
61   my $self = shift;
62   my $job = shift;
63   $job->update_statustext(0) if $job;
64   my @invoices = sort { $a->invnum <=> $b->invnum }
65                  qsearch('cust_bill_batch', { batchnum => $self->batchnum });
66   return "No invoices in batch ".$self->batchnum.'.' if !@invoices;
67
68   my $pdf_out;
69   my $num = 0;
70   foreach my $invoice (@invoices) {
71     my $part = $invoice->cust_bill->print_pdf({$invoice->options});
72     die 'Failed creating PDF from invoice '.$invoice->invnum.'\n' if !$part;
73
74     if($pdf_out) {
75       $pdf_out->appendPDF(CAM::PDF->new($part));
76     }
77     else {
78       $pdf_out = CAM::PDF->new($part);
79     }
80     if($job) {
81       # update progressbar
82       $num++;
83       my $error = $job->update_statustext(int(100 * $num/scalar(@invoices)));
84       die $error if $error;
85     }
86   }
87   $job->update_statustext(100, 'Combining invoices') if $job;
88
89   return $pdf_out->toPDF;
90 }
91
92 =item close
93
94 Set the status of the batch to 'R' (resolved).
95
96 =cut
97
98 sub close {
99   my $self = shift;
100   $self->status('R');
101   return $self->replace;
102 }
103
104 sub check {
105   my $self = shift;
106
107   my $error =
108        $self->ut_numbern('batchnum')
109     || $self->ut_foreign_keyn('agentnum', 'agent', 'agentnum')
110     || $self->ut_enum('status', [ 'O', 'R' ] )
111   ;
112   return $error if $error;
113
114   $self->SUPER::check;
115 }
116
117 =item agent
118
119 Returns the agent (see L<FS::agent>) for this invoice batch.
120
121 =cut
122
123 sub agent {
124   my $self = shift;
125   qsearchs( 'agent', { 'agentnum' => $self->agentnum } );
126 }
127
128 =back
129
130 =head1 SUBROUTINES
131
132 =item process_print_pdf
133
134 =cut
135
136 use Storable 'thaw';
137 use Data::Dumper;
138 use MIME::Base64;
139
140 sub process_print_pdf {
141   my $job = shift;
142   my $param = thaw(decode_base64(shift));
143   warn Dumper($param) if $DEBUG;
144   die "no batchnum specified!\n" if ! exists($param->{batchnum});
145   my $batch = FS::bill_batch->by_key($param->{batchnum});
146   die "batch '$param->{batchnum}' not found!\n" if !$batch;
147
148   if ( $param->{'close'} ) {
149     my $error = $batch->close;
150     die $error if $error;
151   }
152
153   my $pdf = $batch->print_pdf($job);
154   $batch->pdf($pdf);
155   my $error = $batch->replace;
156   die $error if $error;
157 }
158
159 =back
160
161 =head1 BUGS
162
163 =head1 SEE ALSO
164
165 L<FS::Record>, schema.html from the base documentation.
166
167 =cut
168
169 1;
170