5 use FS::Record qw( dbh qsearch qsearchs );
10 #use Crypt::YAPassGen;
12 @ISA = qw( FS::Record );
16 FS::agent - Object methods for agent records
22 $record = new FS::agent \%hash;
23 $record = new FS::agent { 'column' => 'value' };
25 $error = $record->insert;
27 $error = $new_record->replace($old_record);
29 $error = $record->delete;
31 $error = $record->check;
33 $agent_type = $record->agent_type;
35 $hashref = $record->pkgpart_hashref;
36 #may purchase $pkgpart if $hashref->{$pkgpart};
40 An FS::agent object represents an agent. Every customer has an agent. Agents
41 can be used to track things like resellers or salespeople. FS::agent inherits
42 from FS::Record. The following fields are currently supported:
46 =item agentnum - primary key (assigned automatically for new agents)
48 =item agent - Text name of this agent
50 =item typenum - Agent type. See L<FS::agent_type>
52 =item prog - For future use.
54 =item freq - For future use.
56 =item disabled - Disabled flag, empty or 'Y'
58 =item username - Username for the Agent interface
60 =item _password - Password for the Agent interface
70 Creates a new agent. To add the agent to the database, see L<"insert">.
74 sub table { 'agent'; }
78 Adds this agent to the database. If there is an error, returns the error,
79 otherwise returns false.
83 Deletes this agent from the database. Only agents with no customers can be
84 deleted. If there is an error, returns the error, otherwise returns false.
91 return "Can't delete an agent with customers!"
92 if qsearch( 'cust_main', { 'agentnum' => $self->agentnum } );
97 =item replace OLD_RECORD
99 Replaces OLD_RECORD with this one in the database. If there is an error,
100 returns the error, otherwise returns false.
104 Checks all fields to make sure this is a valid agent. If there is an error,
105 returns the error, otherwise returns false. Called by the insert and replace
114 $self->ut_numbern('agentnum')
115 || $self->ut_text('agent')
116 || $self->ut_number('typenum')
117 || $self->ut_numbern('freq')
118 || $self->ut_textn('prog')
120 return $error if $error;
122 if ( $self->dbdef_table->column('disabled') ) {
123 $error = $self->ut_enum('disabled', [ '', 'Y' ] );
124 return $error if $error;
127 if ( $self->dbdef_table->column('username') ) {
128 $error = $self->ut_alphan('username');
129 return $error if $error;
130 if ( length($self->username) ) {
131 my $conflict = qsearchs('agent', { 'username' => $self->username } );
132 return 'duplicate agent username (with '. $conflict->agent. ')'
133 if $conflict && $conflict->agentnum != $self->agentnum;
134 $error = $self->ut_text('password'); # ut_text... arbitrary choice
136 $self->_password('');
140 return "Unknown typenum!"
141 unless $self->agent_type;
148 Returns the FS::agent_type object (see L<FS::agent_type>) for this agent.
154 qsearchs( 'agent_type', { 'typenum' => $self->typenum } );
157 =item pkgpart_hashref
159 Returns a hash reference. The keys of the hash are pkgparts. The value is
160 true if this agent may purchase the specified package definition. See
165 sub pkgpart_hashref {
167 $self->agent_type->pkgpart_hashref;
170 =item num_prospect_cust_main
172 Returns the number of prospects (customers with no packages ever ordered) for
177 sub num_prospect_cust_main {
178 shift->num_sql(FS::cust_main->prospect_sql);
182 my( $self, $sql ) = @_;
183 my $statement = "SELECT COUNT(*) FROM cust_main WHERE agentnum = ? AND $sql";
184 my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
185 $sth->execute($self->agentnum) or die $sth->errstr. "executing $statement";
186 $sth->fetchrow_arrayref->[0];
189 =item prospect_cust_main
191 Returns the prospects (customers with no packages ever ordered) for this agent,
192 as cust_main objects.
196 sub prospect_cust_main {
197 shift->cust_main_sql(FS::cust_main->prospect_sql);
201 my( $self, $sql ) = @_;
202 qsearch( 'cust_main',
203 { 'agentnum' => $self->agentnum },
209 =item num_active_cust_main
211 Returns the number of active customers for this agent.
215 sub num_active_cust_main {
216 shift->num_sql(FS::cust_main->active_sql);
219 =item active_cust_main
221 Returns the active customers for this agent, as cust_main objects.
225 sub active_cust_main {
226 shift->cust_main_sql(FS::cust_main->active_sql);
229 =item num_susp_cust_main
231 Returns the number of suspended customers for this agent.
235 sub num_susp_cust_main {
236 shift->num_sql(FS::cust_main->susp_sql);
241 Returns the suspended customers for this agent, as cust_main objects.
246 shift->cust_main_sql(FS::cust_main->susp_sql);
249 =item num_cancel_cust_main
251 Returns the number of cancelled customer for this agent.
255 sub num_cancel_cust_main {
256 shift->num_sql(FS::cust_main->cancel_sql);
259 =item cancel_cust_main
261 Returns the cancelled customers for this agent, as cust_main objects.
265 sub cancel_cust_main {
266 shift->cust_main_sql(FS::cust_main->cancel_sql);
269 =item num_active_cust_pkg
271 Returns the number of active customer packages for this agent.
275 sub num_active_cust_pkg {
276 shift->num_pkg_sql(FS::cust_pkg->active_sql);
280 my( $self, $sql ) = @_;
282 "SELECT COUNT(*) FROM cust_pkg LEFT JOIN cust_main USING ( custnum )".
283 " WHERE agentnum = ? AND $sql";
284 my $sth = dbh->prepare($statement) or die dbh->errstr." preparing $statement";
285 $sth->execute($self->agentnum) or die $sth->errstr. "executing $statement";
286 $sth->fetchrow_arrayref->[0];
289 =item num_susp_cust_pkg
291 Returns the number of suspended customer packages for this agent.
295 sub num_susp_cust_pkg {
296 shift->num_pkg_sql(FS::cust_pkg->susp_sql);
299 =item num_cancel_cust_pkg
301 Returns the number of cancelled customer packages for this agent.
305 sub num_cancel_cust_pkg {
306 shift->num_pkg_sql(FS::cust_pkg->cancel_sql);
309 =item generate_reg_codes NUM PKGPART_ARRAYREF
311 Generates the specified number of registration codes, allowing purchase of the
312 specified package definitions. Returns an array reference of the newly
313 generated codes, or a scalar error message.
317 #false laziness w/prepay_credit::generate
318 sub generate_reg_codes {
319 my( $self, $num, $pkgparts ) = @_;
321 my @codeset = ( 'A'..'Z' );
323 local $SIG{HUP} = 'IGNORE';
324 local $SIG{INT} = 'IGNORE';
325 local $SIG{QUIT} = 'IGNORE';
326 local $SIG{TERM} = 'IGNORE';
327 local $SIG{TSTP} = 'IGNORE';
328 local $SIG{PIPE} = 'IGNORE';
330 my $oldAutoCommit = $FS::UID::AutoCommit;
331 local $FS::UID::AutoCommit = 0;
336 my $reg_code = new FS::reg_code {
337 'agentnum' => $self->agentnum,
338 'code' => join('', map($codeset[int(rand $#codeset)], (0..7) ) ),
340 my $error = $reg_code->insert($pkgparts);
342 $dbh->rollback if $oldAutoCommit;
345 push @codes, $reg_code->code;
348 $dbh->commit or die $dbh->errstr if $oldAutoCommit;
356 Returns the number of unused registration codes for this agent.
362 my $sth = dbh->prepare(
363 "SELECT COUNT(*) FROM reg_code WHERE agentnum = ?"
364 ) or die dbh->errstr;
365 $sth->execute($self->agentnum) or die $sth->errstr;
366 $sth->fetchrow_arrayref->[0];
369 =item num_prepay_credit
371 Returns the number of unused prepaid cards for this agent.
375 sub num_prepay_credit {
377 my $sth = dbh->prepare(
378 "SELECT COUNT(*) FROM prepay_credit WHERE agentnum = ?"
379 ) or die dbh->errstr;
380 $sth->execute($self->agentnum) or die $sth->errstr;
381 $sth->fetchrow_arrayref->[0];
391 L<FS::Record>, L<FS::agent_type>, L<FS::cust_main>, L<FS::part_pkg>,
392 schema.html from the base documentation.