diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py new file mode 100644 index 0000000000..1b7193ab3f --- /dev/null +++ b/InvenTree/InvenTree/models.py @@ -0,0 +1,83 @@ +from __future__ import unicode_literals + +from django.db import models +from django.core.exceptions import ObjectDoesNotExist +from django.contrib.contenttypes.models import ContentType + +class InvenTreeTree(models.Model): + name = models.CharField(max_length=100) + description = models.CharField(max_length=250) + parent = models.ForeignKey('self', + on_delete=models.CASCADE, + blank=True, + null=True) + #limit_choices_to={id: getAcceptableParents}) + + # Return a flat set of all child items under this node + def getUniqueChildren(self, unique=None): + + if unique is None: + unique = set() + + if self.id in unique: + return unique + + unique.add(self.id) + + # Some magic to get around the limitations of abstract models + contents = ContentType.objects.get_for_model(type(self)) + children = contents.get_all_objects_for_this_type(parent = self.id) + + for child in children: + child.getUniqueChildren(unique) + + return unique + + # Return a list of acceptable other parents + def getAcceptableParents(self): + contents = ContentType.objects.get_for_model(type(self)) + + available = contents.get_all_objects_for_this_type() + + # List of child IDs + childs = getUniqueChildren() + + acceptable = [None] + + for a in available: + if a.id not in childs: + acceptable.append(a) + + return acceptable + + # Return the parent path of this category + @property + def path(self): + if self.parent: + return self.parent.path + [self.parent] + else: + return [] + + return parent_path + + # Custom SetAttribute function to prevent parent recursion + def __setattr__(self, attrname, val): + # Prevent parent from being set such that it would cause a recursion loop + if attrname == 'parent_id': + # Parent cannot be set to same ID (this would cause looping) + if val == self.id: + return + # Null parent is OK + elif val is None: + pass + # Ensure that the new parent is not already a child + else: + kids = self.getUniqueChildren() + if val in kids: + print("ALREADY A CHILD") + return + + super(InvenTreeTree, self).__setattr__(attrname, val) + + class Meta: + abstract = True \ No newline at end of file diff --git a/InvenTree/InvenTree/settings.py b/InvenTree/InvenTree/settings.py index ec07615606..2c945bdd09 100644 --- a/InvenTree/InvenTree/settings.py +++ b/InvenTree/InvenTree/settings.py @@ -38,7 +38,8 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', - 'part.apps.PartConfig' + 'part.apps.PartConfig', + 'stock.apps.StockConfig' ] MIDDLEWARE = [ diff --git a/InvenTree/part/admin.py b/InvenTree/part/admin.py index 7fdd488b8a..34e1ad40e6 100644 --- a/InvenTree/part/admin.py +++ b/InvenTree/part/admin.py @@ -3,4 +3,11 @@ from django.contrib import admin from .models import PartCategory, Part admin.site.register(Part) -admin.site.register(PartCategory) + +# Custom form for PartCategory +class PartCategoryAdmin(admin.ModelAdmin): + # TODO - Only let valid parents be displayed + pass + + +admin.site.register(PartCategory, PartCategoryAdmin) \ No newline at end of file diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 792c342803..78580e2ae3 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -3,69 +3,19 @@ from __future__ import unicode_literals from django.db import models from django.core.exceptions import ObjectDoesNotExist -class InvenTreeTree(models.Model): - - # Return a flat set of all child items under this node - def getUniqueChildren(self, unique=None): - - if unique is None: - unique = set() - - if self.id in unique: - return unique - - unique.add(self.id) - - children = PartCategory.objects.filter(parent = self.id) - - for child in children: - child.getUniqueChildren(unique) - - return unique - - # Return the parent path of this category - @property - def path(self): - if self.parent: - return self.parent.path + [self.parent] - else: - return [] - - return parent_path - - # Custom SetAttribute function to prevent parent recursion - def __setattr__(self, attrname, val): - # Prevent parent from being set such that it would cause a recursion loop - if attrname == 'parent_id': - # Parent cannot be set to same ID (this would cause looping) - if val == self.id: - return - # Null parent is OK - elif val is None: - pass - # Ensure that the new parent is not already a child - else: - kids = self.getUniqueChildren() - if val in kids: - print("ALREADY A CHILD") - return - - super(InvenTreeTree, self).__setattr__(attrname, val) - - class Meta: - abstract = True +from InvenTree.models import InvenTreeTree -class PartCategory(InvenTreeTree): - name = models.CharField(max_length=100) - description = models.CharField(max_length=250) - parent = models.ForeignKey('self', on_delete=models.CASCADE, blank=True, null=True) - +class PartCategory(InvenTreeTree): def __str__(self): if self.parent: return "/".join([p.name for p in self.path]) + "/" + self.name else: return self.name + class Meta: + verbose_name = "Part Category" + verbose_name_plural = "Part Categories" + class Part(models.Model): name = models.CharField(max_length=100) description = models.CharField(max_length=250, blank=True) @@ -80,5 +30,8 @@ class Part(models.Model): else: return self.name + class Meta: + verbose_name = "Part" + verbose_name_plural = "Parts" \ No newline at end of file