diff --git a/tests/py/test_teams.py b/tests/py/test_teams.py
index 59608e9086..f93d7fa554 100644
--- a/tests/py/test_teams.py
+++ b/tests/py/test_teams.py
@@ -340,6 +340,9 @@ def test_stripping_required_inputs(self):
assert self.db.one("SELECT COUNT(*) FROM teams") == 0
assert "Please fill out the 'Team Name' field." in r.body
+ # Migrate Tips
+ # ============
+
def test_migrate_tips_to_payment_instructions(self):
alice = self.make_participant('alice', claimed_time='now')
bob = self.make_participant('bob', claimed_time='now')
@@ -390,7 +393,40 @@ def test_migrate_tips_checks_for_multiple_teams(self):
assert len(payment_instructions) == 1
- # cached values - receiving, nreceiving_from
+ # Dues, Upcoming Payment
+ # ======================
+
+ def test_get_dues(self):
+ alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
+ bob = self.make_participant('bob', claimed_time='now', last_bill_result='Fail!')
+ team = self.make_team(is_approved=True)
+
+ alice.set_payment_instruction(team, '3.00') # Funded
+ bob.set_payment_instruction(team, '5.00') # Unfunded
+
+ # Simulate dues
+ self.db.run("UPDATE payment_instructions SET due = amount")
+
+ assert team.get_dues() == (3, 5)
+
+
+ def test_upcoming_payment(self):
+ alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
+ bob = self.make_participant('bob', claimed_time='now', last_bill_result='')
+ carl = self.make_participant('carl', claimed_time='now', last_bill_result='Fail!')
+ team = self.make_team(is_approved=True)
+
+ alice.set_payment_instruction(team, '5.00') # Funded
+ bob.set_payment_instruction(team, '3.00') # Funded, but won't hit minimum charge
+ carl.set_payment_instruction(team, '10.00') # Unfunded
+
+ # Simulate dues
+ self.db.run("UPDATE payment_instructions SET due = amount")
+
+ assert team.get_upcoming_payment() == 10 # 2 * Alice's $5
+
+ # Cached Values
+ # =============
def test_receiving_only_includes_funded_payment_instructions(self):
alice = self.make_participant('alice', claimed_time='now', last_bill_result='')
diff --git a/www/%team/charts.json.spt b/www/%team/charts.json.spt
index 4af812972e..d5acbff9d4 100644
--- a/www/%team/charts.json.spt
+++ b/www/%team/charts.json.spt
@@ -1,19 +1,13 @@
-"""Return an array of objects with interesting data for the user.
+"""Return an array of objects with interesting data for the team.
-We want one object per payday, but the user probably didn't participate in
-every payday. Our solution is to fetch all paydays and all of the user's
-transfers, and then loop through transfers and aggregate into the relevant
+We want one object per payday, but the team probably didn't participate in
+every payday. Our solution is to fetch all paydays and all of the team's
+payments, and then loop through payments and aggregate into the relevant
payday object.
-If the user has never received, we return an empty array. Client code can take
+If the team has never received, we return an empty array. Client code can take
this to mean, "no chart."
-We specifically don't worry about double-counting npatrons for out-of-band
-transfers. That's a rare case right now, pretty much only when someone
-deactivates their account and distributes their balance as a final gift. It
-could become much more common in a one-off payments world, depending on how the
-implementation.
-
"""
import re
@@ -25,22 +19,7 @@ callback_pattern = re.compile(r'^[_A-Za-z0-9.]+$')
[---]
-username = request.path['username']
-
-anonymous = website.db.one("""
-
- SELECT anonymous_receiving
- FROM participants
- WHERE username = %s
-
-""", (username,))
-
-if anonymous:
- if user.ANON:
- raise Response(401)
- elif user.participant.username != username and not user.ADMIN:
- raise Response(403)
-
+slug = request.path['team']
# Fetch data from the database.
# =============================
@@ -49,29 +28,29 @@ paydays = website.db.all("""
SELECT p.ts_start
, p.ts_start::date AS date
- , 0 AS npatrons
+ , 0 AS nreceiving_from
, 0.00 AS receipts
FROM paydays p
+ WHERE id > 198 -- (Gratipay 2.0)
ORDER BY ts_start DESC
""", back_as=dict)
-transfers = website.db.all("""\
+payments = website.db.all("""\
SELECT timestamp
, amount
- , tipper
- FROM transfers
- WHERE tippee=%s
- AND context <> 'take-over'
+ FROM payments
+ WHERE team=%s
+ AND direction='to-team'
ORDER BY timestamp DESC
-""", (username,), back_as=dict)
+""", (slug,), back_as=dict)
-if not transfers:
+if not payments:
- # This user has never received money.
+ # This team has never received money.
# ===================================
# Send out an empty array, to trigger no charts.
@@ -84,30 +63,33 @@ if paydays:
# =============================================
def genpaydays():
+ cur_week = 153 + len(paydays) # 154 was the first week of Gratipay 2.0
for payday in paydays:
+ payday['xText'] = cur_week
+ cur_week -= 1
yield payday
+
paydaygen = genpaydays()
curpayday = next(paydaygen)
-
# Loop through transfers, advancing payday cursor as appropriate.
# ===============================================================
- for transfer in transfers:
- while transfer['timestamp'] < curpayday['ts_start']:
- del curpayday['ts_start'] # done with it, don't want it in output
+ for payment in payments:
+ while payment['timestamp'] < curpayday['ts_start']:
+ del curpayday['ts_start'] # done with it, don't want it in output
curpayday = next(paydaygen)
- curpayday['npatrons'] += 1
- curpayday['receipts'] += transfer['amount']
+ curpayday['nreceiving_from'] += 1
+ curpayday['receipts'] += payment['amount']
# Prepare response.
# =================
response.headers["Access-Control-Allow-Origin"] = "*"
-out = paydays[:-1] # don't show Gratipay #0
+out = paydays
# JSONP - see https://github.com/gratipay/aspen-python/issues/138
callback = request.qs.get('callback')
diff --git a/www/%team/index.html.spt b/www/%team/index.html.spt
index ea0d6342a5..037563d218 100644
--- a/www/%team/index.html.spt
+++ b/www/%team/index.html.spt
@@ -13,7 +13,7 @@ suppress_sidebar = not(team.is_approved or user.ADMIN)
is_team_owner = not user.ANON and team.owner == user.participant.username
[-----------------------------------------------------------------------------]
-{% extends "templates/base.html" %}
+{% extends "templates/team-base.html" %}
{% block head %}
{% endblock %}
-{% block banner %}
-
{{ _("{0} receives {1} per week from {2} ~users.", team.name, "%s"|safe % receiving, team.nreceiving_from) }}
@@ -34,31 +32,28 @@ title = _("Receiving")
{{ _("weeks") }}
-
-{% if participant.receiving > 0 and
- not user.ANON and (user.participant == participant or user.ADMIN) %}
-{% set tip_distribution = participant.get_tip_distribution()[0] %}
-
-
{{ _("Tips Received, by Number of Tips") }}
-{% include "templates/tip-distribution.html" %}
-
-
{{ _("Tips Received, by Dollar Amount") }}
-
- {% for amount, ncontributors, summed, pcontributors, psummed in tip_distribution %}
-