mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2009-12-15 02:11 am

[dw-free] Paid time gift promotion

[commit: http://hg.dwscoalition.org/dw-free/rev/60b893aac8c6]

http://bugs.dwscoalition.org/show_bug.cgi?id=2203

Holiday Promotion code support.

Patch by [staff profile] mark.

Files modified:
  • bin/upgrading/en.dat
  • cgi-bin/DW/Shop/Cart.pm
  • cgi-bin/DW/Shop/Item/Account.pm
  • cgi-bin/DW/Widget/ShopCartStatusBar.pm
  • cgi-bin/LJ/Widget/ShopCart.pm
  • cgi-bin/ljlib.pl
--------------------------------------------------------------------------------
diff -r 5f6ecf6684f1 -r 60b893aac8c6 bin/upgrading/en.dat
--- a/bin/upgrading/en.dat	Mon Dec 14 22:06:51 2009 +0000
+++ b/bin/upgrading/en.dat	Tue Dec 15 02:11:38 2009 +0000
@@ -2915,6 +2915,23 @@ The [[sitename]] Team
 
 shop.email.comm.anon.subject=[[sitename]] Account Purchase
 
+shop.email.comm.explicit.body<<
+Dear [[touser]],
+
+Your [[sitename]] community [[commname]] has been upgraded by [[fromname]].
+The account that was given is:
+
+    [[accounttype]]
+
+Congratulations on your community's paid time!
+
+
+Regards,
+The [[sitename]] Team
+.
+
+shop.email.comm.explicit.subject=[[sitename]] Account Purchase
+
 shop.email.comm.other.body<<
 Dear [[touser]],
 
@@ -3059,6 +3076,23 @@ The [[sitename]] Team
 .
 
 shop.email.user.anon.subject=[[sitename]] Account Purchase
+
+shop.email.user.explicit.body<<
+Dear [[touser]],
+
+Your [[sitename]] account has been upgraded by [[fromname]].  The account that
+was given is:
+
+    [[accounttype]]
+
+Congratulations on your paid time!
+
+
+Regards,
+The [[sitename]] Team
+.
+
+shop.email.user.explicit.subject=[[sitename]] Account Purchase
 
 shop.email.user.other.body<<
 Dear [[touser]],
diff -r 5f6ecf6684f1 -r 60b893aac8c6 cgi-bin/DW/Shop/Cart.pm
--- a/cgi-bin/DW/Shop/Cart.pm	Mon Dec 14 22:06:51 2009 +0000
+++ b/cgi-bin/DW/Shop/Cart.pm	Tue Dec 15 02:11:38 2009 +0000
@@ -256,7 +256,7 @@ sub add_item {
 sub add_item {
     my ( $self, $item ) = @_;
 
-    # tell teh item who we are
+    # tell the item who we are
     $item->cartid( $self->id );
 
     # make sure this item is allowed to be added
@@ -273,10 +273,17 @@ sub add_item {
         }
     }
 
+    # construct a new, unique id for this item
+    my $itid = LJ::alloc_global_counter( 'I' )
+        or return ( 0, 'Failed to allocate item counter.' );
+    $item->id( $itid );
+
     # looks good, so let's add it...
     push @{$self->items}, $item;
     $self->{total} += $item->cost;
-    $item->id( $#{$self->items} );
+
+    # now call out to the hook system in case anybody wants to munge with us
+    LJ::run_hooks( 'shop_cart_added_item', $self, $item );
 
     # save to db and return
     $self->save || return( 0, 'Unable to save cart.' );
@@ -286,19 +293,30 @@ sub add_item {
 
 # removes an item from this cart by id
 sub remove_item {
-    my ( $self, $id ) = @_;
+    my ( $self, $id, %opts ) = @_;
 
-    my $out = [];
+    my ( $removed, $out ) = ( undef, [] );
     foreach my $it ( @{$self->items} ) {
         if ( $it->id == $id ) {
+            # some items are noremove items
+            if ( $it->noremove && ! $opts{force} ) {
+                push @$out, $it;
+                next;
+            }
+
+            # advise that we removed an item from the cart
+            $removed = $it;
             $self->{total} -= $it->cost;
         } else {
             push @$out, $it;
         }
     }
-
     $self->{items} = $out;
     $self->save;
+
+    # now run the hook, this is later so that we've updated the cart already
+    LJ::run_hooks( 'shop_cart_removed_item', $self, $removed );
+
     return 1;
 }
 
diff -r 5f6ecf6684f1 -r 60b893aac8c6 cgi-bin/DW/Shop/Item/Account.pm
--- a/cgi-bin/DW/Shop/Item/Account.pm	Mon Dec 14 22:06:51 2009 +0000
+++ b/cgi-bin/DW/Shop/Item/Account.pm	Tue Dec 15 02:11:38 2009 +0000
@@ -63,6 +63,14 @@ sub new {
         return undef unless $args{anonymous_target} == 1;
     }
 
+    if ( $args{cannot_conflict} ) {
+        return undef unless $args{cannot_conflict} == 1;
+    }
+
+    if ( $args{noremove} ) {
+        return undef unless $args{noremove} == 1;
+    }
+
     # looks good
     return bless {
         # user supplied arguments (close enough)
@@ -111,8 +119,8 @@ sub _apply_userid {
 
     # will need this later
     my $fu = LJ::load_userid( $self->from_userid );
-    unless ( $self->anonymous || $fu ) {
-        warn "Failed to apply: NOT anonymous and no from_user!\n";
+    unless ( $self->anonymous || $self->from_name || $fu ) {
+        warn "Failed to apply: NOT anonymous, no from_name, no from_user!\n";
         return 0;
     }
 
@@ -138,6 +146,7 @@ sub _apply_userid {
         foreach my $maintu ( values %$maintus ) {
             my $emailtype = $fu && $maintu->equals( $fu ) ? 'self' : 'other';
             $emailtype = 'anon' if $self->anonymous;
+            $emailtype = 'explicit' if $self->from_name;
 
             $subj = LJ::Lang::ml( "shop.email.comm.$emailtype.subject", { sitename => $LJ::SITENAME } );
             $body = LJ::Lang::ml( "shop.email.comm.$emailtype.body",
@@ -147,6 +156,7 @@ sub _apply_userid {
                     commname    => $u->display_name,
                     accounttype => $accounttype_string,
                     sitename    => $LJ::SITENAME,
+                    fromname    => $self->from_name,
                 }
             );
 
@@ -166,6 +176,7 @@ sub _apply_userid {
         } else {
             $emailtype = $fu && $u->equals( $fu ) ? 'self' : 'other';
             $emailtype = 'anon' if $self->anonymous;
+            $emailtype = 'explicit' if $self->from_name;
         }
 
         $subj = LJ::Lang::ml( "shop.email.user.$emailtype.subject", { sitename => $LJ::SITENAME } );
@@ -175,6 +186,7 @@ sub _apply_userid {
                 fromuser    => $fu ? $fu->display_name : '',
                 accounttype => $accounttype_string,
                 sitename    => $LJ::SITENAME,
+                fromname    => $self->from_name,
             }
         );
 
@@ -314,6 +326,10 @@ sub conflicts {
 sub conflicts {
     my ( $self, $item ) = @_;
 
+    # if either item are set as "does not conflict" then never say yes
+    return if
+        $self->cannot_conflict || $item->cannot_conflict;
+
     # first see if we're talking about the same target
     # note that we're not checking email here because they may want to buy
     # multiple paid accounts and send them to all to the same email address
@@ -427,6 +443,20 @@ sub t_userid {
 }
 
 
+# display who this is from
+sub from_html {
+    my $self = $_[0];
+
+    return $self->{from_name} if $self->{from_name};
+
+    my $from_u = LJ::load_userid( $self->from_userid );
+    return LJ::Lang::ml( 'widget.shopcart.anonymous' )
+        if $self->anonymous || ! LJ::isu( $from_u );
+
+    return $from_u->ljuser_display;
+}
+
+
 # simple accessors
 sub applied      { return $_[0]->{applied};         }
 sub cost         { return $_[0]->{cost};            }
@@ -438,7 +468,10 @@ sub deliverydate { return $_[0]->{delive
 sub deliverydate { return $_[0]->{deliverydate};    }
 sub anonymous    { return $_[0]->{anonymous};       }
 sub random       { return $_[0]->{random};          }
+sub noremove     { return $_[0]->{noremove};        }
+sub from_name    { return $_[0]->{from_name};       }
 sub anonymous_target { return $_[0]->{anonymous_target}; }
+sub cannot_conflict  { return $_[0]->{cannot_conflict};  }
 
 
 1;
diff -r 5f6ecf6684f1 -r 60b893aac8c6 cgi-bin/DW/Widget/ShopCartStatusBar.pm
--- a/cgi-bin/DW/Widget/ShopCartStatusBar.pm	Mon Dec 14 22:06:51 2009 +0000
+++ b/cgi-bin/DW/Widget/ShopCartStatusBar.pm	Tue Dec 15 02:11:38 2009 +0000
@@ -36,22 +36,25 @@ sub render_body {
     # old cart is gone with the wind ...
     my $cart = $opts{newcart} ? DW::Shop::Cart->new_cart( $u ) : $shop->cart;
 
-    # if the cart is empty, bail
-    return unless $cart->has_items;
+    # render out information about this cart
+    my $ret;
+    if ( $cart->has_items ) {
+        $ret .= "<div class='shop-cart-status'>";
+        $ret .= "<strong>" . $class->ml( 'widget.shopcartstatusbar.header' ) . "</strong><br />";
+        $ret .= $class->ml( 'widget.shopcartstatusbar.itemcount', { num => $cart->num_items, price => '$' . $cart->display_total . " USD" } );
+        $ret .= "<br />";
 
-    # render out information about this cart
-    my $ret = "<div class='shop-cart-status'>";
-    $ret .= "<strong>" . $class->ml( 'widget.shopcartstatusbar.header' ) . "</strong><br />";
-    $ret .= $class->ml( 'widget.shopcartstatusbar.itemcount', { num => $cart->num_items, price => '$' . $cart->display_total . " USD" } );
-    $ret .= "<br />";
+        $ret .= "<ul>";
+        $ret .= "<li><a href='$LJ::SITEROOT/shop/cart'><strong>" . $class->ml( 'widget.shopcartstatusbar.viewcart' ) . "</strong></a></li>";
+        $ret .= "<li><a href='$LJ::SITEROOT/shop?newcart=1'><strong>" . $class->ml( 'widget.shopcartstatusbar.newcart' ) . "</strong></a></li>";
+        $ret .= "</ul>";
 
-    $ret .= "<ul>";
-    $ret .= "<li><a href='$LJ::SITEROOT/shop/cart'><strong>" . $class->ml( 'widget.shopcartstatusbar.viewcart' ) . "</strong></a></li>";
-    $ret .= "<li><a href='$LJ::SITEROOT/shop?newcart=1'><strong>" . $class->ml( 'widget.shopcartstatusbar.newcart' ) . "</strong></a></li>";
-    $ret .= "</ul>";
+        $ret .= "</div>";
+    }
 
-    $ret .= "</div>";
-
+    # call out to hooks to see if they want to munge with the content
+    LJ::run_hooks( 'shop_cart_status_bar', $shop, $cart, \$ret );
+    
     return $ret;
 }
 
diff -r 5f6ecf6684f1 -r 60b893aac8c6 cgi-bin/LJ/Widget/ShopCart.pm
--- a/cgi-bin/LJ/Widget/ShopCart.pm	Mon Dec 14 22:06:51 2009 +0000
+++ b/cgi-bin/LJ/Widget/ShopCart.pm	Tue Dec 15 02:11:38 2009 +0000
@@ -59,15 +59,18 @@ sub render_body {
     $ret .= "<th>ADMIN</th>" if $opts{admin};
     $ret .= "</tr>";
     foreach my $item ( @{$cart->items} ) {
-        my $from_u = LJ::load_userid( $item->from_userid );
-
         $ret .= "<tr>";
-        $ret .= "<td>" . $class->html_check( name => 'remove_' . $item->id, value => 1 ) . "</td>"
-            unless $opts{receipt};
+        if ( $opts{receipt} ) {
+            # empty column for receipt
+        } elsif ( $item->noremove ) {
+            $ret .= "<td></td>";
+        } else {
+            $ret .= "<td>" . $class->html_check( name => 'remove_' . $item->id, value => 1 ) . "</td>"
+        }
         $ret .= "<td>" . $item->name_html . "</td>";
         $ret .= "<td>" . ( $item->deliverydate ? $item->deliverydate : $class->ml( 'widget.shopcart.deliverydate.today' ) ) . "</td>";
         $ret .= "<td>" . $item->t_html( admin => $opts{admin} ) . "</td>";
-        $ret .= "<td>" . ( $item->anonymous || !LJ::isu( $from_u ) ? $class->ml( 'widget.shopcart.anonymous' ) : $from_u->ljuser_display ) . "</td>";
+        $ret .= "<td>" . $item->from_html . "</td>";
         $ret .= "<td>" . ( $item->random ? 'Y' : 'N' ) . "</td>" if $opts{admin};
         $ret .= "<td>\$" . sprintf( "%.2f" , $item->cost ) . " USD</td>";
         if ( $opts{admin} ) {
diff -r 5f6ecf6684f1 -r 60b893aac8c6 cgi-bin/ljlib.pl
--- a/cgi-bin/ljlib.pl	Mon Dec 14 22:06:51 2009 +0000
+++ b/cgi-bin/ljlib.pl	Tue Dec 15 02:11:38 2009 +0000
@@ -2077,7 +2077,7 @@ sub get_secret
 #        'C' == captcha, 'E' == external user, 
 #        'L' == poLL,  'M' == Messaging, 'H' == sHopping cart,
 #        'F' == PubSubHubbub subscription id (F for Fred),
-#        'K' == sitekeyword
+#        'K' == sitekeyword, 'I' == shopping cart Item
 #
 sub alloc_global_counter
 {
@@ -2087,7 +2087,7 @@ sub alloc_global_counter
 
     # $dom can come as a direct argument or as a string to be mapped via hook
     my $dom_unmod = $dom;
-    unless ( $dom =~ /^[ESLPAHCMFK]$/ ) {
+    unless ( $dom =~ /^[ESLPAHCMFKI]$/ ) {
         $dom = LJ::run_hook('map_global_counter_domain', $dom);
     }
     return LJ::errobj("InvalidParameters", params => { dom => $dom_unmod })->cond_throw
@@ -2135,6 +2135,10 @@ sub alloc_global_counter
         my $max_sitekeys  = $dbh->selectrow_array( "SELECT MAX(kwid) FROM sitekeywords" );
         my $max_interests = $dbh->selectrow_array( "SELECT MAX(intid) FROM interests" );
         $newmax = $max_sitekeys > $max_interests ? $max_sitekeys : $max_interests;
+    } elsif ( $dom eq 'I' ) {
+        # if we have no counter, start at 0, as we have no way of determining what
+        # the maximum used item id is
+        $newmax = 0;
     } else {
         $newmax = LJ::run_hook('global_counter_init_value', $dom);
         die "No alloc_global_counter initalizer for domain '$dom'"
--------------------------------------------------------------------------------