aboutsummaryrefslogtreecommitdiff
path: root/budget/models.py
diff options
context:
space:
mode:
authorXavier Mehrenberger <xavier.mehrenberger@gmail.com>2012-03-12 00:35:06 +0100
committerXavier Mehrenberger <xavier.mehrenberger@gmail.com>2012-03-12 01:35:28 +0100
commitcb13fbb782d3fda9f2ce20fcffddeb7cdf3a84a8 (patch)
tree21f0604a7c3d3ff5b15aec0d8d7e149094776221 /budget/models.py
parent757e86baa1ae3b2bc980fc7a1af2a085b702224c (diff)
downloadihatemoney-mirror-cb13fbb782d3fda9f2ce20fcffddeb7cdf3a84a8.zip
ihatemoney-mirror-cb13fbb782d3fda9f2ce20fcffddeb7cdf3a84a8.tar.gz
ihatemoney-mirror-cb13fbb782d3fda9f2ce20fcffddeb7cdf3a84a8.tar.bz2
Split bills function and basic template.
Diffstat (limited to 'budget/models.py')
-rw-r--r--budget/models.py49
1 files changed, 48 insertions, 1 deletions
diff --git a/budget/models.py b/budget/models.py
index 5783703..a92281b 100644
--- a/budget/models.py
+++ b/budget/models.py
@@ -45,10 +45,57 @@ class Project(db.Model):
for person in self.members:
balance = should_receive[person] - should_pay[person]
- balances[person.id] = round(balance, 2)
+ balances[person] = round(balance, 2)
return balances
+ def settle_bill(self):
+ """Return a list of transactions that could be made to settle the bill"""
+ balances = self.balance
+ credits, debts = list(), list()
+ transactions = list()
+ # Create lists of credits and debts
+ for person in balances.keys():
+ if balances[person] > 0:
+ credits.append({"person": person, "balance": balances[person]})
+ elif balances[person] < 0:
+ debts.append({"person": person, "balance": -balances[person]})
+ # Try and find exact matches
+ for credit in credits:
+ match = self.exactmatch(credit["balance"], debts)
+ if match:
+ for m in match:
+ transactions.append({"ower": m["person"], "payer": credit["person"], "amount": m["balance"]})
+ debts.remove(m)
+ credits.remove(credit)
+ # Split any remaining debts & credits
+ while credits and debts:
+ if credits[0]["balance"] > debts[0]["balance"]:
+ transactions.append({"ower": debts[0]["person"], "payer": credits[0]["person"], "amount": debts[0]["balance"]})
+ credits[0]["balance"] = credits[0]["balance"] - debts[0]["balance"]
+ del debts[0]
+ else:
+ transactions.append({"ower": debts[0]["person"], "payer": credits[0]["person"], "amount": credits[0]["balance"]})
+ debts[0]["balance"] = debts[0]["balance"] - credits[0]["balance"]
+ del credits[0]
+ return transactions
+
+ def exactmatch(self, credit, debts):
+ """Recursively try and find subsets of 'debts' whose sum is equal to credit"""
+ if not debts:
+ return []
+ if debts[0]["balance"] > credit:
+ return self.exactmatch(credit, debts[1:])
+ elif debts[0]["balance"] == credit:
+ return [debts[0]]
+ else:
+ match = self.exactmatch(credit-debts[0]["balance"], debts[1:])
+ if match:
+ match.append(debts[0])
+ else:
+ match = self.exactmatch(credit, debts[1:])
+ return match
+
def has_bills(self):
"""return if the project do have bills or not"""
return self.get_bills().count() > 0