X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Fsvc_acct.pm;h=a76d93dabcb48eb794c3a8b02faf6c3c191327d0;hb=1e64160a779e96d84c5db648622dee4f88f34215;hp=62cb633627e77974cace11937549d5917cc69c78;hpb=0b25e1048d9d41cb92da42b99e0982910539f320;p=freeside.git diff --git a/FS/FS/svc_acct.pm b/FS/FS/svc_acct.pm index 62cb63362..a76d93dab 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; @@ -56,6 +57,7 @@ use FS::svc_forward; use FS::svc_www; use FS::cdr; use FS::tower_sector; +use FS::Misc; $DEBUG = 0; $me = '[FS::svc_acct]'; @@ -259,6 +261,7 @@ sub table_info { 'display_weight' => 10, 'cancel_weight' => 50, 'ip_field' => 'slipip', + 'manual_require' => 1, 'fields' => { 'dir' => 'Home directory', 'uid' => { @@ -282,6 +285,7 @@ sub table_info { disable_default => 1, disable_fixed => 1, disable_select => 1, + required => 1, }, 'password_selfchange' => { label => 'Password modification', type => 'checkbox', @@ -293,27 +297,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', @@ -336,6 +338,7 @@ sub table_info { select_key => 'svcnum', select_label => 'domain', disable_inventory => 1, + required => 1, }, 'pbxsvc' => { label => 'PBX', type => 'select-svc_pbx.html', @@ -726,9 +729,11 @@ sub insert { $cust_main->invoicing_list(\@invoicing_list); } - #welcome email + #welcome email/letter my @welcome_exclude_svcparts = $conf->config('svc_acct_welcome_exclude'); unless ( grep { $_ eq $self->svcpart } @welcome_exclude_svcparts ) { + #indent skips a level for some reason + #welcome email my $error = ''; my $msgnum = $conf->config('welcome_msgnum', $agentnum); if ( $msgnum ) { @@ -812,7 +817,21 @@ sub insert { } # if $welcome_template } # if !$msgnum - } + # print welcome letter + if ($conf->exists('svc_acct_welcome_letter')) { + my $queue = new FS::queue { + 'job' => 'FS::svc_acct::process_print_welcome_letter', + }; + $error = $queue->insert( + 'svcnum' => $self->svcnum, + 'template' => 'svc_acct_welcome_letter', + ); + if ($error) { + warn "can't send welcome letter: $error"; + } + } + #indent skipped a level for some reason + } # unless in @welcome_exclude_svcparts } # if $cust_pkg $dbh->commit or die $dbh->errstr if $oldAutoCommit; @@ -2371,65 +2390,94 @@ sub last_login_text { $self->last_login ? ctime($self->last_login) : 'unknown'; } -=item get_cdrs TIMESTAMP_START TIMESTAMP_END [ 'OPTION' => 'VALUE ... ] +=item psearch_cdrs OPTIONS + +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 -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' - ) - ) - "; +sub psearch_cdrs { + my($self, %options) = @_; + my @fields; + my %hash; + my @where; + my $did = dbh->quote($self->username); + + my $prefix = $options{'default_prefix'} || ''; #convergent.au '+61' + my $prefixdid = dbh->quote($prefix . $self->username); + + my $for_update = $options{'for_update'} ? 'FOR UPDATE' : ''; + + if ( $options{inbound} ) { + # these will be selected under their DIDs + push @where, "FALSE"; + } + + 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) . ')'; + + # $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'; + } - qsearch( - 'select' => "$for_update *", + 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' => { - #( freesidestatus IS NULL OR freesidestatus = '' ) - 'freesidestatus' => '', - }, - 'extra_sql' => $charged_or_src, + 'hashref' => \%hash, + 'extra_sql' => $extra_sql, + 'order_by' => "ORDER BY startdate $for_update", + }); +} - ); +=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 = shift; + my $psearch = $self->psearch_cdrs(@_); + qsearch ( $psearch->{query} ) } # sub radius_groups has moved to svc_Radius_Mixin @@ -2988,6 +3036,26 @@ sub reached_threshold { } } +sub process_print_welcome_letter { + my %opt = @_; + + my $self = qsearchs('svc_acct', { 'svcnum' => $opt{'svcnum'} } ) + or die "invalid svc_acct: " . $opt{'svcnum'}; + my $cust_main = $self->cust_svc->cust_pkg->cust_main; + + my $ps = $cust_main->print_ps('svc_acct_welcome_letter', + 'extra_fields' => { + map { $_ => $self->$_ } $self->fields, # or maybe just username & password? + }, + ); + my $error = FS::Misc::do_print( + [ $ps ], + 'agentnum' => $cust_main->agentnum, + ); + die $error if $error; + +} + =back =head1 BUGS