Add the ability to use a code to join an order.

This commit is contained in:
Alexis Métaireau 2023-08-14 17:36:13 +02:00
parent cf2c79cc3f
commit b4bdfb8cf4
8 changed files with 100 additions and 8 deletions

View file

@ -80,3 +80,15 @@ class ItemCreateForm(forms.ModelForm):
def save(self, commit=True): def save(self, commit=True):
self.instance.grouped_order = GroupedOrder.objects.get(id=self.grouped_order.pk) self.instance.grouped_order = GroupedOrder.objects.get(id=self.grouped_order.pk)
return super().save(commit=commit) return super().save(commit=commit)
class JoinGroupedOrderForm(forms.Form):
code = forms.CharField(label="Code pour rejoindre la commande", max_length=6)
def clean_code(self):
form_code = self.cleaned_data["code"]
if not GroupedOrder.objects.filter(code=form_code).exists():
raise forms.ValidationError(
"Désolé, nous ne trouvons aucune commande avec ce code"
)
return form_code

View file

@ -0,0 +1,43 @@
{% extends 'base.html' %}
{% block title %}Rejoindre une commande{% endblock %}
{% block content %}
<p class="desktop-hidden mobile-content-title">
{% block content_title %}Rejoindre une commande groupée{% endblock %}
</p>
<div class="box">
<div class="columns">
<div class="column is-8">
<h3>Utiliser un code</h3>
<p>Si vous avez un code pour rejoindre une distribution, entrez-le ici.</p>
<form method="post">
{% csrf_token %}
{% for error in form.code.errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
<div class="field has-addons">
<div class="control">
<input name="code" class="input {% if form.code.errors %}is-danger{% endif %}" type="text">
</div>
<div class="control">
<input class="button is-primary" type="submit" value="Rejoindre">
</div>
</div>
</div>
</form>
</div>
</div>
<div class="box">
<h4>Vous avez un lien ?</h4>
<p>Si vous avez reçu un lien par un organisateur ou une organisatrice de commande, vous pouvez coller ce lien dans
la barre de navigation en haut de l'écran !</p>
</div>
<p>Sinon, vous pouvez vous <a href="{% url 'accounts:signup' %}">créer un compte</a> ou <a
href="{% url 'accounts:login' %}">vous connecter</a>
pour organiser une nouvelle commande groupée.
</div>
{% endblock %}

View file

@ -190,6 +190,35 @@ class TestGroupedOrderIndexView:
) )
class TestJoinGroupedOrderView:
def test_correct_code_redirects_properly(self, client, client_log):
logged_user = auth.get_user(client_log)
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="test",
orga_user=logged_user,
)
join_url = reverse("order:grouped_order_join")
response = client.post(join_url, {"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_incorrect_code_errors_out(self, client):
assert len(models.GroupedOrder.objects.all()) == 0
join_url = reverse("order:grouped_order_join")
response = client.post(join_url, {"code": "123456"})
assert (
"nous ne trouvons aucune commande avec ce code" in response.content.decode()
)
class TestGroupedOrderDetailView: class TestGroupedOrderDetailView:
def test_order_item(self, client, other_user): def test_order_item(self, client, other_user):
""" """

View file

@ -1,4 +1,3 @@
# fmt: off
import datetime import datetime
import pytest import pytest
@ -12,7 +11,6 @@ from la_chariotte.order.tests.utils import (
order_items_in_grouped_order, order_items_in_grouped_order,
) )
# fmt: on
pytestmark = pytest.mark.django_db pytestmark = pytest.mark.django_db

View file

@ -13,9 +13,6 @@ pytestmark = pytest.mark.django_db
def create_grouped_order( def create_grouped_order(
days_before_delivery_date, days_before_deadline, name, orga_user days_before_delivery_date, days_before_deadline, name, orga_user
): ):
"""
Creates a grouped order.
"""
date = timezone.now().date() + datetime.timedelta(days=days_before_delivery_date) date = timezone.now().date() + datetime.timedelta(days=days_before_delivery_date)
deadline = timezone.now() + datetime.timedelta(days=days_before_deadline) deadline = timezone.now() + datetime.timedelta(days=days_before_deadline)
grouped_order = models.GroupedOrder.objects.create( grouped_order = models.GroupedOrder.objects.create(

View file

@ -8,7 +8,7 @@ urlpatterns = [
path("", views.IndexView.as_view(), name="index"), path("", views.IndexView.as_view(), name="index"),
path( path(
"rejoindre-une-commande", "rejoindre-une-commande",
TemplateView.as_view(template_name="order/grouped_order_join.html"), views.JoinGroupedOrderView.as_view(),
name="grouped_order_join", name="grouped_order_join",
), ),
path( path(

View file

@ -11,6 +11,7 @@ from .grouped_order import (
GroupedOrderOverview, GroupedOrderOverview,
GroupedOrderUpdateView, GroupedOrderUpdateView,
IndexView, IndexView,
JoinGroupedOrderView,
) )
from .item import ItemCreateView, ItemDeleteView from .item import ItemCreateView, ItemDeleteView
from .order import OrderDeleteView, OrderDetailView, place_order from .order import OrderDeleteView, OrderDetailView, place_order

View file

@ -5,7 +5,7 @@ from io import BytesIO
from django import http from django import http
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers.json import DjangoJSONEncoder
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404, redirect
from django.template.loader import get_template from django.template.loader import get_template
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.utils import timezone from django.utils import timezone
@ -14,7 +14,7 @@ from django_weasyprint import WeasyTemplateResponseMixin
from django_weasyprint.views import WeasyTemplateResponse, WeasyTemplateView from django_weasyprint.views import WeasyTemplateResponse, WeasyTemplateView
from xhtml2pdf import pisa from xhtml2pdf import pisa
from ..forms import GroupedOrderForm, Item from ..forms import GroupedOrderForm, Item, JoinGroupedOrderForm
from ..models import GroupedOrder, OrderAuthor from ..models import GroupedOrder, OrderAuthor
@ -52,6 +52,18 @@ class IndexView(LoginRequiredMixin, generic.ListView):
} }
class JoinGroupedOrderView(generic.FormView, generic.RedirectView, LoginRequiredMixin):
form_class = JoinGroupedOrderForm
template_name = "order/grouped_order_join.html"
def form_valid(self, form):
return redirect(
reverse_lazy(
"order:grouped_order_detail", kwargs={"code": form.cleaned_data["code"]}
)
)
class GroupedOrderDetailView(generic.DetailView): class GroupedOrderDetailView(generic.DetailView):
model = GroupedOrder model = GroupedOrder
template_name = "order/grouped_order_detail.html" template_name = "order/grouped_order_detail.html"