diff --git a/club/templates/club/club_tools.jinja b/club/templates/club/club_tools.jinja
index 9ca46f81..651cc9bb 100644
--- a/club/templates/club/club_tools.jinja
+++ b/club/templates/club/club_tools.jinja
@@ -16,22 +16,13 @@
- {{ show_tokens(profile) }}
- {{ show_slots(profile) }}
-
- {% endif %}
{% else %}
{% trans %}Not subscribed{% endtrans %}
diff --git a/core/views/user.py b/core/views/user.py
index 93b64d3b..24df16ff 100644
--- a/core/views/user.py
+++ b/core/views/user.py
@@ -564,10 +564,8 @@ class UserToolsView(LoginRequiredMixin, QuickNotifMixin, UserTabsMixin, Template
def get_context_data(self, **kwargs):
self.object = self.request.user
- from launderette.models import Launderette
kwargs = super().get_context_data(**kwargs)
- kwargs["launderettes"] = Launderette.objects.all()
kwargs["profile"] = self.request.user
kwargs["object"] = self.request.user
return kwargs
diff --git a/docs/reference/launderette/models.md b/docs/reference/launderette/models.md
deleted file mode 100644
index e773ea38..00000000
--- a/docs/reference/launderette/models.md
+++ /dev/null
@@ -1 +0,0 @@
-::: launderette.models
\ No newline at end of file
diff --git a/docs/reference/launderette/views.md b/docs/reference/launderette/views.md
deleted file mode 100644
index 5b942e44..00000000
--- a/docs/reference/launderette/views.md
+++ /dev/null
@@ -1 +0,0 @@
-::: launderette.views
\ No newline at end of file
diff --git a/launderette/admin.py b/launderette/admin.py
deleted file mode 100644
index c5d8bf07..00000000
--- a/launderette/admin.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#
-# Copyright 2023 © AE UTBM
-# ae@utbm.fr / ae.info@utbm.fr
-#
-# This file is part of the website of the UTBM Student Association (AE UTBM),
-# https://ae.utbm.fr.
-#
-# You can find the source code of the website at https://github.com/ae-utbm/sith
-#
-# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
-# SEE : https://raw.githubusercontent.com/ae-utbm/sith/master/LICENSE
-# OR WITHIN THE LOCAL FILE "LICENSE"
-#
-#
-from django.contrib import admin
-
-from launderette.models import Launderette, Machine, Slot, Token
-
-
-@admin.register(Launderette)
-class LaunderetteAdmin(admin.ModelAdmin):
- list_display = ("name", "counter")
-
-
-@admin.register(Machine)
-class MachineAdmin(admin.ModelAdmin):
- list_display = ("name", "launderette", "type", "is_working")
-
-
-@admin.register(Token)
-class TokenAdmin(admin.ModelAdmin):
- list_display = ("name", "launderette", "type", "user")
- autocomplete_fields = ("user",)
-
-
-@admin.register(Slot)
-class SlotAdmin(admin.ModelAdmin):
- list_display = ("machine", "user", "start_date")
- autocomplete_fields = ("user",)
diff --git a/launderette/migrations/0002_remove_token_launderette_remove_machine_launderette_and_more.py b/launderette/migrations/0002_remove_token_launderette_remove_machine_launderette_and_more.py
new file mode 100644
index 00000000..cb63fa26
--- /dev/null
+++ b/launderette/migrations/0002_remove_token_launderette_remove_machine_launderette_and_more.py
@@ -0,0 +1,14 @@
+# Generated by Django 5.2 on 2025-04-15 19:37
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+ dependencies = [("launderette", "0001_initial")]
+
+ operations = [
+ migrations.DeleteModel(name="Launderette"),
+ migrations.DeleteModel(name="Machine"),
+ migrations.DeleteModel(name="Slot"),
+ migrations.DeleteModel(name="Token"),
+ ]
diff --git a/launderette/models.py b/launderette/models.py
deleted file mode 100644
index 81357768..00000000
--- a/launderette/models.py
+++ /dev/null
@@ -1,193 +0,0 @@
-#
-# Copyright 2023 © AE UTBM
-# ae@utbm.fr / ae.info@utbm.fr
-#
-# This file is part of the website of the UTBM Student Association (AE UTBM),
-# https://ae.utbm.fr.
-#
-# You can find the source code of the website at https://github.com/ae-utbm/sith
-#
-# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
-# SEE : https://raw.githubusercontent.com/ae-utbm/sith/master/LICENSE
-# OR WITHIN THE LOCAL FILE "LICENSE"
-#
-#
-
-from django.conf import settings
-from django.db import DataError, models
-from django.urls import reverse
-from django.utils.translation import gettext_lazy as _
-
-from club.models import Club
-from core.models import User
-from counter.models import Counter
-
-# Create your models here.
-
-
-class Launderette(models.Model):
- name = models.CharField(_("name"), max_length=30)
- counter = models.OneToOneField(
- Counter,
- verbose_name=_("counter"),
- related_name="launderette",
- on_delete=models.CASCADE,
- )
-
- class Meta:
- verbose_name = _("Launderette")
-
- def __str__(self):
- return self.name
-
- def get_absolute_url(self):
- return reverse("launderette:launderette_list")
-
- def is_owned_by(self, user):
- """Method to see if that object can be edited by the given user."""
- if user.is_anonymous:
- return False
- launderette_club = Club.objects.get(id=settings.SITH_LAUNDERETTE_CLUB_ID)
- m = launderette_club.get_membership_for(user)
- return bool(m and m.role >= 9)
-
- def can_be_edited_by(self, user):
- launderette_club = Club.objects.get(id=settings.SITH_LAUNDERETTE_CLUB_ID)
- m = launderette_club.get_membership_for(user)
- return bool(m and m.role >= 2)
-
- def can_be_viewed_by(self, user):
- return user.is_subscribed
-
- def get_machine_list(self):
- return Machine.objects.filter(launderette_id=self.id)
-
- def machine_list(self):
- return [m.id for m in self.get_machine_list()]
-
- def get_token_list(self):
- return Token.objects.filter(launderette_id=self.id)
-
- def token_list(self):
- return [t.id for t in self.get_token_list()]
-
-
-class Machine(models.Model):
- name = models.CharField(_("name"), max_length=30)
- launderette = models.ForeignKey(
- Launderette,
- related_name="machines",
- verbose_name=_("launderette"),
- on_delete=models.CASCADE,
- )
- type = models.CharField(
- _("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
- )
- is_working = models.BooleanField(_("is working"), default=True)
-
- class Meta:
- verbose_name = _("Machine")
-
- def __str__(self):
- return "%s %s" % (self._meta.verbose_name, self.name)
-
- def get_absolute_url(self):
- return reverse(
- "launderette:launderette_admin",
- kwargs={"launderette_id": self.launderette.id},
- )
-
- def is_owned_by(self, user):
- """Method to see if that object can be edited by the given user."""
- if user.is_anonymous:
- return False
- launderette_club = Club.objects.get(id=settings.SITH_LAUNDERETTE_CLUB_ID)
- m = launderette_club.get_membership_for(user)
- return bool(m and m.role >= 9)
-
-
-class Token(models.Model):
- name = models.CharField(_("name"), max_length=5)
- launderette = models.ForeignKey(
- Launderette,
- related_name="tokens",
- verbose_name=_("launderette"),
- on_delete=models.CASCADE,
- )
- type = models.CharField(
- _("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
- )
- borrow_date = models.DateTimeField(_("borrow date"), null=True, blank=True)
- user = models.ForeignKey(
- User,
- related_name="tokens",
- verbose_name=_("user"),
- null=True,
- blank=True,
- on_delete=models.CASCADE,
- )
-
- class Meta:
- verbose_name = _("Token")
- unique_together = ("name", "launderette", "type")
- ordering = ["type", "name"]
-
- def __str__(self):
- return (
- f"{self.__class__._meta.verbose_name} {self.get_type_display()} "
- f"#{self.name} ({self.launderette.name})"
- )
-
- def save(self, *args, **kwargs):
- if self.name == "":
- raise DataError(_("Token name can not be blank"))
- else:
- super().save(*args, **kwargs)
-
- def is_owned_by(self, user):
- """Method to see if that object can be edited by the given user."""
- if user.is_anonymous:
- return False
- launderette_club = Club.objects.get(id=settings.SITH_LAUNDERETTE_CLUB_ID)
- m = launderette_club.get_membership_for(user)
- return bool(m and m.role >= 9)
-
-
-class Slot(models.Model):
- start_date = models.DateTimeField(_("start date"))
- type = models.CharField(
- _("type"), max_length=10, choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES
- )
- machine = models.ForeignKey(
- Machine,
- related_name="slots",
- verbose_name=_("machine"),
- on_delete=models.CASCADE,
- )
- token = models.ForeignKey(
- Token,
- related_name="slots",
- verbose_name=_("token"),
- blank=True,
- null=True,
- on_delete=models.CASCADE,
- )
- user = models.ForeignKey(
- User, related_name="slots", verbose_name=_("user"), on_delete=models.CASCADE
- )
-
- class Meta:
- verbose_name = _("Slot")
- ordering = ["start_date"]
-
- def __str__(self):
- return "User: %s - Date: %s - Type: %s - Machine: %s - Token: %s" % (
- self.user,
- self.start_date,
- self.get_type_display(),
- self.machine.name,
- self.token,
- )
-
- def is_owned_by(self, user):
- return user == self.user
diff --git a/launderette/templates/launderette/launderette_admin.jinja b/launderette/templates/launderette/launderette_admin.jinja
deleted file mode 100644
index 67716183..00000000
--- a/launderette/templates/launderette/launderette_admin.jinja
+++ /dev/null
@@ -1,69 +0,0 @@
-{% extends "core/base.jinja" %}
-
-{% block title %}
- {% trans %}Launderette admin{% endtrans %}
-{% endblock %}
-
-{% block content %}
-
{% trans %}Selling{% endtrans %}
-
{% trans %}Sell{% endtrans %}
-
-
{% trans %}Machines{% endtrans %}
-
{% trans %}New machine{% endtrans %}
-
-
-
{% trans %}Tokens{% endtrans %}
-
-
-
-
-
-
-
- {% trans %}Type{% endtrans %} |
- {% trans %}Name{% endtrans %} |
- {% trans %}User{% endtrans %} |
- {% trans %}Since{% endtrans %} |
-
-
-
- {% for t in launderette.tokens.all() %}
-
- {{ t.get_type_display() }} |
- {{ t.name }} |
- {% if t.user %}
- {{ t.user.get_display_name() }} |
- {{ t.borrow_date|date(DATETIME_FORMAT) }} - {{ t.borrow_date|time(DATETIME_FORMAT) }} |
- {% else %}
- |
- |
- {% endif %}
-
- {% endfor %}
-
-
-
-{% endblock %}
-
-
-
-
diff --git a/launderette/templates/launderette/launderette_book.jinja b/launderette/templates/launderette/launderette_book.jinja
deleted file mode 100644
index ee5e2625..00000000
--- a/launderette/templates/launderette/launderette_book.jinja
+++ /dev/null
@@ -1,58 +0,0 @@
-{% extends "core/base.jinja" %}
-{% from "core/macros.jinja" import show_slots, show_tokens %}
-
-{% block title %}
- {% trans %}Launderette{% endtrans %}
-{% endblock %}
-
-{% macro choose(date) %}
-
-{% endmacro %}
-
-
-{% block content %}
-
{{ launderette }}
-
-
-
-
-
-
-
-
- {% for day in planning.keys() %}
- {{ day|date('l') }} |
- {% endfor %}
-
-
-
- {% for i in range(0, 24) %}
-
- {% for hours in planning.values() %}
-
- {% if hours[i] %}
- {{ hours[i]|time(TIME_FORMAT) }} {{ choose(hours[i]) }}
- {% endif %}
- |
- {% endfor %}
-
- {% endfor %}
-
-
- {{ show_slots(user) }}
- {{ show_tokens(user) }}
-{% endblock %}
diff --git a/launderette/templates/launderette/launderette_book_choose.jinja b/launderette/templates/launderette/launderette_book_choose.jinja
deleted file mode 100644
index 40340096..00000000
--- a/launderette/templates/launderette/launderette_book_choose.jinja
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends "core/base.jinja" %}
-
-{% block title %}
- {% trans %}Launderette{% endtrans %}
-{% endblock %}
-
-{% block content %}
- {% if request.user.is_subscribed %}
-
- {% for l in launderette_list %}
- - {{ l }}
- {% endfor %}
-
- {% endif %}
-{% endblock %}
-
-
-
-
-
-
diff --git a/launderette/templates/launderette/launderette_click.jinja b/launderette/templates/launderette/launderette_click.jinja
deleted file mode 100644
index 682d0038..00000000
--- a/launderette/templates/launderette/launderette_click.jinja
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends "core/base.jinja" %}
-
-{% block title %}
- {{ counter }}
-{% endblock %}
-
-{% block content %}
-
{% trans counter_name=counter %}{{ counter_name }} counter{% endtrans %}
-
-{% endblock %}
diff --git a/launderette/templates/launderette/launderette_list.jinja b/launderette/templates/launderette/launderette_list.jinja
deleted file mode 100644
index c28ee86d..00000000
--- a/launderette/templates/launderette/launderette_list.jinja
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends "core/base.jinja" %}
-
-{% block title %}
- {% trans %}Launderette admin list{% endtrans %}
-{% endblock %}
-
-{% block content %}
- {% if user.is_root %}
-
{% trans %}New launderette{% endtrans %}
- {% endif %}
- {% if launderette_list %}
-
{% trans %}Launderette admin list{% endtrans %}
-
- {% else %}
- {% trans %}There is no launderette in this website.{% endtrans %}
- {% endif %}
-{% endblock %}
-
-
-
diff --git a/launderette/templates/launderette/launderette_main.jinja b/launderette/templates/launderette/launderette_main.jinja
deleted file mode 100644
index 1a554674..00000000
--- a/launderette/templates/launderette/launderette_main.jinja
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends "core/base.jinja" %}
-
-{% block title %}
- {% trans %}Launderette{% endtrans %}
-{% endblock %}
-
-{% block content %}
- {% if request.user.can_edit(page) %}
-
{% trans %}Edit presentation page{% endtrans %}
- {% endif %}
- {% if request.user.is_subscribed %}
-
{% trans %}Book launderette slot{% endtrans %}
- {% endif %}
-
- {{ page.revisions.last().content|markdown }}
-{% endblock %}
-
-
-
-
-
diff --git a/launderette/tests.py b/launderette/tests.py
deleted file mode 100644
index 1288d000..00000000
--- a/launderette/tests.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Copyright 2023 © AE UTBM
-# ae@utbm.fr / ae.info@utbm.fr
-#
-# This file is part of the website of the UTBM Student Association (AE UTBM),
-# https://ae.utbm.fr.
-#
-# You can find the source code of the website at https://github.com/ae-utbm/sith
-#
-# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
-# SEE : https://raw.githubusercontent.com/ae-utbm/sith/master/LICENSE
-# OR WITHIN THE LOCAL FILE "LICENSE"
-#
-#
-
-# Create your tests here.
diff --git a/launderette/urls.py b/launderette/urls.py
deleted file mode 100644
index 3bcb7b99..00000000
--- a/launderette/urls.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# Copyright 2023 © AE UTBM
-# ae@utbm.fr / ae.info@utbm.fr
-#
-# This file is part of the website of the UTBM Student Association (AE UTBM),
-# https://ae.utbm.fr.
-#
-# You can find the source code of the website at https://github.com/ae-utbm/sith
-#
-# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
-# SEE : https://raw.githubusercontent.com/ae-utbm/sith/master/LICENSE
-# OR WITHIN THE LOCAL FILE "LICENSE"
-#
-#
-
-from django.urls import path
-
-from launderette.views import (
- LaunderetteAdminView,
- LaunderetteBookMainView,
- LaunderetteBookView,
- LaunderetteClickView,
- LaunderetteCreateView,
- LaunderetteEditView,
- LaunderetteListView,
- LaunderetteMainClickView,
- LaunderetteMainView,
- MachineCreateView,
- MachineDeleteView,
- MachineEditView,
- SlotDeleteView,
-)
-
-urlpatterns = [
- # views
- path("", LaunderetteMainView.as_view(), name="launderette_main"),
- path("slot/
/delete/", SlotDeleteView.as_view(), name="delete_slot"),
- path("book/", LaunderetteBookMainView.as_view(), name="book_main"),
- path("book//", LaunderetteBookView.as_view(), name="book_slot"),
- path(
- "/click/",
- LaunderetteMainClickView.as_view(),
- name="main_click",
- ),
- path(
- "/click//",
- LaunderetteClickView.as_view(),
- name="click",
- ),
- path("admin/", LaunderetteListView.as_view(), name="launderette_list"),
- path(
- "admin//",
- LaunderetteAdminView.as_view(),
- name="launderette_admin",
- ),
- path(
- "admin//edit/",
- LaunderetteEditView.as_view(),
- name="launderette_edit",
- ),
- path("admin/new/", LaunderetteCreateView.as_view(), name="launderette_new"),
- path("admin/machine/new/", MachineCreateView.as_view(), name="machine_new"),
- path(
- "admin/machine//edit/",
- MachineEditView.as_view(),
- name="machine_edit",
- ),
- path(
- "admin/machine//delete/",
- MachineDeleteView.as_view(),
- name="machine_delete",
- ),
-]
diff --git a/launderette/views.py b/launderette/views.py
deleted file mode 100644
index 1b0f111b..00000000
--- a/launderette/views.py
+++ /dev/null
@@ -1,511 +0,0 @@
-#
-# Copyright 2023 © AE UTBM
-# ae@utbm.fr / ae.info@utbm.fr
-#
-# This file is part of the website of the UTBM Student Association (AE UTBM),
-# https://ae.utbm.fr.
-#
-# You can find the source code of the website at https://github.com/ae-utbm/sith
-#
-# LICENSED UNDER THE GNU GENERAL PUBLIC LICENSE VERSION 3 (GPLv3)
-# SEE : https://raw.githubusercontent.com/ae-utbm/sith/master/LICENSE
-# OR WITHIN THE LOCAL FILE "LICENSE"
-#
-#
-
-from collections import OrderedDict
-from datetime import datetime, timedelta
-from datetime import timezone as tz
-
-from django import forms
-from django.conf import settings
-from django.contrib.auth.mixins import PermissionRequiredMixin
-from django.db import transaction
-from django.template import defaultfilters
-from django.urls import reverse_lazy
-from django.utils import dateparse, timezone
-from django.utils.translation import gettext as _
-from django.views.generic import DetailView, ListView, TemplateView
-from django.views.generic.edit import BaseFormView, CreateView, DeleteView, UpdateView
-
-from club.models import Club
-from core.auth.mixins import CanEditMixin, CanEditPropMixin, CanViewMixin
-from core.models import Page, User
-from counter.forms import GetUserForm
-from counter.models import Counter, Customer, Selling
-from launderette.models import Launderette, Machine, Slot, Token
-
-# For users
-
-
-class LaunderetteMainView(TemplateView):
- """Main presentation view."""
-
- template_name = "launderette/launderette_main.jinja"
-
- def get_context_data(self, **kwargs):
- """Add page to the context."""
- kwargs = super().get_context_data(**kwargs)
- kwargs["page"] = Page.objects.filter(name="launderette").first()
- return kwargs
-
-
-class LaunderetteBookMainView(CanViewMixin, ListView):
- """Choose which launderette to book."""
-
- model = Launderette
- template_name = "launderette/launderette_book_choose.jinja"
-
-
-class LaunderetteBookView(CanViewMixin, DetailView):
- """Display the launderette schedule."""
-
- model = Launderette
- pk_url_kwarg = "launderette_id"
- template_name = "launderette/launderette_book.jinja"
-
- def get(self, request, *args, **kwargs):
- self.slot_type = "BOTH"
- self.machines = {}
- return super().get(request, *args, **kwargs)
-
- def post(self, request, *args, **kwargs):
- self.slot_type = "BOTH"
- self.machines = {}
- with transaction.atomic():
- self.object = self.get_object()
- if "slot_type" in request.POST:
- self.slot_type = request.POST["slot_type"]
- if "slot" in request.POST and request.user.is_authenticated:
- self.subscriber = request.user
- if self.subscriber.is_subscribed:
- self.date = dateparse.parse_datetime(request.POST["slot"]).replace(
- tzinfo=tz.utc
- )
- if self.slot_type in ["WASHING", "DRYING"]:
- if self.check_slot(self.slot_type):
- Slot(
- user=self.subscriber,
- start_date=self.date,
- machine=self.machines[self.slot_type],
- type=self.slot_type,
- ).save()
- elif self.check_slot("WASHING") and self.check_slot(
- "DRYING", self.date + timedelta(hours=1)
- ):
- Slot(
- user=self.subscriber,
- start_date=self.date,
- machine=self.machines["WASHING"],
- type="WASHING",
- ).save()
- Slot(
- user=self.subscriber,
- start_date=self.date + timedelta(hours=1),
- machine=self.machines["DRYING"],
- type="DRYING",
- ).save()
- return super().get(request, *args, **kwargs)
-
- def check_slot(self, machine_type, date=None):
- if date is None:
- date = self.date
- for m in self.object.machines.filter(is_working=True, type=machine_type):
- slot = Slot.objects.filter(start_date=date, machine=m).first()
- if slot is None:
- self.machines[machine_type] = m
- return True
- return False
-
- @staticmethod
- def date_iterator(startDate, endDate, delta=timedelta(days=1)):
- currentDate = startDate
- while currentDate < endDate:
- yield currentDate
- currentDate += delta
-
- def get_context_data(self, **kwargs):
- """Add page to the context."""
- kwargs = super().get_context_data(**kwargs)
- kwargs["planning"] = OrderedDict()
- kwargs["slot_type"] = self.slot_type
- start_date = datetime.now().replace(
- hour=0, minute=0, second=0, microsecond=0, tzinfo=tz.utc
- )
- for date in LaunderetteBookView.date_iterator(
- start_date, start_date + timedelta(days=6), timedelta(days=1)
- ):
- kwargs["planning"][date] = []
- for h in LaunderetteBookView.date_iterator(
- date, date + timedelta(days=1), timedelta(hours=1)
- ):
- free = False
- if (
- (
- self.slot_type == "BOTH"
- and self.check_slot("WASHING", h)
- and self.check_slot("DRYING", h + timedelta(hours=1))
- )
- or (self.slot_type == "WASHING" and self.check_slot("WASHING", h))
- or (self.slot_type == "DRYING" and self.check_slot("DRYING", h))
- ):
- free = True
- if free and datetime.now().replace(tzinfo=tz.utc) < h:
- kwargs["planning"][date].append(h)
- else:
- kwargs["planning"][date].append(None)
- return kwargs
-
-
-class SlotDeleteView(CanEditPropMixin, DeleteView):
- """Delete a slot."""
-
- model = Slot
- pk_url_kwarg = "slot_id"
- template_name = "core/delete_confirm.jinja"
-
- def get_success_url(self):
- return self.request.user.get_absolute_url()
-
-
-# For admins
-
-
-class LaunderetteListView(CanEditPropMixin, ListView):
- """Choose which launderette to administer."""
-
- model = Launderette
- template_name = "launderette/launderette_list.jinja"
-
-
-class LaunderetteEditView(CanEditPropMixin, UpdateView):
- """Edit a launderette."""
-
- model = Launderette
- pk_url_kwarg = "launderette_id"
- fields = ["name"]
- template_name = "core/edit.jinja"
-
-
-class LaunderetteCreateView(PermissionRequiredMixin, CreateView):
- """Create a new launderette."""
-
- model = Launderette
- fields = ["name"]
- template_name = "core/create.jinja"
- permission_required = "launderette.add_launderette"
-
- def form_valid(self, form):
- club = Club.objects.get(id=settings.SITH_LAUNDERETTE_CLUB_ID)
- c = Counter(name=form.instance.name, club=club, type="OFFICE")
- c.save()
- form.instance.counter = c
- return super().form_valid(form)
-
-
-class ManageTokenForm(forms.Form):
- action = forms.ChoiceField(
- choices=[("BACK", _("Back")), ("ADD", _("Add")), ("DEL", _("Delete"))],
- initial="BACK",
- label=_("Action"),
- widget=forms.RadioSelect,
- )
- token_type = forms.ChoiceField(
- choices=settings.SITH_LAUNDERETTE_MACHINE_TYPES,
- label=_("Type"),
- initial="WASHING",
- widget=forms.RadioSelect,
- )
- tokens = forms.CharField(
- max_length=512,
- widget=forms.widgets.Textarea,
- label=_("Tokens, separated by spaces"),
- )
-
- def process(self, launderette):
- cleaned_data = self.cleaned_data
- token_list = cleaned_data["tokens"].strip(" \n\r").split(" ")
- token_type = cleaned_data["token_type"]
- self.data = {}
-
- if cleaned_data["action"] not in ["BACK", "ADD", "DEL"]:
- return
-
- tokens = list(
- Token.objects.filter(
- launderette=launderette, type=token_type, name__in=token_list
- )
- )
- existing_names = {t.name for t in tokens}
- if cleaned_data["action"] in ["BACK", "DEL"]:
- for t in set(token_list) - existing_names:
- self.add_error(
- None,
- _("Token %(token_name)s does not exists") % {"token_name": t},
- )
- if cleaned_data["action"] == "BACK":
- Token.objects.filter(id__in=[t.id for t in tokens]).update(
- borrow_date=None, user=None
- )
- elif cleaned_data["action"] == "DEL":
- Token.objects.filter(id__in=[t.id for t in tokens]).delete()
- elif cleaned_data["action"] == "ADD":
- for name in existing_names:
- self.add_error(
- None,
- _("Token %(token_name)s already exists") % {"token_name": name},
- )
- for t in token_list:
- if t == "":
- self.add_error(None, _("Token name can not be blank"))
- else:
- Token(launderette=launderette, type=token_type, name=t).save()
-
-
-class LaunderetteAdminView(CanEditPropMixin, BaseFormView, DetailView):
- """The admin page of the launderette."""
-
- model = Launderette
- pk_url_kwarg = "launderette_id"
- template_name = "launderette/launderette_admin.jinja"
- form_class = ManageTokenForm
-
- def get(self, request, *args, **kwargs):
- self.object = self.get_object()
- return super().get(request, *args, **kwargs)
-
- def post(self, request, *args, **kwargs):
- self.object = self.get_object()
- return super().post(request, *args, **kwargs)
-
- def form_valid(self, form):
- """We handle here the redirection, passing the user id of the asked customer."""
- form.process(self.object)
- if form.is_valid():
- return super().form_valid(form)
- else:
- return super().form_invalid(form)
-
- def get_context_data(self, **kwargs):
- """We handle here the login form for the barman."""
- kwargs = super().get_context_data(**kwargs)
- if self.request.method == "GET":
- kwargs["form"] = self.get_form()
- return kwargs
-
- def get_success_url(self):
- return reverse_lazy(
- "launderette:launderette_admin", args=self.args, kwargs=self.kwargs
- )
-
-
-class GetLaunderetteUserForm(GetUserForm):
- def clean(self):
- cleaned_data = super().clean()
- sub = cleaned_data["user"]
- if sub.slots.all().count() <= 0:
- raise forms.ValidationError(_("User has booked no slot"))
- return cleaned_data
-
-
-class LaunderetteMainClickView(CanEditMixin, BaseFormView, DetailView):
- """The click page of the launderette."""
-
- model = Launderette
- pk_url_kwarg = "launderette_id"
- template_name = "counter/counter_main.jinja"
- form_class = GetLaunderetteUserForm # Form to enter a client code and get the corresponding user id
-
- def get(self, request, *args, **kwargs):
- self.object = self.get_object()
- return super().get(request, *args, **kwargs)
-
- def post(self, request, *args, **kwargs):
- self.object = self.get_object()
- return super().post(request, *args, **kwargs)
-
- def form_valid(self, form):
- """We handle here the redirection, passing the user id of the asked customer."""
- self.kwargs["user_id"] = form.cleaned_data["user_id"]
- return super().form_valid(form)
-
- def get_context_data(self, **kwargs):
- """We handle here the login form for the barman."""
- kwargs = super().get_context_data(**kwargs)
- kwargs["counter"] = self.object.counter
- kwargs["form"] = self.get_form()
- kwargs["barmen"] = [self.request.user]
- if "last_basket" in self.request.session:
- kwargs["last_basket"] = self.request.session.pop("last_basket", None)
- kwargs["last_customer"] = self.request.session.pop("last_customer", None)
- kwargs["last_total"] = self.request.session.pop("last_total", None)
- kwargs["new_customer_amount"] = self.request.session.pop(
- "new_customer_amount", None
- )
- return kwargs
-
- def get_success_url(self):
- return reverse_lazy("launderette:click", args=self.args, kwargs=self.kwargs)
-
-
-class ClickTokenForm(forms.BaseForm):
- def clean(self):
- with transaction.atomic():
- operator = User.objects.filter(id=self.operator_id).first()
- customer = Customer.objects.filter(user__id=self.subscriber_id).first()
- counter = Counter.objects.filter(id=self.counter_id).first()
- subscriber = customer.user
- self.last_basket = {
- "last_basket": [],
- "last_customer": customer.user.get_display_name(),
- }
- total = 0
- for k, t in self.cleaned_data.items():
- if t is not None:
- slot_id = int(k[5:])
- slot = Slot.objects.filter(id=slot_id).first()
- slot.token = t
- slot.save()
- t.user = subscriber
- t.borrow_date = datetime.now().replace(tzinfo=tz.utc)
- t.save()
- price = settings.SITH_LAUNDERETTE_PRICES[t.type]
- s = Selling(
- label="Jeton " + t.get_type_display() + " N°" + t.name,
- club=counter.club,
- product=None,
- counter=counter,
- unit_price=price,
- quantity=1,
- seller=operator,
- customer=customer,
- )
- s.save()
- total += price
- self.last_basket["last_basket"].append(
- "Jeton " + t.get_type_display() + " N°" + t.name
- )
- self.last_basket["new_customer_amount"] = str(customer.amount)
- self.last_basket["last_total"] = str(total)
- return self.cleaned_data
-
-
-class LaunderetteClickView(CanEditMixin, DetailView, BaseFormView):
- """The click page of the launderette."""
-
- model = Launderette
- pk_url_kwarg = "launderette_id"
- template_name = "launderette/launderette_click.jinja"
-
- def get_form_class(self):
- fields = OrderedDict()
- kwargs = {}
-
- def clean_field_factory(field_name, slot):
- def clean_field(self2):
- t_name = str(self2.data[field_name])
- if t_name != "":
- t = Token.objects.filter(
- name=str(self2.data[field_name]),
- type=slot.type,
- launderette=self.object,
- user=None,
- ).first()
- if t is None:
- raise forms.ValidationError(_("Token not found"))
- return t
-
- return clean_field
-
- for s in self.subscriber.slots.filter(
- token=None, start_date__gte=timezone.now().replace(tzinfo=None)
- ).all():
- field_name = "slot-%s" % (str(s.id))
- fields[field_name] = forms.CharField(
- max_length=5,
- required=False,
- label="%s - %s"
- % (
- s.get_type_display(),
- defaultfilters.date(s.start_date, "j N Y H:i"),
- ),
- )
- # XXX l10n settings.DATETIME_FORMAT didn't work here :/
- kwargs["clean_" + field_name] = clean_field_factory(field_name, s)
- kwargs["subscriber_id"] = self.subscriber.id
- kwargs["counter_id"] = self.object.counter.id
- kwargs["operator_id"] = self.operator.id
- kwargs["base_fields"] = fields
- return type("ClickForm", (ClickTokenForm,), kwargs)
-
- def get(self, request, *args, **kwargs):
- """Simple get view."""
- self.customer = Customer.objects.filter(user__id=self.kwargs["user_id"]).first()
- self.subscriber = self.customer.user
- self.operator = request.user
- return super().get(request, *args, **kwargs)
-
- def post(self, request, *args, **kwargs):
- """Handle the many possibilities of the post request."""
- self.object = self.get_object()
- self.customer = Customer.objects.filter(user__id=self.kwargs["user_id"]).first()
- self.subscriber = self.customer.user
- self.operator = request.user
- return super().post(request, *args, **kwargs)
-
- def form_valid(self, form):
- """We handle here the redirection, passing the user id of the asked customer."""
- self.request.session.update(form.last_basket)
- return super().form_valid(form)
-
- def get_context_data(self, **kwargs):
- """We handle here the login form for the barman."""
- kwargs = super().get_context_data(**kwargs)
- if "form" not in kwargs:
- kwargs["form"] = self.get_form()
- kwargs["counter"] = self.object.counter
- kwargs["customer"] = self.customer
- return kwargs
-
- def get_success_url(self):
- self.kwargs.pop("user_id", None)
- return reverse_lazy(
- "launderette:main_click", args=self.args, kwargs=self.kwargs
- )
-
-
-class MachineEditView(CanEditPropMixin, UpdateView):
- """Edit a machine."""
-
- model = Machine
- pk_url_kwarg = "machine_id"
- fields = ["name", "launderette", "type", "is_working"]
- template_name = "core/edit.jinja"
-
-
-class MachineDeleteView(CanEditPropMixin, DeleteView):
- """Edit a machine."""
-
- model = Machine
- pk_url_kwarg = "machine_id"
- template_name = "core/delete_confirm.jinja"
- success_url = reverse_lazy("launderette:launderette_list")
-
-
-class MachineCreateView(PermissionRequiredMixin, CreateView):
- """Create a new machine."""
-
- model = Machine
- fields = ["name", "launderette", "type"]
- template_name = "core/create.jinja"
- permission_required = "launderette.add_machine"
-
- def get_initial(self):
- ret = super().get_initial()
- if "launderette" in self.request.GET:
- obj = Launderette.objects.filter(
- id=int(self.request.GET["launderette"])
- ).first()
- if obj is not None:
- ret["launderette"] = obj.id
- return ret
diff --git a/mkdocs.yml b/mkdocs.yml
index 4dfe67dc..a89bbeea 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -113,9 +113,6 @@ nav:
- galaxy:
- reference/galaxy/models.md
- reference/galaxy/views.md
- - launderette:
- - reference/launderette/models.md
- - reference/launderette/views.md
- matmat:
- reference/matmat/models.md
- reference/matmat/views.md
diff --git a/sith/settings.py b/sith/settings.py
index 5ccbd136..e1abb779 100644
--- a/sith/settings.py
+++ b/sith/settings.py
@@ -182,7 +182,6 @@ TEMPLATES = [
"can_edit": "core.auth.mixins.can_edit",
"can_view": "core.auth.mixins.can_view",
"settings": "sith.settings",
- "Launderette": "launderette.models.Launderette",
"Counter": "counter.models.Counter",
"timezone": "django.utils.timezone",
"get_sith": "com.views.sith",
@@ -658,10 +657,6 @@ with open(
) as f:
SITH_EBOUTIC_PUB_KEY = f.read()
-# Launderette variables
-SITH_LAUNDERETTE_MACHINE_TYPES = [("WASHING", _("Washing")), ("DRYING", _("Drying"))]
-SITH_LAUNDERETTE_PRICES = {"WASHING": 1.0, "DRYING": 0.75}
-
SITH_NOTIFICATIONS = [
("POSTER_MODERATION", _("A new poster needs to be moderated")),
("MAILING_MODERATION", _("A new mailing list needs to be moderated")),
diff --git a/sith/urls.py b/sith/urls.py
index 7e7e0b63..98608e14 100644
--- a/sith/urls.py
+++ b/sith/urls.py
@@ -42,10 +42,6 @@ urlpatterns = [
path("club/", include(("club.urls", "club"), namespace="club")),
path("counter/", include(("counter.urls", "counter"), namespace="counter")),
path("eboutic/", include(("eboutic.urls", "eboutic"), namespace="eboutic")),
- path(
- "launderette/",
- include(("launderette.urls", "launderette"), namespace="launderette"),
- ),
path("sas/", include(("sas.urls", "sas"), namespace="sas")),
path("election/", include(("election.urls", "election"), namespace="election")),
path("forum/", include(("forum.urls", "forum"), namespace="forum")),