Compare commits

..

2 commits

Author SHA1 Message Date
selfhoster1312 ACAB
ed60e4762a Merge branch 'feat-distribution-place' into 'develop'
Draft: feature: Add placekey relationship for distribution spots

See merge request la-chariotte/la-chariotte!129
2025-03-05 12:53:01 +00:00
selfhoster1312
cef342de83 feature: Add place relationship for distribution spots 2025-03-05 13:52:56 +01:00
5 changed files with 157 additions and 30 deletions

View file

@ -101,15 +101,31 @@ class ItemCreateForm(forms.ModelForm):
class JoinGroupedOrderForm(forms.Form): class JoinGroupedOrderForm(forms.Form):
code = forms.CharField(label="Code pour rejoindre la commande", max_length=6) order_code = forms.CharField(
label="Code pour rejoindre la commande", max_length=6, required=False
)
place_code = forms.CharField(
label="Code pour rejoindre le lieu", max_length=20, required=False
)
def clean_code(self): def clean_place_code(self):
form_code = self.cleaned_data["code"] form_place_code = self.cleaned_data["place_code"]
if not GroupedOrder.objects.filter(code=form_code).exists(): if form_place_code and not Place.objects.filter(code=form_place_code).exists():
raise forms.ValidationError(
"Désolé, nous ne trouvons aucun lieu avec ce code"
)
return form_place_code
def clean_order_code(self):
form_order_code = self.cleaned_data["order_code"]
if (
form_order_code
and not GroupedOrder.objects.filter(code=form_order_code).exists()
):
raise forms.ValidationError( raise forms.ValidationError(
"Désolé, nous ne trouvons aucune commande avec ce code" "Désolé, nous ne trouvons aucune commande avec ce code"
) )
return form_code return form_order_code
class PlaceForm(forms.ModelForm): class PlaceForm(forms.ModelForm):

View file

