Merge branch 'sli'

This commit is contained in:
Skia 2016-09-09 19:56:48 +02:00
commit 5e26e5bde7
9 changed files with 260 additions and 107 deletions

View File

@ -1,14 +1,20 @@
from rest_framework.response import Response 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 from core.templatetags.renderer import markdown
@api_view(['GET']) @api_view(['GET'])
@renderer_classes((StaticHTMLRenderer,))
def RenderMarkdown(request): def RenderMarkdown(request):
""" """
Render Markdown Render Markdown
""" """
if request.method == 'GET': try:
return Response(markdown(request.GET['text'])) data = markdown(request.GET['text'])
except:
data = 'Error'
return Response(data)

View File

@ -33,3 +33,25 @@
</div> </div>
</div> </div>
{%- endmacro %} {%- endmacro %}
{% macro show_slots(user) %}
{% if get_subscriber(user).slots.exists() %}
<h5>{% trans %}Slot{% endtrans %}</h5>
<ul>
{% for i in get_subscriber(user).slots.all() %}
<li>{{ i.get_type_display() }} - {{i.machine.launderette }}, {{ i.start_date|localtime|date("l j") }} : {{ i.start_date|localtime|time(DATETIME_FORMAT) }}</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
{% macro show_tokens(user) %}
{% if get_subscriber(user).tokens.exists() %}
<h5>{% trans %}Tokens{% endtrans %}</h5>
<ul>
{% for i in get_subscriber(user).tokens.all() %}
<li>{{ i }}</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}

View File

@ -1,5 +1,31 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% macro monthly(obj) %}
<table>
<thead>
<tr>
<td>{% trans %}Year{% endtrans %}</td>
<td>{% trans %}Month{% endtrans %}</td>
<td>{% trans %}Total{% endtrans %}</td>
</tr>
</thead>
<tbody>
{% 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) %}
<tr>
<td><a href="{{ link }}">{{ tuple[1].year }}</a></td>
<td><a href="{{ link }}">{{ tuple[1]|date("E") }}</a></td>
<td><a href="{{ link }}">{{ tuple[0] }} €</a></td>
</tr>
{% endif %}
{% endfor %}
{% endfor %}
</tbody>
</table>
{% endmacro %}
{% block title %} {% block title %}
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s account{% endtrans %} {% trans user_name=profile.get_display_name() %}{{ user_name }}'s account{% endtrans %}
{% endblock %} {% endblock %}
@ -10,90 +36,15 @@
<p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p> <p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p>
{% if customer.refillings.exists() %} {% if customer.refillings.exists() %}
<h4>{% trans %}Refillings{% endtrans %}</h4> <h4>{% trans %}Refillings{% endtrans %}</h4>
<table> {{ monthly(refilling_month) }}
<thead>
<tr>
<td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Counter{% endtrans %}</td>
<td>{% trans %}Barman{% endtrans %}</td>
<td>{% trans %}Amount{% endtrans %}</td>
<td>{% trans %}Payment method{% endtrans %}</td>
</tr>
</thead>
<tbody>
{% for i in customer.refillings.order_by('-date').all() %}
<tr>
<td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td>
<td>{{ i.counter }}</td>
<td><a href="{{ i.operator.get_absolute_url() }}">{{ i.operator.get_display_name() }}</a></td>
<td>{{ i.amount }} €</td>
<td>{{ i.get_payment_method_display() }}</td>
{% if i.is_owned_by(user) %}
<td><a href="{{ url('counter:refilling_delete', refilling_id=i.id) }}">Delete</a></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %} {% endif %}
{% if customer.buyings.exists() %} {% if customer.buyings.exists() %}
<h4>{% trans %}Account buyings{% endtrans %}</h4> <h4>{% trans %}Account buyings{% endtrans %}</h4>
<table> {{ monthly(buyings_month) }}
<thead>
<tr>
<td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Counter{% endtrans %}</td>
<td>{% trans %}Barman{% endtrans %}</td>
<td>{% trans %}Label{% endtrans %}</td>
<td>{% trans %}Quantity{% endtrans %}</td>
<td>{% trans %}Total{% endtrans %}</td>
<td>{% trans %}Payment method{% endtrans %}</td>
</tr>
</thead>
<tbody>
{% for i in customer.buyings.order_by('-date').all() %}
<tr>
<td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td>
<td>{{ i.counter }}</td>
<td><a href="{{ i.seller.get_absolute_url() }}">{{ i.seller.get_display_name() }}</a></td>
<td>{{ i.label }}</td>
<td>{{ i.quantity }}</td>
<td>{{ i.quantity * i.unit_price }} €</td>
<td>{{ i.get_payment_method_display() }}</td>
{% if i.is_owned_by(user) %}
<td><a href="{{ url('counter:selling_delete', selling_id=i.id) }}">Delete</a></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %} {% endif %}
{% if customer.user.invoices.exists() %} {% if customer.user.invoices.exists() %}
<h4>{% trans %}Eboutic invoices{% endtrans %}</h4> <h4>{% trans %}Eboutic invoices{% endtrans %}</h4>
<table> {{ monthly(invoices_month) }}
<thead>
<tr>
<td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Items{% endtrans %}</td>
<td>{% trans %}Amount{% endtrans %}</td>
</tr>
</thead>
<tbody>
{% for i in customer.user.invoices.order_by('-date').all() %}
<tr>
<td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td>
<td>
<ul>
{% for it in i.items.all() %}
<li>{{ it.quantity }} x {{ it.product_name }} - {{ it.product_unit_price }} €</li>
{% endfor %}
</ul>
</td>
<td>{{ i.get_total() }} €</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %} {% endif %}
{% else %} {% else %}
<p>{% trans %}User has no account{% endtrans %}</p> <p>{% trans %}User has no account{% endtrans %}</p>

