This commit is contained in:
2026-05-22 06:08:51 +00:00
parent c078a257e9
commit bafec754d1
131 changed files with 2346 additions and 893 deletions

View File

@@ -4,7 +4,8 @@ from django.core.management.base import BaseCommand
from django.contrib.auth import get_user_model
from django.utils import timezone
from django.core.files import File
from operations.models import RadniNalog, RadniNalogSlika, PutniNalog
from django.db import transaction
from operations.models import RadniNalog, RadniNalogSlika, PutniNalog, BrojacSekvence
from fleet.models import Vozilo, Stroj
from kupci.models import Kupac
from kalendar.services import kreiraj_kalendarski_unos
@@ -12,10 +13,10 @@ from kalendar.services import kreiraj_kalendarski_unos
User = get_user_model()
class Command(BaseCommand):
help = 'Popunjava bazu s Putnim nalozima, Radnim nalozima i slikama'
help = 'Popunjava bazu s Putnim nalozima, Radnim nalozima i slikama sinkronizirano sa sekvencama'
def add_arguments(self, parser):
parser.add_argument('total_putovanja', type=int, help='Broj putnih naloga', default=3)
parser.add_argument('total_putovanja', type=int, nargs='?', default=3, help='Broj putnih naloga')
parser.add_argument('--img', type=str, default='test_assets/kvar.jpg')
def handle(self, *args, **kwargs):
@@ -43,23 +44,45 @@ class Command(BaseCommand):
"Hitna intervencija: Stroj u kvaru."
]
self.stdout.write(f'🚀 Generiranje {total_putovanja} putovanja...')
self.stdout.write(f'🚀 Generiranje {total_putovanja} putovanja sinkronizirano sa sekvencama...')
success_count_rn = 0
trenutna_godina = timezone.now().year
# Definiramo ključ i prefikse za putne naloge
prefix_pn = f"PN-{trenutna_godina}-"
kljuc_sekvence_rn = f"radni_nalog_{trenutna_godina}"
for i in range(total_putovanja):
serviser = random.choice(serviseri)
vozilo = random.choice(vozila)
broj_pn = f"PN-{trenutna_godina}-{PutniNalog.objects.count() + 1:04d}"
# 1. Kreiraj PUTNI NALOG (u statusu OTVOREN)
putni_nalog = PutniNalog.objects.create(
broj_naloga=broj_pn,
vozilo=vozilo,
korisnik=serviser,
relacija="Zagreb - Teren - Zagreb",
mjesto_odredista="Teren",
)
# 1. GENERIRANJE NEUNIŠTIVOG BROJA PUTNOG NALOGA
# Da skripta ne bi udarila u unique=True, tražimo stvarni zadnji PN u bazi
with transaction.atomic():
zadnji_pn = PutniNalog.objects.select_for_update().filter(
broj_naloga__startswith=prefix_pn
).order_by('-broj_naloga').first()
if zadnji_pn:
try:
zadnji_broj_pn = int(zadnji_pn.broj_naloga.split('-')[-1])
novi_broj_pn = zadnji_broj_pn + 1
except (ValueError, IndexError):
novi_broj_pn = PutniNalog.objects.count() + 1
else:
novi_broj_pn = 1
broj_pn = f"{prefix_pn}{novi_broj_pn:04d}"
# Kreiraj PUTNI NALOG
putni_nalog = PutniNalog.objects.create(
broj_naloga=broj_pn,
vozilo=vozilo,
korisnik=serviser,
relacija="Zagreb - Teren - Zagreb",
mjesto_odredista="Teren",
vrijeme_polaska=timezone.now()
)
self.stdout.write(self.style.MIGRATE_LABEL(f"Otvoren {broj_pn} (Vozilo: {vozilo.registracija})"))
@@ -69,14 +92,15 @@ class Command(BaseCommand):
for j in range(za_odraditi):
klijenti_sa_strojima = [k for k in kupci if k.strojevi.exists()]
if not klijenti_sa_strojima:
continue
klijent = random.choice(klijenti_sa_strojima)
stroj = random.choice(list(klijent.strojevi.all()))
broj_rn = f"{trenutna_godina}-{RadniNalog.objects.count() + 1:04d}"
try:
# Inicijaliziramo objekt bez broja_naloga kako bi se aktivirala
# naša neuništiva sekvencijska logika unutar save() metode modela!
nalog = RadniNalog(
broj_naloga=broj_rn,
klijent=klijent,
stroj=stroj,
putni_nalog=putni_nalog,
@@ -85,11 +109,14 @@ class Command(BaseCommand):
status=RadniNalog.StatusRadaChoices.PLANIRANO
)
# Prvo moramo izvršiti osnovni save da model kroz BrojacSekvence dodijeli čisti broj
nalog.save()
# Ako slika postoji, dodajemo je NAKON što je broj kreiran (da putanja_slike_naloga ima ispravan folder)
if test_img_path:
with open(test_img_path, 'rb') as f:
nalog.slika_kvara.save(f'rn_{broj_rn}.jpg', File(f), save=False)
nalog.slika_kvara.save(f'rn_{nalog.broj_naloga}.jpg', File(f), save=True)
nalog.save()
kreirani_radni_nalozi.append(nalog)
# Dodatne slike u galeriju
@@ -98,22 +125,24 @@ class Command(BaseCommand):
with open(test_img_path, 'rb') as f:
RadniNalogSlika.objects.create(
radni_nalog=nalog,
slika=File(f, name=f'gal_{broj_rn}_{k}.jpg'),
slika=File(f, name=f'gal_{nalog.broj_naloga}_{k}.jpg'),
opis=f"Detalj kvara {k+1}"
)
# 5. Upis u kalendar
kreiraj_kalendarski_unos(nalog)
try:
kreiraj_kalendarski_unos(nalog)
except Exception as cal_err:
self.stdout.write(self.style.WARNING(f" ⚠️ Kalendar unos preskočen: {cal_err}"))
success_count_rn += 1
self.stdout.write(f"RN-{broj_rn} dodan u {broj_pn}")
self.stdout.write(f"{nalog.broj_naloga} uspješno povezan u {broj_pn}")
except Exception as e:
self.stderr.write(f" ❌ Greška kod RN-{broj_rn}: {e}")
self.stderr.write(f" ❌ Greška kod kreiranja RN: {e}")
# 3. NASUMIČNO ZATVARANJE (Simulacija završenog posla)
# 50% šanse da ćemo u skripti odmah "završiti" ovaj put
if random.random() > 0.5:
if random.random() > 0.5 and kreirani_radni_nalozi:
try:
# Prvo moramo zatvoriti sve radne naloge da bi PN prošao validaciju
for rn in kreirani_radni_nalozi: