feat: integritet zatvaranja taska i putnog naloga

Dodaje status 'spreman_za_zavrsetak' i backend provjeru koja blokira zatvaranje taska kada je povezani putni nalog otvoren, uz 409 odgovor i opcionalni auto-close flow.\n\nPri zatvaranju putnog naloga taskovi u statusu 'servis' automatski prelaze u 'spreman_za_zavrsetak'. Frontend modal sada podržava potvrdu i retry s auto_close_work_order=true.\n\nUključeni su i ciljani testovi za novi behavior, te ažuriran prikaz statusa u dashboardu.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
mariomitte
2026-07-17 19:20:33 +02:00
parent e14665d8ec
commit 7acaef941f
14 changed files with 408 additions and 18 deletions

View File

@@ -6,6 +6,7 @@ from django.core.exceptions import ValidationError as DjangoValidationError
import logging
from .models import Task, TaskTemplate, TaskWorkEntry
from .exceptions import OpenWorkOrderBlockingTaskClose
from modules.fleet.models import VehicleServiceRecord
logger = logging.getLogger(__name__)
@@ -106,10 +107,34 @@ class TaskService:
)
@staticmethod
def update_task_entry(instance, data, user):
def update_task_entry(instance, data, user, auto_close_work_order=False):
if not user.is_staff and instance.assigned_to != user:
raise ValidationError("Nemate dozvolu za izmjenu ovog zadatka.")
target_status = data.get('status', instance.status)
target_work_order = data.get('work_order', instance.work_order)
closing_statuses = {'neaktivan', 'zavrsen'}
if target_status in closing_statuses:
if not target_work_order:
raise ValidationError({"work_order": "Putni nalog je obavezan prije zatvaranja zadatka."})
if target_work_order.status == 'open':
if not auto_close_work_order:
work_order_label = f"WO-{str(target_work_order.id).split('-')[0].upper()}"
raise OpenWorkOrderBlockingTaskClose(detail={
"code": "OPEN_WORK_ORDER_BLOCKING_TASK_CLOSE",
"message": f"Putni nalog {work_order_label} je još otvoren. Želite li ga automatski zatvoriti?",
"work_order_id": str(target_work_order.id),
"work_order_label": work_order_label,
})
if target_work_order.end_mileage is None:
raise ValidationError({
"work_order": "Automatsko zatvaranje putnog naloga nije moguće bez završne kilometraže."
})
from modules.fleet.services import VehicleService
target_work_order = VehicleService.update_work_order(target_work_order, {"status": "closed"})
data['work_order'] = target_work_order
for attr, value in data.items():
if attr == 'template_id':
continue