diff --git a/sql/branch.py b/sql/branch.py new file mode 100644 index 0000000000..30c3621ce0 --- /dev/null +++ b/sql/branch.py @@ -0,0 +1,16 @@ +from gratipay import wireup + +db = wireup.db(wireup.env()) + +participants = db.all(""" + SELECT p.*::participants + FROM participants p + JOIN payment_instructions pi ON pi.participant = p.username -- Only include those with tips +""") +total = len(participants) +counter = 0 + +for p in participants: + print("Participant %s/%s" % (counter, total)) + p.update_giving_and_teams() + counter += 1 diff --git a/sql/branch.sql b/sql/branch.sql new file mode 100644 index 0000000000..dc4aa22346 --- /dev/null +++ b/sql/branch.sql @@ -0,0 +1,3 @@ +BEGIN; + UPDATE payment_instructions SET due = 0 WHERE due > 9.41; +END; diff --git a/sql/payday.sql b/sql/payday.sql index 1750b970e1..c790d267e2 100644 --- a/sql/payday.sql +++ b/sql/payday.sql @@ -186,13 +186,14 @@ CREATE OR REPLACE FUNCTION process_payment_instruction() RETURNS trigger AS $$ FROM payday_participants p WHERE username = NEW.participant ); + IF (NEW.amount + NEW.due <= participant.new_balance OR participant.card_hold_ok) THEN EXECUTE pay(NEW.participant, NEW.team, NEW.amount + NEW.due, 'to-team'); RETURN NEW; - ELSE + ELSIF participant.has_credit_card THEN EXECUTE park(NEW.participant, NEW.team, NEW.amount + NEW.due); - RETURN NULL; END IF; + RETURN NULL; END; $$ LANGUAGE plpgsql; @@ -202,6 +203,7 @@ CREATE TRIGGER process_payment_instruction BEFORE UPDATE OF is_funded ON payday_ WHEN (NEW.is_funded IS true AND OLD.is_funded IS NOT true) EXECUTE PROCEDURE process_payment_instruction(); + -- Create a trigger to process takes CREATE OR REPLACE FUNCTION process_take() RETURNS trigger AS $$ diff --git a/tests/py/test_billing_payday.py b/tests/py/test_billing_payday.py index 17a0284c34..52f9934328 100644 --- a/tests/py/test_billing_payday.py +++ b/tests/py/test_billing_payday.py @@ -101,6 +101,28 @@ def test_payday_preserves_due_until_charged(self, fch): assert obama.balance == D('0.00') assert obama.get_due('TheEnterprise') == D('0.00') + @mock.patch.object(Payday, 'fetch_card_holds') + def test_payday_keeps_dues_under_minimum_charge(self, fch): + Enterprise = self.make_team(is_approved=True) + self.obama.set_payment_instruction(Enterprise, '4.00') + assert self.obama.get_due('TheEnterprise') == D('0.00') + + fch.return_value = {} + Payday.start().run() # payday 0 + + assert self.obama.get_due('TheEnterprise') == D('4.00') + + fch.return_value = {} + self.obama_route.update_error("failed") # card fails + Payday.start().run() # payday 1 + + assert self.obama.get_due('TheEnterprise') == D('4.00') + + fch.return_value = {} + Payday.start().run() # payday 2 + + assert self.obama.get_due('TheEnterprise') == D('4.00') + @mock.patch.object(Payday, 'fetch_card_holds') def test_payday_does_not_move_money_below_min_charge(self, fch): Enterprise = self.make_team(is_approved=True)