import random import os 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 fleet.models import Vozilo, Stroj from kupci.models import Kupac from kalendar.services import kreiraj_kalendarski_unos User = get_user_model() class Command(BaseCommand): help = 'Popunjava bazu s Putnim nalozima, Radnim nalozima i slikama' def add_arguments(self, parser): parser.add_argument('total_putovanja', type=int, help='Broj putnih naloga', default=3) parser.add_argument('--img', type=str, default='test_assets/kvar.jpg') def handle(self, *args, **kwargs): total_putovanja = kwargs['total_putovanja'] test_img_path = kwargs['img'] kupci = Kupac.objects.prefetch_related('strojevi').all() vozila = list(Vozilo.objects.all()) serviseri = list(User.objects.filter(is_staff=True)) if not kupci.exists() or not vozila or not serviseri: self.stdout.write(self.style.ERROR("Baza mora imati kupce, vozila i servisere (is_staff=True).")) return # Provjera slike if not os.path.exists(test_img_path): self.stdout.write(self.style.WARNING(f"Testna slika {test_img_path} nije pronađena. Generiram bez slika.")) test_img_path = None opisi_kvarova = [ "Godišnji periodični servis dizalice.", "Zamjena hidrauličnog crijeva i dopuna ulja.", "Kalibracija senzora opterećenja.", "Popravak daljinskog upravljača.", "Hitna intervencija: Stroj u kvaru." ] self.stdout.write(f'🚀 Generiranje {total_putovanja} putovanja...') success_count_rn = 0 trenutna_godina = timezone.now().year 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", ) self.stdout.write(self.style.MIGRATE_LABEL(f"Otvoren {broj_pn} (Vozilo: {vozilo.registracija})")) # 2. Kreiraj 1 do 3 RADNA NALOGA za ovaj putni nalog za_odraditi = random.randint(1, 3) kreirani_radni_nalozi = [] for j in range(za_odraditi): klijenti_sa_strojima = [k for k in kupci if k.strojevi.exists()] klijent = random.choice(klijenti_sa_strojima) stroj = random.choice(list(klijent.strojevi.all())) broj_rn = f"{trenutna_godina}-{RadniNalog.objects.count() + 1:04d}" try: nalog = RadniNalog( broj_naloga=broj_rn, klijent=klijent, stroj=stroj, putni_nalog=putni_nalog, opis_kvara=random.choice(opisi_kvarova), izvrsitelj=serviser, status=RadniNalog.StatusRadaChoices.PLANIRANO ) 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.save() kreirani_radni_nalozi.append(nalog) # Dodatne slike u galeriju if test_img_path: for k in range(random.randint(1, 2)): with open(test_img_path, 'rb') as f: RadniNalogSlika.objects.create( radni_nalog=nalog, slika=File(f, name=f'gal_{broj_rn}_{k}.jpg'), opis=f"Detalj kvara {k+1}" ) # 5. Upis u kalendar kreiraj_kalendarski_unos(nalog) success_count_rn += 1 self.stdout.write(f" ✅ RN-{broj_rn} dodan u {broj_pn}") except Exception as e: self.stderr.write(f" ❌ Greška kod RN-{broj_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: try: # Prvo moramo zatvoriti sve radne naloge da bi PN prošao validaciju for rn in kreirani_radni_nalozi: rn.status = RadniNalog.StatusRadaChoices.ZAVRSENO rn.save() # Dodajemo završne kilometre (uvijek više od početnih) putni_nalog.zavrsna_km = putni_nalog.pocetna_km + random.randint(50, 500) putni_nalog.status = PutniNalog.StatusChoices.ZAVRSEN putni_nalog.save() self.stdout.write(self.style.SUCCESS(f" 🏁 {broj_pn} automatski ZATVOREN. Kilometri vozila ažurirani.")) except Exception as e: self.stdout.write(self.style.WARNING(f" ⚠️ PN-{broj_pn} nije zatvoren: {e}")) self.stdout.write(self.style.SUCCESS(f'\nGotovo! Generirano {total_putovanja} PN i {success_count_rn} RN.'))