mirror of
https://framagit.org/la-chariotte/la-chariotte.git
synced 2025-05-17 11:11:49 +02:00
Compare commits
2 commits
a8ab66d94d
...
f069bf0ae6
Author | SHA1 | Date | |
---|---|---|---|
![]() |
f069bf0ae6 | ||
![]() |
a93864d2af |
10 changed files with 331 additions and 17 deletions
|
@ -31,7 +31,7 @@ def link_existing_place(apps, schema_editor):
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
dependencies = [
|
dependencies = [
|
||||||
("order", "0029_set_phone_mandatory_for_existing_orders"),
|
("order", "0030_alter_groupedorder_code_alter_orderauthor_email_and_more"),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
|
@ -228,3 +228,12 @@ class Place(models.Model):
|
||||||
|
|
||||||
def get_absolute_url(self):
|
def get_absolute_url(self):
|
||||||
return reverse("order:place_update", kwargs={"code": self.code})
|
return reverse("order:place_update", kwargs={"code": self.code})
|
||||||
|
|
||||||
|
def active_orders(self):
|
||||||
|
# Only return currently active orders (not yet delivered)
|
||||||
|
active_orders = (
|
||||||
|
self.orders.all()
|
||||||
|
.filter(delivery_date__gt=timezone.now())
|
||||||
|
.order_by("-delivery_date")
|
||||||
|
)
|
||||||
|
return active_orders
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{% if place.code in context.orders.keys %}
|
{% if place.code in context.orders.keys %}
|
||||||
{% for place_url, place_orders in context.orders.items %}
|
{% for place_code, place_orders in context.orders.items %}
|
||||||
{% if place_url == place.code %}
|
{% if place_code == place.code %}
|
||||||
{% for order in place_orders %}
|
{% for order in place_orders %}
|
||||||
{% url 'order:grouped_order_detail' code=order.code as order_url %}
|
{% url 'order:grouped_order_detail' code=order.code as order_url %}
|
||||||
{% if order_url %}
|
{% if order_url %}
|
||||||
|
|
|
@ -326,11 +326,11 @@ class GroupedOrderExportView(UserIsOrgaMixin, generic.DetailView):
|
||||||
context["orders_dict"] = orders_dict
|
context["orders_dict"] = orders_dict
|
||||||
|
|
||||||
if grouped_order.has_places:
|
if grouped_order.has_places:
|
||||||
places = dict()
|
# Initialize empty list of orders for every place enabled for this GroupedOrder
|
||||||
|
places = {x.code: {} for x in grouped_order.places.all()}
|
||||||
|
|
||||||
for order, order_items in orders_dict.items():
|
for order, order_items in orders_dict.items():
|
||||||
if order.place.name not in places:
|
places[order.place.code][order] = order_items
|
||||||
lieux[order.place.name] = dict()
|
|
||||||
lieux[order.place.name][order] = order_items
|
|
||||||
context["places"] = places
|
context["places"] = places
|
||||||
|
|
||||||
return context
|
return context
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from django import http
|
from django import http
|
||||||
from django.contrib.auth.mixins import UserPassesTestMixin
|
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||||
|
from django.core.exceptions import SuspiciousOperation
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from django.urls import reverse, reverse_lazy
|
from django.urls import reverse, reverse_lazy
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
@ -50,6 +51,13 @@ def place_order(request, code):
|
||||||
# Make sure requested place is valid in this group order (and exists at all)
|
# Make sure requested place is valid in this group order (and exists at all)
|
||||||
# If no places are enabled for this group order, chosen place is always None
|
# If no places are enabled for this group order, chosen place is always None
|
||||||
if grouped_order.has_places:
|
if grouped_order.has_places:
|
||||||
|
# If places are enabled for the GroupedOrder
|
||||||
|
if "place" not in request.POST:
|
||||||
|
# HTTP error code 400
|
||||||
|
raise SuspiciousOperation(
|
||||||
|
"Aucun lieu n'est spécifié alors que la commande groupée en exige un"
|
||||||
|
)
|
||||||
|
|
||||||
places = grouped_order.places.all()
|
places = grouped_order.places.all()
|
||||||
# Return 404 if the requested place does not exist at all
|
# Return 404 if the requested place does not exist at all
|
||||||
place = get_object_or_404(Place, code=request.POST["place"])
|
place = get_object_or_404(Place, code=request.POST["place"])
|
||||||
|
|
|
@ -26,15 +26,14 @@ class PlaceIndexView(LoginRequiredMixin, generic.ListView):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
places = Place.objects.filter(orga=self.request.user)
|
places = Place.objects.filter(orga=self.request.user)
|
||||||
print(places)
|
|
||||||
|
|
||||||
# Let's filter orders by distribution place (for UI grouping)
|
# Let's filter orders by distribution place (for UI grouping)
|
||||||
orders = dict()
|
orders = dict()
|
||||||
for place in places:
|
for place in places:
|
||||||
# TODO: maybe filter out finished GroupedOrder?
|
# Only get currently-active grouped orders
|
||||||
if place.orders.all():
|
active_orders = place.active_orders()
|
||||||
orders[place.code] = place.orders.all()
|
if active_orders:
|
||||||
# orders[place.code] = orders
|
orders[place.code] = active_orders
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"places": places,
|
"places": places,
|
||||||
|
|
|
@ -5,7 +5,7 @@ from django.contrib import auth
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from la_chariotte.order.models import GroupedOrder, Item
|
from la_chariotte.order.models import GroupedOrder, Item, Place
|
||||||
|
|
||||||
from .utils import create_grouped_order
|
from .utils import create_grouped_order
|
||||||
|
|
||||||
|
@ -140,3 +140,70 @@ class TestItemModel:
|
||||||
assert grouped_order.item_set.first() == item
|
assert grouped_order.item_set.first() == item
|
||||||
assert grouped_order.item_set.all()[1] == item3
|
assert grouped_order.item_set.all()[1] == item3
|
||||||
assert grouped_order.item_set.all()[2] == item2
|
assert grouped_order.item_set.all()[2] == item2
|
||||||
|
|
||||||
|
|
||||||
|
class TestPlaceModel:
|
||||||
|
def test_create_place(self, client_log):
|
||||||
|
assert Place.objects.count() == 0
|
||||||
|
create_place_url = reverse("order:place_create")
|
||||||
|
response = client_log.get(create_place_url)
|
||||||
|
assert response.status_code == 200
|
||||||
|
response = client_log.post(
|
||||||
|
create_place_url,
|
||||||
|
{
|
||||||
|
"name": "Centre social Kropotkine",
|
||||||
|
"code": "kropotkine",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 302
|
||||||
|
assert Place.objects.count() == 1
|
||||||
|
|
||||||
|
def test_order_has_places(self, client_log):
|
||||||
|
now = timezone.now()
|
||||||
|
|
||||||
|
place = Place.objects.create(
|
||||||
|
name="Centre social Kropotkine",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
code="kropotkine",
|
||||||
|
)
|
||||||
|
|
||||||
|
grouped_order_active = GroupedOrder.objects.create(
|
||||||
|
name="test",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
delivery_date=now.date(),
|
||||||
|
deadline=now + datetime.timedelta(days=30),
|
||||||
|
)
|
||||||
|
assert grouped_order_active.has_places == False
|
||||||
|
grouped_order_active.places.add(place.id)
|
||||||
|
assert grouped_order_active.has_places == True
|
||||||
|
|
||||||
|
def test_place_active_orders(self, client_log):
|
||||||
|
now = timezone.now()
|
||||||
|
|
||||||
|
place = Place.objects.create(
|
||||||
|
name="Centre Social Kropotkine",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
code="kropotkine",
|
||||||
|
)
|
||||||
|
|
||||||
|
grouped_order_active = GroupedOrder.objects.create(
|
||||||
|
name="test",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
delivery_date=now.date() + datetime.timedelta(days=30),
|
||||||
|
deadline=now + datetime.timedelta(days=30),
|
||||||
|
)
|
||||||
|
grouped_order_active.places.add(place.id)
|
||||||
|
|
||||||
|
grouped_order_inactive = GroupedOrder.objects.create(
|
||||||
|
name="test",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
delivery_date=now.date() - datetime.timedelta(days=30),
|
||||||
|
deadline=now + datetime.timedelta(days=30),
|
||||||
|
)
|
||||||
|
grouped_order_inactive.places.add(place.id)
|
||||||
|
|
||||||
|
assert place.orders.all().count() == 2
|
||||||
|
|
||||||
|
active_orders = place.active_orders()
|
||||||
|
assert active_orders.count() == 1
|
||||||
|
assert active_orders.first().id == grouped_order_active.id
|
||||||
|
|
|
@ -1437,6 +1437,7 @@ class TestGroupedOrderSheetView:
|
||||||
assert response.context["grouped_order"] == grouped_order
|
assert response.context["grouped_order"] == grouped_order
|
||||||
assert len(response.context["items"]) == 0
|
assert len(response.context["items"]) == 0
|
||||||
assert len(response.context["orders_dict"]) == 0
|
assert len(response.context["orders_dict"]) == 0
|
||||||
|
assert "places" not in response.context.keys()
|
||||||
|
|
||||||
# we order some items in the grouped order
|
# we order some items in the grouped order
|
||||||
order = order_items_in_grouped_order(grouped_order)
|
order = order_items_in_grouped_order(grouped_order)
|
||||||
|
@ -1446,6 +1447,7 @@ class TestGroupedOrderSheetView:
|
||||||
assert len(response.context["items"]) == 2
|
assert len(response.context["items"]) == 2
|
||||||
assert response.context["orders_dict"][order] == [3, 2]
|
assert response.context["orders_dict"][order] == [3, 2]
|
||||||
assert response.context["grouped_order"].total_price == 35
|
assert response.context["grouped_order"].total_price == 35
|
||||||
|
assert "places" not in response.context.keys()
|
||||||
|
|
||||||
# test if the orders are sorted by last names
|
# test if the orders are sorted by last names
|
||||||
orders = list(response.context["orders_dict"].keys())
|
orders = list(response.context["orders_dict"].keys())
|
||||||
|
@ -1455,6 +1457,74 @@ class TestGroupedOrderSheetView:
|
||||||
assert orders[1].author.first_name == "bobby"
|
assert orders[1].author.first_name == "bobby"
|
||||||
assert orders[2].author.last_name == "lescargot"
|
assert orders[2].author.last_name == "lescargot"
|
||||||
|
|
||||||
|
def test_get_pdf_sheet_with_places(self, client_log, other_user):
|
||||||
|
"""The orga of the grouped models.Order accesses the pdf sheet"""
|
||||||
|
|
||||||
|
place1 = models.Place.objects.create(
|
||||||
|
name="Centre social Kropotkine",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
code="kropotkine",
|
||||||
|
)
|
||||||
|
place2 = models.Place.objects.create(
|
||||||
|
name="Centre social Luxemburg",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
code="luxemburg",
|
||||||
|
)
|
||||||
|
|
||||||
|
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),
|
||||||
|
)
|
||||||
|
grouped_order.places.add(place1.id)
|
||||||
|
grouped_order.places.add(place2.id)
|
||||||
|
generate_sheet_url = reverse(
|
||||||
|
"order:grouped_order_sheet",
|
||||||
|
kwargs={
|
||||||
|
"code": grouped_order.code,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
response = client_log.get(generate_sheet_url)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.context["grouped_order"] == grouped_order
|
||||||
|
assert len(response.context["items"]) == 0
|
||||||
|
assert len(response.context["orders_dict"]) == 0
|
||||||
|
assert "places" in response.context.keys()
|
||||||
|
assert len(response.context["places"]) == 2
|
||||||
|
assert len(response.context["places"]["kropotkine"]) == 0
|
||||||
|
assert len(response.context["places"]["luxemburg"]) == 0
|
||||||
|
|
||||||
|
# we order some items in the grouped order
|
||||||
|
order = order_items_in_grouped_order(grouped_order, place=place2)
|
||||||
|
response = client_log.get(generate_sheet_url)
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.context["grouped_order"] == grouped_order
|
||||||
|
assert len(response.context["items"]) == 2
|
||||||
|
assert response.context["orders_dict"][order] == [3, 2]
|
||||||
|
assert response.context["grouped_order"].total_price == 35
|
||||||
|
assert "places" in response.context.keys()
|
||||||
|
|
||||||
|
# test that orders are split by distribution place
|
||||||
|
places = response.context["places"]
|
||||||
|
assert len(places["kropotkine"]) == 0
|
||||||
|
assert len(places["luxemburg"]) == 3
|
||||||
|
|
||||||
|
orders = list(places["luxemburg"])
|
||||||
|
assert orders[0].author.last_name == "alescargot"
|
||||||
|
assert orders[0].author.first_name == "bob"
|
||||||
|
assert orders[1].author.last_name == "alescargot"
|
||||||
|
assert orders[1].author.first_name == "bobby"
|
||||||
|
assert orders[2].author.last_name == "lescargot"
|
||||||
|
|
||||||
|
# test that splitting by place does not affect orders_dict overall
|
||||||
|
orders = list(response.context["orders_dict"].keys())
|
||||||
|
assert orders[0].author.last_name == "alescargot"
|
||||||
|
assert orders[0].author.first_name == "bob"
|
||||||
|
assert orders[1].author.last_name == "alescargot"
|
||||||
|
assert orders[1].author.first_name == "bobby"
|
||||||
|
assert orders[2].author.last_name == "lescargot"
|
||||||
|
|
||||||
|
|
||||||
class TestExportGroupOrderEmailAdressesToDownloadView:
|
class TestExportGroupOrderEmailAdressesToDownloadView:
|
||||||
def test_user_not_logged_gets_redirected(self, client, other_user):
|
def test_user_not_logged_gets_redirected(self, client, other_user):
|
||||||
|
|
|
@ -268,3 +268,164 @@ class TestOrder:
|
||||||
assert grouped_order.order_set.all().count() == 2
|
assert grouped_order.order_set.all().count() == 2
|
||||||
assert grouped_order.total_price == 35 - order_price
|
assert grouped_order.total_price == 35 - order_price
|
||||||
assert item.ordered_nb == 1
|
assert item.ordered_nb == 1
|
||||||
|
|
||||||
|
def test_order_valid_place(self, client_log):
|
||||||
|
"""The orga user requests a non-existing place for distribution. It fails"""
|
||||||
|
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),
|
||||||
|
)
|
||||||
|
place = models.Place.objects.create(
|
||||||
|
name="Centre social Kropotkine",
|
||||||
|
code="kropotkine",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
)
|
||||||
|
grouped_order.places.add(place.id)
|
||||||
|
|
||||||
|
item = models.Item.objects.create(
|
||||||
|
name="test item 1", grouped_order=grouped_order, price=1
|
||||||
|
)
|
||||||
|
|
||||||
|
order_url = reverse(
|
||||||
|
"order:order",
|
||||||
|
kwargs={
|
||||||
|
"code": grouped_order.code,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
response = client_log.post(
|
||||||
|
order_url,
|
||||||
|
{
|
||||||
|
f"quantity_{item.pk}": [4, 0],
|
||||||
|
"first_name": "Prénom",
|
||||||
|
"last_name": "Nom",
|
||||||
|
"phone": "0645632569",
|
||||||
|
"email": "test@mail.fr",
|
||||||
|
"note": "",
|
||||||
|
"place": place.code,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 302
|
||||||
|
|
||||||
|
# TODO: How to test trying to use a place from a different user/orga?
|
||||||
|
def test_order_invalid_place(self, client_log):
|
||||||
|
"""The orga user requests a non-existing place for distribution. It fails"""
|
||||||
|
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),
|
||||||
|
)
|
||||||
|
place = models.Place.objects.create(
|
||||||
|
name="Centre social Kropotkine",
|
||||||
|
code="kropotkine",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
)
|
||||||
|
grouped_order.places.add(place.id)
|
||||||
|
|
||||||
|
item = models.Item.objects.create(
|
||||||
|
name="test item 1", grouped_order=grouped_order, price=1
|
||||||
|
)
|
||||||
|
|
||||||
|
order_url = reverse(
|
||||||
|
"order:order",
|
||||||
|
kwargs={
|
||||||
|
"code": grouped_order.code,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
response = client_log.post(
|
||||||
|
order_url,
|
||||||
|
{
|
||||||
|
f"quantity_{item.pk}": [4, 0],
|
||||||
|
"first_name": "Prénom",
|
||||||
|
"last_name": "Nom",
|
||||||
|
"phone": "0645632569",
|
||||||
|
"email": "test@mail.fr",
|
||||||
|
"note": "",
|
||||||
|
"place": "foobar",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 404
|
||||||
|
|
||||||
|
def test_order_unaffiliated_place(self, client_log):
|
||||||
|
"""The orga user requests a place for distribution unrelated to this grouped order. It fails"""
|
||||||
|
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),
|
||||||
|
)
|
||||||
|
place = models.Place.objects.create(
|
||||||
|
name="Centre social Kropotkine",
|
||||||
|
code="kropotkine",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
)
|
||||||
|
place2 = models.Place.objects.create(
|
||||||
|
name="Centre social Luxemburg",
|
||||||
|
code="luxemburg",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
)
|
||||||
|
grouped_order.places.add(place.id)
|
||||||
|
|
||||||
|
item = models.Item.objects.create(
|
||||||
|
name="test item 1", grouped_order=grouped_order, price=1
|
||||||
|
)
|
||||||
|
|
||||||
|
order_url = reverse(
|
||||||
|
"order:order",
|
||||||
|
kwargs={
|
||||||
|
"code": grouped_order.code,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
response = client_log.post(
|
||||||
|
order_url,
|
||||||
|
{
|
||||||
|
f"quantity_{item.pk}": [4, 0],
|
||||||
|
"first_name": "Prénom",
|
||||||
|
"last_name": "Nom",
|
||||||
|
"phone": "0645632569",
|
||||||
|
"email": "test@mail.fr",
|
||||||
|
"note": "",
|
||||||
|
"place": place2.code,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 404
|
||||||
|
|
||||||
|
def test_order_no_place(self, client_log):
|
||||||
|
"""The orga user requests a non-existing place for distribution. It fails"""
|
||||||
|
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),
|
||||||
|
)
|
||||||
|
place = models.Place.objects.create(
|
||||||
|
name="Centre social Kropotkine",
|
||||||
|
code="kropotkine",
|
||||||
|
orga=auth.get_user(client_log),
|
||||||
|
)
|
||||||
|
grouped_order.places.add(place.id)
|
||||||
|
|
||||||
|
item = models.Item.objects.create(
|
||||||
|
name="test item 1", grouped_order=grouped_order, price=1
|
||||||
|
)
|
||||||
|
|
||||||
|
order_url = reverse(
|
||||||
|
"order:order",
|
||||||
|
kwargs={
|
||||||
|
"code": grouped_order.code,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
response = client_log.post(
|
||||||
|
order_url,
|
||||||
|
{
|
||||||
|
f"quantity_{item.pk}": [4, 0],
|
||||||
|
"first_name": "Prénom",
|
||||||
|
"last_name": "Nom",
|
||||||
|
"phone": "0645632569",
|
||||||
|
"email": "test@mail.fr",
|
||||||
|
"note": "",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert response.status_code == 400
|
||||||
|
|
|
@ -29,7 +29,7 @@ def create_grouped_order(
|
||||||
return grouped_order
|
return grouped_order
|
||||||
|
|
||||||
|
|
||||||
def order_items_in_grouped_order(grouped_order):
|
def order_items_in_grouped_order(grouped_order, place=None):
|
||||||
"""Creates 2 OrderedItems and orders in the given grouped order. Returns the order"""
|
"""Creates 2 OrderedItems and orders in the given grouped order. Returns the order"""
|
||||||
item_1 = grouped_order.item_set.create(name="test item", price="2")
|
item_1 = grouped_order.item_set.create(name="test item", price="2")
|
||||||
item_2 = grouped_order.item_set.create(name="test item 2", price="9")
|
item_2 = grouped_order.item_set.create(name="test item 2", price="9")
|
||||||
|
@ -45,9 +45,9 @@ def order_items_in_grouped_order(grouped_order):
|
||||||
phone="000",
|
phone="000",
|
||||||
email="bob3@escargot.fr",
|
email="bob3@escargot.fr",
|
||||||
)
|
)
|
||||||
order = grouped_order.order_set.create(author=author_1)
|
order = grouped_order.order_set.create(author=author_1, place=place)
|
||||||
order_2 = grouped_order.order_set.create(author=author_2)
|
order_2 = grouped_order.order_set.create(author=author_2, place=place)
|
||||||
order_3 = grouped_order.order_set.create(author=author_3)
|
order_3 = grouped_order.order_set.create(author=author_3, place=place)
|
||||||
models.OrderedItem.objects.create(order=order, item=item_1, nb=3)
|
models.OrderedItem.objects.create(order=order, item=item_1, nb=3)
|
||||||
models.OrderedItem.objects.create(order=order, item=item_2, nb=2)
|
models.OrderedItem.objects.create(order=order, item=item_2, nb=2)
|
||||||
models.OrderedItem.objects.create(order=order_2, item=item_1, nb=1)
|
models.OrderedItem.objects.create(order=order_2, item=item_1, nb=1)
|
||||||
|
|
Loading…
Reference in a new issue