package FS::svc_phone;
+use base qw( FS::svc_Domain_Mixin FS::svc_PBX_Mixin
+ FS::location_Mixin
+ FS::svc_Common
+ );
use strict;
-use base qw( FS::svc_Domain_Mixin FS::location_Mixin FS::svc_Common );
-use vars qw( $DEBUG $me @pw_set $conf $phone_name_max );
+use vars qw( $DEBUG $me @pw_set $conf $phone_name_max
+ $passwordmin $passwordmax
+ );
use Data::Dumper;
use Scalar::Util qw( blessed );
+use List::Util qw( min );
use FS::Conf;
use FS::Record qw( qsearch qsearchs dbh );
use FS::PagedSearch qw( psearch );
use FS::Msgcat qw(gettext);
use FS::part_svc;
-use FS::phone_device;
use FS::svc_pbx;
use FS::svc_domain;
use FS::cust_location;
FS::UID->install_callback( sub {
$conf = new FS::Conf;
$phone_name_max = $conf->config('svc_phone-phone_name-max_length');
+ $passwordmin = $conf->config('sip_passwordmin') || 0;
+ $passwordmax = $conf->config('sip_passwordmax') || 80;
}
);
select_label => 'domain',
disable_inventory => 1,
},
+ 'sms_carrierid' => { label => 'SMS Carrier',
+ type => 'select',
+ select_table => 'cdr_carrier',
+ select_key => 'carrierid',
+ select_label => 'carriername',
+ disable_inventory => 1,
+ },
+ 'sms_account' => { label => 'SMS Carrier Account', },
+ 'max_simultaneous' => { label=>'Maximum number of simultaneous users' },
'locationnum' => {
label => 'E911 location',
disable_inventory => 1,
sub search_sql {
my( $class, $string ) = @_;
- my $conf = new FS::Conf;
+ #my $conf = new FS::Conf;
if ( $conf->exists('svc_phone-allow_alpha_phonenum') ) {
$string =~ s/\W//g;
#false laziness w/cust_pkg.pm... move this to location_Mixin? that would
#make it more of a base class than a mixin... :)
- if ( $options{'cust_location'}
- && ( ! $self->locationnum || $self->locationnum == -1 ) ) {
- my $error = $options{'cust_location'}->insert;
+ if ( $options{'cust_location'} ) {
+ my $error = $options{'cust_location'}->find_or_insert;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return "inserting cust_location (transaction rolled back): $error";
}
-# the delete method can be inherited from FS::Record
-
=item replace OLD_RECORD
Replaces the OLD_RECORD with this one in the database. If there is an error,
sub check {
my $self = shift;
- my $conf = new FS::Conf;
+ #my $conf = new FS::Conf;
+
+ my $x = $self->setfixed;
+ return $x unless ref($x);
+ my $part_svc = $x;
my $phonenum = $self->phonenum;
my $phonenum_check_method;
|| $self->ut_textn('phone_name')
|| $self->ut_foreign_keyn('pbxsvc', 'svc_pbx', 'svcnum' )
|| $self->ut_foreign_keyn('domsvc', 'svc_domain', 'svcnum' )
+ || $self->ut_foreign_keyn('sms_carrierid', 'cdr_carrier', 'carrierid' )
+ || $self->ut_alphan('sms_account')
+ || $self->ut_numbern('max_simultaneous')
|| $self->ut_foreign_keyn('locationnum', 'cust_location', 'locationnum')
|| $self->ut_numbern('forwarddst')
|| $self->ut_textn('email')
unless ( length($self->pin) ) {
my $random_pin = $conf->config('svc_phone-random_pin');
- if ( $random_pin =~ /^\d+$/ ) {
+ if ( defined($random_pin) && $random_pin =~ /^\d+$/ ) {
$self->pin(
join('', map int(rand(10)), 0..($random_pin-1))
);
}
}
- unless ( length($self->sip_password) ) { # option for this?
+ if ( length($self->sip_password) ) {
+
+ return "SIP password must be longer than $passwordmin characters"
+ if length($self->sip_password) < $passwordmin;
+ return "SIP password must be shorter than $passwordmax characters"
+ if length($self->sip_password) > $passwordmax;
+
+ } elsif ( $part_svc->part_svc_column('sip_password')->columnflag ne 'F' ) {
+ # option for this?
$self->sip_password(
- join('', map $pw_set[ int(rand $#pw_set) ], (0..16) )
+ join('', map $pw_set[ int(rand $#pw_set) ], (1..min($passwordmax,16)) )
);
}
my $self = shift;
my %check = ();
- my $conf = new FS::Conf;
+ #my $conf = new FS::Conf;
- $check{'User-Password'} = $conf->config('svc_phone-radius-default_password');
+ my $password;
+ if ( $conf->config('svc_phone-radius-password') eq 'countrycode_phonenum' ) {
+ $password = $self->countrycode. $self->phonenum;
+ } else {
+ $password = $conf->config('svc_phone-radius-default_password');
+ }
+ $check{'User-Password'} = $password;
%check;
}
();
}
-=item phone_device
+=item sms_cdr_carrier
-Returns any FS::phone_device records associated with this service.
+=cut
+
+sub sms_cdr_carrier {
+ my $self = shift;
+ return '' unless $self->sms_carrierid;
+ qsearchs('cdr_carrier', { 'carrierid' => $self->sms_carrierid } );
+}
+
+=item sms_carriername
=cut
-sub phone_device {
+sub sms_carriername {
my $self = shift;
- qsearch('phone_device', { 'svcnum' => $self->svcnum } );
+ my $cdr_carrier = $self->sms_cdr_carrier or return '';
+ $cdr_carrier->carriername;
}
+=item phone_device
+
+Returns any FS::phone_device records associated with this service.
+
+=cut
+
#override location_Mixin version cause we want to try the cust_pkg location
#in between us and cust_main
# XXX what to do in the unlinked case??? return a pseudo-object that returns
=item status => "" (or "processing-tiered", "done"): Return only CDRs with that processing status.
-=item inbound => 1: Return CDRs for inbound calls. With "status", will filter
-on inbound processing status.
+=item inbound => 1: Return CDRs for inbound calls (that is, those that match
+on 'dst'). With "status", will filter on inbound processing status.
=item default_prefix => "XXX": Also accept the phone number of the service prepended
with the chosen prefix.
=item calltypenum: Only return CDRs with this call type.
-=item disable_src => 1: Only match on "charged_party", not "src".
+=item disable_src => 1: Only match on 'charged_party', not 'src'.
+
+=item disable_charged_party => 1: Only match on 'src', not 'charged_party'.
=item nonzero: Only return CDRs where duration > 0.
} else {
- @fields = ( 'charged_party' );
- push @fields, 'src' if !$options{'disable_src'};
+ push @fields, 'charged_party' unless $options{'disable_charged_party'};
+ push @fields, 'src' unless $options{'disable_src'};
$hash{'freesidestatus'} = $options{'status'}
if exists($options{'status'});
}