From f161dc41f9fef5f277b643175abb15b37d45f19c Mon Sep 17 00:00:00 2001 From: Kwesi Aguillera Date: Wed, 14 Jun 2017 14:58:34 -0400 Subject: [PATCH 1/2] Start recording ref when recording an exchange in masspay --- bin/masspay.py | 19 ++++++++++++++----- .../%username/history/record-an-exchange.spt | 11 ++++++++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/bin/masspay.py b/bin/masspay.py index 849cc6e69a..228e719de5 100755 --- a/bin/masspay.py +++ b/bin/masspay.py @@ -167,19 +167,21 @@ def compute_output_csvs(): print("{:>64} {:>7} {:>7}".format(total_gross, total_fees, total_net)) -def load_statuses(): +def load_statuses_and_refs(): _status_map = { 'Completed': 'succeeded' , 'Unclaimed': 'pending' , 'Denied': 'failed' } # PayPal -> Gratipay statuses = {} + refs = {} fp = open(REPORT_CSV) for line in fp: if line.startswith('Transaction ID,Recipient'): break for rec in csv.reader(fp): statuses[rec[1]] = _status_map[rec[5]] - return statuses + refs[rec[1]] = rec[0] + return statuses, refs def post_back_to_gratipay(force=False): @@ -200,7 +202,7 @@ def post_back_to_gratipay(force=False): "did, then rerun with -f.") return - statuses = load_statuses() + statuses, refs = load_statuses_and_refs() nposts = 0 for username, route_id, email, gross, fee, net, additional_note in csv.reader(open(GRATIPAY_CSV)): @@ -210,8 +212,15 @@ def post_back_to_gratipay(force=False): note += " " + additional_note print(note) status = statuses[email] - - data = {'amount': '-' + net, 'fee': fee, 'note': note, 'status': status, 'route_id': route_id} + ref = refs[email] + + data = {'amount': '-' + net + , 'fee': fee + , 'note': note + , 'status': status + , 'ref': ref + , 'route_id': route_id + } try: response = requests.post(url, auth=(gratipay_api_key, ''), data=data) except IncompleteRead: diff --git a/www/~/%username/history/record-an-exchange.spt b/www/~/%username/history/record-an-exchange.spt index 9f708b7e87..cb25ee56bf 100644 --- a/www/~/%username/history/record-an-exchange.spt +++ b/www/~/%username/history/record-an-exchange.spt @@ -45,13 +45,17 @@ if request.method == 'POST': route = ExchangeRoute.from_id(route_id) if not route or route.participant.id != participant.id: raise Response(400, "Route doesn't exist") + + ref = request.body['ref'] + if not ref: + ref = "" with website.db.get_cursor() as cursor: cursor.run(""" INSERT INTO exchanges - (amount, fee, route, participant, recorder, note, status) - VALUES (%s, %s, %s, %s, %s, %s, %s) - """, (amount, fee, route_id, participant.username, user.participant.username, note, status)) + (amount, fee, route, participant, recorder, note, status, ref) + VALUES (%s, %s, %s, %s, %s, %s, %s, %s) + """, (amount, fee, route_id, participant.username, user.participant.username, note, status, ref)) if amount < 0: # For payouts, we need to take the fee out of their Gratipay balance. @@ -96,6 +100,7 @@ if request.method == 'POST':
+

Route

{% for route in routes %} From 067c66179bc3fba4fbd4e6350ac91357dcf04e03 Mon Sep 17 00:00:00 2001 From: Kwesi Aguillera Date: Thu, 15 Jun 2017 14:38:13 -0400 Subject: [PATCH 2/2] Added test for recording ref with exchanges --- tests/py/test_dashboard.py | 1 + tests/py/test_record_an_exchange.py | 18 ++++++++++++++++-- www/~/%username/history/record-an-exchange.spt | 4 ++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/tests/py/test_dashboard.py b/tests/py/test_dashboard.py index d9a6912a53..5b279e7f6d 100644 --- a/tests/py/test_dashboard.py +++ b/tests/py/test_dashboard.py @@ -19,6 +19,7 @@ def post_masspays(self, n): , 'fee': '0' , 'note': 'Exchange!' , 'status': 'succeeded' + , 'ref': 'transactionidref' , 'route_id': unicode(self.homer_route.id) } , auth_as='admin' diff --git a/tests/py/test_record_an_exchange.py b/tests/py/test_record_an_exchange.py index bb9a8b516a..90b56dd196 100644 --- a/tests/py/test_record_an_exchange.py +++ b/tests/py/test_record_an_exchange.py @@ -32,6 +32,9 @@ def record_an_exchange(self, data, make_participants=True): if data['route_id'] is None: del(data['route_id']) + if 'ref' not in data: + data['ref'] = 'N/A' + return self.client.PxST('/~bob/history/record-an-exchange', data, auth_as='alice') @@ -93,21 +96,32 @@ def test_route_should_belong_to_user_else_400(self): assert response.code == 400 assert response.body == "Route doesn't exist" + def test_no_ref_is_400(self): + response = self.record_an_exchange({'amount': '10', 'fee': '0', 'ref': ''}) + assert response.code == 400 + assert response.body == "Invalid Reference" + + def test_whitespace_ref_is_400(self): + response = self.record_an_exchange({'amount': '10', 'fee': '0', 'ref': ' '}) + assert response.code == 400 + assert response.body == "Invalid Reference" + def test_dropping_balance_below_zero_is_allowed_in_this_context(self): self.record_an_exchange({'amount': '-10', 'fee': '0'}) actual = self.db.one("SELECT balance FROM participants WHERE username='bob'") assert actual == D('-10.00') def test_success_records_exchange(self): - self.record_an_exchange({'amount': '10', 'fee': '0.50'}) + self.record_an_exchange({'amount': '10', 'fee': '0.50', 'ref':"605BSOC6G855L15OO"}) expected = { "amount": D('10.00') , "fee": D('0.50') , "participant": "bob" , "recorder": "alice" , "note": "noted" + , "ref" : "605BSOC6G855L15OO" , "route": ExchangeRoute.from_network(self.bob, 'paypal').id } - SQL = "SELECT amount, fee, participant, recorder, note, route " \ + SQL = "SELECT amount, fee, participant, recorder, note, route, ref " \ "FROM exchanges" actual = self.db.one(SQL, back_as=dict) assert actual == expected diff --git a/www/~/%username/history/record-an-exchange.spt b/www/~/%username/history/record-an-exchange.spt index cb25ee56bf..dba6c53b13 100644 --- a/www/~/%username/history/record-an-exchange.spt +++ b/www/~/%username/history/record-an-exchange.spt @@ -46,9 +46,9 @@ if request.method == 'POST': if not route or route.participant.id != participant.id: raise Response(400, "Route doesn't exist") - ref = request.body['ref'] + ref = request.body['ref'].strip() if not ref: - ref = "" + raise Response(400, "Invalid Reference") with website.db.get_cursor() as cursor: cursor.run("""