ssafronova (ssafronova) wrote in changelog,
ssafronova
ssafronova
changelog

[ljcom] r7577: LJSUP-4203: Userpic Add-on - LJSUP-4457:...

Committer: ssafronova
LJSUP-4203: Userpic Add-on - LJSUP-4457: move bulk code to class structure
started making can_belong_to common for 3 actions: add, remove, checkout. Not finished.
made present_in for clean checking for coppa, permanent account, e.t.c.
little bugfix

U   branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Addon/Boolean.pm
U   branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Addon/Sized.pm
U   branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Coppa.pm
U   branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Coupon.pm
U   branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/PaidAccount.pm
U   branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Permanent.pm
U   branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Rename.pm
U   branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/VGift.pm
U   branches/shop/cgi-bin/LJ/Pay/Payment/PayItem.pm
U   branches/shop/cgi-bin/LJ/Pay/Payment.pm
U   branches/shop/cgi-bin/paylib.pl
U   branches/shop/cgi-bin/paylib_cart.pl
U   branches/shop/htdocs/pay/modify.bml
U   branches/shop/ssldocs/pay/cc.bml
U   branches/shop/ssldocs/pay/ccpay.bml
Modified: branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Addon/Boolean.pm
===================================================================
--- branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Addon/Boolean.pm	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Addon/Boolean.pm	2009-08-18 11:17:21 UTC (rev 7577)
@@ -2,22 +2,17 @@
 
 use base LJ::Pay::Payment::PayItem::Addon;
 
+# setup functions for can_belong_to() method in base class
 sub need_paid             { return 1;        }
 sub having_account_levels { return ('perm'); }
 sub disallowed_account_levels { return ();   }
-sub can_be_added_to_special_cases { return 1; }
+sub can_belong_to_special_cases { return 1; } # no special checks - only paid and perm are important
 
 sub is_valid_bool_bonus {
     my $self = shift;
     my ($item, $qty) = ($self->{item}, $self->{qty});
     my $is_rec = shift;
 
-    # allow passing of an $it hash
-    if (ref $item) {
-        $qty  = $item->{qty};
-        $item = $item->{item};
-    }
-
     my $itrec = $LJ::Pay::Payment::PayItem::Addon::bonus{$item};
     return 0 unless ref $itrec;
     return 0 unless $itrec->{type} eq 'bool';
@@ -34,80 +29,6 @@
     return LJ::Lang::ml($bitem->{'name'}) . ($short ? "" : (" - " . ($bitem->{'items'}->{$qty}->{'name'} || $qty)));
 }
 
