Make StudentCardFormView fragment only

This commit is contained in:
Antoine Bartuccio 2024-12-07 17:28:34 +01:00
parent b81cf49d0a
commit d4b9c3afb1
8 changed files with 234 additions and 188 deletions

View File

@ -38,32 +38,17 @@
{% if profile.customer %} {% if profile.customer %}
<h3>{% trans %}Student cards{% endtrans %}</h3> <h3>{% trans %}Student cards{% endtrans %}</h3>
{% if profile.customer.student_cards.exists() %} <p class="justify">
<ul class="student-cards"> {% trans %}You can add a card by asking at a counter or add it yourself here. If you want to manually
{% for card in profile.customer.student_cards.all() %} add a student card yourself, you'll need a NFC reader. We store the UID of the card which is 14 characters long.{% endtrans %}
<li> </p>
{{ card.uid }} <div
&nbsp;-&nbsp; hx-get="{{ url('counter:add_student_card', customer_id=profile.customer.pk) }}"
<a href="{{ url('counter:delete_student_card', customer_id=profile.customer.pk, card_id=card.id) }}"> hx-trigger="load"
{% trans %}Delete{% endtrans %} hx-swap="outerHTML"
</a> >
</li> <div aria-busy="true" style="min-height: 100px;"></div>
{% endfor %} </div>
</ul>
{% else %}
<em class="no-cards">{% trans %}No student card registered.{% endtrans %}</em>
<p class="justify">
{% 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>
{% endif %}
<form class="form form-cards" action="{{ url('counter:add_student_card', customer_id=profile.customer.pk) }}"
method="post">
{% csrf_token %}
{{ student_card_form.as_p() }}
<input class="form-submit-btn" type="submit" value="{% trans %}Save{% endtrans %}" />
</form>
{% endif %} {% endif %}
</div> </div>
{% endblock %} {% endblock %}

View File

@ -70,7 +70,6 @@ from core.views.forms import (
UserGodfathersForm, UserGodfathersForm,
UserProfileForm, UserProfileForm,
) )
from counter.forms import StudentCardForm
from counter.models import Refilling, Selling from counter.models import Refilling, Selling
from eboutic.models import Invoice from eboutic.models import Invoice
from subscription.models import Subscription from subscription.models import Subscription
@ -576,9 +575,6 @@ class UserPreferencesView(UserTabsMixin, CanEditMixin, UpdateView):
hasattr(self.object, "trombi_user") and self.request.user.trombi_user.trombi hasattr(self.object, "trombi_user") and self.request.user.trombi_user.trombi
): ):
kwargs["trombi_form"] = UserTrombiForm() kwargs["trombi_form"] = UserTrombiForm()
if hasattr(self.object, "customer"):
kwargs["student_card_form"] = StudentCardForm()
return kwargs return kwargs

View File

@ -32,7 +32,7 @@
{% if counter.type == 'BAR' %} {% if counter.type == 'BAR' %}
<div <div
hx-get="{{ url('counter:add_student_card_fragment', counter_id=counter.id, customer_id=customer.pk) }}" hx-get="{{ url('counter:add_student_card', customer_id=customer.pk) }}"
hx-trigger="load" hx-trigger="load"
hx-swap="outerHTML" hx-swap="outerHTML"
> >

View File

@ -1,7 +1,6 @@
<div id="student_card_form"> <div id="student_card_form">
<h3>{% trans %}Add a student card{% endtrans %}</h3> <h3>{% trans %}Add a student card{% endtrans %}</h3>
<form <form
hx-trigger="submit"
hx-post="{{ action }}" hx-post="{{ action }}"
hx-swap="outerHTML" hx-swap="outerHTML"
hx-target="#student_card_form" hx-target="#student_card_form"
@ -16,10 +15,15 @@
<ul> <ul>
{% for card in student_cards %} {% for card in student_cards %}
<li>{{ card.uid }}</li> <li>
{{ card.uid }}
<a href="{{ url('counter:delete_student_card', customer_id=customer.pk, card_id=card.id) }}">
{% trans %}Delete{% endtrans %}
</a>
</li>
{% endfor %} {% endfor %}
</ul> </ul>
{% else %} {% else %}
{% trans %}No card registered{% endtrans %} <em class="no-cards">{% trans %}No student card registered.{% endtrans %}</em>
{% endif %} {% endif %}
</div> </div>

View File

