Files
004.erp.generic/backend/modules/task_management/services.py
mariomitte 3ad536a23e
Some checks failed
ERP CI/CD Pipeline / test (push) Has been cancelled
ERP CI/CD Pipeline / Deploy (server git pull + compose) (push) Has been cancelled
interaktivna Tablica radnih sati, db
2026-07-13 00:36:28 +02:00

125 lines
5.1 KiB
Python

# backend/modules/task_management/services.py
from django.db import transaction
from rest_framework.exceptions import ValidationError
from django.core.exceptions import ValidationError as DjangoValidationError
import logging
from .models import Task, TaskTemplate, TaskWorkEntry
from modules.fleet.models import VehicleServiceRecord
logger = logging.getLogger(__name__)
class TaskService:
@staticmethod
def create_task_entry(data: dict, user=None) -> Task:
"""
Univerzalna metoda: prihvaća podatke i opcionalnog korisnika.
"""
payload = dict(data)
template_id = payload.pop('template_id', None)
if payload.get('status') == 'DONE' and (user and not user.is_staff):
raise ValidationError({"status": "Samo admini mogu odmah označiti zadatak kao gotov."})
template = None
if template_id:
template = TaskTemplate.objects.filter(id=template_id, is_active=True).prefetch_related('entries').first()
if not template:
raise ValidationError({"template_id": "Odabrani template nije pronađen."})
payload['title'] = template.title
payload['description'] = template.description
payload['status'] = 'aktivan'
payload.setdefault('work_order', None)
title = (payload.get('title') or '').strip()
if title and len(title) < 3:
raise ValidationError({"title": "Naslov zadatka mora imati barem 3 znaka."})
if not title:
raise ValidationError({"title": "Naslov zadatka je obavezan."})
if user and 'assigned_to' not in payload:
payload['assigned_to'] = user
entry = Task(**payload)
try:
entry.full_clean()
except DjangoValidationError as exc:
logger.error(f"Neuspješna validacija zadatka: {exc}")
raise ValidationError(exc.message_dict if hasattr(exc, 'message_dict') else exc.messages)
with transaction.atomic():
entry.save()
if template:
TaskService._create_work_entries_from_template(task=entry, template=template)
TaskService._create_service_records_from_template(task=entry, template=template, user=user)
logger.info(f"Zadatak uspješno kreiran: {entry.id}")
return entry
@staticmethod
def _create_work_entries_from_template(*, task: Task, template: TaskTemplate):
template_entries = list(template.entries.filter(is_active=True).order_by('sort_order', 'created_at')[:10])
for idx, source in enumerate(template_entries, start=1):
TaskWorkEntry.objects.create(
task=task,
template_entry=source,
sort_order=idx,
title=source.title,
work_description=source.work_description,
active_faults=source.active_faults,
explanation_hr=source.explanation_hr,
)
@staticmethod
def _create_service_records_from_template(*, task: Task, template: TaskTemplate, user):
if not user:
raise ValidationError({
"template_id": "Kreiranje taska iz templatea zahtijeva prijavljenog korisnika za servisne zapise."
})
if not task.vehicle_id:
raise ValidationError({
"vehicle": "Task iz templatea mora imati dodijeljenu dizalicu za generiranje servisnih zapisa."
})
template_entries = list(template.entries.filter(is_active=True).order_by('sort_order', 'created_at')[:10])
for source in template_entries:
description_parts = []
if source.work_description:
description_parts.append(source.work_description.strip())
if source.explanation_hr:
description_parts.append(f"Obrazloženje (HR): {source.explanation_hr.strip()}")
if source.active_faults:
description_parts.append(f"Aktivne greške: {source.active_faults.strip()}")
description = "\n\n".join([part for part in description_parts if part]).strip() or source.title
VehicleServiceRecord.objects.create(
vehicle=task.vehicle,
task=task,
performed_by=user,
service_title=source.title,
description=description,
parts=(source.active_faults or '').strip(),
cost=0,
)
@staticmethod
def update_task_entry(instance, data, user):
if not user.is_staff and instance.assigned_to != user:
raise ValidationError("Nemate dozvolu za izmjenu ovog zadatka.")
for attr, value in data.items():
if attr == 'template_id':
continue
setattr(instance, attr, value)
if 'title' in data and len(str(data.get('title') or '').strip()) < 3:
raise ValidationError({"title": "Naslov zadatka mora imati barem 3 znaka."})
try:
instance.full_clean()
except DjangoValidationError as exc:
raise ValidationError(exc.message_dict if hasattr(exc, 'message_dict') else exc.messages)
instance.save()
return instance