-sub is_valid_cart_item {
-    my $self = shift;
-    my $cartobj = shift;
-
-    my $userid = $self->{'rcptid'};
-    my $item = $self->{'item'};
-
-    # when does paid time in the cart begin?
-    my $cart_paid_start = undef;
-    my $cart_bonus_start = undef;
-
-    if ($cartobj) {
-
-        # check the cart to see if we can immediately exonerate this bonus feature
-        # without even looking in the database.
-        foreach my $it (@{$cartobj->{'items'}}) {
-            next unless $it->{'rcptid'} == $userid;
-
-            # can't buy bool bonus features for permanent accounts
-            return undef if $it->{'item'} eq 'perm';
-
-            # calculate starting time of first applying amount of paid time in the cart
-            if ($it->{'item'} eq 'paidacct') {
-
-                if ($it->{'giveafter'}) {
-                    $cart_paid_start = $it->{'giveafter'} if ! defined $cart_paid_start || $it->{'giveafter'} < $cart_paid_start;
-                    next;
-                }
-
-                # no giveafter time, applies immediately
-                $cart_paid_start = 0;
-                next;
-            }
-
-            # calculate starting time of this bonus item
-            if ($it->{'item'} eq $item) {
-
-                if ($it->{'giveafter'}) {
-                    $cart_bonus_start = $it->{'giveafter'} if ! defined $cart_bonus_start || $it->{'giveafter'} < $cart_bonus_start;
-                    next;
-                }
-
-                # no giveafter time, applies immediately
-                $cart_bonus_start = 0;
-                next;
-            }
-        }
-
-        # immediately applying paid account == we're in the clear
-        # - note that undef == 0 returns true since undef gets converted to numeric
-        #   context (0) before the comparison is done, blah perl
-        return 1 if defined $cart_paid_start && $cart_paid_start == 0;
-        return 1 if defined $cart_bonus_start && defined $cart_paid_start &&
-                    $cart_bonus_start >= $cart_paid_start;
-    }
-
-    # is the specified userid a permanent account?  if so there's a problem
-    $u = LJ::load_userid($userid, "force");
-    return undef if !$u || $u->in_class('perm');
-
-    # can be applied if they have a currently unexpired paid account
-    my $dbh = LJ::get_db_writer();
-    my $paiduntil = $dbh->selectrow_array("SELECT UNIX_TIMESTAMP(paiduntil) FROM paiduser WHERE userid=? AND paiduntil>NOW()",
-                                          undef, $userid);
-
-    # at this point we know that paid time in the cart doesn't immediately
-    # exonerate the bonus feature, because we would have returned already
-    return undef if !$paiduntil || $paiduntil < $cart_bonus_start;
-
-    # everything checked out
-    return 1;
-
-}
-
 sub get_item_base_price {
     my $self = shift;
     my %opts = @_;
@@ -117,18 +38,17 @@
 }
 
 sub validate_user_input {
-    my ($self, $cartobj, $errs_ref) = @_;
+    my ($self, $cartobj, $errs_ref, $warn_ref) = @_;
 
-    return 1 if defined $LJ::Pay::Payment::PayItem::Addon::bonus{$self->{item}}->{items}->{$self->{qty}};
-    return 0;
+    return $self->is_valid_bool_bonus(0);
 }
 
 # fill 'amt', and, may be, 'qty' field
