random indentation fix
[freeside.git] / FS / FS / svc_acct_rt_transaction.pm
1 package FS::svc_acct_rt_transaction;
2
3 use strict;
4 use vars qw( @ISA );
5 use FS::Record qw( qsearch qsearchs dbh );
6
7 @ISA = qw(FS::Record);
8
9 =head1 NAME
10
11 FS::svc_acct_rt_transaction - Object methods for svc_acct_rt_transaction records
12
13 =head1 SYNOPSIS
14
15   use FS::svc_acct_rt_transaction;
16
17   $record = new FS::svc_acct_rt_transaction \%hash;
18   $record = new FS::svc_acct_rt_transaction { 'column' => 'value' };
19
20   $error = $record->insert;
21
22   $error = $new_record->replace($old_record);
23
24   $error = $record->delete;
25
26   $error = $record->check;
27
28 =head1 DESCRIPTION
29
30 An FS::svc_acct_rt_transaction object represents an application of time
31 from a rt transaction to a svc_acct.  FS::svc_acct_rt_transaction inherits from
32 FS::Record.  The following fields are currently supported:
33
34 =over 4
35
36 =item svcrtid - primary key
37
38 =item svcnum -  the svcnum of the svc_acct to which the time applies
39
40 =item transaction_id -  the id of the rt transtaction from which the time applies
41
42 =item seconds - the amount of time which applies
43
44
45 =back
46
47 =head1 METHODS
48
49 =over 4
50
51 =item new HASHREF
52
53 Creates a new svc_acct_rt_transaction.  To add the example to the database, see L<"insert">.
54
55 Note that this stores the hash reference, not a distinct copy of the hash it
56 points to.  You can ask the object for a copy with the I<hash> method.
57
58 =cut
59
60 sub table { 'svc_acct_rt_transaction'; }
61
62 =item insert
63
64 Adds this record to the database.  If there is an error, returns the error,
65 otherwise returns false.
66
67 =cut
68
69 sub insert {
70   my( $self, %options ) = @_;
71   
72   local $SIG{HUP} = 'IGNORE';
73   local $SIG{INT} = 'IGNORE';
74   local $SIG{QUIT} = 'IGNORE';
75   local $SIG{TERM} = 'IGNORE';
76   local $SIG{TSTP} = 'IGNORE';
77   local $SIG{PIPE} = 'IGNORE';
78
79   my $oldAutoCommit = $FS::UID::AutoCommit;
80   local $FS::UID::AutoCommit = 0;
81   my $dbh = dbh;
82
83   my $error = $self->SUPER::insert($options{options} ? %{$options{options}} : ());
84   if ( $error ) {
85     $dbh->rollback if $oldAutoCommit;
86     return $error;
87   }
88
89   my $svc_acct = qsearchs('svc_acct', {'svcnum' => $self->svcnum});
90   unless ($svc_acct) {
91     $dbh->rollback if $oldAutoCommit;
92     return "Can't find svc_acct " . $self->svcnum;
93   }
94
95   my $error = $svc_acct->decrement_seconds($self->seconds);
96   if ( $error ) {
97     $dbh->rollback if $oldAutoCommit;
98     return "Error incrementing service seconds: $error";
99   }
100   
101   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
102   '';
103
104 }
105
106
107 =item delete
108
109 Delete this record from the database.
110
111 =cut
112
113 sub delete { 
114   my $self = shift;
115
116   local $SIG{HUP} = 'IGNORE';
117   local $SIG{INT} = 'IGNORE';
118   local $SIG{QUIT} = 'IGNORE';
119   local $SIG{TERM} = 'IGNORE';
120   local $SIG{TSTP} = 'IGNORE';
121   local $SIG{PIPE} = 'IGNORE';
122
123   my $oldAutoCommit = $FS::UID::AutoCommit;
124   local $FS::UID::AutoCommit = 0;
125   my $dbh = dbh;
126
127   my $error = $self->SUPER::delete;
128   if ( $error ) {
129     $dbh->rollback if $oldAutoCommit;
130     return $error;
131   }
132
133   my $svc_acct = qsearchs('svc_acct', {'svcnum' => $self->svcnum});
134   unless ($svc_acct) {
135     $dbh->rollback if $oldAutoCommit;
136     return "Can't find svc_acct " . $self->svcnum;
137   }
138
139   my $error = $svc_acct->increment_seconds($self->seconds);
140   if ( $error ) {
141     $dbh->rollback if $oldAutoCommit;
142     return "Error incrementing service seconds: $error";
143   }
144   
145   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
146   '';
147
148 }
149
150 =item replace OLD_RECORD
151
152 Replaces the OLD_RECORD with this one in the database.  If there is an error,
153 returns the error, otherwise returns false.
154
155 =cut
156
157 =item check
158
159 Checks all fields to make sure this is a valid svc_acct_rt_transaction.  If there is
160 an error, returns the error, otherwise returns false.  Called by the insert
161 and replace methods.
162
163 =cut
164
165 sub check {
166   my $self = shift;
167
168   my ($selfref) = $self->hashref;
169
170   my $error = 
171     $self->ut_numbern('svcrtid')
172     || $self->ut_numbern('svcnum')
173     || $self->ut_number('transaction_id')
174     || $self->ut_numbern('_date')
175     || $self->ut_snumber('seconds')
176   ;
177   return $error if $error;
178
179   $self->_date(time) unless $self->_date;
180
181   if ($selfref->{custnum}) {
182     my $conf = new FS::Conf;
183     my %packages = map { $_ => 1 } $conf->config('support_packages');
184     my $cust_main = qsearchs('cust_main',{ 'custnum' => $selfref->{custnum} } );
185     return "Invalid custnum: " . $selfref->{custnum} unless $cust_main;
186
187     my (@svcs) = map { $_->svcnum } $cust_main->support_services;
188     return "svcnum ". $self->svcnum. " invalid for custnum ".$selfref->{custnum}
189       unless (!$self->svcnum || scalar(grep { $_ == $self->svcnum } @svcs));
190
191     $self->svcnum($svcs[0]) unless $self->svcnum;
192     return "Can't find support service for custnum ".$selfref->{custnum}
193       unless $self->svcnum;
194   }
195
196   $self->SUPER::check;
197 }
198
199 =item batch_insert SVC_ACCT_RT_TRANSACTION_OBJECT, ...
200
201 Class method which inserts multiple time applications.  Takes a list of
202 FS::svc_acct_rt_transaction objects.  If there is an error inserting any
203 application, the entire transaction is rolled back, i.e. all time is applied
204 or none is.
205
206 For example:
207
208   my $errors = FS::svc_acct_rt_transaction->batch_insert(@transactions);
209   if ( $error ) {
210     #success; all payments were inserted
211   } else {
212     #failure; no payments were inserted.
213   }
214
215 =cut
216
217 sub batch_insert {
218   my $self = shift; #class method
219
220   local $SIG{HUP} = 'IGNORE';
221   local $SIG{INT} = 'IGNORE';
222   local $SIG{QUIT} = 'IGNORE';
223   local $SIG{TERM} = 'IGNORE';
224   local $SIG{TSTP} = 'IGNORE';
225   local $SIG{PIPE} = 'IGNORE';
226
227   my $oldAutoCommit = $FS::UID::AutoCommit;
228   local $FS::UID::AutoCommit = 0;
229   my $dbh = dbh;
230
231   my $error;
232   foreach (@_) {
233     $error = $_->insert;
234     last if $error;
235   }
236
237   if ( $error ) {
238     $dbh->rollback if $oldAutoCommit;
239   } else {
240     $dbh->commit or die $dbh->errstr if $oldAutoCommit;
241   }
242
243   $error;
244
245 }
246
247 =back
248
249 =head1 BUGS
250
251 Possibly the delete method or others.
252
253 =head1 SEE ALSO
254
255 L<FS::Record>, schema.html from the base documentation.
256
257 =cut
258
259 1;
260