diff options
| author | Alexis Metaireau <alexis@notmyidea.org> | 2013-05-09 18:32:55 -0700 |
|---|---|---|
| committer | Alexis Metaireau <alexis@notmyidea.org> | 2013-05-09 18:32:55 -0700 |
| commit | a71d249e6c35b9a204d50e40365945c359ee5b63 (patch) | |
| tree | 4c7e03c81868237192992d8d2ff587f68fab0a4d /budget | |
| parent | aa7d79d2ad119e575d8cd14f19369e74b22f804b (diff) | |
| parent | ff9ead22031563b31f14e87ae3b3c537a06b8c41 (diff) | |
| download | ihatemoney-mirror-a71d249e6c35b9a204d50e40365945c359ee5b63.zip ihatemoney-mirror-a71d249e6c35b9a204d50e40365945c359ee5b63.tar.gz ihatemoney-mirror-a71d249e6c35b9a204d50e40365945c359ee5b63.tar.bz2 | |
Merge pull request #96 from aavenel/master
New feature : Settle the bill
Diffstat (limited to 'budget')
| -rw-r--r-- | budget/messages.pot | 253 | ||||
| -rw-r--r-- | budget/models.py | 47 | ||||
| -rw-r--r-- | budget/templates/layout.html | 3 | ||||
| -rw-r--r-- | budget/templates/list_bills.html | 2 | ||||
| -rw-r--r-- | budget/templates/settle_bills.html | 43 | ||||
| -rw-r--r-- | budget/tests.py | 67 | ||||
| -rw-r--r-- | budget/translations/fr/LC_MESSAGES/messages.mo | bin | 7123 -> 7888 bytes | |||
| -rw-r--r-- | budget/translations/fr/LC_MESSAGES/messages.po | 262 | ||||
| -rw-r--r-- | budget/web.py | 7 |
9 files changed, 460 insertions, 224 deletions
diff --git a/budget/messages.pot b/budget/messages.pot index effeccf..b3cb0cc 100644 --- a/budget/messages.pot +++ b/budget/messages.pot @@ -1,203 +1,211 @@ # Translations template for PROJECT. -# Copyright (C) 2011 ORGANIZATION +# Copyright (C) 2013 ORGANIZATION # This file is distributed under the same license as the PROJECT project. -# Alexis Métaireau <alexis@notmyidea.org>, 2011. +# FIRST AUTHOR <EMAIL@ADDRESS>, 2013. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-11-20 14:05+0100\n" +"POT-Creation-Date: 2013-05-09 22:24+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Quentin Roy <royque@gmail.com>\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" -#: forms.py:20 -msgid "Select All/None" +#: forms.py:22 +msgid "Select all" msgstr "" -#: forms.py:57 +#: forms.py:22 +msgid "Select none" +msgstr "" + +#: forms.py:61 msgid "Project name" msgstr "" -#: forms.py:58 forms.py:82 forms.py:93 +#: forms.py:62 forms.py:86 forms.py:102 msgid "Private code" msgstr "" -#: forms.py:59 +#: forms.py:63 msgid "Email" msgstr "" -#: forms.py:81 forms.py:92 forms.py:98 +#: forms.py:85 forms.py:101 forms.py:107 msgid "Project identifier" msgstr "" -#: forms.py:83 templates/send_invites.html:5 +#: forms.py:87 templates/send_invites.html:5 msgid "Create the project" msgstr "" -#: forms.py:88 +#: forms.py:92 msgid "" "The project identifier is used to log in and for the URL of the project. " "We tried to generate an identifier for you but a project with this " -"identifier already exists. Please create a new identifier you will be " -"able to remember." +"identifier already exists. Please create a new identifier that you will " +"be able to remember." msgstr "" -#: forms.py:94 +#: forms.py:103 msgid "Get in" msgstr "" -#: forms.py:99 +#: forms.py:108 msgid "Send me the code by email" msgstr "" -#: forms.py:103 +#: forms.py:112 msgid "This project does not exists" msgstr "" -#: forms.py:107 +#: forms.py:116 msgid "Date" msgstr "" -#: forms.py:108 +#: forms.py:117 msgid "What?" msgstr "" -#: forms.py:109 +#: forms.py:118 msgid "Payer" msgstr "" -#: forms.py:110 +#: forms.py:119 msgid "Amount paid" msgstr "" -#: forms.py:111 templates/list_bills.html:154 +#: forms.py:120 templates/list_bills.html:103 msgid "For whom?" msgstr "" -#: forms.py:113 -msgid "Send the bill" +#: forms.py:122 +msgid "Submit" msgstr "" -#: forms.py:139 -msgid "Bills can't be null" +#: forms.py:123 +msgid "Submit and add a new one" msgstr "" -#: forms.py:144 -msgid "Name" +#: forms.py:149 +msgid "Bills can't be null" msgstr "" -#: forms.py:144 -msgid "Type user name here" +#: forms.py:154 +msgid "Name" msgstr "" -#: forms.py:145 templates/forms.html:94 +#: forms.py:155 templates/forms.html:95 msgid "Add" msgstr "" -#: forms.py:153 +#: forms.py:163 msgid "User name incorrect" msgstr "" -#: forms.py:157 +#: forms.py:167 msgid "This project already have this member" msgstr "" -#: forms.py:167 +#: forms.py:178 msgid "People to notify" msgstr "" -#: forms.py:168 +#: forms.py:179 msgid "Send invites" msgstr "" -#: forms.py:174 +#: forms.py:185 #, python-format msgid "The email %(email)s is not valid" msgstr "" -#: forms.py:179 -msgid "Start date" +#: forms.py:190 +msgid "Name for this archive (optional)" msgstr "" -#: forms.py:180 -msgid "End date" +#: forms.py:191 +msgid "Start date" msgstr "" -#: forms.py:181 -msgid "Name for this archive (optional)" +#: forms.py:192 +msgid "End date" msgstr "" -#: web.py:89 +#: web.py:95 msgid "This private code is not the right one" msgstr "" -#: web.py:137 +#: web.py:147 #, python-format msgid "You have just created '%(project)s' to share your expenses" msgstr "" -#: web.py:148 +#: web.py:165 #, python-format -msgid "The project identifier is %(project)s" +msgid "%(msg_compl)sThe project identifier is %(project)s" msgstr "" -#: web.py:166 +#: web.py:185 msgid "a mail has been sent to you with the password" msgstr "" -#: web.py:229 +#: web.py:211 +msgid "Project successfully deleted" +msgstr "" + +#: web.py:254 #, python-format msgid "You have been invited to share your expenses for %(project)s" msgstr "" -#: web.py:236 +#: web.py:261 msgid "Your invitations have been sent" msgstr "" -#: web.py:261 +#: web.py:290 #, python-format msgid "%(member)s had been added" msgstr "" -#: web.py:273 +#: web.py:303 #, python-format msgid "%(name)s is part of this project again" msgstr "" -#: web.py:281 +#: web.py:311 #, python-format msgid "User '%(name)s' has been deactivated" msgstr "" -#: web.py:283 +#: web.py:313 #, python-format msgid "User '%(name)s' has been removed" msgstr "" -#: web.py:300 +#: web.py:331 msgid "The bill has been added" msgstr "" -#: web.py:315 +#: web.py:351 msgid "The bill has been deleted" msgstr "" -#: web.py:333 +#: web.py:369 msgid "The bill has been modified" msgstr "" -#: web.py:357 +#: web.py:399 msgid "The data from XX to XX has been archived" msgstr "" -#: templates/add_bill.html:19 +#: templates/add_bill.html:9 msgid "Back to the list" msgstr "" @@ -219,8 +227,27 @@ msgstr "" msgid "Create a new project" msgstr "" -#: templates/edit_project.html:6 templates/list_bills.html:77 -#: templates/list_bills.html:87 +#: templates/dashboard.html:5 +msgid "Project" +msgstr "" + +#: templates/dashboard.html:5 +msgid "Number of members" +msgstr "" + +#: templates/dashboard.html:5 +msgid "Number of bills" +msgstr "" + +#: templates/dashboard.html:5 +msgid "Newest bill" +msgstr "" + +#: templates/dashboard.html:5 +msgid "Oldest bill" +msgstr "" + +#: templates/edit_project.html:6 templates/list_bills.html:24 msgid "you sure?" msgstr "" @@ -228,31 +255,35 @@ msgstr "" msgid "Edit this project" msgstr "" -#: templates/forms.html:24 +#: templates/forms.html:23 msgid "Can't remember the password?" msgstr "" -#: templates/forms.html:27 +#: templates/forms.html:26 msgid "Cancel" msgstr "" -#: templates/forms.html:69 +#: templates/forms.html:68 msgid "Edit the project" msgstr "" -#: templates/forms.html:70 templates/list_bills.html:139 -#: templates/list_bills.html:167 +#: templates/forms.html:69 templates/list_bills.html:70 +#: templates/list_bills.html:114 msgid "delete" msgstr "" -#: templates/forms.html:78 +#: templates/forms.html:77 msgid "Edit this bill" msgstr "" -#: templates/forms.html:78 +#: templates/forms.html:77 templates/list_bills.html:94 msgid "Add a bill" msgstr "" +#: templates/forms.html:95 +msgid "Type user name here" +msgstr "" + #: templates/forms.html:102 msgid "Send the invitations" msgstr "" @@ -265,35 +296,35 @@ msgstr "" msgid "Create an archive" msgstr "" -#: templates/forms.html:115 +#: templates/forms.html:116 msgid "Create the archive" msgstr "" -#: templates/home.html:9 +#: templates/home.html:8 msgid "Manage your shared <br>expenses, easily" msgstr "" -#: templates/home.html:10 +#: templates/home.html:9 msgid "Try out the demo" msgstr "" -#: templates/home.html:13 +#: templates/home.html:12 msgid "You're sharing a house?" msgstr "" -#: templates/home.html:13 +#: templates/home.html:12 msgid "Going on holidays with friends?" msgstr "" -#: templates/home.html:13 +#: templates/home.html:12 msgid "Simply sharing money with others?" msgstr "" -#: templates/home.html:13 +#: templates/home.html:12 msgid "We can help!" msgstr "" -#: templates/home.html:26 +#: templates/home.html:24 msgid "Log to an existing project" msgstr "" @@ -305,107 +336,109 @@ msgstr "" msgid "can't remember your password?" msgstr "" -#: templates/home.html:34 +#: templates/home.html:36 msgid "or create a new one" msgstr "" -#: templates/home.html:36 +#: templates/home.html:40 msgid "let's get started" msgstr "" +#: templates/home.html:51 +msgid "" +"This access code will be sent to your friends. It is stored as-is by the " +"server, so don\\'t reuse a personal password!" +msgstr "" + #: templates/layout.html:5 msgid "Account manager" msgstr "" -#: templates/layout.html:54 +#: templates/layout.html:45 templates/settle_bills.html:4 msgid "Bills" msgstr "" -#: templates/layout.html:58 +#: templates/layout.html:46 templates/settle_bills.html:5 +msgid "Settle" +msgstr "" + +#: templates/layout.html:53 msgid "options" msgstr "" -#: templates/layout.html:60 +#: templates/layout.html:55 msgid "Project settings" msgstr "" -#: templates/layout.html:64 +#: templates/layout.html:59 msgid "switch to" msgstr "" -#: templates/layout.html:67 +#: templates/layout.html:62 msgid "Start a new project" msgstr "" -#: templates/layout.html:69 +#: templates/layout.html:64 msgid "Logout" msgstr "" -#: templates/layout.html:95 +#: templates/layout.html:92 msgid "This is a free software" msgstr "" -#: templates/layout.html:95 +#: templates/layout.html:92 msgid "you can contribute and improve it!" msgstr "" -#: templates/list_bills.html:115 -msgid "Balance" -msgstr "" - -#: templates/list_bills.html:140 +#: templates/list_bills.html:74 msgid "reactivate" msgstr "" -#: templates/list_bills.html:144 +#: templates/list_bills.html:88 msgid "The project identifier is" msgstr "" -#: templates/list_bills.html:144 +#: templates/list_bills.html:88 msgid "remember it!" msgstr "" -#: templates/list_bills.html:145 +#: templates/list_bills.html:89 msgid "Add a new bill" msgstr "" -#: templates/list_bills.html:148 -msgid "hide this form" -msgstr "" - -#: templates/list_bills.html:154 +#: templates/list_bills.html:103 msgid "When?" msgstr "" -#: templates/list_bills.html:154 +#: templates/list_bills.html:103 msgid "Who paid?" msgstr "" -#: templates/list_bills.html:154 +#: templates/list_bills.html:103 msgid "For what?" msgstr "" -#: templates/list_bills.html:154 +#: templates/list_bills.html:103 templates/settle_bills.html:31 msgid "How much?" msgstr "" -#: templates/list_bills.html:154 +#: templates/list_bills.html:103 msgid "Actions" msgstr "" -#: templates/list_bills.html:162 +#: templates/list_bills.html:111 msgid "each" msgstr "" -#: templates/list_bills.html:164 +#: templates/list_bills.html:113 msgid "edit" msgstr "" -#: templates/list_bills.html:177 +#: templates/list_bills.html:122 msgid "Nothing to list yet. You probably want to" msgstr "" -#: templates/list_bills.html:177 +#: templates/list_bills.html:122 msgid "add a bill" msgstr "" @@ -449,3 +482,11 @@ msgstr "" msgid "and notify them yourself" msgstr "" +#: templates/settle_bills.html:31 +msgid "Who pays?" +msgstr "" + +#: templates/settle_bills.html:31 +msgid "To whom?" +msgstr "" + diff --git a/budget/models.py b/budget/models.py index db57869..900b1d0 100644 --- a/budget/models.py +++ b/budget/models.py @@ -49,6 +49,53 @@ class Project(db.Model): return balances + def get_transactions_to_settle_bill(self): + """Return a list of transactions that could be made to settle the bill""" + #cache value for better performance + balance = self.balance + credits, debts, transactions = [],[],[] + # Create lists of credits and debts + for person in self.members: + if balance[person.id] > 0: + credits.append({"person": person, "balance": balance[person.id]}) + elif balance[person.id] < 0: + debts.append({"person": person, "balance": -balance[person.id]}) + # 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"], "receiver": 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"], "receiver": 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"], "receiver": 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 None + 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 diff --git a/budget/templates/layout.html b/budget/templates/layout.html index 8e6d3b2..543bcb3 100644 --- a/budget/templates/layout.html +++ b/budget/templates/layout.html @@ -41,7 +41,10 @@ <h1><a class="brand" href="{{ url_for(".home") }}">#! money?</a></h1> {% if g.project %} <ul class="nav primary-nav"> + {% block navbar %} <li class="active"><a href="{{ url_for(".list_bills") }}">{{ _("Bills") }}</a></li> + <li><a href="{{ url_for(".settle_bill") }}">{{ _("Settle") }}</a></li> + {% endblock %} </ul> {% endif %} <ul class="nav pull-right secondary-nav"> diff --git a/budget/templates/list_bills.html b/budget/templates/list_bills.html index 389e73f..ee97624 100644 --- a/budget/templates/list_bills.html +++ b/budget/templates/list_bills.html @@ -73,7 +73,7 @@ <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 %}"> + <td class="balance-value {% if balance[member] > 0 %}positive{% elif balance[member.id] < 0 %}negative{% endif %}"> {% if balance[member.id] > 0 %}+{% endif %}{{ balance[member.id] }} </td> </tr> diff --git a/budget/templates/settle_bills.html b/budget/templates/settle_bills.html new file mode 100644 index 0000000..29d9b26 --- /dev/null +++ b/budget/templates/settle_bills.html @@ -0,0 +1,43 @@ +{% extends "layout.html" %} + +{% block navbar %} +<li><a href="{{ url_for(".list_bills") }}">{{ _("Bills") }}</a></li> +<li class="active"><a href="{{ url_for(".settle_bill") }}">{{ _("Settle") }}</a></li> +{% endblock %} + +{% block sidebar %} +<div id="sidebar" class="sidebar"> + + <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 %} + <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 %}{{ balance[member.id] }} + </td> + </tr> + {% endfor %} + </table> + </div> + +</div> +{% endblock %} + + +{% block content %} + <table id="bill_table" class="split_bills table table-striped"> + <thead><tr><th>{{ _("Who pays?") }}</th><th>{{ _("To whom?") }}</th><th>{{ _("How much?") }}</th></tr></thead> + <tbody> + {% for bill in bills %} + <tr class="{{ loop.cycle("odd", "even") }}" receiver={{bill.receiver.id}}> + <td>{{ bill.ower }}</td> + <td>{{ bill.receiver }}</td> + <td>{{ "%0.2f"|format(bill.amount) }}</td> + </tr> + {% endfor %} + </tbody> + </table> + +{% endblock %} diff --git a/budget/tests.py b/budget/tests.py index 14e605a..9eea518 100644 --- a/budget/tests.py +++ b/budget/tests.py @@ -6,6 +6,7 @@ except ImportError: import base64 import json +from collections import defaultdict from flask import session @@ -21,9 +22,11 @@ class TestCase(unittest.TestCase): run.app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///memory" run.app.config['CSRF_ENABLED'] = False # simplify the tests self.app = run.app.test_client() - - models.db.init_app(run.app) - run.mail.init_app(run.app) + try: + models.db.init_app(run.app) + run.mail.init_app(run.app) + except: + pass models.db.app = run.app models.db.create_all() @@ -439,7 +442,11 @@ class BudgetTestCase(TestCase): }) balance = models.Project.query.get("raclette").balance - self.assertDictEqual(balance, {3: -8.12, 1: 8.12, 2: 0.0}) + result = {} + result[models.Project.query.get("raclette").members[0].id] = 8.12 + result[models.Project.query.get("raclette").members[1].id] = 0.0 + result[models.Project.query.get("raclette").members[2].id] = -8.12 + self.assertDictEqual(balance, result) def test_edit_project(self): # A project should be editable @@ -470,6 +477,58 @@ class BudgetTestCase(TestCase): response = self.app.get("/dashboard") self.assertEqual(response.status_code, 200) + def test_settle_page(self): + self.post_project("raclette") + response = self.app.get("/raclette/settle_bills") + self.assertEqual(response.status_code, 200) + + def test_settle(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'}) + #Add a member with a balance=0 : + self.app.post("/raclette/members/add", data={'name': 'toto'}) + + # create bills + self.app.post("/raclette/add", data={ + 'date': '2011-08-10', + 'what': u'fromage à raclette', + 'payer': 1, + 'payed_for': [1, 2, 3], + 'amount': '10.0', + }) + + self.app.post("/raclette/add", data={ + 'date': '2011-08-10', + 'what': u'red wine', + 'payer': 2, + 'payed_for': [1], + 'amount': '20', + }) + + self.app.post("/raclette/add", data={ + 'date': '2011-08-10', + 'what': u'delicatessen', + 'payer': 1, + 'payed_for': [1, 2], + 'amount': '10', + }) + project = models.Project.query.get('raclette') + transactions = project.get_transactions_to_settle_bill() + members = defaultdict(int) + #We should have the same values between transactions and project balances + for t in transactions: + members[t['ower']]-=t['amount'] + members[t['receiver']]+=t['amount'] + balance = models.Project.query.get("raclette").balance + for m, a in members.items(): + self.assertEqual(a, balance[m.id]) + return + + class APITestCase(TestCase): """Tests the API""" diff --git a/budget/translations/fr/LC_MESSAGES/messages.mo b/budget/translations/fr/LC_MESSAGES/messages.mo Binary files differindex 563a8e4..4b71866 100644 --- a/budget/translations/fr/LC_MESSAGES/messages.mo +++ b/budget/translations/fr/LC_MESSAGES/messages.mo diff --git a/budget/translations/fr/LC_MESSAGES/messages.po b/budget/translations/fr/LC_MESSAGES/messages.po index ff180b8..467329e 100644 --- a/budget/translations/fr/LC_MESSAGES/messages.po +++ b/budget/translations/fr/LC_MESSAGES/messages.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PROJECT VERSION\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2011-11-20 13:49+0100\n" +"POT-Creation-Date: 2013-05-09 22:24+0200\n" "PO-Revision-Date: 2011-10-14 23:51+0200\n" "Last-Translator: Quentin Roy <royque@gmail.com>\n" "Language-Team: fr <LL@li.org>\n" @@ -17,192 +17,199 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 0.9.6\n" -#: forms.py:20 -msgid "Select All/None" -msgstr "Cocher Tous/Aucun" +#: forms.py:22 +msgid "Select all" +msgstr "Tout cocher" -#: forms.py:57 +#: forms.py:22 +msgid "Select none" +msgstr "Tout décocher" + +#: forms.py:61 msgid "Project name" msgstr "Nom de projet" -#: forms.py:58 forms.py:82 forms.py:93 +#: forms.py:62 forms.py:86 forms.py:102 msgid "Private code" msgstr "Code d'accès" -#: forms.py:59 +#: forms.py:63 msgid "Email" msgstr "Email" -#: forms.py:81 forms.py:92 forms.py:98 +#: forms.py:85 forms.py:101 forms.py:107 msgid "Project identifier" msgstr "Identifiant du projet" -#: forms.py:83 templates/send_invites.html:5 +#: forms.py:87 templates/send_invites.html:5 msgid "Create the project" msgstr "Créer le projet" -#: forms.py:88 +#: forms.py:92 msgid "" "The project identifier is used to log in and for the URL of the project. " "We tried to generate an identifier for you but a project with this " -"identifier already exists. Please create a new identifier you will be " -"able to remember." +"identifier already exists. Please create a new identifier that you will " +"be able to remember." msgstr "" -"L'identifiant de projet est utilisé pour se connecter et dans l'URL du " -"projetNous avons essayé de générer une identifiant pour ce projet mais " +"L'identifiant du projet est utilisé pour se connecter." +"Nous avons essayé de générer un identifiant mais " "celui ci existe déjà. Merci de créer un nouvel identifiant que vous serez" " capable de retenir" -#: forms.py:94 +#: forms.py:103 msgid "Get in" msgstr "Entrer" -#: forms.py:99 +#: forms.py:108 msgid "Send me the code by email" msgstr "Envoyez moi le code par email" -#: forms.py:103 +#: forms.py:112 msgid "This project does not exists" msgstr "Ce projet n'existe pas" -#: forms.py:107 +#: forms.py:116 msgid "Date" msgstr "Date" -#: forms.py:108 +#: forms.py:117 msgid "What?" msgstr "Quoi ?" -#: forms.py:109 +#: forms.py:118 msgid "Payer" msgstr "Payeur" -#: forms.py:110 +#: forms.py:119 msgid "Amount paid" msgstr "Montant" -#: forms.py:111 templates/list_bills.html:154 +#: forms.py:120 templates/list_bills.html:103 msgid "For whom?" msgstr "Pour qui ?" -#: forms.py:113 -msgid "Send the bill" -msgstr "Enregistrer la facture" +#: forms.py:122 +msgid "Submit" +msgstr "Valider" + +#: forms.py:123 +msgid "Submit and add a new one" +msgstr "Valider et ajouter une autre facture" -#: forms.py:139 -#, fuzzy +#: forms.py:149 msgid "Bills can't be null" -msgstr "Le montant d'une facture ne peut pas être négatif" +msgstr "Le montant d'une facture ne peut pas être nul." -#: forms.py:144 +#: forms.py:154 msgid "Name" msgstr "Nom" -#: forms.py:144 -msgid "Type user name here" -msgstr "Nouveau participant" - -#: forms.py:145 templates/forms.html:94 +#: forms.py:155 templates/forms.html:95 msgid "Add" msgstr "Ajouter" -#: forms.py:153 +#: forms.py:163 msgid "User name incorrect" -msgstr "" +msgstr "Nom d'utilisateur incorrect" -#: forms.py:157 +#: forms.py:167 msgid "This project already have this member" msgstr "Ce membre existe déjà pour ce projet" -#: forms.py:167 +#: forms.py:178 msgid "People to notify" msgstr "Personnes à prévenir" -#: forms.py:168 +#: forms.py:179 msgid "Send invites" msgstr "Envoyer les invitations" -#: forms.py:174 +#: forms.py:185 #, python-format msgid "The email %(email)s is not valid" msgstr "L'email %(email)s est invalide" -#: forms.py:179 +#: forms.py:190 +msgid "Name for this archive (optional)" +msgstr "Nom pour cette archive (optionnel)" + +#: forms.py:191 msgid "Start date" msgstr "Date de départ" -#: forms.py:180 +#: forms.py:192 msgid "End date" msgstr "Date de fin" -#: forms.py:181 -msgid "Name for this archive (optional)" -msgstr "Nom pour cette archive" - -#: web.py:89 +#: web.py:95 msgid "This private code is not the right one" msgstr "Le code que vous avez entré n'est pas correct" -#: web.py:137 +#: web.py:147 #, python-format msgid "You have just created '%(project)s' to share your expenses" msgstr "Vous venez de créer '%(project)s' pour partager vos dépenses" -#: web.py:148 +#: web.py:165 #, python-format -msgid "The project identifier is %(project)s" +msgid "%(msg_compl)sThe project identifier is %(project)s" msgstr "L'identifiant de ce projet est '%(project)s'" -#: web.py:166 +#: web.py:185 msgid "a mail has been sent to you with the password" msgstr "Un email vous a été envoyé avec le mot de passe" -#: web.py:229 +#: web.py:211 +msgid "Project successfully deleted" +msgstr "Projet supprimé" + +#: web.py:254 #, python-format msgid "You have been invited to share your expenses for %(project)s" msgstr "Vous avez été invité à partager vos dépenses pour %(project)s" -#: web.py:236 +#: web.py:261 msgid "Your invitations have been sent" msgstr "Vos invitations ont bien été envoyées" -#: web.py:261 +#: web.py:290 #, python-format msgid "%(member)s had been added" msgstr "%(member)s a bien été ajouté" -#: web.py:273 +#: web.py:303 #, python-format msgid "%(name)s is part of this project again" msgstr "%(name)s a rejoint le projet" -#: web.py:281 +#: web.py:311 #, python-format msgid "User '%(name)s' has been deactivated" msgstr "Le membre '%(name)s' a été désactivé" -#: web.py:283 +#: web.py:313 #, python-format msgid "User '%(name)s' has been removed" msgstr "Le membre '%(name)s' a été supprimé" -#: web.py:300 +#: web.py:331 msgid "The bill has been added" msgstr "La facture a bien été ajoutée" -#: web.py:315 +#: web.py:351 msgid "The bill has been deleted" msgstr "La facture a été supprimée" -#: web.py:333 +#: web.py:369 msgid "The bill has been modified" msgstr "La facture a été modifiée" -#: web.py:357 +#: web.py:399 msgid "The data from XX to XX has been archived" msgstr "Les données de XX à XX ont été archivées" -#: templates/add_bill.html:19 +#: templates/add_bill.html:9 msgid "Back to the list" msgstr "Retourner à la liste" @@ -224,8 +231,27 @@ msgstr " ?" msgid "Create a new project" msgstr "Créer un nouveau projet" -#: templates/edit_project.html:6 templates/list_bills.html:77 -#: templates/list_bills.html:87 +#: templates/dashboard.html:5 +msgid "Project" +msgstr "Projets" + +#: templates/dashboard.html:5 +msgid "Number of members" +msgstr "Nombre de membres" + +#: templates/dashboard.html:5 +msgid "Number of bills" +msgstr "Nombre de factures" + +#: templates/dashboard.html:5 +msgid "Newest bill" +msgstr "Facture la plus récente" + +#: templates/dashboard.html:5 +msgid "Oldest bill" +msgstr "Facture la plus ancienne" + +#: templates/edit_project.html:6 templates/list_bills.html:24 msgid "you sure?" msgstr "c'est sûr ?" @@ -233,31 +259,35 @@ msgstr "c'est sûr ?" msgid "Edit this project" msgstr "Éditer ce projet" -#: templates/forms.html:24 +#: templates/forms.html:23 msgid "Can't remember the password?" msgstr "Vous ne vous souvenez plus du code d'accès ?" -#: templates/forms.html:27 +#: templates/forms.html:26 msgid "Cancel" msgstr "Annuler" -#: templates/forms.html:69 +#: templates/forms.html:68 msgid "Edit the project" msgstr "Éditer le projet" -#: templates/forms.html:70 templates/list_bills.html:139 -#: templates/list_bills.html:167 +#: templates/forms.html:69 templates/list_bills.html:70 +#: templates/list_bills.html:114 msgid "delete" msgstr "supprimer" -#: templates/forms.html:78 +#: templates/forms.html:77 msgid "Edit this bill" msgstr "Éditer cette facture" -#: templates/forms.html:78 +#: templates/forms.html:77 templates/list_bills.html:94 msgid "Add a bill" msgstr "Ajouter une facture" +#: templates/forms.html:95 +msgid "Type user name here" +msgstr "Nouveau participant" + #: templates/forms.html:102 msgid "Send the invitations" msgstr "Envoyer les invitations" @@ -270,35 +300,35 @@ msgstr "Non merci" msgid "Create an archive" msgstr "Créer une archive" -#: templates/forms.html:115 +#: templates/forms.html:116 msgid "Create the archive" msgstr "Créer l'archive" -#: templates/home.html:9 +#: templates/home.html:8 msgid "Manage your shared <br>expenses, easily" msgstr "Gérez vos dépenses<br> partagées, facilement" -#: templates/home.html:10 +#: templates/home.html:9 msgid "Try out the demo" msgstr "Essayez la démo" -#: templates/home.html:13 +#: templates/home.html:12 msgid "You're sharing a house?" msgstr "Vous êtes en colocation ?" -#: templates/home.html:13 +#: templates/home.html:12 msgid "Going on holidays with friends?" msgstr "Partez en vacances avec des amis ?" -#: templates/home.html:13 +#: templates/home.html:12 msgid "Simply sharing money with others?" msgstr "Ça vous arrive de partager de l'argent avec d'autres ?" -#: templates/home.html:13 +#: templates/home.html:12 msgid "We can help!" msgstr "On peut vous aider !" -#: templates/home.html:26 +#: templates/home.html:24 msgid "Log to an existing project" msgstr "Se connecter à un projet existant" @@ -310,107 +340,111 @@ msgstr "se connecter" msgid "can't remember your password?" msgstr "vous ne vous souvenez plus du code d'accès ?" -#: templates/home.html:34 +#: templates/home.html:36 msgid "or create a new one" msgstr "ou créez en un nouveau" -#: templates/home.html:36 +#: templates/home.html:40 msgid "let's get started" msgstr "c'est parti !" +#: templates/home.html:51 +msgid "" +"This access code will be sent to your friends. It is stored as-is by the " +"server, so don\\'t reuse a personal password!" +msgstr "" +"Ce code d'accès va être envoyé à vos amis et stocké en clair sur le " +"serveur.N'utilisez pas un mot de passe personnel !" + #: templates/layout.html:5 msgid "Account manager" msgstr "Gestion de comptes" -#: templates/layout.html:54 +#: templates/layout.html:45 templates/settle_bills.html:4 msgid "Bills" msgstr "Factures" -#: templates/layout.html:58 +#: templates/layout.html:46 templates/settle_bills.html:5 +msgid "Settle" +msgstr "Remboursements" + +#: templates/layout.html:53 msgid "options" msgstr "options" -#: templates/layout.html:60 +#: templates/layout.html:55 msgid "Project settings" msgstr "Options du projet" -#: templates/layout.html:64 +#: templates/layout.html:59 msgid "switch to" msgstr "aller à" -#: templates/layout.html:67 +#: templates/layout.html:62 msgid "Start a new project" msgstr "Nouveau projet" -#: templates/layout.html:69 +#: templates/layout.html:64 msgid "Logout" msgstr "Se déconnecter" -#: templates/layout.html:95 +#: templates/layout.html:92 msgid "This is a free software" msgstr "Ceci est un logiciel libre" -#: templates/layout.html:95 +#: templates/layout.html:92 msgid "you can contribute and improve it!" msgstr "vous pouvez y contribuer et l'améliorer" -#: templates/list_bills.html:115 -msgid "Balance" -msgstr "Balance" - -#: templates/list_bills.html:140 +#: templates/list_bills.html:74 msgid "reactivate" msgstr "ré-activer" -#: templates/list_bills.html:144 +#: templates/list_bills.html:88 msgid "The project identifier is" msgstr "L'identifiant de ce projet est" -#: templates/list_bills.html:144 +#: templates/list_bills.html:88 msgid "remember it!" msgstr "souvenez vous en !" -#: templates/list_bills.html:145 +#: templates/list_bills.html:89 msgid "Add a new bill" msgstr "Nouvelle facture" -#: templates/list_bills.html:148 -msgid "hide this form" -msgstr "cacher ce formulaire" - -#: templates/list_bills.html:154 +#: templates/list_bills.html:103 msgid "When?" msgstr "Quand ?" -#: templates/list_bills.html:154 +#: templates/list_bills.html:103 msgid "Who paid?" msgstr "Qui a payé ?" -#: templates/list_bills.html:154 +#: templates/list_bills.html:103 msgid "For what?" msgstr "Pour quoi ?" -#: templates/list_bills.html:154 +#: templates/list_bills.html:103 templates/settle_bills.html:31 msgid "How much?" msgstr "Combien ?" -#: templates/list_bills.html:154 +#: templates/list_bills.html:103 msgid "Actions" msgstr "Actions" -#: templates/list_bills.html:162 +#: templates/list_bills.html:111 msgid "each" msgstr "chacun" -#: templates/list_bills.html:164 +#: templates/list_bills.html:113 msgid "edit" msgstr "éditer" -#: templates/list_bills.html:177 +#: templates/list_bills.html:122 msgid "Nothing to list yet. You probably want to" msgstr "Rien à lister pour l'instant. Vous voulez surement" -#: templates/list_bills.html:177 +#: templates/list_bills.html:122 msgid "add a bill" msgstr "ajouter une facture" @@ -456,3 +490,11 @@ msgstr "sauter cette étape" msgid "and notify them yourself" msgstr "et les notifier vous même" +#: templates/settle_bills.html:31 +msgid "Who pays?" +msgstr "Qui doit payer ?" + +#: templates/settle_bills.html:31 +msgid "To whom?" +msgstr "Pour qui ?" + diff --git a/budget/web.py b/budget/web.py index 5afd9b4..0b302cd 100644 --- a/budget/web.py +++ b/budget/web.py @@ -383,10 +383,11 @@ def change_lang(lang): return redirect(request.headers.get('Referer') or url_for('.home')) -@main.route("/<project_id>/compute") -def compute_bills(): +@main.route("/<project_id>/settle_bills") +def settle_bill(): """Compute the sum each one have to pay to each other and display it""" - return render_template("compute_bills.html") + bills = g.project.get_transactions_to_settle_bill() + return render_template("settle_bills.html", bills=bills) @main.route("/<project_id>/archives/create", methods=["GET", "POST"]) |
