Author SHA1 Message Date
imperosol 15c5a37c99 docs: fix nushell scripts 2026-10-12 14:08:12 +02:00
imperosol 07648f596e docs: describe populated user accounts 2026-10-12 13:51:18 +02:00
9 changed files with 122 additions and 128 deletions

No files matched your search

+7 -19
View File
@@ -83,17 +83,8 @@
{% endmacro %} {% endmacro %}
{% block content %} {% block content %}
<div class="alert alert-yellow">
<div class="alert-main">
{%- trans trimmed -%}
You can see product details.
However, you cannot edit it, thus you won't be able
to submit this form.
{%- endtrans -%}
</div>
</div>
{% if object %} {% if object %}
<h2>{{ object }}</h2> <h2>{% trans name=object %}Edit product {{ name }}{% endtrans %}</h2>
<p><i>{% trans %}Creation date{% endtrans %} : {{ object.created_at|date }}</i></p> <p><i>{% trans %}Creation date{% endtrans %} : {{ object.created_at|date }}</i></p>
<p><i>{% trans %}Last update{% endtrans %} : {{ object.updated_at|date }}</i></p> <p><i>{% trans %}Last update{% endtrans %} : {{ object.updated_at|date }}</i></p>
{% else %} {% else %}
@@ -136,17 +127,19 @@
{{ form.price_formset.management_form }} {{ form.price_formset.management_form }}
<div x-ref="formContainer"> <div x-ref="formContainer">
{%- for form in form.price_formset.forms -%} {%- for form in form.price_formset.forms -%}
<div>{{ price_form(form) }}</div> <div>
{{ price_form(form) }}
</div>
{%- endfor -%} {%- endfor -%}
</div> </div>
<template x-ref="formTemplate"> <template x-ref="formTemplate">
<div>{{ price_form(form.price_formset.empty_form) }}</div> <div>
{{ price_form(form.price_formset.empty_form) }}
</div>
</template> </template>
{% if user.has_perm("counter.change_product") %}
<button class="btn btn-grey" @click.prevent="addForm()"> <button class="btn btn-grey" @click.prevent="addForm()">
<i class="fa fa-plus"></i> {% trans %}Add a price{% endtrans %} <i class="fa fa-plus"></i> {% trans %}Add a price{% endtrans %}
</button> </button>
{% endif %}
</div> </div>
<br /> <br />
@@ -172,16 +165,11 @@
<template x-ref="formTemplate"> <template x-ref="formTemplate">
{{ action_form(form.action_formset.empty_form) }} {{ action_form(form.action_formset.empty_form) }}
</template> </template>
{% if user.has_perm("counter.change_product") %}
<button @click.prevent="addForm()" class="btn btn-grey"> <button @click.prevent="addForm()" class="btn btn-grey">
<i class="fa fa-plus"></i>{% trans %}Add action{% endtrans %} <i class="fa fa-plus"></i>{% trans %}Add action{% endtrans %}
</button> </button>
{% endif %}
</div> </div>
<div class="row gap margin-bottom">{{ form.archived.as_field_group() }}</div> <div class="row gap margin-bottom">{{ form.archived.as_field_group() }}</div>
{% if user.has_perm("counter.change_product") %}
<p><input class="btn btn-blue" type="submit" value="{% trans %}Save{% endtrans %}" /></p> <p><input class="btn btn-blue" type="submit" value="{% trans %}Save{% endtrans %}" /></p>
{% endif %}
</form> </form>
{% endblock %} {% endblock %}
@@ -80,11 +80,9 @@
<h3 class="margin-bottom">{% trans %}Product list{% endtrans %}</h3> <h3 class="margin-bottom">{% trans %}Product list{% endtrans %}</h3>
<div class="row margin-bottom"> <div class="row margin-bottom">
{% if user.has_perm("counter.add_product") %}
<a href="{{ url('counter:new_product') }}" class="btn btn-blue"> <a href="{{ url('counter:new_product') }}" class="btn btn-blue">
{% trans %}New product{% endtrans %} <i class="fa fa-plus"></i> {% trans %}New product{% endtrans %} <i class="fa fa-plus"></i>
</a> </a>
{% endif %}
<button <button
class="btn btn-blue" class="btn btn-blue"
@click="downloadCsv()" @click="downloadCsv()"
@@ -13,12 +13,12 @@
{% endblock %} {% endblock %}
{% block content %} {% block content %}
{% if user.has_perm("counter.add_producttype") %} <p>
<a href="{{ url('counter:new_product_type') }}" class="btn btn-blue margin-bottom"> <a href="{{ url('counter:new_product_type') }}" class="btn btn-blue">
{% trans %}New product type{% endtrans %} {% trans %}New product type{% endtrans %}
<i class="fa fa-plus"></i> <i class="fa fa-plus"></i>
</a> </a>
{% endif %} </p>
{% if product_types %} {% if product_types %}
<aside> <aside>
<p> <p>
+21 -34
View File
@@ -48,7 +48,7 @@ from counter.models import (
Selling, Selling,
) )
from counter.utils import is_logged_in_counter from counter.utils import is_logged_in_counter
from counter.views.mixins import CounterAdminTabsMixin from counter.views.mixins import CounterAdminMixin, CounterAdminTabsMixin
class CounterListView(CounterAdminTabsMixin, CanViewMixin, ListView): class CounterListView(CounterAdminTabsMixin, CanViewMixin, ListView):
@@ -84,18 +84,17 @@ class CounterEditView(
return reverse_lazy("counter:admin", kwargs={"counter_id": self.object.id}) return reverse_lazy("counter:admin", kwargs={"counter_id": self.object.id})
class CounterEditPropView(CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView): class CounterEditPropView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView):
"""Edit a counter's main infos.""" """Edit a counter's main informations (for the counter's admin)."""
model = Counter model = Counter
form_class = modelform_factory(Counter, fields=["name", "club", "type"]) form_class = modelform_factory(Counter, fields=["name", "club", "type"])
pk_url_kwarg = "counter_id" pk_url_kwarg = "counter_id"
template_name = "core/edit.jinja" template_name = "core/edit.jinja"
current_tab = "counters" current_tab = "counters"
permission_required = "counter.change_counter"
class CounterCreateView(CounterAdminTabsMixin, PermissionRequiredMixin, CreateView): class CounterCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView):
"""Create a counter (for the admins).""" """Create a counter (for the admins)."""
model = Counter model = Counter
@@ -106,10 +105,9 @@ class CounterCreateView(CounterAdminTabsMixin, PermissionRequiredMixin, CreateVi
) )
template_name = "core/create.jinja" template_name = "core/create.jinja"
current_tab = "counters" current_tab = "counters"
permission_required = "counter.add_counter"
class CounterDeleteView(CounterAdminTabsMixin, PermissionRequiredMixin, DeleteView): class CounterDeleteView(CounterAdminTabsMixin, CounterAdminMixin, DeleteView):
"""Delete a counter (for the admins).""" """Delete a counter (for the admins)."""
model = Counter model = Counter
@@ -117,33 +115,30 @@ class CounterDeleteView(CounterAdminTabsMixin, PermissionRequiredMixin, DeleteVi
template_name = "core/delete_confirm.jinja" template_name = "core/delete_confirm.jinja"
success_url = reverse_lazy("counter:admin_list") success_url = reverse_lazy("counter:admin_list")
current_tab = "counters" current_tab = "counters"
permission_required = "counter.delete_counter"
# Product management # Product management
class ProductTypeListView(CounterAdminTabsMixin, PermissionRequiredMixin, ListView): class ProductTypeListView(CounterAdminTabsMixin, CounterAdminMixin, ListView):
"""A list view for the admins.""" """A list view for the admins."""
model = ProductType model = ProductType
template_name = "counter/product_type_list.jinja" template_name = "counter/product_type_list.jinja"
current_tab = "product_types" current_tab = "product_types"
context_object_name = "product_types" context_object_name = "product_types"
permission_required = "counter.view_producttype"
class ProductTypeCreateView(CounterAdminTabsMixin, PermissionRequiredMixin, CreateView): class ProductTypeCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView):
"""A create view for the admins.""" """A create view for the admins."""
model = ProductType model = ProductType
fields = ["name", "description", "comment", "icon"] fields = ["name", "description", "comment", "icon"]
template_name = "core/create.jinja" template_name = "core/create.jinja"
current_tab = "products" current_tab = "products"
permission_required = "counter.add_producttype"
class ProductTypeEditView(CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView): class ProductTypeEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView):
"""An edit view for the admins.""" """An edit view for the admins."""
model = ProductType model = ProductType
@@ -151,26 +146,23 @@ class ProductTypeEditView(CounterAdminTabsMixin, PermissionRequiredMixin, Update
fields = ["name", "description", "comment", "icon"] fields = ["name", "description", "comment", "icon"]
pk_url_kwarg = "type_id" pk_url_kwarg = "type_id"
current_tab = "products" current_tab = "products"
permission_required = "counter.change_producttype"
class ProductListView(CounterAdminTabsMixin, PermissionRequiredMixin, TemplateView): class ProductListView(CounterAdminTabsMixin, CounterAdminMixin, TemplateView):
current_tab = "products" current_tab = "products"
template_name = "counter/product_list.jinja" template_name = "counter/product_list.jinja"
permission_required = "counter.view_product"
class ProductCreateView(CounterAdminTabsMixin, PermissionRequiredMixin, CreateView): class ProductCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView):
"""A create view for the admins.""" """A create view for the admins."""
model = Product model = Product
form_class = ProductForm form_class = ProductForm
template_name = "counter/product_form.jinja" template_name = "counter/product_form.jinja"
current_tab = "products" current_tab = "products"
permission_required = "counter.add_product"
class ProductEditView(CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView): class ProductEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView):
"""An edit view for the admins.""" """An edit view for the admins."""
model = Product model = Product
@@ -178,13 +170,6 @@ class ProductEditView(CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView
pk_url_kwarg = "product_id" pk_url_kwarg = "product_id"
template_name = "counter/product_form.jinja" template_name = "counter/product_form.jinja"
current_tab = "products" current_tab = "products"
permission_required = "counter.change_product"
def has_permission(self):
return self.request.user.has_perm("counter.change_product") or (
self.request.method == "GET"
and self.request.user.has_perm("counter.view_product")
)
class ProductFormulaListView(CounterAdminTabsMixin, PermissionRequiredMixin, ListView): class ProductFormulaListView(CounterAdminTabsMixin, PermissionRequiredMixin, ListView):
@@ -314,6 +299,7 @@ class RefillingDeleteView(DeleteView):
template_name = "core/delete_confirm.jinja" template_name = "core/delete_confirm.jinja"
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
"""We have here a very particular right handling, we can't inherit from CanEditPropMixin."""
self.object = self.get_object() self.object = self.get_object()
if timezone.now() - self.object.date <= timedelta( if timezone.now() - self.object.date <= timedelta(
minutes=settings.SITH_LAST_OPERATIONS_LIMIT minutes=settings.SITH_LAST_OPERATIONS_LIMIT
@@ -338,6 +324,7 @@ class SellingDeleteView(DeleteView):
template_name = "core/delete_confirm.jinja" template_name = "core/delete_confirm.jinja"
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
"""We have here a very particular right handling, we can't inherit from CanEditPropMixin."""
self.object = self.get_object() self.object = self.get_object()
if timezone.now() - self.object.date <= timedelta( if timezone.now() - self.object.date <= timedelta(
minutes=settings.SITH_LAST_OPERATIONS_LIMIT minutes=settings.SITH_LAST_OPERATIONS_LIMIT
@@ -389,23 +376,23 @@ class CounterStatView(PermissionRequiredMixin, DetailView):
return kwargs return kwargs
class CounterRefillingListView( class CounterRefillingListView(CounterAdminTabsMixin, CounterAdminMixin, ListView):
CounterAdminTabsMixin, PermissionRequiredMixin, ListView
):
"""List of refillings on a counter.""" """List of refillings on a counter."""
model = Refilling model = Refilling
template_name = "counter/refilling_list.jinja" template_name = "counter/refilling_list.jinja"
current_tab = "counters" current_tab = "counters"
paginate_by = 30 paginate_by = 30
permission_required = "counter.view_refilling"
def get_queryset(self): def dispatch(self, request, *args, **kwargs):
self.counter = get_object_or_404(Counter, pk=self.kwargs["counter_id"]) self.counter = get_object_or_404(Counter, pk=kwargs["counter_id"])
return Refilling.objects.filter(counter=self.counter).order_by("-date") self.queryset = Refilling.objects.filter(counter__id=self.counter.id)
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
return super().get_context_data(**kwargs) | {"counter": self.counter} kwargs = super().get_context_data(**kwargs)
kwargs["counter"] = self.counter
return kwargs
class RefoundAccountView(UserPassesTestMixin, FormView): class RefoundAccountView(UserPassesTestMixin, FormView):
+5 -8
View File
@@ -12,7 +12,7 @@
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# #
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic import DetailView, ListView from django.views.generic import DetailView, ListView
@@ -21,30 +21,28 @@ from django.views.generic.edit import CreateView, UpdateView
from core.auth.mixins import CanViewMixin from core.auth.mixins import CanViewMixin
from counter.forms import EticketForm from counter.forms import EticketForm
from counter.models import Eticket, Selling from counter.models import Eticket, Selling
from counter.views.mixins import CounterAdminTabsMixin from counter.views.mixins import CounterAdminMixin, CounterAdminTabsMixin
class EticketListView(CounterAdminTabsMixin, PermissionRequiredMixin, ListView): class EticketListView(CounterAdminTabsMixin, CounterAdminMixin, ListView):
"""A list view for the admins.""" """A list view for the admins."""
model = Eticket model = Eticket
template_name = "counter/eticket_list.jinja" template_name = "counter/eticket_list.jinja"
ordering = ["id"] ordering = ["id"]
current_tab = "etickets" current_tab = "etickets"
permission_required = "counter.view_eticket"
class EticketCreateView(CounterAdminTabsMixin, PermissionRequiredMixin, CreateView): class EticketCreateView(CounterAdminTabsMixin, CounterAdminMixin, CreateView):
"""Create an eticket.""" """Create an eticket."""
model = Eticket model = Eticket
template_name = "core/create.jinja" template_name = "core/create.jinja"
form_class = EticketForm form_class = EticketForm
current_tab = "etickets" current_tab = "etickets"
permission_required = "counter.add_eticket"
class EticketEditView(CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView): class EticketEditView(CounterAdminTabsMixin, CounterAdminMixin, UpdateView):
"""Edit an eticket.""" """Edit an eticket."""
model = Eticket model = Eticket
@@ -52,7 +50,6 @@ class EticketEditView(CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView
form_class = EticketForm form_class = EticketForm
pk_url_kwarg = "eticket_id" pk_url_kwarg = "eticket_id"
current_tab = "etickets" current_tab = "etickets"
permission_required = "counter.change_eticket"
class EticketPDFView(CanViewMixin, DetailView): class EticketPDFView(CanViewMixin, DetailView):
+35 -35
View File
@@ -13,13 +13,38 @@
# #
# #
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic.base import View
from core.views.mixins import TabedViewMixin from core.views.mixins import TabedViewMixin
from counter.utils import is_logged_in_counter from counter.utils import is_logged_in_counter
class CounterAdminMixin(View):
"""Protect counter admin section."""
edit_group = [settings.SITH_GROUP_COUNTER_ADMIN_ID]
edit_club = []
def _test_group(self, user):
return any(user.is_in_group(pk=grp_id) for grp_id in self.edit_group)
def _test_club(self, user):
return any(c.can_be_edited_by(user) for c in self.edit_club)
def dispatch(self, request, *args, **kwargs):
if not (
request.user.is_root
or self._test_group(request.user)
or self._test_club(request.user)
):
raise PermissionDenied
return super().dispatch(request, *args, **kwargs)
class CounterTabsMixin(TabedViewMixin): class CounterTabsMixin(TabedViewMixin):
def get_tabs_title(self): def get_tabs_title(self):
return self.object return self.object
@@ -64,70 +89,45 @@ class CounterTabsMixin(TabedViewMixin):
class CounterAdminTabsMixin(TabedViewMixin): class CounterAdminTabsMixin(TabedViewMixin):
tabs_title = _("Counter administration") tabs_title = _("Counter administration")
list_of_tabs = [
def get_list_of_tabs(self):
user = self.request.user
res = [
{ {
"url": reverse_lazy("counter:admin_list"), "url": reverse_lazy("counter:admin_list"),
"slug": "counters", "slug": "counters",
"name": _("Counters"), "name": _("Counters"),
} },
]
if user.has_perm("counter.view_product"):
res.append(
{ {
"url": reverse_lazy("counter:product_list"), "url": reverse_lazy("counter:product_list"),
"slug": "products", "slug": "products",
"name": _("Products"), "name": _("Products"),
} },
)
if user.has_perm("counter.view_productformula"):
res.append(
{ {
"url": reverse_lazy("counter:product_formula_list"), "url": reverse_lazy("counter:product_formula_list"),
"slug": "formulas", "slug": "formulas",
"name": _("Formulas"), "name": _("Formulas"),
} },
)
if user.has_perm("counter.view_producttype"):
res.append(
{ {
"url": reverse_lazy("counter:product_type_list"), "url": reverse_lazy("counter:product_type_list"),
"slug": "product_types", "slug": "product_types",
"name": _("Product types"), "name": _("Product types"),
} },
)
if user.has_perm("counter.view_returnableproduct"):
res.append(
{ {
"url": reverse_lazy("counter:returnable_list"), "url": reverse_lazy("counter:returnable_list"),
"slug": "returnable_products", "slug": "returnable_products",
"name": _("Returnable products"), "name": _("Returnable products"),
} },
)
if user.has_perm("counter.view_cashregistersummary"):
res.append(
{ {
"url": reverse_lazy("counter:cash_summary_list"), "url": reverse_lazy("counter:cash_summary_list"),
"slug": "cash_summary", "slug": "cash_summary",
"name": _("Cash register summaries"), "name": _("Cash register summaries"),
} },
)
if user.has_perm("counter.view_invoicecall"):
res.append(
{ {
"url": reverse_lazy("counter:invoices_call"), "url": reverse_lazy("counter:invoices_call"),
"slug": "invoices_call", "slug": "invoices_call",
"name": _("Invoices call"), "name": _("Invoices call"),
} },
)
if user.has_perm("counter.view_eticket"):
res.append(
{ {
"url": reverse_lazy("counter:eticket_list"), "url": reverse_lazy("counter:eticket_list"),
"slug": "etickets", "slug": "etickets",
"name": _("Etickets"), "name": _("Etickets"),
} },
) ]
return res
+5 -7
View File
@@ -48,7 +48,7 @@ des scripts complets mais qui restent lisibles,
``` ```
Ok, c'est de la triche, on installe un package externe. Ok, c'est de la triche, on installe un package externe.
Mais bon, ça marche, et l'équivalent pur bash Mais bon, ça marche, et l'équivalent pur bash
serait carrément plus moche. serait un pur enfer.
=== "nu" === "nu"
@@ -59,20 +59,18 @@ des scripts complets mais qui restent lisibles,
Nombre de lignes total : Nombre de lignes total :
```nu ```nu
ls **/*.py | insert linecount { get name | open | lines | length } | math sum ls **/*.py | par-each { open $in.name | lines | length } | math sum
``` ```
Vous pouvez aussi exlure les lignes vides Vous pouvez aussi exlure les lignes vides
et les les lignes de commentaire : et les les lignes de commentaire :
```nu ```nu
ls **/*.py | ls **/*.py |
insert linecount { par-each {
get name | open $in.name |
open |
lines | lines |
each { str trim } | each { str trim } |
filter { |l| not ($l | str starts-with "#") } | # commentaires where { |l| ($l | str length) > 0 and not ($l | str starts-with "#") } |
filter { |l| ($l | str length) > 0 } | # lignes vides
length length
} | } |
math sum math sum
+33 -9
View File
@@ -18,7 +18,8 @@ il n'est pas possible de développer le site sur ce système d'exploitation.
Heureusement, il existe une alternative qui ne requiert pas de désinstaller votre Heureusement, il existe une alternative qui ne requiert pas de désinstaller votre
OS ni de mettre un dual boot sur votre ordinateur : `WSL`. OS ni de mettre un dual boot sur votre ordinateur : `WSL`.
- **Prérequis:** vous devez être sur Windows 10 version 2004 ou ultérieure (build 19041 & versions ultérieures) ou Windows 11. - **Prérequis:** vous devez être sur Windows 10 version 2004 ou ultérieure (build 19041 & versions ultérieures) ou
Windows 11.
- **Plus d'info:** [docs.microsoft.com](https://docs.microsoft.com/fr-fr/windows/wsl/install) - **Plus d'info:** [docs.microsoft.com](https://docs.microsoft.com/fr-fr/windows/wsl/install)
```shell ```shell
@@ -43,7 +44,7 @@ il suffit d'utiliser la commande suivante :
cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab
``` ```
!!!note !!!success
À ce stade, si vous avez réussi votre installation de `WSL` ou bien qu'il À ce stade, si vous avez réussi votre installation de `WSL` ou bien qu'il
était déjà installé, vous pouvez effectuer la mise en place du projet en suivant était déjà installé, vous pouvez effectuer la mise en place du projet en suivant
@@ -101,10 +102,10 @@ cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab
ln -s /usr/bin/valkey-server /usr/bin/redis-server ln -s /usr/bin/valkey-server /usr/bin/redis-server
``` ```
=== "macOS" === "macOS"
Pour installer les dépendances, il est fortement recommandé d'installer le gestionnaire de paquets `homebrew <https://brew.sh/index_fr>`_. Pour installer les dépendances, il est fortement recommandé
d'installer le gestionnaire de paquets `homebrew <https://brew.sh/index_fr>`_.
Il est également nécessaire d'avoir installé xcode Il est également nécessaire d'avoir installé xcode
```bash ```bash
@@ -116,12 +117,15 @@ cd /mnt/<la_lettre_du_disque>/vos/fichiers/comme/dhab
!!!note !!!note
Si vous rencontrez des erreurs lors de votre configuration, n'hésitez pas à vérifier l'état de votre installation homebrew avec :code:`brew doctor` Si vous rencontrez des erreurs lors de votre configuration,
n'hésitez pas à vérifier l'état de votre installation homebrew
avec :code:`brew doctor`
!!!note !!!note
Python ne fait pas parti des dépendances puisqu'il est automatiquement Python ne fait pas parti des dépendances puisqu'il est automatiquement
installé par uv. Il est cependant parfois nécessaire d'installer les headers Python nécessaire à la compilation de certains paquets. installé par uv. Il est cependant parfois nécessaire d'installer
les headers Python nécessaire à la compilation de certains paquets.
## Finaliser l'installation ## Finaliser l'installation
@@ -145,7 +149,6 @@ uv run ./manage.py install_xapian
de texte à l'écran. de texte à l'écran.
C'est normal, il ne faut pas avoir peur. C'est normal, il ne faut pas avoir peur.
La modification de la configuration passe par la modification de variables La modification de la configuration passe par la modification de variables
d'environnement. d'environnement.
Ces variables sont stockées dans un fichier `.env`. Ces variables sont stockées dans un fichier `.env`.
@@ -183,12 +186,33 @@ Il suffit ensuite d'utiliser cette commande :
uv run ./manage.py runserver uv run ./manage.py runserver
``` ```
!!!note
Le serveur est alors accessible à l'adresse Le serveur est alors accessible à l'adresse
[http://localhost:8000](http://localhost:8000) [http://localhost:8000](http://localhost:8000)
ou bien [http://127.0.0.1:8000/](http://127.0.0.1:8000/). ou bien [http://127.0.0.1:8000/](http://127.0.0.1:8000/).
Pour vous connecter, vous pouvez utiliser un des comptes utilisateur
créés durant l'installation :
| username | description |
|------------------|----------------------------------------------------------------------------|
| `root` | super-utilisateur<br/>il peut tout faire et tout voir |
| `subscriber` | simple cotisant |
| `old_subscriber` | ancien cotisant |
| `public` | non-cotisant |
| `krophil` | cotisant<br/>barman Foyer<br/>président du Troll Penché |
| `sli` | cotisant<br/>VP Troll |
| `skia` | cotisant<br/>barman MDE<br/>membre du bureau AE<br/>ancien membre du Troll |
| `comunity` | cotisant<br/>membre du bureau PdF<br/>admin communication |
| `counter` | cotisant<br/>admin comptoirs |
| `comptable` | cotisant<br/>admin comptabilité |
| `rbatsbak` | cotisant<br/>membre du Troll |
En plus de ces dernier, quelques centaines d'utilisateurs
supplémentaires sont générés procéduralement,
afin de rajouter un peu de volume de données.
Tous les utilisateurs ont le mot de passe `plop`.
!!!note !!!note
Le serveur de développement se charge de lancer redis Le serveur de développement se charge de lancer redis
+13 -11
View File
@@ -6,7 +6,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-10-09 21:44+0200\n" "POT-Creation-Date: 2026-10-02 12:56+0200\n"
"PO-Revision-Date: 2016-07-18\n" "PO-Revision-Date: 2016-07-18\n"
"Last-Translator: Maréchal <thomas.girod@utbm.fr\n" "Last-Translator: Maréchal <thomas.girod@utbm.fr\n"
"Language-Team: AE info <ae.info@utbm.fr>\n" "Language-Team: AE info <ae.info@utbm.fr>\n"
@@ -236,7 +236,7 @@ msgstr "vous devez spécifier au moins un utilisateur ou une adresse email"
msgid "Begin date" msgid "Begin date"
msgstr "Date de début" msgstr "Date de début"
#: club/forms.py com/forms.py counter/forms.py #: club/forms.py com/forms.py counter/forms.py subscription/forms.py
msgid "End date" msgid "End date"
msgstr "Date de fin" msgstr "Date de fin"
@@ -1093,7 +1093,7 @@ msgstr "Prix d'achat"
msgid "Format: 16:9 | Resolution: 1920x1080" msgid "Format: 16:9 | Resolution: 1920x1080"
msgstr "Format : 16:9 | Résolution : 1920x1080" msgstr "Format : 16:9 | Résolution : 1920x1080"
#: com/forms.py #: com/forms.py subscription/forms.py
msgid "Start date" msgid "Start date"
msgstr "Date de début" msgstr "Date de début"
@@ -4102,6 +4102,7 @@ msgstr "Nouvelle formule"
#: counter/templates/counter/fragments/create_student_card.jinja #: counter/templates/counter/fragments/create_student_card.jinja
#: counter/templates/counter/invoices_call.jinja #: counter/templates/counter/invoices_call.jinja
#: sas/templates/sas/picture.jinja #: sas/templates/sas/picture.jinja
#: subscription/templates/subscription/stats.jinja
msgid "Go" msgid "Go"
msgstr "Valider" msgstr "Valider"
@@ -4236,12 +4237,9 @@ msgid "Remove price"
msgstr "Retirer le prix" msgstr "Retirer le prix"
#: counter/templates/counter/product_form.jinja #: counter/templates/counter/product_form.jinja
msgid "" #, python-format
"You can see product details. However, you cannot edit it, thus you won't be " msgid "Edit product %(name)s"
"able to submit this form." msgstr "Édition du produit %(name)s"
msgstr ""
"Vous pouvez voir ce produit. Cependant, vous ne pouvez pas l'éditer ; vous "
"ne serez donc pas en mesure de soumettre le formulaire."
#: counter/templates/counter/product_form.jinja #: counter/templates/counter/product_form.jinja
msgid "Creation date" msgid "Creation date"
@@ -5987,8 +5985,12 @@ msgid "Create another subscription"
msgstr "Créer une nouvelle cotisation" msgstr "Créer une nouvelle cotisation"
#: subscription/templates/subscription/stats.jinja #: subscription/templates/subscription/stats.jinja
msgid "All subscriptions" msgid "Total subscriptions"
msgstr "Toutes les cotisations" msgstr "Cotisations totales"
#: subscription/templates/subscription/stats.jinja
msgid "Subscriptions by type"
msgstr "Cotisations par type"
#: subscription/templates/subscription/subscription.jinja #: subscription/templates/subscription/subscription.jinja
msgid "Existing member" msgid "Existing member"