mirror of
https://framagit.org/la-chariotte/la-chariotte.git
synced 2025-05-01 03:12:26 +02:00
grouped order creation and add items
This commit is contained in:
parent
9d04b173bd
commit
dc78511d9a
8 changed files with 307 additions and 4 deletions
32
la_chariotte/order/forms.py
Normal file
32
la_chariotte/order/forms.py
Normal 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)
|
|
@ -1,5 +1,6 @@
|
|||
from django.contrib.auth.models import User
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
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"""
|
||||
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
|
||||
return (
|
||||
self.name
|
||||
|
@ -48,6 +52,9 @@ class Item(models.Model):
|
|||
) # à transformer en manytomany quand il y aura un catalogue
|
||||
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
|
||||
return f"{self.name} dans la commande groupée {self.grouped_order.pk}"
|
||||
|
||||
|
|
|
@ -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 %}
|
12
la_chariotte/order/templates/order/grouped_order_create.html
Normal file
12
la_chariotte/order/templates/order/grouped_order_create.html
Normal 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 %}
|
|
@ -298,11 +298,157 @@ class TestGroupedOrderOrgaView:
|
|||
"pk": grouped_order.pk,
|
||||
},
|
||||
)
|
||||
detail_view_url = reverse(
|
||||
"order:grouped_order_detail",
|
||||
response = client_log.get(orga_view_url)
|
||||
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={
|
||||
"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
|
||||
|
|
|
@ -14,4 +14,15 @@ urlpatterns = [
|
|||
name="grouped_order_overview",
|
||||
),
|
||||
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",
|
||||
),
|
||||
]
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.urls import reverse, reverse_lazy
|
|||
from django.utils import timezone
|
||||
from django.views import generic
|
||||
|
||||
from .forms import GroupedOrderForm, ItemCreateForm
|
||||
from .models import GroupedOrder, Item, Order, OrderedItem
|
||||
|
||||
|
||||
|
@ -70,6 +71,59 @@ class GroupedOrderOrgaView(UserPassesTestMixin, generic.DetailView):
|
|||
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(
|
||||
request, grouped_order_id
|
||||
): # crée une commande (order) pour cette commande groupée, avec l'item selectionné dedans
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
Mes commandes
|
||||
</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
|
||||
</a>
|
||||
|
||||
|
|
Loading…
Reference in a new issue