[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
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
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