grouped order creation and add items

This commit is contained in:
Laetitia Getti 2023-05-05 15:37:53 +02:00
parent 9d04b173bd
commit dc78511d9a
8 changed files with 307 additions and 4 deletions

View file

@ -0,0 +1,32 @@
from django.contrib.auth.models import User
from django.forms import CharField, ModelForm
from la_chariotte.order.models import GroupedOrder, Item
class GroupedOrderForm(ModelForm):
class Meta:
model = GroupedOrder
fields = ["name", "deadline", "delivery_date"]
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user")
super().__init__(*args, **kwargs)
def save(self, commit=True):
self.instance.orga = User.objects.get(id=self.user.pk)
return super().save(commit=commit)
class ItemCreateForm(ModelForm):
class Meta:
model = Item
fields = ["name"]
def __init__(self, *args, **kwargs):
self.grouped_order = kwargs.pop("grouped_order") # type: GroupedOrder
super().__init__(*args, **kwargs)
def save(self, commit=True):
self.instance.grouped_order = GroupedOrder.objects.get(id=self.grouped_order.pk)
return super().save(commit=commit)

View file

@ -1,5 +1,6 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db import models from django.db import models
from django.urls import reverse
from django.utils import timezone from django.utils import timezone
@ -21,6 +22,9 @@ class GroupedOrder(models.Model):
"""Returns True if the grouped order has not been delivered yet - False if it's old""" """Returns True if the grouped order has not been delivered yet - False if it's old"""
return self.delivery_date >= timezone.now().date() return self.delivery_date >= timezone.now().date()
def get_absolute_url(self):
return reverse("order:manage_items", kwargs={"pk": self.pk})
def __str__(self): # pragma: no cover def __str__(self): # pragma: no cover
return ( return (
self.name self.name
@ -48,6 +52,9 @@ class Item(models.Model):
) # à transformer en manytomany quand il y aura un catalogue ) # à transformer en manytomany quand il y aura un catalogue
ordered_nb = models.IntegerField(default=0) ordered_nb = models.IntegerField(default=0)
def get_absolute_url(self):
return reverse("order:manage_items", kwargs={"pk": self.grouped_order.pk})
def __str__(self): # pragma: no cover def __str__(self): # pragma: no cover
return f"{self.name} dans la commande groupée {self.grouped_order.pk}" return f"{self.name} dans la commande groupée {self.grouped_order.pk}"

View file

@ -0,0 +1,41 @@
{% extends 'base.html' %}
{% block title %}Nouvelle commande groupée{% endblock %}
{% block content_title %}Ajouter des produits à votre commande groupée{% endblock %}
{% block content %}
<p>Commande groupée "{{ grouped_order.name }}", le {{ grouped_order.delivery_date }}<p>
<p>Limite de commande : {{ grouped_order.deadline }}</p>
<p>Sur cette page, vous pouvez voir et modifier les produits qui sont inscrits à votre commande groupée.</p>
{% url 'order:item_create' pk=grouped_order.pk as create_item_url %}
<table class="table">
<thead>
<tr>
<th>Nom</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<form method="post" action="{{ create_item_url }}">
{% csrf_token %}
<td><input name="name" maxlength="100" placeholder="Nom du produit" required></input></td>
<td><button type="submit" class="button is-primary">Ajouter</button></td>
</tr>
{% for item in item_list %}
<tr>
<td>{{ item.name }}</td>
<td>Supprimer (pas possible pour l'instant)</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="buttons is-pulled-right">
<a href="{% url 'order:grouped_order_overview' pk=grouped_order.id %}" class="button is-primary">Valider</a>
</div>
{% endblock %}

View file

@ -0,0 +1,12 @@
{% extends 'base.html' %}
{% block title %}Nouvelle commande groupée{% endblock %}
{% block content_title %}Créer une commande groupée{% endblock %}
{% block content %}
<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
{% endblock %}

View file

@ -298,11 +298,157 @@ class TestGroupedOrderOrgaView:
"pk": grouped_order.pk, "pk": grouped_order.pk,
}, },
) )
detail_view_url = reverse( response = client_log.get(orga_view_url)
"order:grouped_order_detail", assert response.status_code == 403
class TestGroupedOrderCreateView:
def test_create_grouped_order(self, client_log):
"""
A logged user gets the grouped order creation page, and creates a grouped order.
They are redirected to the manage items page.
"""
assert GroupedOrder.objects.count() == 0
create_gorder_url = reverse("order:create_grouped_order")
response = client_log.get(create_gorder_url)
assert response.status_code == 200
date = timezone.now().date() + datetime.timedelta(days=42)
deadline = timezone.now() + datetime.timedelta(days=32)
response = client_log.post(
create_gorder_url,
{"name": "titre test", "deadline": deadline, "delivery_date": date},
)
assert response.status_code == 302
assert response.url.endswith("gerer-produits")
assert GroupedOrder.objects.count() == 1
def test_create_grouped_order__anonymous_user(self, client):
create_gorder_url = reverse("order:create_grouped_order")
response = client.get(create_gorder_url)
assert response.status_code == 302
assert response.url.startswith(reverse("accounts:login"))
assert response.url.endswith(
reverse(
"order:create_grouped_order",
)
)
class TestGroupedOrderAddItemsView:
def test_get_manage_items__user_not_orga(self, client_log, other_user):
"""
A user that is not orga cannot see the GroupedOrderAddItemsView.
They get a 403 forbidden error
"""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="gr order test",
orga_user=other_user,
)
add_items_view_url = reverse(
"order:manage_items",
kwargs={ kwargs={
"pk": grouped_order.pk, "pk": grouped_order.pk,
}, },
) )
response = client_log.get(orga_view_url) response = client_log.get(add_items_view_url)
assert response.status_code == 403
def test_get_manage_items__anonymous_user(self, client, other_user):
"""
A user that is not logged cannot see the GroupedOrderOrgaView. They get redirected to the login view
"""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="gr order test",
orga_user=other_user,
)
add_items_view_url = reverse(
"order:manage_items",
kwargs={
"pk": grouped_order.pk,
},
)
assert auth.get_user(client).is_anonymous
response = client.get(add_items_view_url)
assert response.status_code == 302
assert response.url.startswith(reverse("accounts:login"))
assert response.url.endswith(
reverse(
"order:manage_items",
kwargs={
"pk": grouped_order.pk,
},
)
)
class TestItemCreateView:
def test_create_item(self, client_log):
"""A user that has created a grouped order adds an item to it."""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="gr order test",
orga_user=auth.get_user(client_log),
)
create_item_view_url = reverse(
"order:item_create",
kwargs={
"pk": grouped_order.pk,
},
)
response = client_log.post(create_item_view_url, {"name": "titre item"})
assert response.status_code == 302
assert response.url == reverse(
"order:manage_items",
kwargs={
"pk": grouped_order.pk,
},
)
assert Item.objects.first().name == "titre item"
response = client_log.get(response.url)
assert "titre item" in response.content.decode()
def test_create_item__anonymous_user(self, client, other_user):
"""
A user that is not logged cannot create an item. They get a redirected to loginview.
"""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="gr order test",
orga_user=other_user,
)
create_item_view_url = reverse(
"order:item_create",
kwargs={
"pk": grouped_order.pk,
},
)
response = client.post(create_item_view_url, {"name": "titre item"})
assert response.status_code == 302
assert (
response.url == f"{reverse('accounts:login')}?next={create_item_view_url}"
)
def test_create_item__not_orga(self, client_log, other_user):
"""
A user that is not orga cannot create an item. They get a 403 error.
"""
grouped_order = create_grouped_order(
days_before_delivery_date=5,
days_before_deadline=2,
name="gr order test",
orga_user=other_user,
)
create_item_view_url = reverse(
"order:item_create",
kwargs={
"pk": grouped_order.pk,
},
)
response = client_log.post(create_item_view_url, {"name": "titre item"})
assert response.status_code == 403 assert response.status_code == 403

