mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-25 02:24:26 +00:00
Nice user interface and permission rework
This commit is contained in:
parent
4669e5a4e9
commit
616b7ccfc8
@ -22,6 +22,24 @@
|
|||||||
<p>{% trans trombi=user.trombi_user.trombi %}You already choose to be in that Trombi: {{ trombi }}.{% endtrans %}
|
<p>{% trans trombi=user.trombi_user.trombi %}You already choose to be in that Trombi: {{ trombi }}.{% endtrans %}
|
||||||
<a href="{{ url('trombi:user_tools') }}">{% trans %}Go to my Trombi tools{% endtrans %}</a></p>
|
<a href="{{ url('trombi:user_tools') }}">{% trans %}Go to my Trombi tools{% endtrans %}</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if profile.customer %}
|
||||||
|
<h4>{% trans %}Student cards{% endtrans %}</h4>
|
||||||
|
<p>{% trans %}You can add a card by asking at a counter or add it yourself here. If you want to manually add a student card yourself, you'll need a NFC reader. We store the UID of the card which is 14 characters long.{% endtrans %}</p>
|
||||||
|
<form action="{{ url('counter:add_student_card', customer_id=profile.customer.pk) }}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ student_card_form.as_p() }}
|
||||||
|
<p><input type="submit" value="{% trans %}Save{% endtrans %}" /></p>
|
||||||
|
</form>
|
||||||
|
{% if profile.customer.student_cards.exists() %}
|
||||||
|
<ul>
|
||||||
|
{% for card in profile.customer.student_cards.all() %}
|
||||||
|
<li>{{ card.uid }} - <a href="{{ url('counter:delete_student_card', customer_id=profile.customer.pk, card_id=card.id) }}">{% trans %}Delete{% endtrans %}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
<p>{% trans %}No student cards registered.{% endtrans %}</p>
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ from core.views.forms import (
|
|||||||
)
|
)
|
||||||
from core.models import User, SithFile, Preferences, Gift
|
from core.models import User, SithFile, Preferences, Gift
|
||||||
from subscription.models import Subscription
|
from subscription.models import Subscription
|
||||||
|
from counter.views import StudentCardForm
|
||||||
from trombi.views import UserTrombiForm
|
from trombi.views import UserTrombiForm
|
||||||
|
|
||||||
|
|
||||||
@ -741,6 +742,8 @@ class UserPreferencesView(UserTabsMixin, CanEditMixin, UpdateView):
|
|||||||
kwargs = super(UserPreferencesView, self).get_context_data(**kwargs)
|
kwargs = super(UserPreferencesView, self).get_context_data(**kwargs)
|
||||||
if not hasattr(self.object, "trombi_user"):
|
if not hasattr(self.object, "trombi_user"):
|
||||||
kwargs["trombi_form"] = UserTrombiForm()
|
kwargs["trombi_form"] = UserTrombiForm()
|
||||||
|
if self.object.customer:
|
||||||
|
kwargs["student_card_form"] = StudentCardForm()
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
|
@ -91,22 +91,7 @@ class Customer(models.Model):
|
|||||||
"""
|
"""
|
||||||
Add a new student card on the customer account
|
Add a new student card on the customer account
|
||||||
"""
|
"""
|
||||||
# If you are comming from a counter, only your connection to the counter is checked, not your right on the user to avoid wierd conflicts
|
if not StudentCard.check_creation_permission(request, self, counter):
|
||||||
if counter != None and (
|
|
||||||
counter.type != "BAR"
|
|
||||||
or not (
|
|
||||||
"counter_token" in request.session.keys()
|
|
||||||
and request.session["counter_token"] == counter.token
|
|
||||||
)
|
|
||||||
or len(counter.get_barmen_list()) < 1
|
|
||||||
):
|
|
||||||
raise PermissionDenied
|
|
||||||
# If you are not comming from a counter, your permissions are checked
|
|
||||||
if not (
|
|
||||||
request.user.id == self.user.id
|
|
||||||
or request.user.is_board_member
|
|
||||||
or request.user.is_root
|
|
||||||
):
|
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
StudentCard(customer=self, uid=uid).save()
|
StudentCard(customer=self, uid=uid).save()
|
||||||
|
|
||||||
@ -769,6 +754,38 @@ class StudentCard(models.Model):
|
|||||||
|
|
||||||
UID_SIZE = 14
|
UID_SIZE = 14
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_valid(uid):
|
||||||
|
return len(uid) == StudentCard.UID_SIZE
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __comming_from_right_counter(request, counter):
|
||||||
|
return (
|
||||||
|
counter.type == "BAR"
|
||||||
|
and "counter_token" in request.session.keys()
|
||||||
|
and request.session["counter_token"] == counter.token
|
||||||
|
and len(counter.get_barmen_list()) > 0
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def __user_has_rights(customer, user):
|
||||||
|
return user.pk == customer.user.pk or user.is_board_member or user.is_root
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def check_creation_permission(request, customer, counter=None):
|
||||||
|
"""
|
||||||
|
If you are comming from a counter, only your connection to the counter is checked, not your right on the user to avoid wierd conflicts
|
||||||
|
If you are not comming from a counter, your permissions are checked
|
||||||
|
"""
|
||||||
|
if counter:
|
||||||
|
return StudentCard.__comming_from_right_counter(request, counter)
|
||||||
|
return StudentCard.__user_has_rights(customer, request.user)
|
||||||
|
|
||||||
|
def can_edit(self, obj):
|
||||||
|
if isinstance(obj, User):
|
||||||
|
return StudentCard.__user_has_rights(self.customer, obj)
|
||||||
|
return False
|
||||||
|
|
||||||
uid = models.CharField(
|
uid = models.CharField(
|
||||||
_("uid"), max_length=14, unique=True, validators=[MinLengthValidator(4)]
|
_("uid"), max_length=14, unique=True, validators=[MinLengthValidator(4)]
|
||||||
)
|
)
|
||||||
|
@ -40,6 +40,16 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<input type="submit" value="{% trans %}Go{% endtrans %}" />
|
<input type="submit" value="{% trans %}Go{% endtrans %}" />
|
||||||
</form>
|
</form>
|
||||||
|
<h6>{% trans %}Registered cards{% endtrans %}</h6>
|
||||||
|
{% if customer.student_cards.exists() %}
|
||||||
|
<ul>
|
||||||
|
{% for card in customer.student_cards.all() %}
|
||||||
|
<li>{{ card.uid }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% else %}
|
||||||
|
{% trans %}No card registered{% endtrans %}
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div id="bar_ui">
|
<div id="bar_ui">
|
||||||
<h5>{% trans %}Selling{% endtrans %}</h5>
|
<h5>{% trans %}Selling{% endtrans %}</h5>
|
||||||
|
@ -56,6 +56,16 @@ urlpatterns = [
|
|||||||
EticketPDFView.as_view(),
|
EticketPDFView.as_view(),
|
||||||
name="eticket_pdf",
|
name="eticket_pdf",
|
||||||
),
|
),
|
||||||
|
url(
|
||||||
|
r"^customer/(?P<customer_id>[0-9]+)/card/add$",
|
||||||
|
StudentCardFormView.as_view(),
|
||||||
|
name="add_student_card",
|
||||||
|
),
|
||||||
|
url(
|
||||||
|
r"^customer/(?P<customer_id>[0-9]+)/card/delete/(?P<card_id>[0-9]+)/$",
|
||||||
|
StudentCardDeleteView.as_view(),
|
||||||
|
name="delete_student_card",
|
||||||
|
),
|
||||||
url(r"^admin/(?P<counter_id>[0-9]+)$", CounterEditView.as_view(), name="admin"),
|
url(r"^admin/(?P<counter_id>[0-9]+)$", CounterEditView.as_view(), name="admin"),
|
||||||
url(
|
url(
|
||||||
r"^admin/(?P<counter_id>[0-9]+)/prop$",
|
r"^admin/(?P<counter_id>[0-9]+)/prop$",
|
||||||
|
@ -33,6 +33,7 @@ from django.views.generic.edit import (
|
|||||||
DeleteView,
|
DeleteView,
|
||||||
ProcessFormView,
|
ProcessFormView,
|
||||||
FormMixin,
|
FormMixin,
|
||||||
|
FormView,
|
||||||
)
|
)
|
||||||
from django.forms.models import modelform_factory
|
from django.forms.models import modelform_factory
|
||||||
from django.forms import CheckboxSelectMultiple
|
from django.forms import CheckboxSelectMultiple
|
||||||
@ -50,7 +51,7 @@ from datetime import date, timedelta, datetime
|
|||||||
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
|
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
|
||||||
from ajax_select import make_ajax_field
|
from ajax_select import make_ajax_field
|
||||||
|
|
||||||
from core.views import CanViewMixin, TabedViewMixin
|
from core.views import CanViewMixin, TabedViewMixin, CanEditMixin
|
||||||
from core.views.forms import LoginForm, SelectDate, SelectDateTime
|
from core.views.forms import LoginForm, SelectDate, SelectDateTime
|
||||||
from core.models import User
|
from core.models import User
|
||||||
from subscription.models import Subscription
|
from subscription.models import Subscription
|
||||||
@ -100,6 +101,45 @@ class CounterAdminMixin(View):
|
|||||||
return super(CounterAdminMixin, self).dispatch(request, *args, **kwargs)
|
return super(CounterAdminMixin, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class StudentCardForm(forms.ModelForm):
|
||||||
|
"""
|
||||||
|
Form for adding student cards
|
||||||
|
Only used for user profile since CounterClick is to complicated
|
||||||
|
"""
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = StudentCard
|
||||||
|
fields = ["uid"]
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
cleaned_data = super(StudentCardForm, self).clean()
|
||||||
|
uid = cleaned_data.get("uid")
|
||||||
|
if not StudentCard.is_valid(uid):
|
||||||
|
raise forms.ValidationError(_("This uid is invalid"), code="invalid")
|
||||||
|
return cleaned_data
|
||||||
|
|
||||||
|
|
||||||
|
class StudentCardDeleteView(DeleteView):
|
||||||
|
"""
|
||||||
|
View used to delete a card from a user
|
||||||
|
"""
|
||||||
|
|
||||||
|
model = StudentCard
|
||||||
|
template_name = "core/delete_confirm.jinja"
|
||||||
|
pk_url_kwarg = "card_id"
|
||||||
|
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
self.customer = get_object_or_404(Customer, pk=kwargs["customer_id"])
|
||||||
|
if not self.get_object().can_edit(self.customer.user):
|
||||||
|
raise PermissionDenied
|
||||||
|
return super(StudentCardDeleteView, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_success_url(self, **kwargs):
|
||||||
|
return reverse_lazy(
|
||||||
|
"core:user_prefs", kwargs={"user_id": self.customer.user.pk}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class GetUserForm(forms.Form):
|
class GetUserForm(forms.Form):
|
||||||
"""
|
"""
|
||||||
The Form class aims at providing a valid user_id field in its cleaned data, in order to pass it to some view,
|
The Form class aims at providing a valid user_id field in its cleaned data, in order to pass it to some view,
|
||||||
@ -109,7 +149,9 @@ class GetUserForm(forms.Form):
|
|||||||
some nickname, first name, or last name (TODO)
|
some nickname, first name, or last name (TODO)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
code = forms.CharField(label="Code", max_length=10, required=False)
|
code = forms.CharField(
|
||||||
|
label="Code", max_length=StudentCard.UID_SIZE, required=False
|
||||||
|
)
|
||||||
id = AutoCompleteSelectField(
|
id = AutoCompleteSelectField(
|
||||||
"users", required=False, label=_("Select user"), help_text=None
|
"users", required=False, label=_("Select user"), help_text=None
|
||||||
)
|
)
|
||||||
@ -534,7 +576,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
|
|||||||
"""
|
"""
|
||||||
uid = request.POST["student_card_uid"]
|
uid = request.POST["student_card_uid"]
|
||||||
uid = str(uid)
|
uid = str(uid)
|
||||||
if len(uid) != StudentCard.UID_SIZE:
|
if not StudentCard.is_valid(uid):
|
||||||
request.session["not_valid_student_card_uid"] = True
|
request.session["not_valid_student_card_uid"] = True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@ -1788,3 +1830,27 @@ class CounterRefillingListView(CounterAdminTabsMixin, CounterAdminMixin, ListVie
|
|||||||
kwargs = super(CounterRefillingListView, self).get_context_data(**kwargs)
|
kwargs = super(CounterRefillingListView, self).get_context_data(**kwargs)
|
||||||
kwargs["counter"] = self.counter
|
kwargs["counter"] = self.counter
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
|
|
||||||
|
class StudentCardFormView(FormView):
|
||||||
|
"""
|
||||||
|
Add a new student card
|
||||||
|
"""
|
||||||
|
|
||||||
|
form_class = StudentCardForm
|
||||||
|
template_name = "core/create.jinja"
|
||||||
|
|
||||||
|
def dispatch(self, request, *args, **kwargs):
|
||||||
|
self.customer = get_object_or_404(Customer, pk=kwargs["customer_id"])
|
||||||
|
return super(StudentCardFormView, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
data = form.clean()
|
||||||
|
res = super(FormView, self).form_valid(form)
|
||||||
|
self.customer.add_student_card(data["uid"], self.request)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def get_success_url(self, **kwargs):
|
||||||
|
return reverse_lazy(
|
||||||
|
"core:user_prefs", kwargs={"user_id": self.customer.user.pk}
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user