+Returns the FS::svc_domain record for this account's domain (see
+L<FS::svc_domain>.
+
+=cut
+
+sub svc_domain {
+ my $self = shift;
+ $self->{'_domsvc'}
+ ? $self->{'_domsvc'}
+ : qsearchs( 'svc_domain', { 'svcnum' => $self->domsvc } );
+}
+
+=item cust_svc
+
+Returns the FS::cust_svc record for this account (see L<FS::cust_svc>).
+
+sub cust_svc {
+ my $self = shift;
+ qsearchs( 'cust_svc', { 'svcnum' => $self->svcnum } );
+}
+
+=item email
+
+Returns an email address associated with the account.
+
+=cut
+
+sub email {
+ my $self = shift;
+ $self->username. '@'. $self->domain;
+}
+
+=item seconds_since TIMESTAMP
+
+Returns the number of seconds this account has been online since TIMESTAMP.
+See L<FS::session>
+
+TIMESTAMP is specified as a UNIX timestamp; 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 seconds_since {
+ my $self = shift;
+ $self->cust_svc->seconds_since(@_);
+}
+
+=item radius_groups
+
+Returns all RADIUS groups for this account (see L<FS::radius_usergroup>).
+
+=cut
+
+sub radius_groups {
+ my $self = shift;
+ map { $_->groupname }
+ qsearch('radius_usergroup', { 'svcnum' => $self->svcnum } );
+}
+
+=back
+
+=head1 SUBROUTINES
+
+=over 4
+
+=item send_email
+
+=cut
+
+sub send_email {
+ my %opt = @_;
+
+ use Date::Format;
+ use Mail::Internet 1.44;
+ use Mail::Header;
+
+ $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}) ],
+ );
+ $!=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: $!";
+}
+
+=item check_and_rebuild_fuzzyfiles
+
+=cut
+
+sub check_and_rebuild_fuzzyfiles {
+ my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc;
+ -e "$dir/svc_acct.username"
+ or &rebuild_fuzzyfiles;
+}
+
+=item rebuild_fuzzyfiles
+
+=cut
+
+sub rebuild_fuzzyfiles {
+
+ use Fcntl qw(:flock);
+
+ my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc;
+
+ #username
+
+ open(USERNAMELOCK,">>$dir/svc_acct.username")
+ or die "can't open $dir/svc_acct.username: $!";
+ flock(USERNAMELOCK,LOCK_EX)
+ or die "can't lock $dir/svc_acct.username: $!";
+
+ my @all_username = map $_->getfield('username'), qsearch('svc_acct', {});
+
+ open (USERNAMECACHE,">$dir/svc_acct.username.tmp")
+ or die "can't open $dir/svc_acct.username.tmp: $!";
+ print USERNAMECACHE join("\n", @all_username), "\n";
+ close USERNAMECACHE or die "can't close $dir/svc_acct.username.tmp: $!";
+
+ rename "$dir/svc_acct.username.tmp", "$dir/svc_acct.username";
+ close USERNAMELOCK;
+
+}
+
+=item all_username
+
+=cut
+
+sub all_username {
+ my $dir = $FS::UID::conf_dir. "cache.". $FS::UID::datasrc;
+ open(USERNAMECACHE,"<$dir/svc_acct.username")
+ or die "can't open $dir/svc_acct.username: $!";
+ my @array = map { chomp; $_; } <USERNAMECACHE>;
+ close USERNAMECACHE;
+ \@array;
+}