Files
2026-05-31 19:21:25 +02:00

155 lines
6.0 KiB
Python

# 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)