We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
break history page into multiple pages
Each week should get its own page, with paging nav added in the box.

break history page into multiple pages
Each week should get its own page, with paging nav added in the box.

Total Given on history pages for teams includes takes
On the history pages for teams, the "Total Given" amount includes both tips to people **and** takes by members, which is not _correct_. 


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `gratipay/utils/history.py`
Content:
```
1 def iter_payday_events(db, participant):
2     """Yields payday events for the given participant.
3     """
4     username = participant.username
5     exchanges = db.all("""
6         SELECT *
7           FROM exchanges
8          WHERE participant=%s
9     """, (username,), back_as=dict)
10     transfers = db.all("""
11         SELECT *
12           FROM transfers
13          WHERE tipper=%(username)s OR tippee=%(username)s
14     """, locals(), back_as=dict)
15 
16     if not (exchanges or transfers):
17         return
18 
19     if transfers:
20         yield dict(
21             kind='totals',
22             given=sum(t['amount'] for t in transfers if t['tipper'] == username),
23             received=sum(t['amount'] for t in transfers if t['tippee'] == username),
24         )
25 
26     payday_dates = db.all("""
27         SELECT ts_start::date
28           FROM paydays
29       ORDER BY ts_start ASC
30     """)
31 
32     balance = participant.balance
33     prev_date = None
34     get_timestamp = lambda e: e['timestamp']
35     events = sorted(exchanges+transfers, key=get_timestamp, reverse=True)
36     for event in events:
37 
38         event['balance'] = balance
39 
40         event_date = event['timestamp'].date()
41         if event_date != prev_date:
42             if prev_date:
43                 yield dict(kind='day-close', balance=balance)
44             day_open = dict(kind='day-open', date=event_date, balance=balance)
45             if payday_dates:
46                 while payday_dates and payday_dates[-1] > event_date:
47                     payday_dates.pop()
48                 payday_date = payday_dates[-1] if payday_dates else None
49                 if event_date == payday_date:
50                     day_open['payday_number'] = len(payday_dates) - 1
51             yield day_open
52             prev_date = event_date
53 
54         if 'fee' in event:
55             if event['amount'] > 0:
56                 kind = 'charge'
57                 if event['status'] in (None, 'succeeded'):
58                     balance -= event['amount']
59             else:
60                 kind = 'credit'
61                 if event['status'] != 'failed':
62                     balance -= event['amount'] - event['fee']
63         else:
64             kind = 'transfer'
65             if event['tippee'] == username:
66                 balance -= event['amount']
67             else:
68                 balance += event['amount']
69         event['kind'] = kind
70 
71         yield event
72 
73     yield dict(kind='day-close', balance='0.00')
74
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/gratipay/utils/history.py b/gratipay/utils/history.py
--- a/gratipay/utils/history.py
+++ b/gratipay/utils/history.py
@@ -1,16 +1,83 @@
-def iter_payday_events(db, participant):
+from datetime import datetime
+from decimal import Decimal
+
+from psycopg2 import IntegrityError
+
+
+def get_end_of_year_balance(db, participant, year, current_year):
+    if year == current_year:
+        return participant.balance
+    if year < participant.claimed_time.year:
+        return Decimal('0.00')
+
+    balance = db.one("""
+        SELECT balance
+          FROM balances_at
+         WHERE participant = %s
+           AND "at" = %s
+    """, (participant.id, datetime(year+1, 1, 1)))
+    if balance is not None:
+        return balance
+
+    username = participant.username
+    start_balance = get_end_of_year_balance(db, participant, year-1, current_year)
+    delta = db.one("""
+        SELECT (
+                  SELECT COALESCE(sum(amount), 0) AS a
+                    FROM exchanges
+                   WHERE participant = %(username)s
+                     AND extract(year from timestamp) = %(year)s
+                     AND amount > 0
+                     AND (status is null OR status = 'succeeded')
+               ) + (
+                  SELECT COALESCE(sum(amount-fee), 0) AS a
+                    FROM exchanges
+                   WHERE participant = %(username)s
+                     AND extract(year from timestamp) = %(year)s
+                     AND amount < 0
+                     AND (status is null OR status <> 'failed')
+               ) + (
+                  SELECT COALESCE(sum(-amount), 0) AS a
+                    FROM transfers
+                   WHERE tipper = %(username)s
+                     AND extract(year from timestamp) = %(year)s
+               ) + (
+                  SELECT COALESCE(sum(amount), 0) AS a
+                    FROM transfers
+                   WHERE tippee = %(username)s
+                     AND extract(year from timestamp) = %(year)s
+               ) AS delta
+    """, locals())
+    balance = start_balance + delta
+    try:
+        db.run("""
+            INSERT INTO balances_at
+                        (participant, at, balance)
+                 VALUES (%s, %s, %s)
+        """, (participant.id, datetime(year+1, 1, 1), balance))
+    except IntegrityError:
+        pass
+    return balance
+
+
+def iter_payday_events(db, participant, year=None):
     """Yields payday events for the given participant.
     """
+    current_year = datetime.utcnow().year
+    year = year or current_year
+
     username = participant.username
     exchanges = db.all("""
         SELECT *
           FROM exchanges
-         WHERE participant=%s
-    """, (username,), back_as=dict)
+         WHERE participant=%(username)s
+           AND extract(year from timestamp) = %(year)s
+    """, locals(), back_as=dict)
     transfers = db.all("""
         SELECT *
           FROM transfers
-         WHERE tipper=%(username)s OR tippee=%(username)s
+         WHERE (tipper=%(username)s OR tippee=%(username)s)
+           AND extract(year from timestamp) = %(year)s
     """, locals(), back_as=dict)
 
     if not (exchanges or transfers):
@@ -19,7 +86,7 @@
     if transfers:
         yield dict(
             kind='totals',
-            given=sum(t['amount'] for t in transfers if t['tipper'] == username),
+            given=sum(t['amount'] for t in transfers if t['tipper'] == username and t['context'] != 'take'),
             received=sum(t['amount'] for t in transfers if t['tippee'] == username),
         )
 
@@ -29,7 +96,7 @@
       ORDER BY ts_start ASC
     """)
 
-    balance = participant.balance
+    balance = get_end_of_year_balance(db, participant, year, current_year)
     prev_date = None
     get_timestamp = lambda e: e['timestamp']
     events = sorted(exchanges+transfers, key=get_timestamp, reverse=True)
@@ -70,4 +137,4 @@
 
         yield event
 
-    yield dict(kind='day-close', balance='0.00')
+    yield dict(kind='day-close', balance=balance)

{"golden_diff": "diff --git a/gratipay/utils/history.py b/gratipay/utils/history.py\n--- a/gratipay/utils/history.py\n+++ b/gratipay/utils/history.py\n@@ -1,16 +1,83 @@\n-def iter_payday_events(db, participant):\n+from datetime import datetime\n+from decimal import Decimal\n+\n+from psycopg2 import IntegrityError\n+\n+\n+def get_end_of_year_balance(db, participant, year, current_year):\n+    if year == current_year:\n+        return participant.balance\n+    if year < participant.claimed_time.year:\n+        return Decimal('0.00')\n+\n+    balance = db.one(\"\"\"\n+        SELECT balance\n+          FROM balances_at\n+         WHERE participant = %s\n+           AND \"at\" = %s\n+    \"\"\", (participant.id, datetime(year+1, 1, 1)))\n+    if balance is not None:\n+        return balance\n+\n+    username = participant.username\n+    start_balance = get_end_of_year_balance(db, participant, year-1, current_year)\n+    delta = db.one(\"\"\"\n+        SELECT (\n+                  SELECT COALESCE(sum(amount), 0) AS a\n+                    FROM exchanges\n+                   WHERE participant = %(username)s\n+                     AND extract(year from timestamp) = %(year)s\n+                     AND amount > 0\n+                     AND (status is null OR status = 'succeeded')\n+               ) + (\n+                  SELECT COALESCE(sum(amount-fee), 0) AS a\n+                    FROM exchanges\n+                   WHERE participant = %(username)s\n+                     AND extract(year from timestamp) = %(year)s\n+                     AND amount < 0\n+                     AND (status is null OR status <> 'failed')\n+               ) + (\n+                  SELECT COALESCE(sum(-amount), 0) AS a\n+                    FROM transfers\n+                   WHERE tipper = %(username)s\n+                     AND extract(year from timestamp) = %(year)s\n+               ) + (\n+                  SELECT COALESCE(sum(amount), 0) AS a\n+                    FROM transfers\n+                   WHERE tippee = %(username)s\n+                     AND extract(year from timestamp) = %(year)s\n+               ) AS delta\n+    \"\"\", locals())\n+    balance = start_balance + delta\n+    try:\n+        db.run(\"\"\"\n+            INSERT INTO balances_at\n+                        (participant, at, balance)\n+                 VALUES (%s, %s, %s)\n+        \"\"\", (participant.id, datetime(year+1, 1, 1), balance))\n+    except IntegrityError:\n+        pass\n+    return balance\n+\n+\n+def iter_payday_events(db, participant, year=None):\n     \"\"\"Yields payday events for the given participant.\n     \"\"\"\n+    current_year = datetime.utcnow().year\n+    year = year or current_year\n+\n     username = participant.username\n     exchanges = db.all(\"\"\"\n         SELECT *\n           FROM exchanges\n-         WHERE participant=%s\n-    \"\"\", (username,), back_as=dict)\n+         WHERE participant=%(username)s\n+           AND extract(year from timestamp) = %(year)s\n+    \"\"\", locals(), back_as=dict)\n     transfers = db.all(\"\"\"\n         SELECT *\n           FROM transfers\n-         WHERE tipper=%(username)s OR tippee=%(username)s\n+         WHERE (tipper=%(username)s OR tippee=%(username)s)\n+           AND extract(year from timestamp) = %(year)s\n     \"\"\", locals(), back_as=dict)\n \n     if not (exchanges or transfers):\n@@ -19,7 +86,7 @@\n     if transfers:\n         yield dict(\n             kind='totals',\n-            given=sum(t['amount'] for t in transfers if t['tipper'] == username),\n+            given=sum(t['amount'] for t in transfers if t['tipper'] == username and t['context'] != 'take'),\n             received=sum(t['amount'] for t in transfers if t['tippee'] == username),\n         )\n \n@@ -29,7 +96,7 @@\n       ORDER BY ts_start ASC\n     \"\"\")\n \n-    balance = participant.balance\n+    balance = get_end_of_year_balance(db, participant, year, current_year)\n     prev_date = None\n     get_timestamp = lambda e: e['timestamp']\n     events = sorted(exchanges+transfers, key=get_timestamp, reverse=True)\n@@ -70,4 +137,4 @@\n \n         yield event\n \n-    yield dict(kind='day-close', balance='0.00')\n+    yield dict(kind='day-close', balance=balance)\n", "issue": "break history page into multiple pages\nEach week should get its own page, with paging nav added in the box.\n\nbreak history page into multiple pages\nEach week should get its own page, with paging nav added in the box.\n\nTotal Given on history pages for teams includes takes\nOn the history pages for teams, the \"Total Given\" amount includes both tips to people **and** takes by members, which is not _correct_. \n\n", "before_files": [{"content": "def iter_payday_events(db, participant):\n    \"\"\"Yields payday events for the given participant.\n    \"\"\"\n    username = participant.username\n    exchanges = db.all(\"\"\"\n        SELECT *\n          FROM exchanges\n         WHERE participant=%s\n    \"\"\", (username,), back_as=dict)\n    transfers = db.all(\"\"\"\n        SELECT *\n          FROM transfers\n         WHERE tipper=%(username)s OR tippee=%(username)s\n    \"\"\", locals(), back_as=dict)\n\n    if not (exchanges or transfers):\n        return\n\n    if transfers:\n        yield dict(\n            kind='totals',\n            given=sum(t['amount'] for t in transfers if t['tipper'] == username),\n            received=sum(t['amount'] for t in transfers if t['tippee'] == username),\n        )\n\n    payday_dates = db.all(\"\"\"\n        SELECT ts_start::date\n          FROM paydays\n      ORDER BY ts_start ASC\n    \"\"\")\n\n    balance = participant.balance\n    prev_date = None\n    get_timestamp = lambda e: e['timestamp']\n    events = sorted(exchanges+transfers, key=get_timestamp, reverse=True)\n    for event in events:\n\n        event['balance'] = balance\n\n        event_date = event['timestamp'].date()\n        if event_date != prev_date:\n            if prev_date:\n                yield dict(kind='day-close', balance=balance)\n            day_open = dict(kind='day-open', date=event_date, balance=balance)\n            if payday_dates:\n                while payday_dates and payday_dates[-1] > event_date:\n                    payday_dates.pop()\n                payday_date = payday_dates[-1] if payday_dates else None\n                if event_date == payday_date:\n                    day_open['payday_number'] = len(payday_dates) - 1\n            yield day_open\n            prev_date = event_date\n\n        if 'fee' in event:\n            if event['amount'] > 0:\n                kind = 'charge'\n                if event['status'] in (None, 'succeeded'):\n                    balance -= event['amount']\n            else:\n                kind = 'credit'\n                if event['status'] != 'failed':\n                    balance -= event['amount'] - event['fee']\n        else:\n            kind = 'transfer'\n            if event['tippee'] == username:\n                balance -= event['amount']\n            else:\n                balance += event['amount']\n        event['kind'] = kind\n\n        yield event\n\n    yield dict(kind='day-close', balance='0.00')\n", "path": "gratipay/utils/history.py"}], "after_files": [{"content": "from datetime import datetime\nfrom decimal import Decimal\n\nfrom psycopg2 import IntegrityError\n\n\ndef get_end_of_year_balance(db, participant, year, current_year):\n    if year == current_year:\n        return participant.balance\n    if year < participant.claimed_time.year:\n        return Decimal('0.00')\n\n    balance = db.one(\"\"\"\n        SELECT balance\n          FROM balances_at\n         WHERE participant = %s\n           AND \"at\" = %s\n    \"\"\", (participant.id, datetime(year+1, 1, 1)))\n    if balance is not None:\n        return balance\n\n    username = participant.username\n    start_balance = get_end_of_year_balance(db, participant, year-1, current_year)\n    delta = db.one(\"\"\"\n        SELECT (\n                  SELECT COALESCE(sum(amount), 0) AS a\n                    FROM exchanges\n                   WHERE participant = %(username)s\n                     AND extract(year from timestamp) = %(year)s\n                     AND amount > 0\n                     AND (status is null OR status = 'succeeded')\n               ) + (\n                  SELECT COALESCE(sum(amount-fee), 0) AS a\n                    FROM exchanges\n                   WHERE participant = %(username)s\n                     AND extract(year from timestamp) = %(year)s\n                     AND amount < 0\n                     AND (status is null OR status <> 'failed')\n               ) + (\n                  SELECT COALESCE(sum(-amount), 0) AS a\n                    FROM transfers\n                   WHERE tipper = %(username)s\n                     AND extract(year from timestamp) = %(year)s\n               ) + (\n                  SELECT COALESCE(sum(amount), 0) AS a\n                    FROM transfers\n                   WHERE tippee = %(username)s\n                     AND extract(year from timestamp) = %(year)s\n               ) AS delta\n    \"\"\", locals())\n    balance = start_balance + delta\n    try:\n        db.run(\"\"\"\n            INSERT INTO balances_at\n                        (participant, at, balance)\n                 VALUES (%s, %s, %s)\n        \"\"\", (participant.id, datetime(year+1, 1, 1), balance))\n    except IntegrityError:\n        pass\n    return balance\n\n\ndef iter_payday_events(db, participant, year=None):\n    \"\"\"Yields payday events for the given participant.\n    \"\"\"\n    current_year = datetime.utcnow().year\n    year = year or current_year\n\n    username = participant.username\n    exchanges = db.all(\"\"\"\n        SELECT *\n          FROM exchanges\n         WHERE participant=%(username)s\n           AND extract(year from timestamp) = %(year)s\n    \"\"\", locals(), back_as=dict)\n    transfers = db.all(\"\"\"\n        SELECT *\n          FROM transfers\n         WHERE (tipper=%(username)s OR tippee=%(username)s)\n           AND extract(year from timestamp) = %(year)s\n    \"\"\", locals(), back_as=dict)\n\n    if not (exchanges or transfers):\n        return\n\n    if transfers:\n        yield dict(\n            kind='totals',\n            given=sum(t['amount'] for t in transfers if t['tipper'] == username and t['context'] != 'take'),\n            received=sum(t['amount'] for t in transfers if t['tippee'] == username),\n        )\n\n    payday_dates = db.all(\"\"\"\n        SELECT ts_start::date\n          FROM paydays\n      ORDER BY ts_start ASC\n    \"\"\")\n\n    balance = get_end_of_year_balance(db, participant, year, current_year)\n    prev_date = None\n    get_timestamp = lambda e: e['timestamp']\n    events = sorted(exchanges+transfers, key=get_timestamp, reverse=True)\n    for event in events:\n\n        event['balance'] = balance\n\n        event_date = event['timestamp'].date()\n        if event_date != prev_date:\n            if prev_date:\n                yield dict(kind='day-close', balance=balance)\n            day_open = dict(kind='day-open', date=event_date, balance=balance)\n            if payday_dates:\n                while payday_dates and payday_dates[-1] > event_date:\n                    payday_dates.pop()\n                payday_date = payday_dates[-1] if payday_dates else None\n                if event_date == payday_date:\n                    day_open['payday_number'] = len(payday_dates) - 1\n            yield day_open\n            prev_date = event_date\n\n        if 'fee' in event:\n            if event['amount'] > 0:\n                kind = 'charge'\n                if event['status'] in (None, 'succeeded'):\n                    balance -= event['amount']\n            else:\n                kind = 'credit'\n                if event['status'] != 'failed':\n                    balance -= event['amount'] - event['fee']\n        else:\n            kind = 'transfer'\n            if event['tippee'] == username:\n                balance -= event['amount']\n            else:\n                balance += event['amount']\n        event['kind'] = kind\n\n        yield event\n\n    yield dict(kind='day-close', balance=balance)\n", "path": "gratipay/utils/history.py"}]}