Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions essenza/essenza/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
path("catalog/", CatalogView.as_view(), name="catalog"),
path("catalog/<int:pk>/", CatalogDetailView.as_view(), name="catalog_detail"),
path("cart/", include("cart.urls")),
path("order/", include("order.urls")),

]

if settings.DEBUG:
Expand Down
206 changes: 206 additions & 0 deletions essenza/order/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
from django.test import TestCase, Client
from django.urls import reverse
from django.contrib.auth import get_user_model

from product.models import Product, Category
from order.models import Order, OrderProduct, Status

User = get_user_model()


class OrderListUserViewTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.client = Client()

cls.user = User.objects.create_user(
username="user1",
email="user@test.com",
password="1234",
role="user"
)
cls.other_user = User.objects.create_user(
username="user2",
email="user2@test.com",
password="1234",
role="user"
)

cls.product = Product.objects.create(
name="Producto A",
brand="Marca A",
description="Desc",
category=Category.MAQUILLAJE,
price="10.00",
stock=10,
is_active=True,
)

# Pedido visible (NO en preparación) del usuario
cls.order_user = Order.objects.create(
user=cls.user,
status=Status.ENVIADO,
address="Calle 1",
)
OrderProduct.objects.create(
order=cls.order_user,
product=cls.product,
quantity=2
)

# Pedido del usuario que NO debe salir (EN_PREPARACION)
cls.order_hidden = Order.objects.create(
user=cls.user,
status=Status.EN_PREPARACION,
address="Calle Oculta",
)
OrderProduct.objects.create(
order=cls.order_hidden,
product=cls.product,
quantity=1
)

# Pedido de otro usuario
cls.order_other = Order.objects.create(
user=cls.other_user,
status=Status.ENVIADO,
address="Otra calle",
)
OrderProduct.objects.create(
order=cls.order_other,
product=cls.product,
quantity=1
)

cls.url = reverse("order_list_user")

def test_user_must_login(self):
resp = self.client.get(self.url)
self.assertEqual(resp.status_code, 302) # redirect a login

def test_user_sees_only_his_non_preparacion_orders(self):
self.client.login(email="user@test.com", password="1234")
resp = self.client.get(self.url)

self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, "order/order_list_user.html")

orders = resp.context["orders"]
self.assertEqual(orders.count(), 1)
self.assertEqual(orders.first().id, self.order_user.id)

self.assertContains(resp, "Producto A")
self.assertContains(resp, "Calle 1")


class OrderListAdminViewTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.client = Client()

cls.admin = User.objects.create_user(
username="admin1",
email="admin@test.com",
password="1234",
role="admin",
is_staff=True
)

cls.user = User.objects.create_user(
username="user3",
email="user3@test.com",
password="1234",
role="user"
)

cls.product = Product.objects.create(
name="Prod",
brand="Brand",
description="d",
category=Category.PERFUME,
price="5.00",
stock=10,
is_active=True,
)

cls.order = Order.objects.create(
user=cls.user,
status=Status.ENVIADO,
address="Dir",
)
OrderProduct.objects.create(
order=cls.order,
product=cls.product,
quantity=1
)

cls.url = reverse("order_list_admin")

def test_admin_must_login(self):
resp = self.client.get(self.url)
self.assertEqual(resp.status_code, 302)

def test_admin_can_view_orders(self):
self.client.login(email="admin@test.com", password="1234")
resp = self.client.get(self.url)

self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, "order/order_list_admin.html")
self.assertContains(resp, "Prod")
self.assertContains(resp, "user3@test.com")


class OrderTrackViewTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.client = Client()

cls.user = User.objects.create_user(
username="trackuser",
email="track@test.com",
password="1234",
role="user"
)

cls.product = Product.objects.create(
name="Producto Track",
brand="Marca Track",
description="Desc",
category=Category.CABELLO,
price="12.00",
stock=5,
is_active=True,
)

cls.order = Order.objects.create(
user=cls.user,
status=Status.ENVIADO,
address="Direccion de prueba",
)
OrderProduct.objects.create(
order=cls.order,
product=cls.product,
quantity=1
)

cls.url = reverse("order_track") # ⬅️ SIN args

def test_track_get_returns_form(self):
resp = self.client.get(self.url)
self.assertEqual(resp.status_code, 200)
self.assertTemplateUsed(resp, "order/order_track.html")

def test_track_post_valid_shows_order(self):
data = {"order_id": str(self.order.id), "email": "track@test.com"}
resp = self.client.post(self.url, data)

self.assertEqual(resp.status_code, 200)
self.assertContains(resp, "Direccion de prueba")
self.assertContains(resp, self.order.get_status_display())

def test_track_post_invalid_shows_error(self):
data = {"order_id": "9999", "email": "track@test.com"}
resp = self.client.post(self.url, data)

self.assertEqual(resp.status_code, 200)
self.assertContains(resp, "No se ha encontrado ningún pedido")
14 changes: 14 additions & 0 deletions essenza/order/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from django.urls import path
from .views import (
OrderListAdminView,
OrderListUserView,
OrderTrackView
)

urlpatterns = [
path("admin/listado/", OrderListAdminView.as_view(), name="order_list_admin"),
path("mis-pedidos/", OrderListUserView.as_view(), name="order_list_user"),
path("seguimiento/", OrderTrackView.as_view(), name="order_track"),

]

86 changes: 86 additions & 0 deletions essenza/order/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.views import View
from django.shortcuts import render, redirect
from django.db.models import Prefetch
from .models import Order, OrderProduct, Status

# =======================================================
# LISTADO DE PEDIDOS - ADMIN
# =======================================================
class OrderListAdminView(LoginRequiredMixin, UserPassesTestMixin, View):
template_name = "order/order_list_admin.html"

def test_func(self):
return self.request.user.is_authenticated and self.request.user.role == "admin"

def handle_no_permission(self):
if not self.request.user.is_authenticated:
return redirect("login")
return redirect("dashboard")

def get(self, request):
orders = (
Order.objects.select_related("user")
.prefetch_related(
Prefetch("order_products", queryset=OrderProduct.objects.select_related("product"))
)
.order_by("-placed_at")
)
return render(request, self.template_name, {"orders": orders})


# =======================================================
# LISTADO DE PEDIDOS - USER
# =======================================================
class OrderListUserView(LoginRequiredMixin, View):
template_name = "order/order_list_user.html"

def get(self, request):
orders = (
Order.objects.filter(user=request.user)
.exclude(status=Status.EN_PREPARACION) # carrito / en preparación NO
.prefetch_related(
Prefetch("order_products", queryset=OrderProduct.objects.select_related("product"))
)
.order_by("-placed_at")
)
return render(request, self.template_name, {"orders": orders})


# =======================================================
# SEGUIMIENTO SIN LOGIN
# =======================================================
class OrderTrackView(View):
template_name = "order/order_track.html"

def get(self, request):
# Solo formulario
return render(request, self.template_name, {"order": None, "searched": False})

def post(self, request):
order_id = request.POST.get("order_id", "").strip()
email = request.POST.get("email", "").strip().lower()

order = None
error = None

if not order_id or not email:
error = "Debes introducir el número de pedido y el email."
else:
try:
order_pk = int(order_id)
order = (
Order.objects.select_related("user")
.prefetch_related(
Prefetch("order_products", queryset=OrderProduct.objects.select_related("product"))
)
.get(pk=order_pk, user__email__iexact=email)
)
except (ValueError, Order.DoesNotExist):
error = "No se ha encontrado ningún pedido con esos datos."

return render(
request,
self.template_name,
{"order": order, "searched": True, "error": error},
)
Loading