package FS::svc_acct;
use strict;
-use vars qw( @ISA $noexport_hack $conf
+use vars qw( @ISA $DEBUG $me $conf
$dir_prefix @shells $usernamemin
$usernamemax $passwordmin $passwordmax
$username_ampersand $username_letter $username_letterfirst
$username_noperiod $username_nounderscore $username_nodash
$username_uppercase
+ $mydomain
$welcome_template $welcome_from $welcome_subject $welcome_mimetype
$smtpmachine
$radius_password
use FS::Conf;
use FS::Record qw( qsearch qsearchs fields dbh );
use FS::svc_Common;
+use Net::SSH;
use FS::cust_svc;
use FS::part_svc;
use FS::svc_acct_pop;
+use FS::svc_acct_sm;
use FS::cust_main_invoice;
use FS::svc_domain;
use FS::raddb;
@ISA = qw( FS::svc_Common );
+$DEBUG = 0;
+$me = '[FS::svc_acct]';
+
#ask FS::UID to run this stuff for us later
$FS::UID::callback{'FS::svc_acct'} = sub {
$conf = new FS::Conf;
$username_nodash = $conf->exists('username-nodash');
$username_uppercase = $conf->exists('username-uppercase');
$username_ampersand = $conf->exists('username-ampersand');
+ $mydomain = $conf->config('domain');
$dirhash = $conf->config('dirhash') || 0;
if ( $conf->exists('welcome_email') ) {
$welcome_template = new Text::Template (
$welcome_mimetype = $conf->config('welcome_email-mimetype') || 'text/plain';
} else {
$welcome_template = '';
+ $welcome_from = '';
+ $welcome_subject = '';
+ $welcome_mimetype = '';
}
$smtpmachine = $conf->config('smtpmachine');
$radius_password = $conf->config('radius-password') || 'Password';
(TODOC: L<FS::queue> and L<freeside-queued>)
-(TODOC: new exports! $noexport_hack)
+(TODOC: new exports!)
=cut
# qsearch('export_svc', { 'exportnum' => $part_export->exportnum });
#}
- my $nodomain = $exports->{$part_export->exporttype}{'nodomain'};
+ #my $nodomain = $exports->{$part_export->exporttype}{'nodomain'};
+ #silly kludge to avoid uninitialized value errors
+ my $nodomain = exists( $exports->{$part_export->exporttype}{'nodomain'} )
+ ? $exports->{$part_export->exporttype}{'nodomain'}
+ : '';
if ( $nodomain =~ /^Y/i ) {
$conflict_user_svcpart{$_} = $part_export->exportnum
foreach @svcparts;
'svcnum' => $self->svcnum,
'job' => 'FS::svc_acct::send_email'
};
- warn "attempting to queue email to $to";
my $error = $wqueue->insert(
'to' => $to,
'from' => $welcome_from,
'subject' => $welcome_subject,
'mimetype' => $welcome_mimetype,
'body' => $welcome_template->fill_in( HASH => {
+ 'custnum' => $self->custnum,
'username' => $self->username,
'password' => $self->_password,
'first' => $cust_main->first,
);
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
- return "queuing welcome email: $error";
+ return "error queuing welcome email: $error";
}
foreach my $jobnum ( @jobnums ) {
my $error = $wqueue->depend_insert($jobnum);
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
- return "queuing welcome email job dependancy: $error";
+ return "error queuing welcome email job dependancy: $error";
}
}
The corresponding FS::cust_svc record will be deleted as well.
-(TODOC: new exports! $noexport_hack)
+(TODOC: new exports!)
=cut
sub delete {
my $self = shift;
+ if ( defined( $FS::Record::dbdef->table('svc_acct_sm') ) ) {
+ return "Can't delete an account which has (svc_acct_sm) mail aliases!"
+ if $self->uid && qsearch( 'svc_acct_sm', { 'domuid' => $self->uid } );
+ }
+
return "Can't delete an account which is a (svc_forward) source!"
if qsearch( 'svc_forward', { 'srcsvc' => $self->svcnum } );
sub replace {
my ( $new, $old ) = ( shift, shift );
my $error;
+ warn "$me replacing $old with $new\n" if $DEBUG;
return "Username in use"
if $old->username ne $new->username &&
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
+ # redundant, but so $new->usergroup gets set
+ $error = $new->check;
+ return $error if $error;
+
$old->usergroup( [ $old->radius_groups ] );
+ warn "old groups: ". join(' ',@{$old->usergroup}). "\n" if $DEBUG;
+ warn "new groups: ". join(' ',@{$new->usergroup}). "\n" if $DEBUG;
if ( $new->usergroup ) {
#(sorta) false laziness with FS::part_export::sqlradius::_export_replace
my @newgroups = @{$new->usergroup};
return $error if $error;
}
- #false laziness with sub insert (and cust_main)
- my $queue = new FS::queue {
- 'svcnum' => $new->svcnum,
- 'job' => 'FS::svc_acct::append_fuzzyfiles'
- };
- $error = $queue->insert($new->username);
- if ( $error ) {
- $dbh->rollback if $oldAutoCommit;
- return "queueing job (transaction rolled back): $error";
+ if ( $new->username ne $old->username ) {
+ #false laziness with sub insert (and cust_main)
+ my $queue = new FS::queue {
+ 'svcnum' => $new->svcnum,
+ 'job' => 'FS::svc_acct::append_fuzzyfiles'
+ };
+ $error = $queue->insert($new->username);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "queueing job (transaction rolled back): $error";
+ }
}
-
$dbh->commit or die $dbh->errstr if $oldAutoCommit;
''; #no error
}
}
my $error = $self->ut_numbern('svcnum')
- || $self->ut_number('domsvc')
+ #|| $self->ut_number('domsvc')
+ || $self->ut_foreign_key('domsvc', 'svc_domain', 'svcnum' )
|| $self->ut_textn('sec_phrase')
;
return $error if $error;
unless ( $part_svc->part_svc_column('slipip')->columnflag eq 'F' ) {
unless ( $recref->{slipip} eq '0e0' ) {
$recref->{slipip} =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/
- or return "Illegal slipip: ". $self->slipip;
+ or return "Illegal slipip". $self->slipip;
$recref->{slipip} = $1;
} else {
$recref->{slipip} = '0e0';
my $self = shift;
my $password = $self->_password;
my $pw_attrib = length($password) <= 12 ? $radius_password : 'Crypt-Password';
- ( $pw_attrib => $password,
+ ( $pw_attrib => $self->_password,
map {
/^(rc_(.*))$/;
my($column, $attrib) = ($1, $2);
sub domain {
my $self = shift;
- die "svc_acct.domsvc is null for svcnum ". $self->svcnum unless $self->domsvc;
- my $svc_domain = $self->svc_domain
- or die "no svc_domain.svcnum for svc_acct.domsvc ". $self->domsvc;
- $svc_domain->domain;
+ if ( $self->domsvc ) {
+ #$self->svc_domain->domain;
+ my $svc_domain = $self->svc_domain
+ or die "no svc_domain.svcnum for svc_acct.domsvc ". $self->domsvc;
+ $svc_domain->domain;
+ } else {
+ $mydomain or die "svc_acct.domsvc is null and no legacy domain config file";
+ }
}
=item svc_domain
started in the specified range but are still open are counted from session
start to the end of the range (unless they are over 1 day old, in which case
they are presumed missing their stop record and not counted). Also, sessions
-which end in therange but started earlier are counted from the start of the
+which end in the range but started earlier are counted from the start of the
range to session end. Finally, sessions which start before the range but end
after are counted for the entire range.
$self->cust_svc->seconds_since_sqlradacct(@_);
}
+=item attribute_since_sqlradacct TIMESTAMP_START TIMESTAMP_END ATTRIBUTE
+
+Returns the sum of the given attribute for all accounts (see L<FS::svc_acct>)
+in this package for sessions ending between TIMESTAMP_START (inclusive) and
+TIMESTAMP_END (exclusive).
+
+TIMESTAMP_START and TIMESTAMP_END are specified as UNIX timestamps; see
+L<perlfunc/"time">. Also see L<Time::Local> and L<Date::Parse> for conversion
+functions.
+
+=cut
+
+#note: POD here, implementation in FS::cust_svc
+sub attribute_since_sqlradacct {
+ my $self = shift;
+ $self->cust_svc->attribute_since_sqlradacct(@_);
+}
+
+
=item radius_groups
Returns all RADIUS groups for this account (see L<FS::radius_usergroup>).
L<FS::svc_Common>, edit/part_svc.cgi from an installed web interface,
export.html from the base documentation, L<FS::Record>, L<FS::Conf>,
L<FS::cust_svc>, L<FS::part_svc>, L<FS::cust_pkg>, L<FS::queue>,
-L<freeside-queued>), L<FS::svc_acct_pop>,
+L<freeside-queued>), L<Net::SSH>, L<ssh>, L<FS::svc_acct_pop>,
schema.html from the base documentation.
=cut