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/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 9f708b7e87..dba6c53b13 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'].strip()
+ if not ref:
+ raise Response(400, "Invalid Reference")
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':
+