# operations/views.py from django.http import HttpResponse from django.utils import timezone from django_filters.rest_framework import DjangoFilterBackend from rest_framework import viewsets, filters, permissions, status from rest_framework.views import APIView from rest_framework.decorators import action from rest_framework.response import Response from .models import RadniNalog, RadniNalogSlika, PutniNalog from .mixins import AstroBridgeViewSetMixin from .services import izvrsi_perform_create_logiku, get_optimized_image from .serializers import ( RadniNalogSerializer, RadniNalogDetaljiSerializer, KreirajPutniNalogSerializer, PutniNalogSerializer ) class RadniNalogViewSet(AstroBridgeViewSetMixin, viewsets.ModelViewSet): queryset = RadniNalog.objects.all().select_related( 'klijent', 'izvrsitelj', 'putni_nalog__vozilo' ) auto_handle_files = True file_field_name = 'slike' related_file_model = RadniNalogSlika related_file_fk = 'radni_nalog' filter_backends = [ DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter ] filterset_fields = ['status', 'izvrsitelj', 'klijent', 'putni_nalog__vozilo'] search_fields = ['broj_naloga', 'klijent__naziv', 'putni_nalog__vozilo__registracija', 'putni_nalog__vozilo__naziv'] ordering_fields = ['datum_kreiranja', 'status', 'broj_naloga'] ordering = ['-datum_kreiranja'] def get_serializer_class(self): if self.action in ['create', 'update', 'partial_update']: return RadniNalogSerializer return RadniNalogDetaljiSerializer def get_queryset(self): queryset = self.queryset if self.action in ['list', 'retrieve']: queryset = queryset.prefetch_related('slike') return queryset def perform_create(self, serializer): # Delegiramo izvršavanje u operacije.py return izvrsi_perform_create_logiku(serializer, self.request.user) def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) instance = self.perform_create(serializer) instance.refresh_from_db() izlazni_serializer = RadniNalogDetaljiSerializer(instance, context={'request': request}) return Response(izlazni_serializer.data, status=status.HTTP_201_CREATED) def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', True) instance = self.get_object() serializer = RadniNalogSerializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) instance.refresh_from_db() return Response(RadniNalogDetaljiSerializer(instance, context={'request': request}).data) @action(detail=False, methods=['get'], url_path='sljedeci-broj', permission_classes=[permissions.AllowAny]) def dohvati_sljedeci_broj(self, request): godina = timezone.now().year kljuc_sekvence = f"radni_nalog_{godina}" prefix = f"RN-{godina}-" from .models import BrojacSekvence brojac = BrojacSekvence.objects.filter(naziv_sekvence=kljuc_sekvence).first() if brojac: sljedeci_broj = brojac.zadnji_broj + 1 else: zadnji_nalog = RadniNalog.objects.filter(broj_naloga__startswith=prefix).order_by('-broj_naloga').first() if zadnji_nalog: try: sljedeci_broj = int(zadnji_nalog.broj_naloga.split('-')[-1]) + 1 except (ValueError, IndexError): sljedeci_broj = 1 else: sljedeci_broj = 1 sljedeci_broj_formatiran = f"{prefix}{sljedeci_broj:04d}" return Response({"broj_naloga": sljedeci_broj_formatiran}) class PutniNalogViewSet(AstroBridgeViewSetMixin, viewsets.ModelViewSet): queryset = PutniNalog.objects.all().order_by('-datum_izdavanja', '-id') permission_classes = [permissions.IsAuthenticated] def get_serializer_class(self): if self.action == 'create': return KreirajPutniNalogSerializer return PutniNalogSerializer def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data, context={'request': request}) serializer.is_valid(raise_exception=True) putni_nalog = serializer.save() return Response( { "id": putni_nalog.id, "broj_naloga": putni_nalog.broj_naloga, "status": putni_nalog.status, "pocetna_km": putni_nalog.pocetna_km, "message": "Putni nalog uspješno kreiran!" }, status=status.HTTP_201_CREATED ) class ProxyImageView(APIView): http_method_names = ['get'] permission_classes = [permissions.AllowAny] def get(self, request): image_url = request.query_params.get('url') try: width = int(request.query_params.get('w', 600)) # Defaultna širina za terensku karticu except (ValueError, TypeError): width = 600 if not image_url: return Response({"error": "URL slike nije zadan"}, status=status.HTTP_400_BAD_REQUEST) try: # get_optimized_image vraća sirove binarne bajtove WebP slike iz BytesIO-a image_data = get_optimized_image(image_url, width=width) response = HttpResponse(image_data, content_type="image/webp") # 🚀 KLJUČNO ZA OFFLINE I BRZINU: Kažemo pregledniku da kešira sliku na 7 dana response['Cache-Control'] = 'public, max-age=604800, immutable' return response except Exception as e: print(f"[ProxyImageView Krah] Detalji: {e}") return Response({"error": f"Greška pri optimizaciji: {str(e)}"}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)