from django.db import models class Nomenclature(models.Model): VEHICLE = "vehicle" CONTAINER = "container" APPLIES_TO_CHOICES = [ (VEHICLE, "Vehicle"), (CONTAINER, "Container"), ] LOOKUP = "lookup" FIELD = "field" KIND_CHOICES = [ (LOOKUP, "Lookup Table"), (FIELD, "Custom Field"), ] code = models.CharField(max_length=50, unique=True) name = models.CharField(max_length=255) applies_to = models.CharField(max_length=50, choices=APPLIES_TO_CHOICES) kind = models.CharField(max_length=10, choices=KIND_CHOICES, default=LOOKUP) display_field = models.CharField( max_length=50, default="name", blank=True, help_text="Key of the NomenclatureField to use as dropdown label (for lookup kind)", ) sort_order = models.IntegerField(default=0) class Meta: ordering = ["sort_order", "code"] def __str__(self): return f"{self.name} ({self.code})" class NomenclatureField(models.Model): TEXT = "text" NUMBER = "number" BOOL = "bool" CHOICE = "choice" FIELD_TYPES = [ (TEXT, "Text"), (NUMBER, "Number"), (BOOL, "Boolean"), (CHOICE, "Choice"), ] nomenclature = models.ForeignKey( Nomenclature, on_delete=models.CASCADE, related_name="fields", ) key = models.CharField(max_length=50) label = models.CharField(max_length=100, blank=True) field_type = models.CharField(max_length=20, choices=FIELD_TYPES) required = models.BooleanField(default=False) choices = models.JSONField( null=True, blank=True, help_text='List of allowed values for choice type, e.g. ["Red","Green","Blue"]', ) sort_order = models.IntegerField(default=0) class Meta: unique_together = [("nomenclature", "key")] ordering = ["sort_order", "key"] def __str__(self): return f"{self.nomenclature.code}.{self.key} ({self.field_type})" class NomenclatureEntry(models.Model): nomenclature = models.ForeignKey( Nomenclature, on_delete=models.CASCADE, related_name="entries", ) data = models.JSONField(default=dict) is_active = models.BooleanField(default=True) class Meta: verbose_name_plural = "Nomenclature entries" ordering = ["id"] def __str__(self): display_key = self.nomenclature.display_field or "name" return str(self.data.get(display_key, f"Entry #{self.pk}"))