[dw-free] self-expiring promo codes
[commit: http://hg.dwscoalition.org/dw-free/rev/1364c50df8e7]
http://bugs.dwscoalition.org/show_bug.cgi?id=3386
Allow to auto-expire promo codes.
Patch by
rb.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=3386
Allow to auto-expire promo codes.
Patch by
Files modified:
- bin/upgrading/update-db-general.pl
- cgi-bin/DW/InviteCodes.pm
- cgi-bin/DW/InviteCodes/Promo.pm
- htdocs/admin/invites/promo.bml
- htdocs/admin/invites/promo.bml.text
--------------------------------------------------------------------------------
diff -r ce0787149088 -r 1364c50df8e7 bin/upgrading/update-db-general.pl
--- a/bin/upgrading/update-db-general.pl Fri Oct 28 19:14:26 2011 +0800
+++ b/bin/upgrading/update-db-general.pl Fri Oct 28 19:26:06 2011 +0800
@@ -2972,6 +2972,7 @@
suggest_journalid int unsigned,
paid_class varchar(100),
paid_months tinyint unsigned,
+ expiry_date int(10) unsigned not null default 0,
PRIMARY KEY ( code )
)
@@ -3949,6 +3950,10 @@
do_alter( 'acctcode_promo', "ALTER TABLE acctcode_promo ADD COLUMN paid_months tinyint unsigned" );
}
+ unless ( column_type( 'acctcode_promo', 'expiry_date' ) ) {
+ do_alter( 'acctcode_promo', "ALTER TABLE acctcode_promo ADD COLUMN expiry_date int(10) unsigned NOT NULL default '0'" );
+ }
+
if ( $LJ::IS_DEV_SERVER ) {
# strip constant definitions from user layers
if ( table_relevant( "s2compiled2" ) && ! check_dbnote( "no_layer_constants" ) ) {
diff -r ce0787149088 -r 1364c50df8e7 cgi-bin/DW/InviteCodes.pm
--- a/cgi-bin/DW/InviteCodes.pm Fri Oct 28 19:14:26 2011 +0800
+++ b/cgi-bin/DW/InviteCodes.pm Fri Oct 28 19:26:06 2011 +0800
@@ -148,8 +148,7 @@
# if it is, make sure it's active and we're not over the creation limit for the code
my $promo_code_info = DW::InviteCodes::Promo->load( code => $code );
if ( ref $promo_code_info ) {
- return 0 unless $promo_code_info->{active} && ( $promo_code_info->{current_count} < $promo_code_info->{max_count} );
- return 1;
+ return $promo_code_info->usable;
}
return 0 unless $class->could_be_code( string => $code );
diff -r ce0787149088 -r 1364c50df8e7 cgi-bin/DW/InviteCodes/Promo.pm
--- a/cgi-bin/DW/InviteCodes/Promo.pm Fri Oct 28 19:14:26 2011 +0800
+++ b/cgi-bin/DW/InviteCodes/Promo.pm Fri Oct 28 19:26:06 2011 +0800
@@ -100,6 +100,23 @@
=head1 INSTANCE METHODS
+=head2 C<< $self->usable >>
+
+Checks code is available, not already used up, and not expired.
+
+=cut
+
+sub usable {
+ my ( $self ) = @_;
+
+ return 0 unless $self->{active};
+ return 0 unless $self->{current_count} < $self->{max_count};
+
+ # 0 for expiry_date means never expire;
+ return 0 unless $self->{expiry_date} && time() < $self->{expiry_date};
+ return 1;
+}
+
=head2 C<< $self->apply_for_user( $u ) >>
Handle any post-create operations for this user.
@@ -151,7 +168,7 @@
return $_[0]->{paid_class} ? $_[0]->{paid_months} : 0;
}
-=head2 C<< $self->paid_type >>
+=head2 C<< $self->paid_class >>
=cut
sub paid_class {
diff -r ce0787149088 -r 1364c50df8e7 htdocs/admin/invites/promo.bml
--- a/htdocs/admin/invites/promo.bml Fri Oct 28 19:14:26 2011 +0800
+++ b/htdocs/admin/invites/promo.bml Fri Oct 28 19:26:06 2011 +0800
@@ -35,6 +35,7 @@
my $errors = $_[1] || {};
my $suggest_u = ( $data && $data->{suggest_journalid} ) ? LJ::load_userid($data->{suggest_journalid}) : undef;
my $active = ( defined $data->{active} ) ? $data->{active} : 1;
+ my $expiry_date = $data->{expiry_date} ? LJ::mysql_date( $data->{expiry_date} ) : "";
if ( $state eq 'create' ) {
$title = $ML{'.title.create'};
@@ -69,7 +70,7 @@
$ret .= LJ::html_text( { id => 'suggest_journal', name => 'suggest_journal', value => ( $suggest_u ? $suggest_u->username : ( $data->{suggest_journal} || "" ) ), size => 28, maxlength => 25 } );
$ret .= " <strong>[$ML{'.error.label'} " . join(', ', @{$errors->{suggest_journal}}) . "]</strong>" if $errors->{suggest_journal};
$ret .= '<br />';
-
+
$ret .= LJ::labelfy( 'paid_class', "$ML{'.field.paid_class.label'} " );
$ret .= LJ::html_select( {
id => 'paid_class',
@@ -81,16 +82,27 @@
{ value => 'premium', text => $ML{'.field.paid_class.premium'} },
);
$ret .= '<br />';
-
+
$ret .= LJ::labelfy( 'paid_months', "$ML{'.field.paid_months.label'} " );
$ret .= LJ::html_text( { id => 'paid_months', name => 'paid_months', value => ( $data->{paid_months} || "" ), size => 10, maxlength => 2 } );
$ret .= '<br />';
-
+ $ret .= LJ::html_hidden( { name => 'expiry_date_unedited', value => $expiry_date } );
+
+ $ret .= LJ::labelfy( 'expiry_date', "$ML{'.field.expiry_date.label'} " );
+ $ret .= LJ::html_text( { id => 'expiry_date', name => 'expiry_date', value => $expiry_date, size => 12, maxlength => 12 } );
+ $ret .= $ML{'.field.expiry_date.format'} . ", " . $ML{'.field.expiry_date.label_extra'} . " ";
+ $ret .= LJ::html_text( { id => 'expiry_months', name => 'expiry_months', value => ( $data->{expiry_months} || "" ), size => 5, maxlength => 2 } );
+ $ret .= LJ::labelfy( 'expiry_months', "$ML{'.field.expiry_date.months'} " );
+ $ret .= LJ::html_text( { id => 'expiry_days', name => 'expiry_days', value => ( $data->{expiry_days} || "" ), size => 5, maxlength => 2 } );
+ $ret .= LJ::labelfy( 'expiry_days', "$ML{'.field.expiry_date.days'} " );
+ $ret .= " <strong>[$ML{'.error.label'} " . join(', ', @{$errors->{expiry_date}}) . "]</strong>" if $errors->{expiry_date};
+ $ret .= "</br>";
+
$ret .= LJ::html_submit( value => $ML{ ( $data ? '.btn.save' : '.btn.create' ) } );
$ret .= "</form>";
};
-
+
if ( LJ::did_post ) {
return LJ::error_list( $ML{'error.invalidform'} )
unless LJ::check_form_auth();
@@ -105,6 +117,10 @@
suggest_journal => $POST{suggest_journal},
paid_class => $POST{paid_class} || '',
paid_months => $POST{paid_months} || undef,
+ expiry_date_unedited => $POST{expiry_date_unedited} || 0,
+ expiry_date => $POST{expiry_date} || 0,
+ expiry_months => $POST{expiry_months} || 0,
+ expiry_days => $POST{expiry_days} || 0,
};
my $valid = 1;
my $errors = {};
@@ -136,10 +152,35 @@
$data->{paid_class} = undef;
$data->{paid_months} = undef;
}
+
+ if ( $data->{expiry_date} ne $data->{expiry_date_unedited} ) {
+ if ( $data->{expiry_days} || $data->{expiry_months} ) {
+ push @{$errors->{expiry_date}}, $ML{'.error.date.double_specified'};
+ $valid = 0;
+ }
+ $data->{expiry_db} = LJ::mysqldate_to_time( $data->{expiry_date} );
+ } else {
+ if ( $data->{expiry_days} < 0 ) {
+ push @{$errors->{expiry_date}}, $ML{'.error.days.negative'};
+ $valid = 0;
+ }
+ if ($data->{expiry_months} < 0) {
+ push @{$errors->{expiry_date}}, $ML{'.error.months.negative'};
+ $valid = 0;
+ }
+ $data->{expiry_months} = 0 unless $data->{expiry_months};
+ $data->{expiry_days} = 0 unless $data->{expiry_days};
+ my $length = $data->{expiry_months} * 30 + $data->{expiry_days};
+ if ( $length ) {
+ $data->{expiry_db} = time() + ( $length * 86400 );
+ } else {
+ $data->{expiry_db} = 0;
+ }
+ }
if ( $valid ) {
my $dbh = LJ::get_db_writer();
- $dbh->do( "INSERT INTO acctcode_promo (code, max_count, active, suggest_journalid, paid_class, paid_months) VALUES (?, ?, ?, ?, ?, ?)", undef,
- $data->{code}, $data->{max_count}, $data->{active}, $data->{suggest_journalid}, $data->{paid_class}, $data->{paid_months} ) or die $dbh->errstr;
+ $dbh->do( "INSERT INTO acctcode_promo (code, max_count, active, suggest_journalid, paid_class, paid_months, expiry_date) VALUES (?, ?, ?, ?, ?, ?, ?)", undef,
+ $data->{code}, $data->{max_count}, $data->{active}, $data->{suggest_journalid}, $data->{paid_class}, $data->{paid_months}, $data->{expiry_db} ) or die $dbh->errstr;
} else {
$create_form->( $data, $errors );
return $ret;
@@ -155,6 +196,10 @@
suggest_journal => $POST{suggest_journal},
paid_class => $POST{paid_class} || '',
paid_months => $POST{paid_months} || undef,
+ expiry_date_unedited => $POST{expiry_date_unedited} || 0,
+ expiry_date => $POST{expiry_date} || 0,
+ expiry_days => $POST{expiry_days} || 0,
+ expiry_months => $POST{expiry_months} || 0,
};
my $valid = 1;
my $errors = {};
@@ -186,10 +231,36 @@
$data->{paid_class} = undef;
$data->{paid_months} = undef;
}
+
+ if ( $data->{expiry_date} ne $data->{expiry_date_unedited} ) {
+ if ( $data->{expiry_days} || $data->{expiry_months} ) {
+ push @{$errors->{expiry_date}}, $ML{'.error.date.double_specified'};
+ $valid = 0;
+ }
+ $data->{expiry_db} = LJ::mysqldate_to_time( $data->{expiry_date} );
+ } else {
+ if ( $data->{expiry_days} < 0 ) {
+ push @{$errors->{expiry_date}}, $ML{'.error.days.negative'};
+ $valid = 0;
+ }
+ if ($data->{expiry_months} < 0) {
+ push @{$errors->{expiry_date}}, $ML{'.error.months.negative'};
+ $valid = 0;
+ }
+ $data->{expiry_months} = 0 unless $data->{expiry_months};
+ $data->{expiry_days} = 0 unless $data->{expiry_days};
+ my $length = $data->{expiry_months} * 30 + $data->{expiry_days};
+ if ( $length ) {
+ $data->{expiry_db} = time() + ( $length * 86400 );
+ } else {
+ $data->{expiry_db} = 0;
+ }
+ }
+
if ( $valid ) {
my $dbh = LJ::get_db_writer();
- $dbh->do( "UPDATE acctcode_promo SET max_count = ?, active = ?, suggest_journalid = ?, paid_class = ?, paid_months = ? WHERE code = ?", undef,
- $data->{max_count}, $data->{active}, $data->{suggest_journalid}, $data->{paid_class}, $data->{paid_months}, $data->{code} ) or die $dbh->errstr;
+ $dbh->do( "UPDATE acctcode_promo SET max_count = ?, active = ?, suggest_journalid = ?, paid_class = ?, paid_months = ?, expiry_date =? WHERE code = ?", undef,
+ $data->{max_count}, $data->{active}, $data->{suggest_journalid}, $data->{paid_class}, $data->{paid_months}, $data->{expiry_db}, $data->{code} ) or die $dbh->errstr;
} else {
$create_form->( $data, $errors );
return $ret;
@@ -214,7 +285,7 @@
$ret .= '<a href="/admin/invites/promo?state=noneleft">' . $ML{'.state.noneleft'} . '</a>';
$ret .= "<table>";
- $ret .= "<thead><tr><th>$ML{'.heading.code'}</th><th>$ML{'.heading.active'}</th><th>$ML{'.heading.count'}</th><th>$ML{'.heading.suggest'}</th><th>$ML{'.heading.paid'}</tr></thead>";
+ $ret .= "<thead><tr><th>$ML{'.heading.code'}</th><th>$ML{'.heading.active'}</th><th>$ML{'.heading.count'}</th><th>$ML{'.heading.suggest'}</th><th>$ML{'.heading.paid'}</th><th>$ML{'.heading.expiry'}</th></tr></thead>";
if ( scalar( @$codes ) ) {
foreach my $code (@$codes) {
@@ -233,10 +304,11 @@
} else {
$ret .= "<td>$ML{'.paid.no'}</td>";
}
+ $ret .= "<td>" . ( $code->{expiry_date} ? LJ::mysql_date( $code->{expiry_date} ) : $ML{'.expiry.none'} ) . "</td>";
$ret .= "</tr>";
}
} else {
- $ret .= '<tr><th colspan="4">' . $ML{'.nomatch'} . '</th></tr>';
+ $ret .= '<tr><th colspan="5">' . $ML{'.nomatch'} . '</th></tr>';
}
$ret .= "</table>";
}
@@ -252,3 +324,4 @@
</style>
<=head
page?>
+
diff -r ce0787149088 -r 1364c50df8e7 htdocs/admin/invites/promo.bml.text
--- a/htdocs/admin/invites/promo.bml.text Fri Oct 28 19:14:26 2011 +0800
+++ b/htdocs/admin/invites/promo.bml.text Fri Oct 28 19:26:06 2011 +0800
@@ -23,6 +23,14 @@
.error.suggest_journal.invalid=Cannot find that user
+.error.months.negative=Months until expiry must be positive or zero
+
+.error.days.negative=Days until expiry must be positive or zero
+
+.error.date.double_specified=You can't specify both an expiry date and months/days to add.
+
+.expiry.none=(none)
+
.field.active.label=Active
.field.code.label=Code:
@@ -41,6 +49,16 @@
.field.suggest_journal.label=Suggest Journal:
+.field.expiry_date.label=Expiry Date:
+
+.field.expiry_date.format=(YYYY-MM-DD)
+
+.field.expiry_date.label_extra=or add time
+
+.field.expiry_date.months=months
+
+.field.expiry_date.days=days
+
.heading.active=Active
.heading.code=Code
@@ -51,6 +69,8 @@
.heading.suggest=Suggest Journal
+.heading.expiry=Expiry Date
+
.nomatch=No promo codes match your criteria
.paid=[[type]] for [[months]] [[?months|month|months]]
--------------------------------------------------------------------------------

no subject
Why the quotes around the '0'?
They don't match the "create table" statement, and they don't make a lot of sense to me for an int column.
no subject