119 lines
4.4 KiB
Python
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,
|
|
}
|
|
)
|