add skip_dcontext_suffix to skip CDRs with dcontext ending in a definable string...
[freeside.git] / FS / FS / cgp_rule.pm
1 package FS::cgp_rule;
2 use base qw( FS::o2m_Common FS::Record );
3
4 use strict;
5 use FS::Record qw( dbh );
6
7 =head1 NAME
8
9 FS::cgp_rule - Object methods for cgp_rule records
10
11 =head1 SYNOPSIS
12
13   use FS::cgp_rule;
14
15   $record = new FS::cgp_rule \%hash;
16   $record = new FS::cgp_rule { '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::cgp_rule object represents a mail filtering rule.  FS::cgp_rule
29 inherits from FS::Record.  The following fields are currently supported:
30
31 =over 4
32
33 =item rulenum
34
35 primary key
36
37 =item name
38
39 name
40
41 =item comment
42
43 comment
44
45 =item svcnum
46
47 svcnum
48
49 =item priority
50
51 priority
52
53
54 =back
55
56 =head1 METHODS
57
58 =over 4
59
60 =item new HASHREF
61
62 Creates a new rule.  To add the rule to the database, see L<"insert">.
63
64 Note that this stores the hash reference, not a distinct copy of the hash it
65 points to.  You can ask the object for a copy with the I<hash> method.
66
67 =cut
68
69 # the new method can be inherited from FS::Record, if a table method is defined
70
71 sub table { 'cgp_rule'; }
72
73 =item insert
74
75 Adds this record to the database.  If there is an error, returns the error,
76 otherwise returns false.
77
78 =cut
79
80 #  sub insert {
81 #    my $self = shift;
82 #  
83 #    local $SIG{HUP} = 'IGNORE';
84 #    local $SIG{INT} = 'IGNORE';
85 #    local $SIG{QUIT} = 'IGNORE';
86 #    local $SIG{TERM} = 'IGNORE';
87 #    local $SIG{TSTP} = 'IGNORE';
88 #    local $SIG{PIPE} = 'IGNORE';
89 #  
90 #    my $oldAutoCommit = $FS::UID::AutoCommit;
91 #    local $FS::UID::AutoCommit = 0;
92 #    my $dbh = dbh;
93 #  
94 #    my $error = $self->SUPER::insert(@_);
95 #    if ( $error ) {
96 #      $dbh->rollback if $oldAutoCommit;
97 #      return $error;
98 #    }
99 #  
100 #    #conditions and actions not in yet
101 #    #$error = $self->svc_export;
102 #    #if ( $error ) {
103 #    #  $dbh->rollback if $oldAutoCommit;
104 #    #  return $error;
105 #    #}
106 #  
107 #    $dbh->commit or die $dbh->errstr if $oldAutoCommit;
108 #    '';
109 #  }
110
111 =item delete
112
113 Delete this record from the database.
114
115 =cut
116
117 sub delete {
118   my $self = shift;
119
120   local $SIG{HUP} = 'IGNORE';
121   local $SIG{INT} = 'IGNORE';
122   local $SIG{QUIT} = 'IGNORE';
123   local $SIG{TERM} = 'IGNORE';
124   local $SIG{TSTP} = 'IGNORE';
125   local $SIG{PIPE} = 'IGNORE';
126
127   my $oldAutoCommit = $FS::UID::AutoCommit;
128   local $FS::UID::AutoCommit = 0;
129   my $dbh = dbh;
130
131   my @del = $self->cgp_rule_condition;
132   push @del, $self->cgp_rule_action;
133
134   foreach my $del (@del) {
135     my $error = $del->delete;
136     if ( $error ) {
137       $dbh->rollback if $oldAutoCommit;
138       return $error;
139     }
140   }
141
142   my $error = $self->SUPER::delete(@_);
143   if ( $error ) {
144     $dbh->rollback if $oldAutoCommit;
145     return $error;
146   }
147
148   $error = $self->svc_export;
149   if ( $error ) {
150     $dbh->rollback if $oldAutoCommit;
151     return $error;
152   }
153
154   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
155   '';
156 }
157
158 =item replace OLD_RECORD
159
160 Replaces the OLD_RECORD with this one in the database.  If there is an error,
161 returns the error, otherwise returns false.
162
163 =cut
164
165 sub replace {
166   my $new = shift;
167
168   my $old = ( ref($_[0]) eq ref($new) )
169               ? shift
170               : $new->replace_old;
171
172   local $SIG{HUP} = 'IGNORE';
173   local $SIG{INT} = 'IGNORE';
174   local $SIG{QUIT} = 'IGNORE';
175   local $SIG{TERM} = 'IGNORE';
176   local $SIG{TSTP} = 'IGNORE';
177   local $SIG{PIPE} = 'IGNORE';
178
179   my $oldAutoCommit = $FS::UID::AutoCommit;
180   local $FS::UID::AutoCommit = 0;
181   my $dbh = dbh;
182
183   my $error = $new->SUPER::replace($old, @_);
184   if ( $error ) {
185     $dbh->rollback or die $dbh->errstr if $oldAutoCommit;
186     return $error;
187   }
188
189   #conditions and actions not in yet
190   #$error = $new->svc_export;
191   #if ( $error ) {
192   #  $dbh->rollback if $oldAutoCommit;
193   #  return $error;
194   #}
195
196   $dbh->commit or die $dbh->errstr if $oldAutoCommit;
197   '';
198
199 }
200
201 =item svc_export
202
203 Calls the replace export for any communigate exports attached to this rule's
204 service.
205
206 =cut
207
208 sub svc_export {
209   my $self = shift;
210
211   my $cust_svc = $self->cust_svc;
212   my $svc_x = $cust_svc->svc_x;
213   
214   #_singledomain too
215   my @exports = $cust_svc->part_svc->part_export('communigate_pro');
216   my @errors = map $_->export_replace($svc_x, $svc_x), @exports;
217
218   @errors ? join(' / ', @errors) : '';
219
220 }
221
222 =item check
223
224 Checks all fields to make sure this is a valid rule.  If there is
225 an error, returns the error, otherwise returns false.  Called by the insert
226 and replace methods.
227
228 =cut
229
230 # the check method should currently be supplied - FS::Record contains some
231 # data checking routines
232
233 sub check {
234   my $self = shift;
235
236   my $error = 
237     $self->ut_numbern('rulenum')
238     || $self->ut_text('name')
239     || $self->ut_textn('comment')
240     || $self->ut_foreign_key('svcnum', 'cust_svc', 'svcnum')
241     || $self->ut_number('priority')
242   ;
243   return $error if $error;
244
245   $self->SUPER::check;
246 }
247
248 =item clone NEW_SVCNUM
249
250 Clones this rule into an identical rule for the specified new service.
251
252 If there is an error, returns the error, otherwise returns false.
253
254 =cut
255
256 #should return the newly inserted rule instead? used in misc/clone-cgp_rule.html
257
258 #i should probably be transactionalized so i'm all-or-nothing
259 sub clone {
260   my( $self, $svcnum ) = @_;
261
262   my $new = $self->new( { $self->hash } );
263   $new->rulenum('');
264   $new->svcnum( $svcnum );
265   my $error = $new->insert;
266   return $error if $error;
267
268   my @dup = $self->cgp_rule_condition;
269   push @dup, $self->cgp_rule_action;
270
271   foreach my $dup (@dup) {
272     my $new_dup = $dup->new( { $dup->hash } );
273     my $pk = $new_dup->primary_key;
274     $new_dup->$pk('');
275     $new_dup->rulenum( $new->rulenum );
276
277     $error = $new_dup->insert;
278     return $error if $error;
279
280   }
281
282   $error = $new->svc_export;
283   return $error if $error;
284
285   '';
286
287 }
288
289 =item cust_svc
290
291 =item cgp_rule_condition
292
293 Returns the conditions associated with this rule, as FS::cgp_rule_condition
294 objects.
295
296 =item arrayref
297
298 Returns an arraref representing this rule, suitable for Communigate Pro API
299 commands:
300
301 The first element specifies the rule priority.
302
303 The second element specifies the rule name.
304
305 The third element specifies the rule conditions.
306
307 The fourth element specifies the rule actions.
308
309 The fifth element specifies the rule comment.
310
311 =cut
312
313 sub arrayref {
314   my $self = shift;
315   [ $self->priority,
316     $self->name,
317     [ map $_->arrayref, $self->cgp_rule_condition ],
318     [ map $_->arrayref, $self->cgp_rule_action ],
319     $self->comment,
320   ],
321 }
322
323 =back
324
325 =head1 BUGS
326
327 =head1 SEE ALSO
328
329 L<FS::Record>, schema.html from the base documentation.
330
331 =cut
332
333 1;
334