X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=FS%2FFS%2Fsvc_acct.pm;h=ffcadc9cbcbd95668ba89c815d7f2d8b9ea6f23f;hp=26d6e5b72c46bcb2acebd76addf59288481956ee;hb=ec271a1445bf232cd172c38e2dd3fd9d3c5c7c4e;hpb=54a357b171aa44f9399b4c146acd2afd3b686075 diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 26d6e5b72..ffcadc9cb 100644 --- a/FS/FS/svc_acct.pm +++ b/FS/FS/svc_acct.pm @@ -40,6 +40,7 @@ use FS::Record qw( qsearch qsearchs fields dbh dbdef ); use FS::Msgcat qw(gettext); use FS::UI::bytecount; use FS::UI::Web; +use FS::PagedSearch qw( psearch ); # XXX in v4, replace with FS::Cursor use FS::part_pkg; use FS::part_svc; use FS::svc_acct_pop; @@ -283,6 +284,7 @@ sub table_info { disable_default => 1, disable_fixed => 1, disable_select => 1, + required => 1, }, 'password_selfchange' => { label => 'Password modification', type => 'checkbox', @@ -294,27 +296,25 @@ sub table_info { label => 'Quota', #Mail storage limit type => 'text', disable_inventory => 1, - disable_select => 1, }, 'file_quota'=> { label => 'File storage limit', type => 'text', disable_inventory => 1, - disable_select => 1, }, 'file_maxnum'=> { label => 'Number of files limit', type => 'text', disable_inventory => 1, - disable_select => 1, }, 'file_maxsize'=> { label => 'File size limit', type => 'text', disable_inventory => 1, - disable_select => 1, }, - '_password' => 'Password', + '_password' => { label => 'Password', + required => 1 + }, 'gid' => { label => 'GID', def_info => 'when blank, defaults to UID', @@ -337,6 +337,7 @@ sub table_info { select_key => 'svcnum', select_label => 'domain', disable_inventory => 1, + required => 1, }, 'pbxsvc' => { label => 'PBX', type => 'select-svc_pbx.html', @@ -2369,130 +2370,105 @@ sub seconds_since { $self->cust_svc->seconds_since(@_); } -=item seconds_since_sqlradacct TIMESTAMP_START TIMESTAMP_END - -Returns the numbers of seconds this account has been online between -TIMESTAMP_START (inclusive) and TIMESTAMP_END (exclusive), according to an -external SQL radacct table, specified via sqlradius export. Sessions which -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 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. +=item last_login_text -TIMESTAMP_START and TIMESTAMP_END are specified as UNIX timestamps; see -L. Also see L and L for conversion -functions. +Returns text describing the time of last login. =cut -#note: POD here, implementation in FS::cust_svc -sub seconds_since_sqlradacct { +sub last_login_text { my $self = shift; - $self->cust_svc->seconds_since_sqlradacct(@_); + $self->last_login ? ctime($self->last_login) : 'unknown'; } -=item attribute_since_sqlradacct TIMESTAMP_START TIMESTAMP_END ATTRIBUTE - -Returns the sum of the given attribute for all accounts (see L) -in this package for sessions ending between TIMESTAMP_START (inclusive) and -TIMESTAMP_END (exclusive). +=item psearch_cdrs OPTIONS -TIMESTAMP_START and TIMESTAMP_END are specified as UNIX timestamps; see -L. Also see L and L for conversion -functions. +Returns a paged search (L) for Call Detail Records +associated with this service. For svc_acct, "associated with" means that +either the "src" or the "charged_party" field of the CDR matches the +"username" field of the service. =cut -#note: POD here, implementation in FS::cust_svc -sub attribute_since_sqlradacct { - my $self = shift; - $self->cust_svc->attribute_since_sqlradacct(@_); -} +sub psearch_cdrs { + my($self, %options) = @_; + my @fields; + my %hash; + my @where; -=item get_session_history TIMESTAMP_START TIMESTAMP_END + my $did = dbh->quote($self->username); -Returns an array of hash references of this customers login history for the -given time range. (document this better) + my $prefix = $options{'default_prefix'} || ''; #convergent.au '+61' + my $prefixdid = dbh->quote($prefix . $self->username); -=cut + my $for_update = $options{'for_update'} ? 'FOR UPDATE' : ''; -sub get_session_history { - my $self = shift; - $self->cust_svc->get_session_history(@_); -} - -=item last_login_text + if ( $options{inbound} ) { + # these will be selected under their DIDs + push @where, "FALSE"; + } -Returns text describing the time of last login. + my @orwhere; + if (!$options{'disable_charged_party'}) { + push @orwhere, + "charged_party = $did", + "charged_party = $prefixdid"; + } + if (!$options{'disable_src'}) { + push @orwhere, + "src = $did AND charged_party IS NULL", + "src = $prefixdid AND charged_party IS NULL"; + } + push @where, '(' . join(' OR ', @orwhere) . ')'; -=cut + # $options{'status'} = '' is meaningful; for the rest of them it's not + if ( exists $options{'status'} ) { + $hash{'freesidestatus'} = $options{'status'}; + } + if ( $options{'cdrtypenum'} ) { + $hash{'cdrtypenum'} = $options{'cdrtypenum'}; + } + if ( $options{'calltypenum'} ) { + $hash{'calltypenum'} = $options{'calltypenum'}; + } + if ( $options{'begin'} ) { + push @where, 'startdate >= '. $options{'begin'}; + } + if ( $options{'end'} ) { + push @where, 'startdate < '. $options{'end'}; + } + if ( $options{'nonzero'} ) { + push @where, 'duration > 0'; + } -sub last_login_text { - my $self = shift; - $self->last_login ? ctime($self->last_login) : 'unknown'; + my $extra_sql = join(' AND ', @where); + if ($extra_sql) { + if (keys %hash) { + $extra_sql = " AND ".$extra_sql; + } else { + $extra_sql = " WHERE ".$extra_sql; + } + } + return psearch({ + 'select' => '*', + 'table' => 'cdr', + 'hashref' => \%hash, + 'extra_sql' => $extra_sql, + 'order_by' => "ORDER BY startdate $for_update", + }); } -=item get_cdrs TIMESTAMP_START TIMESTAMP_END [ 'OPTION' => 'VALUE ... ] +=item get_cdrs (DEPRECATED) + +Like psearch_cdrs, but returns all the L objects at once, in a +single list. Arguments are the same as for psearch_cdrs. =cut sub get_cdrs { - my($self, $start, $end, %opt ) = @_; - - my $did = $self->username; #yup - - my $prefix = $opt{'default_prefix'}; #convergent.au '+61' - - my $for_update = $opt{'for_update'} ? 'FOR UPDATE' : ''; - - #SELECT $for_update * FROM cdr - # WHERE calldate >= $start #need a conversion - # AND calldate < $end #ditto - # AND ( charged_party = "$did" - # OR charged_party = "$prefix$did" #if length($prefix); - # OR ( ( charged_party IS NULL OR charged_party = '' ) - # AND - # ( src = "$did" OR src = "$prefix$did" ) # if length($prefix) - # ) - # ) - # AND ( freesidestatus IS NULL OR freesidestatus = '' ) - - my $charged_or_src; - if ( length($prefix) ) { - $charged_or_src = - " AND ( charged_party = '$did' - OR charged_party = '$prefix$did' - OR ( ( charged_party IS NULL OR charged_party = '' ) - AND - ( src = '$did' OR src = '$prefix$did' ) - ) - ) - "; - } else { - $charged_or_src = - " AND ( charged_party = '$did' - OR ( ( charged_party IS NULL OR charged_party = '' ) - AND - src = '$did' - ) - ) - "; - - } - - qsearch( - 'select' => "$for_update *", - 'table' => 'cdr', - 'hashref' => { - #( freesidestatus IS NULL OR freesidestatus = '' ) - 'freesidestatus' => '', - }, - 'extra_sql' => $charged_or_src, - - ); - + my $self = shift; + my $psearch = $self->psearch_cdrs(@_); + qsearch ( $psearch->{query} ) } # sub radius_groups has moved to svc_Radius_Mixin