from rest_framework import generics, status from rest_framework.exceptions import NotFound, ValidationError from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView from apps.billing.permissions import HasActiveFeature from apps.orders.api.services import OrderStageService, generate_tracking_code from apps.orders.models import Order, OrderStage, OrderStageLog from .serializers import OrderSerializer, OrderStageLogSerializer, OrderStageSerializer class _UserScopedListCreateView(generics.ListCreateAPIView): permission_classes = [IsAuthenticated, HasActiveFeature] feature_key = "orders" def get_queryset(self): return self.model.objects.filter(user=self.request.user) def perform_create(self, serializer): serializer.save(user=self.request.user) class _UserScopedDetailView(generics.RetrieveUpdateDestroyAPIView): permission_classes = [IsAuthenticated, HasActiveFeature] feature_key = "orders" def get_queryset(self): return self.model.objects.filter(user=self.request.user) class OrderStageListCreateView(_UserScopedListCreateView): model = OrderStage serializer_class = OrderStageSerializer def get_queryset(self): OrderStageService.ensure_default_stage(self.request.user) return super().get_queryset() class OrderStageDetailView(_UserScopedDetailView): model = OrderStage serializer_class = OrderStageSerializer class OrderListCreateView(_UserScopedListCreateView): model = Order serializer_class = OrderSerializer def perform_create(self, serializer): serializer.save( user=self.request.user, tracking_code=serializer.validated_data.get("tracking_code") or generate_tracking_code(), ) class OrderDetailView(_UserScopedDetailView): model = Order serializer_class = OrderSerializer class AdvanceOrderStageView(APIView): """با هر بار زدن «مرحله‌ی بعد»، سفارش را به مرحله‌ی بعدیِ تعریف‌شده می‌برد و طبق قالبِ همان مرحله برای مشتریِ همین سفارش پیامک می‌فرستد.""" permission_classes = [IsAuthenticated, HasActiveFeature] feature_key = "orders" def post(self, request, pk): if not Order.objects.filter(pk=pk, user=request.user).exists(): raise NotFound("سفارش یافت نشد.") extra_input_value = request.data.get("extra_input_value", "") try: order, message_sent = OrderStageService.advance(request.user, pk, extra_input_value) except Order.DoesNotExist: raise NotFound("سفارش یافت نشد.") except ValueError as exc: raise ValidationError(str(exc)) return Response( {**OrderSerializer(order).data, "message_sent": message_sent}, status=status.HTTP_200_OK, ) class GenerateOrderTrackingCodeView(APIView): """یک کدِ پیگیریِ تازه برای سفارش می‌سازد — برای وقتی هنوز کدِ واقعیِ پستی را نداری ولی می‌خواهی از همین حالا یک مرجع به مشتری بدهی.""" permission_classes = [IsAuthenticated, HasActiveFeature] feature_key = "orders" def post(self, request, pk): order = Order.objects.filter(pk=pk, user=request.user).first() if order is None: raise NotFound("سفارش یافت نشد.") order.tracking_code = generate_tracking_code() order.save(update_fields=["tracking_code", "updated_at"]) return Response(OrderSerializer(order).data) class OrderStageLogListView(generics.ListAPIView): serializer_class = OrderStageLogSerializer permission_classes = [IsAuthenticated, HasActiveFeature] feature_key = "orders" def get_queryset(self): return OrderStageLog.objects.filter(order_id=self.kwargs["pk"], order__user=self.request.user)