use Exporter;
use Tie::IxHash;
use FS::UID qw( dbh driver_name );
+use FS::Conf;
use FS::Record;
use FS::svc_domain;
$FS::svc_domain::whois_hack = 1;
@ISA = qw( Exporter );
-@EXPORT_OK = qw( upgrade );
+@EXPORT_OK = qw( upgrade upgrade_sqlradius );
=head1 NAME
}
+sub upgrade_sqlradius {
+ #my %opt = @_;
+
+ my $conf = new FS::Conf;
+
+ my @part_export = FS::part_export::sqlradius->all_sqlradius_withaccounting();
+
+ foreach my $part_export ( @part_export ) {
+ my $dbh = DBI->connect( map $part_export->option($_),
+ qw ( datasrc username password ) );
+
+ my $str2time = str2time_sql( $dbh->{Driver}->{Name} );
+ my $group = "UserName";
+ $group .= ",Realm"
+ if ( ref($part_export) =~ /withdomain/ );
+
+ my $sth_alter = $dbh->prepare(
+ "ALTER TABLE radacct ADD COLUMN FreesideStatus varchar(32) NULL"
+ );
+ if ( $sth_alter && $sth_alter->execute ) {
+ my $sth_update = $dbh->prepare(
+ "UPDATE radacct SET FreesideStatus = 'done' WHERE FreesideStatus IS NULL"
+ ) or die $dbh->errstr;
+ $sth_update->execute or die $sth_update->errstr;
+ }
+
+ my $sth = $dbh->prepare("SELECT UserName,
+ Realm,
+ $str2time max(AcctStartTime)),
+ $str2time max(AcctStopTime))
+ FROM radacct
+ WHERE FreesideStatus = 'done'
+ AND AcctStartTime != 0
+ AND AcctStopTime != 0
+ GROUP BY $group
+ ")
+ or die $dbh->errstr;
+ $sth->execute() or die $sth->errstr;
+
+ while (my $row = $sth->fetchrow_arrayref ) {
+ my ($username, $realm, $start, $stop) = @$row;
+
+ $username = lc($username) unless $conf->exists('username-uppercase');
+ my $extra_sql = '';
+ if ( ref($part_export) =~ /withdomain/ ) {
+ $extra_sql = " And '$realm' = ( SELECT domain FROM svc_domain
+ WHERE svc_domain.svcnum = svc_acct.domsvc ) ";
+ }
+
+ my $svc_acct = qsearchs( 'svc_acct',
+ { 'username' => $username },
+ '',
+ $extra_sql,
+ );
+ if ($svc_acct) {
+ $svc_acct->last_login($start)
+ if $start && (!$svc_acct->last_login || $start > $svc_acct->last_login);
+ $svc_acct->last_logout($stop)
+ if $stop && (!$svc_acct->last_logout || $stop > $svc_acct->last_logout);
+ }
+ }
+ }
+
+}
=back
return 'skipped';
}
+###
+#class methods
+###
+
+sub all_sqlradius {
+ #my $class = shift;
+
+ #don't just look for ->can('usage_sessions'), we're sqlradius-specific
+ # (radiator is supposed to be setup with a radacct table)
+ #i suppose it would be more slick to look for things that inherit from us..
+
+ my @part_export = ();
+ push @part_export, qsearch('part_export', { 'exporttype' => $_ } )
+ foreach qw(sqlradius sqlradius_withdomain radiator);
+ @part_export;
+}
+
+sub all_sqlradius_withaccounting {
+ my $class = shift;
+ grep { ! $_->option('ignore_accounting') } $class->_part_export_sqlradius;
+}
+
1;
use FS::UID qw(adminsuidsetup); #forksuidsetup driver_name dbh myconnect);
use FS::Record qw(qsearch); # qsearchs);
use FS::part_export;
+use FS::part_export::sqlradius;
#use FS::svc_acct;
#use FS::cust_svc;
#--
-#don't just look for ->can('usage_sessions'), we're sqlradius-specific
-# (radiator is supposed to be setup with a radacct table)
-
-@part_export =
- qsearch('part_export', { 'exporttype' => 'sqlradius' } );
-push @part_export,
- qsearch('part_export', { 'exporttype' => 'sqlradius_withdomain' } );
-push @part_export,
- qsearch('part_export', { 'exporttype' => 'radiator' } );
-
-@part_export = grep { ! $_->option('ignore_accounting') } @part_export;
+my @part_export = FS::part_export::sqlradius->all_sqlradius_withaccounting();
die "no sqlradius, sqlradius_withdomain or radiator exports without".
" ignore_accounting"
Imports records from an the SQL radacct tables of all sqlradius,
sqlradius_withdomain and radiator exports (except those with the
-ignore_accounting flag) and updates the svc_acct.seconds for each account.
-Runs as a daemon and updates the database in real-time.
+ignore_accounting flag) and updates the following fields in svc_acct (see
+L<FS::svc_acct>) for each account: last_login, last_logout, seconds,
+upbytes, downbytes, totalbytes. Runs as a daemon and updates the database
+in real-time.
B<username> is a username added by freeside-adduser.
=head1 RADIUS DATABASE CHANGES
+In 1.7.4+, freeside-upgrade should have taken care of these changes already.
+
ALTER TABLE radacct ADD COLUMN FreesideStatus varchar(32) NULL;
If you want to ignore the existing accountg records, also do:
upgrade()
unless $DRY_RUN || $opt_s;
+upgrade_sqlradius()
+ unless $DRY_RUN || $opt_s;
+
$dbh->commit or die $dbh->errstr;
dbdef_create($dbh, $dbdef_file);
}
sub usage {
- die "Usage:\n freeside-upgrade [ -d ] [ -q | -v ] user\n";
+ die "Usage:\n freeside-upgrade [ -d ] [ -s ] [ -q | -v ] user\n";
}
=head1 NAME
freeside-queued $QUEUED_USER
echo "done."
- #echo -n "Starting freeside-sqlradius-radacctd: "
- #freeside-sqlradius-radacctd $QUEUED_USER
- #echo "done."
+ echo -n "Starting freeside-sqlradius-radacctd: "
+ freeside-sqlradius-radacctd $QUEUED_USER
+ echo "done."
echo -n "Starting freeside-prepaidd: "
freeside-prepaidd $QUEUED_USER