View file

@ -14,4 +14,15 @@ urlpatterns = [
name="grouped_order_overview", name="grouped_order_overview",
), ),
path("<int:grouped_order_id>/commander/", views.order, name="order"), path("<int:grouped_order_id>/commander/", views.order, name="order"),
path("creer", views.GroupedOrderCreateView.as_view(), name="create_grouped_order"),
path(
"<int:pk>/gerer-produits",
views.GroupedOrderAddItemsView.as_view(),
name="manage_items",
),
path(
"<int:pk>/gerer-produits/nouveau",
views.ItemCreateView.as_view(),
name="item_create",
),
] ]

View file

@ -5,6 +5,7 @@ from django.urls import reverse, reverse_lazy
from django.utils import timezone from django.utils import timezone
from django.views import generic from django.views import generic
from .forms import GroupedOrderForm, ItemCreateForm
from .models import GroupedOrder, Item, Order, OrderedItem from .models import GroupedOrder, Item, Order, OrderedItem
@ -70,6 +71,59 @@ class GroupedOrderOrgaView(UserPassesTestMixin, generic.DetailView):
return self.get_object().orga == self.request.user return self.get_object().orga == self.request.user
class GroupedOrderCreateView(LoginRequiredMixin, generic.CreateView):
"""View for creating a new grouped order"""
model = GroupedOrder
form_class = GroupedOrderForm
template_name = "order/grouped_order_create.html"
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["user"] = self.request.user
return kwargs
class GroupedOrderAddItemsView(UserPassesTestMixin, generic.ListView):
"""After creating grouped order, view for adding items to it"""
model = Item
template_name = "order/grouped_order_add_items.html"
queryset = Item.objects.all()
def get_queryset(self):
items = super().get_queryset()
items = items.filter(grouped_order__id=self.kwargs.get("pk"))
return items
def get_context_data(self, **kwargs):
context = super(GroupedOrderAddItemsView, self).get_context_data(**kwargs)
context["grouped_order"] = GroupedOrder.objects.get(id=self.kwargs.get("pk"))
return context
def test_func(self):
"""Accessible only if the requesting user is the grouped order organizer"""
grouped_order_id = self.kwargs.get("pk")
return GroupedOrder.objects.get(pk=grouped_order_id).orga == self.request.user
class ItemCreateView(UserPassesTestMixin, generic.CreateView):
"""CreateView for an item"""
model = Item
form_class = ItemCreateForm
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs["grouped_order"] = GroupedOrder.objects.get(id=self.kwargs.get("pk"))
return kwargs
def test_func(self):
"""Accessible only if the requesting user is the grouped order organizer"""
grouped_order_id = self.kwargs.get("pk")
return GroupedOrder.objects.get(pk=grouped_order_id).orga == self.request.user
def order( def order(
request, grouped_order_id request, grouped_order_id
): # crée une commande (order) pour cette commande groupée, avec l'item selectionné dedans ): # crée une commande (order) pour cette commande groupée, avec l'item selectionné dedans

View file

@ -81,7 +81,7 @@
Mes commandes Mes commandes
</a> </a>
<a class="navbar-item" href="{% url 'order:index' %}"> <a class="navbar-item" href="{% url 'order:create_grouped_order' %}">
Créer une commande groupée Créer une commande groupée
</a> </a>