interaktivna Tablica radnih sati, db
This commit is contained in:
@@ -31,4 +31,16 @@ class TaskSerializerTests(TestCase):
|
||||
task = Task.objects.create(title="Task 2", description="", status="servis", assigned_to=self.user, vehicle=self.vehicle)
|
||||
|
||||
serializer = TaskSerializer(instance=task, data={"status": "neaktivan", "work_order": str(work_order.id)}, partial=True)
|
||||
assert serializer.is_valid(), serializer.errors
|
||||
|
||||
def test_cannot_mark_finished_without_work_order(self):
|
||||
serializer = TaskSerializer(data={"title": "Task 3", "description": "", "status": "zavrsen", "vehicle": str(self.vehicle.id)})
|
||||
with self.assertRaises(ValidationError):
|
||||
serializer.is_valid(raise_exception=True)
|
||||
|
||||
def test_can_mark_finished_with_work_order(self):
|
||||
work_order = WorkOrder.objects.create(vehicle=self.vehicle, creator=self.user, purpose='kontrola')
|
||||
task = Task.objects.create(title="Task 4", description="", status="servis", assigned_to=self.user, vehicle=self.vehicle)
|
||||
|
||||
serializer = TaskSerializer(instance=task, data={"status": "zavrsen", "work_order": str(work_order.id)}, partial=True)
|
||||
assert serializer.is_valid(), serializer.errors
|
||||
@@ -2,8 +2,8 @@ from django.test import TestCase
|
||||
from django.contrib.auth import get_user_model
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from modules.task_management.services import TaskService
|
||||
from modules.task_management.models import Task
|
||||
from modules.fleet.models import Vehicle, WorkOrder
|
||||
from modules.task_management.models import Task, TaskTemplate, TaskTemplateEntry, TaskWorkEntry
|
||||
from modules.fleet.models import Vehicle, WorkOrder, VehicleServiceRecord
|
||||
|
||||
|
||||
class TaskServiceTests(TestCase):
|
||||
@@ -50,4 +50,84 @@ class TaskServiceTests(TestCase):
|
||||
user=self.user,
|
||||
)
|
||||
assert updated.status == "neaktivan"
|
||||
assert updated.work_order == work_order
|
||||
assert updated.work_order == work_order
|
||||
|
||||
def test_update_task_entry_rejects_finished_without_work_order(self):
|
||||
task = Task.objects.create(title="Za završetak", description="", assigned_to=self.user, status='servis')
|
||||
with self.assertRaises(ValidationError):
|
||||
TaskService.update_task_entry(instance=task, data={"status": "zavrsen"}, user=self.user)
|
||||
|
||||
def test_update_task_entry_allows_finished_with_work_order(self):
|
||||
vehicle = Vehicle.objects.create(registration_number="ZG-TASK-01A", asset_type='crane')
|
||||
work_order = WorkOrder.objects.create(vehicle=vehicle, creator=self.user, purpose='kontrola')
|
||||
task = Task.objects.create(title="Za završetak", description="", assigned_to=self.user, status='servis', vehicle=vehicle)
|
||||
updated = TaskService.update_task_entry(
|
||||
instance=task,
|
||||
data={"status": "zavrsen", "work_order": work_order},
|
||||
user=self.user,
|
||||
)
|
||||
assert updated.status == "zavrsen"
|
||||
assert updated.work_order == work_order
|
||||
|
||||
def test_create_task_entry_from_template_creates_service_records(self):
|
||||
vehicle = Vehicle.objects.create(registration_number="ZG-TASK-02", asset_type='crane')
|
||||
template = TaskTemplate.objects.create(
|
||||
code='template-servis-zapisi',
|
||||
title='Template servis',
|
||||
description='Opis templatea',
|
||||
status='aktivan',
|
||||
)
|
||||
TaskTemplateEntry.objects.create(
|
||||
task_template=template,
|
||||
sort_order=1,
|
||||
title='Pregled sustava',
|
||||
work_description='Provjera hidraulike',
|
||||
active_faults='Greška E101',
|
||||
explanation_hr='Prevedeno i objašnjeno.',
|
||||
)
|
||||
TaskTemplateEntry.objects.create(
|
||||
task_template=template,
|
||||
sort_order=2,
|
||||
title='Zamjena senzora',
|
||||
work_description='Zamijenjen senzor kuta',
|
||||
active_faults='',
|
||||
explanation_hr='Senzor kalibriran.',
|
||||
)
|
||||
|
||||
created = TaskService.create_task_entry(
|
||||
data={'template_id': template.id, 'vehicle': vehicle},
|
||||
user=self.user,
|
||||
)
|
||||
|
||||
self.assertEqual(created.vehicle_id, vehicle.id)
|
||||
self.assertEqual(TaskWorkEntry.objects.filter(task=created).count(), 2)
|
||||
records = VehicleServiceRecord.objects.filter(task=created).order_by('created_at')
|
||||
self.assertEqual(records.count(), 2)
|
||||
self.assertEqual(records.first().service_title, 'Pregled sustava')
|
||||
self.assertIn('Obrazloženje (HR): Prevedeno i objašnjeno.', records.first().description)
|
||||
self.assertIn('Aktivne greške: Greška E101', records.first().description)
|
||||
self.assertEqual(records.first().performed_by_id, self.user.id)
|
||||
|
||||
def test_create_task_entry_from_template_limits_service_records_to_ten(self):
|
||||
vehicle = Vehicle.objects.create(registration_number="ZG-TASK-03", asset_type='crane')
|
||||
template = TaskTemplate.objects.create(
|
||||
code='template-limit-10',
|
||||
title='Template limit',
|
||||
description='Opis',
|
||||
status='aktivan',
|
||||
)
|
||||
for index in range(1, 13):
|
||||
TaskTemplateEntry.objects.create(
|
||||
task_template=template,
|
||||
sort_order=index,
|
||||
title=f'Korak {index}',
|
||||
work_description=f'Opis {index}',
|
||||
)
|
||||
|
||||
created = TaskService.create_task_entry(
|
||||
data={'template_id': template.id, 'vehicle': vehicle},
|
||||
user=self.user,
|
||||
)
|
||||
|
||||
self.assertEqual(TaskWorkEntry.objects.filter(task=created).count(), 10)
|
||||
self.assertEqual(VehicleServiceRecord.objects.filter(task=created).count(), 10)
|
||||
@@ -1,10 +1,11 @@
|
||||
from django.test import TestCase, RequestFactory
|
||||
from django.contrib.auth import get_user_model
|
||||
from unittest.mock import patch
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from modules.task_management.views import TaskViewSet
|
||||
from modules.task_management.serializers import TaskSerializer
|
||||
from modules.task_management.models import Task
|
||||
from modules.task_management.models import Task, TaskTemplate, TaskTemplateEntry
|
||||
from modules.fleet.models import Vehicle
|
||||
|
||||
|
||||
@@ -17,6 +18,8 @@ class TaskViewSetTests(TestCase):
|
||||
self.view.request = self.factory.post("/")
|
||||
self.view.request.user = self.user
|
||||
self.vehicle = Vehicle.objects.create(registration_number="ZG-TV-01", asset_type='crane')
|
||||
self.api_client = APIClient()
|
||||
self.api_client.force_authenticate(user=self.user)
|
||||
|
||||
@patch("modules.task_management.views.TaskService.create_task_entry")
|
||||
def test_perform_create_calls_service(self, mock_create):
|
||||
@@ -53,4 +56,32 @@ class TaskViewSetTests(TestCase):
|
||||
task = Task.objects.create(title="ToDelete", description="", assigned_to=self.user)
|
||||
self.view.perform_destroy(task)
|
||||
task.refresh_from_db()
|
||||
assert task.is_active is False
|
||||
assert task.is_active is False
|
||||
|
||||
def test_template_created_task_is_visible_in_service_records_endpoint(self):
|
||||
template = TaskTemplate.objects.create(
|
||||
code='template-api-service-records',
|
||||
title='Template API',
|
||||
description='Opis',
|
||||
status='aktivan',
|
||||
)
|
||||
TaskTemplateEntry.objects.create(
|
||||
task_template=template,
|
||||
sort_order=1,
|
||||
title='Korak API',
|
||||
work_description='Opis API koraka',
|
||||
)
|
||||
|
||||
response = self.api_client.post(
|
||||
"/api/tasks/tasks/",
|
||||
data={"template_id": str(template.id), "vehicle": str(self.vehicle.id)},
|
||||
format="json",
|
||||
)
|
||||
self.assertEqual(response.status_code, 201, response.content)
|
||||
created_task_id = str(response.json()["id"])
|
||||
|
||||
service_records_response = self.api_client.get("/api/fleet/service-records/")
|
||||
self.assertEqual(service_records_response.status_code, 200, service_records_response.content)
|
||||
payload = service_records_response.json()
|
||||
rows = payload if isinstance(payload, list) else payload.get("results", [])
|
||||
self.assertTrue(any(str(row.get("task") or "") == created_task_id for row in rows))
|
||||
@@ -0,0 +1,97 @@
|
||||
from django.test import TestCase
|
||||
from django.contrib.auth import get_user_model
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from modules.fleet.models import Vehicle, WorkOrder, VehicleServiceRecord
|
||||
from modules.task_management.models import Task, TaskWorkHoursTable
|
||||
|
||||
|
||||
class TaskWorkHoursTableTests(TestCase):
|
||||
def setUp(self):
|
||||
User = get_user_model()
|
||||
self.user = User.objects.create_user(username="wh-user", email="wh-user@example.test", password="Pass123!abc")
|
||||
self.client = APIClient()
|
||||
self.client.force_authenticate(user=self.user)
|
||||
self.vehicle = Vehicle.objects.create(registration_number="ZG-WH-01", asset_type='crane')
|
||||
self.work_order = WorkOrder.objects.create(
|
||||
vehicle=self.vehicle,
|
||||
creator=self.user,
|
||||
purpose='kontrola',
|
||||
location='Zagreb',
|
||||
)
|
||||
self.task = Task.objects.create(
|
||||
title="Task tablica sati",
|
||||
description="",
|
||||
status="aktivan",
|
||||
assigned_to=self.user,
|
||||
vehicle=self.vehicle,
|
||||
work_order=self.work_order,
|
||||
)
|
||||
|
||||
def test_put_work_hours_table_accepts_null_data(self):
|
||||
response = self.client.put(
|
||||
f"/api/tasks/tasks/{self.task.id}/work-hours-table/",
|
||||
data=None,
|
||||
format="json",
|
||||
)
|
||||
self.assertEqual(response.status_code, 200, response.content)
|
||||
self.assertIsNone(response.json().get('data'))
|
||||
|
||||
def test_put_work_hours_table_accepts_partial_row_and_normalizes(self):
|
||||
response = self.client.put(
|
||||
f"/api/tasks/tasks/{self.task.id}/work-hours-table/",
|
||||
data={"rows": [{"day": "NED", "travel_hours": "2,5", "departure_place": "Zagreb"}]},
|
||||
format="json",
|
||||
)
|
||||
self.assertEqual(response.status_code, 200, response.content)
|
||||
payload = response.json()
|
||||
rows = payload.get('data', {}).get('rows', [])
|
||||
self.assertEqual(len(rows), 1)
|
||||
self.assertEqual(rows[0].get('day'), 'NED')
|
||||
self.assertEqual(rows[0].get('travel_hours'), '2,5')
|
||||
self.assertEqual(rows[0].get('departure_place'), 'Zagreb')
|
||||
self.assertIn('arrival_place', rows[0])
|
||||
self.assertEqual(rows[0].get('arrival_place'), '')
|
||||
|
||||
def test_put_work_hours_table_rejects_invalid_json_shape(self):
|
||||
response = self.client.put(
|
||||
f"/api/tasks/tasks/{self.task.id}/work-hours-table/",
|
||||
data="invalid-shape",
|
||||
format="json",
|
||||
)
|
||||
self.assertEqual(response.status_code, 400, response.content)
|
||||
|
||||
def test_task_service_context_includes_work_hours_table_data(self):
|
||||
TaskWorkHoursTable.objects.create(
|
||||
task=self.task,
|
||||
data={"rows": [{"day": "NED", "date": "12.07.2026"}]},
|
||||
)
|
||||
VehicleServiceRecord.objects.create(
|
||||
vehicle=self.vehicle,
|
||||
task=self.task,
|
||||
performed_by=self.user,
|
||||
service_title="Servis zapis",
|
||||
description="Opis",
|
||||
cost=0,
|
||||
)
|
||||
|
||||
response = self.client.get(f"/api/fleet/work-orders/{self.work_order.id}/task-service-context/")
|
||||
self.assertEqual(response.status_code, 200, response.content)
|
||||
payload = response.json()
|
||||
tasks = payload.get('tasks', [])
|
||||
self.assertEqual(len(tasks), 1)
|
||||
self.assertEqual(tasks[0].get('work_hours_table'), {"rows": [{"day": "NED", "date": "12.07.2026"}]})
|
||||
|
||||
def test_service_records_pdf_works_with_empty_work_hours_table(self):
|
||||
VehicleServiceRecord.objects.create(
|
||||
vehicle=self.vehicle,
|
||||
task=self.task,
|
||||
performed_by=self.user,
|
||||
service_title="Servis zapis",
|
||||
description="Opis",
|
||||
cost=0,
|
||||
)
|
||||
|
||||
response = self.client.get(f"/api/fleet/work-orders/{self.work_order.id}/service-records-pdf/")
|
||||
self.assertEqual(response.status_code, 200, response.content)
|
||||
self.assertEqual(response["Content-Type"], "application/pdf")
|
||||
Reference in New Issue
Block a user