112 lines
4.0 KiB
Python
112 lines
4.0 KiB
Python
# src/operations/admin.py
|
|
from django.contrib import admin
|
|
from django.utils.html import format_html
|
|
from .models import RadniNalog, RadniNalogSlika, PutniNalog
|
|
|
|
# --- INLINES ---
|
|
|
|
class RadniNalogSlikaInline(admin.TabularInline):
|
|
"""Omogućuje dodavanje više slika unutar samog radnog naloga."""
|
|
model = RadniNalogSlika
|
|
extra = 1
|
|
fields = ('slika', 'opis')
|
|
|
|
class RadniNalogInline(admin.StackedInline):
|
|
"""
|
|
Omogućuje dodavanje i pregled radnih naloga direktno unutar Putnog naloga.
|
|
Ovo je ključno za terenski rad (jedno putovanje -> više odrađenih strojeva).
|
|
"""
|
|
model = RadniNalog
|
|
extra = 0
|
|
autocomplete_fields = ['stroj', 'klijent', 'izvrsitelj']
|
|
fieldsets = (
|
|
(None, {
|
|
'fields': (('broj_naloga', 'status'), ('klijent', 'stroj'), 'opis_kvara')
|
|
}),
|
|
)
|
|
|
|
# --- ADMIN REGISTRACIJE ---
|
|
|
|
@admin.register(PutniNalog)
|
|
class PutniNalogAdmin(admin.ModelAdmin):
|
|
list_display = ('broj_naloga', 'prikaz_vozila', 'korisnik', 'pocetna_km', 'zavrsna_km', 'status_marker')
|
|
list_filter = ('status', 'datum_izdavanja', 'vozilo')
|
|
search_fields = ('broj_naloga', 'vozilo__registracija', 'korisnik__last_name')
|
|
autocomplete_fields = ['vozilo', 'korisnik']
|
|
|
|
# Inlines omogućuju da vidiš servise (RN) unutar putovanja (PN)
|
|
inlines = [RadniNalogInline]
|
|
|
|
# pocetna_km je readonly jer se automatski povlači iz flote pri kreiranju
|
|
readonly_fields = ('pocetna_km',)
|
|
|
|
fieldsets = (
|
|
('Logistika puta', {
|
|
'fields': (('broj_naloga', 'status'), ('vozilo', 'korisnik'), 'relacija', 'mjesto_odredista')
|
|
}),
|
|
('Kilometraža i vrijeme', {
|
|
'fields': (('pocetna_km', 'zavrsna_km'), ('vrijeme_polaska', 'vrijeme_povratka')),
|
|
'description': 'Završni kilometri će automatski ažurirati bazu vozila po zatvaranju naloga.'
|
|
}),
|
|
)
|
|
|
|
def prikaz_vozila(self, obj):
|
|
return format_html('<b>{}</b>', obj.vozilo.registracija)
|
|
prikaz_vozila.short_description = "Vozilo"
|
|
|
|
def status_marker(self, obj):
|
|
color = 'green' if obj.status == 'ZAVRSEN' else 'orange'
|
|
return format_html('<span style="color: {}; font-weight: bold;">{}</span>', color, obj.get_status_display())
|
|
status_marker.short_description = "Status"
|
|
|
|
|
|
@admin.register(RadniNalog)
|
|
class RadniNalogAdmin(admin.ModelAdmin):
|
|
# Prikazujemo stroj i putni nalog kako bismo znali gdje je servis odrađen
|
|
list_display = ('prikaz_broja', 'datum_kreiranja', 'klijent', 'stroj', 'status_boja', 'povezani_pn')
|
|
list_filter = ('status', 'datum_kreiranja', 'izvrsitelj', 'stroj__tip')
|
|
|
|
# Pretraga po serijskom broju stroja je ključna za servisere
|
|
search_fields = (
|
|
'broj_naloga',
|
|
'klijent__naziv',
|
|
'stroj__naziv',
|
|
'stroj__serijski_broj'
|
|
)
|
|
|
|
# Autocomplete za lakše biranje među stotinama strojeva i klijenata
|
|
autocomplete_fields = ['klijent', 'stroj', 'putni_nalog', 'izvrsitelj']
|
|
|
|
inlines = [RadniNalogSlikaInline]
|
|
|
|
fieldsets = (
|
|
('Subjekt servisa', {
|
|
'fields': (('broj_naloga', 'status'), ('klijent', 'stroj'), ('izvrsitelj', 'putni_nalog'))
|
|
}),
|
|
('Opis i dokumentacija', {
|
|
'fields': ('opis_kvara', 'slika_kvara', 'potpis_klijenta')
|
|
}),
|
|
)
|
|
|
|
def prikaz_broja(self, obj):
|
|
return format_html('<b>RN-{}</b>', obj.broj_naloga)
|
|
prikaz_broja.short_description = "Nalog"
|
|
|
|
def povezani_pn(self, obj):
|
|
if obj.putni_nalog:
|
|
return obj.putni_nalog.broj_naloga
|
|
return "Nema (Radiona)"
|
|
povezani_pn.short_description = "Putni nalog"
|
|
|
|
def status_boja(self, obj):
|
|
boje = {
|
|
'PLANIRANO': '#6b7280',
|
|
'U_RADU': '#2563eb',
|
|
'ZAVRSENO': '#10b981',
|
|
}
|
|
return format_html(
|
|
'<span style="color: {}; font-weight: bold;">{}</span>',
|
|
boje.get(obj.status, 'black'),
|
|
obj.get_status_display()
|
|
)
|
|
status_boja.short_description = "Status" |