- Dodano polje 'display_code' na WorkOrder model (format: 2 inicijala + ddmmyy) - Migracije za kreiranje polja i backfill postojećih naloga - Ažuriran WorkOrderSerializer za validaciju i serijalizaciju display_code - Backend tasks za auto-generiranje display_code pri kreiranju - Frontend komponente ažurirane za prikaz display_code umjesto UUID: * FleetDashboardShell tablica putnih naloga * WorkOrderDetailModal * TaskCreateModal * Sve PDF stranice - displayIds.js utility za formatiranjeDisplay ID-eva - Admin interface prikazuje display_code
131 lines
5.1 KiB
Python
131 lines
5.1 KiB
Python
import uuid
|
|
from django.test import TestCase
|
|
from django.contrib.auth import get_user_model
|
|
from modules.fleet.services import VehicleService
|
|
from modules.fleet.models import Vehicle, WorkOrder, VehicleServiceRecord
|
|
from modules.fleet.serializers import WorkOrderSerializer
|
|
from modules.task_management.models import Task
|
|
from rest_framework.test import APIRequestFactory
|
|
|
|
|
|
class FleetServiceTests(TestCase):
|
|
def setUp(self):
|
|
User = get_user_model()
|
|
self.user = User.objects.create_user(username="tech2", email=f"tech2+{uuid.uuid4()}@example.test", password="pass")
|
|
self.vehicle = Vehicle.objects.create(
|
|
registration_number=f"RI-{uuid.uuid4().hex[:6].upper()}",
|
|
make="VW",
|
|
model="Polo",
|
|
current_mileage=5000,
|
|
service_interval_km=10000,
|
|
assigned_servicer=self.user
|
|
)
|
|
|
|
def test_create_work_order_via_service(self):
|
|
data = {"vehicle": self.vehicle, "creator": self.user, "start_mileage": 5000, "end_mileage": 5200, "purpose": "kontrola"}
|
|
wo = VehicleService.create_work_order(data)
|
|
self.vehicle.refresh_from_db()
|
|
self.assertEqual(self.vehicle.current_mileage, 5200)
|
|
self.assertEqual(wo.distance, 200)
|
|
|
|
def test_create_service_record_via_service(self):
|
|
data = {"vehicle": self.vehicle, "performed_by": self.user, "description": "Brake pads", "mileage": 5200, "cost": "120.00"}
|
|
rec = VehicleService.create_service_record(data)
|
|
self.vehicle.refresh_from_db()
|
|
self.assertEqual(rec.next_service_due_at, 5200 + self.vehicle.service_interval_km)
|
|
self.assertEqual(self.vehicle.current_mileage, 5200)
|
|
|
|
def test_vehicle_next_service_at_logic(self):
|
|
# current=12000, interval=15000 -> blocks=(12000//15000)+1 = 1 -> 1*15000 = 15000
|
|
v = Vehicle.objects.create(current_mileage=12000, service_interval_km=15000)
|
|
assert v.next_service_at() == 15000
|
|
|
|
# current=16000, interval=15000 -> blocks=(16000//15000)+1 = 2 -> 2*15000 = 30000
|
|
v.current_mileage = 16000
|
|
assert v.next_service_at() == 30000
|
|
|
|
def test_work_order_distance_property(self):
|
|
vehicle = Vehicle.objects.create(registration_number="ZG-004")
|
|
# Nalog bez završne kilometraže
|
|
wo = WorkOrder.objects.create(vehicle=vehicle, creator=self.user, start_mileage=1000)
|
|
assert wo.distance is None
|
|
|
|
# Nalog sa završnom kilometražom
|
|
wo.end_mileage = 1100
|
|
assert wo.distance == 100
|
|
|
|
def test_closing_work_order_moves_task_to_ready_for_completion(self):
|
|
work_order = WorkOrder.objects.create(
|
|
vehicle=self.vehicle,
|
|
creator=self.user,
|
|
purpose="kontrola",
|
|
status="open",
|
|
start_mileage=5000,
|
|
end_mileage=5200,
|
|
)
|
|
task = Task.objects.create(
|
|
title="Servis",
|
|
description="",
|
|
status="servis",
|
|
assigned_to=self.user,
|
|
vehicle=self.vehicle,
|
|
work_order=work_order,
|
|
)
|
|
|
|
VehicleService.update_work_order(work_order, {"status": "closed"})
|
|
task.refresh_from_db()
|
|
self.assertEqual(task.status, "spreman_za_zavrsetak")
|
|
|
|
def test_closing_work_order_moves_active_task_to_ready_for_completion(self):
|
|
work_order = WorkOrder.objects.create(
|
|
vehicle=self.vehicle,
|
|
creator=self.user,
|
|
purpose="kontrola",
|
|
status="open",
|
|
start_mileage=5000,
|
|
end_mileage=5200,
|
|
)
|
|
task = Task.objects.create(
|
|
title="Preventiva",
|
|
description="",
|
|
status="aktivan",
|
|
assigned_to=self.user,
|
|
vehicle=self.vehicle,
|
|
work_order=work_order,
|
|
)
|
|
|
|
VehicleService.update_work_order(work_order, {"status": "closed"})
|
|
task.refresh_from_db()
|
|
self.assertEqual(task.status, "spreman_za_zavrsetak")
|
|
|
|
def test_work_order_serializer_autogenerates_display_code(self):
|
|
self.user.first_name = "Mario"
|
|
self.user.last_name = "Tkalac"
|
|
self.user.save(update_fields=["first_name", "last_name"])
|
|
|
|
request = APIRequestFactory().post('/api/fleet/work-orders/', {})
|
|
request.user = self.user
|
|
serializer = WorkOrderSerializer(
|
|
data={
|
|
"vehicle": str(self.vehicle.id),
|
|
"purpose": "kontrola",
|
|
},
|
|
context={"request": request},
|
|
)
|
|
self.assertTrue(serializer.is_valid(), serializer.errors)
|
|
work_order = serializer.save()
|
|
self.assertRegex(work_order.display_code, r'^MT[0-9]{6}$')
|
|
|
|
def test_work_order_serializer_rejects_invalid_display_code(self):
|
|
request = APIRequestFactory().post('/api/fleet/work-orders/', {})
|
|
request.user = self.user
|
|
serializer = WorkOrderSerializer(
|
|
data={
|
|
"vehicle": str(self.vehicle.id),
|
|
"purpose": "kontrola",
|
|
"display_code": "BAD-CODE",
|
|
},
|
|
context={"request": request},
|
|
)
|
|
self.assertFalse(serializer.is_valid())
|
|
self.assertIn("display_code", serializer.errors) |