Merge branch 'master' of git.freeside.biz:/home/git/freeside
[freeside.git] / FS / FS / invoice_conf.pm
1 package FS::invoice_conf;
2
3 use strict;
4 use base qw( FS::Record FS::Conf );
5 use FS::Record qw( qsearch qsearchs );
6
7 =head1 NAME
8
9 FS::invoice_conf - Object methods for invoice_conf records
10
11 =head1 SYNOPSIS
12
13   use FS::invoice_conf;
14
15   $record = new FS::invoice_conf \%hash;
16   $record = new FS::invoice_conf { 'column' => 'value' };
17
18   $error = $record->insert;
19
20   $error = $new_record->replace($old_record);
21
22   $error = $record->delete;
23
24   $error = $record->check;
25
26 =head1 DESCRIPTION
27
28 An FS::invoice_conf object represents a set of localized invoice 
29 configuration values.  FS::invoice_conf inherits from FS::Record and FS::Conf,
30 and supports the FS::Conf interface.  The following fields are supported:
31
32 =over 4
33
34 =item confnum - primary key
35
36 =item modenum - L<FS::invoice_mode> foreign key
37
38 =item locale - locale string (see L<FS::Locales>)
39
40 =item notice_name - the title to display on the invoice
41
42 =item subject - subject line of the email
43
44 =item htmlnotes - "notes" section (HTML)
45
46 =item htmlfooter - footer (HTML)
47
48 =item htmlsummary - summary header, for invoices in summary format (HTML)
49
50 =item htmlreturnaddress - return address (HTML)
51
52 =item latexnotes - "notes" section (LaTeX)
53
54 =item latexfooter - footer (LaTeX)
55
56 =item latexsummary - summary header, for invoices in summary format (LaTeX)
57
58 =item latexreturnaddress - return address (LaTeX)
59
60 =item latexcoupon - payment coupon section (LaTeX)
61
62 =item latexsmallfooter - footer for pages after the first (LaTeX)
63
64 =item latextopmargin - top margin
65
66 =item latexheadsep - distance from bottom of header to top of body
67
68 =item latexaddresssep - distance from top of body to customer address
69
70 =item latextextheight - maximum height of invoice body text
71
72 =item latexextracouponspace - additional footer space to allow for coupon
73
74 =item latexcouponfootsep - distance from bottom of coupon content to top
75 of page footer
76
77 =item latexcouponamountenclosedsep - distance from coupon balance line to
78 "Amount Enclosed" box
79
80 =item latexcoupontoaddresssep - distance from "Amount Enclosed" box to 
81 coupon mailing address
82
83 =item latexverticalreturnaddress - 'Y' to place the return address below 
84 the company logo rather than beside it
85
86 =item latexcouponaddcompanytoaddress - 'Y' to add the company name to the 
87 address on the payment coupon
88
89 =item logo_png - company logo, as a PNG, for HTML invoices
90
91 =item logo_eps - company logo, as an EPS, for LaTeX invoices
92
93 =item lpr - command to print the invoice (passed on stdin as a PDF)
94
95 =back
96
97 =head1 METHODS
98
99 =over 4
100
101 =item new HASHREF
102
103 Creates a new invoice configuration.  To add it to the database, see 
104 L<"insert">.
105
106 =cut
107
108 # the new method can be inherited from FS::Record, if a table method is defined
109
110 sub table { 'invoice_conf'; }
111
112 =item insert
113
114 Adds this record to the database.  If there is an error, returns the error,
115 otherwise returns false.
116
117 =cut
118
119 # slightly special: you can insert/replace the invoice mode this way
120
121 sub insert {
122   my $self = shift;
123   if (!$self->modenum) {
124     my $invoice_mode = FS::invoice_mode->new({
125         'modename' => $self->modename,
126         'agentnum' => $self->agentnum,
127     });
128     my $error = $invoice_mode->insert;
129     return $error if $error;
130     $self->set('modenum' => $invoice_mode->modenum);
131   } else {
132     my $invoice_mode = FS::invoice_mode->by_key($self->modenum);
133     my $changed = 0;
134     foreach (qw(agentnum modename)) {
135       $changed ||= ($invoice_mode->get($_) eq $self->get($_));
136       $invoice_mode->set($_, $self->get($_));
137     }
138     my $error = $invoice_mode->replace if $changed;
139     return $error if $error;
140   }
141   $self->SUPER::insert(@_);
142 }
143
144 =item delete
145
146 Delete this record from the database.
147
148 =cut
149
150 sub delete {
151   my $self = shift;
152   my $error = $self->FS::Record::delete; # not Conf::delete
153   return $error if $error;
154   my $invoice_mode = FS::invoice_mode->by_key($self->modenum);
155   if ( $invoice_mode and
156        FS::invoice_conf->count('modenum = '.$invoice_mode->modenum) == 0 ) {
157     $error = $invoice_mode->delete;
158     return $error if $error;
159   }
160   '';
161 }
162
163 =item replace OLD_RECORD
164
165 Replaces the OLD_RECORD with this one in the database.  If there is an error,
166 returns the error, otherwise returns false.
167
168 =cut
169
170 sub replace {
171   my $self = shift;
172   my $error = $self->SUPER::replace(@_);
173   return $error if $error;
174
175   my $invoice_mode = FS::invoice_mode->by_key($self->modenum);
176   my $changed = 0;
177   foreach (qw(agentnum modename)) {
178     $changed ||= ($invoice_mode->get($_) eq $self->get($_));
179     $invoice_mode->set($_, $self->get($_));
180   }
181   $error = $invoice_mode->replace if $changed;
182   return $error if $error;
183 }
184
185 =item check
186
187 Checks all fields to make sure this is a valid example.  If there is
188 an error, returns the error, otherwise returns false.  Called by the insert
189 and replace methods.
190
191 =cut
192
193 # the check method should currently be supplied - FS::Record contains some
194 # data checking routines
195
196 sub check {
197   my $self = shift;
198
199   my $error = 
200     $self->ut_numbern('confnum')
201     || $self->ut_number('modenum')
202     || $self->ut_textn('locale')
203     || $self->ut_anything('notice_name')
204     || $self->ut_anything('subject')
205     || $self->ut_anything('htmlnotes')
206     || $self->ut_anything('htmlfooter')
207     || $self->ut_anything('htmlsummary')
208     || $self->ut_anything('htmlreturnaddress')
209     || $self->ut_anything('latexnotes')
210     || $self->ut_anything('latexfooter')
211     || $self->ut_anything('latexsummary')
212     || $self->ut_anything('latexcoupon')
213     || $self->ut_anything('latexsmallfooter')
214     || $self->ut_anything('latexreturnaddress')
215     || $self->ut_textn('latextopmargin')
216     || $self->ut_textn('latexheadsep')
217     || $self->ut_textn('latexaddresssep')
218     || $self->ut_textn('latextextheight')
219     || $self->ut_textn('latexextracouponspace')
220     || $self->ut_textn('latexcouponfootsep')
221     || $self->ut_textn('latexcouponamountenclosedsep')
222     || $self->ut_textn('latexcoupontoaddresssep')
223     || $self->ut_flag('latexverticalreturnaddress')
224     || $self->ut_flag('latexcouponaddcompanytoaddress')
225     || $self->ut_anything('logo_png')
226     || $self->ut_anything('logo_eps')
227   ;
228   return $error if $error;
229
230   $self->SUPER::check;
231 }
232
233 # hook _config to substitute our own values; let FS::Conf do the rest of 
234 # the interface
235
236 sub _config {
237   my $self = shift;
238   # if we fall back, we still want FS::Conf to respect our locale
239   $self->{locale} = $self->get('locale');
240   my ($key, $agentnum, $nodefault) = @_;
241   # some fields, but not all, start with invoice_
242   my $colname = $key;
243   if ( $key =~ /^invoice_(.*)$/ ) {
244     $colname = $1;
245   }
246   if ( length($self->get($colname)) ) {
247     return FS::conf->new({ 'name'   => $key,
248                            'value'  => $self->get($colname) });
249   } else {
250     return $self->FS::Conf::_config(@_);
251   }
252 }
253
254 # disambiguation
255 sub set {
256   my $self = shift;
257   $self->FS::Record::set(@_);
258 }
259
260 sub exists {
261   my $self = shift;
262   $self->FS::Conf::exists(@_);
263 }
264
265 =back
266
267 =head1 SEE ALSO
268
269 L<FS::Template_Mixin>, L<FS::Record>, schema.html from the base documentation.
270
271 =cut
272
273 1;
274