2 use base qw( FS::svc_External_Common );
6 use FS::Record qw( qsearch qsearchs dbh );
14 FS::svc_pbx - Object methods for svc_pbx records
20 $record = new FS::svc_pbx \%hash;
21 $record = new FS::svc_pbx { 'column' => 'value' };
23 $error = $record->insert;
25 $error = $new_record->replace($old_record);
27 $error = $record->delete;
29 $error = $record->check;
31 $error = $record->suspend;
33 $error = $record->unsuspend;
35 $error = $record->cancel;
39 An FS::svc_pbx object represents a PBX tenant. FS::svc_pbx inherits from
40 FS::svc_Common. The following fields are currently supported:
46 Primary key (assigned automatcially for new accounts)
50 (Unique?) number of external record
58 Maximum number of extensions
60 =item max_simultaneous
62 Maximum number of simultaneous users
72 Creates a new PBX tenant. To add the PBX tenant to the database, see
75 Note that this stores the hash reference, not a distinct copy of the hash it
76 points to. You can ask the object for a copy with the I<hash> method.
80 sub table { 'svc_pbx'; }
84 tie my %fields, 'Tie::IxHash',
86 'id' => 'PBX/Tenant ID',
88 'max_extensions' => 'Maximum number of User Extensions',
89 'max_simultaneous' => 'Maximum number of simultaneous users',
94 'name_plural' => 'PBXs',
95 'lcname_plural' => 'PBXs',
96 'longname_plural' => 'PBXs',
97 'sorts' => 'svcnum', # optional sort field (or arrayref of sort fields, main first)
98 'display_weight' => 70,
99 'cancel_weight' => 90,
100 'fields' => \%fields,
104 =item search_sql STRING
106 Class method which returns an SQL fragment to search for the given string.
111 #or something more complicated if necessary
113 # my($class, $string) = @_;
114 # $class->search_sql_field('title', $string);
119 Returns the title field for this PBX tenant.
130 Adds this record to the database. If there is an error, returns the error,
131 otherwise returns false.
133 The additional fields pkgnum and svcpart (see L<FS::cust_svc>) should be
134 defined. An FS::cust_svc record will be created and inserted.
142 $error = $self->SUPER::insert;
143 return $error if $error;
150 Delete this record from the database.
157 local $SIG{HUP} = 'IGNORE';
158 local $SIG{INT} = 'IGNORE';
159 local $SIG{QUIT} = 'IGNORE';
160 local $SIG{TERM} = 'IGNORE';
161 local $SIG{TSTP} = 'IGNORE';
162 local $SIG{PIPE} = 'IGNORE';
164 my $oldAutoCommit = $FS::UID::AutoCommit;
165 local $FS::UID::AutoCommit = 0;
168 foreach my $svc_phone (qsearch('svc_phone', { 'pbxsvc' => $self->svcnum } )) {
169 $svc_phone->pbxsvc('');
170 my $error = $svc_phone->replace;
172 $dbh->rollback if $oldAutoCommit;
177 foreach my $svc_acct (qsearch('svc_acct', { 'pbxsvc' => $self->svcnum } )) {
178 my $error = $svc_acct->delete;
180 $dbh->rollback if $oldAutoCommit;
185 my $error = $self->SUPER::delete;
187 $dbh->rollback if $oldAutoCommit;
191 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
196 =item replace OLD_RECORD
198 Replaces the OLD_RECORD with this one in the database. If there is an error,
199 returns the error, otherwise returns false.
204 # my ( $new, $old ) = ( shift, shift );
207 # $error = $new->SUPER::replace($old);
208 # return $error if $error;
215 Called by the suspend method of FS::cust_pkg (see L<FS::cust_pkg>).
219 Called by the unsuspend method of FS::cust_pkg (see L<FS::cust_pkg>).
223 Called by the cancel method of FS::cust_pkg (see L<FS::cust_pkg>).
227 Checks all fields to make sure this is a valid PBX tenant. If there is
228 an error, returns the error, otherwise returns false. Called by the insert
236 my $x = $self->setfixed;
237 return $x unless ref($x);
244 sub _check_duplicate {
247 my $conf = new FS::Conf;
251 foreach my $field ('title', 'id') {
252 my $global_unique = $conf->config("global_unique-pbx_$field");
253 # can be 'disabled', 'enabled', or empty.
254 # if empty, check per exports; if not empty or disabled, check
256 next if $global_unique eq 'disabled';
257 my @dup = $self->find_duplicates(
258 ($global_unique ? 'global' : 'export') , $field
261 return "duplicate $field '".$self->getfield($field).
262 "': conflicts with svcnum ".$dup[0]->svcnum;
269 Returns a set of Call Detail Records (see L<FS::cdr>) associated with this
270 service. By default, "associated with" means that the "charged_party" field of
271 the CDR matches the "title" field of the service.
275 Accepts the following options:
277 =item for_update => 1: SELECT the CDRs "FOR UPDATE".
279 =item status => "" (or "done"): Return only CDRs with that processing status.
281 =item inbound => 1: No-op for svc_pbx CDR processing.
283 =item default_prefix => "XXX": Also accept the phone number of the service prepended
284 with the chosen prefix.
286 =item disable_src => 1: No-op for svc_pbx CDR processing.
288 =item by_svcnum => 1: Select CDRs where the svcnum field matches, instead of
289 title/charged_party. Normally this field is set after processing.
291 =item begin, end: Start and end of date range, as unix timestamp.
293 =item cdrtypenum: Only return CDRs with this type number.
300 my($self, %options) = @_;
304 my @fields = ( 'charged_party' );
305 $hash{'freesidestatus'} = $options{'status'}
306 if exists($options{'status'});
308 if ($options{'cdrtypenum'}) {
309 $hash{'cdrtypenum'} = $options{'cdrtypenum'};
312 my $for_update = $options{'for_update'} ? 'FOR UPDATE' : '';
314 if ( $options{'by_svcnum'} ) {
315 $hash{'svcnum'} = $self->svcnum;
319 my $title = $self->title;
321 my $prefix = $options{'default_prefix'};
323 my @orwhere = map " $_ = '$title' ", @fields;
324 push @orwhere, map " $_ = '$prefix$title' ", @fields
326 if ( $prefix =~ /^\+(\d+)$/ ) {
327 push @orwhere, map " $_ = '$1$title' ", @fields
330 push @where, ' ( '. join(' OR ', @orwhere ). ' ) ';
333 if ( $options{'begin'} ) {
334 push @where, 'startdate >= '. $options{'begin'};
336 if ( $options{'end'} ) {
337 push @where, 'startdate < '. $options{'end'};
340 my $extra_sql = ( keys(%hash) ? ' AND ' : ' WHERE ' ). join(' AND ', @where )
347 'extra_sql' => $extra_sql,
348 'order_by' => "ORDER BY startdate $for_update",
360 L<FS::svc_Common>, L<FS::Record>, L<FS::cust_svc>, L<FS::part_svc>,
361 L<FS::cust_pkg>, schema.html from the base documentation.