Files
004.erp.generic/backend/modules/task_management/views.py
mariomitte 0c9e1b7d50 feat: dodaj scheduled_date na Task i kalendar widget
- Novo polje Task.scheduled_date (DateField, nullable, db_index) za planiranje
- Migracija 0009_task_scheduled_date
- Celery task notify_upcoming_tasks: dnevno u 08:00 šalje Pusher + email za sutrašnje zadatke
- TaskCalendarWidget: react-spring slide panel s lijeve strane, grid prikaz mjeseca, dot indikatori, klik otvara TaskServiceRecordsModal
- FleetDashboardShell: import + render kalendara, Planirano stupac u tablici zadataka
- TaskCreateModal + TaskServiceRecordsModal: scheduled_date input i prikaz
- Admin + serializer + views: scheduled_date filter i prikaz
- 47 backend testova prolaze (uključuje 8 novih za notify_upcoming_tasks)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-19 14:52:10 +02:00

95 lines
3.5 KiB
Python

# backend/modules/task_management/views.py
import logging
from rest_framework import viewsets, permissions
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.exceptions import ValidationError
from .models import Task, TaskTemplate
from .serializers import TaskSerializer, TaskTemplateSerializer, TaskWorkHoursTableSerializer
from .services import TaskService
logger = logging.getLogger(__name__)
class TaskViewSet(viewsets.ModelViewSet):
"""
ViewSet koji koristi TaskService za rukovanje operacijama.
"""
serializer_class = TaskSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
qs = Task.objects.filter(is_active=True).select_related(
'assigned_to', 'vehicle', 'work_order', 'work_order__vehicle', 'work_hours_table'
)
vehicle_id = self.request.query_params.get('vehicle')
if vehicle_id:
qs = qs.filter(vehicle_id=vehicle_id)
scheduled_date = self.request.query_params.get('scheduled_date')
if scheduled_date:
qs = qs.filter(scheduled_date=scheduled_date)
return qs
def perform_create(self, serializer):
try:
entry = TaskService.create_task_entry(
data=serializer.validated_data,
user=self.request.user,
)
serializer.instance = entry
except ValidationError as e:
logger.warning(f"Validacijska greška pri kreiranju zadatka od strane {self.request.user}: {e}")
raise e
def perform_update(self, serializer):
auto_close_work_order = serializer.validated_data.pop('auto_close_work_order', False)
TaskService.update_task_entry(
instance=serializer.instance,
data=serializer.validated_data,
user=self.request.user,
auto_close_work_order=auto_close_work_order,
)
serializer.save()
def perform_destroy(self, instance):
instance.is_active = False
instance.save()
logger.info(f"Zapis zadatka {instance.id} je deaktiviran od strane {self.request.user}")
@action(detail=False, methods=['get'], url_path='templates')
def templates(self, request):
templates = TaskTemplate.objects.filter(is_active=True).prefetch_related('entries').order_by('title')
serializer = TaskTemplateSerializer(templates, many=True)
return Response(serializer.data)
@action(detail=True, methods=['get', 'put', 'patch'], url_path='work-hours-table')
def work_hours_table(self, request, pk=None):
task = self.get_object()
table = getattr(task, 'work_hours_table', None)
if request.method.lower() == 'get':
if table:
serializer = TaskWorkHoursTableSerializer(table)
return Response(serializer.data)
return Response({'task': str(task.id), 'data': None})
if isinstance(request.data, dict) and 'data' in request.data:
payload_data = request.data.get('data')
else:
payload_data = request.data
if payload_data == {}:
payload_data = None
serializer = TaskWorkHoursTableSerializer(
table,
data={
'task': str(task.id),
'data': payload_data,
},
partial=bool(table),
)
serializer.is_valid(raise_exception=True)
instance = serializer.save(task=task)
return Response(TaskWorkHoursTableSerializer(instance).data)