summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FS/FS.pm4
-rw-r--r--FS/FS/ClientAPI/Signup.pm31
-rw-r--r--FS/FS/agent.pm61
-rw-r--r--FS/FS/cust_pkg.pm23
-rw-r--r--FS/FS/part_pkg.pm5
-rw-r--r--FS/FS/reg_code.pm223
-rw-r--r--FS/FS/reg_code_pkg.pm135
-rw-r--r--FS/MANIFEST4
-rwxr-xr-xFS/bin/freeside-setup20
-rw-r--r--FS/t/reg_code.t5
-rw-r--r--FS/t/reg_code_pkg.t5
-rw-r--r--README.1.5.0pre719
-rw-r--r--fs_signup/FS-SignupClient/cgi/regcode.html14
-rwxr-xr-xfs_signup/FS-SignupClient/cgi/signup.cgi13
-rwxr-xr-xfs_signup/FS-SignupClient/cgi/signup.html4
-rw-r--r--httemplate/docs/install.html1
-rw-r--r--httemplate/docs/schema.html11
-rw-r--r--httemplate/docs/upgrade10.html21
-rw-r--r--httemplate/edit/process/reg_code.cgi41
-rw-r--r--httemplate/edit/reg_code.cgi36
-rw-r--r--httemplate/search/reg_code.html35
21 files changed, 698 insertions, 13 deletions
diff --git a/FS/FS.pm b/FS/FS.pm
index 3bbd66fb6..57a1f6cfe 100644
--- a/FS/FS.pm
+++ b/FS/FS.pm
@@ -88,6 +88,10 @@ L<FS::part_pkg_option> - Package definition option class
L<FS::pkg_svc> - Class linking package definitions (see L<FS::part_pkg>) with
service definitions (see L<FS::part_svc>)
+L<FS::reg_code> - One-time registration codes
+
+L<FS::reg_code_pkg> - Class linking registration codes (see L<FS::reg_code>) with package definitions (see L<FS::part_pkg>)
+
L<FS::rate> - Rate plans for call billing
L<FS::rate_region> - Rate regions for call billing
diff --git a/FS/FS/ClientAPI/Signup.pm b/FS/FS/ClientAPI/Signup.pm
index dc627e9bd..46ef9e4d5 100644
--- a/FS/FS/ClientAPI/Signup.pm
+++ b/FS/FS/ClientAPI/Signup.pm
@@ -14,6 +14,7 @@ use FS::cust_pkg;
use FS::svc_acct;
use FS::acct_snarf;
use FS::queue;
+use FS::reg_code;
use FS::ClientAPI; #hmm
FS::ClientAPI->register_handlers(
@@ -105,7 +106,22 @@ sub signup_info {
}
$signup_info->{'part_pkg'} = [];
- if ( $packet->{'promo_code'} ) {
+
+ if ( $packet->{'reg_code'} ) {
+ $signup_info->{'part_pkg'} =
+ [ map { { 'payby' => [ $_->payby ], %{$_->hashref} } }
+ grep { $_->svcpart('svc_acct') }
+ map { $_->part_pkg }
+ qsearchs( 'reg_code', { 'code' => $packet->{'reg_code'},
+ 'agentnum' => $agentnum, } )
+
+ ];
+
+ $signup_info->{'error'} = 'Unknown registration code'
+ unless @{ $signup_info->{'part_pkg'} };
+
+ } elsif ( $packet->{'promo_code'} ) {
+
$signup_info->{'part_pkg'} =
[ map { { 'payby' => [ $_->payby ], %{$_->hashref} } }
grep { $_->svcpart('svc_acct') }
@@ -209,10 +225,18 @@ sub new_customer {
or return { 'error' => "WARNING: unknown pkgpart: $pkgpart" };
my $svcpart = $part_pkg->svcpart('svc_acct');
+ my $reg_code = '';
+ if ( $packet->{'reg_code'} ) {
+ $reg_code = qsearchs( 'reg_code', { 'code' => $packet->{'reg_code'},
+ 'agentnum' => $agentnum, } )
+ or return { 'error' => 'Unknown registration code' };
+ }
+
my $cust_pkg = new FS::cust_pkg ( {
#later#'custnum' => $custnum,
'pkgpart' => $packet->{'pkgpart'},
'promo_code' => $packet->{'promo_code'},
+ 'reg_code' => $packet->{'reg_code'},
} );
#my $error = $cust_pkg->check;
#return { 'error' => $error } if $error;
@@ -305,6 +329,11 @@ sub new_customer {
}
+ if ( $reg_code ) {
+ $error = $reg_code->delete;
+ return { 'error' => $error } if $error;
+ }
+
$error = $placeholder->delete;
return { 'error' => $error } if $error;
diff --git a/FS/FS/agent.pm b/FS/FS/agent.pm
index a9e41a666..3d8e67739 100644
--- a/FS/FS/agent.pm
+++ b/FS/FS/agent.pm
@@ -5,6 +5,8 @@ use vars qw( @ISA );
use FS::Record qw( dbh qsearch qsearchs );
use FS::cust_main;
use FS::agent_type;
+use FS::reg_code;
+#use Crypt::YAPassGen;
@ISA = qw( FS::Record );
@@ -264,6 +266,65 @@ sub cancel_cust_main {
shift->cust_main_sql(FS::cust_main->cancel_sql);
}
+=item generate_reg_codes NUM PKGPART_ARRAYREF
+
+Generates the specified number of registration codes, allowing purchase of the
+specified package definitions. Returns an array reference of the newly
+generated codes, or a scalar error message.
+
+=cut
+
+sub generate_reg_codes {
+ my( $self, $num, $pkgparts ) = @_;
+
+ my @codeset = ( 'A'..'Z' );
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ my @codes = ();
+ for ( 1 ... $num ) {
+ my $reg_code = new FS::reg_code {
+ 'agentnum' => $self->agentnum,
+ 'code' => join('', map($codeset[int(rand $#codeset)], (0..7) ) ),
+ };
+ my $error = $reg_code->insert($pkgparts);
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ push @codes, $reg_code->code;
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+
+ \@codes;
+
+}
+
+=item num_reg_code
+
+Returns the number of unused registration codes for this agent.
+
+=cut
+
+sub num_reg_code {
+ my $self = shift;
+ my $sth = dbh->prepare(
+ "SELECT COUNT(*) FROM reg_code WHERE agentnum = ?"
+ ) or die dbh->errstr;
+ $sth->execute($self->agentnum) or die $sth->errstr;
+ $sth->fetchrow_arrayref->[0];
+}
+
=back
=head1 BUGS
diff --git a/FS/FS/cust_pkg.pm b/FS/FS/cust_pkg.pm
index 0c39f6868..a6115a0a0 100644
--- a/FS/FS/cust_pkg.pm
+++ b/FS/FS/cust_pkg.pm
@@ -12,6 +12,7 @@ use FS::type_pkgs;
use FS::pkg_svc;
use FS::cust_bill_pkg;
use FS::h_cust_svc;
+use FS::reg_code;
# need to 'use' these instead of 'require' in sub { cancel, suspend, unsuspend,
# setup }
@@ -176,6 +177,15 @@ sub insert {
return $error;
}
+ #if ( $self->reg_code ) {
+ # my $reg_code = qsearchs('reg_code', { 'code' => $self->reg_code } );
+ # $error = $reg_code->delete;
+ # if ( $error ) {
+ # $dbh->rollback if $oldAutoCommit;
+ # return $error;
+ # }
+ #}
+
my $conf = new FS::Conf;
my $cust_main = $self->cust_main;
my $part_pkg = $self->part_pkg;
@@ -289,7 +299,17 @@ sub check {
;
return $error if $error;
- if ( $self->promo_code ) {
+ if ( $self->reg_code ) {
+
+ unless ( grep { $self->pkgpart == $_->pkgpart }
+ map { $_->reg_code_pkg }
+ qsearchs( 'reg_code', { 'code' => $self->reg_code,
+ 'agentnum' => $self->cust_main->agentnum })
+ ) {
+ return "Unknown registraiton code";
+ }
+
+ } elsif ( $self->promo_code ) {
my $promo_part_pkg =
qsearchs('part_pkg', {
@@ -297,7 +317,6 @@ sub check {
'promo_code' => { op=>'ILIKE', value=>$self->promo_code },
} );
return 'Unknown promotional code' unless $promo_part_pkg;
- $self->pkgpart($promo_part_pkg->pkgpart);
} else {
diff --git a/FS/FS/part_pkg.pm b/FS/FS/part_pkg.pm
index cef4a612a..f210a67d4 100644
--- a/FS/FS/part_pkg.pm
+++ b/FS/FS/part_pkg.pm
@@ -584,7 +584,7 @@ Returns the option value for the given name, or the empty string.
=cut
sub option {
- my( $self, $opt ) = @_;
+ my( $self, $opt, $ornull ) = @_;
my $part_pkg_option =
qsearchs('part_pkg_option', {
pkgpart => $self->pkgpart,
@@ -594,7 +594,8 @@ sub option {
my %plandata = map { /^(\w+)=(.*)$/; ( $1 => $2 ); }
split("\n", $self->get('plandata') );
return $plandata{$opt} if exists $plandata{$opt};
- cluck "Package definition option $opt not found in options or plandata!\n";
+ cluck "Package definition option $opt not found in options or plandata!\n"
+ unless $ornull;
'';
}
diff --git a/FS/FS/reg_code.pm b/FS/FS/reg_code.pm
new file mode 100644
index 000000000..f48ccf048
--- /dev/null
+++ b/FS/FS/reg_code.pm
@@ -0,0 +1,223 @@
+package FS::reg_code;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw(qsearch dbh);
+use FS::agent;
+use FS::reg_code_pkg;
+
+@ISA = qw(FS::Record);
+
+=head1 NAME
+
+FS::reg_code - One-time registration codes
+
+=head1 SYNOPSIS
+
+ use FS::reg_code;
+
+ $record = new FS::reg_code \%hash;
+ $record = new FS::reg_code { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::reg_code object is a one-time registration code. FS::reg_code inherits
+from FS::Record. The following fields are currently supported:
+
+=over 4
+
+=item codenum - primary key
+
+=item code - registration code string
+
+=item agentnum - Agent (see L<FS::agent>)
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new registration code. To add the code 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 { 'reg_code'; }
+
+=item insert [ PKGPART_ARRAYREF ]
+
+Adds this record to the database. If an arrayref of pkgparts
+(see L<FS::part_pkg>) is specified, the appropriate reg_code_pkg records
+(see L<FS::reg_code_pkg>) will be inserted.
+
+If there is an error, returns the error, otherwise returns false.
+
+=cut
+
+sub insert {
+ my $self = shift;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ my $error = $self->SUPER::insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ if ( @_ ) {
+ my $pkgparts = shift;
+ foreach my $pkgpart ( @$pkgparts ) {
+ my $reg_code_pkg = new FS::reg_code_pkg ( {
+ 'codenum' => $self->codenum,
+ 'pkgpart' => $pkgpart,
+ } );
+ $error = $reg_code_pkg->insert;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ '';
+
+}
+
+=item delete
+
+Delete this record (and all associated reg_code_pkg records) from the database.
+
+=cut
+
+sub delete {
+ my $self = shift;
+
+ local $SIG{HUP} = 'IGNORE';
+ local $SIG{INT} = 'IGNORE';
+ local $SIG{QUIT} = 'IGNORE';
+ local $SIG{TERM} = 'IGNORE';
+ local $SIG{TSTP} = 'IGNORE';
+ local $SIG{PIPE} = 'IGNORE';
+
+ my $oldAutoCommit = $FS::UID::AutoCommit;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+
+ foreach my $reg_code_pkg ( $self->reg_code_pkg ) {
+ my $error = $reg_code_pkg->delete;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+ }
+
+ my $error = $self->SUPER::delete;
+ if ( $error ) {
+ $dbh->rollback if $oldAutoCommit;
+ return $error;
+ }
+
+ $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+ '';
+
+}
+
+=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 registration code. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+and replace methods.
+
+=cut
+
+# the check method should currently be supplied - FS::Record contains some
+# data checking routines
+
+sub check {
+ my $self = shift;
+
+ my $error =
+ $self->ut_numbern('codenum')
+ || $self->ut_alpha('code')
+ || $self->ut_foreign_key('agentnum', 'agent', 'agentnum')
+ ;
+ return $error if $error;
+
+ $self->SUPER::check;
+}
+
+=item part_pkg
+
+Returns all package definitions (see L<FS::part_pkg> for this registration
+code.
+
+=cut
+
+sub part_pkg {
+ my $self = shift;
+ map { $_->part_pkg } $self->reg_code_pkg;
+}
+
+=item reg_code_pkg
+
+Returns all FS::reg_code_pkg records for this registration code.
+
+=cut
+
+sub reg_code_pkg {
+ my $self = shift;
+ qsearch('reg_code_pkg', { 'codenum' => $self->codenum } );
+}
+
+
+=back
+
+=head1 BUGS
+
+Feeping creaturitis.
+
+=head1 SEE ALSO
+
+L<FS::reg_code_pkg>, L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
+
diff --git a/FS/FS/reg_code_pkg.pm b/FS/FS/reg_code_pkg.pm
new file mode 100644
index 000000000..598497c46
--- /dev/null
+++ b/FS/FS/reg_code_pkg.pm
@@ -0,0 +1,135 @@
+package FS::reg_code_pkg;
+
+use strict;
+use vars qw( @ISA );
+use FS::Record qw(qsearchs);
+use FS::reg_code;
+use FS::part_pkg;
+
+@ISA = qw(FS::Record);
+
+=head1 NAME
+
+FS::reg_code_pkg - Class linking registration codes (see L<FS::reg_code>) with package definitions (see L<FS::part_pkg>)
+
+=head1 SYNOPSIS
+
+ use FS::reg_code_pkg;
+
+ $record = new FS::reg_code_pkg \%hash;
+ $record = new FS::reg_code_pkg { 'column' => 'value' };
+
+ $error = $record->insert;
+
+ $error = $new_record->replace($old_record);
+
+ $error = $record->delete;
+
+ $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::reg_code_pkg object links a registration code to a package definition.
+FS::table_name inherits from FS::Record. The following fields are currently
+supported:
+
+=over 4
+
+=item codenum - registration code (see L<FS::reg_code>)
+
+=item pkgpart - package definition (see L<FS::part_pkg>)
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new example. To add the example 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 { 'reg_code_pkg'; }
+
+=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 record. If there is
+an error, returns the error, otherwise returns false. Called by the insert
+and replace methods.
+
+=cut
+
+# the check method should currently be supplied - FS::Record contains some
+# data checking routines
+
+sub check {
+ my $self = shift;
+
+ my $error =
+ $self->ut_foreign_key('codenum', 'reg_code', 'codenum')
+ || $self->ut_foreign_key('pkgpart', 'part_pkg', 'pkgpart')
+ ;
+ return $error if $error;
+
+ $self->SUPER::check;
+}
+
+=item part_pkg
+
+Returns the package definition (see L<FS::part_pkg>)
+
+=cut
+
+sub part_pkg {
+ my $self = shift;
+ qsearchs('part_pkg', { 'pkgpart' => $self->pkgpart } );
+}
+
+=back
+
+=head1 BUGS
+
+Feeping creaturitis.
+
+=head1 SEE ALSO
+
+L<FS::reg_code_pkg>, L<FS::Record>, schema.html from the base documentation.
+
+=cut
+
+1;
+
+
diff --git a/FS/MANIFEST b/FS/MANIFEST
index 32785c20e..4e33efea7 100644
--- a/FS/MANIFEST
+++ b/FS/MANIFEST
@@ -125,6 +125,8 @@ FS/rate.pm
FS/rate_detail.pm
FS/rate_region.pm
FS/rate_prefix.pm
+FS/reg_code.pm
+FS/reg_code_pkg.pm
FS/svc_Common.pm
FS/svc_acct.pm
FS/svc_acct_pop.pm
@@ -248,6 +250,8 @@ t/rate_detail.t
t/rate_region.t
t/rate_prefix.t
t/radius_usergroup.t
+t/reg_code.t
+t/reg_code_pkg.t
t/session.t
t/svc_acct.t
t/svc_acct_pop.t
diff --git a/FS/bin/freeside-setup b/FS/bin/freeside-setup
index c867a721f..24b0685de 100755
--- a/FS/bin/freeside-setup
+++ b/FS/bin/freeside-setup
@@ -1209,6 +1209,26 @@ sub tables_hash_hack {
'index' => [ [ 'countrycode' ], [ 'regionnum' ] ],
},
+ 'reg_code' => {
+ 'columns' => [
+ 'codenum', 'serial', '', '',
+ 'code', 'varchar', '', $char_d,
+ 'agentnum', 'int', '', '',
+ ],
+ 'primary_key' => 'codenum',
+ 'unique' => [ [ 'agentnum', 'code' ] ],
+ 'index' => [ [ 'agentnum' ] ],
+ },
+
+ 'reg_code_pkg' => {
+ 'columns' => [
+ 'codenum', 'int', '', '',
+ 'pkgpart', 'int', '', '',
+ ],
+ 'primary_key' => '',
+ 'unique' => [ [ 'codenum', 'pkgpart' ] ],
+ 'index' => [ [ 'codenum' ] ],
+ },
);
diff --git a/FS/t/reg_code.t b/FS/t/reg_code.t
new file mode 100644
index 000000000..4b9599078
--- /dev/null
+++ b/FS/t/reg_code.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::reg_code;
+$loaded=1;
+print "ok 1\n";
diff --git a/FS/t/reg_code_pkg.t b/FS/t/reg_code_pkg.t
new file mode 100644
index 000000000..7f89ffaee
--- /dev/null
+++ b/FS/t/reg_code_pkg.t
@@ -0,0 +1,5 @@
+BEGIN { $| = 1; print "1..1\n" }
+END {print "not ok 1\n" unless $loaded;}
+use FS::reg_code_pkg;
+$loaded=1;
+print "ok 1\n";
diff --git a/README.1.5.0pre7 b/README.1.5.0pre7
index dda49a76b..5c136ab5f 100644
--- a/README.1.5.0pre7
+++ b/README.1.5.0pre7
@@ -31,6 +31,22 @@ CREATE TABLE rate_prefix (
CREATE INDEX rate_prefix1 ON rate_prefix ( countrycode );
CREATE INDEX rate_prefix2 ON rate_prefix ( regionnum );
+CREATE TABLE reg_code (
+ codenum serial NOT NULL,
+ code varchar(80) NOT NULL,
+ agentnum int NOT NULL,
+ PRIMARY KEY (codenum)
+);
+CREATE UNIQUE INDEX reg_code1 ON reg_code ( agentnum, code );
+CREATE INDEX reg_code2 ON reg_code ( agentnum );
+
+CREATE TABLE reg_code_pkg (
+ codenum int NOT NULL,
+ pkgpart int NOT NULL
+);
+CREATE UNIQUE INDEX reg_code_pkg1 ON reg_code_pkg ( codenum, pkgpart );
+CREATE INDEX reg_code_pkg2 ON reg_code_pkg ( codenum );
+
ALTER TABLE part_pkg ADD promo_code varchar(80) NULL;
ALTER TABLE h_part_pkg ADD promo_code varchar(80) NULL;
CREATE INDEX part_pkg2 ON part_pkg ( promo_code );
@@ -63,9 +79,10 @@ Installs w/integrated RT:
dbdef-create username
-create-history-tables username rate rate_detail rate_region rate_prefix
+create-history-tables username rate rate_detail rate_region rate_prefix reg_code reg_code_pkg
dbdef-create username
+install Javascript::RPC (JavaScript::RPC::Server::CGI)
afterwords (for installs w/integrated RT):
make configure-rt
diff --git a/fs_signup/FS-SignupClient/cgi/regcode.html b/fs_signup/FS-SignupClient/cgi/regcode.html
new file mode 100644
index 000000000..e639b9b53
--- /dev/null
+++ b/fs_signup/FS-SignupClient/cgi/regcode.html
@@ -0,0 +1,14 @@
+<HTML><HEAD><TITLE>ISP Signup</TITLE></HEAD>
+<BODY BGCOLOR="#e8e8e8"><FONT SIZE=7>ISP Signup - registration code</FONT><BR><BR>
+<SCRIPT>
+function gotoURL(object) {
+ window.location.href = 'signup.cgi?reg_code=' + object.reg_code.value;
+}
+</SCRIPT>
+<FORM>
+Enter registration code <INPUT TYPE="text" NAME="reg_code">
+<INPUT type="submit" VALUE="Signup" onClick="gotoURL(this.form)">
+
+</FORM>
+</BODY>
+</HTML>
diff --git a/fs_signup/FS-SignupClient/cgi/signup.cgi b/fs_signup/FS-SignupClient/cgi/signup.cgi
index f49ad3285..aae3fb84a 100755
--- a/fs_signup/FS-SignupClient/cgi/signup.cgi
+++ b/fs_signup/FS-SignupClient/cgi/signup.cgi
@@ -1,7 +1,7 @@
#!/usr/bin/perl -T
#!/usr/bin/perl -Tw
#
-# $Id: signup.cgi,v 1.54 2004-12-01 18:38:22 ivan Exp $
+# $Id: signup.cgi,v 1.55 2005-01-29 12:34:11 ivan Exp $
use strict;
use vars qw( @payby $cgi $locales $packages
@@ -134,7 +134,10 @@ if ( -e $decline_html ) {
$cgi = new CGI;
-$init_data = signup_info( 'promo_code' => $cgi->param('promo_code') );
+$init_data = signup_info( 'agentnum' => $agentnum,
+ 'promo_code' => scalar($cgi->param('promo_code')),
+ 'reg_code' => uc(scalar($cgi->param('reg_code'))),
+ );
$error = $init_data->{'error'};
$locales = $init_data->{'cust_main_county'};
$packages = $init_data->{'part_pkg'};
@@ -175,7 +178,8 @@ if ( defined $cgi->param('magic') ) {
$cgi->param('ship_county') =~ /^([\w ]*)$/
or die "illegal county: ". $cgi->param('ship_county');
$ship_county = $1;
- $cgi->param('ship_country') =~ /^(\w+)$/
+ #$cgi->param('ship_country') =~ /^(\w+)$/
+ $cgi->param('ship_country') =~ /^(\w*)$/
or die "illegal ship_country: ". $cgi->param('ship_country');
$ship_country = $1;
#} else {
@@ -307,7 +311,8 @@ if ( defined $cgi->param('magic') ) {
'payname' => $payname,
'invoicing_list' => $invoicing_list,
'referral_custnum' => $referral_custnum,
- 'promo_code' => $cgi->param('promo_code'),
+ 'promo_code' => scalar($cgi->param('promo_code')),
+ 'reg_code' => uc(scalar($cgi->param('reg_code'))),
'pkgpart' => $pkgpart,
'username' => $username,
'sec_phrase' => $sec_phrase,
diff --git a/fs_signup/FS-SignupClient/cgi/signup.html b/fs_signup/FS-SignupClient/cgi/signup.html
index c0e4f73eb..da522f4f4 100755
--- a/fs_signup/FS-SignupClient/cgi/signup.html
+++ b/fs_signup/FS-SignupClient/cgi/signup.html
@@ -167,7 +167,9 @@ Contact Information
</TR></TABLE><font color="#ff0000">*</font> required fields for each billing type
<BR><BR>First package
-<INPUT TYPE="hidden" NAME="promo_code" VALUE="<%= $cgi->param('promo_code') %>"><TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
+<INPUT TYPE="hidden" NAME="promo_code" VALUE="<%= $cgi->param('promo_code') %>">
+<INPUT TYPE="hidden" NAME="reg_code" VALUE="<%= uc($cgi->param('reg_code')) %>">
+<TABLE BGCOLOR="#c0c0c0" BORDER=0 CELLSPACING=0 WIDTH="100%">
<TR>
<TD COLSPAN=2><SELECT NAME="pkgpart">
diff --git a/httemplate/docs/install.html b/httemplate/docs/install.html
index 898eb9ef8..a880d9104 100644
--- a/httemplate/docs/install.html
+++ b/httemplate/docs/install.html
@@ -59,6 +59,7 @@ Before installing, you need:
<li><a href="http://search.cpan.org/search?dist=Chart">Chart</a>
<li><a href="http://search.cpan.org/search?dist=Crypt-PasswdMD5">Crypt::PasswdMD5</a>
<li><a href="http://search.cpan.org/search?dist=JavaScript-RPC">JavaScript::RPC (JavaScript::RPC::Server::CGI)</a>
+<!-- <li><a href="http://search.cpan.org/search?dist=Crypt-YAPassGen">Crypt::YAPassGen</a> -->
<li><a href="http://search.cpan.org/search?dist=ApacheDBI">Apache::DBI</a> <i>(optional but recommended for better webinterface performance)</i>
</ul>
</ul>
diff --git a/httemplate/docs/schema.html b/httemplate/docs/schema.html
index c5cfd5119..8af8aa9df 100644
--- a/httemplate/docs/schema.html
+++ b/httemplate/docs/schema.html
@@ -285,6 +285,17 @@
<li>optionname - option name
<li>optionvalue - option value
</ul>
+ <li><a name="reg_code" href="man/FS/reg_code.html">reg_code</A> - One-time registration codes
+ <ul>
+ <li>codenum - primary key
+ <li>code
+ <li>agentnum - <a href="#agent">Agent</a>
+ </ul>
+ <li><a name="reg_code_pkg" href="man/FS/reg_code_pkg.html">reg_code_pkg</A> - Registration code link to package definitions
+ <ul>
+ <li>codenum - <a href="#reg_code">Registration code</a>
+ <li>pkgpart - <a href="#part_pkg">Package definition</a>
+ </ul>
<li><a name="part_referral" href="man/FS/part_referral.html">part_referral</a> - Referral listing
<ul>
<li>refnum - primary key
diff --git a/httemplate/docs/upgrade10.html b/httemplate/docs/upgrade10.html
index d8186858f..7441cf1cc 100644
--- a/httemplate/docs/upgrade10.html
+++ b/httemplate/docs/upgrade10.html
@@ -8,7 +8,8 @@ install Net::SSH 0.08
- In httpd.conf, change &lt;Files ~ \.cgi&gt; to &lt;Files ~ (\.cgi|\.html)&gt;
- In httpd.conf, change <b>AddHandler perl-script .cgi</b> or <b>SetHandler perl-script</b> to <b>AddHandler perl-script .cgi .html</b>
-install NetAddr::IP, Chart::Base, IPC::ShareLite and Locale::SubCountry
+install NetAddr::IP, Chart::Base, IPC::ShareLite, Locale::SubCountry,
+JavaScript::RPC (JavaScript::RPC::Server::CGI) <!-- and Crypt::YAPassGen-->
INSERT INTO msgcat ( msgnum, msgcode, locale, msg ) VALUES ( 20, 'svc_external-id', 'en_US', 'External ID' );
INSERT INTO msgcat ( msgnum, msgcode, locale, msg ) VALUES ( 21, 'svc_external-title', 'en_US', 'Title' );
@@ -223,6 +224,22 @@ CREATE TABLE rate_prefix (
CREATE INDEX rate_prefix1 ON rate_prefix ( countrycode );
CREATE INDEX rate_prefix2 ON rate_prefix ( regionnum );
+CREATE TABLE reg_code (
+ codenum serial NOT NULL,
+ code varchar(80) NOT NULL,
+ agentnum int NOT NULL,
+ PRIMARY KEY (codenum)
+);
+CREATE UNIQUE INDEX reg_code1 ON reg_code ( agentnum, code );
+CREATE INDEX reg_code2 ON reg_code ( agentnum );
+
+CREATE TABLE reg_code_pkg (
+ codenum int NOT NULL,
+ pkgpart int NOT NULL
+);
+CREATE UNIQUE INDEX reg_code_pkg1 ON reg_code_pkg ( codenum, pkgpart );
+CREATE INDEX reg_code_pkg2 ON reg_code_pkg ( codenum );
+
DROP INDEX cust_bill_pkg1;
ALTER TABLE cust_bill_pkg ADD itemdesc varchar(80) NULL;
@@ -296,7 +313,7 @@ optionally:
mandatory again:
dbdef-create username
-create-history-tables username cust_bill_pkg_detail router part_svc_router addr_block svc_broadband acct_snarf svc_external cust_pay_refund cust_pay_void part_pkg_option rate rate_detail rate_region rate_prefix
+create-history-tables username cust_bill_pkg_detail router part_svc_router addr_block svc_broadband acct_snarf svc_external cust_pay_refund cust_pay_void part_pkg_option rate rate_detail rate_region rate_prefix reg_code reg_code_pkg
dbdef-create username
apache - fix <Files> sections to include .html also
diff --git a/httemplate/edit/process/reg_code.cgi b/httemplate/edit/process/reg_code.cgi
new file mode 100644
index 000000000..581ede893
--- /dev/null
+++ b/httemplate/edit/process/reg_code.cgi
@@ -0,0 +1,41 @@
+<%
+
+$cgi->param('agentnum') =~ /^(\d+)$/
+ or eidiot 'illegal agentnum '. $cgi->param('agentnum');
+my $agentnum = $1;
+my $agent = qsearchs('agent', { 'agentnum' => $agentnum } );
+
+my $error = '';
+
+my $num = 0;
+if ( $cgi->param('num') =~ /^\s*(\d+)\s*$/ ) {
+ $num = $1;
+} else {
+ $error = 'Illegal number of codes: '. $cgi->param('num');
+}
+
+my @pkgparts =
+ map { /^pkgpart(.*)$/; $1 }
+ grep { $cgi->param($_) }
+ grep { /^pkgpart/ }
+ $cgi->param;
+
+$error ||= $agent->generate_reg_codes($num, \@pkgparts);
+
+unless ( ref($error) ) { %><%=
+ $cgi->redirect(popurl(3). "edit/reg_code.cgi?". $cgi->query_string )
+%><% } else { %>
+
+<%= header("$num registration codes generated for ". $agent->agent, menubar(
+ 'View all agents' => popurl(3). 'browse/agent.cgi',
+) ) %>
+
+<PRE><FONT SIZE="+1">
+<% foreach my $code ( @$error ) { %>
+ <%= $code %>
+<% } %>
+
+</FONT></PRE>
+
+</BODY></HTML>
+<% } %>
diff --git a/httemplate/edit/reg_code.cgi b/httemplate/edit/reg_code.cgi
new file mode 100644
index 000000000..899d1ec45
--- /dev/null
+++ b/httemplate/edit/reg_code.cgi
@@ -0,0 +1,36 @@
+<%
+my $agentnum = $cgi->param('agentnum');
+$agentnum =~ /^(\d+)$/ or eidiot "illegal agentnum $agentnum";
+$agentnum = $1;
+my $agent = qsearchs('agent', { 'agentnum' => $agentnum } );
+
+%>
+
+<%= header('Generate registration codes for '. $agent->agent, menubar(
+ 'Main Menu' => $p,
+ ))
+%>
+
+<% if ( $cgi->param('error') ) { %>
+ <FONT SIZE="+1" COLOR="#FF0000">Error: <%= $cgi->param('error') %></FONT>
+<% } %>
+
+<FORM ACTION="<%=popurl(1)%>process/reg_code.cgi" METHOD="POST" NAME="OneTrueForm" onSubmit="document.OneTrueForm.submit.disabled=true">
+<INPUT TYPE="hidden" NAME="agentnum" VALUE="<%= $agent->agentnum %>">
+
+Generate
+<INPUT TYPE="text" NAME="num" VALUE="<%= $cgi->param('num') %>" SIZE=5 MAXLENGTH=4>
+registration codes for <B><%= $agent->agent %></B> allowing the following packages:
+<BR><BR>
+
+<% foreach my $part_pkg ( qsearch('part_pkg', { 'disabled' => '' } ) ) { %>
+ <INPUT TYPE="checkbox" NAME="pkgpart<%= $part_pkg->pkgpart %>">
+ <%= $part_pkg->pkg %> - <%= $part_pkg->comment %>
+ <BR>
+<% } %>
+
+<BR>
+<INPUT TYPE="submit" NAME="submit" VALUE="Generate">
+
+</FORM></BODY></HTML>
+
diff --git a/httemplate/search/reg_code.html b/httemplate/search/reg_code.html
new file mode 100644
index 000000000..ba1eee078
--- /dev/null
+++ b/httemplate/search/reg_code.html
@@ -0,0 +1,35 @@
+<%
+
+my $agentnum = $cgi->param('agentnum');
+$agentnum =~ /^(\d+)$/ or eidiot "illegal agentnum $agentnum";
+$agentnum = $1;
+my $agent = qsearchs('agent', { 'agentnum' => $agentnum } );
+
+my $count_query = "SELECT COUNT(*) FROM reg_code WHERE agentnum = $agentnum";
+
+%>
+<%= include( 'elements/search.html',
+ 'title' => 'Unused Registration Codes for '. $agent->agent,
+ 'name' => 'registration codes',
+ 'query' => { 'table' => 'reg_code',
+ 'hashref' => { 'agentnum' => $agentnum, },
+ },
+ 'count_query' => $count_query,
+ #'redirect' => $link,
+ 'header' => [ qw(Code Packages) ],
+ 'fields' => [
+ 'code',
+ sub { map {
+ qq!<A HREF="${p}edit/part_pkg.cgi?!. $_->pkgpart. '">'.
+ $_->pkg. ' - '. $_->comment.
+ '</A><BR>'
+ } $_[0]->part_pkg
+ },
+ ],
+ 'links' => [
+ '',
+ #$plink,
+ '',
+ ],
+ )
+%>