155 lines
6.0 KiB
Python
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) |