diff --git a/api/views/api.py b/api/views/api.py
index 6e7933be..37557587 100644
--- a/api/views/api.py
+++ b/api/views/api.py
@@ -1,14 +1,20 @@
from rest_framework.response import Response
-from rest_framework.decorators import api_view
+from rest_framework.decorators import api_view, renderer_classes
+from rest_framework.renderers import StaticHTMLRenderer
+from rest_framework.views import APIView
from core.templatetags.renderer import markdown
@api_view(['GET'])
+@renderer_classes((StaticHTMLRenderer,))
def RenderMarkdown(request):
"""
Render Markdown
"""
- if request.method == 'GET':
- return Response(markdown(request.GET['text']))
+ try:
+ data = markdown(request.GET['text'])
+ except:
+ data = 'Error'
+ return Response(data)
diff --git a/core/templates/core/macros.jinja b/core/templates/core/macros.jinja
index ac930514..9a048636 100644
--- a/core/templates/core/macros.jinja
+++ b/core/templates/core/macros.jinja
@@ -33,3 +33,25 @@
{%- endmacro %}
+
+{% macro show_slots(user) %}
+ {% if get_subscriber(user).slots.exists() %}
+
{% trans %}Slot{% endtrans %}
+
+ {% for i in get_subscriber(user).slots.all() %}
+ - {{ i.get_type_display() }} - {{i.machine.launderette }}, {{ i.start_date|localtime|date("l j") }} : {{ i.start_date|localtime|time(DATETIME_FORMAT) }}
+ {% endfor %}
+
+ {% endif %}
+{% endmacro %}
+
+{% macro show_tokens(user) %}
+ {% if get_subscriber(user).tokens.exists() %}
+ {% trans %}Tokens{% endtrans %}
+
+ {% for i in get_subscriber(user).tokens.all() %}
+ - {{ i }}
+ {% endfor %}
+
+ {% endif %}
+{% endmacro %}
\ No newline at end of file
diff --git a/core/templates/core/user_account.jinja b/core/templates/core/user_account.jinja
index e06c04ec..dfc3cdd8 100644
--- a/core/templates/core/user_account.jinja
+++ b/core/templates/core/user_account.jinja
@@ -1,5 +1,31 @@
{% extends "core/base.jinja" %}
+{% macro monthly(obj) %}
+
+
+
+ {% trans %}Year{% endtrans %} |
+ {% trans %}Month{% endtrans %} |
+ {% trans %}Total{% endtrans %} |
+
+
+
+ {% for array in obj %}
+ {% for tuple in array %}
+ {% if tuple[0] != 0 %}
+ {% set link=url('core:user_account_detail', user_id=profile.id, year=tuple[1].year, month=tuple[1].month) %}
+
+ {{ tuple[1].year }} |
+ {{ tuple[1]|date("E") }} |
+ {{ tuple[0] }} € |
+
+ {% endif %}
+ {% endfor %}
+ {% endfor %}
+
+
+{% endmacro %}
+
{% block title %}
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s account{% endtrans %}
{% endblock %}
@@ -10,90 +36,15 @@
{% trans %}Amount: {% endtrans %}{{ customer.amount }} €
{% if customer.refillings.exists() %}
{% trans %}Refillings{% endtrans %}
-
-
-
- {% trans %}Date{% endtrans %} |
- {% trans %}Counter{% endtrans %} |
- {% trans %}Barman{% endtrans %} |
- {% trans %}Amount{% endtrans %} |
- {% trans %}Payment method{% endtrans %} |
-
-
-
- {% for i in customer.refillings.order_by('-date').all() %}
-
- {{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }} |
- {{ i.counter }} |
- {{ i.operator.get_display_name() }} |
- {{ i.amount }} € |
- {{ i.get_payment_method_display() }} |
- {% if i.is_owned_by(user) %}
- Delete |
- {% endif %}
-
-{% endfor %}
-
-
+ {{ monthly(refilling_month) }}
{% endif %}
{% if customer.buyings.exists() %}
{% trans %}Account buyings{% endtrans %}
-
-
-
- {% trans %}Date{% endtrans %} |
- {% trans %}Counter{% endtrans %} |
- {% trans %}Barman{% endtrans %} |
- {% trans %}Label{% endtrans %} |
- {% trans %}Quantity{% endtrans %} |
- {% trans %}Total{% endtrans %} |
- {% trans %}Payment method{% endtrans %} |
-
-
-
- {% for i in customer.buyings.order_by('-date').all() %}
-
- {{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }} |
- {{ i.counter }} |
- {{ i.seller.get_display_name() }} |
- {{ i.label }} |
- {{ i.quantity }} |
- {{ i.quantity * i.unit_price }} € |
- {{ i.get_payment_method_display() }} |
- {% if i.is_owned_by(user) %}
- Delete |
- {% endif %}
-
-{% endfor %}
-
-
+ {{ monthly(buyings_month) }}
{% endif %}
{% if customer.user.invoices.exists() %}
{% trans %}Eboutic invoices{% endtrans %}
-
-
-
- {% trans %}Date{% endtrans %} |
- {% trans %}Items{% endtrans %} |
- {% trans %}Amount{% endtrans %} |
-
-
-
- {% for i in customer.user.invoices.order_by('-date').all() %}
-
- {{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }} |
-
-
- {% for it in i.items.all() %}
- - {{ it.quantity }} x {{ it.product_name }} - {{ it.product_unit_price }} €
- {% endfor %}
-
- |
- {{ i.get_total() }} € |
-
-{% endfor %}
-
-
+ {{ monthly(invoices_month) }}
{% endif %}
{% else %}
{% trans %}User has no account{% endtrans %}
diff --git a/core/templates/core/user_account_detail.jinja b/core/templates/core/user_account_detail.jinja
new file mode 100644
index 00000000..19748bd2
--- /dev/null
+++ b/core/templates/core/user_account_detail.jinja
@@ -0,0 +1,105 @@
+{% extends "core/base.jinja" %}
+
+{% block title %}
+{% trans user_name=profile.get_display_name() %}{{ user_name }}'s account{% endtrans %}
+{% endblock %}
+
+{% block content %}
+{% if customer %}
+{% trans %}User account{% endtrans %}
+{% trans %}Amount: {% endtrans %}{{ customer.amount }} €
+{% if customer.refillings.exists() %}
+{% trans %}Refillings{% endtrans %}
+
+
+
+ {% trans %}Date{% endtrans %} |
+ {% trans %}Counter{% endtrans %} |
+ {% trans %}Barman{% endtrans %} |
+ {% trans %}Amount{% endtrans %} |
+ {% trans %}Payment method{% endtrans %} |
+
+
+
+ {% for i in customer.refillings.order_by('-date').filter(
+ date__year=year, date__month=month) %}
+
+ {{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }} |
+ {{ i.counter }} |
+ {{ i.operator.get_display_name() }} |
+ {{ i.amount }} € |
+ {{ i.get_payment_method_display() }} |
+ {% if i.is_owned_by(user) %}
+ Delete |
+ {% endif %}
+
+{% endfor %}
+
+
+{% endif %}
+{% if customer.buyings.exists() %}
+{% trans %}Account buyings{% endtrans %}
+
+
+
+ {% trans %}Date{% endtrans %} |
+ {% trans %}Counter{% endtrans %} |
+ {% trans %}Barman{% endtrans %} |
+ {% trans %}Label{% endtrans %} |
+ {% trans %}Quantity{% endtrans %} |
+ {% trans %}Total{% endtrans %} |
+ {% trans %}Payment method{% endtrans %} |
+
+
+
+ {% for i in customer.buyings.order_by('-date').all().filter(
+ date__year=year, date__month=month) %}
+
+ {{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }} |
+ {{ i.counter }} |
+ {{ i.seller.get_display_name() }} |
+ {{ i.label }} |
+ {{ i.quantity }} |
+ {{ i.quantity * i.unit_price }} € |
+ {{ i.get_payment_method_display() }} |
+ {% if i.is_owned_by(user) %}
+ Delete |
+ {% endif %}
+
+{% endfor %}
+
+
+{% endif %}
+{% if customer.user.invoices.exists() %}
+{% trans %}Eboutic invoices{% endtrans %}
+
+
+
+ {% trans %}Date{% endtrans %} |
+ {% trans %}Items{% endtrans %} |
+ {% trans %}Amount{% endtrans %} |
+
+
+
+ {% for i in customer.user.invoices.order_by('-date').all().filter(
+ date__year=year, date__month=month) %}
+
+ {{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }} |
+
+
+ {% for it in i.items.all() %}
+ - {{ it.quantity }} x {{ it.product_name }} - {{ it.product_unit_price }} €
+ {% endfor %}
+
+ |
+ {{ i.get_total() }} € |
+
+{% endfor %}
+
+
+{% endif %}
+{% else %}
+{% trans %}User has no account{% endtrans %}
+{% endif %}
+Retour
+{% endblock %}
diff --git a/core/templates/core/user_detail.jinja b/core/templates/core/user_detail.jinja
index 55eb0870..8bf4075c 100644
--- a/core/templates/core/user_detail.jinja
+++ b/core/templates/core/user_detail.jinja
@@ -1,4 +1,5 @@
{% extends "core/base.jinja" %}
+{% from "core/macros.jinja" import show_slots, show_tokens %}
{% block title %}
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s profile{% endtrans %}
@@ -37,6 +38,11 @@
{{ profile.phone }}
{% endif %}
+ {% if profile.address %}
+
+ {{ profile.address }}
+
+ {% endif %}
{% if profile.promo %}
@@ -50,22 +56,19 @@
{# if the user is member of a club, he can view the subscription state #}
{% if get_subscriber(profile).is_subscribed() %}
-{% trans subscription_end=get_subscriber(profile).subscriptions.last().subscription_end %}Subscribed until {{ subscription_end }}{% endtrans %}
-{% trans %}Account number: {% endtrans %}{{ profile.customer.account_id }}
-{% if get_subscriber(profile).tokens.exists() %}
-
-{% for i in get_subscriber(profile).tokens.all() %}
- - {{ i }}
-{% endfor %}
-
-{% endif %}
+ {% trans subscription_end=get_subscriber(profile).subscriptions.last().subscription_end %}Subscribed until {{ subscription_end }}{% endtrans %}
+ {% trans %}Account number: {% endtrans %}{{ profile.customer.account_id }}
+ {# Shows tokens bought by the user #}
+ {{ show_tokens(profile) }}
+ {# Shows slots took by the user #}
+ {{ show_slots(profile) }}
{% else %}
-{% trans %}Not subscribed{% endtrans %}
-{% if user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) %}
-{% trans %}New subscription{% endtrans %}
-{% endif %}
-{% endif %}
-
+ {% trans %}Not subscribed{% endtrans %}
+ {% if user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) %}
+ {% trans %}New subscription{% endtrans %}
+ {% endif %}
+ {% endif %}
+
{% endif %}
{% endblock %}
diff --git a/core/urls.py b/core/urls.py
index baeae800..94767c20 100644
--- a/core/urls.py
+++ b/core/urls.py
@@ -37,6 +37,7 @@ urlpatterns = [
url(r'^user/(?P[0-9]+)/groups$', UserUpdateGroupView.as_view(), name='user_groups'),
url(r'^user/tools/$', UserToolsView.as_view(), name='user_tools'),
url(r'^user/(?P[0-9]+)/account$', UserAccountView.as_view(), name='user_account'),
+ url(r'^user/(?P[0-9]+)/account/(?P[0-9]+)/(?P[0-9]+)$', UserAccountDetailView.as_view(), name='user_account_detail'),
url(r'^user/(?P[0-9]+)/stats$', UserStatsView.as_view(), name='user_stats'),
# File views
diff --git a/core/views/user.py b/core/views/user.py
index a4d95ab7..522fbce7 100644
--- a/core/views/user.py
+++ b/core/views/user.py
@@ -11,8 +11,10 @@ from django.forms.models import modelform_factory
from django.forms import CheckboxSelectMultiple
from django.template.response import TemplateResponse
from django.conf import settings
+from django.views.generic.dates import YearMixin, MonthMixin
-from datetime import timedelta
+from django.utils import timezone
+from datetime import timedelta, datetime, date
import logging
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin
@@ -300,17 +302,17 @@ class UserToolsView(UserTabsMixin, TemplateView):
kwargs['object'] = self.request.user
return kwargs
-class UserAccountView(UserTabsMixin, DetailView):
+class UserAccountBase(UserTabsMixin, DetailView):
"""
- Display a user's account
+ Base class for UserAccount
"""
+
model = User
pk_url_kwarg = "user_id"
- template_name = "core/user_account.jinja"
current_tab = "account"
def dispatch(self, request, *arg, **kwargs): # Manually validates the rights
- res = super(UserAccountView, self).dispatch(request, *arg, **kwargs)
+ res = super(UserAccountBase, self).dispatch(request, *arg, **kwargs)
if (self.object == request.user
or request.user.is_in_group(settings.SITH_GROUPS['accounting-admin']['name'])
or request.user.is_in_group(settings.SITH_BAR_MANAGER['unix_name']+settings.SITH_BOARD_SUFFIX)
@@ -318,14 +320,78 @@ class UserAccountView(UserTabsMixin, DetailView):
return res
raise PermissionDenied
+class UserAccountView(UserAccountBase):
+ """
+ Display a user's account
+ """
+
+ template_name = "core/user_account.jinja"
+
+ def expense_by_month(self, obj, calc):
+ stats = []
+
+ for year in obj.datetimes('date', 'year', order='DESC'):
+ stats.append([])
+ i = 0
+ for month in obj.filter(date__year=year.year).datetimes(
+ 'date', 'month', order='DESC'):
+ q = obj.filter(
+ date__year=month.year,
+ date__month=month.month
+ )
+ stats[i].append((
+ sum([calc(p) for p in q]),
+ month
+ ))
+ i += 1
+
+ return stats
+
+ def invoices_calc(self, query):
+ t = 0
+ for it in query.items.all():
+ t += it.quantity * it.product_unit_price
+ return t
+
def get_context_data(self, **kwargs):
kwargs = super(UserAccountView, self).get_context_data(**kwargs)
kwargs['profile'] = self.object
try:
kwargs['customer'] = self.object.customer
+ kwargs['buyings_month'] = self.expense_by_month(
+ self.object.customer.buyings,
+ (lambda q: q.unit_price * q.quantity)
+ )
+ kwargs['invoices_month'] = self.expense_by_month(
+ self.object.customer.user.invoices,
+ self.invoices_calc
+ )
+ kwargs['refilling_month'] = self.expense_by_month(
+ self.object.customer.refillings,
+ (lambda q: q.amount)
+ )
except:
pass
# TODO: add list of month where account has activity
return kwargs
+
+class UserAccountDetailView(UserAccountBase, YearMixin, MonthMixin):
+ """
+ Display a user's account for month
+ """
+
+ template_name = "core/user_account_detail.jinja"
+
+ def get_context_data(self, **kwargs):
+ kwargs = super(UserAccountDetailView, self).get_context_data(**kwargs)
+ kwargs['profile'] = self.object
+ kwargs['year'] = self.get_year()
+ kwargs['month'] = self.get_month()
+ try:
+ kwargs['customer'] = self.object.customer
+ except:
+ pass
+ kwargs['tab'] = "account"
+ return kwargs
diff --git a/launderette/templates/launderette/launderette_book.jinja b/launderette/templates/launderette/launderette_book.jinja
index 6eca751a..5f3e9bc2 100644
--- a/launderette/templates/launderette/launderette_book.jinja
+++ b/launderette/templates/launderette/launderette_book.jinja
@@ -1,4 +1,5 @@
{% extends "core/base.jinja" %}
+{% from "core/macros.jinja" import show_slots, show_tokens %}
{% block title %}
{% trans %}Launderette{% endtrans %}
@@ -52,10 +53,6 @@
{% endfor %}
+{{ show_slots(user) }}
+{{ show_tokens(user) }}
{% endblock %}
-
-
-
-
-
-
diff --git a/requirements.txt b/requirements.txt
index f414561d..e9438558 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,3 +7,5 @@ pyopenssl
pytz
djangorestframework
django-phonenumber-field
+django-ajax-selects
+mysqlclient