View File

@ -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 %}
<h3>{% trans %}User account{% endtrans %}</h3>
<p>{% trans %}Amount: {% endtrans %}{{ customer.amount }} €</p>
{% if customer.refillings.exists() %}
<h4>{% trans %}Refillings{% endtrans %}</h4>
<table>
<thead>
<tr>
<td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Counter{% endtrans %}</td>
<td>{% trans %}Barman{% endtrans %}</td>
<td>{% trans %}Amount{% endtrans %}</td>
<td>{% trans %}Payment method{% endtrans %}</td>
</tr>
</thead>
<tbody>
{% for i in customer.refillings.order_by('-date').filter(
date__year=year, date__month=month) %}
<tr>
<td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td>
<td>{{ i.counter }}</td>
<td><a href="{{ i.operator.get_absolute_url() }}">{{ i.operator.get_display_name() }}</a></td>
<td>{{ i.amount }} €</td>
<td>{{ i.get_payment_method_display() }}</td>
{% if i.is_owned_by(user) %}
<td><a href="{{ url('counter:refilling_delete', refilling_id=i.id) }}">Delete</a></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% if customer.buyings.exists() %}
<h4>{% trans %}Account buyings{% endtrans %}</h4>
<table>
<thead>
<tr>
<td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Counter{% endtrans %}</td>
<td>{% trans %}Barman{% endtrans %}</td>
<td>{% trans %}Label{% endtrans %}</td>
<td>{% trans %}Quantity{% endtrans %}</td>
<td>{% trans %}Total{% endtrans %}</td>
<td>{% trans %}Payment method{% endtrans %}</td>
</tr>
</thead>
<tbody>
{% for i in customer.buyings.order_by('-date').all().filter(
date__year=year, date__month=month) %}
<tr>
<td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td>
<td>{{ i.counter }}</td>
<td><a href="{{ i.seller.get_absolute_url() }}">{{ i.seller.get_display_name() }}</a></td>
<td>{{ i.label }}</td>
<td>{{ i.quantity }}</td>
<td>{{ i.quantity * i.unit_price }} €</td>
<td>{{ i.get_payment_method_display() }}</td>
{% if i.is_owned_by(user) %}
<td><a href="{{ url('counter:selling_delete', selling_id=i.id) }}">Delete</a></td>
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% if customer.user.invoices.exists() %}
<h4>{% trans %}Eboutic invoices{% endtrans %}</h4>
<table>
<thead>
<tr>
<td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Items{% endtrans %}</td>
<td>{% trans %}Amount{% endtrans %}</td>
</tr>
</thead>
<tbody>
{% for i in customer.user.invoices.order_by('-date').all().filter(
date__year=year, date__month=month) %}
<tr>
<td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td>
<td>
<ul>
{% for it in i.items.all() %}
<li>{{ it.quantity }} x {{ it.product_name }} - {{ it.product_unit_price }} €</li>
{% endfor %}
</ul>
</td>
<td>{{ i.get_total() }} €</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
{% else %}
<p>{% trans %}User has no account{% endtrans %}</p>
{% endif %}
<p><a href="{{ url('core:user_account', user_id=profile.id) }}">Retour</a></p>
{% endblock %}

View File