@ -1,15 +1,27 @@
import json import json
import string import string
from datetime import timedelta
import pytest import pytest
from django.conf import settings
from django.contrib.auth.base_user import make_password
from django.test import Client, TestCase from django.test import Client, TestCase
from django.urls import reverse from django.urls import reverse
from django.utils.timezone import now
from model_bakery import baker from model_bakery import baker
from core.baker_recipes import subscriber_user from club.models import Membership
from core.baker_recipes import board_user, subscriber_user
from core.models import User from core.models import User
from counter.baker_recipes import refill_recipe, sale_recipe from counter.baker_recipes import refill_recipe, sale_recipe
from counter.models import BillingInfo, Counter, Customer, Refilling, Selling from counter.models import (
BillingInfo,
Counter,
Customer,
Refilling,
Selling,
StudentCard,
)
@pytest.mark.django_db @pytest.mark.django_db
@ -162,43 +174,65 @@ class TestStudentCard(TestCase):
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
cls.krophil = User.objects.get(username="krophil") cls.customer = subscriber_user.make()
cls.sli = User.objects.get(username="sli") cls.customer.save()
cls.skia = User.objects.get(username="skia") cls.barmen = subscriber_user.make(password=make_password("plop"))
cls.root = User.objects.get(username="root") cls.board_admin = board_user.make()
cls.club_admin = baker.make(User)
cls.root = baker.make(User, is_superuser=True)
cls.subscriber = subscriber_user.make()
cls.counter = Counter.objects.get(id=2) cls.counter = baker.make(Counter, type="BAR")
cls.ae_counter = Counter.objects.get(name="AE") cls.counter.sellers.add(cls.barmen)
cls.club_counter = baker.make(Counter)
baker.make(
Membership,
start_date=now() - timedelta(days=30),
club=cls.club_counter.club,
role=settings.SITH_CLUB_ROLES_ID["Board member"],
user=cls.club_admin,
)
cls.valid_card = baker.make(
StudentCard, customer=cls.customer.customer, uid="8A89B82018B0A0"
)
def setUp(self): def setUp(self):
# Auto login on counter # Auto login on counter
self.client.post( self.client.post(
reverse("counter:login", args=[self.counter.id]), reverse("counter:login", args=[self.counter.id]),
{"username": "krophil", "password": "plop"}, {"username": self.barmen.username, "password": "plop"},
) )
def test_search_user_with_student_card(self): def test_search_user_with_student_card(self):
response = self.client.post( response = self.client.post(
reverse("counter:details", args=[self.counter.id]), reverse("counter:details", args=[self.counter.id]),
{"code": "9A89B82018B0A0"}, {"code": self.valid_card.uid},
) )
assert response.url == reverse( assert response.url == reverse(
"counter:click", "counter:click",
kwargs={"counter_id": self.counter.id, "user_id": self.sli.id}, kwargs={"counter_id": self.counter.id, "user_id": self.customer.id},
) )
def test_add_student_card_from_counter(self): def test_add_student_card_from_counter(self):
# Test card with mixed letters and numbers # Test card with mixed letters and numbers
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card_fragment", "counter:add_student_card",
kwargs={ kwargs={
"counter_id": self.counter.id, "customer_id": self.customer.customer.pk,
"customer_id": self.sli.customer.pk,
}, },
), ),
{"uid": "8B90734A802A8F"}, {"uid": "8B90734A802A8F"},
HTTP_REFERER=reverse(
"counter:click",
kwargs={
"counter_id": self.counter.id,
"user_id": self.customer.customer.pk,
},
),
) )
assert response.status_code == 302 assert response.status_code == 302
self.assertContains(self.client.get(response.url), text="8B90734A802A8F") self.assertContains(self.client.get(response.url), text="8B90734A802A8F")
@ -206,13 +240,19 @@ class TestStudentCard(TestCase):
# Test card with only numbers # Test card with only numbers
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card_fragment", "counter:add_student_card",
kwargs={ kwargs={
"counter_id": self.counter.id, "customer_id": self.customer.customer.pk,
"customer_id": self.sli.customer.pk,
}, },
), ),
{"uid": "04786547890123"}, {"uid": "04786547890123"},
HTTP_REFERER=reverse(
"counter:click",
kwargs={
"counter_id": self.counter.id,
"user_id": self.customer.customer.pk,
},
),
) )
assert response.status_code == 302 assert response.status_code == 302
self.assertContains(self.client.get(response.url), text="04786547890123") self.assertContains(self.client.get(response.url), text="04786547890123")
@ -220,13 +260,19 @@ class TestStudentCard(TestCase):
# Test card with only letters # Test card with only letters
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card_fragment", "counter:add_student_card",
kwargs={ kwargs={
"counter_id": self.counter.id, "customer_id": self.customer.customer.pk,
"customer_id": self.sli.customer.pk,
}, },
), ),
{"uid": "ABCAAAFAAFAAAB"}, {"uid": "ABCAAAFAAFAAAB"},
HTTP_REFERER=reverse(
"counter:click",
kwargs={
"counter_id": self.counter.id,
"user_id": self.customer.customer.pk,
},
),
) )
assert response.status_code == 302 assert response.status_code == 302
self.assertContains(self.client.get(response.url), text="ABCAAAFAAFAAAB") self.assertContains(self.client.get(response.url), text="ABCAAAFAAFAAAB")
@ -235,26 +281,38 @@ class TestStudentCard(TestCase):
# UID too short # UID too short
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card_fragment", "counter:add_student_card",
kwargs={ kwargs={
"counter_id": self.counter.id, "customer_id": self.customer.customer.pk,
"customer_id": self.sli.customer.pk,
}, },
), ),
{"uid": "8B90734A802A8"}, {"uid": "8B90734A802A8"},
HTTP_REFERER=reverse(
"counter:click",
kwargs={
"counter_id": self.counter.id,
"user_id": self.customer.customer.pk,
},
),
) )
self.assertContains(response, text="Cet UID est invalide") self.assertContains(response, text="Cet UID est invalide")
# UID too long # UID too long
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card_fragment", "counter:add_student_card",
kwargs={ kwargs={
"counter_id": self.counter.id, "customer_id": self.customer.customer.pk,
"customer_id": self.sli.customer.pk,
}, },
), ),
{"uid": "8B90734A802A8FA"}, {"uid": "8B90734A802A8FA"},
HTTP_REFERER=reverse(
"counter:click",
kwargs={
"counter_id": self.counter.id,
"user_id": self.customer.customer.pk,
},
),
) )
self.assertContains(response, text="Cet UID est invalide") self.assertContains(response, text="Cet UID est invalide")
self.assertContains( self.assertContains(
@ -265,13 +323,19 @@ class TestStudentCard(TestCase):
# Test with already existing card # Test with already existing card
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card_fragment", "counter:add_student_card",
kwargs={ kwargs={
"counter_id": self.counter.id, "customer_id": self.customer.customer.pk,
"customer_id": self.sli.customer.pk, },
),
{"uid": self.valid_card.uid},
HTTP_REFERER=reverse(
"counter:click",
kwargs={
"counter_id": self.counter.id,
"user_id": self.customer.customer.pk,
}, },
), ),
{"uid": "9A89B82018B0A0"},
) )
self.assertContains(response, text="Cet UID est invalide") self.assertContains(response, text="Cet UID est invalide")
self.assertContains( self.assertContains(
@ -281,26 +345,38 @@ class TestStudentCard(TestCase):
# Test with lowercase # Test with lowercase
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card_fragment", "counter:add_student_card",
kwargs={ kwargs={
"counter_id": self.counter.id, "customer_id": self.customer.customer.pk,
"customer_id": self.sli.customer.pk,
}, },
), ),
{"uid": "8b90734a802a9f"}, {"uid": "8b90734a802a9f"},
HTTP_REFERER=reverse(
"counter:click",
kwargs={
"counter_id": self.counter.id,
"user_id": self.customer.customer.pk,
},
),
) )
self.assertContains(response, text="Cet UID est invalide") self.assertContains(response, text="Cet UID est invalide")
# Test with white spaces # Test with white spaces
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card_fragment", "counter:add_student_card",
kwargs={ kwargs={
"counter_id": self.counter.id, "customer_id": self.customer.customer.pk,
"customer_id": self.sli.customer.pk,
}, },
), ),
{"uid": " "}, {"uid": " "},
HTTP_REFERER=reverse(
"counter:click",
kwargs={
"counter_id": self.counter.id,
"user_id": self.customer.customer.pk,
},
),
) )
self.assertContains(response, text="Cet UID est invalide") self.assertContains(response, text="Cet UID est invalide")
self.assertContains(response, text="Ce champ est obligatoire.") self.assertContains(response, text="Ce champ est obligatoire.")
@ -309,52 +385,58 @@ class TestStudentCard(TestCase):
# Send to a counter where you aren't logged in # Send to a counter where you aren't logged in
self.client.post( self.client.post(
reverse("counter:logout", args=[self.counter.id]), reverse("counter:logout", args=[self.counter.id]),
{"user_id": self.krophil.id}, {"user_id": self.barmen.id},
) )
def send_valid_request(client, counter_id): def send_valid_request(client, counter_id):
return client.post( return client.post(
reverse( reverse(
"counter:add_student_card_fragment", "counter:add_student_card",
kwargs={ kwargs={
"counter_id": counter_id, "customer_id": self.customer.customer.pk,
"customer_id": self.sli.customer.pk,
}, },
), ),
{"uid": "8B90734A802A8F"}, {"uid": "8B90734A802A8F"},
HTTP_REFERER=reverse(
"counter:click",
kwargs={
"counter_id": counter_id,
"user_id": self.customer.customer.pk,
},
),
) )
assert send_valid_request(self.client, self.counter.id).status_code == 403 assert send_valid_request(self.client, self.counter.id).status_code == 403
# Send to a non bar counter # Send to a non bar counter
self.client.force_login(self.skia) self.client.force_login(self.club_admin)
assert send_valid_request(self.client, self.ae_counter.id) assert send_valid_request(self.client, self.club_counter.id).status_code == 403
def test_delete_student_card_with_owner(self): def test_delete_student_card_with_owner(self):
self.client.force_login(self.sli) self.client.force_login(self.customer)
self.client.post( self.client.post(
reverse( reverse(
"counter:delete_student_card", "counter:delete_student_card",
kwargs={ kwargs={
"customer_id": self.sli.customer.pk, "customer_id": self.customer.customer.pk,
"card_id": self.sli.customer.student_cards.first().id, "card_id": self.customer.customer.student_cards.first().id,
}, },
) )
) )
assert not self.sli.customer.student_cards.exists() assert not self.customer.customer.student_cards.exists()
def test_delete_student_card_with_board_member(self): def test_delete_student_card_with_board_member(self):
self.client.force_login(self.skia) self.client.force_login(self.board_admin)
self.client.post( self.client.post(
reverse( reverse(
"counter:delete_student_card", "counter:delete_student_card",
kwargs={ kwargs={
"customer_id": self.sli.customer.pk, "customer_id": self.customer.customer.pk,
"card_id": self.sli.customer.student_cards.first().id, "card_id": self.customer.customer.student_cards.first().id,
}, },
) )
) )
assert not self.sli.customer.student_cards.exists() assert not self.customer.customer.student_cards.exists()
def test_delete_student_card_with_root(self): def test_delete_student_card_with_root(self):
self.client.force_login(self.root) self.client.force_login(self.root)
@ -362,100 +444,107 @@ class TestStudentCard(TestCase):
reverse( reverse(
"counter:delete_student_card", "counter:delete_student_card",
kwargs={ kwargs={
"customer_id": self.sli.customer.pk, "customer_id": self.customer.customer.pk,
"card_id": self.sli.customer.student_cards.first().id, "card_id": self.customer.customer.student_cards.first().id,
}, },
) )
) )
assert not self.sli.customer.student_cards.exists() assert not self.customer.customer.student_cards.exists()
def test_delete_student_card_fail(self): def test_delete_student_card_fail(self):
self.client.force_login(self.krophil) self.client.force_login(self.subscriber)
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:delete_student_card", "counter:delete_student_card",
kwargs={ kwargs={
"customer_id": self.sli.customer.pk, "customer_id": self.customer.customer.pk,
"card_id": self.sli.customer.student_cards.first().id, "card_id": self.customer.customer.student_cards.first().id,
}, },
) )
) )
assert response.status_code == 403 assert response.status_code == 403
assert self.sli.customer.student_cards.exists() assert self.customer.customer.student_cards.exists()
def test_add_student_card_from_user_preferences(self): def test_add_student_card_from_user_preferences(self):
# Test with owner of the card # Test with owner of the card
self.client.force_login(self.sli) self.client.force_login(self.customer)
self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": "8B90734A802A8F"}, {"uid": "8B90734A802A8F"},
) )
response = self.client.get( assert response.status_code == 302
reverse("core:user_prefs", kwargs={"user_id": self.sli.id})
) response = self.client.get(response.url)
self.assertContains(response, text="8B90734A802A8F") self.assertContains(response, text="8B90734A802A8F")
# Test with board member # Test with board member
self.client.force_login(self.skia) self.client.force_login(self.board_admin)
self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": "8B90734A802A8A"}, {"uid": "8B90734A802A8A"},
) )
response = self.client.get( assert response.status_code == 302
reverse("core:user_prefs", kwargs={"user_id": self.sli.id})
) response = self.client.get(response.url)
self.assertContains(response, text="8B90734A802A8A") self.assertContains(response, text="8B90734A802A8A")
# Test card with only numbers # Test card with only numbers
self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": "04786547890123"}, {"uid": "04786547890123"},
) )
response = self.client.get( assert response.status_code == 302
reverse("core:user_prefs", kwargs={"user_id": self.sli.id})
) response = self.client.get(response.url)
self.assertContains(response, text="04786547890123") self.assertContains(response, text="04786547890123")
# Test card with only letters # Test card with only letters
self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": "ABCAAAFAAFAAAB"}, {"uid": "ABCAAAFAAFAAAB"},
) )
response = self.client.get(
reverse("core:user_prefs", kwargs={"user_id": self.sli.id}) assert response.status_code == 302
)
response = self.client.get(response.url)
self.assertContains(response, text="ABCAAAFAAFAAAB") self.assertContains(response, text="ABCAAAFAAFAAAB")
# Test with root # Test with root
self.client.force_login(self.root) self.client.force_login(self.root)
self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": "8B90734A802A8B"}, {"uid": "8B90734A802A8B"},
) )
response = self.client.get( assert response.status_code == 302
reverse("core:user_prefs", kwargs={"user_id": self.sli.id})
) response = self.client.get(response.url)
self.assertContains(response, text="8B90734A802A8B") self.assertContains(response, text="8B90734A802A8B")
def test_add_student_card_from_user_preferences_fail(self): def test_add_student_card_from_user_preferences_fail(self):
self.client.force_login(self.sli) self.client.force_login(self.customer)
# UID too short # UID too short
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": "8B90734A802A8"}, {"uid": "8B90734A802A8"},
) )
@ -465,7 +554,8 @@ class TestStudentCard(TestCase):
# UID too long # UID too long
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": "8B90734A802A8FA"}, {"uid": "8B90734A802A8FA"},
) )
@ -474,9 +564,10 @@ class TestStudentCard(TestCase):
# Test with already existing card # Test with already existing card
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": "9A89B82018B0A0"}, {"uid": self.valid_card.uid},
) )
self.assertContains( self.assertContains(
response, text="Un objet Student card avec ce champ Uid existe déjà." response, text="Un objet Student card avec ce champ Uid existe déjà."
@ -485,7 +576,8 @@ class TestStudentCard(TestCase):
# Test with lowercase # Test with lowercase
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": "8b90734a802a9f"}, {"uid": "8b90734a802a9f"},
) )
@ -494,17 +586,19 @@ class TestStudentCard(TestCase):
# Test with white spaces # Test with white spaces
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": " " * 14}, {"uid": " " * 14},
) )
self.assertContains(response, text="Cet UID est invalide") self.assertContains(response, text="Cet UID est invalide")
# Test with unauthorized user # Test with unauthorized user
self.client.force_login(self.krophil) self.client.force_login(self.subscriber)
response = self.client.post( response = self.client.post(
reverse( reverse(
"counter:add_student_card", kwargs={"customer_id": self.sli.customer.pk} "counter:add_student_card",
kwargs={"customer_id": self.customer.customer.pk},
), ),
{"uid": "8B90734A802A8F"}, {"uid": "8B90734A802A8F"},
) )

