1 Commits

Author SHA1 Message Date
dependabot[bot] 2297eb638a [UPDATE] Update beautifulsoup4 requirement
Updates the requirements on [beautifulsoup4](https://www.crummy.com/software/BeautifulSoup/bs4/) to permit the latest version.

---
updated-dependencies:
- dependency-name: beautifulsoup4
  dependency-version: 4.15.0
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-06-08 08:23:16 +00:00
7 changed files with 30 additions and 74 deletions
+5 -7
View File
@@ -39,7 +39,6 @@ from counter.models import (
Customer,
Eticket,
InvoiceCall,
Permanency,
Price,
Product,
ProductFormula,
@@ -152,13 +151,12 @@ class CounterLoginForm(LoginForm):
raise ValidationError(
message=_("You are not a barman of this counter."), code="not_barman"
)
if Permanency.objects.filter(end=None, user=user).exists():
if user in self.request.barmen:
message = _("You are already logged in this counter.")
elif user in self.counter.barmen_list:
message = _("You are already logged in another counter.")
else:
message = _("You are already logged on another device")
message = (
_("You are already logged in this counter.")
if user in self.counter.barmen_list
else _("You are already logged in another counter.")
)
raise ValidationError(message=message, code="already_logged_in")
+19 -21
View File
@@ -1,7 +1,8 @@
from typing import TYPE_CHECKING, Callable
from django.db.models import Exists, OuterRef
from django.http import HttpRequest, HttpResponse
from django.utils.functional import SimpleLazyObject
from django.utils.functional import SimpleLazyObject, empty
from core.models import User
from counter.models import Permanency
@@ -10,31 +11,20 @@ if TYPE_CHECKING:
from django.contrib.sessions.backends.base import SessionBase
SESSION_PERMANENCES_KEY = "permanence_ids"
SESSION_BARMEN_KEY = "barmen_ids"
def get_cached_barmen(request: HttpRequest) -> set[User]:
if not hasattr(request, "_cached_barmen"):
session: SessionBase = request.session
if session_ids := session.get(SESSION_PERMANENCES_KEY, None):
# Get ongoing permanences which id is in session.
# Note : we store permanence ids rather than user id to be sure
# not to wrongfully mark someone as logged here,
# even if it logged out then logged in elsewhere.
permanences = (
Permanency.objects.filter(end=None, id__in=session_ids)
.order_by("id")
.select_related("user")
barmen_ids = session.get(SESSION_BARMEN_KEY, [])
if barmen_ids:
request._cached_barmen = set(
User.objects.filter(
Exists(Permanency.objects.filter(user=OuterRef("pk"), end=None)),
id__in=barmen_ids,
)
)
# if the list of permanences occurring on this device has changed
# since the last page load, change the ids stored in session
real_ids = [p.id for p in permanences]
if real_ids != session_ids:
session[SESSION_PERMANENCES_KEY] = real_ids
request._cached_barmen = {p.user for p in permanences}
else:
request._cached_barmen = set()
@@ -63,4 +53,12 @@ class BarmenMiddleware:
def __call__(self, request: HttpRequest):
request.barmen = SimpleLazyObject(lambda: get_cached_barmen(request))
return self.get_response(request)
response = self.get_response(request)
if request.barmen._wrapped is not empty and {
b.id for b in request.barmen
} != set(request.session.get(SESSION_BARMEN_KEY, [])):
# update the session data only if `session.barmen`
# has been accessed and modified.
request.session[SESSION_BARMEN_KEY] = [b.id for b in request.barmen]
return response
+1 -1
View File
@@ -1105,7 +1105,7 @@ class Permanency(models.Model):
on_delete=models.CASCADE,
)
start = models.DateTimeField(_("start date"))
end = models.DateTimeField(_("end date"), null=True, blank=True, db_index=True)
end = models.DateTimeField(_("end date"), null=True, db_index=True)
activity = models.DateTimeField(_("last activity date"), auto_now=True)
class Meta:
+1 -36
View File
@@ -760,10 +760,10 @@ class TestBarmanConnection(TestCase):
assert last_perm.counter == self.counter
assert last_perm.user == self.barman
assert last_perm.end is None
assert self.barman in response.wsgi_request.barmen
response = self.client.get(
self.detail_url, {"username": self.barman.username, "password": "plop"}
)
assert self.barman in response.wsgi_request.barmen
assert response.context_data.get("barmen") == [self.barman]
soup = BeautifulSoup(response.text, "lxml")
assert soup.find("form", id="select-user-form") is not None
@@ -804,41 +804,6 @@ class TestBarmanConnection(TestCase):
)
self.assert_counter_login_fails(self.barman)
def test_barman_already_logged_in_another_device(self):
"""Test when the barman is already logged in the current counter on another device."""
other_client = Client()
other_client.post(
self.login_url, {"username": self.barman.username, "password": "plop"}
)
self.assert_counter_login_fails(self.barman)
def test_barman_login_elsewhere(self):
"""Test when the barman log himself out then log in on another device."""
self.client.post(
self.login_url, {"username": self.barman.username, "password": "plop"}
)
other_client = Client()
other_client.post(
reverse("counter:logout", kwargs={"counter_id": self.counter.id}),
data={"user_id": self.barman.id},
)
response = other_client.post(
self.login_url, {"username": self.barman.username, "password": "plop"}
)
assert response.status_code == 200
assert response.headers["HX-Redirect"] == self.detail_url
# the barmen should now be logged in `other_client`...
response = other_client.get(
self.detail_url, {"username": self.barman.username, "password": "plop"}
)
assert self.barman in response.wsgi_request.barmen
# ... but not in `self.client`
response = self.client.get(
self.detail_url, {"username": self.barman.username, "password": "plop"}
)
assert self.barman not in response.wsgi_request.barmen
def test_barman_already_logged_elsewhere(self):
"""Test when the barman is already logged in another counter."""
other_counter = baker.make(Counter, type="BAR")
+2 -3
View File
@@ -30,7 +30,6 @@ from django.views.generic.edit import FormView
from core.auth.mixins import CanViewMixin
from core.views import FragmentMixin, UseFragmentsMixin
from counter.forms import CounterLoginForm, GetUserForm
from counter.middleware import SESSION_PERMANENCES_KEY
from counter.models import Counter, Permanency
from counter.utils import is_logged_in_counter
from counter.views.mixins import CounterTabsMixin
@@ -59,8 +58,8 @@ class CounterLoginFragment(FragmentMixin, SingleObjectMixin, FormView):
def form_valid(self, form: CounterLoginForm):
user = form.get_user()
perm = self.object.permanencies.create(user=user, start=timezone.now())
self.request.session.setdefault(SESSION_PERMANENCES_KEY, []).append(perm.id)
self.object.permanencies.create(user=user, start=timezone.now())
self.request.barmen.add(user)
self.success_url = reverse(
"counter:details", kwargs={"counter_id": self.object.id}
)
-4
View File
@@ -3217,10 +3217,6 @@ msgstr "Vous êtes déjà connecté à ce comptoir."
msgid "You are already logged in another counter."
msgstr "Vous êtes déjà connecté à un autre comptoir."
#: counter/forms.py
msgid "You are already logged on another device"
msgstr "Vous êtes déjà connecté sur un autre appareil"
#: counter/forms.py
msgid "Regular barmen"
msgstr "Barmen réguliers"
+1 -1
View File
@@ -77,7 +77,7 @@ tests = [
"pytest-cov>=7.1.0,<8.0.0",
"pytest-django>=4.12.0,<5.0.0",
"model-bakery>=1.23.4,<2.0.0",
"beautifulsoup4>=4.14.3,<5",
"beautifulsoup4>=4.15.0,<5",
"lxml>=6.1.1,<7",
]
docs = [