From 389c7b8bcd2813d8549858265432859259942fd6 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Sat, 3 Feb 2018 17:49:12 +0100 Subject: Remove dead code --- ihatemoney/templates/statistics.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ihatemoney') diff --git a/ihatemoney/templates/statistics.html b/ihatemoney/templates/statistics.html index ae1c80e..ee59cb9 100644 --- a/ihatemoney/templates/statistics.html +++ b/ihatemoney/templates/statistics.html @@ -5,7 +5,7 @@ {% set balance = g.project.balance %} {% for member in g.project.members | sort(attribute='name') if member.activated or balance[member.id]|round(2) != 0 %} - +
{{ member.name }} {% if balance[member.id]|round(2) > 0 %}+{% endif %}{{ "%.2f" | format(balance[member.id]) }} -- cgit v1.1 From b1a4572e8c72e1d7f49b07aaeb5be0f3603bf0a7 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Sat, 3 Feb 2018 18:04:06 +0100 Subject: Change statistics data structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clearer data structure, and simpler template This commit has a side effect: sidebar now hides disabled members. IMHO, the disabled members should either be hidden or shown consistently between sidebar and central table. Previous status was: shown in sidebar (if balance ≠ 0) and hidden in central table. --- ihatemoney/templates/statistics.html | 19 +++++++++---------- ihatemoney/tests/tests.py | 24 ++++++++++++------------ ihatemoney/web.py | 27 ++++++++++++++------------- 3 files changed, 35 insertions(+), 35 deletions(-) (limited to 'ihatemoney') diff --git a/ihatemoney/templates/statistics.html b/ihatemoney/templates/statistics.html index ee59cb9..1b07a33 100644 --- a/ihatemoney/templates/statistics.html +++ b/ihatemoney/templates/statistics.html @@ -3,12 +3,11 @@ {% block sidebar %}
- {% set balance = g.project.balance %} - {% for member in g.project.members | sort(attribute='name') if member.activated or balance[member.id]|round(2) != 0 %} + {% for stat in members_stats| sort(attribute='member.name') %} - - + {% endfor %} @@ -21,12 +20,12 @@
{{ member.name }} - {% if balance[member.id]|round(2) > 0 %}+{% endif %}{{ "%.2f" | format(balance[member.id]) }} + {{ stat.member.name }} + {% if stat.balance|round(2) > 0 %}+{% endif %}{{ "%.2f" | format(stat.balance) }}
- {% for member in members %} + {% for stat in members_stats %} - - - - + + + + {% endfor %} diff --git a/ihatemoney/tests/tests.py b/ihatemoney/tests/tests.py index c13131c..3582032 100644 --- a/ihatemoney/tests/tests.py +++ b/ihatemoney/tests/tests.py @@ -750,24 +750,24 @@ class BudgetTestCase(IhatemoneyTestCase): }) response = self.client.get("/raclette/statistics") - self.assertIn("\n " - + "\n " - + "\n " + self.assertIn("\n " + + "\n " + + "\n " + "\n", response.data.decode('utf-8')) - self.assertIn("\n " - + "\n " - + "\n " + self.assertIn("\n " + + "\n " + + "\n " + "\n", response.data.decode('utf-8')) - self.assertIn("\n " - + "\n " - + "\n " + self.assertIn("\n " + + "\n " + + "\n " + "\n", response.data.decode('utf-8')) - self.assertIn("\n " - + "\n " - + "\n " + self.assertIn("\n " + + "\n " + + "\n " + "\n", response.data.decode('utf-8')) diff --git a/ihatemoney/web.py b/ihatemoney/web.py index 6b1b358..85b02e5 100644 --- a/ihatemoney/web.py +++ b/ihatemoney/web.py @@ -566,21 +566,22 @@ def settle_bill(): @main.route("//statistics") def statistics(): """Compute what each member has paid and spent and display it""" - members = g.project.active_members - balance = g.project.balance - paid = {} - spent = {} - for member in members: - paid[member.id] = sum([bill.amount - for bill in g.project.get_member_bills(member.id).all()]) - spent[member.id] = sum([bill.pay_each() * member.weight - for bill in g.project.get_bills().all() if member in bill.owers]) + members_stats = [{ + 'member': member, + 'paid': sum([ + bill.amount + for bill in g.project.get_member_bills(member.id).all() + ]), + 'spent': sum([ + bill.pay_each() * member.weight + for bill in g.project.get_bills().all() if member in bill.owers + ]), + 'balance': g.project.balance[member.id] + } for member in g.project.active_members] + return render_template( "statistics.html", - members=members, - balance=balance, - paid=paid, - spent=spent, + members_stats=members_stats, current_view='statistics', ) -- cgit v1.1 From 036cd05e5716a694f575b3c65f6541f04a8b48bf Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Sat, 3 Feb 2018 18:26:44 +0100 Subject: Move member stats computation to a dedicated method --- ihatemoney/models.py | 20 ++++++++++++++++++++ ihatemoney/web.py | 15 +-------------- 2 files changed, 21 insertions(+), 14 deletions(-) (limited to 'ihatemoney') diff --git a/ihatemoney/models.py b/ihatemoney/models.py index aa3083d..c6ce23f 100644 --- a/ihatemoney/models.py +++ b/ihatemoney/models.py @@ -53,6 +53,26 @@ class Project(db.Model): return balances @property + def members_stats(self): + """Compute what each member has paid + + :return: one stat dict per member + :rtype list: + """ + return [{ + 'member': member, + 'paid': sum([ + bill.amount + for bill in self.get_member_bills(member.id).all() + ]), + 'spent': sum([ + bill.pay_each() * member.weight + for bill in self.get_bills().all() if member in bill.owers + ]), + 'balance': self.balance[member.id] + } for member in self.active_members] + + @property def uses_weights(self): return len([i for i in self.members if i.weight != 1]) > 0 diff --git a/ihatemoney/web.py b/ihatemoney/web.py index 85b02e5..1e16202 100644 --- a/ihatemoney/web.py +++ b/ihatemoney/web.py @@ -566,22 +566,9 @@ def settle_bill(): @main.route("//statistics") def statistics(): """Compute what each member has paid and spent and display it""" - members_stats = [{ - 'member': member, - 'paid': sum([ - bill.amount - for bill in g.project.get_member_bills(member.id).all() - ]), - 'spent': sum([ - bill.pay_each() * member.weight - for bill in g.project.get_bills().all() if member in bill.owers - ]), - 'balance': g.project.balance[member.id] - } for member in g.project.active_members] - return render_template( "statistics.html", - members_stats=members_stats, + members_stats=g.project.members_stats, current_view='statistics', ) -- cgit v1.1 From b95ea7f4e68a0794a44e68621a8210bb4db43e67 Mon Sep 17 00:00:00 2001 From: Jocelyn Delalande Date: Sat, 3 Feb 2018 18:52:04 +0100 Subject: Add statistics support to API --- ihatemoney/api.py | 8 ++++++++ ihatemoney/tests/tests.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) (limited to 'ihatemoney') diff --git a/ihatemoney/api.py b/ihatemoney/api.py index 31ed06c..6068cf7 100644 --- a/ihatemoney/api.py +++ b/ihatemoney/api.py @@ -65,6 +65,13 @@ class ProjectHandler(Resource): return form.errors, 400 +class ProjectStatsHandler(Resource): + method_decorators = [need_auth] + + def get(self, project): + return project.members_stats + + class APIMemberForm(MemberForm): """ Member is not disablable via a Form. @@ -163,6 +170,7 @@ class BillHandler(Resource): restful_api.add_resource(ProjectsHandler, '/projects') restful_api.add_resource(ProjectHandler, '/projects/') restful_api.add_resource(MembersHandler, "/projects//members") +restful_api.add_resource(ProjectStatsHandler, "/projects//statistics") restful_api.add_resource(MemberHandler, "/projects//members/") restful_api.add_resource(BillsHandler, "/projects//bills") restful_api.add_resource(BillHandler, "/projects//bills/") diff --git a/ihatemoney/tests/tests.py b/ihatemoney/tests/tests.py index 3582032..3797f09 100644 --- a/ihatemoney/tests/tests.py +++ b/ihatemoney/tests/tests.py @@ -1325,6 +1325,40 @@ class APITestCase(IhatemoneyTestCase): headers=self.get_auth("raclette")) self.assertStatus(404, req) + def test_statistics(self): + # create a project + self.api_create("raclette") + + # add members + self.api_add_member("raclette", "alexis") + self.api_add_member("raclette", "fred") + + # add a bill + req = self.client.post("/api/projects/raclette/bills", data={ + 'date': '2011-08-10', + 'what': 'fromage', + 'payer': "1", + 'payed_for': ["1", "2"], + 'amount': '25', + }, headers=self.get_auth("raclette")) + + # get the list of bills (should be empty) + req = self.client.get("/api/projects/raclette/statistics", + headers=self.get_auth("raclette")) + self.assertStatus(200, req) + self.assertEqual([ + {'balance': 12.5, + 'member': {'activated': True, 'id': 1, + 'name': 'alexis', 'weight': 1.0}, + 'paid': 25.0, + 'spent': 12.5}, + {'balance': -12.5, + 'member': {'activated': True, 'id': 2, + 'name': 'fred', 'weight': 1.0}, + 'paid': 0, + 'spent': 12.5}], + json.loads(req.data.decode('utf-8'))) + def test_username_xss(self): # create a project # self.api_create("raclette") -- cgit v1.1
{{ _("Who?") }}{{ _("Paid") }}{{ _("Spent") }}{{ _("Balance") }}
{{ member.name }}{{ "%0.2f"|format(paid[member.id]) }}{{ "%0.2f"|format(spent[member.id]) }}{{ "%0.2f"|format(balance[member.id]) }}{{ stat.member.name }}{{ "%0.2f"|format(stat.paid) }}{{ "%0.2f"|format(stat.spent) }}{{ "%0.2f"|format(stat.balance) }}
alexis20.0031.67alexis20.0031.67-11.67fred20.005.83fred20.005.8314.17tata0.002.50tata0.002.50-2.50toto0.000.00toto0.000.000.00