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')
121 return $error if $error;
123 if ( $self->dbdef_table->column('disabled') ) {
124 $error = $self->ut_enum('disabled', [ '', 'Y' ] );
125 return $error if $error;
128 if ( $self->dbdef_table->column('username') ) {
129 $error = $self->ut_alphan('username');
130 return $error if $error;
131 if ( length($self->username) ) {
132 my $conflict = qsearchs('agent', { 'username' => $self->username } );
133 return 'duplicate agent username (with '. $conflict->agent. ')'
134 if $conflict && $conflict->agentnum != $self->agentnum;
135 $error = $self->ut_text('password'); # ut_text... arbitrary choice
137 $self->_password('');
141 return "Unknown typenum!"
142 unless $self->agent_type;
149 Returns the FS::agent_type object (see L<FS::agent_type>) for this agent.
155 qsearchs( 'agent_type', { 'typenum' => $self->typenum } );
158 =item pkgpart_hashref
160 Returns a hash reference. The keys of the hash are pkgparts. The value is
161 true if this agent may purchase the specified package definition. See
166 sub pkgpart_hashref {
168 $self->agent_type->pkgpart_hashref;
171 =item ticketing_queue
173 Returns the queue name corresponding with the id from the I<ticketing_queueid>
174 field, or the empty string.
178 sub ticketing_queue {
180 FS::TicketSystem->queue($self->ticketing_queueid);
183 =item num_prospect_cust_main
185 Returns the number of prospects (customers with no packages ever ordered) for
190 sub num_prospect_cust_main {
191 shift->num_sql(FS::cust_main->prospect_sql);
195 my( $self, $sql ) = @_;
196 my $statement = "SELECT COUNT(*) FROM cust_main WHERE agentnum = ? AND $sql";
197 my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
198 $sth->execute($self->agentnum) or die $sth->errstr. " executing $statement";
199 $sth->fetchrow_arrayref->[0];
202 =item prospect_cust_main
204 Returns the prospects (customers with no packages ever ordered) for this agent,
205 as cust_main objects.
209 sub prospect_cust_main {
210 shift->cust_main_sql(FS::cust_main->prospect_sql);
214 my( $self, $sql ) = @_;
215 qsearch( 'cust_main',
216 { 'agentnum' => $self->agentnum },
222 =item num_active_cust_main
224 Returns the number of active customers for this agent (customers with active
229 sub num_active_cust_main {
230 shift->num_sql(FS::cust_main->active_sql);
233 =item active_cust_main
235 Returns the active customers for this agent, as cust_main objects.
239 sub active_cust_main {
240 shift->cust_main_sql(FS::cust_main->active_sql);
243 =item num_inactive_cust_main
245 Returns the number of inactive customers for this agent (customers with no
246 active recurring packages, but otherwise unsuspended/uncancelled).
250 sub num_inactive_cust_main {
251 shift->num_sql(FS::cust_main->inactive_sql);
254 =item inactive_cust_main
256 Returns the inactive customers for this agent, as cust_main objects.
260 sub inactive_cust_main {
261 shift->cust_main_sql(FS::cust_main->inactive_sql);
265 =item num_susp_cust_main
267 Returns the number of suspended customers for this agent.
271 sub num_susp_cust_main {
272 shift->num_sql(FS::cust_main->susp_sql);
277 Returns the suspended customers for this agent, as cust_main objects.
282 shift->cust_main_sql(FS::cust_main->susp_sql);
285 =item num_cancel_cust_main
287 Returns the number of cancelled customer for this agent.
291 sub num_cancel_cust_main {
292 shift->num_sql(FS::cust_main->cancel_sql);
295 =item cancel_cust_main
297 Returns the cancelled customers for this agent, as cust_main objects.
301 sub cancel_cust_main {
302 shift->cust_main_sql(FS::cust_main->cancel_sql);
305 =item num_active_cust_pkg
307 Returns the number of active customer packages for this agent.
311 sub num_active_cust_pkg {
312 shift->num_pkg_sql(FS::cust_pkg->active_sql);
316 my( $self, $sql ) = @_;
318 "SELECT COUNT(*) FROM cust_pkg LEFT JOIN cust_main USING ( custnum )".
319 " WHERE agentnum = ? AND $sql";
320 my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
321 $sth->execute($self->agentnum) or die $sth->errstr. "executing $statement";
322 $sth->fetchrow_arrayref->[0];
325 =item num_inactive_cust_pkg
327 Returns the number of inactive customer packages (one-time packages otherwise
328 unsuspended/uncancelled) for this agent.
332 sub num_inactive_cust_pkg {
333 shift->num_pkg_sql(FS::cust_pkg->inactive_sql);
336 =item num_susp_cust_pkg
338 Returns the number of suspended customer packages for this agent.
342 sub num_susp_cust_pkg {
343 shift->num_pkg_sql(FS::cust_pkg->susp_sql);
346 =item num_cancel_cust_pkg
348 Returns the number of cancelled customer packages for this agent.
352 sub num_cancel_cust_pkg {
353 shift->num_pkg_sql(FS::cust_pkg->cancel_sql);
356 =item generate_reg_codes NUM PKGPART_ARRAYREF
358 Generates the specified number of registration codes, allowing purchase of the
359 specified package definitions. Returns an array reference of the newly
360 generated codes, or a scalar error message.
364 #false laziness w/prepay_credit::generate
365 sub generate_reg_codes {
366 my( $self, $num, $pkgparts ) = @_;
368 my @codeset = ( 'A'..'Z' );
370 local $SIG{HUP} = 'IGNORE';
371 local $SIG{INT} = 'IGNORE';
372 local $SIG{QUIT} = 'IGNORE';
373 local $SIG{TERM} = 'IGNORE';
374 local $SIG{TSTP} = 'IGNORE';
375 local $SIG{PIPE} = 'IGNORE';
377 my $oldAutoCommit = $FS::UID::AutoCommit;
378 local $FS::UID::AutoCommit = 0;
383 my $reg_code = new FS::reg_code {
384 'agentnum' => $self->agentnum,
385 'code' => join('', map($codeset[int(rand $#codeset)], (0..7) ) ),
387 my $error = $reg_code->insert($pkgparts);
389 $dbh->rollback if $oldAutoCommit;
392 push @codes, $reg_code->code;
395 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
403 Returns the number of unused registration codes for this agent.
409 my $sth = dbh->prepare(
410 "SELECT COUNT(*) FROM reg_code WHERE agentnum = ?"
411 ) or die dbh->errstr;
412 $sth->execute($self->agentnum) or die $sth->errstr;
413 $sth->fetchrow_arrayref->[0];
416 =item num_prepay_credit
418 Returns the number of unused prepaid cards for this agent.
422 sub num_prepay_credit {
424 my $sth = dbh->prepare(
425 "SELECT COUNT(*) FROM prepay_credit WHERE agentnum = ?"
426 ) or die dbh->errstr;
427 $sth->execute($self->agentnum) or die $sth->errstr;
428 $sth->fetchrow_arrayref->[0];
438 L<FS::Record>, L<FS::agent_type>, L<FS::cust_main>, L<FS::part_pkg>,
439 schema.html from the base documentation.