1 package FS::ClientAPI::Agent;
3 #some false laziness w/MyAccount
7 use Digest::MD5 qw(md5_hex);
8 use Cache::SharedMemoryCache; #store in db?
9 use FS::Record qw(qsearchs qsearch dbdef dbh);
14 FS::ClientAPI->register_handlers(
15 'Agent/agent_login' => \&agent_login,
16 'Agent/agent_logout' => \&agent_logout,
17 'Agent/agent_info' => \&agent_info,
18 'Agent/agent_list_customers' => \&agent_list_customers,
22 my $cache = new Cache::SharedMemoryCache( {
23 'namespace' => 'FS::ClientAPI::Agent',
29 #don't allow a blank login to first unconfigured agent with no user/pass
30 return { error => 'Must specify your reseller username and password.' }
31 unless length($p->{'username'}) && length($p->{'password'});
33 my $agent = qsearchs( 'agent', {
34 'username' => $p->{'username'},
35 '_password' => $p->{'password'},
38 unless ( $agent ) { return { error => 'Incorrect password.' } }
41 'agentnum' => $agent->agentnum,
42 'agent' => $agent->agent,
47 $session_id = md5_hex(md5_hex(time(). {}. rand(). $$))
48 } until ( ! defined $cache->get($session_id) ); #just in case
50 $cache->set( $session_id, $session, '1 hour' );
53 'session_id' => $session_id,
59 if ( $p->{'session_id'} ) {
60 $cache->remove($p->{'session_id'});
61 return { 'error' => '' };
63 return { 'error' => "Can't resume session" }; #better error message
70 my $session = $cache->get($p->{'session_id'})
71 or return { 'error' => "Can't resume session" }; #better error message
75 my $agentnum = $session->{'agentnum'};
77 my $agent = qsearchs( 'agent', { 'agentnum' => $agentnum } )
78 or return { 'error' => "unknown agentnum $agentnum" };
81 'agentnum' => $agentnum,
82 'agent' => $agent->agent,
83 'num_prospect' => $agent->num_prospect_cust_main,
84 'num_active' => $agent->num_active_cust_main,
85 'num_susp' => $agent->num_susp_cust_main,
86 'num_cancel' => $agent->num_cancel_cust_main,
92 sub agent_list_customers {
95 my $session = $cache->get($p->{'session_id'})
96 or return { 'error' => "Can't resume session" }; #better error message
100 my $agentnum = $session->{'agentnum'};
102 my $agent = qsearchs( 'agent', { 'agentnum' => $agentnum } )
103 or return { 'error' => "unknown agentnum $agentnum" };
107 #warn $p->{'search'};
108 if ( $p->{'search'} =~ /^\s*(\d+)\s*$/ ) { # customer # search
109 push @cust_main, qsearch('cust_main', { 'agentnum' => $agentnum,
111 } elsif ( $p->{'search'} =~ /^\s*(\S.*\S)\s*$/ ) { #value search
113 my $q_value = dbh->quote($value);
116 my $sql = " AND ( LOWER(last) = $q_value OR LOWER(company) = $q_value";
117 $sql .= " OR LOWER(ship_last) = $q_value OR LOWER(ship_company) = $q_value"
118 if defined dbdef->table('cust_main')->column('ship_last');
121 push @cust_main, qsearch( 'cust_main',
122 { 'agentnum' => $agentnum },
127 unless ( @cust_main ) {
128 warn "no exact match, trying substring/fuzzy\n";
130 #still some false laziness w/ search/cust_main.cgi
133 push @cust_main, qsearch( 'cust_main',
134 { 'agentnum' => $agentnum,
135 'last' => { 'op' => 'ILIKE',
136 'value' => "%$q_value%" } } );
138 push @cust_main, qsearch( 'cust_main',
139 { 'agentnum' => $agentnum,
140 'ship_last' => { 'op' => 'ILIKE',
141 'value' => "%$q_value%" } } )
142 if defined dbdef->table('cust_main')->column('ship_last');
144 push @cust_main, qsearch( 'cust_main',
145 { 'agentnum' => $agentnum,
146 'company' => { 'op' => 'ILIKE',
147 'value' => "%$q_value%" } } );
149 push @cust_main, qsearch( 'cust_main',
150 { 'agentnum' => $agentnum,
151 'ship_company' => { 'op' => 'ILIKE',
152 'value' => "%$q_value%" } } )
153 if defined dbdef->table('cust_main')->column('ship_last');
156 push @cust_main, FS::cust_main->fuzzy_search(
157 { 'last' => $value },
158 { 'agentnum' => $agentnum }
160 push @cust_main, FS::cust_main->fuzzy_search(
161 { 'company' => $value },
162 { 'agentnum' => $agentnum }
170 map $agent->$_(), map $_.'_cust_main',
171 grep $p->{$_}, qw( prospect active susp cancel );
175 @cust_main = grep { !$saw{$_->custnum}++ } @cust_main;
177 { customers => [ map {
179 my $hashref = $cust_main->hashref;
180 $hashref->{$_} = $cust_main->$_()
181 foreach qw(name status statuscolor);
182 delete $hashref->{$_} foreach qw( payinfo paycvv );