diff --git a/InvenTree/InvenTree/models.py b/InvenTree/InvenTree/models.py index acfdad80fc..bbac3a9b03 100644 --- a/InvenTree/InvenTree/models.py +++ b/InvenTree/InvenTree/models.py @@ -38,7 +38,7 @@ class InvenTreeTree(models.Model): abstract = True unique_together = ('name', 'parent') - name = models.CharField(max_length=100) + name = models.CharField(max_length=100, unique=True) description = models.CharField(max_length=250, blank=True) parent = models.ForeignKey('self', on_delete=models.CASCADE, @@ -126,10 +126,11 @@ class InvenTreeTree(models.Model): @property def path(self): - if self.parent: - return "/".join([p.name for p in self.parentpath]) + "/" + self.name - else: - return self.name + return self.parentpath + [self] + + @property + def pathstring(self): + return '/'.join([item.name for item in self.path]) def __setattr__(self, attrname, val): """ Custom Attribute Setting function @@ -174,7 +175,7 @@ class InvenTreeTree(models.Model): This is recursive - Make it not so. """ - return self.path + return self.pathstring def FilterChildren(queryset, parent): diff --git a/InvenTree/InvenTree/urls.py b/InvenTree/InvenTree/urls.py index 7038fcbb19..2917ca1baf 100644 --- a/InvenTree/InvenTree/urls.py +++ b/InvenTree/InvenTree/urls.py @@ -3,7 +3,8 @@ from django.contrib import admin from rest_framework.documentation import include_docs_urls -from part.urls import part_urls, part_cat_urls +from part.urls import part_api_urls, part_cat_api_urls +from part.urls import part_urls from bom.urls import bom_urls from stock.urls import stock_urls, stock_loc_urls from supplier.urls import cust_urls, manu_urls, supplier_part_urls, price_break_urls, supplier_urls @@ -13,6 +14,8 @@ from supplier.urls import cust_urls, manu_urls, supplier_part_urls, price_break_ from users.urls import user_urls +from . import views + admin.site.site_header = "InvenTree Admin" apipatterns = [ @@ -22,8 +25,8 @@ apipatterns = [ url(r'^stock-location/', include(stock_loc_urls)), # Part URLs - url(r'^part/', include(part_urls)), - url(r'^part-category/', include(part_cat_urls)), + url(r'^part/', include(part_api_urls)), + url(r'^part-category/', include(part_cat_api_urls)), #url(r'^part-param/', include(part_param_urls)), #url(r'^part-param-template/', include(part_param_template_urls)), @@ -52,9 +55,12 @@ apipatterns = [ ] urlpatterns = [ + # API URL url(r'^api/', include(apipatterns)), + url(r'^part/', include(part_urls)), + url(r'^api-doc/', include_docs_urls(title='InvenTree API')), url(r'^admin/', admin.site.urls), diff --git a/InvenTree/bom/serializers.py b/InvenTree/bom/serializers.py index 925f0f05d4..adabb99fc6 100644 --- a/InvenTree/bom/serializers.py +++ b/InvenTree/bom/serializers.py @@ -3,7 +3,7 @@ from rest_framework import serializers from .models import BomItem -class BomItemSerializer(serializers.HyperlinkedModelSerializer): +class BomItemSerializer(serializers.ModelSerializer): class Meta: model = BomItem diff --git a/InvenTree/part/admin.py b/InvenTree/part/admin.py index 10b5b0d415..70a4728776 100644 --- a/InvenTree/part/admin.py +++ b/InvenTree/part/admin.py @@ -4,12 +4,12 @@ from .models import PartCategory, Part class PartAdmin(admin.ModelAdmin): - list_display = ('name', 'IPN', 'stock', 'category') + list_display = ('name', 'IPN', 'description', 'stock', 'category') class PartCategoryAdmin(admin.ModelAdmin): - list_display = ('name', 'path', 'description') + list_display = ('name', 'pathstring', 'description') """ class ParameterTemplateAdmin(admin.ModelAdmin): diff --git a/InvenTree/part/models.py b/InvenTree/part/models.py index 3ca4ebab0c..866dc18f86 100644 --- a/InvenTree/part/models.py +++ b/InvenTree/part/models.py @@ -36,7 +36,7 @@ class Part(models.Model): IPN = models.CharField(max_length=100, blank=True) # Part category - all parts must be assigned to a category - category = models.ForeignKey(PartCategory, on_delete=models.CASCADE) + category = models.ForeignKey(PartCategory, on_delete=models.CASCADE, related_name='parts') # Minimum "allowed" stock level minimum_stock = models.PositiveIntegerField(default=0, validators=[MinValueValidator(0)]) @@ -75,11 +75,21 @@ class Part(models.Model): result = stocks.aggregate(total=Sum('quantity')) return result['total'] + @property + def bomItemCount(self): + return self.bom_items.all().count() + + + @property + def usedInCount(self): + return self.used_in.all().count() + + """ @property def projects(self): - """ Return a list of unique projects that this part is associated with. + " Return a list of unique projects that this part is associated with. A part may be used in zero or more projects. - """ + " project_ids = set() project_parts = self.projectpart_set.all() @@ -92,6 +102,6 @@ class Part(models.Model): projects.append(pp.project) return projects - + """ diff --git a/InvenTree/part/serializers.py b/InvenTree/part/serializers.py index d1ef66f3e2..34d8c98b8e 100644 --- a/InvenTree/part/serializers.py +++ b/InvenTree/part/serializers.py @@ -17,7 +17,8 @@ class PartParameterSerializer(serializers.HyperlinkedModelSerializer): 'units') """ -class PartSerializer(serializers.HyperlinkedModelSerializer): +#class PartSerializer(serializers.HyperlinkedModelSerializer): +class PartSerializer(serializers.ModelSerializer): """ Serializer for complete detail information of a part. Used when displaying all details of a single component. """ @@ -31,7 +32,8 @@ class PartSerializer(serializers.HyperlinkedModelSerializer): 'category', 'stock', 'units', - 'trackable') + 'trackable', + ) class PartCategorySerializer(serializers.HyperlinkedModelSerializer): @@ -42,7 +44,7 @@ class PartCategorySerializer(serializers.HyperlinkedModelSerializer): 'name', 'description', 'parent', - 'path') + 'pathstring') """ class PartTemplateSerializer(serializers.HyperlinkedModelSerializer): diff --git a/InvenTree/part/templates/cat_link.html b/InvenTree/part/templates/cat_link.html new file mode 100644 index 0000000000..aff374a4d7 --- /dev/null +++ b/InvenTree/part/templates/cat_link.html @@ -0,0 +1,7 @@ +
{{ part.name }} | +{{ part.description }} | +