View File

@ -54,7 +54,6 @@ from counter.views.home import (
from counter.views.invoice import InvoiceCallView from counter.views.invoice import InvoiceCallView
from counter.views.student_card import ( from counter.views.student_card import (
StudentCardDeleteView, StudentCardDeleteView,
StudentCardFormFragmentView,
StudentCardFormView, StudentCardFormView,
) )
@ -81,11 +80,6 @@ urlpatterns = [
StudentCardFormView.as_view(), StudentCardFormView.as_view(),
name="add_student_card", name="add_student_card",
), ),
path(
"customer/<int:customer_id>/card/add/counter/<int:counter_id>/",
StudentCardFormFragmentView.as_view(),
name="add_student_card_fragment",
),
path( path(
"customer/<int:customer_id>/card/delete/<int:card_id>/", "customer/<int:customer_id>/card/delete/<int:card_id>/",
StudentCardDeleteView.as_view(), StudentCardDeleteView.as_view(),

View File

@ -22,14 +22,22 @@ def is_logged_in_counter(request: HttpRequest) -> bool:
to the counter) to the counter)
- The current session has a counter token associated with it. - The current session has a counter token associated with it.
- A counter with this token exists. - A counter with this token exists.
- The counter is open
""" """
referer_ok = ( referer_ok = (
"HTTP_REFERER" in request.META "HTTP_REFERER" in request.META
and resolve(urlparse(request.META["HTTP_REFERER"]).path).app_name == "counter" and resolve(urlparse(request.META["HTTP_REFERER"]).path).app_name == "counter"
) )
return ( has_token = (
(referer_ok or request.resolver_match.app_name == "counter") (referer_ok or request.resolver_match.app_name == "counter")
and "counter_token" in request.session and "counter_token" in request.session
and request.session["counter_token"] and request.session["counter_token"]
and Counter.objects.filter(token=request.session["counter_token"]).exists() )
if not has_token:
return False
return (
Counter.objects.annotate_is_open()
.filter(token=request.session["counter_token"], is_open=True)
.exists()
) )

