sub cust_status {
my $self = shift;
return $self->cust_unlinked_msg unless $self->cust_linked;
-
- #FS::cust_main::status($self)
- #false laziness w/actual cust_main::status
- # (make sure FS::cust_main methods are called)
- for my $status (qw( prospect active inactive suspended cancelled )) {
- my $method = $status.'_sql';
- my $sql = FS::cust_main->$method();;
- my $numnum = ( $sql =~ s/cust_main\.custnum/?/g );
- my $sth = dbh->prepare("SELECT $sql") or die dbh->errstr;
- $sth->execute( ($self->custnum) x $numnum )
- or die "Error executing 'SELECT $sql': ". $sth->errstr;
- return $status if $sth->fetchrow_arrayref->[0];
- }
+ my $cust_main = $self->cust_main;
+ return $self->cust_unlinked_msg unless $cust_main;
+ return $cust_main->cust_status;
}
=item ucfirst_cust_status
: '000000';
}
+=item agent_name
+
+=cut
+
+sub agent_name {
+ my $self = shift;
+ $self->cust_linked
+ ? $self->cust_main->agent_name
+ : $self->cust_unlinked_msg;
+}
+
=item prospect_sql
=item active_sql
=item search
-Hashref of params to the L<search()> method. Required.
+Hashref of params to the L<FS::Record/search> method. Required.
=item msgnum
sub email_search_result {
my($class, $param) = @_;
+ my $conf = FS::Conf->new;
+ my $send_to_domain = $conf->config('email-to-voice_domain');
+
my $msgnum = $param->{msgnum};
my $from = delete $param->{from};
my $subject = delete $param->{subject};
my $html_body = delete $param->{html_body};
my $text_body = delete $param->{text_body};
my $to_contact_classnum = delete $param->{to_contact_classnum};
+ my $emailtovoice_name = delete $param->{emailtovoice_contact};
+
my $error = '';
+ my $to = $emailtovoice_name . '@' . $send_to_domain unless !$emailtovoice_name;
+
my $job = delete $param->{'job'}
or die "email_search_result must run from the job queue.\n";
next; # unlinked object; nothing else we can do
}
+ my %to = ( to => $to ) if $to;
+
if ( $msg_template ) {
# Now supports other context objects.
%message = $msg_template->prepare(
'cust_main' => $cust_main,
'object' => $obj,
'to_contact_classnum' => $to_contact_classnum,
+ %to
);
} else {
# 3.x: false laziness with msg_template.pm; on 4.x, all email notices
# are generated from templates and this case goes away
my @classes;
- if ( $opt{'to_contact_classnum'} ) {
- my $classnum = $opt{'to_contact_classnum'};
- @classes = ref($classnum) ? @$classnum : split(',', $classnum);
+ if ( $to_contact_classnum ) {
+ @classes = ref($to_contact_classnum) ? @$to_contact_classnum : split(',', $to_contact_classnum);
}
if (!@classes) {
@classes = ( 'invoice' );
}
- my @to = $cust_main->contact_list_email(@classes);
+ my @to = $to ? split(',', $to) : $cust_main->contact_list_email(@classes);
next if !@to;
%message = (
} #if $msg_template
# For non-cust_main searches, we avoid duplicates based on message
- # body text.
+ # body text.
my $unique = $cust_main->custnum;
$unique .= sha1($message{'text_body'}) if $class ne 'FS::cust_main';
if( $sent_to{$unique} ) {
}
+sub customer_agent_transfer_search_result {
+ my($class, $param) = @_;
+
+ my $newagentnum = $param->{agentnum};
+ my $error = '';
+ my @customers;
+
+ my $job = delete $param->{'job'}
+ or die "customer_agent_transfer_search_result must run from the job queue.\n";
+
+ my $list = $param->{'list'};
+
+ if ($param->{'search'}) {
+ my $sql_query = $class->search($param->{'search'});
+ $sql_query->{'select'} = $sql_query->{'table'} . '.*';
+ @customers = qsearch($sql_query);
+ }
+
+ @customers = @$list if !@customers && $list;
+ my $num_cust = scalar(@customers);
+
+ my( $num, $last, $min_sec ) = (0, time, 5); #progresbar
+
+ # Transactionize
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ foreach my $obj ( @customers ) {
+
+ #progressbar first, so that the count is right
+ $num++;
+ if ( time - $min_sec > $last ) {
+ my $error = $job->update_statustext(
+ int( 100 * $num / $num_cust )
+ );
+ die $error if $error;
+ $last = time;
+ }
+
+ my $cust_main = $obj->cust_main;
+ if ( !$cust_main ) {
+ next; # unlinked object nothing to do
+ }
+
+ $cust_main->agentnum($newagentnum);
+ $error = $cust_main->replace;
+
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return "transfering to new agent: $error";
+ }
+
+ } # foreach $obj
+
+ $dbh->commit if $oldAutoCommit;
+ return '';
+}
+
+=item process_customer_agent_transfer_search_result
+
+Mass transfers customers to new agent.
+
+Is Transactionized so entire list transfers or none.
+
+excepts either a list of cust_main objects in the base64 encoded cgi param list
+or a list of search fields in the base64 encoded cgi param search.
+
+=cut
+
+sub process_customer_agent_transfer_search_result {
+ my $job = shift;
+
+ my $param = shift;
+ warn Dumper($param) if $DEBUG;
+
+ $param->{'job'} = $job;
+
+ $param->{'search'} = thaw(decode_base64($param->{'search'}))
+ or die "process_customer_agent_transfer_search_result.\n" if $param->{'search'};
+
+ $param->{'list'} = thaw(decode_base64($param->{'list'}))
+ or die "process_customer_agent_transfer_search_result.\n" if $param->{'list'};;
+
+ my $table = $param->{'table'}
+ or die "process_customer_agent_transfer_search_result.\n";
+
+ eval "use FS::$table;";
+ die "error loading FS::$table: $@\n" if $@;
+
+ my $error = "FS::$table"->customer_agent_transfer_search_result( $param );
+
+ die $error if $error;
+
+}
+
=item conf
Returns a configuration handle (L<FS::Conf>) set to the customer's locale,
}
my $balance = $cust_main->balance || 0;
if ($balance <= $maxbalance) {
- my @errors = $cust_main->unsuspend;
+ my @errors = $cust_main->unsuspend(
+ 'reason_type' => $conf->config('unsuspend_reason_type')
+ );
# side-fx with nested transactions? upstack rolls back?
warn "WARNING:Errors unsuspending customer ". $cust_main->custnum. ": ".
join(' / ', @errors)