--
-added case-insensitive and substring to default search
-
-full history tables (notification for deleted payments)
-
-alternate templates (late invoices!)
-
-new export! (well, almost)
-
-icradius groups (usergroup table if not radgroupreply & radgroupcheck)
-
-message catalogs (infrastructure, anyway) & anything which gets sent to a
-customer from the signup server should use message catalog
-
-multi-agent signup server
-
-signup_server-realtime to run cards immediately
-
-and signup-alternate.html for free/paid packages on same signup
+- New export code!
+- Name and company searches:
+ - now case-insensative
+ - pulldown for search type
+- Email notification for deleted payments
+- History tables - complete history of all database changes
+- Alternate invoice templates for things like late noitces
+- ICRADIUS groups (usergroup table if not radgroupreply & radgroupcheck)
+- Signup server
+ - Error messages in message catalog
+ - Agent is now selectable (multiple signup servers for different agents
+ can now run on the same machine)
+ - signup_server-realtime configuration option to run cards immediately
+ - signup-alternate.html example for free and pay packages on the same
+ signup page
+- Texas tax
+
+schema diagram
+
+--
L<FS::Msgcat> - Message catalog
-L<FS::SearchCache> - Message catalog
+L<FS::SearchCache> - Search cache
L<FS::raddb> - RADIUS dictionary
L<FS::queue_arg> - Job arguments
+L<FS::queue_depend> - Job dependencies
+
L<FS::msgcat> - Message catalogs
=head1 Remote API modules
my $method = "radius_$table";
my %attrib = $svc_acct->$method;
next unless keys %attrib;
- my $error = $self->sqlradius_queue( $svc_acct->svcnum, 'insert',
+ my $err_or_queue = $self->sqlradius_queue( $svc_acct->svcnum, 'insert',
$table, $svc_acct->username, %attrib );
- return $error if $error;
+ return $err_or_queue unless ref($err_or_queue);
}
my @groups = $svc_acct->radius_groups;
if ( @groups ) {
- my $error = $self->sqlradius_queue( $svc_acct->svcnum, 'usergroup_insert',
+ my $err_or_queue = $self->sqlradius_queue(
+ $svc_acct->svcnum, 'usergroup_insert',
$svc_acct->username, @groups );
- return $error if $error;
+ return $err_or_queue unless ref($err_or_queue);
}
'';
}
#return "can't (yet) change username with sqlradius"
# if $old->username ne $new->username;
if ( $old->username ne $new->username ) {
- my $error = $self->sqlradius_queue( $new->svcnum, 'rename',
+ my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'rename',
$new->username, $old->username );
- return $error if $error;
+ return $err_or_queue unless ref($err_or_queue);
}
foreach my $table (qw(reply check)) {
|| $new{$_} ne $old{$_} #changed
} keys %new
) {
- my $error = $self->sqlradius_queue( $new->svcnum, 'insert',
+ my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'insert',
$table, $new->username, %new );
- return $error if $error;
+ return $err_or_queue unless ref($err_or_queue);
}
my @del = grep { !exists $new{$_} } keys %old;
if ( @del ) {
- my $error = $self->sqlradius_queue( $new->svcnum, 'attrib_delete',
+ my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'attrib_delete',
$table, $new->username, @del );
- return $error if $error;
+ return $err_or_queue unless ref($err_or_queue);
}
}
}
if ( @delgroups ) {
- my $error = $self->sqlradius_queue( $new->svcnum, 'usergroup_delete',
+ my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'usergroup_delete',
$new->username, @delgroups );
- return $error if $error;
+ return $err_or_queue unless ref($err_or_queue);
}
if ( @newgroups ) {
- my $error = $self->sqlradius_queue( $new->svcnum, 'usergroup_insert',
+ my $err_or_queue = $self->sqlradius_queue( $new->svcnum, 'usergroup_insert',
$new->username, @newgroups );
- return $error if $error;
+ return $err_or_queue unless ref($err_or_queue);
}
'';
sub _export_delete {
my( $self, $svc_acct ) = (shift, shift);
- $self->sqlradius_queue( $svc_acct->svcnum, 'delete',
+ my $err_or_queue = $self->sqlradius_queue( $svc_acct->svcnum, 'delete',
$svc_acct->username );
+ ref($err_or_queue) ? '' : $err_or_queue;
}
sub sqlradius_queue {
$self->option('username'),
$self->option('password'),
@_,
- );
+ ) or $queue;
}
sub sqlradius_insert { #subroutine, not method
use FS::Record qw( qsearch qsearchs dbh );
#use FS::queue;
use FS::queue_arg;
+use FS::queue_depend;
use FS::cust_svc;
@ISA = qw(FS::Record);
local $FS::UID::AutoCommit = 0;
my $dbh = dbh;
- my @args = qsearch( 'queue_arg', { 'jobnum' => $self->jobnum } );
+ my @del = qsearch( 'queue_arg', { 'jobnum' => $self->jobnum } );
+ push @del, qsearch( 'queue_depend', { 'depend_jobnum' => $self->jobnum } );
my $error = $self->SUPER::delete;
if ( $error ) {
return $error;
}
- foreach my $arg ( @args ) {
- $error = $arg->delete;
+ foreach my $del ( @del ) {
+ $error = $del->delete;
if ( $error ) {
$dbh->rollback if $oldAutoCommit;
return $error;
=item args
+Returns a list of the arguments associated with this job.
+
=cut
sub args {
qsearchs('cust_svc', { 'svcnum' => $self->svcnum } );
}
+=item depend_insert OTHER_JOBNUM
+
+Inserts a dependancy for this job. If there is an error, returns the error,
+otherwise returns false.
+
+When using job dependancies, you should wrap the insertion of jobs in a
+database transaction.
+
+=cut
+
+sub depend_insert {
+ my($self, $other_jobnum) = @_;
+ my $queue_depend = new FS::queue_depend (
+ 'jobnum' => $self->jobnum,
+ 'depend_jobnum' => $other_jobnum,
+ );
+ $queue_depend->insert;
+}
+
+=back
+
+=head1 SUBROUTINES
+
+=over 4
+
=item joblisting HASHREF NOACTIONS
=cut
=head1 VERSION
-$Id: queue.pm,v 1.11 2002-04-13 08:51:54 ivan Exp $
+$Id: queue.pm,v 1.12 2002-05-15 13:24:24 ivan Exp $
=head1 BUGS
--- /dev/null
+package FS::queue_depend;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw( qsearch qsearchs );
+use FS::queue;
+
+@ISA = qw(FS::Record);
+
+=head1 NAME
+
+FS::queue_depend - Object methods for queue_depend records
+
+=head1 SYNOPSIS
+
+ use FS::queue_depend;
+
+ $record = new FS::queue_depend \%hash;
+ $record = new FS::queue_depend { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::queue_depend object represents an job dependancy. FS::queue_depend
+inherits from FS::Record. The following fields are currently supported:
+
+=over 4
+
+=item dependnum - primary key
+
+=item jobnum - source jobnum (see L<FS::queue>).
+
+=item depend_jobnum - dependancy jobnum (see L<FS::queue>)
+
+=back
+
+The job specified by B<jobnum> depends on the job specified B<depend_jobnum> -
+the B<jobnum> job will not be run until the B<depend_jobnum> job has completed
+sucessfully (or manually removed).
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new dependancy. To add the dependancy to the database, see
+L<"insert">.
+
+Note that this stores the hash reference, not a distinct copy of the hash it
+points to. You can ask the object for a copy with the I<hash> method.
+
+=cut
+
+# the new method can be inherited from FS::Record, if a table method is defined
+
+sub table { 'queue_depend'; }
+
+=item insert
+
+Adds this record to the database. If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+# the insert method can be inherited from FS::Record
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+# the delete method can be inherited from FS::Record
+
+=item replace OLD_RECORD
+
+Replaces the OLD_RECORD with this one in the database. If there is an error,
+returns the error, otherwise returns false.
+
+=cut
+
+# the replace method can be inherited from FS::Record
+
+=item check
+
+Checks all fields to make sure this is a valid dependancy. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+and replace methods.
+
+=cut
+
+sub check {
+ my $self = shift;
+
+ $self->ut_numbern('dependnum')
+ || $self->ut_foreign_key('jobnum', 'queue', 'jobnum')
+ || $self->ut_foreign_key('depend_jobnum', 'queue', 'jobnum')
+ ;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::queue>, L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
FS/radius_usergroup.pm
FS/queue.pm
FS/queue_arg.pm
+FS/queue_depend.pm
FS/msgcat.pm
FS/cust_tax_exempt.pm
t/agent.t
}
$warnkids=0;
+ my $nodepend = 'AND 0 = ( SELECT COUNT(*) FROM queue_depend'.
+ ' WHERE queue_depend.jobnum = queue.jobnum ) ';
+
my $job = qsearchs(
'queue',
{ 'status' => 'new' },
'',
driver_name =~ /^mysql$/i
- ? 'ORDER BY jobnum LIMIT 1 FOR UPDATE'
- : 'ORDER BY jobnum FOR UPDATE LIMIT 1'
+ ? "$nodepend ORDER BY jobnum LIMIT 1 FOR UPDATE"
+ : "$nodepend ORDER BY jobnum FOR UPDATE LIMIT 1"
) or do {
sleep 5; #connecting to db is expensive
next;
$kids++;
} else { #kid time
- #get new db handles
+ #get new db handle
$FS::UID::dbh->{InactiveDestroy} = 1;
- $FS::svc_acct::icradius_dbh->{InactiveDestroy} = 1
- if $FS::svc_acct::icradius_dbh;
+
forksuidsetup($user);
#auto-use export classes...
--- /dev/null
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::queue_depend;
+$loaded=1;
+print "ok 1\n";
#not changable yet
FREESIDE_CONF = /usr/local/etc/freeside
-#VERSION=1.4.0pre12
-#TAG=freeside_1_4_0_pre12
VERSION=1.4.0pre13
TAG=freeside_1_4_0_pre13
#VERSION=1.4.0beta1
--- /dev/null
+the following is necessary to upgrade from 1.4.0pre12 to 1.4.0pre13
+
+if you're upgrading from before 1.4.0pre13 see README.1.4.0pre12 first!
+
+if you're upgrading from 1.3.1 follow the instructions in
+httemplate/docs/upgrade8.html instead
+
+----
+
+install the FS perl modules and httemplate as per install.html or upgrade8.html
+
+CREATE TABLE queue_depend (
+ dependnum int primary key,
+ jobnum int not null,
+ depend_jobnum int not null
+);
+CREATE INDEX queue_depend1 ON queue_depend ( jobnum );
+CREATE INDEX queue_depend2 ON queue_depend ( depend_jobnum );
+
+Run bin/dbdef-create
+
+Run bin/create-history-tables [username] queue_depend
+
+Run bin/dbdef-create again
+
+Restart Apache and freeside-queued
+
#!/usr/bin/perl -Tw
#
-# $Id: fs-setup,v 1.90 2002-05-04 15:00:18 ivan Exp $
+# $Id: fs-setup,v 1.91 2002-05-15 13:24:24 ivan Exp $
#to delay loading dbdef until we're ready
BEGIN { $FS::Record::setup_hack = 1; }
'index' => [ [ 'jobnum' ] ],
},
+ 'queue_depend' => {
+ 'columns' => [
+ 'dependnum', 'int', '', '',
+ 'jobnum', 'int', '', '',
+ 'depend_jobnum', 'int', '', '',
+ ],
+ 'primary_key' => 'dependnum',
+ 'unique' => [],
+ 'index' => [ [ 'jobnum' ], [ 'depend_jobnum' ] ],
+ },
+
'export_svc' => {
'columns' => [
'exportsvcnum' => 'int', '', '',
sub _export_insert {
my($self, $svc_something) = (shift, shift);
- $self->myexport_queue( $svc_acct->svcnum, 'insert',
+ $err_or_queue = $self->myexport_queue( $svc_acct->svcnum, 'insert',
$svc_something->username, $svc_something->_password );
+ ref($err_or_queue) ? '' : $err_or_queue;
}
sub _export_replace {
#return "can't change username with myexport"
# if $old->username ne $new->username;
#return '' unless $old->_password ne $new->_password;
- $self->myexport_queue( $new->svcnum,
+ $err_or_queue = $self->myexport_queue( $new->svcnum,
'replace', $new->username, $new->_password );
+ ref($err_or_queue) ? '' : $err_or_queue;
}
sub _export_delete {
my( $self, $svc_something ) = (shift, shift);
- $self->myexport_queue( $svc_acct->svcnum,
+ $err_or_queue = $self->myexport_queue( $svc_acct->svcnum,
'delete', $svc_something->username );
+ ref($err_or_queue) ? '' : $err_or_queue;
}
#a good idea to queue anything that could fail or take any time
'svcnum' => $svcnum,
'job' => "FS::part_export::myexport::myexport_$method",
};
- $queue->insert( @_ );
+ $queue->insert( @_ ) or $queue;
}
sub myexport_insert { #subroutine, not method
$ su freeside
$ bin/populate-msgcat <b>username</b>
</pre>
- <li><tt>freeside-queued</tt> was installed with the Perl modules. Start it now and ensure that is run upon system startup.
+ <li><tt>freeside-queued</tt> was installed with the Perl modules. Start it now and ensure that is run upon system startup (Do this manually, or, edit the top-level Makefile, replacing INIT_FILE with the appropriate location on your system, and run <tt>make install-init</tt>.
<li>Now proceed to the initial <a href="admin.html">administration</a> of your installation.
</ul>
</body>
<li>jobnum - <a href="#queue">job</a>
<li>arg - argument
</ul>
+ <li><a name="queue_depend" href="man/FS/queue_depend.html">queue_depend</a> - job dependancies
+ <ul>
+ <li>dependnum - primary key
+ <li>jobnum - source jobnum
+ <li>depend_jobnum - dependancy jobnum
+ </ul>
<li><a name="radius_usergroup" href="man/FS/radius_usergroup.html">radius_usergroup</a> - Link users to RADIUS groups.
<ul>
<li>usergroupnum - primary key
);
CREATE INDEX queue_arg1 ON queue_arg ( jobnum );
+CREATE TABLE queue_depend (
+ dependnum int primary key,
+ jobnum int not null,
+ depend_jobnum int not null
+);
+CREATE INDEX queue_depend1 ON queue_depend ( jobnum );
+CREATE INDEX queue_depend2 ON queue_depend ( depend_jobnum );
+
CREATE TABLE part_pop_local (
localnum int primary key,
popnum int not null,