View File

@ -13,14 +13,17 @@
# #
# #
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.http import HttpRequest
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.views.generic.edit import DeleteView, FormView from django.views.generic.edit import DeleteView, FormView
from core.views import AllowFragment, CanEditMixin from core.views import CanEditMixin
from counter.forms import StudentCardForm from counter.forms import StudentCardForm
from counter.models import Counter, Customer, StudentCard from counter.models import Customer, StudentCard
from counter.utils import is_logged_in_counter
class StudentCardDeleteView(DeleteView, CanEditMixin): class StudentCardDeleteView(DeleteView, CanEditMixin):
@ -40,16 +43,22 @@ class StudentCardDeleteView(DeleteView, CanEditMixin):
) )
class StudentCardFormView(AllowFragment, FormView): class StudentCardFormView(FormView):
"""Add a new student card.""" """Add a new student card. This is a fragment view !"""
form_class = StudentCardForm form_class = StudentCardForm
template_name = "core/create.jinja" template_name = "counter/fragments/create_student_card.jinja"
def dispatch(self, request, *args, **kwargs): def dispatch(self, request: HttpRequest, *args, **kwargs):
self.customer = get_object_or_404(Customer, pk=kwargs["customer_id"]) self.customer = get_object_or_404(
if not StudentCard.can_create(self.customer, request.user): Customer.objects.prefetch_related("student_cards"), pk=kwargs["customer_id"]
)
if not is_logged_in_counter(request) and not StudentCard.can_create(
self.customer, request.user
):
raise PermissionDenied raise PermissionDenied
return super().dispatch(request, *args, **kwargs) return super().dispatch(request, *args, **kwargs)
def form_valid(self, form): def form_valid(self, form):
@ -58,56 +67,12 @@ class StudentCardFormView(AllowFragment, FormView):
StudentCard(customer=self.customer, uid=data["uid"]).save() StudentCard(customer=self.customer, uid=data["uid"]).save()
return res return res
def get_success_url(self, **kwargs):
return reverse_lazy(
"core:user_prefs", kwargs={"user_id": self.customer.user.pk}
)
class StudentCardFormFragmentView(FormView):
"""
Add a new student card from a counter
This is a fragment only view which integrates with counter_click.jinja
"""
form_class = StudentCardForm
template_name = "counter/add_student_card_fragment.jinja"
def dispatch(self, request, *args, **kwargs):
self.counter = get_object_or_404(
Counter.objects.annotate_is_open(), pk=kwargs["counter_id"]
)
self.customer = get_object_or_404(
Customer.objects.prefetch_related("student_cards"), pk=kwargs["customer_id"]
)
if not (
self.counter.type == "BAR"
and "counter_token" in request.session
and request.session["counter_token"] == self.counter.token
and self.counter.is_open
):
raise PermissionDenied
return super().dispatch(request, *args, **kwargs)
def form_valid(self, form):
data = form.clean()
res = super().form_valid(form)
StudentCard(customer=self.customer, uid=data["uid"]).save()
return res
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs) context = super().get_context_data(**kwargs)
context["counter"] = self.counter
context["customer"] = self.customer context["customer"] = self.customer
context["action"] = self.request.path context["action"] = self.request.path
context["student_cards"] = self.customer.student_cards.all() context["student_cards"] = self.customer.student_cards.all()
return context return context
def get_success_url(self, **kwargs): def get_success_url(self, **kwargs):
return reverse_lazy( return self.request.path
"counter:add_student_card_fragment",
kwargs={
"customer_id": self.customer.pk,
"counter_id": self.counter.id,
},
)