Repository: liberapay/liberapay.com

Issue:
Fix the stats page
- [x] hide the graphs until there is enough data to be interesting
- [x] drop the part about credit cards "on file"
- [x] fix the charges and withdrawals graphs (#12 removed their data source)



Discussion:
Tagged High Priority, because this bug has become visible after our first payday (https://github.com/liberapay/salon/issues/10).


Resolving patch:
diff --git a/liberapay/billing/payday.py b/liberapay/billing/payday.py
--- a/liberapay/billing/payday.py
+++ b/liberapay/billing/payday.py
@@ -115,11 +115,45 @@ def shuffle(self, log_dir=''):
                 self.check_balances(cursor)
                 with open(self.transfers_filename, 'wb') as f:
                     pickle.dump(transfers, f)
+                if self.id > 1:
+                    previous_ts_start = self.db.one("""
+                        SELECT ts_start
+                          FROM paydays
+                         WHERE id = %s
+                    """, (self.id - 1,))
+                else:
+                    previous_ts_start = constants.EPOCH
+                assert previous_ts_start
+                ts_start = self.ts_start
                 cursor.run("""
+                    WITH week_exchanges AS (
+                             SELECT e.*
+                               FROM exchanges e
+                              WHERE e.timestamp < %(ts_start)s
+                                AND e.timestamp >= %(previous_ts_start)s
+                                AND status <> 'failed'
+                         )
                     UPDATE paydays
                        SET nparticipants = (SELECT count(*) FROM payday_participants)
+                         , nusers = (
+                               SELECT count(*)
+                                 FROM participants
+                                WHERE kind IN ('individual', 'organization')
+                                  AND join_time < %(ts_start)s
+                                  AND status = 'active'
+                           )
+                         , week_deposits = (
+                               SELECT COALESCE(sum(amount), 0)
+                                 FROM week_exchanges
+                                WHERE amount > 0
+                           )
+                         , week_withdrawals = (
+                               SELECT COALESCE(-sum(amount), 0)
+                                 FROM week_exchanges
+                                WHERE amount < 0
+                           )
                      WHERE ts_end='1970-01-01T00:00:00+00'::timestamptz;
-                """)
+                """, locals())
             self.clean_up()
 
         self.transfer_for_real(transfers)
diff --git a/liberapay/constants.py b/liberapay/constants.py
--- a/liberapay/constants.py
+++ b/liberapay/constants.py
@@ -36,6 +36,8 @@ def __str__(self):
 EMAIL_VERIFICATION_TIMEOUT = timedelta(hours=24)
 EMAIL_RE = re.compile(r'^[^@]+@[^@]+\.[^@]+$')
 
+EPOCH = datetime(1970, 1, 1, 0, 0, 0, 0, utc)
+
 JINJA_ENV_COMMON = dict(
     trim_blocks=True, lstrip_blocks=True,
     line_statement_prefix='%',


Test patch:
diff --git a/liberapay/testing/__init__.py b/liberapay/testing/__init__.py
--- a/liberapay/testing/__init__.py
+++ b/liberapay/testing/__init__.py
@@ -151,6 +151,7 @@ def clear_tables(self):
                 self.tablenames.remove(tablename)
                 self.tablenames.insert(0, tablename)
         self.db.run("ALTER SEQUENCE participants_id_seq RESTART WITH 1")
+        self.db.run("ALTER SEQUENCE paydays_id_seq RESTART WITH 1")
 
 
     def make_elsewhere(self, platform, user_id, user_name, **kw):
diff --git a/tests/py/test_charts_json.py b/tests/py/test_charts_json.py
--- a/tests/py/test_charts_json.py
+++ b/tests/py/test_charts_json.py
@@ -136,13 +136,16 @@ def test_transfer_volume(self):
         self.run_payday()
         self.run_payday()
 
-        expected = { "date": today()
-                   , "weekly_gifts": '3.00'
-                   , "active_users": '3'
-                   , "total_users": '4'
-                   , "total_gifts": '6.00'
-                   , "xTitle": utcnow().strftime('%Y-%m-%d')
-                    }
+        expected = {
+            "date": today(),
+            "transfer_volume": '3.00',
+            "nactive": '3',
+            "nparticipants": '4',
+            "nusers": '4',
+            "week_deposits": '0.00',
+            "week_withdrawals": '0.00',
+            "xTitle": utcnow().strftime('%Y-%m-%d'),
+        }
         actual = json.loads(self.client.GET('/about/charts.json').body)[0]
 
         assert actual == expected