6 use FS::Record qw( dbh qsearch qsearchs );
13 @ISA = qw( FS::Record );
17 FS::agent - Object methods for agent records
23 $record = new FS::agent \%hash;
24 $record = new FS::agent { 'column' => 'value' };
26 $error = $record->insert;
28 $error = $new_record->replace($old_record);
30 $error = $record->delete;
32 $error = $record->check;
34 $agent_type = $record->agent_type;
36 $hashref = $record->pkgpart_hashref;
37 #may purchase $pkgpart if $hashref->{$pkgpart};
41 An FS::agent object represents an agent. Every customer has an agent. Agents
42 can be used to track things like resellers or salespeople. FS::agent inherits
43 from FS::Record. The following fields are currently supported:
47 =item agentnum - primary key (assigned automatically for new agents)
49 =item agent - Text name of this agent
51 =item typenum - Agent type. See L<FS::agent_type>
53 =item prog - For future use.
55 =item freq - For future use.
57 =item disabled - Disabled flag, empty or 'Y'
59 =item username - Username for the Agent interface
61 =item _password - Password for the Agent interface
71 Creates a new agent. To add the agent to the database, see L<"insert">.
75 sub table { 'agent'; }
79 Adds this agent to the database. If there is an error, returns the error,
80 otherwise returns false.
84 Deletes this agent from the database. Only agents with no customers can be
85 deleted. If there is an error, returns the error, otherwise returns false.
92 return "Can't delete an agent with customers!"
93 if qsearch( 'cust_main', { 'agentnum' => $self->agentnum } );
98 =item replace OLD_RECORD
100 Replaces OLD_RECORD with this one in the database. If there is an error,
101 returns the error, otherwise returns false.
105 Checks all fields to make sure this is a valid agent. If there is an error,
106 returns the error, otherwise returns false. Called by the insert and replace
115 $self->ut_numbern('agentnum')
116 || $self->ut_text('agent')
117 || $self->ut_number('typenum')
118 || $self->ut_numbern('freq')
119 || $self->ut_textn('prog')
120 || $self->ut_textn('invoice_template')
122 return $error if $error;
124 if ( $self->dbdef_table->column('disabled') ) {
125 $error = $self->ut_enum('disabled', [ '', 'Y' ] );
126 return $error if $error;
129 if ( $self->dbdef_table->column('username') ) {
130 $error = $self->ut_alphan('username');
131 return $error if $error;
132 if ( length($self->username) ) {
133 my $conflict = qsearchs('agent', { 'username' => $self->username } );
134 return 'duplicate agent username (with '. $conflict->agent. ')'
135 if $conflict && $conflict->agentnum != $self->agentnum;
136 $error = $self->ut_text('password'); # ut_text... arbitrary choice
138 $self->_password('');
142 return "Unknown typenum!"
143 unless $self->agent_type;
150 Returns the FS::agent_type object (see L<FS::agent_type>) for this agent.
156 qsearchs( 'agent_type', { 'typenum' => $self->typenum } );
159 =item pkgpart_hashref
161 Returns a hash reference. The keys of the hash are pkgparts. The value is
162 true if this agent may purchase the specified package definition. See
167 sub pkgpart_hashref {
169 $self->agent_type->pkgpart_hashref;
172 =item ticketing_queue
174 Returns the queue name corresponding with the id from the I<ticketing_queueid>
175 field, or the empty string.
179 sub ticketing_queue {
181 FS::TicketSystem->queue($self->ticketing_queueid);
184 =item num_prospect_cust_main
186 Returns the number of prospects (customers with no packages ever ordered) for
191 sub num_prospect_cust_main {
192 shift->num_sql(FS::cust_main->prospect_sql);
196 my( $self, $sql ) = @_;
197 my $statement = "SELECT COUNT(*) FROM cust_main WHERE agentnum = ? AND $sql";
198 my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
199 $sth->execute($self->agentnum) or die $sth->errstr. " executing $statement";
200 $sth->fetchrow_arrayref->[0];
203 =item prospect_cust_main
205 Returns the prospects (customers with no packages ever ordered) for this agent,
206 as cust_main objects.
210 sub prospect_cust_main {
211 shift->cust_main_sql(FS::cust_main->prospect_sql);
215 my( $self, $sql ) = @_;
216 qsearch( 'cust_main',
217 { 'agentnum' => $self->agentnum },
223 =item num_active_cust_main
225 Returns the number of active customers for this agent (customers with active
230 sub num_active_cust_main {
231 shift->num_sql(FS::cust_main->active_sql);
234 =item active_cust_main
236 Returns the active customers for this agent, as cust_main objects.
240 sub active_cust_main {
241 shift->cust_main_sql(FS::cust_main->active_sql);
244 =item num_inactive_cust_main
246 Returns the number of inactive customers for this agent (customers with no
247 active recurring packages, but otherwise unsuspended/uncancelled).
251 sub num_inactive_cust_main {
252 shift->num_sql(FS::cust_main->inactive_sql);
255 =item inactive_cust_main
257 Returns the inactive customers for this agent, as cust_main objects.
261 sub inactive_cust_main {
262 shift->cust_main_sql(FS::cust_main->inactive_sql);
266 =item num_susp_cust_main
268 Returns the number of suspended customers for this agent.
272 sub num_susp_cust_main {
273 shift->num_sql(FS::cust_main->susp_sql);
278 Returns the suspended customers for this agent, as cust_main objects.
283 shift->cust_main_sql(FS::cust_main->susp_sql);
286 =item num_cancel_cust_main
288 Returns the number of cancelled customer for this agent.
292 sub num_cancel_cust_main {
293 shift->num_sql(FS::cust_main->cancel_sql);
296 =item cancel_cust_main
298 Returns the cancelled customers for this agent, as cust_main objects.
302 sub cancel_cust_main {
303 shift->cust_main_sql(FS::cust_main->cancel_sql);
306 =item num_active_cust_pkg
308 Returns the number of active customer packages for this agent.
312 sub num_active_cust_pkg {
313 shift->num_pkg_sql(FS::cust_pkg->active_sql);
317 my( $self, $sql ) = @_;
319 "SELECT COUNT(*) FROM cust_pkg LEFT JOIN cust_main USING ( custnum )".
320 " WHERE agentnum = ? AND $sql";
321 my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
322 $sth->execute($self->agentnum) or die $sth->errstr. "executing $statement";
323 $sth->fetchrow_arrayref->[0];
326 =item num_inactive_cust_pkg
328 Returns the number of inactive customer packages (one-time packages otherwise
329 unsuspended/uncancelled) for this agent.
333 sub num_inactive_cust_pkg {
334 shift->num_pkg_sql(FS::cust_pkg->inactive_sql);
337 =item num_susp_cust_pkg
339 Returns the number of suspended customer packages for this agent.
343 sub num_susp_cust_pkg {
344 shift->num_pkg_sql(FS::cust_pkg->susp_sql);
347 =item num_cancel_cust_pkg
349 Returns the number of cancelled customer packages for this agent.
353 sub num_cancel_cust_pkg {
354 shift->num_pkg_sql(FS::cust_pkg->cancel_sql);
357 =item generate_reg_codes NUM PKGPART_ARRAYREF
359 Generates the specified number of registration codes, allowing purchase of the
360 specified package definitions. Returns an array reference of the newly
361 generated codes, or a scalar error message.
365 #false laziness w/prepay_credit::generate
366 sub generate_reg_codes {
367 my( $self, $num, $pkgparts ) = @_;
369 my @codeset = ( 'A'..'Z' );
371 local $SIG{HUP} = 'IGNORE';
372 local $SIG{INT} = 'IGNORE';
373 local $SIG{QUIT} = 'IGNORE';
374 local $SIG{TERM} = 'IGNORE';
375 local $SIG{TSTP} = 'IGNORE';
376 local $SIG{PIPE} = 'IGNORE';
378 my $oldAutoCommit = $FS::UID::AutoCommit;
379 local $FS::UID::AutoCommit = 0;
384 my $reg_code = new FS::reg_code {
385 'agentnum' => $self->agentnum,
386 'code' => join('', map($codeset[int(rand $#codeset)], (0..7) ) ),
388 my $error = $reg_code->insert($pkgparts);
390 $dbh->rollback if $oldAutoCommit;
393 push @codes, $reg_code->code;
396 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
404 Returns the number of unused registration codes for this agent.
410 my $sth = dbh->prepare(
411 "SELECT COUNT(*) FROM reg_code WHERE agentnum = ?"
412 ) or die dbh->errstr;
413 $sth->execute($self->agentnum) or die $sth->errstr;
414 $sth->fetchrow_arrayref->[0];
417 =item num_prepay_credit
419 Returns the number of unused prepaid cards for this agent.
423 sub num_prepay_credit {
425 my $sth = dbh->prepare(
426 "SELECT COUNT(*) FROM prepay_credit WHERE agentnum = ?"
427 ) or die dbh->errstr;
428 $sth->execute($self->agentnum) or die $sth->errstr;
429 $sth->fetchrow_arrayref->[0];
439 L<FS::Record>, L<FS::agent_type>, L<FS::cust_main>, L<FS::part_pkg>,
440 schema.html from the base documentation.