@ -55,11 +55,31 @@ class JoinGroupedOrderView(generic.FormView, generic.RedirectView, LoginRequired
template_name = "dashboard.html" template_name = "dashboard.html"
def form_valid(self, form): def form_valid(self, form):
return redirect( # Give priority to order code, for arbitrary reasons
reverse_lazy( if form.cleaned_data["order_code"]:
"order:grouped_order_detail", kwargs={"code": form.cleaned_data["code"]} return redirect(
reverse_lazy(
"order:grouped_order_detail",
kwargs={"code": form.cleaned_data["order_code"]},
)
) )
) elif form.cleaned_data["place_code"]:
return redirect(
reverse_lazy(
"order:place_overview",
kwargs={"code": form.cleaned_data["place_code"]},
)
)
else:
# No valid data found. Either no data was supplied, or they failed validation.
if (
"order_code" not in form.data
or not form.data["order_code"]
or "place_code" not in form.data
or not form.data["place_code"]
):
# No data supplied, redirect to dashboard
return redirect(reverse_lazy("dashboard"))
class GroupedOrderEventView(generic.DetailView): class GroupedOrderEventView(generic.DetailView):

View file

@ -86,6 +86,9 @@
<a class="navbar-item" href="{% url 'order:index' %}"> <a class="navbar-item" href="{% url 'order:index' %}">
<i class="fa fa-shopping-basket mr-3" aria-hidden="true"></i>Mes commandes groupées <i class="fa fa-shopping-basket mr-3" aria-hidden="true"></i>Mes commandes groupées
</a> </a>
<a class="navbar-item" href="{% url 'order:place_index' %}">
<i class="fa fa-home mr-3" aria-hidden="true"></i>Mes lieux de distribution
</a>
{% endif %} {% endif %}
<a class="navbar-item" href="{% url 'about_chariotte' %}"> <a class="navbar-item" href="{% url 'about_chariotte' %}">
<i class="fa fa-info-circle mr-3" aria-hidden="true"></i>La Chariotte, c'est quoi&nbsp;? <i class="fa fa-info-circle mr-3" aria-hidden="true"></i>La Chariotte, c'est quoi&nbsp;?

View file

@ -5,6 +5,17 @@
{% block content %} {% block content %}
{% load static %} {% load static %}
{% if user.is_authenticated %}
<div class="buttons is-centered mt-3">
<a class="button is-primary" href="{% url 'order:index' %}">
<i class="fa fa-shopping-basket mr-3" aria-hidden="true"></i>Mes commandes groupées
</a>
<a class="button is-primary" href="{% url 'order:place_index' %}">
<i class="fa fa-home mr-3" aria-hidden="true"></i>Mes lieux de distribution
</a>
</div>
{% endif %}
<p class="desktop-hidden mobile-content-title"> <p class="desktop-hidden mobile-content-title">
{% block content_title %}Bienvenue{% if user.is_authenticated %}, {{ user.first_name }}{% else %} sur la Chariotte !{% endif %}{% endblock %} {% block content_title %}Bienvenue{% if user.is_authenticated %}, {{ user.first_name }}{% else %} sur la Chariotte !{% endif %}{% endblock %}
</p> </p>
@ -15,15 +26,15 @@
<p>Si vous avez un code à 6 caractères, entrez-le ici :</p> <p>Si vous avez un code à 6 caractères, entrez-le ici :</p>
<form method="post"> <form method="post">
{% csrf_token %} {% csrf_token %}
{% for error in form.code.errors %} {% for error in form.order_code.errors %}
<p class="help is-danger">{{ error }}</p> <p class="help is-danger">{{ error }}</p>
{% endfor %} {% endfor %}
<div class="field has-addons"> <div class="field has-addons">
<div class="control"> <div class="control">
<input name="code" class="input {% if form.code.errors %}is-danger{% endif %}" type="text"> <input name="order_code" class="input {% if form.order_code.errors %}is-danger{% endif %}" type="text">
</div> </div>
<div class="control"> <div class="control">
<input class="button is-primary" type="submit" value="Rejoindre"> <input class="button is-primary" type="submit" value="Rejoindre une commande">
</div> </div>
</div> </div>
</form> </form>
@ -31,23 +42,42 @@
</div> </div>
<div class="column is-half"> <div class="column is-half">
<div class="box full-height"> <div class="box full-height">
{% if user.is_authenticated %} <p class="subtitle">Rejoindre un lieu de distribution</p>
<p class="subtitle">... Ou accédez à vos commandes groupées</p> <p>Si vous avez un code de lieu, entrez-le ici :</p>
<a class="button is-primary" href="{% url 'order:index' %}"> <form method="post">
<i class="fa fa-shopping-basket mr-3" aria-hidden="true"></i>Mes commandes groupées {% csrf_token %}
</a> {% for error in form.place_code.errors %}
{% else %} <p class="help is-danger">{{ error }}</p>
<p class="subtitle">... Ou connectez-vous pour organiser une commande groupée</p> {% endfor %}
<a class="button is-primary" href="{% url 'accounts:login' %}"> <div class="field has-addons">
<i class="fa fa-sign-in mr-3" aria-hidden="true"></i>Se connecter <div class="control">
</a> <input name="place_code" class="input {% if form.place_code.errors %}is-danger{% endif %}" type="text">
<a class="button is-light" href="{% url 'accounts:signup' %}"> </div>
<strong>Créer un compte</strong> <div class="control">
</a> <input class="button is-primary" type="submit" value="Rejoindre un lieu">
{% endif %} </div>
</div>
</form>
</div> </div>
</div> </div>
</div> </div>
{% if not user.is_authenticated %}
<div class="columns is-centered">
<div class="column is-centered is-half">
<div class="box">
<p class="subtitle">... Ou connectez-vous pour organiser une commande groupée</p>
<div class="buttons is-centered mt-3">
<a class="button is-primary" href="{% url 'accounts:login' %}">
<i class="fa fa-sign-in mr-3" aria-hidden="true"></i>Se connecter
</a>
<a class="button is-light" href="{% url 'accounts:signup' %}">
<strong>Créer un compte</strong>
</a>
</div>
</div>
</div>
</div>
{% endif %}
<div class="columns is-centered"> <div class="columns is-centered">
<div class="column is-10"> <div class="column is-10">
<div class="box"> <div class="box">

View file

@ -191,7 +191,7 @@ class TestGroupedOrderIndexView:
class TestJoinGroupedOrderView: class TestJoinGroupedOrderView:
def test_correct_code_redirects_properly(self, client, client_log): def test_correct_order_code_redirects_properly(self, client, client_log):
logged_user = auth.get_user(client_log) logged_user = auth.get_user(client_log)
grouped_order = create_grouped_order( grouped_order = create_grouped_order(
days_before_delivery_date=5, days_before_delivery_date=5,
@ -200,7 +200,7 @@ class TestJoinGroupedOrderView:
orga_user=logged_user, orga_user=logged_user,
) )
join_url = reverse("dashboard") join_url = reverse("dashboard")
response = client.post(join_url, {"code": grouped_order.code}) response = client.post(join_url, {"order_code": grouped_order.code})
expected_url = reverse( expected_url = reverse(
"order:grouped_order_detail", kwargs={"code": grouped_order.code} "order:grouped_order_detail", kwargs={"code": grouped_order.code}
@ -208,17 +208,75 @@ class TestJoinGroupedOrderView:
assert response.status_code == 302 assert response.status_code == 302
assert response.url == expected_url assert response.url == expected_url
def test_incorrect_code_errors_out(self, client): def test_incorrect_order_code_errors_out(self, client):
assert len(models.GroupedOrder.objects.all()) == 0 assert len(models.GroupedOrder.objects.all()) == 0
join_url = reverse("dashboard") join_url = reverse("dashboard")
response = client.post(join_url, {"code": "123456"}) response = client.post(join_url, {"order_code": "123456"})
assert ( assert (
"Désolé, nous ne trouvons aucune commande avec ce code" "Désolé, nous ne trouvons aucune commande avec ce code"
in response.content.decode() in response.content.decode()
) )
def test_correct_place_code_redirects_properly(self, client, client_log):
place = models.Place.objects.create(
name="foo",
orga=auth.get_user(client_log),
code="foo",
)
join_url = reverse("dashboard")
response = client.post(join_url, {"place_code": place.code})
expected_url = reverse("order:place_overview", kwargs={"code": place.code})
assert response.status_code == 302
assert response.url == expected_url
def test_incorrect_place_code_errors_out(self, client):
assert len(models.Place.objects.all()) == 0
join_url = reverse("dashboard")
response = client.post(join_url, {"place_code": "123456"})
assert (
"Désolé, nous ne trouvons aucun lieu avec ce code"
in response.content.decode()
)
def test_correct_order_code_has_precedence(self, client, client_log):
logged_user = auth.get_user(client_log)
place = models.Place.objects.create(
name="foo",
orga=logged_user,
code="foo",
)
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="test",
orga_user=logged_user,
)
join_url = reverse("dashboard")
response = client.post(
join_url, {"place_code": place.code, "order_code": grouped_order.code}
)
expected_url = reverse(
"order:grouped_order_detail", kwargs={"code": grouped_order.code}
)
assert response.status_code == 302
assert response.url == expected_url
def test_no_code_redirects_to_dashboard(self, client_log):
join_url = reverse("dashboard")
response = client_log.post(join_url, {})
assert response.status_code == 302
assert response.url == join_url
class TestGroupedOrderDetailView: class TestGroupedOrderDetailView:
def test_order_item_with_authenticated_user(self, client, connected_grouped_order): def test_order_item_with_authenticated_user(self, client, connected_grouped_order):