$username_uppercase
$welcome_template $welcome_from $welcome_subject $welcome_mimetype
$smtpmachine
- $radius_password
+ $radius_password $radius_ip
$dirhash
@saltset @pw_set );
use Carp;
use Fcntl qw(:flock);
use FS::UID qw( datasrc );
use FS::Conf;
-use FS::Record qw( qsearch qsearchs fields dbh );
+use FS::Record qw( qsearch qsearchs fields dbh dbdef );
use FS::svc_Common;
use FS::cust_svc;
use FS::part_svc;
}
$smtpmachine = $conf->config('smtpmachine');
$radius_password = $conf->config('radius-password') || 'Password';
+ $radius_ip = $conf->config('radius-ip') || 'Framed-IP-Address';
};
@saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
contain an arrayref of group names. See L<FS::radius_usergroup>. (used in
sqlradius export only)
+The additional field I<child_objects> can optionally be defined; if so it
+should contain an arrayref of FS::tablename objects. They will have their
+svcnum fields set and will be inserted after this record, but before any
+exports are run.
+
(TODOC: L<FS::queue> and L<freeside-queued>)
(TODOC: new exports!)
+
=cut
sub insert {
# 'domsvc' => $self->domsvc,
# } );
- if ( $self->svcnum ) {
+ if ( $self->svcnum && qsearchs('cust_svc',{'svcnum'=>$self->svcnum}) ) {
my $cust_svc = qsearchs('cust_svc',{'svcnum'=>$self->svcnum});
unless ( $cust_svc ) {
$dbh->rollback if $oldAutoCommit;
#see? i told you it was more complicated
my @jobnums;
- $error = $self->SUPER::insert(\@jobnums);
+ $error = $self->SUPER::insert(\@jobnums, $self->child_objects || [] );
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return $error;
=item suspend
-Suspends this account by prefixing *SUSPENDED* to the password. If there is an
-error, returns the error, otherwise returns false.
+Suspends this account by calling export-specific suspend hooks. If there is
+an error, returns the error, otherwise returns false.
Called by the suspend method of FS::cust_pkg (see L<FS::cust_pkg>).
=item unsuspend
-Unsuspends this account by removing *SUSPENDED* from the password. If there is
-an error, returns the error, otherwise returns false.
+Unsuspends this account by by calling export-specific suspend hooks. If there
+is an error, returns the error, otherwise returns false.
Called by the unsuspend method of FS::cust_pkg (see L<FS::cust_pkg>).
}
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;
or return "Illegal finger: ". $self->getfield('finger');
$self->setfield('finger', $1);
- $recref->{quota} =~ /^(\d*)$/ or return "Illegal quota";
+ $recref->{quota} =~ /^(\w*)$/ or return "Illegal quota";
$recref->{quota} = $1;
unless ( $part_svc->part_svc_column('slipip')->columnflag eq 'F' ) {
- unless ( $recref->{slipip} eq '0e0' ) {
+ if ( $recref->{slipip} eq '' ) {
+ $recref->{slipip} = '';
+ } elsif ( $recref->{slipip} eq '0e0' ) {
+ $recref->{slipip} = '0e0';
+ } else {
$recref->{slipip} =~ /^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/
or return "Illegal slipip: ". $self->slipip;
$recref->{slipip} = $1;
- } else {
- $recref->{slipip} = '0e0';
}
}
#$recref->{password} = $1.
# crypt($3,$saltset[int(rand(64))].$saltset[int(rand(64))]
#;
- } elsif ( $recref->{_password} =~ /^((\*SUSPENDED\* )?)([\w\.\/\$\;\+]{13,34})$/ ) {
+ } elsif ( $recref->{_password} =~ /^((\*SUSPENDED\* )?)([\w\.\/\$\;\+]{13,60})$/ ) {
$recref->{_password} = $1.$3;
} elsif ( $recref->{_password} eq '*' ) {
$recref->{_password} = '*';
+ } elsif ( $recref->{_password} eq '!' ) {
+ $recref->{_password} = '!';
} elsif ( $recref->{_password} eq '!!' ) {
$recref->{_password} = '!!';
} else {
": ". $recref->{_password};
}
- ''; #no error
+ $self->SUPER::check;
}
=item radius
( $FS::raddb::attrib{lc($attrib)}, $self->getfield($column) );
} grep { /^radius_/ && $self->getfield($_) } fields( $self->table );
if ( $self->slipip && $self->slipip ne '0e0' ) {
- $reply{'Framed-IP-Address'} = $self->slipip;
+ $reply{$radius_ip} = $self->slipip;
}
%reply;
}
Returns the FS::cust_svc record for this account (see L<FS::cust_svc>).
+=cut
+
sub cust_svc {
my $self = shift;
qsearchs( 'cust_svc', { 'svcnum' => $self->svcnum } );
$self->username. '@'. $self->domain;
}
+=item acct_snarf
+
+Returns an array of FS::acct_snarf records associated with the account.
+If the acct_snarf table does not exist or there are no associated records,
+an empty list is returned
+
+=cut
+
+sub acct_snarf {
+ my $self = shift;
+ return () unless dbdef->table('acct_snarf');
+ eval "use FS::acct_snarf;";
+ die $@ if $@;
+ qsearch('acct_snarf', { 'svcnum' => $self->svcnum } );
+}
+
=item seconds_since TIMESTAMP
Returns the number of seconds this account has been online since TIMESTAMP,
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->attribute_since_sqlradacct(@_);
}
+=item get_session_history_sqlradacct TIMESTAMP_START TIMESTAMP_END
+
+Returns an array of hash references of this customers login history for the
+given time range. (document this better)
+
+=cut
+
+sub get_session_history_sqlradacct {
+ my $self = shift;
+ $self->cust_svc->get_session_history_sqlradacct(@_);
+}
+
=item radius_groups
Returns all RADIUS groups for this account (see L<FS::radius_usergroup>).
=item send_email
+This is the FS::svc_acct job-queue-able version. It still uses
+FS::Misc::send_email under-the-hood.
+
=cut
sub send_email {
my %opt = @_;
- use Date::Format;
- use Mail::Internet 1.44;
- use Mail::Header;
+ eval "use FS::Misc qw(send_email)";
+ die $@ if $@;
$opt{mimetype} ||= 'text/plain';
$opt{mimetype} .= '; charset="iso-8859-1"' unless $opt{mimetype} =~ /charset/;
- $ENV{MAILADDRESS} = $opt{from};
- my $header = new Mail::Header ( [
- "From: $opt{from}",
- "To: $opt{to}",
- "Sender: $opt{from}",
- "Reply-To: $opt{from}",
- "Date: ". time2str("%a, %d %b %Y %X %z", time),
- "Subject: $opt{subject}",
- "Content-Type: $opt{mimetype}",
- ] );
- my $message = new Mail::Internet (
- 'Header' => $header,
- 'Body' => [ map "$_\n", split("\n", $opt{body}) ],
+ my $error = send_email(
+ 'from' => $opt{from},
+ 'to' => $opt{to},
+ 'subject' => $opt{subject},
+ 'content-type' => $opt{mimetype},
+ 'body' => [ map "$_\n", split("\n", $opt{body}) ],
);
- $!=0;
- $message->smtpsend( Host => $smtpmachine )
- or $message->smtpsend( Host => $smtpmachine, Debug => 1 )
- or die "can't send email to $opt{to} via $smtpmachine with SMTP: $!";
+ die $error if $error;
}
=item check_and_rebuild_fuzzyfiles