Repository: gratipay/gratipay.com

Issue:
Can't update my take
I tried to increase my take from one of the teams that I belong but was unable to. I got the following error.

![image](https://cloud.githubusercontent.com/assets/1266505/4205610/5f9a33e0-3842-11e4-82f1-f0c72dd24467.png)

I was increasing to less that double the amount and my history shows that the new amount is less than double the the amount I was attempting to take. 



Discussion:
@kaguillera for some reason the Members take table has been reset on this team 

Looking into this ...

@kaguillera @whit537 should I rise a ticket?

I raised one. 

On Sep 9, 2014, at 1:16 PM, Christopher Clarke notifications@github.com wrote:

> @kaguillera @whit537 should I rise a ticket?
> 
> —
> Reply to this email directly or view it on GitHub.

Updating your take is based on your _actual_ take last week. Since a failed credit card transaction meant that there wasn't enough money for your take from 7Macaw to go through last week, the baseline for our take math was 0. I'm pretty sure that's what's happening here, and I'd call it an edge case and a bug. We should base the take math on your last successful ( > 0 ) take.

Another question this raises: if a Team has a credit card attached, should we charge that to cover takes if need be?

I'm marking this ★★★ to get @kaguillera's take state repaired for this week. We can drop to ★★☆ or reticket to deal with fixing root cause(s).

@chrisdev I am seeing three people on the 7Macaw team. From what I can tell, @kaguillera is the only one who had his take clipped this week. Yes?

@whit537  I think my take was also clipped but its not so important :smile: 
I think i've got to fund the team with a larger amount upfront . The weekly funding payments are are sub-optimal. 
I've encountered a number of issues in terms funding teams /paying larger sums to Gratipay I hope to write them up by the end of the week including my work arounds.

This also affects the https://gratipay.com/DrupalCoreGittipTeam team

+1 from @Bojhan (also DrupalCore) at https://github.com/gratipay/gratipay.com/issues/2537#issuecomment-55026082:

> This issue occurred again?
> 
> I wanted to down my payment from $64 to $32 and it resetted me to $1
> 
> https://gratipay.com/DrupalCoreGittipTeam/members/

This seems like a pretty big deal to fix before payday this week.

Is it? We currently [max out the take](https://github.com/gratipay/gratipay.com/blob/f3668ee9c8b443b926977f53b9811a4243ce2a3a/gratipay/models/_mixin_team.py#L104-L129) to be no more than 2x the [actual amount received last week](https://github.com/gratipay/gratipay.com/blob/f3668ee9c8b443b926977f53b9811a4243ce2a3a/gratipay/models/_mixin_team.py#L73-L92).

One option would be to skip this code if you're setting your take to be less than what it's currently set at, though I think it would make more sense to store a history of team takes (do we not?) and compare to the take that applied last week.


Resolving patch:
diff --git a/gratipay/models/_mixin_team.py b/gratipay/models/_mixin_team.py
--- a/gratipay/models/_mixin_team.py
+++ b/gratipay/models/_mixin_team.py
@@ -71,7 +71,7 @@ def member_of(self, team):
         return False
 
     def get_take_last_week_for(self, member):
-        """What did the user actually take most recently? Used in throttling.
+        """Get the user's nominal take last week. Used in throttling.
         """
         assert self.IS_PLURAL
         membername = member.username if hasattr(member, 'username') \
@@ -79,15 +79,15 @@ def get_take_last_week_for(self, member):
         return self.db.one("""
 
             SELECT amount
-              FROM transfers
-             WHERE tipper=%s AND tippee=%s AND context='take'
-               AND timestamp > (
+              FROM takes
+             WHERE team=%s AND member=%s
+               AND mtime < (
                        SELECT ts_start
                          FROM paydays
                         WHERE ts_end > ts_start
                      ORDER BY ts_start DESC LIMIT 1
                    )
-          ORDER BY timestamp ASC LIMIT 1
+          ORDER BY mtime DESC LIMIT 1
 
         """, (self.username, membername), default=Decimal('0.00'))
 


Test patch:
diff --git a/tests/py/test_take.py b/tests/py/test_take.py
--- a/tests/py/test_take.py
+++ b/tests/py/test_take.py
@@ -22,19 +22,15 @@ def make_team(self, username=TEAM, **kw):
         self.warbucks.set_tip_to(team, '100')
         return team
 
-    def make_participant(self, username, **kw):
-        take_last_week = kw.pop('take_last_week', None)
-        team_name = kw.pop('', TEAM)
-        participant = Harness.make_participant(self, username, **kw)
-        if take_last_week is not None:
-            if self.db.one('SELECT * FROM paydays') is None:
-                self.db.run("INSERT INTO paydays DEFAULT VALUES")
-            self.db.run( "INSERT INTO transfers (timestamp, tipper, tippee, amount, context) "
-                         "VALUES (now(), %(tipper)s, %(tippee)s, %(amount)s, 'take')"
-                       , dict(tipper=team_name, tippee=username, amount=take_last_week,)
-                        )
-            self.db.run("UPDATE paydays SET ts_end=now()")
-        return participant
+    def take_last_week(self, team, member, amount, actual_amount=None):
+        team._MixinTeam__set_take_for(member, amount, member)
+        self.db.run("INSERT INTO paydays DEFAULT VALUES")
+        actual_amount = amount if actual_amount is None else actual_amount
+        self.db.run("""
+            INSERT INTO transfers (timestamp, tipper, tippee, amount, context)
+            VALUES (now(), %(tipper)s, %(tippee)s, %(amount)s, 'take')
+        """, dict(tipper=team.username, tippee=member.username, amount=actual_amount))
+        self.db.run("UPDATE paydays SET ts_end=now() WHERE ts_end < ts_start")
 
     def test_we_can_make_a_team(self):
         team = self.make_team()
@@ -47,47 +43,48 @@ def test_random_schmoe_is_not_member_of_team(self):
 
     def test_team_member_is_team_member(self):
         team = self.make_team()
-        alice = self.make_participant('alice', take_last_week='40.00', claimed_time='now')
-        team.add_member(alice)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '40.00')
         assert alice.member_of(team)
 
     def test_cant_grow_tip_a_lot(self):
         team = self.make_team()
-        alice = self.make_participant('alice', take_last_week='40.00')
-        team._MixinTeam__set_take_for(alice, D('40.00'), team)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '40.00')
         assert team.set_take_for(alice, D('100.00'), alice) == 80
 
     def test_take_can_double(self):
         team = self.make_team()
-        alice = self.make_participant('alice', take_last_week='40.00')
-        team._MixinTeam__set_take_for(alice, D('40.00'), team)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '40.00')
         team.set_take_for(alice, D('80.00'), alice)
         assert team.get_take_for(alice) == 80
 
     def test_take_can_double_but_not_a_penny_more(self):
         team = self.make_team()
-        alice = self.make_participant('alice', take_last_week='40.00')
-        team._MixinTeam__set_take_for(alice, D('40.00'), team)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '40.00')
         actual = team.set_take_for(alice, D('80.01'), alice)
         assert actual == 80
 
-    def test_increase_is_based_on_actual_take_last_week(self):
+    def test_increase_is_based_on_nominal_take_last_week(self):
         team = self.make_team()
-        alice = self.make_participant('alice', take_last_week='20.00')
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '20.00', actual_amount='15.03')
         team._MixinTeam__set_take_for(alice, D('35.00'), team)
         assert team.set_take_for(alice, D('42.00'), alice) == 40
 
     def test_if_last_week_is_less_than_a_dollar_can_increase_to_a_dollar(self):
         team = self.make_team()
-        alice = self.make_participant('alice', take_last_week='0.01', claimed_time='now')
-        team.add_member(alice)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '0.01')
         actual = team.set_take_for(alice, D('42.00'), team)
         assert actual == 1
 
     def test_get_members(self):
         team = self.make_team()
-        alice = self.make_participant('alice', take_last_week='40.00', claimed_time='now')
-        team.add_member(alice)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '40.00')
         team.set_take_for(alice, D('42.00'), team)
         members = team.get_members(alice)
         assert len(members) == 2
@@ -97,8 +94,8 @@ def test_get_members(self):
 
     def test_compute_actual_takes_counts_the_team_balance(self):
         team = self.make_team(balance=D('59.46'))
-        alice = self.make_participant('alice', take_last_week='100.00', claimed_time='now')
-        team.add_member(alice)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '100.00')
         team.set_take_for(alice, D('142.00'), team)
         takes = team.compute_actual_takes().values()
         assert len(takes) == 2
@@ -111,8 +108,8 @@ def test_compute_actual_takes_counts_the_team_balance(self):
 
     def test_compute_actual_takes_gives_correct_final_balance(self):
         team = self.make_team(balance=D('53.72'))
-        alice = self.make_participant('alice', take_last_week='100.00', claimed_time='now')
-        team.add_member(alice)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '100.00')
         team.set_take_for(alice, D('86.00'), team)
         takes = team.compute_actual_takes().values()
         assert len(takes) == 2
@@ -125,8 +122,8 @@ def test_compute_actual_takes_gives_correct_final_balance(self):
 
     def test_taking_and_receiving_are_updated_correctly(self):
         team = self.make_team()
-        alice = self.make_participant('alice', take_last_week='40.00', claimed_time='now')
-        team.add_member(alice)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '40.00')
         team.set_take_for(alice, D('42.00'), alice)
         assert alice.taking == 42
         assert alice.receiving == 42
@@ -157,8 +154,8 @@ def test_but_team_can_take_from_other_team(self):
 
     def test_changes_to_team_receiving_affect_members_take(self):
         team = self.make_team()
-        alice = self.make_participant('alice', take_last_week='40.00', claimed_time='now')
-        team.add_member(alice)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '40.00')
         team.set_take_for(alice, D('42.00'), alice)
 
         self.warbucks.set_tip_to(team, D('10.00'))  # hard times
@@ -168,12 +165,12 @@ def test_changes_to_team_receiving_affect_members_take(self):
     def test_changes_to_others_take_affects_members_take(self):
         team = self.make_team()
 
-        alice = self.make_participant('alice', take_last_week='30.00', claimed_time='now')
-        team.add_member(alice)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '30.00')
         team.set_take_for(alice, D('42.00'), alice)
 
-        bob = self.make_participant('bob', take_last_week='50.00', claimed_time='now')
-        team.add_member(bob)
+        bob = self.make_participant('bob', claimed_time='now')
+        self.take_last_week(team, bob, '50.00')
         team.set_take_for(bob, D('60.00'), bob)
 
         alice = Participant.from_username('alice')
@@ -185,12 +182,12 @@ def test_changes_to_others_take_affects_members_take(self):
     def test_changes_to_others_take_can_increase_members_take(self):
         team = self.make_team()
 
-        alice = self.make_participant('alice', take_last_week='30.00', claimed_time='now')
-        team.add_member(alice)
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '30.00')
         team.set_take_for(alice, D('42.00'), alice)
 
-        bob = self.make_participant('bob', take_last_week='60.00', claimed_time='now')
-        team.add_member(bob)
+        bob = self.make_participant('bob', claimed_time='now')
+        self.take_last_week(team, bob, '60.00')
         team.set_take_for(bob, D('80.00'), bob)
         alice = Participant.from_username('alice')
         assert alice.receiving == alice.taking == 20
@@ -203,9 +200,9 @@ def test_changes_to_others_take_can_increase_members_take(self):
 
     def test_gtlwf_works_during_payday(self):
         team = self.make_team()
-        alice = self.make_participant('alice', take_last_week='30.00', claimed_time='now')
+        alice = self.make_participant('alice', claimed_time='now')
+        self.take_last_week(team, alice, '30.00')
         take_this_week = D('42.00')
-        team.add_member(alice)
         team.set_take_for(alice, take_this_week, alice)
         self.db.run("INSERT INTO paydays DEFAULT VALUES")
         assert team.get_take_last_week_for(alice) == 30