@ -1,4 +1,5 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% from "core/macros.jinja" import show_slots, show_tokens %}
{% block title %} {% block title %}
{% trans user_name=profile.get_display_name() %}{{ user_name }}'s profile{% endtrans %} {% trans user_name=profile.get_display_name() %}{{ user_name }}'s profile{% endtrans %}
@ -37,6 +38,11 @@
{{ profile.phone }} {{ profile.phone }}
</p> </p>
{% endif %} {% endif %}
{% if profile.address %}
<p>
{{ profile.address }}
</p>
{% endif %}
</p> </p>
{% if profile.promo %} {% if profile.promo %}
<p><img src="{{ static('core/img/promo_%02d.png' % profile.promo) }}" alt="Promo {{ profile.promo }}" class="promo_pict" /> <p><img src="{{ static('core/img/promo_%02d.png' % profile.promo) }}" alt="Promo {{ profile.promo }}" class="promo_pict" />
@ -52,13 +58,10 @@
{% if get_subscriber(profile).is_subscribed() %} {% if get_subscriber(profile).is_subscribed() %}
{% trans subscription_end=get_subscriber(profile).subscriptions.last().subscription_end %}Subscribed until {{ subscription_end }}{% endtrans %}<br/> {% trans subscription_end=get_subscriber(profile).subscriptions.last().subscription_end %}Subscribed until {{ subscription_end }}{% endtrans %}<br/>
{% trans %}Account number: {% endtrans %}{{ profile.customer.account_id }}<br/> {% trans %}Account number: {% endtrans %}{{ profile.customer.account_id }}<br/>
{% if get_subscriber(profile).tokens.exists() %} {# Shows tokens bought by the user #}
<ul> {{ show_tokens(profile) }}
{% for i in get_subscriber(profile).tokens.all() %} {# Shows slots took by the user #}
<li>{{ i }}</li> {{ show_slots(profile) }}
{% endfor %}
</ul>
{% endif %}
{% else %} {% else %}
{% trans %}Not subscribed{% endtrans %} {% trans %}Not subscribed{% endtrans %}
{% if user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) %} {% if user.is_in_group(settings.SITH_MAIN_BOARD_GROUP) %}

View File

@ -37,6 +37,7 @@ urlpatterns = [
url(r'^user/(?P<user_id>[0-9]+)/groups$', UserUpdateGroupView.as_view(), name='user_groups'), url(r'^user/(?P<user_id>[0-9]+)/groups$', UserUpdateGroupView.as_view(), name='user_groups'),
url(r'^user/tools/$', UserToolsView.as_view(), name='user_tools'), url(r'^user/tools/$', UserToolsView.as_view(), name='user_tools'),
url(r'^user/(?P<user_id>[0-9]+)/account$', UserAccountView.as_view(), name='user_account'), url(r'^user/(?P<user_id>[0-9]+)/account$', UserAccountView.as_view(), name='user_account'),
url(r'^user/(?P<user_id>[0-9]+)/account/(?P<year>[0-9]+)/(?P<month>[0-9]+)$', UserAccountDetailView.as_view(), name='user_account_detail'),
url(r'^user/(?P<user_id>[0-9]+)/stats$', UserStatsView.as_view(), name='user_stats'), url(r'^user/(?P<user_id>[0-9]+)/stats$', UserStatsView.as_view(), name='user_stats'),
# File views # File views

View File

@ -11,8 +11,10 @@ from django.forms.models import modelform_factory
from django.forms import CheckboxSelectMultiple from django.forms import CheckboxSelectMultiple
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.conf import settings 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 import logging
from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin from core.views import CanViewMixin, CanEditMixin, CanEditPropMixin, TabedViewMixin
@ -300,17 +302,17 @@ class UserToolsView(UserTabsMixin, TemplateView):
kwargs['object'] = self.request.user kwargs['object'] = self.request.user
return kwargs return kwargs
class UserAccountView(UserTabsMixin, DetailView): class UserAccountBase(UserTabsMixin, DetailView):
""" """
Display a user's account Base class for UserAccount
""" """
model = User model = User
pk_url_kwarg = "user_id" pk_url_kwarg = "user_id"
template_name = "core/user_account.jinja"
current_tab = "account" current_tab = "account"
def dispatch(self, request, *arg, **kwargs): # Manually validates the rights 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 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_GROUPS['accounting-admin']['name'])
or request.user.is_in_group(settings.SITH_BAR_MANAGER['unix_name']+settings.SITH_BOARD_SUFFIX) 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 return res
raise PermissionDenied 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): def get_context_data(self, **kwargs):
kwargs = super(UserAccountView, self).get_context_data(**kwargs) kwargs = super(UserAccountView, self).get_context_data(**kwargs)
kwargs['profile'] = self.object kwargs['profile'] = self.object
try: try:
kwargs['customer'] = self.object.customer 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: except:
pass pass
# TODO: add list of month where account has activity # TODO: add list of month where account has activity
return kwargs 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

View File

@ -1,4 +1,5 @@
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% from "core/macros.jinja" import show_slots, show_tokens %}
{% block title %} {% block title %}
{% trans %}Launderette{% endtrans %} {% trans %}Launderette{% endtrans %}
@ -52,10 +53,6 @@
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{{ show_slots(user) }}
{{ show_tokens(user) }}
{% endblock %} {% endblock %}

View File

@ -7,3 +7,5 @@ pyopenssl
pytz pytz
djangorestframework djangorestframework
django-phonenumber-field django-phonenumber-field
django-ajax-selects
mysqlclient