delete an item when it's not ordered yet

This commit is contained in:
Laetitia Getti 2023-05-30 14:52:56 +02:00
parent c1026c78d1
commit 7ab2db66e2
5 changed files with 205 additions and 39 deletions

View file

@ -6,43 +6,124 @@
<p class="desktop-hidden mobile-content-title">
{% block content_title %}Ajouter des produits à votre commande groupée{% endblock %}
</p>
<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>Prix unitaire</th>
<th>Quantité max (optionnel)</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" autofocus required></input></td>
<td><input name="price" size="2" placeholder="5,40" required></input></td>
<td><input name="max_limit" size="2" placeholder="42"></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>{{ item.price }}</td>
<td>{% if item.max_limit %}{{ item.max_limit }}{% else %}---{% endif %}</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 class="buttons">
<a class="button is-light" href={% url 'order:grouped_order_overview' grouped_order.id %}>Retour</a>
<a class="button is-primary" href="{% url 'order:index' %}">Mes commandes</a>
</div>
<div class="box">
<p class="title">Gestion des produits - {{ grouped_order.name }}</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>Prix unitaire</th>
<th>Quantité max (optionnel)</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" autofocus required></input></td>
<td><input name="price" size="2" placeholder="5,40" required></input></td>
<td><input name="max_limit" size="2" placeholder="42"></input></td>
<td><button type="submit" class="button is-primary">Ajouter</button></td>
</form>
</tr>
{% for item in item_list %}
<tr>
<td>{{ item.name }}</td>
<td>{{ item.price }}</td>
<td>{% if item.max_limit %}{{ item.max_limit }}{% else %}---{% endif %}</td>
<td>
{% if item.ordered_nb == 0 %}
<button class="button is-light is-small js-modal-trigger" data-target="confirm-delete-{{ item.id }}">
Supprimer
</button>
{% else %}
Produit déjà commandé
{% endif %}
</td>
</tr>
<!-- Confirm delete modal -->
<div id="confirm-delete-{{ item.id }}" class="modal">
<div class="modal-background"></div>
<div class="modal-content">
<div class="box">
<p>Voulez-vous vraiment supprimer le produit {{ item.name }} de la commande ?</p>
<form action="{% url 'order:item_delete' grouped_order.id item.id %}" method="post">
{% csrf_token %}
<input type="submit" name="{{ item.id }}" value="Oui" class="button is-danger"/>
<a class="button is-light" href="">Non</a>
</form>
</div>
</div>
<button class="modal-close is-large" aria-label="close"></button>
</div>
{% 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>
</div>
{% endblock %}
<script>
{% block extra_js %}
document.addEventListener('DOMContentLoaded', () => {
// Functions to open and close a modal
function openModal($el) {
$el.classList.add('is-active');
}
function closeModal($el) {
$el.classList.remove('is-active');
}
function closeAllModals() {
(document.querySelectorAll('.modal') || []).forEach(($modal) => {
closeModal($modal);
});
}
// Add a click event on buttons to open a specific modal
(document.querySelectorAll('.js-modal-trigger') || []).forEach(($trigger) => {
const modal = $trigger.dataset.target;
const $target = document.getElementById(modal);
$trigger.addEventListener('click', () => {
openModal($target);
});
});
// Add a click event on various child elements to close the parent modal
(document.querySelectorAll('.modal-background, .modal-close, .modal-card-head .delete, .modal-card-foot .button') || []).forEach(($close) => {
const $target = $close.closest('.modal');
$close.addEventListener('click', () => {
closeModal($target);
});
});
// Add a keyboard event to close all modals
document.addEventListener('keydown', (event) => {
const e = event || window.event;
if (e.keyCode === 27) { // Escape key
closeAllModals();
}
});
});
{% endblock %}
</script>

View file

@ -22,7 +22,9 @@
{% endif %}
<p>Date de livraison : {{ grouped_order.delivery_date }}</p>
<p>Date limite de commande : {{ grouped_order.deadline }}</p>
<a class="button is-light" href={% url 'order:grouped_order_detail' grouped_order.id %}>Retour à la page de commande</a>
<div class="buttons">
<a class="button is-light" href={% url 'order:grouped_order_detail' grouped_order.id %}>Retour à la page de commande</a>
</div>
</div>
</div>
</div>
@ -54,6 +56,7 @@
</div>
<div class="box">
<a class="button is-primary is-pulled-right" href="{% url 'order:manage_items' grouped_order.pk %}">Gérer les produits</a>
<p class="title">Produits commandés</p>
{% if grouped_order.item_set.all %}
<table class="table">

View file

@ -779,6 +779,67 @@ class TestGroupedOrderAddItemsView:
)
)
def test_delete_item(self, client_log):
"""
A user on the manage item page creates and then deletes an item
"""
assert models.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 models.GroupedOrder.objects.count() == 1
# Create an item
grouped_order = models.GroupedOrder.objects.first()
create_item_url = reverse("order:item_create", args=[grouped_order.id])
response = client_log.post(create_item_url, {"name": "Pain test", "price": "2"})
response.status_code == 302
response.url == reverse("order:manage_items", args=[grouped_order.pk])
assert grouped_order.item_set.count() == 1
# Delete the item
item = grouped_order.item_set.first()
delete_item_url = reverse("order:item_delete", args=[grouped_order.id, item.id])
response = client_log.post(delete_item_url)
assert response.status_code == 302
assert response.url == reverse("order:manage_items", args=[grouped_order.pk])
assert grouped_order.item_set.count() == 0
def test_create_or_delete_item__not_orga(self, client_log, other_user):
"""
A user that is not orga delete or create an item
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,
)
# Create an item
grouped_order = models.GroupedOrder.objects.first()
create_item_url = reverse("order:item_create", args=[grouped_order.id])
response = client_log.post(create_item_url, {"name": "Pain test", "price": "2"})
response.status_code == 403
assert grouped_order.item_set.count() == 0
# Delete an item
item = grouped_order.item_set.create(name="Pain test", price="2")
assert grouped_order.item_set.count() == 1
delete_item_url = reverse("order:item_delete", args=[grouped_order.id, item.id])
response = client_log.post(delete_item_url)
assert response.status_code == 403
assert grouped_order.item_set.count() == 1
class TestItemCreateView:
def test_create_item(self, client_log):

View file

@ -30,6 +30,11 @@ urlpatterns = [
views.ItemCreateView.as_view(),
name="item_create",
),
path(
"<int:grouped_order_id>/gerer-produits/<int:pk>/supprimer",
views.ItemDeleteView.as_view(),
name="item_delete",
),
path(
"<int:pk>/gerer/imprimer",
views.GroupedOrderSheetView.as_view(),

View file

@ -130,6 +130,7 @@ class GroupedOrderAddItemsView(UserPassesTestMixin, generic.ListView):
def test_func(self):
"""Accessible only if the requesting user is the grouped order organizer"""
grouped_order_id = self.kwargs.get("pk")
# breakpoint()
return GroupedOrder.objects.get(pk=grouped_order_id).orga == self.request.user
@ -150,6 +151,21 @@ class ItemCreateView(UserPassesTestMixin, generic.CreateView):
return GroupedOrder.objects.get(pk=grouped_order_id).orga == self.request.user
class ItemDeleteView(UserPassesTestMixin, generic.DeleteView):
"""DeleteView for an item
The form does a GET to this view - it displays a confirmation page - then we post this view
"""
model = Item
def get_success_url(self):
return reverse_lazy("order:manage_items", args=[self.object.grouped_order.id])
def test_func(self):
"""Accessible only if the requesting user is the grouped order organizer"""
return self.get_object().grouped_order.orga == self.request.user
def order(request, grouped_order_id):
"""Creates an AnonymousUser, and an Order for this GroupedOrder, with related OrderedItems"""
grouped_order = get_object_or_404(GroupedOrder, pk=grouped_order_id)