mirror of
https://github.com/spiral-project/ihatemoney.git
synced 2025-04-28 17:32:38 +02:00
Initial montly expenses (#526)
This commit is contained in:
parent
bf691660ee
commit
02242f2e12
4 changed files with 38 additions and 1 deletions
|
@ -94,6 +94,18 @@ class Project(db.Model):
|
||||||
for member in self.active_members
|
for member in self.active_members
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def monthly_stats(self):
|
||||||
|
"""Compute expenses by month
|
||||||
|
|
||||||
|
:return: a dict of years mapping to a dict of months mapping to the amount
|
||||||
|
:rtype dict:
|
||||||
|
"""
|
||||||
|
monthly = defaultdict(lambda: defaultdict(float))
|
||||||
|
for bill in self.get_bills().all():
|
||||||
|
monthly[bill.date.year][bill.date.month] += bill.amount
|
||||||
|
return monthly
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def uses_weights(self):
|
def uses_weights(self):
|
||||||
return len([i for i in self.members if i.weight != 1]) > 0
|
return len([i for i in self.members if i.weight != 1]) > 0
|
||||||
|
|
|
@ -311,8 +311,9 @@ footer .footer-left {
|
||||||
background: url("../images/see.png") no-repeat right;
|
background: url("../images/see.png") no-repeat right;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bill_table {
|
#bill_table, #monthly_stats {
|
||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-actions > .delete,
|
.project-actions > .delete,
|
||||||
|
@ -487,3 +488,9 @@ footer .icon svg {
|
||||||
.icon.icon-white {
|
.icon.icon-white {
|
||||||
fill: white;
|
fill: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* align the first column */
|
||||||
|
#monthly_stats tr *:first-child {
|
||||||
|
text-align: right;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<h2>{{ _("Balance") }}</h2>
|
||||||
<table id="bill_table" class="split_bills table table-striped">
|
<table id="bill_table" class="split_bills table table-striped">
|
||||||
<thead><tr><th>{{ _("Who?") }}</th><th>{{ _("Paid") }}</th><th>{{ _("Spent") }}</th></tr></thead>
|
<thead><tr><th>{{ _("Who?") }}</th><th>{{ _("Paid") }}</th><th>{{ _("Spent") }}</th></tr></thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -33,5 +34,17 @@
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<h2>{{ _("Expenses by Month") }}</h2>
|
||||||
|
<table id="monthly_stats" class="table table-striped">
|
||||||
|
<thead><tr><th>{{ _("Period") }}</th><th>{{ _("Spent") }}</th></tr></thead>
|
||||||
|
<tbody>
|
||||||
|
{% for month in months %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ _(month.strftime("%B")) }} {{ month.year }}</td>
|
||||||
|
<td>{{ "%0.2f"|format(monthly_stats[month.year][month.month]) }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -55,6 +55,8 @@ from ihatemoney.utils import (
|
||||||
get_members,
|
get_members,
|
||||||
same_bill,
|
same_bill,
|
||||||
)
|
)
|
||||||
|
from datetime import datetime
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
|
||||||
main = Blueprint("main", __name__)
|
main = Blueprint("main", __name__)
|
||||||
|
|
||||||
|
@ -737,9 +739,12 @@ def settle_bill():
|
||||||
@main.route("/<project_id>/statistics")
|
@main.route("/<project_id>/statistics")
|
||||||
def statistics():
|
def statistics():
|
||||||
"""Compute what each member has paid and spent and display it"""
|
"""Compute what each member has paid and spent and display it"""
|
||||||
|
today = datetime.now()
|
||||||
return render_template(
|
return render_template(
|
||||||
"statistics.html",
|
"statistics.html",
|
||||||
members_stats=g.project.members_stats,
|
members_stats=g.project.members_stats,
|
||||||
|
monthly_stats=g.project.monthly_stats,
|
||||||
|
months=[today - relativedelta(months=i) for i in range(12)],
|
||||||
current_view="statistics",
|
current_view="statistics",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue