diff options
| author | Alexis Metaireau <alexis@notmyidea.org> | 2011-07-31 23:55:18 +0200 |
|---|---|---|
| committer | Alexis Metaireau <alexis@notmyidea.org> | 2011-07-31 23:55:18 +0200 |
| commit | 769bcbf3f10f59a1bce952c336adeb1804a5cc77 (patch) | |
| tree | 46e7c4266b3a93d4ffa67d77d03e24cf2c5f998a | |
| parent | 548101d8bbd5adff4887cfad8fc70d1a4cf82370 (diff) | |
| download | ihatemoney-mirror-769bcbf3f10f59a1bce952c336adeb1804a5cc77.zip ihatemoney-mirror-769bcbf3f10f59a1bce952c336adeb1804a5cc77.tar.gz ihatemoney-mirror-769bcbf3f10f59a1bce952c336adeb1804a5cc77.tar.bz2 | |
Makes the computation working.
| -rw-r--r-- | budget/models.py | 26 | ||||
| -rw-r--r-- | budget/templates/compute_bills.html | 11 | ||||
| -rw-r--r-- | budget/templates/list_bills.html | 18 | ||||
| -rw-r--r-- | budget/web.py | 38 |
4 files changed, 63 insertions, 30 deletions
diff --git a/budget/models.py b/budget/models.py index bf9ad92..efb5a3d 100644 --- a/budget/models.py +++ b/budget/models.py @@ -1,3 +1,5 @@ +from collections import defaultdict + from datetime import datetime from flaskext.sqlalchemy import SQLAlchemy @@ -12,6 +14,28 @@ class Project(db.Model): contact_email = db.Column(db.String) members = db.relationship("Person", backref="project") + @property + def active_members(self): + return [m for m in self.members if m.activated] + + def get_balance(self): + + balances, should_pay, should_receive = defaultdict(int), defaultdict(int), defaultdict(int) + + # for each person + for person in self.members: + # get the list of bills he has to pay + bills = Bill.query.filter(Bill.owers.contains(person)) + for bill in bills.all(): + if person != bill.payer: + should_pay[person] += bill.pay_each() + should_receive[bill.payer] += bill.pay_each() + + for person in self.members: + balances[person] = should_receive[person] - should_pay[person] + + return balances + def __repr__(self): return "<Project %s>" % self.name @@ -22,7 +46,7 @@ class Person(db.Model): bills = db.relationship("Bill", backref="payer") name = db.Column(db.UnicodeText) - # activated = db.Column(db.Boolean, default=True) + activated = db.Column(db.Boolean, default=True) def __str__(self): return self.name diff --git a/budget/templates/compute_bills.html b/budget/templates/compute_bills.html index 8f286cf..4c6fd56 100644 --- a/budget/templates/compute_bills.html +++ b/budget/templates/compute_bills.html @@ -1,4 +1,9 @@ {% extends "layout.html" %} + +{% block top_menu %} +<a href="{{ url_for('list_bills', project_id=project.id) }}">Back to the list</a> +{% endblock %} + {% block content %} <h2>Computations</h2> @@ -12,14 +17,14 @@ </div> <div class="container span-6 last"> - <a class="awesome large green button" onclick = "if (! confirm('Are you sure ?')) return false;" href="{{ url_for("reset_bills") }}">Mark this as payed / processed</a> + <a class="awesome large green button" onclick = "if (! confirm('Are you sure ?')) return false;" href="">Mark this as payed / processed</a> </div> <table> <thead><tr><th>Name</th><th>Balance</th></tr></thead> <tbody> -{% for name, balance in balances.items() %} - <tr><td>{{ name }}</td><td>{{ balance }}</td></tr> +{% for person, balance in balances.items() %} + <tr><td>{{ person.name }}</td><td>{{ balance }}</td></tr> {% endfor %} </tbody> </table> diff --git a/budget/templates/list_bills.html b/budget/templates/list_bills.html index a26dccc..48308fe 100644 --- a/budget/templates/list_bills.html +++ b/budget/templates/list_bills.html @@ -7,16 +7,22 @@ {% endblock %} {% block content %} -<div id="leftmenu" class="span-6"> +<div id="leftmenu" class="span-4"> <ul> - {% for member in project.members %} - <li>{{ member.name }}</li> + {% set balance = project.get_balance() %} + {% for member in project.active_members %} + <li> {{ member.name }} {{ balance[member] }} <a href="{{ url_for("remove_member", project_id=project.id, member_id=member.id) }}">x</a></li> {% endfor %} </ul> - {% set form=member_form %} - {% include "member_form.html" %} + <form action="{{ url_for("add_member", project_id=project.id) }}" method="post"> + {{ forms.add_member(member_form) }} + </form> </div> -<div id="content" class="span-18 last"> +<div id="content" class="uniForm span-20 last"> + <form id="add_bill" action="{{ url_for('add_bill', project_id=project.id) }}" method="post" style="width: 400px; display: none"> + {{ forms.add_bill(bill_form) }} + </form> + {% if bills.count() > 0 %} <table> <thead><tr><th>When ?</th><th>Who paid?</th><th>for what ?</th><th>Owers</th><th>How much ?</th><th>Actions</th></tr></thead> diff --git a/budget/web.py b/budget/web.py index 1afb8c1..c2909bc 100644 --- a/budget/web.py +++ b/budget/web.py @@ -1,3 +1,5 @@ +from collections import defaultdict + from flask import (Flask, session, request, redirect, url_for, render_template, flash) from flaskext.mail import Mail, Message @@ -107,7 +109,10 @@ def list_bills(project): # FIXME filter to only get the bills for this particular project bills = Bill.query.order_by(Bill.id.asc()) return render_template("list_bills.html", - bills=bills, project=project, member_form=MemberForm(project)) + bills=bills, project=project, + member_form=MemberForm(project), + bill_form=get_billform_for(project) + ) @app.route("/<string:project_id>/members/add", methods=["GET", "POST"]) @requires_auth @@ -121,10 +126,20 @@ def add_member(project): return redirect(url_for("list_bills", project_id=project.id)) return render_template("add_member.html", form=form, project=project) +@app.route("/<string:project_id>/members/<int:member_id>/delete", methods=["GET", "POST"]) +@requires_auth +def remove_member(project, member_id): + person = Person.query.get_or_404(member_id) + if person.project == project: + person.activated = False + db.session.commit() + flash("%s has been removed" % person.name) + return redirect(url_for("list_bills", project_id=project.id)) + @app.route("/<string:project_id>/add", methods=["GET", "POST"]) @requires_auth def add_bill(project): - form = get_billform_for(project.id) + form = get_billform_for(project) if request.method == 'POST': if form.validate(): db.session.add(form.save()) @@ -140,24 +155,7 @@ def add_bill(project): @requires_auth def compute_bills(project): """Compute the sum each one have to pay to each other and display it""" - # FIXME make it work - - balances, should_pay, should_receive = {}, {}, {} - # for each person, get the list of should_pay other have for him - for name, void in PAYER_CHOICES: - bills = Bill.query.join(BillOwer).filter(Bill.processed==False)\ - .filter(BillOwer.name==name) - for bill in bills.all(): - if name != bill.payer: - should_pay.setdefault(name, 0) - should_pay[name] += bill.pay_each() - should_receive.setdefault(bill.payer, 0) - should_receive[bill.payer] += bill.pay_each() - - for name, void in PAYER_CHOICES: - balances[name] = should_receive.get(name, 0) - should_pay.get(name, 0) - - return render_template("compute_bills.html", balances=balances, project=project) + return render_template("compute_bills.html", project=project) @app.route("/<string:project_id>/reset") |
