Files
booking_backend/equipment/views.py
2026-04-10 20:51:43 -05:00

119 lines
4.4 KiB
Python

from django.db.models import Q
from django.utils.dateparse import parse_datetime
from rest_framework import generics, permissions, viewsets
from rest_framework.exceptions import PermissionDenied
from rest_framework.response import Response
from rest_framework.views import APIView
from booking.models import Booking
from marketing.mixins import EquipmentListingClickTrackingMixin
from .models import EquipmentItem
from .serializers import EquipmentItemSerializer
class PublicEquipmentListView(generics.ListAPIView):
serializer_class = EquipmentItemSerializer
permission_classes = (permissions.AllowAny,)
def get_queryset(self):
queryset = EquipmentItem.objects.filter(is_active=True).select_related("category", "vendor").prefetch_related("images")
params = self.request.query_params
category = params.get("category")
if category:
if category.isdigit():
queryset = queryset.filter(category_id=category)
else:
queryset = queryset.filter(category__slug=category)
location = params.get("location")
if location:
queryset = queryset.filter(location__icontains=location)
vendor_slug = params.get("vendor_slug")
if vendor_slug:
queryset = queryset.filter(vendor__slug=vendor_slug)
min_price = params.get("min_price")
if min_price:
queryset = queryset.filter(price_per_day__gte=min_price)
max_price = params.get("max_price")
if max_price:
queryset = queryset.filter(price_per_day__lte=max_price)
start = parse_datetime(params.get("available_from", "")) if params.get("available_from") else None
end = parse_datetime(params.get("available_to", "")) if params.get("available_to") else None
if start and end:
blocked_item_ids = (
Booking.objects.filter(
equipment_item__isnull=False,
status__in=[Booking.Status.REQUESTED, Booking.Status.APPROVED, Booking.Status.CONFIRMED],
)
.filter(starts_at__lt=end, ends_at__gt=start)
.values_list("equipment_item_id", flat=True)
)
queryset = queryset.exclude(id__in=blocked_item_ids)
return queryset
class PublicEquipmentDetailView(EquipmentListingClickTrackingMixin, generics.RetrieveAPIView):
serializer_class = EquipmentItemSerializer
permission_classes = (permissions.AllowAny,)
lookup_field = "public_id"
def get_queryset(self):
return EquipmentItem.objects.filter(is_active=True).select_related("category", "vendor").prefetch_related("images")
class VendorEquipmentViewSet(viewsets.ModelViewSet):
serializer_class = EquipmentItemSerializer
permission_classes = (permissions.IsAuthenticated,)
def get_queryset(self):
user = self.request.user
if not user.is_vendor or not hasattr(user, "vendor_profile"):
return EquipmentItem.objects.none()
return (
EquipmentItem.objects.filter(vendor=user.vendor_profile)
.select_related("category", "vendor")
.prefetch_related("images")
)
def perform_create(self, serializer):
user = self.request.user
if not user.is_vendor or not hasattr(user, "vendor_profile"):
raise PermissionDenied("Only vendors can create equipment.")
serializer.save(vendor=user.vendor_profile)
class VendorStorefrontView(APIView):
permission_classes = (permissions.AllowAny,)
def get(self, request, slug):
items = (
EquipmentItem.objects.filter(vendor__slug=slug, is_active=True)
.select_related("category", "vendor")
.prefetch_related("images")
)
if not items.exists():
return Response({"detail": "Vendor storefront not found."}, status=404)
vendor = items.first().vendor
return Response(
{
"vendor": {
"business_name": vendor.business_name,
"slug": vendor.slug,
"description": vendor.description,
"contact_email": vendor.contact_email,
"contact_phone": vendor.contact_phone,
"city": vendor.city,
"country": vendor.country,
},
"items": EquipmentItemSerializer(items, many=True, context={"request": request}).data,
}
)