Skip to content

Commit

Permalink
Merge pull request spiral-project#164 from zorun/fix_zero_transfers
Browse files Browse the repository at this point in the history
Fix zero-amount transfers and other rounding issues
  • Loading branch information
almet authored Jan 16, 2017
2 parents a961574 + eb29a6b commit db95fcd
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 8 deletions.
4 changes: 2 additions & 2 deletions budget/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,9 @@ def get_transactions_to_settle_bill(self):
credits, debts, transactions = [],[],[]
# Create lists of credits and debts
for person in self.members:
if balance[person.id] > 0:
if round(balance[person.id], 2) > 0:
credits.append({"person": person, "balance": balance[person.id]})
elif balance[person.id] < 0:
elif round(balance[person.id], 2) < 0:
debts.append({"person": person, "balance": -balance[person.id]})
# Try and find exact matches
for credit in credits:
Expand Down
6 changes: 3 additions & 3 deletions budget/templates/list_bills.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
<div id="table_overflow">
<table class="balance table">
{% set balance = g.project.balance %}
{% for member in g.project.members | sort(attribute='name') if member.activated or balance[member.id] != 0 %}
{% for member in g.project.members | sort(attribute='name') if member.activated or balance[member.id]|round(2) != 0 %}
<tr id="bal-member-{{ member.id }}" action={% if member.activated %}delete{% else %}reactivate{% endif %}>
<td class="balance-name">{{ member.name }}
<span class="light{% if not g.project.uses_weights %} extra-info{% endif %}">(x{{ member.weight|minimal_round(1) }})</span>
Expand All @@ -82,8 +82,8 @@
<form class="action reactivate" action="{{ url_for(".reactivate", member_id=member.id) }}" method="POST">
<button type="submit">{{ _("reactivate") }}</button></form></td>
{% endif %}
<td class="balance-value {% if balance[member.id] > 0 %}positive{% elif balance[member.id] < 0 %}negative{% endif %}">
{% if balance[member.id] > 0 %}+{% endif %}{{ "%.2f" | format(balance[member.id]) }}
<td class="balance-value {% if balance[member.id]|round(2) > 0 %}positive{% elif balance[member.id]|round(2) < 0 %}negative{% endif %}">
{% if balance[member.id]|round(2) > 0 %}+{% endif %}{{ "%.2f" | format(balance[member.id]) }}
</td>
</tr>
{% endfor %}
Expand Down
6 changes: 3 additions & 3 deletions budget/templates/settle_bills.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
<div id="table_overflow">
<table class="balance table">
{% set balance = g.project.balance %}
{% for member in g.project.members | sort(attribute='name') if member.activated or balance[member.id] != 0 %}
{% for member in g.project.members | sort(attribute='name') if member.activated or balance[member.id]|round(2) != 0 %}
<tr id="bal-member-{{ member.id }}" action={% if member.activated %}delete{% else %}reactivate{% endif %}>
<td class="balance-name">{{ member.name }}</td>
<td class="balance-value {% if balance[member.id] > 0 %}positive{% elif balance[member.id] < 0 %}negative{% endif %}">
{% if balance[member.id] > 0 %}+{% endif %}{{ "%.2f" | format(balance[member.id]) }}
<td class="balance-value {% if balance[member.id]|round(2) > 0 %}positive{% elif balance[member.id]|round(2) < 0 %}negative{% endif %}">
{% if balance[member.id]|round(2) > 0 %}+{% endif %}{{ "%.2f" | format(balance[member.id]) }}
</td>
</tr>
{% endfor %}
Expand Down
40 changes: 40 additions & 0 deletions budget/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,46 @@ def test_settle(self):
self.assertEqual(a, balance[m.id])
return

def test_settle_zero(self):
self.post_project("raclette")

# add members
self.app.post("/raclette/members/add", data={'name': 'alexis'})
self.app.post("/raclette/members/add", data={'name': 'fred'})
self.app.post("/raclette/members/add", data={'name': 'tata'})

# create bills
self.app.post("/raclette/add", data={
'date': '2016-12-31',
'what': u'fromage à raclette',
'payer': 1,
'payed_for': [1, 2, 3],
'amount': '10.0',
})

self.app.post("/raclette/add", data={
'date': '2016-12-31',
'what': u'red wine',
'payer': 2,
'payed_for': [1, 3],
'amount': '20',
})

self.app.post("/raclette/add", data={
'date': '2017-01-01',
'what': u'refund',
'payer': 3,
'payed_for': [2],
'amount': '13.33',
})
project = models.Project.query.get('raclette')
transactions = project.get_transactions_to_settle_bill()
members = defaultdict(int)
# There should not be any zero-amount transfer after rounding
for t in transactions:
rounded_amount = round(t['amount'], 2)
self.assertNotEqual(0.0, rounded_amount,
msg='%f is equal to zero after rounding' % t['amount'])


class APITestCase(TestCase):
Expand Down

0 comments on commit db95fcd

Please sign in to comment.