fu: Close-up of Fu, bringing a scoop of water to her mouth (Default)
fu ([personal profile] fu) wrote in [site community profile] changelog2011-10-28 11:25 am

[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 [personal profile] rb.

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]]
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org