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 ticketing_queueid - Ticketing Queue
55 =item invoice_template - Invoice template name
57 =item agent_custnum - Optional agent customer (see L<FS::cust_main>)
59 =item disabled - Disabled flag, empty or 'Y'
61 =item prog - Deprecated (never used)
63 =item freq - Deprecated (never used)
65 =item username - (Deprecated) Username for the Agent interface
67 =item _password - (Deprecated) Password for the Agent interface
77 Creates a new agent. To add the agent to the database, see L<"insert">.
81 sub table { 'agent'; }
85 Adds this agent to the database. If there is an error, returns the error,
86 otherwise returns false.
90 Deletes this agent from the database. Only agents with no customers can be
91 deleted. If there is an error, returns the error, otherwise returns false.
98 return "Can't delete an agent with customers!"
99 if qsearch( 'cust_main', { 'agentnum' => $self->agentnum } );
101 $self->SUPER::delete;
104 =item replace OLD_RECORD
106 Replaces OLD_RECORD with this one in the database. If there is an error,
107 returns the error, otherwise returns false.
111 Checks all fields to make sure this is a valid agent. If there is an error,
112 returns the error, otherwise returns false. Called by the insert and replace
121 $self->ut_numbern('agentnum')
122 || $self->ut_text('agent')
123 || $self->ut_number('typenum')
124 || $self->ut_numbern('freq')
125 || $self->ut_textn('prog')
126 || $self->ut_textn('invoice_template')
127 || $self->ut_foreign_keyn('agent_custnum', 'cust_main', 'custnum' )
129 return $error if $error;
131 if ( $self->dbdef_table->column('disabled') ) {
132 $error = $self->ut_enum('disabled', [ '', 'Y' ] );
133 return $error if $error;
136 if ( $self->dbdef_table->column('username') ) {
137 $error = $self->ut_alphan('username');
138 return $error if $error;
139 if ( length($self->username) ) {
140 my $conflict = qsearchs('agent', { 'username' => $self->username } );
141 return 'duplicate agent username (with '. $conflict->agent. ')'
142 if $conflict && $conflict->agentnum != $self->agentnum;
143 $error = $self->ut_text('password'); # ut_text... arbitrary choice
145 $self->_password('');
149 return "Unknown typenum!"
150 unless $self->agent_type;
157 Returns the FS::agent_type object (see L<FS::agent_type>) for this agent.
163 qsearchs( 'agent_type', { 'typenum' => $self->typenum } );
166 =item agent_cust_main
168 Returns the FS::cust_main object (see L<FS::cust_main>), if any, for this
173 sub agent_cust_main {
175 qsearchs( 'cust_main', { 'custnum' => $self->agent_custnum } );
178 =item pkgpart_hashref
180 Returns a hash reference. The keys of the hash are pkgparts. The value is
181 true if this agent may purchase the specified package definition. See
186 sub pkgpart_hashref {
188 $self->agent_type->pkgpart_hashref;
191 =item ticketing_queue
193 Returns the queue name corresponding with the id from the I<ticketing_queueid>
194 field, or the empty string.
198 sub ticketing_queue {
200 FS::TicketSystem->queue($self->ticketing_queueid);
203 =item num_prospect_cust_main
205 Returns the number of prospects (customers with no packages ever ordered) for
210 sub num_prospect_cust_main {
211 shift->num_sql(FS::cust_main->prospect_sql);
215 my( $self, $sql ) = @_;
216 my $statement = "SELECT COUNT(*) FROM cust_main WHERE agentnum = ? AND $sql";
217 my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
218 $sth->execute($self->agentnum) or die $sth->errstr. " executing $statement";
219 $sth->fetchrow_arrayref->[0];
222 =item prospect_cust_main
224 Returns the prospects (customers with no packages ever ordered) for this agent,
225 as cust_main objects.
229 sub prospect_cust_main {
230 shift->cust_main_sql(FS::cust_main->prospect_sql);
234 my( $self, $sql ) = @_;
235 qsearch( 'cust_main',
236 { 'agentnum' => $self->agentnum },
242 =item num_active_cust_main
244 Returns the number of active customers for this agent (customers with active
249 sub num_active_cust_main {
250 shift->num_sql(FS::cust_main->active_sql);
253 =item active_cust_main
255 Returns the active customers for this agent, as cust_main objects.
259 sub active_cust_main {
260 shift->cust_main_sql(FS::cust_main->active_sql);
263 =item num_inactive_cust_main
265 Returns the number of inactive customers for this agent (customers with no
266 active recurring packages, but otherwise unsuspended/uncancelled).
270 sub num_inactive_cust_main {
271 shift->num_sql(FS::cust_main->inactive_sql);
274 =item inactive_cust_main
276 Returns the inactive customers for this agent, as cust_main objects.
280 sub inactive_cust_main {
281 shift->cust_main_sql(FS::cust_main->inactive_sql);
285 =item num_susp_cust_main
287 Returns the number of suspended customers for this agent.
291 sub num_susp_cust_main {
292 shift->num_sql(FS::cust_main->susp_sql);
297 Returns the suspended customers for this agent, as cust_main objects.
302 shift->cust_main_sql(FS::cust_main->susp_sql);
305 =item num_cancel_cust_main
307 Returns the number of cancelled customer for this agent.
311 sub num_cancel_cust_main {
312 shift->num_sql(FS::cust_main->cancel_sql);
315 =item cancel_cust_main
317 Returns the cancelled customers for this agent, as cust_main objects.
321 sub cancel_cust_main {
322 shift->cust_main_sql(FS::cust_main->cancel_sql);
325 =item num_active_cust_pkg
327 Returns the number of active customer packages for this agent.
331 sub num_active_cust_pkg {
332 shift->num_pkg_sql(FS::cust_pkg->active_sql);
336 my( $self, $sql ) = @_;
338 "SELECT COUNT(*) FROM cust_pkg LEFT JOIN cust_main USING ( custnum )".
339 " WHERE agentnum = ? AND $sql";
340 my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
341 $sth->execute($self->agentnum) or die $sth->errstr. "executing $statement";
342 $sth->fetchrow_arrayref->[0];
345 =item num_inactive_cust_pkg
347 Returns the number of inactive customer packages (one-time packages otherwise
348 unsuspended/uncancelled) for this agent.
352 sub num_inactive_cust_pkg {
353 shift->num_pkg_sql(FS::cust_pkg->inactive_sql);
356 =item num_susp_cust_pkg
358 Returns the number of suspended customer packages for this agent.
362 sub num_susp_cust_pkg {
363 shift->num_pkg_sql(FS::cust_pkg->susp_sql);
366 =item num_cancel_cust_pkg
368 Returns the number of cancelled customer packages for this agent.
372 sub num_cancel_cust_pkg {
373 shift->num_pkg_sql(FS::cust_pkg->cancel_sql);
376 =item generate_reg_codes NUM PKGPART_ARRAYREF
378 Generates the specified number of registration codes, allowing purchase of the
379 specified package definitions. Returns an array reference of the newly
380 generated codes, or a scalar error message.
384 #false laziness w/prepay_credit::generate
385 sub generate_reg_codes {
386 my( $self, $num, $pkgparts ) = @_;
388 my @codeset = ( 'A'..'Z' );
390 local $SIG{HUP} = 'IGNORE';
391 local $SIG{INT} = 'IGNORE';
392 local $SIG{QUIT} = 'IGNORE';
393 local $SIG{TERM} = 'IGNORE';
394 local $SIG{TSTP} = 'IGNORE';
395 local $SIG{PIPE} = 'IGNORE';
397 my $oldAutoCommit = $FS::UID::AutoCommit;
398 local $FS::UID::AutoCommit = 0;
403 my $reg_code = new FS::reg_code {
404 'agentnum' => $self->agentnum,
405 'code' => join('', map($codeset[int(rand $#codeset)], (0..7) ) ),
407 my $error = $reg_code->insert($pkgparts);
409 $dbh->rollback if $oldAutoCommit;
412 push @codes, $reg_code->code;
415 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
423 Returns the number of unused registration codes for this agent.
429 my $sth = dbh->prepare(
430 "SELECT COUNT(*) FROM reg_code WHERE agentnum = ?"
431 ) or die dbh->errstr;
432 $sth->execute($self->agentnum) or die $sth->errstr;
433 $sth->fetchrow_arrayref->[0];
436 =item num_prepay_credit
438 Returns the number of unused prepaid cards for this agent.
442 sub num_prepay_credit {
444 my $sth = dbh->prepare(
445 "SELECT COUNT(*) FROM prepay_credit WHERE agentnum = ?"
446 ) or die dbh->errstr;
447 $sth->execute($self->agentnum) or die $sth->errstr;
448 $sth->fetchrow_arrayref->[0];
458 L<FS::Record>, L<FS::agent_type>, L<FS::cust_main>, L<FS::part_pkg>,
459 schema.html from the base documentation.