Files
eumi_v4/equipment/models.py
T

292 lines
9.0 KiB
Python

from django.db import models
from datetime import date
from simple_history.models import HistoricalRecords
from users.models import Employee
from django.core.exceptions import ValidationError
EQUIPMENT_STATUS = [
("activ", "Activ"),
("casat", "Casat (Decommissioned)"),
]
class Computer(models.Model):
# Unique ID and Entry
equipment_code = models.CharField(
max_length=50, unique=True, verbose_name="Cod Echipament"
)
entry_date = models.DateField(default=date.today, verbose_name="Data intrării")
# Hardware Specs
oem_name = models.CharField(
max_length=255, null=True, blank=True, verbose_name="Producător (OEM)"
)
motherboard = models.CharField(max_length=255, verbose_name="Placă de bază")
cpu = models.CharField(max_length=255, verbose_name="Procesor (CPU)")
ram = models.CharField(max_length=100, verbose_name="Memorie RAM")
storage = models.CharField(max_length=100, verbose_name="Stocare (HDD/SSD)")
optical_drive = models.CharField(
max_length=100, blank=True, null=True, verbose_name="Unitate optică"
)
gpu = models.CharField(
max_length=255, null=True, blank=True, verbose_name="Placă video (GPU)"
)
mac_address = models.CharField(max_length=50, verbose_name="Adresă MAC")
# Software & Misc
os_license = models.CharField(max_length=255, verbose_name="Licență OS")
additional_licenses = models.TextField(
blank=True, null=True, verbose_name="Licențe adiționale"
)
observations = models.TextField(blank=True, null=True, verbose_name="Observații")
# Custody Assignment
assigned_to = models.ForeignKey(
Employee,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="computers",
verbose_name="Atribuit către",
)
status = models.CharField(
max_length=20, choices=EQUIPMENT_STATUS, default="activ", verbose_name="Stare"
)
history = HistoricalRecords()
def __str__(self):
return f"{self.equipment_code} - {self.oem_name or 'Sistem Asamblat'}"
class Meta:
verbose_name = "Computer / Laptop"
verbose_name_plural = "Computere / Laptopuri"
class Monitor(models.Model):
equipment_code = models.CharField(
max_length=50, unique=True, verbose_name="Cod Echipament"
)
entry_date = models.DateField(default=date.today, verbose_name="Data intrării")
name = models.CharField(max_length=255, verbose_name="Nume Monitor")
serial_number = models.CharField(max_length=100, verbose_name="Număr Serial")
screen_diagonal = models.CharField(max_length=50, verbose_name="Diagonală (inch)")
observations = models.TextField(blank=True, null=True, verbose_name="Observații")
assigned_to = models.ForeignKey(
Employee,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="monitors",
verbose_name="Atribuit către",
)
status = models.CharField(
max_length=20, choices=EQUIPMENT_STATUS, default="activ", verbose_name="Stare"
)
history = HistoricalRecords()
def __str__(self):
return f"{self.equipment_code} - {self.name}"
class Meta:
verbose_name = "Monitor"
verbose_name_plural = "Monitoare"
class Peripheral(models.Model):
PERIPHERAL_TYPES = [
("printer", "Imprimantă"),
("ups", "UPS"),
("scanner", "Scanner"),
("copier", "Copiator"),
("ethernet", "Adaptor Ethernet"),
("audio", "Boxe Audio"),
("hdd_ext", "HDD Extern"),
("webcam", "Cameră Web"),
("other", "Altul"),
]
equipment_code = models.CharField(
max_length=50, unique=True, verbose_name="Cod Echipament"
)
entry_date = models.DateField(default=date.today, verbose_name="Data intrării")
peripheral_type = models.CharField(
max_length=50, choices=PERIPHERAL_TYPES, verbose_name="Tip Periferic"
)
name = models.CharField(max_length=255, verbose_name="Nume Echipament")
serial_number = models.CharField(max_length=100, verbose_name="Număr Serial")
assigned_to = models.ForeignKey(
Employee,
on_delete=models.SET_NULL,
null=True,
blank=True,
related_name="peripherals",
verbose_name="Atribuit către",
)
status = models.CharField(
max_length=20, choices=EQUIPMENT_STATUS, default="activ", verbose_name="Stare"
)
history = HistoricalRecords()
def __str__(self):
return f"{self.equipment_code} - {self.name} ({self.get_peripheral_type_display()})"
class Meta:
verbose_name = "Periferic"
verbose_name_plural = "Periferice"
class DigitalCertificate(models.Model):
CERT_TYPES = [
("cloud", "Cloud"),
("usb", "USB Token"),
]
certificate_type = models.CharField(
max_length=50, choices=CERT_TYPES, verbose_name="Tip Certificat"
)
issue_date = models.DateField(verbose_name="Data emiterii")
expiration_date = models.DateField(verbose_name="Data expirării")
is_canceled = models.BooleanField(default=False, verbose_name="Anulat?")
# Links directly to the employee
assigned_to = models.ForeignKey(
Employee,
on_delete=models.CASCADE,
related_name="digital_certificates",
verbose_name="Titular Certificat",
)
history = HistoricalRecords()
def __str__(self):
return f"Certificat {self.get_certificate_type_display()} - {self.assigned_to.name}"
class Meta:
verbose_name = "Certificat Digital"
verbose_name_plural = "Certificate Digitale"
class MaintenanceRecord(models.Model):
date = models.DateField(default=date.today, verbose_name="Data intervenției")
operation_type = models.CharField(
max_length=150, verbose_name="Tip operațiune (Curățare, Upgrade, etc.)"
)
description = models.TextField(verbose_name="Descriere detaliată")
performed_by = models.CharField(max_length=100, verbose_name="Efectuat de")
# Links to equipment (only one should be populated)
computer = models.ForeignKey(
Computer,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="maintenance_logs",
)
monitor = models.ForeignKey(
Monitor,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="maintenance_logs",
)
peripheral = models.ForeignKey(
Peripheral,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="maintenance_logs",
)
history = HistoricalRecords()
def clean(self):
equipment_count = sum(
[bool(self.computer), bool(self.monitor), bool(self.peripheral)]
)
if equipment_count != 1:
raise ValidationError(
"O înregistrare de mentenanță trebuie să fie legată de exact un singur echipament."
)
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
def __str__(self):
return f"{self.date} - {self.operation_type}"
class Meta:
verbose_name = "Foaie de Mentenanță"
verbose_name_plural = "Foi de Mentenanță"
class DecommissionRecord(models.Model):
date = models.DateField(default=date.today, verbose_name="Data casării")
document_number = models.CharField(
max_length=100, verbose_name="Număr document (Proces Verbal)"
)
reason = models.TextField(verbose_name="Motivul casării (Defect, Uzat moral, etc.)")
# Links to equipment
computer = models.OneToOneField(
Computer,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="decommission_log",
)
monitor = models.OneToOneField(
Monitor,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="decommission_log",
)
peripheral = models.OneToOneField(
Peripheral,
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="decommission_log",
)
history = HistoricalRecords()
def clean(self):
equipment_count = sum(
[bool(self.computer), bool(self.monitor), bool(self.peripheral)]
)
if equipment_count != 1:
raise ValidationError(
"Un proces verbal de casare trebuie să fie legat de exact un singur echipament."
)
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
# Automatically update the status of the linked equipment to 'casat'
if self.computer:
self.computer.status = "casat"
self.computer.save()
elif self.monitor:
self.monitor.status = "casat"
self.monitor.save()
elif self.peripheral:
self.peripheral.status = "casat"
self.peripheral.save()
def __str__(self):
return f"Casare {self.document_number} din {self.date}"
class Meta:
verbose_name = "Înregistrare Casare"
verbose_name_plural = "Înregistrări Casare"