-# may be called on incomplete or 'bad' object (which will not pass checks in 'can_be_added' method)
+# may be called on incomplete or 'bad' object (which will not pass checks in 'can_be_belong_to' method)
 sub calculate_price {
     my ($self, $is_gift, $cartobj) = @_;
 
-    if ($self->is_valid_bool_bonus) {
+    if ($self->is_valid_bool_bonus(0)) {
         $self->{'amt'} = $LJ::Pay::Payment::PayItem::Addon::bonus{$self->{item}}->{items}->{$self->{qty}}->{'amount'};
     } else {
         $self->{'amt'} = undef;

Modified: branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Addon/Sized.pm
===================================================================
--- branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Addon/Sized.pm	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Addon/Sized.pm	2009-08-18 11:17:21 UTC (rev 7577)
@@ -217,13 +217,6 @@
         ($short ? "" : (" - " . ($sizeit->{'qty'}->{$qty}->{'name'} || $qty)));
 }
 
-sub is_valid_cart_item {
-    my $self = shift;
-    my $cartobj = shift;
-
-    return $self->can_apply_sized_bonus($self->{'rcptid'}, $cartobj);
-}
-
 sub get_item_base_price {
     my $self = shift;
     my %opts = @_;
@@ -232,8 +225,8 @@
     return $LJ::Pay::Payment::PayItem::Addon::bonus{$self->{item}}->{'items'}->{$self->{amt}}->{'qty'}->{$self->{qty}}->{'amount_rec'};
 }
 
-sub can_be_added {
-    my ($self, $cartobj, $errs_ref, $warn_ref) = @_;
+sub can_belong_to {
+    my ($self, $cartobj, $errs_ref, $warn_ref, $action) = @_;
 
     return 0 unless defined $LJ::Pay::Payment::PayItem::Addon::bonus{$self->{item}}->{items}->{$self->{subitem}}
         and defined $LJ::Pay::Payment::PayItem::Addon::bonus{$self->{item}}->{items}->{$self->{subitem}}->{qty}->{$self->{qty}};

Modified: branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Coppa.pm
===================================================================
--- branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Coppa.pm	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Coppa.pm	2009-08-18 11:17:21 UTC (rev 7577)
@@ -39,8 +39,8 @@
     return (1, undef, undef); # need not any processing
 }
 
-sub can_be_added {
-    my ($self, $cartobj, $errs_ref, $warn_ref) = @_;
+sub can_belong_to {
+    my ($self, $cartobj, $errs_ref, $warn_ref, $action) = @_;
 
         # can't do coppa verifications except on $remote
 

Modified: branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Coupon.pm
===================================================================
--- branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Coupon.pm	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Coupon.pm	2009-08-18 11:17:21 UTC (rev 7577)
@@ -190,8 +190,8 @@
     return (1, $subject, $body);
 }
 
-sub can_be_added {
-    my ($self, $cartobj, $errs_ref, $warn_ref) = @_;
+sub can_belong_to {
+    my ($self, $cartobj, $errs_ref, $warn_ref, $action) = @_;
 
     return 1 if grep { $_ eq $qty } @LJ::Pay::Payment::PayItem::Coupon::coupon;
     return 0;

Modified: branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/PaidAccount.pm
===================================================================
--- branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/PaidAccount.pm	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/PaidAccount.pm	2009-08-18 11:17:21 UTC (rev 7577)
@@ -1,6 +1,7 @@
 package LJ::Pay::Payment::PayItem::PaidAccount;
 
 use base LJ::Pay::Payment::PayItem::RecBillAble;
+use DateTime;
 
 sub item { return 'paidacct'; } 
 
@@ -339,8 +340,8 @@
     return LJ::Pay::paid_account_price( interval => $self->{qty}, rec => 1, %opts );
 }
 
-sub can_be_added {
-    my ($self, $cartobj, $errs_ref, $warn_ref) = @_;
+sub can_belong_to {
+    my ($self, $cartobj, $errs_ref, $warn_ref, $action) = @_;
 
     return 0 unless defined $LJ::Pay::Payment::PayItem::PaidAccount::account{$self->{'qty'}};
     return 0 unless $self->{'rcptid'};
@@ -371,4 +372,53 @@
     $self->{'amt'} = paid_account_price( interval => $self->{'qty'}, rec => 0, gift => $is_gift);
 }
 
+# get ALL intervals of paid time, both DB and cart
+# only continuous
+# supposed, that $deliver_timestamp is less or equal to present paiduntil values in paiduser table
+# $deliver_timestamp must be written as MySQL constant ('1997-10-04 22:23:00')
+sub get_paid_intervals {
+    my ($class, $cartobj, $rcpt_id, $deliver_timestamp) = @_;
+    $deliver_timestamp ||= "NOW()";
+
+    # algorithm of delivery: everything without giveafter field (at moment of delivery), then sorted giveafter intervals
+
+    my $no_ga_monthes = 0; # monthes of paid account without giveafter field
+    my @ga_monthes; # array of ::PaidAccount items
+    foreach my $it (@{$cartobj->{'items'}}) {
+        next unless $it->{'rcptid'} == $rcpt_id;
+        next unless $it->{'item'} == $class->item;
+
+        if ($it->{'giveafter'}) {
+            push @ga_monthes, $it;
+        } else {
+            $no_ga_monthes += $it->{'qty'};
+        }
+    }
+
+    my $dbh = LJ::get_db_writer() or return undef;
+
+        # retrieve (check, really) paiduntil, convert 'now()' to unixtimestamp and add monthes (to paiduntil or 'now()')
+    my ($current_start, $current_end) = 
+        $dbh->selectrow_array("SELECT IF(paiduntil, 0, UNIT_TIMESTAMP($deliver_timestamp)), "
+                                   . "UNIX_TIMESTAMP(DATE_ADD(GREATEST(IFNULL(paiduntil, $deliver_timestamp), $deliver_timestamp), "
+                                                  . "INTERVAL $no_ga_monthes MONTH)) FROM paiduser WHERE userid=?",
+                              undef, $rcpt_id) || 0;
+
+    my @intervals;
+    foreach my $ga_item (sort { $a->{'giveafter'} <=> $b->{'giveafter'} } @ga_monthes) {
+        if ($ga_item->{'giveafter'} < $current_end) {
+            $current_end = DateTime->from_epoch(epoch => $current_end)->add(months => $ga_time->{'qty'})->epoch;
+            next;
+        }
+
+        push @intervals, [$current_start, $current_end] if $current_end - $current_start;
+        $current_start = $ga_item->{'giveafter'};
+        $current_end = DateTime->from_epoch(epoch => $current_start)->add(months => $ga_time->{'qty'})->epoch;
+    } 
+
+    push @intervals, [$current_start, $current_end];
+
+    return @intervals;
+}
+
 1;

Modified: branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Permanent.pm
===================================================================
--- branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Permanent.pm	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Permanent.pm	2009-08-18 11:17:21 UTC (rev 7577)
@@ -163,8 +163,8 @@
     return (1, "$LJ::SITENAMEABBREV Permanent Account Upgrade", $msg); # account changes were successful: close transaction, need to send email
 }
 
-sub can_be_added {
-    my ($self, $cartobj, $errs_ref, $warn_ref) = @_;
+sub can_belong_to {
+    my ($self, $cartobj, $errs_ref, $warn_ref, $action) = @_;
 
     return 0 unless LJ::conf_test($LJ::PERM_SALE);
 

Modified: branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Rename.pm
===================================================================
--- branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Rename.pm	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/Rename.pm	2009-08-18 11:17:21 UTC (rev 7577)
@@ -75,8 +75,8 @@
 
 }
 
-sub can_be_added {
-    my ($self, $cartobj, $errs_ref, $warn_ref) = @_;
+sub can_belong_to {
+    my ($self, $cartobj, $errs_ref, $warn_ref, $action) = @_;
 
     return 1;
 }

Modified: branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/VGift.pm
===================================================================
--- branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/VGift.pm	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/LJ/Pay/Payment/PayItem/VGift.pm	2009-08-18 11:17:21 UTC (rev 7577)
@@ -248,8 +248,8 @@
     return (1, undef, undef); 
 }
 
-sub can_be_added {
-    my ($self, $cartobj, $errs_ref, $warn_ref) = @_;
+sub can_belong_to {
+    my ($self, $cartobj, $errs_ref, $warn_ref, $action) = @_;
 
     my $all_vgifts = LJ::Pay::ShopVGift->get_all_vgifts; # simple DB hashrefs, memcached e.t.c
     return 0 unless defined $all_vgifts->{by_name}->{$self->{subitem}};

Modified: branches/shop/cgi-bin/LJ/Pay/Payment/PayItem.pm
===================================================================
--- branches/shop/cgi-bin/LJ/Pay/Payment/PayItem.pm	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/LJ/Pay/Payment/PayItem.pm	2009-08-18 11:17:21 UTC (rev 7577)
@@ -718,10 +718,6 @@
     die "Cannot define pay item type";
 }
 
-sub is_valid_cart_item {
-    return undef; # negative default - it is wrong, that we have no child class object
-}
-
 sub render_cart_item {
     my $self = shift;
     my $opts = shift;
@@ -795,19 +791,52 @@
     return (0, undef, undef); # not ok (may not mark item as 'done'), no mail message
 }
 
-sub need_paid             { return 0;  }
-sub having_account_levels { return (); }
-sub disallowed_account_levels { return (); }
-sub can_be_added_to_special_cases { return 0; } # base class method will work only on incorrect pay items, disallow them
+# setup functions for can_belong_to() method
+# need_paid() object(!) method says, need this payitem checking for paid account in DB and cart, or not
+#   return: boolean
+# having_account_levels() object(!) method says, which account levels already have item feature, and therefore cannot buy it
+#   example: paid account already have statistics and cannot buy it
+#   return: array of values, applicable for LJ::User->in_class call
+# disallowed_account_levels() object(!) method says, which account levels may not buy item
+#   example: sponsored account may not buy paid account
+#   return: array of values, applicable for LJ::User->in_class call
+# can_belong_to_special_cases() object method and have same signature as can_belong_to()
+#   it is intended for adding some exceptions for algorithms
+#   can_belong_to_special_cases() will be called only in case of positive answer for all(!) account level checks
+#   return: boolean
+# any child class must redefine can_belong_to_special_cases() to return 1 (or something more difficult)
+# but we may not put such default here, because base class is not only common code for child classes,
+# but used for obsolete or incorrect items sometime
+sub need_paid             { return 0;  } # default: no need in paid account
+sub having_account_levels { return (); } # default: no any account already have item feature
+sub disallowed_account_levels { return (); } # default: any account allowed to buy feature
+sub can_belong_to_special_cases { return 0; } # base class method will work only on incorrect pay items, disallow them
 
-sub can_be_added {
-    my ($self, $cartobj, $errs_ref, $warn_ref) = @_;
+# check business rules between payitem and cart (returns boolean: "Can $self item belong to $cartobj?")
+# called in 3 different actions:
+#   'add' (this item is not in cart yet),
+#   'remove' (other item already deleted, this item in cart yet, method must recheck business rules after deletition),
+#   'checkout' (this item is in cart now, method must recheck business rules in most fresh conditions)
+# it is intended, that some subclasses will redefine method instead of filling setup functions
+# implementation in this class made for item, depending on paid account and other account levels
+# some items, vgift for example, is easier to check item directly, by reimplementing this method
+# for now, we not use action name in algorithm, but for later life we provide it
+# method must return true for correct item and false for incorrect
+# user input is not validated at start of this algorithm, validating it is first step
+# invalid user input means that user changed page code in his/her browser, so we need not provide detailed error
+# in case of invalid user input parameters we silently return 0 and caller silently redirects user to the cart page
+# in case of account level error we provide array(!) of errors in @$errs_ref
+# some type of errors are not stopping, and we provide that errors in $$warn_ref (scalar!) and caller asks user acknoledge
+# because found warning case stops the algorithm, caller must pass undef as value of $warn_ref on second pass (after acknoledge)
+# it is allowed, that one call checks several items of same type and same recipient
+sub can_belong_to {
+    my ($self, $cartobj, $errs_ref, $warn_ref, $action) = @_;
 
-    return 0 unless $self->validate_user_input;
+    return 0 unless $self->validate_user_input($cartobj, $errs_ref, $warn_ref, $action);
 
     my $rcptuser = LJ::load_userid($self->{'rcptid'});
     return 0 unless $rcptuser;
-
+=comment Not Finished yet
     my $dbh = LJ::get_db_writer() or return 0;
 
     my $dispname = $self->product_name("short");
@@ -836,52 +865,43 @@
         }
     }
 
-    # may be we will need this later, on accout levels checks
-    my $cart_bonus_months = $self->{'qty'};      # months of bonus feat. in cart
-    my $cart_paid_months = 0;                    # months of paidacct in cart
-    my $cart_bonus_start = $self->{'giveafter'}; # start of bonus feature in cart
-    my $cart_paid_start  = undef;                # start of paid account in cart
-    my $cart_perm_acct = 0;                      # can't buy bool bonus features for perms
     if ($self->need_paid) {
-        # check to see if the user is trying to buy bonus features that extend
-        # past the expiration of their paid account... factor in any paid time
-        # currently in the cart as well.  if so, ask for confirmation
 
-        foreach my $it (@{$cartobj->{'items'}}) {
-            next unless $it->{'rcptid'} == $self->{'rcptid'};
+        # used in messages, $rcptuser is always defined here
+        my $utag = LJ::ljuser($rcptuser);
 
-            my $ga = $it->{'giveafter'} || 0;
+        my $cart_perm_acct = LJ::Pay::Payment::PayItem::Permanent->present_in($cartobj, $self->{'rcptid'}); # can't buy bool bonus features for perms
+        my $is_perm = ($cart_perm_acct || $rcptuser->in_class('perm'));
 
-            # bonus item
-            if ($it->{'item'} eq $self->{item}) {
-                $cart_bonus_months += $it->{'qty'};
+        my @paid_intervals = LJ::Pay::Payment::PayItem::PaidAccount->get_paid_intervals($cartobj, $self->{'rcptid'});
 
-                # find which instance of this bonus feature takes effect first
-                if (! defined $cart_bonus_start ||
-                    $ga < $cart_bonus_start) {
+        my $found = 0;
+        my $need_warn = 0;
 
-                    $cart_bonus_start = $ga;
-                }
+        if ($self->{'giveafter'}) {
 
-            # paid account
-            } elsif ($it->{'item'} eq "paidacct") {
-                $cart_paid_months += $it->{'qty'};
+            my $self_end = DateTime->from_epoch(epoch => $self->{'giveafter'})->add(months => $ga_time->{'qty'})->epoch;
 
-                # find which paid account takes effect sooner
-                if (! defined $cart_paid_start ||
-                    $ga < $cart_paid_start) {
-
-                    $cart_paid_start = $ga;
+            foreach my $interval (@paid_intervals) {
+                if ($interval->[0] <= $self->{'giveafter'} and $self->{'giveafter'} <= $interval->[1]) {
+                    $found = 1;
+                    $need_warn = $self_end > $interval->[1];
                 }
+            }
 
-            } elsif ($it->{'item'} eq 'perm') {
-                $cart_perm_acct = 1;
+        } else { # no giveafter, check against first interval (DB time + cart monthes without giveafter)
+            if ($paid_intervals[0]->[0] <= $self->{'giveafter'} and $self->{'giveafter'} <= $paid_intervals[0]->[1]) {
+                $found = 1;
+                $need_warn = ## FIX ME;
             }
         }
-        $cart_paid_start ||= 0;
 
-        my $is_perm = ($cart_perm_acct || $rcptuser->in_class('perm'));
+        unless ($found or $is_perm) {
+            $errs_ref->[0] = BML::ml('.error.cantbuyextrasforfreeaccount', {'item' => "<b>$dispname</b>", 'user' => $utag});
+            return 0;
+        }
 
+
         # return max of arguments, undef if none
         my $max = sub { @_ ? (sort { $b <=> $a } @_)[0] : undef; };
 
@@ -890,14 +910,7 @@
                                   "FROM paiduser WHERE userid=?",
                                   undef, $self->{'rcptid'}) || 0;
 
-        # used in messages, $rcptuser is always defined here
-        my $utag = LJ::ljuser($rcptuser);
 
-        # no paid account at all
-        unless ($db_paid_time || $cart_paid_months) {
-            $errs_ref->[0] = BML::ml('.error.cantbuyextrasforfreeaccount', {'item' => "<b>$dispname</b>", 'user' => $utag});
-            return 0;
-        }
 
         my $ga = $self->{'giveafter'} || 0;
 
@@ -928,7 +941,7 @@
         # remove giveafter if no paid account in cart and it is after the
         # expiration of their current paid account
         if ($warn_ref && $db_paid_time > 0 && $ga > $db_paid_time &&
-            (! $cart_paid_months || $ga < $cart_paid_start)) { # no acknoledgement phase yet...
+            (! $cart_paid_months || $ga < $cart_paid_start)) { # non-undef $warn_ref means no acknoledgement phase yet...
 
             # get rid of giveafter date in memory, to be clean
             $self->{'giveafter'} = 0;
@@ -1006,7 +1019,7 @@
                 $$warn_ref = "<?h1 " . BML::ml('.paidtimewillexpire.header') . " h1?>";
                 $$warn_ref .= "<?p " . BML::ml('.paidtimewillexpire.text1', {'item' => "<b>$dispname</b>", 'user' => $utag}) . " p?>";
 
-                if ($db_paid_time && $self->{'rcptid'} == $remote->{'rcptid'}) {
+                if ($db_paid_time && $remote && $self->{'rcptid'} == $remote->{'rcptid'}) {
                     $$warn_ref .= "<p>" . BML::ml('.paidtimewillexpire.text2_expires', {'user' => $utag,
                                                     'date' => "<i>" . LJ::time_to_http($db_paid_time) . "</i>", 
                                                     'item' => "<b>$dispname</b>"}) . "</p>";
@@ -1041,7 +1054,7 @@
         }
     }
 =cut
-    return $self->can_be_added_to_special_cases($cartobj, $errs_ref, $warn_ref);
+    return $self->can_belong_to_special_cases($cartobj, $errs_ref, $warn_ref, $action);
 }
 
 # fill 'amt', and, may be, 'qty' field
@@ -1052,4 +1065,14 @@
     $self->{amt} = 0;
 }
 
+# simple check of payitem presence in cart
+# returns number of occurrence
+sub present_in {
+    my ($class, $cartobj, $rcpt_id ) = @_;
+
+    return 0 unless $cartobj;
+    return 0 unless @{$cartobj->{items}};
+    return scalar grep { $_->{item} eq $class->item and (not $rcpt_id or $_->{rcptid} eq $rcpt_id) } @{$cartobj->{items}};
+}
+
 1;

Modified: branches/shop/cgi-bin/LJ/Pay/Payment.pm
===================================================================
--- branches/shop/cgi-bin/LJ/Pay/Payment.pm	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/LJ/Pay/Payment.pm	2009-08-18 11:17:21 UTC (rev 7577)
@@ -810,14 +810,6 @@
     return 1;
 }
 
-sub contains_coppa {
-    my LJ::Pay::Payment $self = shift
-        or return _err("invalid arguments");
-
-    return 0 unless @{$self->{items}};
-    return scalar grep { $_->{item} eq 'coppa' } @{$self->{items}};
-}
-
 sub needs_shipping {
     my LJ::Pay::Payment $self = shift
         or return _err("invalid arguments");

Modified: branches/shop/cgi-bin/paylib.pl
===================================================================
--- branches/shop/cgi-bin/paylib.pl	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/paylib.pl	2009-08-18 11:17:21 UTC (rev 7577)
@@ -354,13 +354,6 @@
     return 1;
 }
 
-sub LJ::Pay::item_needs_shipping {
-    my $it = shift;
-    return 0 unless $it;
-    return $it->needs_shipping;
-}
-
-
 # FIXME: this should probably be in something like weblib-local.pl
 sub LJ::Pay::get_blurb {
     my $pos = shift;

Modified: branches/shop/cgi-bin/paylib_cart.pl
===================================================================
--- branches/shop/cgi-bin/paylib_cart.pl	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/cgi-bin/paylib_cart.pl	2009-08-18 11:17:21 UTC (rev 7577)
@@ -127,7 +127,8 @@
 
     # iterate over all items and make sure that each one is allowed to be there
     my %done = ();
-    my $found_coppa = undef;
+    my $found_coppa = LJ::Pay::Payment::PayItem::Coppa->present_in($cartobj);
+    return undef if $found_coppa > 1;
     foreach my $it (@{$cartobj->{'items'}}) {
 
         # cache that we checked this (userid, item) combination
@@ -137,12 +138,8 @@
             $done{$key} = 1;
         }
 
-        if ($it->{'item'} eq LJ::Pay::Payment::PayItem::Coppa::item()) {
-            return undef if $found_coppa; # second coppa in cart
-            $found_coppa = 1;
-        }
-
-        if ($it->is_valid_cart_item($cartobj)) {
+        my @errs;
+        if ($it->can_belong_to($cartobj, \@errs, undef, 'checkout')) {
             next;
         } else {
             return undef;
@@ -175,7 +172,7 @@
     my $ret = shift;
     my $opts = shift;
     my $remote = LJ::get_remote();
-    my $has_coppa = $cartobj->contains_coppa;
+    my $has_coppa = LJ::Pay::Payment::PayItem::Coppa->present_in($cartobj);
 
     $$ret .= <<HDR;
 <table width='95%' cellpadding='2' style='border-collapse: collapse'>

Modified: branches/shop/htdocs/pay/modify.bml
===================================================================
--- branches/shop/htdocs/pay/modify.bml	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/htdocs/pay/modify.bml	2009-08-18 11:17:21 UTC (rev 7577)
@@ -218,8 +218,8 @@
         }
 
         return $err->($ML{'.error.invalidpaymentmethodforage'}) if
-            $POST{'paymeth'} ne 'cc' && $cartobj->contains_coppa;
-        $POST{'paymeth'} = "free" if $cartobj->{'amount'} == 0 && ! $cartobj->needs_shipping && ! $cartobj->contains_coppa;
+            $POST{'paymeth'} ne 'cc' && LJ::Pay::Payment::PayItem::Coppa->present_in($cartobj);
+        $POST{'paymeth'} = "free" if $cartobj->{'amount'} == 0 && ! $cartobj->needs_shipping && ! LJ::Pay::Payment::PayItem::Coppa->present_in($cartobj);
 
         if ($cartobj->{userid} && $remote && $remote->underage &&
             ! scalar grep { $_->{item} eq 'coppa' } @{$cartobj->{items}}) {
@@ -744,7 +744,7 @@
         my @errs;
         my $warn;
         my $warn_ref = $POST{'action:additem:confirm'} ? undef : \$warn; # user have seen warning already? skip it now...
-        my $can_be_added = $item->can_be_added($cartobj, \@errs, $warn_ref);
+        my $can_be_added = $item->can_belong_to($cartobj, \@errs, $warn_ref, 'additem');
         return BML::redirect("/pay/?c=$cart") if not $can_be_added and not @errs; # nothing to say? draw the cart silently
         return $err->(@errs) unless $can_be_added;
 
@@ -758,8 +758,9 @@
             return $err->($err_msg) if $err_msg;
         }
 
-        if ($warn and !$POST{'action:additem:confirm'}) {
+        if ($warn) {
 
+            # fixing for user possibly changed giveafter
             $POST{'giveafter'} = $item->{'giveafter'};
 
             # pass on post variables
@@ -768,7 +769,7 @@
                                       qw(otheruser paymeth action:additem for item cart
                                          giveafter giveafter_yyyy giveafter_mm giveafter_dd anongift) );
 
-            # explain expiration
+            # explain warning condition (most times it is expiration of paid account)
             $body .= $warn;
             $body .= "<p align='center'>" . LJ::html_submit('action:additem:confirm', $ML{'.btn.acknowledged'}) . "</p>";
             $body .= "</form>";

Modified: branches/shop/ssldocs/pay/cc.bml
===================================================================
--- branches/shop/ssldocs/pay/cc.bml	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/ssldocs/pay/cc.bml	2009-08-18 11:17:21 UTC (rev 7577)
@@ -19,7 +19,7 @@
     return BML::redirect("$LJ::SITEROOT/pay/") unless $cartobj;
 
     my $needs_shipping = $cartobj->needs_shipping;
-    my $has_coppa      = $cartobj->contains_coppa;
+    my $has_coppa      = LJ::Pay::Payment::PayItem::Coppa->present_in($cartobj);
 
     $title = $has_coppa ? $ML{'.coppa.title'} : $ML{'.title'};
 
@@ -296,7 +296,7 @@
         # if there is no userid, then we know it's clean because we checked
         # each individual item for email blocks when they were added to the cart
         
-        my $has_coppa      = $cartobj->contains_coppa;
+        my $has_coppa      = LJ::Pay::Payment::PayItem::Coppa->present_in($cartobj);
         my $needs_shipping = $cartobj->needs_shipping;
         
         # coppa requires remote

Modified: branches/shop/ssldocs/pay/ccpay.bml
===================================================================
--- branches/shop/ssldocs/pay/ccpay.bml	2009-08-18 10:34:25 UTC (rev 7576)
+++ branches/shop/ssldocs/pay/ccpay.bml	2009-08-18 11:17:21 UTC (rev 7577)
@@ -191,7 +191,7 @@
     # if there is no userid, then we know it's clean because we checked
     # each individual item for email blocks when they were added to the cart
 
-    my $has_coppa      = $cartobj->contains_coppa;
+    my $has_coppa      = LJ::Pay::Payment::PayItem::Coppa->present_in($cartobj);
     my $needs_shipping = $cartobj->needs_shipping;
 
     # coppa requires remote

Subscribe

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 0 comments