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 @@

{% trans %}Counters:{% endtrans %}

- {% if object.id == settings.SITH_LAUNDERETTE_CLUB_ID %} -
  • {% trans %}Manage launderettes{% endtrans %}
  • - {% endif %} {% endblock %} diff --git a/core/management/commands/populate.py b/core/management/commands/populate.py index 96d322f2..ea1f0342 100644 --- a/core/management/commands/populate.py +++ b/core/management/commands/populate.py @@ -123,11 +123,6 @@ class Command(BaseCommand): name="PdF", address="6 Boulevard Anatole France, 90000 Belfort", ) - Club.objects.create( - id=settings.SITH_LAUNDERETTE_CLUB_ID, - name="Laverie", - address="6 Boulevard Anatole France, 90000 Belfort", - ) self.reset_index("club") for bar_id, bar_name in settings.SITH_COUNTER_BARS: @@ -291,13 +286,7 @@ class Command(BaseCommand): page=services_page, title="Services", author=skia, - content=""" -| | | | -| :---: | :---: | :---: | -| [Eboutic](/eboutic) | [Laverie](/launderette) | Matmat | -| SAS | Weekmail | Forum| - -""", + content="- [Eboutic](/eboutic)\n- Matmat\n- SAS\n- Weekmail\n- Forum", ) index_page = Page(name="Index") @@ -306,23 +295,10 @@ class Command(BaseCommand): page=index_page, title="Wiki index", author=root, - content=""" -Welcome to the wiki page! -""", + content="Welcome to the wiki page!", ) - laundry_page = Page(name="launderette") - laundry_page.save(force_lock=True) - PageRev.objects.create( - page=laundry_page, - title="Laverie", - author=root, - content="Fonctionnement de la laverie", - ) - - groups.public.viewable_page.set( - [syntax_page, services_page, index_page, laundry_page] - ) + groups.public.viewable_page.set([syntax_page, services_page, index_page]) self._create_subscription(root) self._create_subscription(skia) @@ -868,7 +844,7 @@ Welcome to the wiki page! counter_admin.permissions.add( *list( perms.filter( - Q(content_type__app_label__in=["counter", "launderette"]) + Q(content_type__app_label__in=["counter"]) & ~Q(codename__in=["delete_product", "delete_producttype"]) ) ) diff --git a/core/models.py b/core/models.py index 5c873c6c..1f02ad84 100644 --- a/core/models.py +++ b/core/models.py @@ -421,14 +421,6 @@ class User(AbstractUser): def is_board_member(self) -> bool: return self.groups.filter(club_board=settings.SITH_MAIN_CLUB_ID).exists() - @cached_property - def is_launderette_manager(self): - from club.models import Club - - return Club.objects.get( - id=settings.SITH_LAUNDERETTE_CLUB_ID - ).get_membership_for(self) - @cached_property def is_banned_alcohol(self) -> bool: return self.ban_groups.filter(id=settings.SITH_GROUP_BANNED_ALCOHOL_ID).exists() @@ -676,10 +668,6 @@ class AnonymousUser(AuthAnonymousUser): def is_board_member(self): return False - @property - def is_launderette_manager(self): - return False - @property def is_banned_alcohol(self): return False diff --git a/core/static/core/style.scss b/core/static/core/style.scss index 58b188fc..8d1421a8 100644 --- a/core/static/core/style.scss +++ b/core/static/core/style.scss @@ -822,12 +822,6 @@ textarea { margin-top: 10px; } -/*---------------------------LAUNDERETTE-------------------------------*/ - -#token_form label { - display: inline; -} - /*--------------------------------FOOTER-------------------------------*/ footer { diff --git a/core/templates/core/base/navbar.jinja b/core/templates/core/base/navbar.jinja index fcdd4b1b..09fac241 100644 --- a/core/templates/core/base/navbar.jinja +++ b/core/templates/core/base/navbar.jinja @@ -24,7 +24,6 @@ {% trans %}Services{% endtrans %} diff --git a/core/templates/core/macros.jinja b/core/templates/core/macros.jinja index b43ba844..40676258 100644 --- a/core/templates/core/macros.jinja +++ b/core/templates/core/macros.jinja @@ -86,19 +86,6 @@ {% trans %}Account number: {% endtrans %}{{ user.customer.account_id }}
    {%- endmacro %} -{% macro show_slots(user) %} - {% if user.slots.filter(start_date__gte=timezone.now()).exists() %} -
    {% trans %}Slot{% endtrans %}
    - - {% endif %} -{% endmacro %} - {% macro show_tokens(user) %} {% if user.tokens.exists() %}
    {% trans %}Tokens{% endtrans %}
    diff --git a/core/templates/core/user_detail.jinja b/core/templates/core/user_detail.jinja index 771ead72..4ad1f5d9 100644 --- a/core/templates/core/user_detail.jinja +++ b/core/templates/core/user_detail.jinja @@ -141,12 +141,6 @@ {{ user_subscription(profile) }} {% endif %} - {% if user == profile or user.is_root or user.is_board_member or user.is_launderette_manager %} -
    - {{ 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 %}

    -

    -

    - {% csrf_token %} -

    {{ form.action.errors }} - {% for c in form.action %} - {{ c }} - {% endfor %} -

    -

    {{ form.token_type.errors }} - {% for c in form.token_type %} - {{ c }} - {% endfor %} -

    - {{ form.tokens }} -

    -
    -

    -

    - - - - - - - - - - - {% for t in launderette.tokens.all() %} - - - - {% if t.user %} - - - {% else %} - - - {% endif %} - - {% endfor %} - -
    {% trans %}Type{% endtrans %}{% trans %}Name{% endtrans %}{% trans %}User{% endtrans %}{% trans %}Since{% endtrans %}
    {{ t.get_type_display() }}{{ t.name }}{{ t.user.get_display_name() }}{{ t.borrow_date|date(DATETIME_FORMAT) }} - {{ t.borrow_date|time(DATETIME_FORMAT) }}
    -

    -{% 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) %} -
    - {% csrf_token %} - - -
    -{% endmacro %} - - -{% block content %} -

    {{ launderette }}

    -

    -

    - {% csrf_token %} - -
    -
    - {% csrf_token %} - -
    -
    - {% csrf_token %} - -
    -

    - - - - {% for day in planning.keys() %} - - {% endfor %} - - - - {% for i in range(0, 24) %} - - {% for hours in planning.values() %} - - {% endfor %} - - {% endfor %} - -
    {{ day|date('l') }}
    - {% if hours[i] %} - {{ hours[i]|time(TIME_FORMAT) }} {{ choose(hours[i]) }} - {% endif %} -
    - {{ 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 %} - - {% 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 %}

    -
    -
    - {% csrf_token %} - {{ form.as_p() }} -

    -
    -
    -{% 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")),