invoice voiding, RT#18677
[freeside.git] / FS / FS / cust_bill_void.pm
1 package FS::cust_bill_void;
2 use base qw( FS::Template_Mixin FS::cust_main_Mixin FS::otaker_Mixin FS::Record );
3
4 use strict;
5 use FS::Record qw( qsearch qsearchs dbh fields );
6 use FS::cust_main;
7 use FS::cust_statement;
8 use FS::access_user;
9 use FS::cust_bill_pkg_void;
10 use FS::cust_bill;
11
12 =head1 NAME
13
14 FS::cust_bill_void - Object methods for cust_bill_void records
15
16 =head1 SYNOPSIS
17
18   use FS::cust_bill_void;
19
20   $record = new FS::cust_bill_void \%hash;
21   $record = new FS::cust_bill_void { 'column' => 'value' };
22
23   $error = $record->insert;
24
25   $error = $new_record->replace($old_record);
26
27   $error = $record->delete;
28
29   $error = $record->check;
30
31 =head1 DESCRIPTION
32
33 An FS::cust_bill_void object represents a voided invoice.  FS::cust_bill_void
34 inherits from FS::Record.  The following fields are currently supported:
35
36 =over 4
37
38 =item invnum
39
40 primary key
41
42 =item custnum
43
44 custnum
45
46 =item _date
47
48 _date
49
50 =item charged
51
52 charged
53
54 =item invoice_terms
55
56 invoice_terms
57
58 =item previous_balance
59
60 previous_balance
61
62 =item billing_balance
63
64 billing_balance
65
66 =item closed
67
68 closed
69
70 =item statementnum
71
72 statementnum
73
74 =item agent_invid
75
76 agent_invid
77
78 =item promised_date
79
80 promised_date
81
82 =item void_date
83
84 void_date
85
86 =item reason
87
88 reason
89
90 =item void_usernum
91
92 void_usernum
93
94
95 =back
96
97 =head1 METHODS
98
99 =over 4
100
101 =item new HASHREF
102
103 Creates a new voided invoice.  To add the voided invoice to the database, see L<"insert">.
104
105 Note that this stores the hash reference, not a distinct copy of the hash it
106 points to.  You can ask the object for a copy with the I<hash> method.
107
108 =cut
109
110 sub table { 'cust_bill_void'; }
111 sub notice_name { 'VOIDED Invoice'; }
112 #XXXsub template_conf { 'quotation_'; }
113
114 =item insert
115
116 Adds this record to the database.  If there is an error, returns the error,
117 otherwise returns false.
118
119 =cut
120
121 =item unvoid 
122
123 "Un-void"s this invoice: Deletes the voided invoice from the database and adds
124 back a normal invoice (and related tables).
125
126 =cut
127
128 sub unvoid {
129   my $self = shift;
130
131   local $SIG{HUP} = 'IGNORE';
132   local $SIG{INT} = 'IGNORE';
133   local $SIG{QUIT} = 'IGNORE';
134   local $SIG{TERM} = 'IGNORE';
135   local $SIG{TSTP} = 'IGNORE';
136   local $SIG{PIPE} = 'IGNORE';
137
138   my $oldAutoCommit = $FS::UID::AutoCommit;
139   local $FS::UID::AutoCommit = 0;
140   my $dbh = dbh;
141
142   my $cust_bill = new FS::cust_bill ( {
143     map { $_ => $self->get($_) } fields('cust_bill')
144   } );
145   my $error = $cust_bill->insert;
146   if ( $error ) {
147     $dbh->rollback if $oldAutoCommit;
148     return $error;
149   }
150
151   foreach my $cust_bill_pkg_void ( $self->cust_bill_pkg ) {
152     my $error = $cust_bill_pkg_void->unvoid;
153     if ( $error ) {
154       $dbh->rollback if $oldAutoCommit;
155       return $error;
156     }
157   }
158
159   $error = $self->delete;
160   if ( $error ) {
161     $dbh->rollback if $oldAutoCommit;
162     return $error;
163   }
164
165   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
166
167   '';
168
169 }
170
171 =item delete
172
173 Delete this record from the database.
174
175 =cut
176
177 =item replace OLD_RECORD
178
179 Replaces the OLD_RECORD with this one in the database.  If there is an error,
180 returns the error, otherwise returns false.
181
182 =cut
183
184 =item check
185
186 Checks all fields to make sure this is a valid voided invoice.  If there is
187 an error, returns the error, otherwise returns false.  Called by the insert
188 and replace methods.
189
190 =cut
191
192 sub check {
193   my $self = shift;
194
195   my $error = 
196     $self->ut_number('invnum')
197     || $self->ut_foreign_key('custnum', 'cust_main', 'custnum' )
198     || $self->ut_numbern('_date')
199     || $self->ut_money('charged')
200     || $self->ut_textn('invoice_terms')
201     || $self->ut_moneyn('previous_balance')
202     || $self->ut_moneyn('billing_balance')
203     || $self->ut_enum('closed', [ '', 'Y' ])
204     || $self->ut_foreign_keyn('statementnum', 'cust_statement', 'statementnum')
205     || $self->ut_numbern('agent_invid')
206     || $self->ut_numbern('promised_date')
207     || $self->ut_numbern('void_date')
208     || $self->ut_textn('reason')
209     || $self->ut_numbern('void_usernum')
210   ;
211   return $error if $error;
212
213   $self->void_date(time) unless $self->void_date;
214
215   $self->void_usernum($FS::CurrentUser::CurrentUser->usernum)
216     unless $self->void_usernum;
217
218   $self->SUPER::check;
219 }
220
221 =item display_invnum
222
223 Returns the displayed invoice number for this invoice: agent_invid if
224 cust_bill-default_agent_invid is set and it has a value, invnum otherwise.
225
226 =cut
227
228 sub display_invnum {
229   my $self = shift;
230   my $conf = $self->conf;
231   if ( $conf->exists('cust_bill-default_agent_invid') && $self->agent_invid ){
232     return $self->agent_invid;
233   } else {
234     return $self->invnum;
235   }
236 }
237
238 =item void_access_user
239
240 Returns the voiding employee object (see L<FS::access_user>).
241
242 =cut
243
244 sub void_access_user {
245   my $self = shift;
246   qsearchs('access_user', { 'usernum' => $self->void_usernum } );
247 }
248
249 =item cust_main
250
251 =cut
252
253 sub cust_main {
254   my $self = shift;
255   qsearchs('cust_main', { 'custnum' => $self->custnum } );
256 }
257
258 =item cust_bill_pkg
259
260 =cut
261
262 sub cust_bill_pkg { #actually cust_bill_pkg_void objects
263   my $self = shift;
264   qsearch('cust_bill_pkg_void', { invnum=>$self->invnum });
265 }
266
267 =back
268
269 =item enable_previous
270
271 =cut
272
273 sub enable_previous { 0 }
274
275 =back
276
277 =head1 BUGS
278
279 =head1 SEE ALSO
280
281 L<FS::Record>, schema.html from the base documentation.
282
283 =cut
284
285 1;
286