summaryrefslogtreecommitdiff
path: root/FS/FS/cust_svc.pm
diff options
context:
space:
mode:
authorivan <ivan>2002-10-12 13:26:46 +0000
committerivan <ivan>2002-10-12 13:26:46 +0000
commit6f8a6c416174bcf8095c959085d14ba820425aad (patch)
treeacbc5ca383683fc409c1cef2e43a2095ead9c9fc /FS/FS/cust_svc.pm
parenteb9d5b215af1fbe867b75c12328126f650f9fb06 (diff)
sqlradacct_hour price plan to charge per-hour against an external radacct table
Diffstat (limited to 'FS/FS/cust_svc.pm')
-rw-r--r--FS/FS/cust_svc.pm87
1 files changed, 86 insertions, 1 deletions
diff --git a/FS/FS/cust_svc.pm b/FS/FS/cust_svc.pm
index 9d510b3..4fc6634 100644
--- a/FS/FS/cust_svc.pm
+++ b/FS/FS/cust_svc.pm
@@ -336,11 +336,93 @@ sub seconds_since {
$sth->fetchrow_arrayref->[0];
}
+=item seconds_since_sqlradacct TIMESTAMP_START TIMESTAMP_END ( DBI_DATABASE_HANDLE | DATASRC DB_USERNAME DB_PASSWORD )
+
+See L<FS::svc_acct/seconds_since_sqlradacct>. Equivalent to
+$cust_svc->svc_x->seconds_since, but more efficient. Meaningless for records
+where B<svcdb> is not "svc_acct".
+
+NOTE: specifying a DATASRC/USERNAME/PASSWORD instead of a DBI database handle
+is not yet implemented.
+
+=cut
+
+#note: implementation here, POD in FS::svc_acct
+sub seconds_since_sqlradacct {
+ my($self, $start, $end, $dbh) = @_;
+
+ my $username = $self->svc_x->username;
+
+ #select a unix time conversion function based on database type
+ my $str2time;
+ if ( $dbh->{Driver}->{Name} eq 'mysql' ) {
+ $str2time = 'UNIX_TIMESTAMP(';
+ } elsif ( $dbh->{Driver}->{Name} eq 'Pg' ) {
+ $str2time = 'EXTRACT( EPOCH FROM ';
+ } else {
+ warn "warning: unknown database type ". $dbh->{Driver}->{Name}.
+ "; guessing how to convert to UNIX timestamps";
+ $str2time = 'extract(epoch from ';
+ }
+
+ #find sessions completely within the given range
+ my $sth = $dbh->prepare("SELECT SUM(acctsessiontime)
+ FROM radacct
+ WHERE UserName = ?
+ AND $str2time AcctStartTime) >= ?
+ AND $str2time AcctStopTime ) < ?
+ AND AcctStopTime =! 0
+ AND AcctStopTime IS NOT NULL"
+ ) or die $dbh->errstr;
+ $sth->execute($username, $start, $end) or die $sth->errstr;
+ my $regular = $sth->fetchrow_arrayref->[0];
+
+ #find open sessions which start in the range, count session start->range end
+ $sth = $dbh->prepare("SELECT SUM( ? - $str2time AcctStartTime ) )
+ FROM radacct
+ WHERE UserName = ?
+ AND AcctStartTime >= ?
+ AND ( AcctStopTime = 0
+ OR AcctStopTime IS NULL )"
+ ) or die $dbh->errstr;
+ $sth->execute($end, $username, $start) or die $sth->errstr;
+ my $start_during = $sth->fetchrow_arrayref->[0];
+
+ #find closed sessions which start before the range but stop during,
+ #count range start->session end
+ $sth = $dbh->prepare("SELECT SUM( $str2time AcctStopTime ) - ? )
+ FROM radacct
+ WHERE UserName = ?
+ AND AcctStartTime < ?
+ AND AcctStopTime >= ?
+ AND AcctStopTime < ?
+ AND AcctStopTime != 0
+ AND AcctStopTime IS NOT NULL"
+ ) or die $dbh->errstr;
+ $sth->execute($start, $username, $start, $start, $end ) or die $sth->errstr;
+ my $end_during = $sth->fetchrow_arrayref->[0];
+
+ #find closed or open sessions which start before the range but stop
+ # after, or are still open, count range start->range end
+ $sth = $dbh->prepare("SELECT COUNT(*)
+ FROM radacct
+ WHERE UserName = ?
+ AND AcctStartTime < ?
+ AND ( AcctStopTime >= ?
+ OR AcctStopTime = 0
+ OR AcctStopTime IS NULL )"
+ ) or die $dbh->errstr;
+ $sth->execute($username, $start, $end ) or die $sth->errstr;
+ my $entire_range = ($end-$start) * $sth->fetchrow_arrayref->[0];
+
+ $regular + $end_during + $start_during + $entire_range;
+}
+
=back
=head1 VERSION
-$Id: cust_svc.pm,v 1.17 2002-09-18 22:39:01 ivan Exp $
+$Id: cust_svc.pm,v 1.18 2002-10-12 13:26:45 ivan Exp $
=head1 BUGS
@@ -352,6 +434,9 @@ pkg_svc records are not checked in general (here).
Deleting this record doesn't check or delete the svc_* record associated
with this record.
+In seconds_since_sqlradacct, specifying a DATASRC/USERNAME/PASSWORD instead of
+a DBI database handle is not yet implemented.
+
=head1 SEE ALSO
L<FS::Record>, L<FS::cust_pkg>, L<FS::part_svc>, L<FS::pkg_svc>,