Repository: liberapay/liberapay.com

Issue:
Wrong `low_balance` notifications
For the past two weeks we've been sending `low_balance` notifications to someone who still has plenty of money in their account.
Checking "Hide total receiving from others" on team results in error
![image](https://user-images.githubusercontent.com/3729038/34309357-3b1de052-e717-11e7-9fe5-7b322868bcbd.png)

Reported at https://gitter.im/liberapay/salon?at=5a3d512203838b2f2a280e2b. I can confirm this happens with my own teams as well.


Discussion:
![screen shot 2017-12-28 at 16 23 05](https://user-images.githubusercontent.com/1581590/34414770-69c778e0-ebeb-11e7-8c75-ca7c4857afb4.png)

Hiding the income of a team is not allowed. In fact the whole privacy section is inadequate for teams, it used to be in the Settings page and hidden for team accounts.

Resolving patch:
diff --git a/liberapay/billing/payday.py b/liberapay/billing/payday.py
--- a/liberapay/billing/payday.py
+++ b/liberapay/billing/payday.py
@@ -818,6 +818,7 @@ def notify_participants(self):
         """, (self.ts_start,), default=constants.BIRTHDAY)
 
         # Income notifications
+        n = 0
         get_username = lambda i: self.db.one(
             "SELECT username FROM participants WHERE id = %s", (i,)
         )
@@ -846,8 +847,11 @@ def notify_participants(self):
                 by_team=by_team,
                 new_balance=p.get_balances(),
             )
+            n += 1
+        log("Sent %i income notifications." % n)
 
         # Identity-required notifications
+        n = 0
         participants = self.db.all("""
             SELECT p
               FROM participants p
@@ -865,8 +869,11 @@ def notify_participants(self):
         """)
         for p in participants:
             p.notify('identity_required', force_email=True)
+            n += 1
+        log("Sent %i identity_required notifications." % n)
 
         # Low-balance notifications
+        n = 0
         participants = self.db.all("""
             SELECT p, COALESCE(w.balance, zero(needed)) AS balance, needed
               FROM (
@@ -879,7 +886,9 @@ def notify_participants(self):
                    GROUP BY t.tipper, t.amount::currency
                    ) a
               JOIN participants p ON p.id = a.tipper
-         LEFT JOIN wallets w ON w.owner = p.id AND w.balance::currency = needed::currency
+         LEFT JOIN wallets w ON w.owner = p.id
+                            AND w.balance::currency = needed::currency
+                            AND w.is_current IS TRUE
              WHERE COALESCE(w.balance, zero(needed)) < needed
                AND EXISTS (
                      SELECT 1
@@ -893,6 +902,8 @@ def notify_participants(self):
         """, (previous_ts_end, self.ts_end))
         for p, balance, needed in participants:
             p.notify('low_balance', low_balance=balance, needed=needed)
+            n += 1
+        log("Sent %i low_balance notifications." % n)
 
 
 def create_payday_issue():
diff --git a/liberapay/constants.py b/liberapay/constants.py
--- a/liberapay/constants.py
+++ b/liberapay/constants.py
@@ -241,11 +241,11 @@ def with_vat(self):
 )
 
 PRIVACY_FIELDS = OrderedDict([
-    ('hide_giving', _("Hide total giving from others.")),
-    ('hide_receiving', _("Hide total receiving from others.")),
-    ('hide_from_search', _("Hide myself from search results on Liberapay.")),
-    ('profile_noindex', _("Tell web search engines not to index my profile.")),
-    ('hide_from_lists', _("Prevent my profile from being listed on Liberapay.")),
+    ('hide_giving', (_("Hide total giving from others."), False)),
+    ('hide_receiving', (_("Hide total receiving from others."), False)),
+    ('hide_from_search', (_("Hide this profile from search results on Liberapay."), True)),
+    ('profile_noindex', (_("Tell web search engines not to index this profile."), True)),
+    ('hide_from_lists', (_("Prevent this profile from being listed on Liberapay."), True)),
 ])
 PRIVACY_FIELDS_S = ' '.join(PRIVACY_FIELDS.keys())
 


Test patch:
diff --git a/tests/py/test_identity.py b/tests/py/test_identity.py
--- a/tests/py/test_identity.py
+++ b/tests/py/test_identity.py
@@ -80,6 +80,9 @@ def test_identity_form_with_bad_birthday(self):
         kw = dict(auth_as=janeway, raise_immediately=False, HTTP_ACCEPT='text/html')
 
         data = dict(user_data, Birthday='16-01-1995', terms='agree')
+        data['organization'] = 'yes'
+        data['LegalPersonType'] = 'ORGANIZATION'
+        data['Name'] = 'Starfleet'
         r = self.client.POST('/janeway/identity', data, **kw)
         assert "Invalid date of birth" in r.text
 
diff --git a/tests/py/test_search.py b/tests/py/test_search.py
--- a/tests/py/test_search.py
+++ b/tests/py/test_search.py
@@ -47,3 +47,12 @@ def test_hide_from_search(self):
         response = self.client.GET('/search.json?q=alice&scope=usernames')
         data = json.loads(response.text)['usernames']
         assert data == []
+
+    def test_search_unknown_languages(self):
+        alice = self.make_participant('alice')
+        alice.upsert_statement('en', "Foobar")
+        response = self.client.GET(
+            '/search.json?q=foobar', HTTP_ACCEPT_LANGUAGE="xxa,xxb,xxc,xxd,xxe"
+        )
+        data = json.loads(response.text)
+        assert len(data['statements']) == 1